heading-setext.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 'use strict';
  2. module.exports = setextHeading;
  3. var C_NEWLINE = '\n';
  4. var C_TAB = '\t';
  5. var C_SPACE = ' ';
  6. var C_EQUALS = '=';
  7. var C_DASH = '-';
  8. var MAX_HEADING_INDENT = 3;
  9. /* Map of characters which can be used to mark setext
  10. * headers, mapping to their corresponding depth. */
  11. var SETEXT_MARKERS = {};
  12. SETEXT_MARKERS[C_EQUALS] = 1;
  13. SETEXT_MARKERS[C_DASH] = 2;
  14. function setextHeading(eat, value, silent) {
  15. var self = this;
  16. var now = eat.now();
  17. var length = value.length;
  18. var index = -1;
  19. var subvalue = '';
  20. var content;
  21. var queue;
  22. var character;
  23. var marker;
  24. var depth;
  25. /* Eat initial indentation. */
  26. while (++index < length) {
  27. character = value.charAt(index);
  28. if (character !== C_SPACE || index >= MAX_HEADING_INDENT) {
  29. index--;
  30. break;
  31. }
  32. subvalue += character;
  33. }
  34. /* Eat content. */
  35. content = '';
  36. queue = '';
  37. while (++index < length) {
  38. character = value.charAt(index);
  39. if (character === C_NEWLINE) {
  40. index--;
  41. break;
  42. }
  43. if (character === C_SPACE || character === C_TAB) {
  44. queue += character;
  45. } else {
  46. content += queue + character;
  47. queue = '';
  48. }
  49. }
  50. now.column += subvalue.length;
  51. now.offset += subvalue.length;
  52. subvalue += content + queue;
  53. /* Ensure the content is followed by a newline and a
  54. * valid marker. */
  55. character = value.charAt(++index);
  56. marker = value.charAt(++index);
  57. if (character !== C_NEWLINE || !SETEXT_MARKERS[marker]) {
  58. return;
  59. }
  60. subvalue += character;
  61. /* Eat Setext-line. */
  62. queue = marker;
  63. depth = SETEXT_MARKERS[marker];
  64. while (++index < length) {
  65. character = value.charAt(index);
  66. if (character !== marker) {
  67. if (character !== C_NEWLINE) {
  68. return;
  69. }
  70. index--;
  71. break;
  72. }
  73. queue += character;
  74. }
  75. if (silent) {
  76. return true;
  77. }
  78. return eat(subvalue + queue)({
  79. type: 'heading',
  80. depth: depth,
  81. children: self.tokenizeInline(content, now)
  82. });
  83. }