markdown-it-mark.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*! markdown-it-mark 3.0.1 https://github.com/markdown-it/markdown-it-mark @license MIT */
  2. (function (global, factory) {
  3. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  4. typeof define === 'function' && define.amd ? define(factory) :
  5. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.markdownitMark = factory());
  6. }(this, (function () { 'use strict';
  7. var markdownItMark = function ins_plugin(md) {
  8. // Insert each marker as a separate text token, and add it to delimiter list
  9. //
  10. function tokenize(state, silent) {
  11. var i, scanned, token, len, ch,
  12. start = state.pos,
  13. marker = state.src.charCodeAt(start);
  14. if (silent) { return false; }
  15. if (marker !== 0x3D/* = */) { return false; }
  16. scanned = state.scanDelims(state.pos, true);
  17. len = scanned.length;
  18. ch = String.fromCharCode(marker);
  19. if (len < 2) { return false; }
  20. if (len % 2) {
  21. token = state.push('text', '', 0);
  22. token.content = ch;
  23. len--;
  24. }
  25. for (i = 0; i < len; i += 2) {
  26. token = state.push('text', '', 0);
  27. token.content = ch + ch;
  28. if (!scanned.can_open && !scanned.can_close) { continue; }
  29. state.delimiters.push({
  30. marker: marker,
  31. length: 0, // disable "rule of 3" length checks meant for emphasis
  32. jump: i / 2, // 1 delimiter = 2 characters
  33. token: state.tokens.length - 1,
  34. end: -1,
  35. open: scanned.can_open,
  36. close: scanned.can_close
  37. });
  38. }
  39. state.pos += scanned.length;
  40. return true;
  41. }
  42. // Walk through delimiter list and replace text tokens with tags
  43. //
  44. function postProcess(state, delimiters) {
  45. var i, j,
  46. startDelim,
  47. endDelim,
  48. token,
  49. loneMarkers = [],
  50. max = delimiters.length;
  51. for (i = 0; i < max; i++) {
  52. startDelim = delimiters[i];
  53. if (startDelim.marker !== 0x3D/* = */) {
  54. continue;
  55. }
  56. if (startDelim.end === -1) {
  57. continue;
  58. }
  59. endDelim = delimiters[startDelim.end];
  60. token = state.tokens[startDelim.token];
  61. token.type = 'mark_open';
  62. token.tag = 'mark';
  63. token.nesting = 1;
  64. token.markup = '==';
  65. token.content = '';
  66. token = state.tokens[endDelim.token];
  67. token.type = 'mark_close';
  68. token.tag = 'mark';
  69. token.nesting = -1;
  70. token.markup = '==';
  71. token.content = '';
  72. if (state.tokens[endDelim.token - 1].type === 'text' &&
  73. state.tokens[endDelim.token - 1].content === '=') {
  74. loneMarkers.push(endDelim.token - 1);
  75. }
  76. }
  77. // If a marker sequence has an odd number of characters, it's splitted
  78. // like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the
  79. // start of the sequence.
  80. //
  81. // So, we have to move all those markers after subsequent s_close tags.
  82. //
  83. while (loneMarkers.length) {
  84. i = loneMarkers.pop();
  85. j = i + 1;
  86. while (j < state.tokens.length && state.tokens[j].type === 'mark_close') {
  87. j++;
  88. }
  89. j--;
  90. if (i !== j) {
  91. token = state.tokens[j];
  92. state.tokens[j] = state.tokens[i];
  93. state.tokens[i] = token;
  94. }
  95. }
  96. }
  97. md.inline.ruler.before('emphasis', 'mark', tokenize);
  98. md.inline.ruler2.before('emphasis', 'mark', function (state) {
  99. var curr,
  100. tokens_meta = state.tokens_meta,
  101. max = (state.tokens_meta || []).length;
  102. postProcess(state, state.delimiters);
  103. for (curr = 0; curr < max; curr++) {
  104. if (tokens_meta[curr] && tokens_meta[curr].delimiters) {
  105. postProcess(state, tokens_meta[curr].delimiters);
  106. }
  107. }
  108. });
  109. };
  110. return markdownItMark;
  111. })));