showdown/src/subParsers/anchors.js

89 lines
3.0 KiB
JavaScript
Raw Normal View History

2015-01-16 05:21:33 +08:00
/**
* Turn Markdown link shortcuts into XHTML <a> tags.
*/
showdown.subParser('anchors', function (text, options, globals) {
2015-01-19 19:37:21 +08:00
'use strict';
text = globals.converter._dispatch('anchors.before', text, options, globals);
2015-01-19 19:37:21 +08:00
var writeAnchorTag = function (wholeMatch, m1, m2, m3, m4, m5, m6, m7) {
if (showdown.helper.isUndefined(m7)) {
m7 = '';
}
wholeMatch = m1;
var linkText = m2,
linkId = m3.toLowerCase(),
url = m4,
title = m7;
if (!url) {
if (!linkId) {
// lower-case and turn embedded newlines into spaces
linkId = linkText.toLowerCase().replace(/ ?\n/g, ' ');
}
url = '#' + linkId;
if (!showdown.helper.isUndefined(globals.gUrls[linkId])) {
url = globals.gUrls[linkId];
if (!showdown.helper.isUndefined(globals.gTitles[linkId])) {
title = globals.gTitles[linkId];
2015-01-16 05:21:33 +08:00
}
2015-01-19 19:37:21 +08:00
} else {
if (wholeMatch.search(/\(\s*\)$/m) > -1) {
// Special case for explicit empty url
url = '';
} else {
return wholeMatch;
2015-01-16 05:21:33 +08:00
}
2015-01-19 19:37:21 +08:00
}
}
//url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance
url = url.replace(showdown.helper.regexes.asteriskAndDash, showdown.helper.escapeCharactersCallback);
2015-01-19 19:37:21 +08:00
var result = '<a href="' + url + '"';
if (title !== '' && title !== null) {
title = title.replace(/"/g, '&quot;');
//title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance
title = title.replace(showdown.helper.regexes.asteriskAndDash, showdown.helper.escapeCharactersCallback);
2015-01-19 19:37:21 +08:00
result += ' title="' + title + '"';
}
result += '>' + linkText + '</a>';
return result;
};
// First, handle reference-style links: [link text] [id]
text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)][ ]?(?:\n[ ]*)?\[(.*?)])()()()()/g, writeAnchorTag);
2015-01-19 19:37:21 +08:00
// Next, inline-style links: [link text](url "optional title")
text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*()<?(.*?(?:\(.*?\).*?)?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,
2015-01-19 19:37:21 +08:00
writeAnchorTag);
// handle reference-style shortcuts: [link text]
2015-01-19 19:37:21 +08:00
// These must come last in case you've also got [link test][1]
// or [link test](/foo)
text = text.replace(/(\[([^\[\]]+)])()()()()()/g, writeAnchorTag);
2015-01-19 19:37:21 +08:00
// Lastly handle GithubMentions if option is enabled
if (options.ghMentions) {
2017-01-06 12:58:28 +08:00
text = text.replace(/(^|\s)(\\)?(@([a-z\d\-]+))(?=[.!?;,[\]()]|\s|$)/gmi, function (wm, st, escape, mentions, username) {
if (escape === '\\') {
return st + mentions;
}
//check if options.ghMentionsLink is a string
if (!showdown.helper.isString(options.ghMentionsLink)) {
throw new Error('ghMentionsLink option must be a string');
}
var lnk = options.ghMentionsLink.replace(/\{u}/g, username);
return st + '<a href="' + lnk + '">' + mentions + '</a>';
2017-01-06 12:58:28 +08:00
});
}
text = globals.converter._dispatch('anchors.after', text, options, globals);
2015-01-19 19:37:21 +08:00
return text;
2015-01-16 05:21:33 +08:00
});