670 lines
34 KiB
TypeScript
670 lines
34 KiB
TypeScript
import { defineMode, type Mode, getMode, StringStream, startState } from "codemirror";
|
|
import type { MarkdownState } from "hypermd/mode/hypermd";
|
|
|
|
const EN = /^(?:[*\-+]|^[0-9]+([.)]))\s+/, SN = /^(?:(?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i, xN = /^(?:(?:[^<>()[\]\\.,;:\s@\"`]+(?:\.[^<>()[\]\\.,;:\s@\"]+)*)|(?:\".+\"))@(?:(?:\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(?:(?:[a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))\b/, TN = /^(?:[^\u2000-\u206F\u2E00-\u2E7F'!"#$%&()*+,.:;<=>?@^`{|}~\[\]\\\s])+/;
|
|
const PN = /^\s*[^\|].*?\|.*[^|]\s*$/, IN = /^\s*[^\|].*\|/, FN = /^\|(?:[^|]+\|)+?\s*$/, ON = /^\|/, BN = /^\s*-+\s*:\s*$/, NN = /^\s*:\s*-+\s*$/, RN = /^\s*:\s*-+\s*:\s*$/, HN = /^\s*-+\s*$/;
|
|
const readSideRegex = /(?:([\u200F\p{sc=Arabic}\p{sc=Hebrew}\p{sc=Syriac}\p{sc=Thaana}])|([\u200E\p{sc=Armenian}\p{sc=Bengali}\p{sc=Bopomofo}\p{sc=Braille}\p{sc=Buhid}\p{sc=Canadian_Aboriginal}\p{sc=Cherokee}\p{sc=Cyrillic}\p{sc=Devanagari}\p{sc=Ethiopic}\p{sc=Georgian}\p{sc=Greek}\p{sc=Gujarati}\p{sc=Gurmukhi}\p{sc=Han}\p{sc=Hangul}\p{sc=Hanunoo}\p{sc=Hiragana}\p{sc=Kannada}\p{sc=Katakana}\p{sc=Khmer}\p{sc=Lao}\p{sc=Latin}\p{sc=Limbu}\p{sc=Malayalam}\p{sc=Mongolian}\p{sc=Myanmar}\p{sc=Ogham}\p{sc=Oriya}\p{sc=Runic}\p{sc=Sinhala}\p{sc=Tagalog}\p{sc=Tagbanwa}\p{sc=Tamil}\p{sc=Telugu}\p{sc=Thai}\p{sc=Tibetan}\p{sc=Yi}]))/u;
|
|
const readSide = function(e: string) {
|
|
var t = e.match(readSideRegex);
|
|
if (t) {
|
|
if (t[1])
|
|
return "rtl";
|
|
if (t[2])
|
|
return "ltr"
|
|
}
|
|
return "auto"
|
|
}
|
|
const isLetter = (e: string) => /[a-z]/i.test(e);
|
|
const clearSubstringWords = (str: string, substring: string) => str.replace(new RegExp("\\s?[^\\s]*".concat(substring, "[^\\s]*","g")), "");
|
|
const enum HashtagType {
|
|
NONE = 0,
|
|
NORMAL = 1,
|
|
WITH_SPACE = 2
|
|
}
|
|
const enum TableType {
|
|
NONE = 0,
|
|
SIMPLE = 1,
|
|
NORMAL = 2
|
|
}
|
|
const enum NextMaybe {
|
|
NONE = 0,
|
|
FRONT_MATTER = 1,
|
|
FRONT_MATTER_END = 2
|
|
}
|
|
const enum LinkType {
|
|
NONE = 0,
|
|
BARELINK = 1,
|
|
FOOTREF = 2,
|
|
NORMAL = 3,
|
|
FOOTNOTE = 4,
|
|
MAYBE_FOOTNOTE_URL = 5,
|
|
MAYBE_FOOTNOTE_URL_TITLE = 6,
|
|
BARELINK2 = 7,
|
|
FOOTREF2 = 8,
|
|
INTERNAL_LINK = 9,
|
|
EMBED = 10,
|
|
}
|
|
const CLASSES: Record<number, string> = {
|
|
1: "hmd-barelink",
|
|
7: "hmd-barelink2",
|
|
2: "hmd-barelink footref",
|
|
4: "hmd-barelink hmd-footnote line-HyperMD-footnote",
|
|
8: "hmd-footref2",
|
|
9: "hmd-internal-link",
|
|
10: "hmd-internal-link hmd-embed",
|
|
}
|
|
|
|
export declare type TokenFunc = (stream: CodeMirror.StringStream, state: HyperMDState) => string;
|
|
export declare type InnerModeExitChecker = (stream: CodeMirror.StringStream, state: HyperMDState) => {
|
|
endPos?: number;
|
|
skipInnerMode?: boolean;
|
|
style?: string;
|
|
} | null;
|
|
interface HyperMDState extends MarkdownState {
|
|
hmdTableRTL: boolean;
|
|
highlight: boolean;
|
|
hasAlias: boolean;
|
|
isAlias: boolean;
|
|
comment: boolean;
|
|
mathed: boolean;
|
|
internalEmbed: any;
|
|
internalLink: any;
|
|
inFootnote: boolean;
|
|
inlineFootnote: boolean;
|
|
wasHeading: boolean;
|
|
isHeading: boolean;
|
|
hmdTable: TableType;
|
|
hmdTableID: string | null;
|
|
hmdTableColumns: string[];
|
|
hmdTableCol: number;
|
|
hmdTableRow: number;
|
|
hmdOverride: TokenFunc | null;
|
|
hmdHashtag: HashtagType | boolean;
|
|
hmdInnerStyle: string;
|
|
hmdInnerExitChecker: InnerModeExitChecker | null;
|
|
hmdInnerMode: CodeMirror.Mode<any> | null;
|
|
hmdInnerState: any;
|
|
hmdLinkType: LinkType;
|
|
hmdNextMaybe: NextMaybe;
|
|
hmdNextState: HyperMDState | null;
|
|
hmdNextStyle: string | null;
|
|
hmdNextPos: number | null;
|
|
}
|
|
|
|
function resetTable(state: HyperMDState)
|
|
{
|
|
state.hmdTable = TableType.NONE,
|
|
state.hmdTableRTL = !1,
|
|
state.hmdTableColumns = [],
|
|
state.hmdTableID = null,
|
|
state.hmdTableCol = state.hmdTableRow = 0
|
|
}
|
|
defineMode('d-any', function(cm, config) {
|
|
const markdownMode: Mode<MarkdownState> = getMode(cm, { ...config, name: 'markdown' }) as any;
|
|
const mode: Mode<HyperMDState> = getMode(cm, { ...config, name: 'hypermd' }) as any;
|
|
|
|
config = Object.assign({}, {
|
|
front_matter: !0,
|
|
math: !0,
|
|
table: !0,
|
|
toc: !0,
|
|
orgModeMarkup: !0,
|
|
hashtag: !0,
|
|
fencedCodeBlockHighlighting: !0,
|
|
highlightFormatting: !0,
|
|
taskLists: !0,
|
|
strikethrough: !0,
|
|
emoji: !1,
|
|
highlight: !0,
|
|
headers: !0,
|
|
blockquotes: !0,
|
|
indentedCode: !0,
|
|
lists: !0,
|
|
hr: !0,
|
|
blockId: !0
|
|
}, config)
|
|
|
|
function modeOverride(stream: CodeMirror.StringStream, state: HyperMDState): string {
|
|
const exit = state.hmdInnerExitChecker!(stream, state);
|
|
const extraStyle = state.hmdInnerStyle;
|
|
|
|
let ans = (!exit || !exit.skipInnerMode) && state.hmdInnerMode!.token(stream, state.hmdInnerState) || "";
|
|
|
|
if (extraStyle) ans += " " + extraStyle;
|
|
if (exit) {
|
|
if (exit.style) ans += " " + exit.style;
|
|
if (exit.endPos) stream.pos = exit.endPos;
|
|
|
|
state.hmdInnerExitChecker = null;
|
|
state.hmdInnerMode = null;
|
|
state.hmdInnerState = null;
|
|
state.hmdOverride = null;
|
|
}
|
|
|
|
return ans.trim();
|
|
}
|
|
|
|
function advanceMarkdown(stream: CodeMirror.StringStream, state: HyperMDState) {
|
|
if (stream.eol() || state.hmdNextState) return false;
|
|
|
|
let oldStart = stream.start;
|
|
let oldPos = stream.pos;
|
|
|
|
stream.start = oldPos;
|
|
let newState = { ...state };
|
|
let newStyle = mode.token(stream, newState);
|
|
|
|
state.hmdNextPos = stream.pos;
|
|
state.hmdNextState = newState;
|
|
state.hmdNextStyle = newStyle;
|
|
|
|
stream.start = oldStart;
|
|
stream.pos = oldPos;
|
|
|
|
return true;
|
|
}
|
|
|
|
function createDummyMode(endTag: string): CodeMirror.Mode<void> {
|
|
return {
|
|
token(stream) {
|
|
let endTagSince = stream.string.indexOf(endTag, stream.start);
|
|
if (endTagSince === -1) stream.skipToEnd(); // endTag not in this line
|
|
else if (endTagSince === 0) stream.pos += endTag.length; // current token is endTag
|
|
else {
|
|
stream.pos = endTagSince;
|
|
if (stream.string.charAt(endTagSince - 1) === "\\") stream.pos++;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
function createSimpleInnerModeExitChecker(endTag: string, retInfo?: ReturnType<InnerModeExitChecker>): InnerModeExitChecker {
|
|
if (!retInfo) retInfo = {};
|
|
|
|
return function (stream, state) {
|
|
if (stream.string.substring(stream.start, stream.start + endTag.length) === endTag) {
|
|
retInfo.endPos = stream.start + endTag.length;
|
|
return retInfo;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
interface BasicInnerModeOptions {
|
|
skipFirstToken?: boolean
|
|
style?: string
|
|
}
|
|
|
|
interface InnerModeOptions1 extends BasicInnerModeOptions {
|
|
fallbackMode: () => CodeMirror.Mode<any>
|
|
exitChecker: InnerModeExitChecker
|
|
}
|
|
|
|
interface InnerModeOptions2 extends BasicInnerModeOptions {
|
|
endTag: string
|
|
}
|
|
|
|
type InnerModeOptions = InnerModeOptions1 | InnerModeOptions2
|
|
|
|
/**
|
|
* switch to another mode
|
|
*
|
|
* After entering a mode, you can then set `hmdInnerExitStyle` and `hmdInnerState` of `state`
|
|
*
|
|
* @returns if `skipFirstToken` not set, returns `innerMode.token(stream, innerState)`, meanwhile, stream advances
|
|
*/
|
|
function enterMode(stream: StringStream, state: HyperMDState, mode: string | CodeMirror.Mode<any> | null, opt: InnerModeOptions): string {
|
|
if (typeof mode === "string") mode = getMode(cm, mode);
|
|
|
|
if (!mode || mode["name"] === "null") {
|
|
if ('endTag' in opt) mode = createDummyMode(opt.endTag);
|
|
else if(typeof opt.fallbackMode === 'function') mode = opt.fallbackMode();
|
|
|
|
if (!mode) throw new Error("no mode");
|
|
}
|
|
|
|
state.hmdInnerExitChecker = ('endTag' in opt) ? createSimpleInnerModeExitChecker(opt.endTag) : opt.exitChecker;
|
|
state.hmdInnerStyle = opt.style ?? '';
|
|
state.hmdInnerMode = mode;
|
|
state.hmdOverride = modeOverride;
|
|
state.hmdInnerState = startState(mode);
|
|
|
|
let ans = opt.style || "";
|
|
if (!opt.skipFirstToken)
|
|
ans += " " + mode.token(stream, state.hmdInnerState);
|
|
|
|
return ans.trim();
|
|
}
|
|
|
|
const i: Record<string, any> = {
|
|
htmlBlock: null,
|
|
block: null
|
|
};
|
|
|
|
return {
|
|
name: 'd-any',
|
|
...mode,
|
|
token(stream, _state) {
|
|
const state = _state as HyperMDState;
|
|
stream.tabSize = 4;
|
|
if (state.hmdOverride)
|
|
return state.hmdOverride(stream, state);
|
|
|
|
if (state.hmdTable && " " === stream.peek())
|
|
{
|
|
if ("|" === stream.string[stream.pos - 1] && "\\" !== stream.string[stream.pos - 2])
|
|
return stream.match(/^ +/), "";
|
|
if (stream.match(/^ +\|/))
|
|
return stream.backUp(1), "";
|
|
}
|
|
if (state.hmdNextMaybe === NextMaybe.FRONT_MATTER)
|
|
{
|
|
if ("---" === stream.string)
|
|
return state.hmdNextMaybe = NextMaybe.FRONT_MATTER_END, enterMode(stream, state, "yaml", {
|
|
style: "hmd-frontmatter",
|
|
fallbackMode: function() {
|
|
return createDummyMode("---");
|
|
},
|
|
exitChecker: function(e, stream) {
|
|
return e.string.startsWith("---") && "" === e.string.substring(3).trim() ? (stream.hmdNextMaybe = NextMaybe.NONE,
|
|
{
|
|
endPos: e.string.length
|
|
}) : null;
|
|
}
|
|
});
|
|
state.hmdNextMaybe = NextMaybe.NONE;
|
|
}
|
|
let a = state.f === i.htmlBlock, c = -1 === state.code, u = state.quote, h = 0 === stream.start;
|
|
h && (state.inFootnote && state.hmdLinkType === LinkType.MAYBE_FOOTNOTE_URL || (state.hmdLinkType = LinkType.NONE),
|
|
state.inlineFootnote = !1,
|
|
state.wasHeading = state.isHeading,
|
|
state.isHeading = !1,
|
|
!state.code || 1 !== state.code && 2 !== state.code || (state.code = 0));
|
|
let d, p, f = state.linkText, m = state.linkHref, v = !(c || a), g = v && !(state.code || state.indentedCode || state.linkHref), y = "", b = !1, w = -1, k = !1;
|
|
if (v)
|
|
{
|
|
if (g && "\\" === stream.peek() && (k = !0), state.list && !state.header && "#" === stream.peek() && /^\s*[*\-+]\s$/.test(stream.string.substring(0, stream.pos)))
|
|
{
|
|
const C = stream.match(/^(#+)(?: |$)/, !0);
|
|
if (C)
|
|
{
|
|
const M = C[1].length;
|
|
return state.header = M, "formatting formatting-header formatting-header-" + M + " header header-" + M;
|
|
}
|
|
}
|
|
if (config.math && g && "$" === stream.peek() && (state.hmdLinkType === LinkType.NONE || state.hmdLinkType === LinkType.MAYBE_FOOTNOTE_URL) && !state.internalLink && !state.internalEmbed)
|
|
{
|
|
let E: string[] | null = stream.match(/^(\$)[^\s$]/, !1), S = stream.match(/^(\${2})/, !1), x = E ? "$" : "$$";
|
|
if (E)
|
|
{
|
|
let I = stream.string.slice(stream.pos + 1).match(/[^\\]\$(.|$)/)
|
|
if(!I || !I[0].match(/^[^\s\\]\$([^0-9]|$)/))
|
|
E = null;
|
|
}
|
|
let T = !1;
|
|
if (E || S)
|
|
{
|
|
if (0 !== stream.pos || state.mathed)
|
|
{
|
|
let D = "math";
|
|
state.quote && (D += " line-HyperMD-quote line-HyperMD-quote-" + state.quote + " line-HyperMD-quote-lazy");
|
|
const A = getMode(cm, {
|
|
name: "stex"
|
|
}), L = "stex" !== A.name;
|
|
return y += enterMode(stream, state, A, {
|
|
style: D,
|
|
skipFirstToken: L,
|
|
fallbackMode: function() {
|
|
return createDummyMode(x);
|
|
},
|
|
exitChecker: function(e, stream) {
|
|
let n = e.start, i = e.string, r = "formatting formatting-math formatting-math-end math-";
|
|
return stream.hmdTable && "|" === i[n] ? {
|
|
endPos: n,
|
|
style: r
|
|
} : i.substring(n, n + x.length) === x ? {
|
|
endPos: n + x.length,
|
|
style: r
|
|
} : null;
|
|
}
|
|
}),
|
|
E ? (L && (stream.pos += E[1].length),
|
|
y += " formatting formatting-math formatting-math-begin") : (L && (stream.pos += S[1].length),
|
|
y += " formatting formatting-math formatting-math-begin math-block")
|
|
}
|
|
T = !0, w = 0;
|
|
}
|
|
state.mathed = T;
|
|
}
|
|
if (g) {
|
|
state.internalLink ? (state.hmdLinkType = LinkType.INTERNAL_LINK,
|
|
state.internalLink = !1) : state.internalEmbed && (state.hmdLinkType = LinkType.EMBED,
|
|
state.internalEmbed = !1);
|
|
let P = state.hmdLinkType === LinkType.INTERNAL_LINK || state.hmdLinkType === LinkType.EMBED;
|
|
if (P)
|
|
if ("|" === stream.peek())
|
|
state.isAlias = !0,
|
|
w = stream.pos + 1,
|
|
y += " link-alias-pipe";
|
|
else if ("]" === stream.peek() && stream.match("]]", !1))
|
|
state.hmdLinkType = LinkType.NONE,
|
|
state.linkText = !1,
|
|
state.isAlias = !1,
|
|
state.hasAlias = !1,
|
|
w = stream.pos + 2,
|
|
y += " formatting-link formatting-link-end";
|
|
else {
|
|
b = !0,
|
|
state.isAlias && (y += " link-alias"),
|
|
state.hasAlias && !state.isAlias && (y += " link-has-alias");
|
|
let I = stream.match(/^([^|\]]*?)/, !1);
|
|
w = stream.pos + Math.max(1, I[0].length)
|
|
}
|
|
else if("!" === stream.peek() || "[" === stream.peek())
|
|
{
|
|
const I = stream.match(/^(!?\[\[)(.*?)]]/, !1)
|
|
if(I)
|
|
"!" === I[1].charAt(0) ? (y += " formatting-link formatting-link-start formatting-embed", state.internalEmbed = !0) : (y += " formatting-link formatting-link-start", state.internalLink = !0), w = stream.pos + I[1].length, state.hasAlias = I[2].includes("|");
|
|
}
|
|
if (state.hmdLinkType === LinkType.FOOTREF)
|
|
if (b = !0,
|
|
"]" === stream.peek())
|
|
state.hmdLinkType = LinkType.NONE,
|
|
w = stream.pos + 1,
|
|
y += " formatting formatting-link formatting-link-end " + CLASSES[LinkType.FOOTREF];
|
|
else {
|
|
let I = stream.match(/^([^\]]*?)/, !1);
|
|
w = stream.pos + Math.max(1, I[0].length)
|
|
}
|
|
else
|
|
{
|
|
const I = stream.peek() === "[" && stream.match(/^\[\^([^\]\s]*?)\](:?)/, false);
|
|
if(I && (h || I[2]))
|
|
{
|
|
stream.match("[^"),
|
|
y += " formatting formatting-link formatting-link-start",
|
|
state.hmdLinkType = LinkType.FOOTREF,
|
|
w = stream.pos;
|
|
}
|
|
}
|
|
if (config.blockId && "^" === stream.peek() && stream.match(/^\^([a-zA-Z0-9\-]+)$/))
|
|
return y += " blockid";
|
|
!state.inlineFootnote && "^" === stream.peek() && stream.match("^[", !1) ? (state.inlineFootnote = !0,
|
|
y += " inline-footnote-start formatting-inline-footnote",
|
|
w = stream.pos + 2) : state.inlineFootnote && !P && state.hmdLinkType === LinkType.NONE && !state.image && stream.match("]") && (state.inlineFootnote = !1,
|
|
y += " footref inline-footnote inline-footnote-end formatting-inline-footnote",
|
|
w = stream.pos),
|
|
"%" === stream.peek() && stream.match("%%", !1) ? (state.comment ? (y += " comment formatting comment-end",
|
|
state.comment = !1) : (y += " comment formatting comment-start",
|
|
state.comment = !0),
|
|
w = stream.pos + 2) : state.comment && (y += " comment")
|
|
}
|
|
if (g && (state.hmdLinkType || state.image || state.linkText || (isLetter(stream.peek()!) && stream.match(SN) || (p = stream.peek(),
|
|
!/[\s<>()[\]\\.,;:\s@\"`]/.test(p!) && stream.match(xN))) && (y += " url",
|
|
w = stream.pos)),
|
|
h && state.inFootnote) {
|
|
let F = stream.match(/^\s*/, !1)[0].replace(/\stream/g, " ").length;
|
|
F && F % stream.tabSize == 0 ? y += " line-HyperMD-footnote" : state.inFootnote = !1
|
|
}
|
|
let O = h && "[" === stream.peek() && stream.match(/^\[((?:[^\]\\]|\\.)*)\]:/, !1);
|
|
if (O) {
|
|
let B = O[1];
|
|
if ("^" !== B[0] || !/\s/.test(B))
|
|
return stream.match(/\[\^?/),
|
|
state.hmdLinkType = LinkType.FOOTNOTE,
|
|
state.formatting = "link",
|
|
state.linkText = !0,
|
|
y += "formatting formatting-link link " + CLASSES[LinkType.FOOTNOTE]
|
|
} else if (state.hmdLinkType === LinkType.FOOTNOTE) {
|
|
if ("]" === stream.peek() && stream.match("]:"))
|
|
return y += " formatting formatting-link link " + CLASSES[LinkType.FOOTNOTE],
|
|
state.linkText = !1,
|
|
state.inFootnote = !0,
|
|
state.hmdLinkType = LinkType.MAYBE_FOOTNOTE_URL,
|
|
//@ts-ignore
|
|
state.f = state.inline = markdownMode.startState().inline,
|
|
y;
|
|
y += " link " + CLASSES[LinkType.FOOTNOTE]
|
|
} else if (state.hmdLinkType === LinkType.MAYBE_FOOTNOTE_URL) {
|
|
if (stream.eatSpace())
|
|
return y;
|
|
if (isLetter(stream.peek()!) && stream.match(SN))
|
|
return y += " url hmd-footnote-url",
|
|
state.hmdLinkType = LinkType.MAYBE_FOOTNOTE_URL_TITLE,
|
|
y;
|
|
state.hmdLinkType = LinkType.NONE
|
|
} else if (state.hmdLinkType === LinkType.MAYBE_FOOTNOTE_URL_TITLE) {
|
|
if (stream.eatSpace())
|
|
return y;
|
|
if (state.hmdLinkType = LinkType.NONE,
|
|
stream.match(/^(["']).*?\1/) || stream.match(/^\([^)]*?\)/))
|
|
return y += " hmd-footnote-url-title"
|
|
}
|
|
}
|
|
if (state.hmdTable && "|" === stream.peek() && "\\" !== stream.string[stream.pos - 1] && function(e)
|
|
{
|
|
e.code = !1,
|
|
e.comment = !1,
|
|
e.em = !1,
|
|
e.formatting = !1,
|
|
e.highlight = !1,
|
|
e.hmdHashtag = !1,
|
|
e.hmdLinkType = LinkType.NONE,
|
|
e.isAlias = !1,
|
|
e.internalEmbed = !1,
|
|
e.internalLink = !1,
|
|
e.linkHref = !1,
|
|
e.linkText = !1,
|
|
e.linkTitle = !1,
|
|
e.strikethrough = !1,
|
|
e.strong = !1
|
|
}(state),
|
|
state.hmdNextState)
|
|
stream.pos = state.hmdNextPos!,
|
|
y += " " + (state.hmdNextStyle || ""),
|
|
Object.assign(state, state.hmdNextState),
|
|
state.hmdNextState = null,
|
|
state.hmdNextStyle = null,
|
|
state.hmdNextPos = null;
|
|
else {
|
|
let N = h && 0 !== stream.pos;
|
|
if (b) {
|
|
//@ts-ignore
|
|
let R = markdownMode.copyState(state), H = stream.pos;
|
|
y += " " + (markdownMode.token(stream, R) || ""),
|
|
stream.pos = H
|
|
} else
|
|
y += " " + (markdownMode.token(stream, state) || "");
|
|
//@ts-ignore
|
|
N && state.f === state.block && (state.f = state.inline = markdownMode.startState().inline),
|
|
state.inFootnote && (state.indentationDiff = 0)
|
|
}
|
|
y = function(e, text) {
|
|
return text ? (!config.hr && e.hr && (text = clearSubstringWords(text, "hr"),
|
|
e.hr = !1),
|
|
!config.headers && e.header && (text = clearSubstringWords(text, "header"),
|
|
e.header = 0),
|
|
!config.indentedCode && e.indentedCode && (text = clearSubstringWords(text, "inline-code"),
|
|
e.indentedCode = !1),
|
|
!config.blockquotes && e.quote && (text = clearSubstringWords(text, "quote"),
|
|
e.quote = 0),
|
|
!config.lists && e.list && (text = clearSubstringWords(text, "list"),
|
|
e.list = !1),
|
|
text) : text
|
|
}(state, y),
|
|
y.includes("formatting-task") && (y += " line-HyperMD-task-line"),
|
|
state.hmdHashtag && (y += " " + config.tokenTypeOverrides.hashtag),
|
|
-1 !== w && (stream.pos = w),
|
|
state.header && (state.isHeading = !0),
|
|
!i.htmlBlock && state.htmlState && (i.htmlBlock = state.f);
|
|
let V = state.f === i.htmlBlock
|
|
, z = -1 === state.code;
|
|
if (v = v && !(V || z),
|
|
g = g && v && !(state.code || state.indentedCode || state.linkHref),
|
|
state.hmdTable && V) {
|
|
let q = stream.current();
|
|
/(?:^|[^\\])\|/.test(q) && ("" === y.trim() || /string|attribute/.test(y)) && (V = !1,
|
|
a = !1,
|
|
state.htmlState = null,
|
|
state.block = i.block,
|
|
//@ts-ignore
|
|
state.f = state.inline = markdownMode.startState().inline,
|
|
stream.pos = "|" === q ? stream.start : stream.start + 1)
|
|
}
|
|
let U = stream.current();
|
|
if (V !== a && (V ? (y += " hmd-html-begin",
|
|
i.htmlBlock = state.f) : y += " hmd-html-end"),
|
|
(c || z) && (state.localMode && c || (y = y.replace("inline-code", "")),
|
|
y += " line-HyperMD-codeblock line-background-HyperMD-codeblock-bg hmd-codeblock",
|
|
z !== c && (z ? c || (y += " line-HyperMD-codeblock-begin line-background-HyperMD-codeblock-begin-bg") : y += " line-HyperMD-codeblock-end line-background-HyperMD-codeblock-end-bg")),
|
|
v) {
|
|
let _ = state.hmdTable;
|
|
if (h && _)
|
|
(_ == TableType.SIMPLE ? IN : ON).test(stream.string) ? (state.hmdTableCol = 0,
|
|
state.hmdTableRow++) : resetTable(state);
|
|
if (h && state.header && (/^(?:---+|===+)\s*$/.test(stream.string) && state.prevLine && state.prevLine.header ? y += " line-HyperMD-header-line line-HyperMD-header-line-" + state.header : y += " line-HyperMD-header line-HyperMD-header-" + state.header),
|
|
state.indentedCode && (y += " hmd-indented-code"),
|
|
state.quote) {
|
|
if (stream.match(/^\s*>/, !1) && !stream.eol() || (y += " line-HyperMD-quote line-HyperMD-quote-" + state.quote,
|
|
/^ {0,3}\>/.test(stream.string) || (y += " line-HyperMD-quote-lazy")),
|
|
h && (d = U.match(/^\s+/)))
|
|
return stream.pos = d![0].length,
|
|
(y += " hmd-indent-in-quote").trim();
|
|
if (state.quote > u)
|
|
{
|
|
const I = "[" === stream.peek() && stream.match(/^\[!([^\]]+)\]([+\-]?)(?:\s|$)/);
|
|
if(I)
|
|
y += " line-HyperMD-callout hmd-callout line-HyperMD-quote line-HyperMD-quote-" + state.quote
|
|
}
|
|
}
|
|
let W = (state.listStack[state.listStack.length - 1] || 0) + 3
|
|
, j = h && /^\s+$/.test(U) && (!1 !== state.list || stream.indentation() <= W)
|
|
, G = state.list && y.includes("formatting-list");
|
|
if (G || j && (!1 !== state.list || stream.match(EN, !1))) {
|
|
let K = state.listStack && state.listStack.length || 0;
|
|
if (j) {
|
|
if (stream.match(EN, !1))
|
|
!1 === state.list && K++;
|
|
else {
|
|
for (; K > 0 && stream.pos < state.listStack[K - 1]; )
|
|
K--;
|
|
if (!K)
|
|
return y.trim() || null;
|
|
y += " line-HyperMD-list-line-nobullet line-HyperMD-list-line line-HyperMD-list-line-".concat(K.toString())
|
|
}
|
|
y += " hmd-list-indent hmd-list-indent-".concat(K.toString())
|
|
} else
|
|
G && (y += " line-HyperMD-list-line line-HyperMD-list-line-".concat(K.toString()))
|
|
}
|
|
if (f !== state.linkText && (f || state.internalLink || state.internalEmbed ? state.hmdLinkType !== LinkType.FOOTNOTE && (state.hmdLinkType in CLASSES && (y += " " + CLASSES[state.hmdLinkType]),
|
|
state.hmdLinkType = LinkType.NONE) : (d = stream.match(/^([^\]]+)\](\(| ?\[|\:)?/, !1)) ? d[2] ? "[" !== d[2] && " [" !== d[2] || "]" !== stream.string.charAt(stream.pos + d[0].length) ? state.hmdLinkType = LinkType.NORMAL : state.hmdLinkType = LinkType.BARELINK2 : "^" !== d[1][0] || /\s/.test(d[1]) ? state.hmdLinkType = LinkType.BARELINK : state.hmdLinkType = LinkType.FOOTREF : state.hmdLinkType = LinkType.BARELINK),
|
|
m !== state.linkHref && (m ? state.hmdLinkType && (y += " " + CLASSES[state.hmdLinkType],
|
|
state.hmdLinkType = LinkType.NONE) : "[" === U && "]" !== stream.peek() && (state.hmdLinkType = LinkType.FOOTREF2)),
|
|
state.hmdLinkType !== LinkType.NONE && state.hmdLinkType in CLASSES && (y += " " + CLASSES[state.hmdLinkType]),
|
|
state.inlineFootnote && (y += " footref inline-footnote"),
|
|
k && U.length > 1) {
|
|
let Y = U.length - 1
|
|
, Z = y.replace("formatting-escape", "escape") + " hmd-escape-char";
|
|
return state.hmdOverride = function(e, stream) {
|
|
return e.pos += Y,
|
|
stream.hmdOverride = null,
|
|
Z.trim()
|
|
}
|
|
,
|
|
y += " hmd-escape-backslash",
|
|
stream.pos -= Y,
|
|
y
|
|
}
|
|
if (!y.trim() && config.table) {
|
|
let X = !1;
|
|
if ("|" === U.charAt(0) && (stream.pos = stream.start + 1,
|
|
U = "|",
|
|
X = !0),
|
|
!_ && state.prevLine && state.prevLine.stream && state.prevLine.stream.string.trim() && !state.wasHeading && (X = !1),
|
|
X) {
|
|
if (!_) {
|
|
PN.test(stream.string) ? _ = TableType.SIMPLE : FN.test(stream.string) && (_ = TableType.NORMAL);
|
|
let $: string[] | undefined = void 0;
|
|
if (_) {
|
|
let Q = stream.lookAhead(1);
|
|
if (_ === TableType.NORMAL ? FN.test(Q) ? Q = Q.replace(/^\s*\|/, "").replace(/\|\s*$/, "") : _ = TableType.NONE : _ === TableType.SIMPLE && (PN.test(Q) || (_ = TableType.NONE)),
|
|
_) {
|
|
$ = Q.split("|");
|
|
for (let J = 0; J < $.length; J++) {
|
|
let ee = $[J];
|
|
if (BN.test(ee))
|
|
ee = "right";
|
|
else if (NN.test(ee))
|
|
ee = "left";
|
|
else if (RN.test(ee))
|
|
ee = "center";
|
|
else {
|
|
if (!HN.test(ee)) {
|
|
_ = TableType.NONE;
|
|
break
|
|
}
|
|
ee = "default"
|
|
}
|
|
$[J] = ee
|
|
}
|
|
}
|
|
}
|
|
_ && (state.hmdTable = _,
|
|
state.hmdTableColumns = $!,
|
|
"rtl" === readSide(stream.string) && (state.hmdTableRTL = !0),
|
|
state.hmdTableRow = state.hmdTableCol = 0)
|
|
}
|
|
if (_) {
|
|
let te = state.hmdTableColumns.length - 1
|
|
, ne = state.hmdTableCol
|
|
, ee = state.hmdTableRow;
|
|
0 == ne && (y += " line-HyperMD-table-".concat(_.toString(), " line-HyperMD-table-row line-HyperMD-table-row-").concat(ee.toString()),
|
|
state.hmdTableRTL && (y += " line-HyperMD-table-rtl")),
|
|
_ === TableType.NORMAL && (0 === state.hmdTableCol && /^\s*\|$/.test(stream.string.slice(0, stream.pos)) || stream.match(/^\s*$/, !1)) ? y += " hmd-table-sep hmd-table-sep-dummy" : state.hmdTableCol < te && (y += " hmd-table-sep hmd-table-sep-".concat(ne.toString()),
|
|
state.hmdTableCol += 1)
|
|
}
|
|
}
|
|
}
|
|
if (_ && 1 === state.hmdTableRow && y.includes("emoji") && (y = ""),
|
|
g && "<" === U) {
|
|
let ie = null;
|
|
if ("!" === stream.peek() && stream.match(/^\![A-Z]+/) ? ie = ">" : "!" === stream.peek() && stream.match("![CDATA[") ? ie = "]]>" : "?" === stream.peek() && (ie = "?>"),
|
|
null != ie)
|
|
return enterMode(stream, state, null, {
|
|
endTag: ie,
|
|
style: (y + " comment hmd-cdata-html").trim()
|
|
})
|
|
}
|
|
if (config.hashtag && g)
|
|
if (state.hmdHashtag) {
|
|
let re = !1;
|
|
if (!(y = y.replace(/((formatting )?formatting-em|em) /g, "")).includes("formatting") && !/^\s*$/.test(U)) {
|
|
d = U.match(TN);
|
|
let oe = U.length - (d ? d[0].length : 0);
|
|
oe > 0 && (stream.backUp(oe),
|
|
re = !0)
|
|
}
|
|
if (re || (re = stream.eol()),
|
|
re || (re = !TN.test(stream.peek()!)),
|
|
re)
|
|
{
|
|
let le = stream.current();
|
|
y += " hashtag-end " + (le = "tag-" + le.replace(/[^_a-zA-Z0-9\-]/g, "")),
|
|
state.hmdHashtag = !1
|
|
}
|
|
} else if ("#" === U && !state.linkText && !state.image && (h || /^\s*$/.test(stream.string.charAt(stream.start - 1)))) {
|
|
let ae = stream.string.slice(stream.pos).replace(/\\./g, "")
|
|
, se = TN.exec(ae);
|
|
if (se && /[^0-9]/.test(se[0])) {
|
|
let le = "tag-" + se[0].replace(/[^_a-zA-Z0-9\-]/g, "");
|
|
state.hmdHashtag = !0,
|
|
y += " formatting formatting-hashtag hashtag-begin " + config.tokenTypeOverrides.hashtag + " " + le
|
|
}
|
|
}
|
|
}
|
|
return y.trim() || null;
|
|
},
|
|
}
|
|
}, 'd-any'); |