footnote-definition.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. 'use strict';
  2. var whitespace = require('is-whitespace-character');
  3. var normalize = require('../util/normalize');
  4. module.exports = footnoteDefinition;
  5. footnoteDefinition.notInList = true;
  6. footnoteDefinition.notInBlock = true;
  7. var C_BACKSLASH = '\\';
  8. var C_NEWLINE = '\n';
  9. var C_TAB = '\t';
  10. var C_SPACE = ' ';
  11. var C_BRACKET_OPEN = '[';
  12. var C_BRACKET_CLOSE = ']';
  13. var C_CARET = '^';
  14. var C_COLON = ':';
  15. var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm;
  16. function footnoteDefinition(eat, value, silent) {
  17. var self = this;
  18. var offsets = self.offset;
  19. var index;
  20. var length;
  21. var subvalue;
  22. var now;
  23. var currentLine;
  24. var content;
  25. var queue;
  26. var subqueue;
  27. var character;
  28. var identifier;
  29. var add;
  30. var exit;
  31. if (!self.options.footnotes) {
  32. return;
  33. }
  34. index = 0;
  35. length = value.length;
  36. subvalue = '';
  37. now = eat.now();
  38. currentLine = now.line;
  39. while (index < length) {
  40. character = value.charAt(index);
  41. if (!whitespace(character)) {
  42. break;
  43. }
  44. subvalue += character;
  45. index++;
  46. }
  47. if (
  48. value.charAt(index) !== C_BRACKET_OPEN ||
  49. value.charAt(index + 1) !== C_CARET
  50. ) {
  51. return;
  52. }
  53. subvalue += C_BRACKET_OPEN + C_CARET;
  54. index = subvalue.length;
  55. queue = '';
  56. while (index < length) {
  57. character = value.charAt(index);
  58. if (character === C_BRACKET_CLOSE) {
  59. break;
  60. } else if (character === C_BACKSLASH) {
  61. queue += character;
  62. index++;
  63. character = value.charAt(index);
  64. }
  65. queue += character;
  66. index++;
  67. }
  68. if (
  69. !queue ||
  70. value.charAt(index) !== C_BRACKET_CLOSE ||
  71. value.charAt(index + 1) !== C_COLON
  72. ) {
  73. return;
  74. }
  75. if (silent) {
  76. return true;
  77. }
  78. identifier = normalize(queue);
  79. subvalue += queue + C_BRACKET_CLOSE + C_COLON;
  80. index = subvalue.length;
  81. while (index < length) {
  82. character = value.charAt(index);
  83. if (character !== C_TAB && character !== C_SPACE) {
  84. break;
  85. }
  86. subvalue += character;
  87. index++;
  88. }
  89. now.column += subvalue.length;
  90. now.offset += subvalue.length;
  91. queue = '';
  92. content = '';
  93. subqueue = '';
  94. while (index < length) {
  95. character = value.charAt(index);
  96. if (character === C_NEWLINE) {
  97. subqueue = character;
  98. index++;
  99. while (index < length) {
  100. character = value.charAt(index);
  101. if (character !== C_NEWLINE) {
  102. break;
  103. }
  104. subqueue += character;
  105. index++;
  106. }
  107. queue += subqueue;
  108. subqueue = '';
  109. while (index < length) {
  110. character = value.charAt(index);
  111. if (character !== C_SPACE) {
  112. break;
  113. }
  114. subqueue += character;
  115. index++;
  116. }
  117. if (subqueue.length === 0) {
  118. break;
  119. }
  120. queue += subqueue;
  121. }
  122. if (queue) {
  123. content += queue;
  124. queue = '';
  125. }
  126. content += character;
  127. index++;
  128. }
  129. subvalue += content;
  130. content = content.replace(EXPRESSION_INITIAL_TAB, function (line) {
  131. offsets[currentLine] = (offsets[currentLine] || 0) + line.length;
  132. currentLine++;
  133. return '';
  134. });
  135. add = eat(subvalue);
  136. exit = self.enterBlock();
  137. content = self.tokenizeBlock(content, now);
  138. exit();
  139. return add({
  140. type: 'footnoteDefinition',
  141. identifier: identifier,
  142. children: content
  143. });
  144. }