markdown-it-abbr.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*! markdown-it-abbr 1.0.4 https://github.com//markdown-it/markdown-it-abbr @license MIT */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.markdownitAbbr = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. // Enclose abbreviations in <abbr> tags
  3. //
  4. 'use strict';
  5. module.exports = function sub_plugin(md) {
  6. var escapeRE = md.utils.escapeRE,
  7. arrayReplaceAt = md.utils.arrayReplaceAt;
  8. // ASCII characters in Cc, Sc, Sm, Sk categories we should terminate on;
  9. // you can check character classes here:
  10. // http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
  11. var OTHER_CHARS = ' \r\n$+<=>^`|~';
  12. var UNICODE_PUNCT_RE = md.utils.lib.ucmicro.P.source;
  13. var UNICODE_SPACE_RE = md.utils.lib.ucmicro.Z.source;
  14. function abbr_def(state, startLine, endLine, silent) {
  15. var label, title, ch, labelStart, labelEnd,
  16. pos = state.bMarks[startLine] + state.tShift[startLine],
  17. max = state.eMarks[startLine];
  18. if (pos + 2 >= max) { return false; }
  19. if (state.src.charCodeAt(pos++) !== 0x2A/* * */) { return false; }
  20. if (state.src.charCodeAt(pos++) !== 0x5B/* [ */) { return false; }
  21. labelStart = pos;
  22. for (; pos < max; pos++) {
  23. ch = state.src.charCodeAt(pos);
  24. if (ch === 0x5B /* [ */) {
  25. return false;
  26. } else if (ch === 0x5D /* ] */) {
  27. labelEnd = pos;
  28. break;
  29. } else if (ch === 0x5C /* \ */) {
  30. pos++;
  31. }
  32. }
  33. if (labelEnd < 0 || state.src.charCodeAt(labelEnd + 1) !== 0x3A/* : */) {
  34. return false;
  35. }
  36. if (silent) { return true; }
  37. label = state.src.slice(labelStart, labelEnd).replace(/\\(.)/g, '$1');
  38. title = state.src.slice(labelEnd + 2, max).trim();
  39. if (label.length === 0) { return false; }
  40. if (title.length === 0) { return false; }
  41. if (!state.env.abbreviations) { state.env.abbreviations = {}; }
  42. // prepend ':' to avoid conflict with Object.prototype members
  43. if (typeof state.env.abbreviations[':' + label] === 'undefined') {
  44. state.env.abbreviations[':' + label] = title;
  45. }
  46. state.line = startLine + 1;
  47. return true;
  48. }
  49. function abbr_replace(state) {
  50. var i, j, l, tokens, token, text, nodes, pos, reg, m, regText, regSimple,
  51. currentToken,
  52. blockTokens = state.tokens;
  53. if (!state.env.abbreviations) { return; }
  54. regSimple = new RegExp('(?:' +
  55. Object.keys(state.env.abbreviations).map(function (x) {
  56. return x.substr(1);
  57. }).sort(function (a, b) {
  58. return b.length - a.length;
  59. }).map(escapeRE).join('|') +
  60. ')');
  61. regText = '(^|' + UNICODE_PUNCT_RE + '|' + UNICODE_SPACE_RE +
  62. '|[' + OTHER_CHARS.split('').map(escapeRE).join('') + '])'
  63. + '(' + Object.keys(state.env.abbreviations).map(function (x) {
  64. return x.substr(1);
  65. }).sort(function (a, b) {
  66. return b.length - a.length;
  67. }).map(escapeRE).join('|') + ')'
  68. + '($|' + UNICODE_PUNCT_RE + '|' + UNICODE_SPACE_RE +
  69. '|[' + OTHER_CHARS.split('').map(escapeRE).join('') + '])';
  70. reg = new RegExp(regText, 'g');
  71. for (j = 0, l = blockTokens.length; j < l; j++) {
  72. if (blockTokens[j].type !== 'inline') { continue; }
  73. tokens = blockTokens[j].children;
  74. // We scan from the end, to keep position when new tags added.
  75. for (i = tokens.length - 1; i >= 0; i--) {
  76. currentToken = tokens[i];
  77. if (currentToken.type !== 'text') { continue; }
  78. pos = 0;
  79. text = currentToken.content;
  80. reg.lastIndex = 0;
  81. nodes = [];
  82. // fast regexp run to determine whether there are any abbreviated words
  83. // in the current token
  84. if (!regSimple.test(text)) { continue; }
  85. while ((m = reg.exec(text))) {
  86. if (m.index > 0 || m[1].length > 0) {
  87. token = new state.Token('text', '', 0);
  88. token.content = text.slice(pos, m.index + m[1].length);
  89. nodes.push(token);
  90. }
  91. token = new state.Token('abbr_open', 'abbr', 1);
  92. token.attrs = [ [ 'title', state.env.abbreviations[':' + m[2]] ] ];
  93. nodes.push(token);
  94. token = new state.Token('text', '', 0);
  95. token.content = m[2];
  96. nodes.push(token);
  97. token = new state.Token('abbr_close', 'abbr', -1);
  98. nodes.push(token);
  99. reg.lastIndex -= m[3].length;
  100. pos = reg.lastIndex;
  101. }
  102. if (!nodes.length) { continue; }
  103. if (pos < text.length) {
  104. token = new state.Token('text', '', 0);
  105. token.content = text.slice(pos);
  106. nodes.push(token);
  107. }
  108. // replace current node
  109. blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes);
  110. }
  111. }
  112. }
  113. md.block.ruler.before('reference', 'abbr_def', abbr_def, { alt: [ 'paragraph', 'reference' ] });
  114. md.core.ruler.after('linkify', 'abbr_replace', abbr_replace);
  115. };
  116. },{}]},{},[1])(1)
  117. });