aboutsummaryrefslogtreecommitdiff
path: root/node_modules/markdown-it/lib/rules_core/linkify.js
diff options
context:
space:
mode:
authorruki <waruqi@gmail.com>2018-11-08 00:38:48 +0800
committerruki <waruqi@gmail.com>2018-11-07 21:53:09 +0800
commit26105034da4fcce7ac883c899d781f016559310d (patch)
treec459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/markdown-it/lib/rules_core/linkify.js
parent2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff)
downloadxmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz
xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip
switch to vuepress
Diffstat (limited to 'node_modules/markdown-it/lib/rules_core/linkify.js')
-rw-r--r--node_modules/markdown-it/lib/rules_core/linkify.js133
1 files changed, 133 insertions, 0 deletions
diff --git a/node_modules/markdown-it/lib/rules_core/linkify.js b/node_modules/markdown-it/lib/rules_core/linkify.js
new file mode 100644
index 00000000..7c3ffc86
--- /dev/null
+++ b/node_modules/markdown-it/lib/rules_core/linkify.js
@@ -0,0 +1,133 @@
+// Replace link-like texts with link nodes.
+//
+// Currently restricted by `md.validateLink()` to http/https/ftp
+//
+'use strict';
+
+
+var arrayReplaceAt = require('../common/utils').arrayReplaceAt;
+
+
+function isLinkOpen(str) {
+ return /^<a[>\s]/i.test(str);
+}
+function isLinkClose(str) {
+ return /^<\/a\s*>/i.test(str);
+}
+
+
+module.exports = function linkify(state) {
+ var i, j, l, tokens, token, currentToken, nodes, ln, text, pos, lastPos,
+ level, htmlLinkLevel, url, fullUrl, urlText,
+ blockTokens = state.tokens,
+ links;
+
+ if (!state.md.options.linkify) { return; }
+
+ for (j = 0, l = blockTokens.length; j < l; j++) {
+ if (blockTokens[j].type !== 'inline' ||
+ !state.md.linkify.pretest(blockTokens[j].content)) {
+ continue;
+ }
+
+ tokens = blockTokens[j].children;
+
+ htmlLinkLevel = 0;
+
+ // We scan from the end, to keep position when new tags added.
+ // Use reversed logic in links start/end match
+ for (i = tokens.length - 1; i >= 0; i--) {
+ currentToken = tokens[i];
+
+ // Skip content of markdown links
+ if (currentToken.type === 'link_close') {
+ i--;
+ while (tokens[i].level !== currentToken.level && tokens[i].type !== 'link_open') {
+ i--;
+ }
+ continue;
+ }
+
+ // Skip content of html tag links
+ if (currentToken.type === 'html_inline') {
+ if (isLinkOpen(currentToken.content) && htmlLinkLevel > 0) {
+ htmlLinkLevel--;
+ }
+ if (isLinkClose(currentToken.content)) {
+ htmlLinkLevel++;
+ }
+ }
+ if (htmlLinkLevel > 0) { continue; }
+
+ if (currentToken.type === 'text' && state.md.linkify.test(currentToken.content)) {
+
+ text = currentToken.content;
+ links = state.md.linkify.match(text);
+
+ // Now split string to nodes
+ nodes = [];
+ level = currentToken.level;
+ lastPos = 0;
+
+ for (ln = 0; ln < links.length; ln++) {
+
+ url = links[ln].url;
+ fullUrl = state.md.normalizeLink(url);
+ if (!state.md.validateLink(fullUrl)) { continue; }
+
+ urlText = links[ln].text;
+
+ // Linkifier might send raw hostnames like "example.com", where url
+ // starts with domain name. So we prepend http:// in those cases,
+ // and remove it afterwards.
+ //
+ if (!links[ln].schema) {
+ urlText = state.md.normalizeLinkText('http://' + urlText).replace(/^http:\/\//, '');
+ } else if (links[ln].schema === 'mailto:' && !/^mailto:/i.test(urlText)) {
+ urlText = state.md.normalizeLinkText('mailto:' + urlText).replace(/^mailto:/, '');
+ } else {
+ urlText = state.md.normalizeLinkText(urlText);
+ }
+
+ pos = links[ln].index;
+
+ if (pos > lastPos) {
+ token = new state.Token('text', '', 0);
+ token.content = text.slice(lastPos, pos);
+ token.level = level;
+ nodes.push(token);
+ }
+
+ token = new state.Token('link_open', 'a', 1);
+ token.attrs = [ [ 'href', fullUrl ] ];
+ token.level = level++;
+ token.markup = 'linkify';
+ token.info = 'auto';
+ nodes.push(token);
+
+ token = new state.Token('text', '', 0);
+ token.content = urlText;
+ token.level = level;
+ nodes.push(token);
+
+ token = new state.Token('link_close', 'a', -1);
+ token.level = --level;
+ token.markup = 'linkify';
+ token.info = 'auto';
+ nodes.push(token);
+
+ lastPos = links[ln].lastIndex;
+ }
+ if (lastPos < text.length) {
+ token = new state.Token('text', '', 0);
+ token.content = text.slice(lastPos);
+ token.level = level;
+ nodes.push(token);
+ }
+
+ // replace current node
+ blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes);
+ }
+ }
+ }
+};