Browse Source

Added autolink parse

pull/14/head
Vitaly Puzrin 10 years ago
parent
commit
0d8b010bd2
  1. 11
      lib/helpers.js
  2. 1
      lib/lexer_inline.js
  3. 57
      lib/lexer_inline/autolink.js
  4. 17
      lib/renderer.js

11
lib/helpers.js

@ -82,6 +82,16 @@ function getLines(state, begin, end, indent, keepLastLF) {
return queue.join(''); return queue.join('');
} }
function escapeHtml(str) {
if (str.indexOf('&') >= 0) { str = str.replace(/&/g, '&'); }
if (str.indexOf('<') >= 0) { str = str.replace(/</g, '&lt;'); }
if (str.indexOf('>') >= 0) { str = str.replace(/>/g, '&gt;'); }
if (str.indexOf('"') >= 0) { str = str.replace(/"/g, '&quot;'); }
return str;
}
exports.isWhiteSpace = isWhiteSpace; exports.isWhiteSpace = isWhiteSpace;
exports.isEmpty = isEmpty; exports.isEmpty = isEmpty;
exports.skipEmptyLines = skipEmptyLines; exports.skipEmptyLines = skipEmptyLines;
@ -89,3 +99,4 @@ exports.skipSpaces = skipSpaces;
exports.skipChars = skipChars; exports.skipChars = skipChars;
exports.getLines = getLines; exports.getLines = getLines;
exports.skipCharsBack = skipCharsBack; exports.skipCharsBack = skipCharsBack;
exports.escapeHtml = escapeHtml;

1
lib/lexer_inline.js

@ -17,6 +17,7 @@ rules.push(require('./lexer_inline/newline'));
rules.push(require('./lexer_inline/escape')); rules.push(require('./lexer_inline/escape'));
// //
// //
rules.push(require('./lexer_inline/autolink'));
rules.push(require('./lexer_inline/entity')); rules.push(require('./lexer_inline/entity'));
rules.push(require('./lexer_inline/escape_html_char')); rules.push(require('./lexer_inline/escape_html_char'));

57
lib/lexer_inline/autolink.js

@ -0,0 +1,57 @@
// Process autolinks '<protocol:...>'
var escape = require('../helpers').escapeHtml;
/*eslint max-len:0*/
var EMAIL_RE = /^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/;
var AUTOLINK_RE = /^<([a-zA-Z.\-]{1,15}):([^<>\x00-\x20]*)>/;
var linkPrefix = 'coap|doi|javascript|aaa|aaas|about|acap|cap|cid|crid|data|dav|dict|dns|file|ftp|geo|go|gopher|h323|http|https|iax|icap|im|imap|info|ipp|iris|iris.beep|iris.xpc|iris.xpcs|iris.lwz|ldap|mailto|mid|msrp|msrps|mtqp|mupdate|news|nfs|ni|nih|nntp|opaquelocktoken|pop|pres|rtsp|service|session|shttp|sieve|sip|sips|sms|snmp|soap.beep|soap.beeps|tag|tel|telnet|tftp|thismessage|tn3270|tip|tv|urn|vemmi|ws|wss|xcon|xcon-userid|xmlrpc.beep|xmlrpc.beeps|xmpp|z39.50r|z39.50s|adiumxtra|afp|afs|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|chrome|chrome-extension|com-eventbrite-attendee|content|cvs|dlna-playsingle|dlna-playcontainer|dtn|dvb|ed2k|facetime|feed|finger|fish|gg|git|gizmoproject|gtalk|hcp|icon|ipn|irc|irc6|ircs|itms|jar|jms|keyparc|lastfm|ldaps|magnet|maps|market|message|mms|ms-help|msnim|mumble|mvn|notes|oid|palm|paparazzi|platform|proxy|psyc|query|res|resource|rmi|rsync|rtmp|secondlife|sftp|sgn|skype|smb|soldat|spotify|ssh|steam|svn|teamspeak|things|udp|unreal|ut2004|ventrilo|view-source|webcal|wtai|wyciwyg|xfire|xri|ymsgr'.split('|');
module.exports = function autolink(state) {
var tail, linkMatch, emailMatch, pos = state.pos;
if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; }
tail = state.src.slice(pos);
if (tail.indexOf('>') < 0) { return false; }
linkMatch = tail.match(AUTOLINK_RE);
if (linkMatch) {
if (linkPrefix.indexOf(linkMatch[1]) < 0) { return false; }
state.tokens.push({
type: 'link_open',
href: escape(linkMatch[0].slice(1, -1))
});
state.tokens.push({
type: 'text',
content: escape(linkMatch[0].slice(1, -1))
});
state.tokens.push({ type: 'link_close' });
state.pos += linkMatch[0].length;
return true;
}
emailMatch = tail.match(EMAIL_RE);
if (emailMatch) {
state.tokens.push({
type: 'link_open',
href: 'mailto:' + escape(emailMatch[0].slice(1, -1))
});
state.tokens.push({
type: 'text',
content: escape(emailMatch[0].slice(1, -1))
});
state.tokens.push({ type: 'link_close' });
state.pos += emailMatch[0].length;
return true;
}
return false;
};

17
lib/renderer.js

@ -2,14 +2,7 @@
var assign = require('object-assign'); var assign = require('object-assign');
var escapeHtml = require('./helpers').escapeHtml;
function escapeHtml(str) {
return str.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
// check if we need to hide '\n' before next token // check if we need to hide '\n' before next token
@ -98,6 +91,14 @@ rules.paragraph_close = function (tokens, idx /*, options*/) {
}; };
rules.link_open = function (tokens, idx /*, options*/) {
return '<a href="' + tokens[idx].href + '">';
};
rules.link_close = function (/*tokens, idx, options*/) {
return '</a>';
};
rules.table_open = function (/*tokens, idx, options*/) { rules.table_open = function (/*tokens, idx, options*/) {
return '<table>\n'; return '<table>\n';
}; };

Loading…
Cancel
Save