|
@ -6,19 +6,19 @@ import ucmicro from 'uc.micro' |
|
|
import { decodeHTML } from 'entities' |
|
|
import { decodeHTML } from 'entities' |
|
|
import UNICODE_PUNCT_RE from 'uc.micro/categories/P/regex.js' |
|
|
import UNICODE_PUNCT_RE from 'uc.micro/categories/P/regex.js' |
|
|
|
|
|
|
|
|
function _class(obj) { return Object.prototype.toString.call(obj) } |
|
|
function _class (obj) { return Object.prototype.toString.call(obj) } |
|
|
|
|
|
|
|
|
function isString(obj) { return _class(obj) === '[object String]' } |
|
|
function isString (obj) { return _class(obj) === '[object String]' } |
|
|
|
|
|
|
|
|
const _hasOwnProperty = Object.prototype.hasOwnProperty |
|
|
const _hasOwnProperty = Object.prototype.hasOwnProperty |
|
|
|
|
|
|
|
|
function has(object, key) { |
|
|
function has (object, key) { |
|
|
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, ...*/) { |
|
|
const sources = Array.prototype.slice.call(arguments, 1) |
|
|
const sources = Array.prototype.slice.call(arguments, 1) |
|
|
|
|
|
|
|
|
sources.forEach(function (source) { |
|
|
sources.forEach(function (source) { |
|
@ -38,13 +38,13 @@ function assign(obj /*from1, from2, from3, ...*/) { |
|
|
|
|
|
|
|
|
// Remove element from array and put another array at those position.
|
|
|
// Remove element from array and put another array at those position.
|
|
|
// Useful for some operations with tokens
|
|
|
// Useful for some operations with tokens
|
|
|
function arrayReplaceAt(src, pos, newElements) { |
|
|
function arrayReplaceAt (src, pos, newElements) { |
|
|
return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1)) |
|
|
return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1)) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
function isValidEntityCode(c) { |
|
|
function isValidEntityCode (c) { |
|
|
/*eslint no-bitwise:0*/ |
|
|
/*eslint no-bitwise:0*/ |
|
|
// broken sequence
|
|
|
// broken sequence
|
|
|
if (c >= 0xD800 && c <= 0xDFFF) { return false } |
|
|
if (c >= 0xD800 && c <= 0xDFFF) { return false } |
|
@ -61,7 +61,7 @@ function isValidEntityCode(c) { |
|
|
return true |
|
|
return true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function fromCodePoint(c) { |
|
|
function fromCodePoint (c) { |
|
|
/*eslint no-bitwise:0*/ |
|
|
/*eslint no-bitwise:0*/ |
|
|
if (c > 0xffff) { |
|
|
if (c > 0xffff) { |
|
|
c -= 0x10000 |
|
|
c -= 0x10000 |
|
@ -81,7 +81,7 @@ const UNESCAPE_ALL_RE = new RegExp(UNESCAPE_MD_RE.source + '|' + ENTITY_RE.sourc |
|
|
const DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i |
|
|
const DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function replaceEntityPattern(match, name) { |
|
|
function replaceEntityPattern (match, name) { |
|
|
if (name.charCodeAt(0) === 0x23/* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) { |
|
|
if (name.charCodeAt(0) === 0x23/* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) { |
|
|
const code = name[1].toLowerCase() === 'x' ? |
|
|
const code = name[1].toLowerCase() === 'x' ? |
|
|
parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10) |
|
|
parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10) |
|
@ -107,12 +107,12 @@ function replaceEntityPattern(match, name) { |
|
|
return str.replace(ENTITY_RE, replaceEntityPattern); |
|
|
return str.replace(ENTITY_RE, replaceEntityPattern); |
|
|
}*/ |
|
|
}*/ |
|
|
|
|
|
|
|
|
function unescapeMd(str) { |
|
|
function unescapeMd (str) { |
|
|
if (str.indexOf('\\') < 0) { return str } |
|
|
if (str.indexOf('\\') < 0) { return str } |
|
|
return str.replace(UNESCAPE_MD_RE, '$1') |
|
|
return str.replace(UNESCAPE_MD_RE, '$1') |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function unescapeAll(str) { |
|
|
function unescapeAll (str) { |
|
|
if (str.indexOf('\\') < 0 && str.indexOf('&') < 0) { return str } |
|
|
if (str.indexOf('\\') < 0 && str.indexOf('&') < 0) { return str } |
|
|
|
|
|
|
|
|
return str.replace(UNESCAPE_ALL_RE, function (match, escaped, entity) { |
|
|
return str.replace(UNESCAPE_ALL_RE, function (match, escaped, entity) { |
|
@ -132,11 +132,11 @@ const HTML_REPLACEMENTS = { |
|
|
'"': '"' |
|
|
'"': '"' |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function replaceUnsafeChar(ch) { |
|
|
function replaceUnsafeChar (ch) { |
|
|
return HTML_REPLACEMENTS[ch] |
|
|
return HTML_REPLACEMENTS[ch] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function escapeHtml(str) { |
|
|
function escapeHtml (str) { |
|
|
if (HTML_ESCAPE_TEST_RE.test(str)) { |
|
|
if (HTML_ESCAPE_TEST_RE.test(str)) { |
|
|
return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar) |
|
|
return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar) |
|
|
} |
|
|
} |
|
@ -147,13 +147,13 @@ function escapeHtml(str) { |
|
|
|
|
|
|
|
|
const REGEXP_ESCAPE_RE = /[.?*+^$[\]\\(){}|-]/g |
|
|
const REGEXP_ESCAPE_RE = /[.?*+^$[\]\\(){}|-]/g |
|
|
|
|
|
|
|
|
function escapeRE(str) { |
|
|
function escapeRE (str) { |
|
|
return str.replace(REGEXP_ESCAPE_RE, '\\$&') |
|
|
return str.replace(REGEXP_ESCAPE_RE, '\\$&') |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
function isSpace(code) { |
|
|
function isSpace (code) { |
|
|
switch (code) { |
|
|
switch (code) { |
|
|
case 0x09: |
|
|
case 0x09: |
|
|
case 0x20: |
|
|
case 0x20: |
|
@ -163,7 +163,7 @@ function isSpace(code) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Zs (unicode class) || [\t\f\v\r\n]
|
|
|
// Zs (unicode class) || [\t\f\v\r\n]
|
|
|
function isWhiteSpace(code) { |
|
|
function isWhiteSpace (code) { |
|
|
if (code >= 0x2000 && code <= 0x200A) { return true } |
|
|
if (code >= 0x2000 && code <= 0x200A) { return true } |
|
|
switch (code) { |
|
|
switch (code) { |
|
|
case 0x09: // \t
|
|
|
case 0x09: // \t
|
|
@ -187,7 +187,7 @@ function isWhiteSpace(code) { |
|
|
/*eslint-disable max-len*/ |
|
|
/*eslint-disable max-len*/ |
|
|
|
|
|
|
|
|
// Currently without astral characters support.
|
|
|
// Currently without astral characters support.
|
|
|
function isPunctChar(ch) { |
|
|
function isPunctChar (ch) { |
|
|
return UNICODE_PUNCT_RE.test(ch) |
|
|
return UNICODE_PUNCT_RE.test(ch) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -199,7 +199,7 @@ function isPunctChar(ch) { |
|
|
//
|
|
|
//
|
|
|
// 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 0x21/* ! */: |
|
|
case 0x21/* ! */: |
|
|
case 0x22/* " */: |
|
|
case 0x22/* " */: |
|
@ -241,7 +241,7 @@ function isMdAsciiPunct(ch) { |
|
|
|
|
|
|
|
|
// 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, ' ') |
|
|