Markdown parser, done right. 100% CommonMark support, extensions, syntax plugins & high speed https://markdown-it.github.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

91 lines
2.5 KiB

// Enclose abbreviations in <abbr> tags
//
'use strict';
var arrayReplaceAt = require('../common/utils').arrayReplaceAt;
var PUNCT_CHARS = ' \n()[]\'".,!?-';
// from Google closure library
// http://closure-library.googlecode.com/git-history/docs/local_closure_goog_string_string.js.source.html#line1021
function regEscape(s) {
return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1');
}
module.exports = function abbr2(state) {
var i, j, l, tokens, token, text, nodes, pos, level, reg, m, regText,
blockTokens = state.tokens;
if (!state.env.abbreviations) { return; }
if (!state.env.abbrRegExp) {
regText = '(^|[' + PUNCT_CHARS.split('').map(regEscape).join('') + '])'
+ '(' + Object.keys(state.env.abbreviations).map(function (x) {
return x.substr(1);
}).sort(function (a, b) {
return b.length - a.length;
}).map(regEscape).join('|') + ')'
+ '($|[' + PUNCT_CHARS.split('').map(regEscape).join('') + '])';
state.env.abbrRegExp = new RegExp(regText, 'g');
}
reg = state.env.abbrRegExp;
for (j = 0, l = blockTokens.length; j < l; j++) {
if (blockTokens[j].type !== 'inline') { continue; }
tokens = blockTokens[j].children;
// We scan from the end, to keep position when new tags added.
for (i = tokens.length - 1; i >= 0; i--) {
token = tokens[i];
if (token.type !== 'text') { continue; }
pos = 0;
text = token.content;
reg.lastIndex = 0;
level = token.level;
nodes = [];
while ((m = reg.exec(text))) {
if (reg.lastIndex > pos) {
nodes.push({
type: 'text',
content: text.slice(pos, m.index + m[1].length),
level: level
});
}
nodes.push({
type: 'abbr_open',
title: state.env.abbreviations[':' + m[2]],
level: level++
});
nodes.push({
type: 'text',
content: m[2],
level: level
});
nodes.push({
type: 'abbr_close',
level: --level
});
pos = reg.lastIndex - m[3].length;
}
if (!nodes.length) { continue; }
if (pos < text.length) {
nodes.push({
type: 'text',
content: text.slice(pos),
level: level
});
}
// replace current node
blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes);
}
}
};