65 lines
1.4 KiB
TypeScript
65 lines
1.4 KiB
TypeScript
/**
|
|
* @license
|
|
*
|
|
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
|
* https://github.com/chjj/marked
|
|
*
|
|
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
|
* https://github.com/ts-stack/markdown
|
|
*/
|
|
|
|
import type { Replacements } from "./interfaces.ts";
|
|
|
|
const escapeTest = /[&<>"']/;
|
|
const escapeReplace = /[&<>"']/g;
|
|
const replacements: Replacements = {
|
|
"&": "&",
|
|
"<": "<",
|
|
">": ">",
|
|
'"': """,
|
|
// tslint:disable-next-line:quotemark
|
|
"'": "'",
|
|
};
|
|
|
|
const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
|
|
const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
|
|
|
|
export function escape(html: string, encode?: boolean) {
|
|
if (encode) {
|
|
if (escapeTest.test(html)) {
|
|
return html.replace(escapeReplace, (ch: string) => replacements[ch]);
|
|
}
|
|
} else {
|
|
if (escapeTestNoEncode.test(html)) {
|
|
return html.replace(
|
|
escapeReplaceNoEncode,
|
|
(ch: string) => replacements[ch]
|
|
);
|
|
}
|
|
}
|
|
|
|
return html;
|
|
}
|
|
|
|
export function unescape(html: string) {
|
|
// Explicitly match decimal, hex, and named HTML entities
|
|
return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi, function (
|
|
_,
|
|
n
|
|
) {
|
|
n = n.toLowerCase();
|
|
|
|
if (n === "colon") {
|
|
return ":";
|
|
}
|
|
|
|
if (n.charAt(0) === "#") {
|
|
return n.charAt(1) === "x"
|
|
? String.fromCharCode(parseInt(n.substring(2), 16))
|
|
: String.fromCharCode(+n.substring(1));
|
|
}
|
|
|
|
return "";
|
|
});
|
|
}
|