parser.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. 'use strict';
  2. var xtend = require('xtend');
  3. var toggle = require('state-toggle');
  4. var vfileLocation = require('vfile-location');
  5. var unescape = require('./unescape');
  6. var decode = require('./decode');
  7. var tokenizer = require('./tokenizer');
  8. module.exports = Parser;
  9. function Parser(doc, file) {
  10. this.file = file;
  11. this.offset = {};
  12. this.options = xtend(this.options);
  13. this.setOptions({});
  14. this.inList = false;
  15. this.inBlock = false;
  16. this.inLink = false;
  17. this.atStart = true;
  18. this.toOffset = vfileLocation(file).toOffset;
  19. this.unescape = unescape(this, 'escape');
  20. this.decode = decode(this);
  21. }
  22. var proto = Parser.prototype;
  23. /* Expose core. */
  24. proto.setOptions = require('./set-options');
  25. proto.parse = require('./parse');
  26. /* Expose `defaults`. */
  27. proto.options = require('./defaults');
  28. /* Enter and exit helpers. */
  29. proto.exitStart = toggle('atStart', true);
  30. proto.enterList = toggle('inList', false);
  31. proto.enterLink = toggle('inLink', false);
  32. proto.enterBlock = toggle('inBlock', false);
  33. /* Nodes that can interupt a paragraph:
  34. *
  35. * ```markdown
  36. * A paragraph, followed by a thematic break.
  37. * ___
  38. * ```
  39. *
  40. * In the above example, the thematic break “interupts”
  41. * the paragraph. */
  42. proto.interruptParagraph = [
  43. ['thematicBreak'],
  44. ['atxHeading'],
  45. ['fencedCode'],
  46. ['blockquote'],
  47. ['html'],
  48. ['setextHeading', {commonmark: false}],
  49. ['definition', {commonmark: false}],
  50. ['footnote', {commonmark: false}]
  51. ];
  52. /* Nodes that can interupt a list:
  53. *
  54. * ```markdown
  55. * - One
  56. * ___
  57. * ```
  58. *
  59. * In the above example, the thematic break “interupts”
  60. * the list. */
  61. proto.interruptList = [
  62. ['atxHeading', {pedantic: false}],
  63. ['fencedCode', {pedantic: false}],
  64. ['thematicBreak', {pedantic: false}],
  65. ['definition', {commonmark: false}],
  66. ['footnote', {commonmark: false}]
  67. ];
  68. /* Nodes that can interupt a blockquote:
  69. *
  70. * ```markdown
  71. * > A paragraph.
  72. * ___
  73. * ```
  74. *
  75. * In the above example, the thematic break “interupts”
  76. * the blockquote. */
  77. proto.interruptBlockquote = [
  78. ['indentedCode', {commonmark: true}],
  79. ['fencedCode', {commonmark: true}],
  80. ['atxHeading', {commonmark: true}],
  81. ['setextHeading', {commonmark: true}],
  82. ['thematicBreak', {commonmark: true}],
  83. ['html', {commonmark: true}],
  84. ['list', {commonmark: true}],
  85. ['definition', {commonmark: false}],
  86. ['footnote', {commonmark: false}]
  87. ];
  88. /* Handlers. */
  89. proto.blockTokenizers = {
  90. newline: require('./tokenize/newline'),
  91. indentedCode: require('./tokenize/code-indented'),
  92. fencedCode: require('./tokenize/code-fenced'),
  93. blockquote: require('./tokenize/blockquote'),
  94. atxHeading: require('./tokenize/heading-atx'),
  95. thematicBreak: require('./tokenize/thematic-break'),
  96. list: require('./tokenize/list'),
  97. setextHeading: require('./tokenize/heading-setext'),
  98. html: require('./tokenize/html-block'),
  99. footnote: require('./tokenize/footnote-definition'),
  100. definition: require('./tokenize/definition'),
  101. table: require('./tokenize/table'),
  102. paragraph: require('./tokenize/paragraph')
  103. };
  104. proto.inlineTokenizers = {
  105. escape: require('./tokenize/escape'),
  106. autoLink: require('./tokenize/auto-link'),
  107. url: require('./tokenize/url'),
  108. html: require('./tokenize/html-inline'),
  109. link: require('./tokenize/link'),
  110. reference: require('./tokenize/reference'),
  111. strong: require('./tokenize/strong'),
  112. emphasis: require('./tokenize/emphasis'),
  113. deletion: require('./tokenize/delete'),
  114. code: require('./tokenize/code-inline'),
  115. break: require('./tokenize/break'),
  116. text: require('./tokenize/text')
  117. };
  118. /* Expose precedence. */
  119. proto.blockMethods = keys(proto.blockTokenizers);
  120. proto.inlineMethods = keys(proto.inlineTokenizers);
  121. /* Tokenizers. */
  122. proto.tokenizeBlock = tokenizer('block');
  123. proto.tokenizeInline = tokenizer('inline');
  124. proto.tokenizeFactory = tokenizer;
  125. /* Get all keys in `value`. */
  126. function keys(value) {
  127. var result = [];
  128. var key;
  129. for (key in value) {
  130. result.push(key);
  131. }
  132. return result;
  133. }