|
|
@ -1,6 +1,6 @@
|
|
|
|
/*! markdown-it 13.0.1 https://github.com/markdown-it/markdown-it @license MIT */
|
|
|
|
/*! markdown-it 13.0.1 https://github.com/markdown-it/markdown-it @license MIT */
|
|
|
|
(function(global, factory) {
|
|
|
|
(function(global, factory) {
|
|
|
|
typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self,
|
|
|
|
typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self,
|
|
|
|
global.markdownit = factory());
|
|
|
|
global.markdownit = factory());
|
|
|
|
})(this, (function() {
|
|
|
|
})(this, (function() {
|
|
|
|
"use strict";
|
|
|
|
"use strict";
|
|
|
@ -2164,7 +2164,7 @@
|
|
|
|
var encodeCache = {};
|
|
|
|
var encodeCache = {};
|
|
|
|
// Create a lookup array where anything but characters in `chars` string
|
|
|
|
// Create a lookup array where anything but characters in `chars` string
|
|
|
|
// and alphanumeric chars is percent-encoded.
|
|
|
|
// and alphanumeric chars is percent-encoded.
|
|
|
|
|
|
|
|
|
|
|
|
function getEncodeCache(exclude) {
|
|
|
|
function getEncodeCache(exclude) {
|
|
|
|
var i, ch, cache = encodeCache[exclude];
|
|
|
|
var i, ch, cache = encodeCache[exclude];
|
|
|
|
if (cache) {
|
|
|
|
if (cache) {
|
|
|
@ -2187,11 +2187,11 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Encode unsafe characters with percent-encoding, skipping already
|
|
|
|
// Encode unsafe characters with percent-encoding, skipping already
|
|
|
|
// encoded sequences.
|
|
|
|
// encoded sequences.
|
|
|
|
|
|
|
|
|
|
|
|
// - string - string to encode
|
|
|
|
// - string - string to encode
|
|
|
|
// - exclude - list of characters to ignore (in addition to a-zA-Z0-9)
|
|
|
|
// - exclude - list of characters to ignore (in addition to a-zA-Z0-9)
|
|
|
|
// - keepEscaped - don't encode '%' in a correct escape sequence (default: true)
|
|
|
|
// - keepEscaped - don't encode '%' in a correct escape sequence (default: true)
|
|
|
|
|
|
|
|
|
|
|
|
function encode$2(string, exclude, keepEscaped) {
|
|
|
|
function encode$2(string, exclude, keepEscaped) {
|
|
|
|
var i, l, code, nextCode, cache, result = "";
|
|
|
|
var i, l, code, nextCode, cache, result = "";
|
|
|
|
if (typeof exclude !== "string") {
|
|
|
|
if (typeof exclude !== "string") {
|
|
|
@ -2253,7 +2253,7 @@
|
|
|
|
return cache;
|
|
|
|
return cache;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Decode percent-encoded string.
|
|
|
|
// Decode percent-encoded string.
|
|
|
|
|
|
|
|
|
|
|
|
function decode$2(string, exclude) {
|
|
|
|
function decode$2(string, exclude) {
|
|
|
|
var cache;
|
|
|
|
var cache;
|
|
|
|
if (typeof exclude !== "string") {
|
|
|
|
if (typeof exclude !== "string") {
|
|
|
@ -2340,26 +2340,26 @@
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
|
|
// Copyright Joyent, Inc. and other Node contributors.
|
|
|
|
|
|
|
|
|
|
|
|
// Changes from joyent/node:
|
|
|
|
// Changes from joyent/node:
|
|
|
|
|
|
|
|
|
|
|
|
// 1. No leading slash in paths,
|
|
|
|
// 1. No leading slash in paths,
|
|
|
|
// e.g. in `url.parse('http://foo?bar')` pathname is ``, not `/`
|
|
|
|
// e.g. in `url.parse('http://foo?bar')` pathname is ``, not `/`
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Backslashes are not replaced with slashes,
|
|
|
|
// 2. Backslashes are not replaced with slashes,
|
|
|
|
// so `http:\\example.org\` is treated like a relative path
|
|
|
|
// so `http:\\example.org\` is treated like a relative path
|
|
|
|
|
|
|
|
|
|
|
|
// 3. Trailing colon is treated like a part of the path,
|
|
|
|
// 3. Trailing colon is treated like a part of the path,
|
|
|
|
// i.e. in `http://example.org:foo` pathname is `:foo`
|
|
|
|
// i.e. in `http://example.org:foo` pathname is `:foo`
|
|
|
|
|
|
|
|
|
|
|
|
// 4. Nothing is URL-encoded in the resulting object,
|
|
|
|
// 4. Nothing is URL-encoded in the resulting object,
|
|
|
|
// (in joyent/node some chars in auth and paths are encoded)
|
|
|
|
// (in joyent/node some chars in auth and paths are encoded)
|
|
|
|
|
|
|
|
|
|
|
|
// 5. `url.parse()` does not have `parseQueryString` argument
|
|
|
|
// 5. `url.parse()` does not have `parseQueryString` argument
|
|
|
|
|
|
|
|
|
|
|
|
// 6. Removed extraneous result properties: `host`, `path`, `query`, etc.,
|
|
|
|
// 6. Removed extraneous result properties: `host`, `path`, `query`, etc.,
|
|
|
|
// which can be constructed using other parts of the url.
|
|
|
|
// which can be constructed using other parts of the url.
|
|
|
|
|
|
|
|
|
|
|
|
function Url() {
|
|
|
|
function Url() {
|
|
|
|
this.protocol = null;
|
|
|
|
this.protocol = null;
|
|
|
|
this.slashes = null;
|
|
|
|
this.slashes = null;
|
|
|
@ -2373,28 +2373,28 @@
|
|
|
|
// Reference: RFC 3986, RFC 1808, RFC 2396
|
|
|
|
// Reference: RFC 3986, RFC 1808, RFC 2396
|
|
|
|
// define these here so at least they only have to be
|
|
|
|
// define these here so at least they only have to be
|
|
|
|
// compiled once on the first module load.
|
|
|
|
// compiled once on the first module load.
|
|
|
|
var protocolPattern = /^([a-z0-9.+-]+:)/i, portPattern = /:[0-9]*$/,
|
|
|
|
var protocolPattern = /^([a-z0-9.+-]+:)/i, portPattern = /:[0-9]*$/,
|
|
|
|
// Special case for a simple path URL
|
|
|
|
// Special case for a simple path URL
|
|
|
|
simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
|
|
|
|
simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
|
|
|
|
// RFC 2396: characters reserved for delimiting URLs.
|
|
|
|
// RFC 2396: characters reserved for delimiting URLs.
|
|
|
|
// We actually just auto-escape these.
|
|
|
|
// We actually just auto-escape these.
|
|
|
|
delims = [ "<", ">", '"', "`", " ", "\r", "\n", "\t" ],
|
|
|
|
delims = [ "<", ">", '"', "`", " ", "\r", "\n", "\t" ],
|
|
|
|
// RFC 2396: characters not allowed for various reasons.
|
|
|
|
// RFC 2396: characters not allowed for various reasons.
|
|
|
|
unwise = [ "{", "}", "|", "\\", "^", "`" ].concat(delims),
|
|
|
|
unwise = [ "{", "}", "|", "\\", "^", "`" ].concat(delims),
|
|
|
|
// Allowed by RFCs, but cause of XSS attacks. Always escape these.
|
|
|
|
// Allowed by RFCs, but cause of XSS attacks. Always escape these.
|
|
|
|
autoEscape = [ "'" ].concat(unwise),
|
|
|
|
autoEscape = [ "'" ].concat(unwise),
|
|
|
|
// Characters that are never ever allowed in a hostname.
|
|
|
|
// Characters that are never ever allowed in a hostname.
|
|
|
|
// Note that any invalid chars are also handled, but these
|
|
|
|
// Note that any invalid chars are also handled, but these
|
|
|
|
// are the ones that are *expected* to be seen, so we fast-path
|
|
|
|
// are the ones that are *expected* to be seen, so we fast-path
|
|
|
|
// them.
|
|
|
|
// them.
|
|
|
|
nonHostChars = [ "%", "/", "?", ";", "#" ].concat(autoEscape), hostEndingChars = [ "/", "?", "#" ], hostnameMaxLen = 255, hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
|
|
|
|
nonHostChars = [ "%", "/", "?", ";", "#" ].concat(autoEscape), hostEndingChars = [ "/", "?", "#" ], hostnameMaxLen = 255, hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
|
|
|
|
// protocols that can allow "unsafe" and "unwise" chars.
|
|
|
|
// protocols that can allow "unsafe" and "unwise" chars.
|
|
|
|
/* eslint-disable no-script-url */
|
|
|
|
/* eslint-disable no-script-url */
|
|
|
|
// protocols that never have a hostname.
|
|
|
|
// protocols that never have a hostname.
|
|
|
|
hostlessProtocol = {
|
|
|
|
hostlessProtocol = {
|
|
|
|
javascript: true,
|
|
|
|
javascript: true,
|
|
|
|
"javascript:": true
|
|
|
|
"javascript:": true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// protocols that always contain a // bit.
|
|
|
|
// protocols that always contain a // bit.
|
|
|
|
slashedProtocol = {
|
|
|
|
slashedProtocol = {
|
|
|
|
http: true,
|
|
|
|
http: true,
|
|
|
@ -2632,7 +2632,7 @@
|
|
|
|
return _hasOwnProperty.call(object, key);
|
|
|
|
return _hasOwnProperty.call(object, key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Merge objects
|
|
|
|
// Merge objects
|
|
|
|
|
|
|
|
|
|
|
|
function assign(obj /*from1, from2, from3, ...*/) {
|
|
|
|
function assign(obj /*from1, from2, from3, ...*/) {
|
|
|
|
var sources = Array.prototype.slice.call(arguments, 1);
|
|
|
|
var sources = Array.prototype.slice.call(arguments, 1);
|
|
|
|
sources.forEach((function(source) {
|
|
|
|
sources.forEach((function(source) {
|
|
|
@ -2798,12 +2798,12 @@
|
|
|
|
return regex$4.test(ch);
|
|
|
|
return regex$4.test(ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Markdown ASCII punctuation characters.
|
|
|
|
// Markdown ASCII punctuation characters.
|
|
|
|
|
|
|
|
|
|
|
|
// !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, or ~
|
|
|
|
// !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, or ~
|
|
|
|
// http://spec.commonmark.org/0.15/#ascii-punctuation-character
|
|
|
|
// http://spec.commonmark.org/0.15/#ascii-punctuation-character
|
|
|
|
|
|
|
|
|
|
|
|
// Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.
|
|
|
|
// Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.
|
|
|
|
|
|
|
|
|
|
|
|
function isMdAsciiPunct(ch) {
|
|
|
|
function isMdAsciiPunct(ch) {
|
|
|
|
switch (ch) {
|
|
|
|
switch (ch) {
|
|
|
|
case 33 /* ! */ :
|
|
|
|
case 33 /* ! */ :
|
|
|
@ -2845,58 +2845,58 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Hepler to unify [reference labels].
|
|
|
|
// Hepler to unify [reference labels].
|
|
|
|
|
|
|
|
|
|
|
|
function normalizeReference(str) {
|
|
|
|
function normalizeReference(str) {
|
|
|
|
// Trim and collapse whitespace
|
|
|
|
// Trim and collapse whitespace
|
|
|
|
str = str.trim().replace(/\s+/g, " ");
|
|
|
|
str = str.trim().replace(/\s+/g, " ");
|
|
|
|
// In node v10 'ẞ'.toLowerCase() === 'Ṿ', which is presumed to be a bug
|
|
|
|
// In node v10 'ẞ'.toLowerCase() === 'Ṿ', which is presumed to be a bug
|
|
|
|
// fixed in v12 (couldn't find any details).
|
|
|
|
// fixed in v12 (couldn't find any details).
|
|
|
|
|
|
|
|
|
|
|
|
// So treat this one as a special case
|
|
|
|
// So treat this one as a special case
|
|
|
|
// (remove this when node v10 is no longer supported).
|
|
|
|
// (remove this when node v10 is no longer supported).
|
|
|
|
|
|
|
|
|
|
|
|
if ("\u1e9e".toLowerCase() === "\u1e7e") {
|
|
|
|
if ("\u1e9e".toLowerCase() === "\u1e7e") {
|
|
|
|
str = str.replace(/\u1e9e/g, "\xdf");
|
|
|
|
str = str.replace(/\u1e9e/g, "\xdf");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// .toLowerCase().toUpperCase() should get rid of all differences
|
|
|
|
// .toLowerCase().toUpperCase() should get rid of all differences
|
|
|
|
// between letter variants.
|
|
|
|
// between letter variants.
|
|
|
|
|
|
|
|
|
|
|
|
// Simple .toLowerCase() doesn't normalize 125 code points correctly,
|
|
|
|
// Simple .toLowerCase() doesn't normalize 125 code points correctly,
|
|
|
|
// and .toUpperCase doesn't normalize 6 of them (list of exceptions:
|
|
|
|
// and .toUpperCase doesn't normalize 6 of them (list of exceptions:
|
|
|
|
// İ, ϴ, ẞ, Ω, K, Å - those are already uppercased, but have differently
|
|
|
|
// İ, ϴ, ẞ, Ω, K, Å - those are already uppercased, but have differently
|
|
|
|
// uppercased versions).
|
|
|
|
// uppercased versions).
|
|
|
|
|
|
|
|
|
|
|
|
// Here's an example showing how it happens. Lets take greek letter omega:
|
|
|
|
// Here's an example showing how it happens. Lets take greek letter omega:
|
|
|
|
// uppercase U+0398 (Θ), U+03f4 (ϴ) and lowercase U+03b8 (θ), U+03d1 (ϑ)
|
|
|
|
// uppercase U+0398 (Θ), U+03f4 (ϴ) and lowercase U+03b8 (θ), U+03d1 (ϑ)
|
|
|
|
|
|
|
|
|
|
|
|
// Unicode entries:
|
|
|
|
// Unicode entries:
|
|
|
|
// 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;
|
|
|
|
// 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;
|
|
|
|
// 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398
|
|
|
|
// 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398
|
|
|
|
// 03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398
|
|
|
|
// 03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398
|
|
|
|
// 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;
|
|
|
|
// 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;
|
|
|
|
|
|
|
|
|
|
|
|
// Case-insensitive comparison should treat all of them as equivalent.
|
|
|
|
// Case-insensitive comparison should treat all of them as equivalent.
|
|
|
|
|
|
|
|
|
|
|
|
// But .toLowerCase() doesn't change ϑ (it's already lowercase),
|
|
|
|
// But .toLowerCase() doesn't change ϑ (it's already lowercase),
|
|
|
|
// and .toUpperCase() doesn't change ϴ (already uppercase).
|
|
|
|
// and .toUpperCase() doesn't change ϴ (already uppercase).
|
|
|
|
|
|
|
|
|
|
|
|
// Applying first lower then upper case normalizes any character:
|
|
|
|
// Applying first lower then upper case normalizes any character:
|
|
|
|
// '\u0398\u03f4\u03b8\u03d1'.toLowerCase().toUpperCase() === '\u0398\u0398\u0398\u0398'
|
|
|
|
// '\u0398\u03f4\u03b8\u03d1'.toLowerCase().toUpperCase() === '\u0398\u0398\u0398\u0398'
|
|
|
|
|
|
|
|
|
|
|
|
// Note: this is equivalent to unicode case folding; unicode normalization
|
|
|
|
// Note: this is equivalent to unicode case folding; unicode normalization
|
|
|
|
// is a different step that is not required here.
|
|
|
|
// is a different step that is not required here.
|
|
|
|
|
|
|
|
|
|
|
|
// Final result should be uppercased, because it's later stored in an object
|
|
|
|
// Final result should be uppercased, because it's later stored in an object
|
|
|
|
// (this avoid a conflict with Object.prototype members,
|
|
|
|
// (this avoid a conflict with Object.prototype members,
|
|
|
|
// most notably, `__proto__`)
|
|
|
|
// most notably, `__proto__`)
|
|
|
|
|
|
|
|
|
|
|
|
return str.toLowerCase().toUpperCase();
|
|
|
|
return str.toLowerCase().toUpperCase();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Re-export libraries commonly used in both markdown-it and its plugins,
|
|
|
|
// Re-export libraries commonly used in both markdown-it and its plugins,
|
|
|
|
// so plugins won't have to depend on them explicitly, which reduces their
|
|
|
|
// so plugins won't have to depend on them explicitly, which reduces their
|
|
|
|
// bundled size (e.g. a browser build).
|
|
|
|
// bundled size (e.g. a browser build).
|
|
|
|
|
|
|
|
|
|
|
|
exports.lib = {};
|
|
|
|
exports.lib = {};
|
|
|
|
exports.lib.mdurl = mdurl;
|
|
|
|
exports.lib.mdurl = mdurl;
|
|
|
|
exports.lib.ucmicro = uc_micro;
|
|
|
|
exports.lib.ucmicro = uc_micro;
|
|
|
@ -3129,7 +3129,7 @@
|
|
|
|
var token = tokens[idx];
|
|
|
|
var token = tokens[idx];
|
|
|
|
// "alt" attr MUST be set, even if empty. Because it's mandatory and
|
|
|
|
// "alt" attr MUST be set, even if empty. Because it's mandatory and
|
|
|
|
// should be placed on proper position for tests.
|
|
|
|
// should be placed on proper position for tests.
|
|
|
|
|
|
|
|
|
|
|
|
// Replace content with actual value
|
|
|
|
// Replace content with actual value
|
|
|
|
token.attrs[token.attrIndex("alt")][1] = slf.renderInlineAsText(token.children, options, env);
|
|
|
|
token.attrs[token.attrIndex("alt")][1] = slf.renderInlineAsText(token.children, options, env);
|
|
|
|
return slf.renderToken(tokens, idx, options);
|
|
|
|
return slf.renderToken(tokens, idx, options);
|
|
|
@ -3215,11 +3215,11 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Insert a newline between hidden paragraph and subsequent opening
|
|
|
|
// Insert a newline between hidden paragraph and subsequent opening
|
|
|
|
// block-level tag.
|
|
|
|
// block-level tag.
|
|
|
|
|
|
|
|
|
|
|
|
// For example, here we should insert a newline before blockquote:
|
|
|
|
// For example, here we should insert a newline before blockquote:
|
|
|
|
// - a
|
|
|
|
// - a
|
|
|
|
// >
|
|
|
|
// >
|
|
|
|
|
|
|
|
|
|
|
|
if (token.block && token.nesting !== -1 && idx && tokens[idx - 1].hidden) {
|
|
|
|
if (token.block && token.nesting !== -1 && idx && tokens[idx - 1].hidden) {
|
|
|
|
result += "\n";
|
|
|
|
result += "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3343,16 +3343,16 @@
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
this.__rules__ = [];
|
|
|
|
this.__rules__ = [];
|
|
|
|
// Cached rule chains.
|
|
|
|
// Cached rule chains.
|
|
|
|
|
|
|
|
|
|
|
|
// First level - chain name, '' for default.
|
|
|
|
// First level - chain name, '' for default.
|
|
|
|
// Second level - diginal anchor for fast filtering by charcodes.
|
|
|
|
// Second level - diginal anchor for fast filtering by charcodes.
|
|
|
|
|
|
|
|
|
|
|
|
this.__cache__ = null;
|
|
|
|
this.__cache__ = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Helper methods, should not be used directly
|
|
|
|
// Helper methods, should not be used directly
|
|
|
|
// Find rule index by name
|
|
|
|
// Find rule index by name
|
|
|
|
|
|
|
|
|
|
|
|
Ruler.prototype.__find__ = function(name) {
|
|
|
|
Ruler.prototype.__find__ = function(name) {
|
|
|
|
for (var i = 0; i < this.__rules__.length; i++) {
|
|
|
|
for (var i = 0; i < this.__rules__.length; i++) {
|
|
|
|
if (this.__rules__[i].name === name) {
|
|
|
|
if (this.__rules__[i].name === name) {
|
|
|
@ -3362,7 +3362,7 @@
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Build rules lookup cache
|
|
|
|
// Build rules lookup cache
|
|
|
|
|
|
|
|
|
|
|
|
Ruler.prototype.__compile__ = function() {
|
|
|
|
Ruler.prototype.__compile__ = function() {
|
|
|
|
var self = this;
|
|
|
|
var self = this;
|
|
|
|
var chains = [ "" ];
|
|
|
|
var chains = [ "" ];
|
|
|
@ -3726,7 +3726,7 @@
|
|
|
|
// Linkifier might send raw hostnames like "example.com", where url
|
|
|
|
// Linkifier might send raw hostnames like "example.com", where url
|
|
|
|
// starts with domain name. So we prepend http:// in those cases,
|
|
|
|
// starts with domain name. So we prepend http:// in those cases,
|
|
|
|
// and remove it afterwards.
|
|
|
|
// and remove it afterwards.
|
|
|
|
|
|
|
|
|
|
|
|
if (!links[ln].schema) {
|
|
|
|
if (!links[ln].schema) {
|
|
|
|
urlText = state.md.normalizeLinkText("http://" + urlText).replace(/^http:\/\//, "");
|
|
|
|
urlText = state.md.normalizeLinkText("http://" + urlText).replace(/^http:\/\//, "");
|
|
|
|
} else if (links[ln].schema === "mailto:" && !/^mailto:/i.test(urlText)) {
|
|
|
|
} else if (links[ln].schema === "mailto:" && !/^mailto:/i.test(urlText)) {
|
|
|
@ -3874,7 +3874,7 @@
|
|
|
|
isSingle = t[0] === "'";
|
|
|
|
isSingle = t[0] === "'";
|
|
|
|
// Find previous character,
|
|
|
|
// Find previous character,
|
|
|
|
// default to space if it's the beginning of the line
|
|
|
|
// default to space if it's the beginning of the line
|
|
|
|
|
|
|
|
|
|
|
|
lastChar = 32;
|
|
|
|
lastChar = 32;
|
|
|
|
if (t.index - 1 >= 0) {
|
|
|
|
if (t.index - 1 >= 0) {
|
|
|
|
lastChar = text.charCodeAt(t.index - 1);
|
|
|
|
lastChar = text.charCodeAt(t.index - 1);
|
|
|
@ -3890,7 +3890,7 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Find next character,
|
|
|
|
// Find next character,
|
|
|
|
// default to space if it's the end of the line
|
|
|
|
// default to space if it's the end of the line
|
|
|
|
|
|
|
|
|
|
|
|
nextChar = 32;
|
|
|
|
nextChar = 32;
|
|
|
|
if (pos < max) {
|
|
|
|
if (pos < max) {
|
|
|
|
nextChar = text.charCodeAt(pos);
|
|
|
|
nextChar = text.charCodeAt(pos);
|
|
|
@ -4193,7 +4193,7 @@
|
|
|
|
// re-export Token class to use in core rules
|
|
|
|
// re-export Token class to use in core rules
|
|
|
|
StateCore.prototype.Token = token;
|
|
|
|
StateCore.prototype.Token = token;
|
|
|
|
var state_core = StateCore;
|
|
|
|
var state_core = StateCore;
|
|
|
|
var _rules$2 = [ [ "normalize", normalize ], [ "block", block ], [ "inline", inline ], [ "linkify", linkify$1 ], [ "replacements", replacements ], [ "smartquotes", smartquotes ],
|
|
|
|
var _rules$2 = [ [ "normalize", normalize ], [ "block", block ], [ "inline", inline ], [ "linkify", linkify$1 ], [ "replacements", replacements ], [ "smartquotes", smartquotes ],
|
|
|
|
// `text_join` finds `text_special` tokens (for escape sequences)
|
|
|
|
// `text_join` finds `text_special` tokens (for escape sequences)
|
|
|
|
// and joins them with the rest of the text
|
|
|
|
// and joins them with the rest of the text
|
|
|
|
[ "text_join", text_join ] ];
|
|
|
|
[ "text_join", text_join ] ];
|
|
|
@ -4590,12 +4590,12 @@
|
|
|
|
oldParentType = state.parentType;
|
|
|
|
oldParentType = state.parentType;
|
|
|
|
state.parentType = "blockquote";
|
|
|
|
state.parentType = "blockquote";
|
|
|
|
// Search the end of the block
|
|
|
|
// Search the end of the block
|
|
|
|
|
|
|
|
|
|
|
|
// Block ends with either:
|
|
|
|
// Block ends with either:
|
|
|
|
// 1. an empty line outside:
|
|
|
|
// 1. an empty line outside:
|
|
|
|
// ```
|
|
|
|
// ```
|
|
|
|
// > test
|
|
|
|
// > test
|
|
|
|
|
|
|
|
|
|
|
|
// ```
|
|
|
|
// ```
|
|
|
|
// 2. an empty line inside:
|
|
|
|
// 2. an empty line inside:
|
|
|
|
// ```
|
|
|
|
// ```
|
|
|
@ -4712,7 +4712,7 @@
|
|
|
|
oldTShift.push(state.tShift[nextLine]);
|
|
|
|
oldTShift.push(state.tShift[nextLine]);
|
|
|
|
oldSCount.push(state.sCount[nextLine]);
|
|
|
|
oldSCount.push(state.sCount[nextLine]);
|
|
|
|
// A negative indentation means that this is a paragraph continuation
|
|
|
|
// A negative indentation means that this is a paragraph continuation
|
|
|
|
|
|
|
|
|
|
|
|
state.sCount[nextLine] = -1;
|
|
|
|
state.sCount[nextLine] = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
oldIndent = state.blkIndent;
|
|
|
|
oldIndent = state.blkIndent;
|
|
|
@ -4905,9 +4905,9 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
token.map = listLines = [ startLine, 0 ];
|
|
|
|
token.map = listLines = [ startLine, 0 ];
|
|
|
|
token.markup = String.fromCharCode(markerCharCode);
|
|
|
|
token.markup = String.fromCharCode(markerCharCode);
|
|
|
|
|
|
|
|
|
|
|
|
// Iterate list items
|
|
|
|
// Iterate list items
|
|
|
|
|
|
|
|
|
|
|
|
nextLine = startLine;
|
|
|
|
nextLine = startLine;
|
|
|
|
prevEmptyEnd = false;
|
|
|
|
prevEmptyEnd = false;
|
|
|
|
terminatorRules = state.md.block.ruler.getRules("list");
|
|
|
|
terminatorRules = state.md.block.ruler.getRules("list");
|
|
|
@ -4957,7 +4957,7 @@
|
|
|
|
// - example list
|
|
|
|
// - example list
|
|
|
|
// ^ listIndent position will be here
|
|
|
|
// ^ listIndent position will be here
|
|
|
|
// ^ blkIndent position will be here
|
|
|
|
// ^ blkIndent position will be here
|
|
|
|
|
|
|
|
|
|
|
|
oldListIndent = state.listIndent;
|
|
|
|
oldListIndent = state.listIndent;
|
|
|
|
state.listIndent = state.blkIndent;
|
|
|
|
state.listIndent = state.blkIndent;
|
|
|
|
state.blkIndent = indent;
|
|
|
|
state.blkIndent = indent;
|
|
|
@ -4995,9 +4995,9 @@
|
|
|
|
if (nextLine >= endLine) {
|
|
|
|
if (nextLine >= endLine) {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Try to check if list is terminated or continued.
|
|
|
|
// Try to check if list is terminated or continued.
|
|
|
|
|
|
|
|
|
|
|
|
if (state.sCount[nextLine] < state.blkIndent) {
|
|
|
|
if (state.sCount[nextLine] < state.blkIndent) {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -5245,7 +5245,7 @@
|
|
|
|
var HTML_OPEN_CLOSE_TAG_RE = html_re.HTML_OPEN_CLOSE_TAG_RE;
|
|
|
|
var HTML_OPEN_CLOSE_TAG_RE = html_re.HTML_OPEN_CLOSE_TAG_RE;
|
|
|
|
// An array of opening and corresponding closing sequences for html tags,
|
|
|
|
// An array of opening and corresponding closing sequences for html tags,
|
|
|
|
// last argument defines whether it can terminate a paragraph or not
|
|
|
|
// last argument defines whether it can terminate a paragraph or not
|
|
|
|
|
|
|
|
|
|
|
|
var HTML_SEQUENCES = [ [ /^<(script|pre|style|textarea)(?=(\s|>|$))/i, /<\/(script|pre|style|textarea)>/i, true ], [ /^<!--/, /-->/, true ], [ /^<\?/, /\?>/, true ], [ /^<![A-Z]/, />/, true ], [ /^<!\[CDATA\[/, /\]\]>/, true ], [ new RegExp("^</?(" + html_blocks.join("|") + ")(?=(\\s|/?>|$))", "i"), /^$/, true ], [ new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + "\\s*$"), /^$/, false ] ];
|
|
|
|
var HTML_SEQUENCES = [ [ /^<(script|pre|style|textarea)(?=(\s|>|$))/i, /<\/(script|pre|style|textarea)>/i, true ], [ /^<!--/, /-->/, true ], [ /^<\?/, /\?>/, true ], [ /^<![A-Z]/, />/, true ], [ /^<!\[CDATA\[/, /\]\]>/, true ], [ new RegExp("^</?(" + html_blocks.join("|") + ")(?=(\\s|/?>|$))", "i"), /^$/, true ], [ new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + "\\s*$"), /^$/, false ] ];
|
|
|
|
var html_block = function html_block(state, startLine, endLine, silent) {
|
|
|
|
var html_block = function html_block(state, startLine, endLine, silent) {
|
|
|
|
var i, nextLine, token, lineText, pos = state.bMarks[startLine] + state.tShift[startLine], max = state.eMarks[startLine];
|
|
|
|
var i, nextLine, token, lineText, pos = state.bMarks[startLine] + state.tShift[startLine], max = state.eMarks[startLine];
|
|
|
@ -5357,9 +5357,9 @@
|
|
|
|
if (state.sCount[nextLine] - state.blkIndent > 3) {
|
|
|
|
if (state.sCount[nextLine] - state.blkIndent > 3) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check for underline in setext header
|
|
|
|
// Check for underline in setext header
|
|
|
|
|
|
|
|
|
|
|
|
if (state.sCount[nextLine] >= state.blkIndent) {
|
|
|
|
if (state.sCount[nextLine] >= state.blkIndent) {
|
|
|
|
pos = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
|
|
pos = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
|
|
max = state.eMarks[nextLine];
|
|
|
|
max = state.eMarks[nextLine];
|
|
|
@ -5456,9 +5456,9 @@
|
|
|
|
// link to parser instance
|
|
|
|
// link to parser instance
|
|
|
|
this.md = md;
|
|
|
|
this.md = md;
|
|
|
|
this.env = env;
|
|
|
|
this.env = env;
|
|
|
|
|
|
|
|
|
|
|
|
// Internal state vartiables
|
|
|
|
// Internal state vartiables
|
|
|
|
|
|
|
|
|
|
|
|
this.tokens = tokens;
|
|
|
|
this.tokens = tokens;
|
|
|
|
this.bMarks = [];
|
|
|
|
this.bMarks = [];
|
|
|
|
// line begin offsets for fast jumps
|
|
|
|
// line begin offsets for fast jumps
|
|
|
@ -5470,14 +5470,14 @@
|
|
|
|
// indents for each line (tabs expanded)
|
|
|
|
// indents for each line (tabs expanded)
|
|
|
|
// An amount of virtual spaces (tabs expanded) between beginning
|
|
|
|
// An amount of virtual spaces (tabs expanded) between beginning
|
|
|
|
// of each line (bMarks) and real beginning of that line.
|
|
|
|
// of each line (bMarks) and real beginning of that line.
|
|
|
|
|
|
|
|
|
|
|
|
// It exists only as a hack because blockquotes override bMarks
|
|
|
|
// It exists only as a hack because blockquotes override bMarks
|
|
|
|
// losing information in the process.
|
|
|
|
// losing information in the process.
|
|
|
|
|
|
|
|
|
|
|
|
// It's used only when expanding tabs, you can think about it as
|
|
|
|
// It's used only when expanding tabs, you can think about it as
|
|
|
|
// an initial tab length, e.g. bsCount=21 applied to string `\t123`
|
|
|
|
// an initial tab length, e.g. bsCount=21 applied to string `\t123`
|
|
|
|
// means first tab should be expanded to 4-21%4 === 3 spaces.
|
|
|
|
// means first tab should be expanded to 4-21%4 === 3 spaces.
|
|
|
|
|
|
|
|
|
|
|
|
this.bsCount = [];
|
|
|
|
this.bsCount = [];
|
|
|
|
// block parser variables
|
|
|
|
// block parser variables
|
|
|
|
this.blkIndent = 0;
|
|
|
|
this.blkIndent = 0;
|
|
|
@ -5543,7 +5543,7 @@
|
|
|
|
// don't count last fake line
|
|
|
|
// don't count last fake line
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Push new token to "stream".
|
|
|
|
// Push new token to "stream".
|
|
|
|
|
|
|
|
|
|
|
|
StateBlock.prototype.push = function(type, tag, nesting) {
|
|
|
|
StateBlock.prototype.push = function(type, tag, nesting) {
|
|
|
|
var token$1 = new token(type, tag, nesting);
|
|
|
|
var token$1 = new token(type, tag, nesting);
|
|
|
|
token$1.block = true;
|
|
|
|
token$1.block = true;
|
|
|
@ -5655,7 +5655,7 @@
|
|
|
|
// re-export Token class to use in block rules
|
|
|
|
// re-export Token class to use in block rules
|
|
|
|
StateBlock.prototype.Token = token;
|
|
|
|
StateBlock.prototype.Token = token;
|
|
|
|
var state_block = StateBlock;
|
|
|
|
var state_block = StateBlock;
|
|
|
|
var _rules$1 = [
|
|
|
|
var _rules$1 = [
|
|
|
|
// First 2 params - rule name & source. Secondary array - list of rules,
|
|
|
|
// First 2 params - rule name & source. Secondary array - list of rules,
|
|
|
|
// which can be terminated by this one.
|
|
|
|
// which can be terminated by this one.
|
|
|
|
[ "table", table, [ "paragraph", "reference" ] ], [ "code", code ], [ "fence", fence, [ "paragraph", "reference", "blockquote", "list" ] ], [ "blockquote", blockquote, [ "paragraph", "reference", "blockquote", "list" ] ], [ "hr", hr, [ "paragraph", "reference", "blockquote", "list" ] ], [ "list", list, [ "paragraph", "reference", "blockquote" ] ], [ "reference", reference ], [ "html_block", html_block, [ "paragraph", "reference", "blockquote" ] ], [ "heading", heading, [ "paragraph", "reference", "blockquote" ] ], [ "lheading", lheading ], [ "paragraph", paragraph ] ];
|
|
|
|
[ "table", table, [ "paragraph", "reference" ] ], [ "code", code ], [ "fence", fence, [ "paragraph", "reference", "blockquote", "list" ] ], [ "blockquote", blockquote, [ "paragraph", "reference", "blockquote", "list" ] ], [ "hr", hr, [ "paragraph", "reference", "blockquote", "list" ] ], [ "list", list, [ "paragraph", "reference", "blockquote" ] ], [ "reference", reference ], [ "html_block", html_block, [ "paragraph", "reference", "blockquote" ] ], [ "heading", heading, [ "paragraph", "reference", "blockquote" ] ], [ "lheading", lheading ], [ "paragraph", paragraph ] ];
|
|
|
@ -5675,7 +5675,7 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Generate tokens for input range
|
|
|
|
// Generate tokens for input range
|
|
|
|
|
|
|
|
|
|
|
|
ParserBlock.prototype.tokenize = function(state, startLine, endLine) {
|
|
|
|
ParserBlock.prototype.tokenize = function(state, startLine, endLine) {
|
|
|
|
var ok, i, rules = this.ruler.getRules(""), len = rules.length, line = startLine, hasEmptyLines = false, maxNesting = state.md.options.maxNesting;
|
|
|
|
var ok, i, rules = this.ruler.getRules(""), len = rules.length, line = startLine, hasEmptyLines = false, maxNesting = state.md.options.maxNesting;
|
|
|
|
while (line < endLine) {
|
|
|
|
while (line < endLine) {
|
|
|
@ -5696,7 +5696,7 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Try all possible rules.
|
|
|
|
// Try all possible rules.
|
|
|
|
// On success, rule should:
|
|
|
|
// On success, rule should:
|
|
|
|
|
|
|
|
|
|
|
|
// - update `state.line`
|
|
|
|
// - update `state.line`
|
|
|
|
// - update `state.tokens`
|
|
|
|
// - update `state.tokens`
|
|
|
|
// - return true
|
|
|
|
// - return true
|
|
|
@ -5961,7 +5961,7 @@
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// ~~strike through~~
|
|
|
|
// ~~strike through~~
|
|
|
|
// Insert each marker as a separate text token, and add it to delimiter list
|
|
|
|
// Insert each marker as a separate text token, and add it to delimiter list
|
|
|
|
|
|
|
|
|
|
|
|
var tokenize$1 = function strikethrough(state, silent) {
|
|
|
|
var tokenize$1 = function strikethrough(state, silent) {
|
|
|
|
var i, scanned, token, len, ch, start = state.pos, marker = state.src.charCodeAt(start);
|
|
|
|
var i, scanned, token, len, ch, start = state.pos, marker = state.src.charCodeAt(start);
|
|
|
|
if (silent) {
|
|
|
|
if (silent) {
|
|
|
@ -6027,9 +6027,9 @@
|
|
|
|
// If a marker sequence has an odd number of characters, it's splitted
|
|
|
|
// If a marker sequence has an odd number of characters, it's splitted
|
|
|
|
// like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the
|
|
|
|
// like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the
|
|
|
|
// start of the sequence.
|
|
|
|
// start of the sequence.
|
|
|
|
|
|
|
|
|
|
|
|
// So, we have to move all those markers after subsequent s_close tags.
|
|
|
|
// So, we have to move all those markers after subsequent s_close tags.
|
|
|
|
|
|
|
|
|
|
|
|
while (loneMarkers.length) {
|
|
|
|
while (loneMarkers.length) {
|
|
|
|
i = loneMarkers.pop();
|
|
|
|
i = loneMarkers.pop();
|
|
|
|
j = i + 1;
|
|
|
|
j = i + 1;
|
|
|
@ -6045,7 +6045,7 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Walk through delimiter list and replace text tokens with tags
|
|
|
|
// Walk through delimiter list and replace text tokens with tags
|
|
|
|
|
|
|
|
|
|
|
|
var postProcess_1$1 = function strikethrough(state) {
|
|
|
|
var postProcess_1$1 = function strikethrough(state) {
|
|
|
|
var curr, tokens_meta = state.tokens_meta, max = state.tokens_meta.length;
|
|
|
|
var curr, tokens_meta = state.tokens_meta, max = state.tokens_meta.length;
|
|
|
|
postProcess$1(state, state.delimiters);
|
|
|
|
postProcess$1(state, state.delimiters);
|
|
|
@ -6061,7 +6061,7 @@
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Process *this* and _that_
|
|
|
|
// Process *this* and _that_
|
|
|
|
// Insert each marker as a separate text token, and add it to delimiter list
|
|
|
|
// Insert each marker as a separate text token, and add it to delimiter list
|
|
|
|
|
|
|
|
|
|
|
|
var tokenize = function emphasis(state, silent) {
|
|
|
|
var tokenize = function emphasis(state, silent) {
|
|
|
|
var i, scanned, token, start = state.pos, marker = state.src.charCodeAt(start);
|
|
|
|
var i, scanned, token, start = state.pos, marker = state.src.charCodeAt(start);
|
|
|
|
if (silent) {
|
|
|
|
if (silent) {
|
|
|
@ -6107,12 +6107,12 @@
|
|
|
|
endDelim = delimiters[startDelim.end];
|
|
|
|
endDelim = delimiters[startDelim.end];
|
|
|
|
// If the previous delimiter has the same marker and is adjacent to this one,
|
|
|
|
// If the previous delimiter has the same marker and is adjacent to this one,
|
|
|
|
// merge those into one strong delimiter.
|
|
|
|
// merge those into one strong delimiter.
|
|
|
|
|
|
|
|
|
|
|
|
// `<em><em>whatever</em></em>` -> `<strong>whatever</strong>`
|
|
|
|
// `<em><em>whatever</em></em>` -> `<strong>whatever</strong>`
|
|
|
|
|
|
|
|
|
|
|
|
isStrong = i > 0 && delimiters[i - 1].end === startDelim.end + 1 &&
|
|
|
|
isStrong = i > 0 && delimiters[i - 1].end === startDelim.end + 1 &&
|
|
|
|
// check that first two markers match and adjacent
|
|
|
|
// check that first two markers match and adjacent
|
|
|
|
delimiters[i - 1].marker === startDelim.marker && delimiters[i - 1].token === startDelim.token - 1 &&
|
|
|
|
delimiters[i - 1].marker === startDelim.marker && delimiters[i - 1].token === startDelim.token - 1 &&
|
|
|
|
// check that last two markers are adjacent (we can safely assume they match)
|
|
|
|
// check that last two markers are adjacent (we can safely assume they match)
|
|
|
|
delimiters[startDelim.end + 1].token === endDelim.token + 1;
|
|
|
|
delimiters[startDelim.end + 1].token === endDelim.token + 1;
|
|
|
|
ch = String.fromCharCode(startDelim.marker);
|
|
|
|
ch = String.fromCharCode(startDelim.marker);
|
|
|
@ -6136,7 +6136,7 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Walk through delimiter list and replace text tokens with tags
|
|
|
|
// Walk through delimiter list and replace text tokens with tags
|
|
|
|
|
|
|
|
|
|
|
|
var postProcess_1 = function emphasis(state) {
|
|
|
|
var postProcess_1 = function emphasis(state) {
|
|
|
|
var curr, tokens_meta = state.tokens_meta, max = state.tokens_meta.length;
|
|
|
|
var curr, tokens_meta = state.tokens_meta, max = state.tokens_meta.length;
|
|
|
|
postProcess(state, state.delimiters);
|
|
|
|
postProcess(state, state.delimiters);
|
|
|
@ -6251,10 +6251,10 @@
|
|
|
|
href = ref.href;
|
|
|
|
href = ref.href;
|
|
|
|
title = ref.title;
|
|
|
|
title = ref.title;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// We found the end of the link, and know for a fact it's a valid link;
|
|
|
|
// We found the end of the link, and know for a fact it's a valid link;
|
|
|
|
// so all that's left to do is to call tokenizer.
|
|
|
|
// so all that's left to do is to call tokenizer.
|
|
|
|
|
|
|
|
|
|
|
|
if (!silent) {
|
|
|
|
if (!silent) {
|
|
|
|
state.pos = labelStart;
|
|
|
|
state.pos = labelStart;
|
|
|
|
state.posMax = labelEnd;
|
|
|
|
state.posMax = labelEnd;
|
|
|
@ -6375,10 +6375,10 @@
|
|
|
|
href = ref.href;
|
|
|
|
href = ref.href;
|
|
|
|
title = ref.title;
|
|
|
|
title = ref.title;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// We found the end of the link, and know for a fact it's a valid link;
|
|
|
|
// We found the end of the link, and know for a fact it's a valid link;
|
|
|
|
// so all that's left to do is to call tokenizer.
|
|
|
|
// so all that's left to do is to call tokenizer.
|
|
|
|
|
|
|
|
|
|
|
|
if (!silent) {
|
|
|
|
if (!silent) {
|
|
|
|
content = state.src.slice(labelStart, labelEnd);
|
|
|
|
content = state.src.slice(labelStart, labelEnd);
|
|
|
|
state.md.inline.parse(content, state.md, state.env, tokens = []);
|
|
|
|
state.md.inline.parse(content, state.md, state.env, tokens = []);
|
|
|
@ -6547,7 +6547,7 @@
|
|
|
|
// markers belong to same delimiter run if:
|
|
|
|
// markers belong to same delimiter run if:
|
|
|
|
// - they have adjacent tokens
|
|
|
|
// - they have adjacent tokens
|
|
|
|
// - AND markers are the same
|
|
|
|
// - AND markers are the same
|
|
|
|
|
|
|
|
|
|
|
|
if (delimiters[headerIdx].marker !== closer.marker || lastTokenIdx !== closer.token - 1) {
|
|
|
|
if (delimiters[headerIdx].marker !== closer.marker || lastTokenIdx !== closer.token - 1) {
|
|
|
|
headerIdx = closerIdx;
|
|
|
|
headerIdx = closerIdx;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -6555,7 +6555,7 @@
|
|
|
|
// Length is only used for emphasis-specific "rule of 3",
|
|
|
|
// Length is only used for emphasis-specific "rule of 3",
|
|
|
|
// if it's not defined (in strikethrough or 3rd party plugins),
|
|
|
|
// if it's not defined (in strikethrough or 3rd party plugins),
|
|
|
|
// we can default it to 0 to disable those checks.
|
|
|
|
// we can default it to 0 to disable those checks.
|
|
|
|
|
|
|
|
|
|
|
|
closer.length = closer.length || 0;
|
|
|
|
closer.length = closer.length || 0;
|
|
|
|
if (!closer.close) continue;
|
|
|
|
if (!closer.close) continue;
|
|
|
|
// Previously calculated lower bounds (previous fails)
|
|
|
|
// Previously calculated lower bounds (previous fails)
|
|
|
@ -6574,12 +6574,12 @@
|
|
|
|
if (opener.open && opener.end < 0) {
|
|
|
|
if (opener.open && opener.end < 0) {
|
|
|
|
isOddMatch = false;
|
|
|
|
isOddMatch = false;
|
|
|
|
// from spec:
|
|
|
|
// from spec:
|
|
|
|
|
|
|
|
|
|
|
|
// If one of the delimiters can both open and close emphasis, then the
|
|
|
|
// If one of the delimiters can both open and close emphasis, then the
|
|
|
|
// sum of the lengths of the delimiter runs containing the opening and
|
|
|
|
// sum of the lengths of the delimiter runs containing the opening and
|
|
|
|
// closing delimiters must not be a multiple of 3 unless both lengths
|
|
|
|
// closing delimiters must not be a multiple of 3 unless both lengths
|
|
|
|
// are multiples of 3.
|
|
|
|
// are multiples of 3.
|
|
|
|
|
|
|
|
|
|
|
|
if (opener.close || closer.open) {
|
|
|
|
if (opener.close || closer.open) {
|
|
|
|
if ((opener.length + closer.length) % 3 === 0) {
|
|
|
|
if ((opener.length + closer.length) % 3 === 0) {
|
|
|
|
if (opener.length % 3 !== 0 || closer.length % 3 !== 0) {
|
|
|
|
if (opener.length % 3 !== 0 || closer.length % 3 !== 0) {
|
|
|
@ -6678,7 +6678,7 @@
|
|
|
|
this.linkLevel = 0;
|
|
|
|
this.linkLevel = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Flush pending text
|
|
|
|
// Flush pending text
|
|
|
|
|
|
|
|
|
|
|
|
StateInline.prototype.pushPending = function() {
|
|
|
|
StateInline.prototype.pushPending = function() {
|
|
|
|
var token$1 = new token("text", "", 0);
|
|
|
|
var token$1 = new token("text", "", 0);
|
|
|
|
token$1.content = this.pending;
|
|
|
|
token$1.content = this.pending;
|
|
|
@ -6689,7 +6689,7 @@
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Push new token to "stream".
|
|
|
|
// Push new token to "stream".
|
|
|
|
// If pending text exists - flush it as text token
|
|
|
|
// If pending text exists - flush it as text token
|
|
|
|
|
|
|
|
|
|
|
|
StateInline.prototype.push = function(type, tag, nesting) {
|
|
|
|
StateInline.prototype.push = function(type, tag, nesting) {
|
|
|
|
if (this.pending) {
|
|
|
|
if (this.pending) {
|
|
|
|
this.pushPending();
|
|
|
|
this.pushPending();
|
|
|
@ -6718,10 +6718,10 @@
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Scan a sequence of emphasis-like markers, and determine whether
|
|
|
|
// Scan a sequence of emphasis-like markers, and determine whether
|
|
|
|
// it can start an emphasis sequence or end an emphasis sequence.
|
|
|
|
// it can start an emphasis sequence or end an emphasis sequence.
|
|
|
|
|
|
|
|
|
|
|
|
// - start - position to scan from (it should point at a valid marker);
|
|
|
|
// - start - position to scan from (it should point at a valid marker);
|
|
|
|
// - canSplitWord - determine if these markers can be found inside a word
|
|
|
|
// - canSplitWord - determine if these markers can be found inside a word
|
|
|
|
|
|
|
|
|
|
|
|
StateInline.prototype.scanDelims = function(start, canSplitWord) {
|
|
|
|
StateInline.prototype.scanDelims = function(start, canSplitWord) {
|
|
|
|
var pos = start, lastChar, nextChar, count, can_open, can_close, isLastWhiteSpace, isLastPunctChar, isNextWhiteSpace, isNextPunctChar, left_flanking = true, right_flanking = true, max = this.posMax, marker = this.src.charCodeAt(start);
|
|
|
|
var pos = start, lastChar, nextChar, count, can_open, can_close, isLastWhiteSpace, isLastPunctChar, isNextWhiteSpace, isNextPunctChar, left_flanking = true, right_flanking = true, max = this.posMax, marker = this.src.charCodeAt(start);
|
|
|
|
// treat beginning of the line as a whitespace
|
|
|
|
// treat beginning of the line as a whitespace
|
|
|
@ -6771,10 +6771,10 @@
|
|
|
|
var _rules = [ [ "text", text ], [ "linkify", linkify ], [ "newline", newline ], [ "escape", _escape ], [ "backticks", backticks ], [ "strikethrough", strikethrough.tokenize ], [ "emphasis", emphasis.tokenize ], [ "link", link ], [ "image", image ], [ "autolink", autolink ], [ "html_inline", html_inline ], [ "entity", entity ] ];
|
|
|
|
var _rules = [ [ "text", text ], [ "linkify", linkify ], [ "newline", newline ], [ "escape", _escape ], [ "backticks", backticks ], [ "strikethrough", strikethrough.tokenize ], [ "emphasis", emphasis.tokenize ], [ "link", link ], [ "image", image ], [ "autolink", autolink ], [ "html_inline", html_inline ], [ "entity", entity ] ];
|
|
|
|
// `rule2` ruleset was created specifically for emphasis/strikethrough
|
|
|
|
// `rule2` ruleset was created specifically for emphasis/strikethrough
|
|
|
|
// post-processing and may be changed in the future.
|
|
|
|
// post-processing and may be changed in the future.
|
|
|
|
|
|
|
|
|
|
|
|
// Don't use this for anything except pairs (plugins working with `balance_pairs`).
|
|
|
|
// Don't use this for anything except pairs (plugins working with `balance_pairs`).
|
|
|
|
|
|
|
|
|
|
|
|
var _rules2 = [ [ "balance_pairs", balance_pairs ], [ "strikethrough", strikethrough.postProcess ], [ "emphasis", emphasis.postProcess ],
|
|
|
|
var _rules2 = [ [ "balance_pairs", balance_pairs ], [ "strikethrough", strikethrough.postProcess ], [ "emphasis", emphasis.postProcess ],
|
|
|
|
// rules for pairs separate '**' into its own text tokens, which may be left unused,
|
|
|
|
// rules for pairs separate '**' into its own text tokens, which may be left unused,
|
|
|
|
// rule below merges unused segments back with the rest of the text
|
|
|
|
// rule below merges unused segments back with the rest of the text
|
|
|
|
[ "fragments_join", fragments_join ] ];
|
|
|
|
[ "fragments_join", fragments_join ] ];
|
|
|
@ -6802,7 +6802,7 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Skip single token by running all rules in validation mode;
|
|
|
|
// Skip single token by running all rules in validation mode;
|
|
|
|
// returns `true` if any rule reported success
|
|
|
|
// returns `true` if any rule reported success
|
|
|
|
|
|
|
|
|
|
|
|
ParserInline.prototype.skipToken = function(state) {
|
|
|
|
ParserInline.prototype.skipToken = function(state) {
|
|
|
|
var ok, i, pos = state.pos, rules = this.ruler.getRules(""), len = rules.length, maxNesting = state.md.options.maxNesting, cache = state.cache;
|
|
|
|
var ok, i, pos = state.pos, rules = this.ruler.getRules(""), len = rules.length, maxNesting = state.md.options.maxNesting, cache = state.cache;
|
|
|
|
if (typeof cache[pos] !== "undefined") {
|
|
|
|
if (typeof cache[pos] !== "undefined") {
|
|
|
@ -6837,7 +6837,7 @@
|
|
|
|
cache[pos] = state.pos;
|
|
|
|
cache[pos] = state.pos;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Generate tokens for input range
|
|
|
|
// Generate tokens for input range
|
|
|
|
|
|
|
|
|
|
|
|
ParserInline.prototype.tokenize = function(state) {
|
|
|
|
ParserInline.prototype.tokenize = function(state) {
|
|
|
|
var ok, i, rules = this.ruler.getRules(""), len = rules.length, end = state.posMax, maxNesting = state.md.options.maxNesting;
|
|
|
|
var ok, i, rules = this.ruler.getRules(""), len = rules.length, end = state.posMax, maxNesting = state.md.options.maxNesting;
|
|
|
|
while (state.pos < end) {
|
|
|
|
while (state.pos < end) {
|
|
|
@ -6928,11 +6928,11 @@
|
|
|
|
re.src_xn = "xn--[a-z0-9\\-]{1,59}";
|
|
|
|
re.src_xn = "xn--[a-z0-9\\-]{1,59}";
|
|
|
|
// More to read about domain names
|
|
|
|
// More to read about domain names
|
|
|
|
// http://serverfault.com/questions/638260/
|
|
|
|
// http://serverfault.com/questions/638260/
|
|
|
|
re.src_domain_root =
|
|
|
|
re.src_domain_root =
|
|
|
|
// Allow letters & digits (http://test1)
|
|
|
|
// Allow letters & digits (http://test1)
|
|
|
|
"(?:" + re.src_xn + "|" + re.src_pseudo_letter + "{1,63}" + ")";
|
|
|
|
"(?:" + re.src_xn + "|" + re.src_pseudo_letter + "{1,63}" + ")";
|
|
|
|
re.src_domain = "(?:" + re.src_xn + "|" + "(?:" + re.src_pseudo_letter + ")" + "|" + "(?:" + re.src_pseudo_letter + "(?:-|" + re.src_pseudo_letter + "){0,61}" + re.src_pseudo_letter + ")" + ")";
|
|
|
|
re.src_domain = "(?:" + re.src_xn + "|" + "(?:" + re.src_pseudo_letter + ")" + "|" + "(?:" + re.src_pseudo_letter + "(?:-|" + re.src_pseudo_letter + "){0,61}" + re.src_pseudo_letter + ")" + ")";
|
|
|
|
re.src_host = "(?:" +
|
|
|
|
re.src_host = "(?:" +
|
|
|
|
// Don't need IP check, because digits are already allowed in normal domain names
|
|
|
|
// Don't need IP check, because digits are already allowed in normal domain names
|
|
|
|
// src_ip4 +
|
|
|
|
// src_ip4 +
|
|
|
|
// '|' +
|
|
|
|
// '|' +
|
|
|
@ -6949,11 +6949,11 @@
|
|
|
|
// Rude test fuzzy links by host, for quick deny
|
|
|
|
// Rude test fuzzy links by host, for quick deny
|
|
|
|
re.tpl_host_fuzzy_test = "localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:" + re.src_ZPCc + "|>|$))";
|
|
|
|
re.tpl_host_fuzzy_test = "localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:" + re.src_ZPCc + "|>|$))";
|
|
|
|
re.tpl_email_fuzzy = "(^|" + text_separators + '|"|\\(|' + re.src_ZCc + ")" + "(" + re.src_email_name + "@" + re.tpl_host_fuzzy_strict + ")";
|
|
|
|
re.tpl_email_fuzzy = "(^|" + text_separators + '|"|\\(|' + re.src_ZCc + ")" + "(" + re.src_email_name + "@" + re.tpl_host_fuzzy_strict + ")";
|
|
|
|
re.tpl_link_fuzzy =
|
|
|
|
re.tpl_link_fuzzy =
|
|
|
|
// Fuzzy link can't be prepended with .:/\- and non punctuation.
|
|
|
|
// Fuzzy link can't be prepended with .:/\- and non punctuation.
|
|
|
|
// but can start with > (markdown blockquote)
|
|
|
|
// but can start with > (markdown blockquote)
|
|
|
|
"(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|" + re.src_ZPCc + "))" + "((?![$+<=>^`|\uff5c])" + re.tpl_host_port_fuzzy_strict + re.src_path + ")";
|
|
|
|
"(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|" + re.src_ZPCc + "))" + "((?![$+<=>^`|\uff5c])" + re.tpl_host_port_fuzzy_strict + re.src_path + ")";
|
|
|
|
re.tpl_link_no_ip_fuzzy =
|
|
|
|
re.tpl_link_no_ip_fuzzy =
|
|
|
|
// Fuzzy link can't be prepended with .:/\- and non punctuation.
|
|
|
|
// Fuzzy link can't be prepended with .:/\- and non punctuation.
|
|
|
|
// but can start with > (markdown blockquote)
|
|
|
|
// but can start with > (markdown blockquote)
|
|
|
|
"(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|" + re.src_ZPCc + "))" + "((?![$+<=>^`|\uff5c])" + re.tpl_host_port_no_ip_fuzzy_strict + re.src_path + ")";
|
|
|
|
"(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|" + re.src_ZPCc + "))" + "((?![$+<=>^`|\uff5c])" + re.tpl_host_port_no_ip_fuzzy_strict + re.src_path + ")";
|
|
|
@ -6962,7 +6962,7 @@
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Helpers
|
|
|
|
// Helpers
|
|
|
|
// Merge objects
|
|
|
|
// Merge objects
|
|
|
|
|
|
|
|
|
|
|
|
function assign(obj /*from1, from2, from3, ...*/) {
|
|
|
|
function assign(obj /*from1, from2, from3, ...*/) {
|
|
|
|
var sources = Array.prototype.slice.call(arguments, 1);
|
|
|
|
var sources = Array.prototype.slice.call(arguments, 1);
|
|
|
|
sources.forEach((function(source) {
|
|
|
|
sources.forEach((function(source) {
|
|
|
@ -7025,7 +7025,7 @@
|
|
|
|
var tail = text.slice(pos);
|
|
|
|
var tail = text.slice(pos);
|
|
|
|
if (!self.re.no_http) {
|
|
|
|
if (!self.re.no_http) {
|
|
|
|
// compile lazily, because "host"-containing variables can change on tlds update.
|
|
|
|
// compile lazily, because "host"-containing variables can change on tlds update.
|
|
|
|
self.re.no_http = new RegExp("^" + self.re.src_auth +
|
|
|
|
self.re.no_http = new RegExp("^" + self.re.src_auth +
|
|
|
|
// Don't allow single-level domains, because of false positives like '//test'
|
|
|
|
// Don't allow single-level domains, because of false positives like '//test'
|
|
|
|
// with code comments
|
|
|
|
// with code comments
|
|
|
|
"(?:localhost|(?:(?:" + self.re.src_domain + ")\\.)+" + self.re.src_domain_root + ")" + self.re.src_port + self.re.src_host_terminator + self.re.src_path, "i");
|
|
|
|
"(?:localhost|(?:(?:" + self.re.src_domain + ")\\.)+" + self.re.src_domain_root + ")" + self.re.src_port + self.re.src_host_terminator + self.re.src_path, "i");
|
|
|
@ -7082,7 +7082,7 @@
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Schemas compiler. Build regexps.
|
|
|
|
// Schemas compiler. Build regexps.
|
|
|
|
|
|
|
|
|
|
|
|
function compile(self) {
|
|
|
|
function compile(self) {
|
|
|
|
// Load & clone RE patterns.
|
|
|
|
// Load & clone RE patterns.
|
|
|
|
var re$1 = self.re = re(self.__opts__);
|
|
|
|
var re$1 = self.re = re(self.__opts__);
|
|
|
@ -7101,9 +7101,9 @@
|
|
|
|
re$1.link_fuzzy = RegExp(untpl(re$1.tpl_link_fuzzy), "i");
|
|
|
|
re$1.link_fuzzy = RegExp(untpl(re$1.tpl_link_fuzzy), "i");
|
|
|
|
re$1.link_no_ip_fuzzy = RegExp(untpl(re$1.tpl_link_no_ip_fuzzy), "i");
|
|
|
|
re$1.link_no_ip_fuzzy = RegExp(untpl(re$1.tpl_link_no_ip_fuzzy), "i");
|
|
|
|
re$1.host_fuzzy_test = RegExp(untpl(re$1.tpl_host_fuzzy_test), "i");
|
|
|
|
re$1.host_fuzzy_test = RegExp(untpl(re$1.tpl_host_fuzzy_test), "i");
|
|
|
|
|
|
|
|
|
|
|
|
// Compile each schema
|
|
|
|
// Compile each schema
|
|
|
|
|
|
|
|
|
|
|
|
var aliases = [];
|
|
|
|
var aliases = [];
|
|
|
|
self.__compiled__ = {};
|
|
|
|
self.__compiled__ = {};
|
|
|
|
// Reset compiled data
|
|
|
|
// Reset compiled data
|
|
|
@ -7144,9 +7144,9 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
schemaError(name, val);
|
|
|
|
schemaError(name, val);
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
// Compile postponed aliases
|
|
|
|
// Compile postponed aliases
|
|
|
|
|
|
|
|
|
|
|
|
aliases.forEach((function(alias) {
|
|
|
|
aliases.forEach((function(alias) {
|
|
|
|
if (!self.__compiled__[self.__schemas__[alias]]) {
|
|
|
|
if (!self.__compiled__[self.__schemas__[alias]]) {
|
|
|
|
// Silently fail on missed schemas to avoid errons on disable.
|
|
|
|
// Silently fail on missed schemas to avoid errons on disable.
|
|
|
@ -7156,16 +7156,16 @@
|
|
|
|
self.__compiled__[alias].validate = self.__compiled__[self.__schemas__[alias]].validate;
|
|
|
|
self.__compiled__[alias].validate = self.__compiled__[self.__schemas__[alias]].validate;
|
|
|
|
self.__compiled__[alias].normalize = self.__compiled__[self.__schemas__[alias]].normalize;
|
|
|
|
self.__compiled__[alias].normalize = self.__compiled__[self.__schemas__[alias]].normalize;
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
// Fake record for guessed links
|
|
|
|
// Fake record for guessed links
|
|
|
|
|
|
|
|
|
|
|
|
self.__compiled__[""] = {
|
|
|
|
self.__compiled__[""] = {
|
|
|
|
validate: null,
|
|
|
|
validate: null,
|
|
|
|
normalize: createNormalizer()
|
|
|
|
normalize: createNormalizer()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Build schema condition
|
|
|
|
// Build schema condition
|
|
|
|
|
|
|
|
|
|
|
|
var slist = Object.keys(self.__compiled__).filter((function(name) {
|
|
|
|
var slist = Object.keys(self.__compiled__).filter((function(name) {
|
|
|
|
// Filter disabled & fake schemas
|
|
|
|
// Filter disabled & fake schemas
|
|
|
|
return name.length > 0 && self.__compiled__[name];
|
|
|
|
return name.length > 0 && self.__compiled__[name];
|
|
|
@ -7175,9 +7175,9 @@
|
|
|
|
self.re.schema_search = RegExp("(^|(?!_)(?:[><\uff5c]|" + re$1.src_ZPCc + "))(" + slist + ")", "ig");
|
|
|
|
self.re.schema_search = RegExp("(^|(?!_)(?:[><\uff5c]|" + re$1.src_ZPCc + "))(" + slist + ")", "ig");
|
|
|
|
self.re.schema_at_start = RegExp("^" + self.re.schema_search.source, "i");
|
|
|
|
self.re.schema_at_start = RegExp("^" + self.re.schema_search.source, "i");
|
|
|
|
self.re.pretest = RegExp("(" + self.re.schema_test.source + ")|(" + self.re.host_fuzzy_test.source + ")|@", "i");
|
|
|
|
self.re.pretest = RegExp("(" + self.re.schema_test.source + ")|(" + self.re.host_fuzzy_test.source + ")|@", "i");
|
|
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
// Cleanup
|
|
|
|
|
|
|
|
|
|
|
|
resetScanCache(self);
|
|
|
|
resetScanCache(self);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -7673,7 +7673,7 @@
|
|
|
|
* @returns {String} The resulting string of Unicode symbols.
|
|
|
|
* @returns {String} The resulting string of Unicode symbols.
|
|
|
|
*/ function decode(input) {
|
|
|
|
*/ function decode(input) {
|
|
|
|
// Don't use UCS-2
|
|
|
|
// Don't use UCS-2
|
|
|
|
var output = [], inputLength = input.length, out, i = 0, n = initialN, bias = initialBias, basic, j, index, oldi, w, k, digit, t,
|
|
|
|
var output = [], inputLength = input.length, out, i = 0, n = initialN, bias = initialBias, basic, j, index, oldi, w, k, digit, t,
|
|
|
|
/** Cached calculation results */
|
|
|
|
/** Cached calculation results */
|
|
|
|
baseMinusT;
|
|
|
|
baseMinusT;
|
|
|
|
// Handle the basic code points: let `basic` be the number of input code
|
|
|
|
// Handle the basic code points: let `basic` be the number of input code
|
|
|
@ -7738,9 +7738,9 @@
|
|
|
|
* @param {String} input The string of Unicode symbols.
|
|
|
|
* @param {String} input The string of Unicode symbols.
|
|
|
|
* @returns {String} The resulting Punycode string of ASCII-only symbols.
|
|
|
|
* @returns {String} The resulting Punycode string of ASCII-only symbols.
|
|
|
|
*/ function encode(input) {
|
|
|
|
*/ function encode(input) {
|
|
|
|
var n, delta, handledCPCount, basicLength, bias, j, m, q, k, t, currentValue, output = [],
|
|
|
|
var n, delta, handledCPCount, basicLength, bias, j, m, q, k, t, currentValue, output = [],
|
|
|
|
/** `inputLength` will hold the number of code points in `input`. */
|
|
|
|
/** `inputLength` will hold the number of code points in `input`. */
|
|
|
|
inputLength,
|
|
|
|
inputLength,
|
|
|
|
/** Cached calculation results */
|
|
|
|
/** Cached calculation results */
|
|
|
|
handledCPCountPlusOne, baseMinusT, qMinusT;
|
|
|
|
handledCPCountPlusOne, baseMinusT, qMinusT;
|
|
|
|
// Convert the input in UCS-2 to Unicode
|
|
|
|
// Convert the input in UCS-2 to Unicode
|
|
|
@ -7993,13 +7993,13 @@
|
|
|
|
commonmark: commonmark
|
|
|
|
commonmark: commonmark
|
|
|
|
};
|
|
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
// This validator can prohibit more than really needed to prevent XSS. It's a
|
|
|
|
// This validator can prohibit more than really needed to prevent XSS. It's a
|
|
|
|
// tradeoff to keep code simple and to be secure by default.
|
|
|
|
// tradeoff to keep code simple and to be secure by default.
|
|
|
|
|
|
|
|
|
|
|
|
// If you need different setup - override validator method as you wish. Or
|
|
|
|
// If you need different setup - override validator method as you wish. Or
|
|
|
|
// replace it with dummy function and use external sanitizer.
|
|
|
|
// replace it with dummy function and use external sanitizer.
|
|
|
|
|
|
|
|
|
|
|
|
var BAD_PROTO_RE = /^(vbscript|javascript|file|data):/;
|
|
|
|
var BAD_PROTO_RE = /^(vbscript|javascript|file|data):/;
|
|
|
|
var GOOD_DATA_RE = /^data:image\/(gif|png|jpeg|webp);/;
|
|
|
|
var GOOD_DATA_RE = /^data:image\/(gif|png|jpeg|webp);/;
|
|
|
|
function validateLink(url) {
|
|
|
|
function validateLink(url) {
|
|
|
|