UNPKG

hackmd-to-html-cli

Version:

A node.js CLI tool for converting HackMD markdown to HTML.

199 lines 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BlockquoteToken = exports.BlockquoteTokenProperty = void 0; exports.parseBlockquoteParams = parseBlockquoteParams; exports.MarkdownItBlockquoteX = MarkdownItBlockquoteX; const token_1 = require("./token"); var BlockquoteTokenProperty; (function (BlockquoteTokenProperty) { BlockquoteTokenProperty[BlockquoteTokenProperty["name"] = 0] = "name"; BlockquoteTokenProperty[BlockquoteTokenProperty["time"] = 1] = "time"; BlockquoteTokenProperty[BlockquoteTokenProperty["color"] = 2] = "color"; BlockquoteTokenProperty[BlockquoteTokenProperty["text"] = 3] = "text"; BlockquoteTokenProperty[BlockquoteTokenProperty["blockquoteXStart"] = 4] = "blockquoteXStart"; BlockquoteTokenProperty[BlockquoteTokenProperty["blockquoteXEnd"] = 5] = "blockquoteXEnd"; })(BlockquoteTokenProperty || (exports.BlockquoteTokenProperty = BlockquoteTokenProperty = {})); class BlockquoteToken { constructor(property, value) { this.property = property; this.value = value; } } exports.BlockquoteToken = BlockquoteToken; function parseBlockquoteParams(src) { var _a, _b, _c, _d, _e, _f, _g, _h; // [name=ChengHan Wu] [time=Sun, Jun 28, 2015 10:00 PM] [color=red] const pattern = /\[(.*?)=(.*?)\]/g; const matching = [...src.matchAll(pattern)]; if (matching.length === 0) return []; const tokens = []; let j = 0; let blockquoteStart = false; // decide whether close for (let i = 0; i < matching.length; i++) { const property = (_b = (_a = matching[i][1]) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : ''; const value = (_c = matching[i][2]) !== null && _c !== void 0 ? _c : ''; const textLen = (_d = matching[i][0].length) !== null && _d !== void 0 ? _d : 0; const pos = (_f = (_e = matching[i]) === null || _e === void 0 ? void 0 : _e.index) !== null && _f !== void 0 ? _f : 0; if (pos > j) { if (blockquoteStart) { tokens.push(new BlockquoteToken(BlockquoteTokenProperty.blockquoteXEnd, '')); blockquoteStart = false; } // normal text tokens.push(new BlockquoteToken(BlockquoteTokenProperty.text, src.substring(j, pos))); } switch (property) { case 'name': if (tokens.length == 0 || ((_g = tokens[tokens.length - 1]) === null || _g === void 0 ? void 0 : _g.property) === BlockquoteTokenProperty.text) { if (blockquoteStart) { tokens.push(new BlockquoteToken(BlockquoteTokenProperty.blockquoteXEnd, '')); } tokens.push(new BlockquoteToken(BlockquoteTokenProperty.blockquoteXStart, '')); blockquoteStart = true; } tokens.push(new BlockquoteToken(BlockquoteTokenProperty.name, value.trimStart())); break; case 'time': if (tokens.length == 0 || ((_h = tokens[tokens.length - 1]) === null || _h === void 0 ? void 0 : _h.property) === BlockquoteTokenProperty.text) { if (blockquoteStart) { tokens.push(new BlockquoteToken(BlockquoteTokenProperty.blockquoteXEnd, '')); } tokens.push(new BlockquoteToken(BlockquoteTokenProperty.blockquoteXStart, '')); blockquoteStart = true; } tokens.push(new BlockquoteToken(BlockquoteTokenProperty.time, value.trimStart())); break; case 'color': tokens.push(new BlockquoteToken(BlockquoteTokenProperty.color, value.trimStart())); break; default: tokens.push(new BlockquoteToken(BlockquoteTokenProperty.text, value)); break; } j = pos + textLen + 1; } if (blockquoteStart) { tokens.push(new BlockquoteToken(BlockquoteTokenProperty.blockquoteXEnd, '')); blockquoteStart = false; } if (src.length != j) { tokens.push(new BlockquoteToken(BlockquoteTokenProperty.text, src.substring(j, src.length))); } return tokens; } function MarkdownItBlockquoteX(md) { function blockquoteX(state) { var _a, _b, _c; const blockTokens = state.tokens; let detect = false; let blockquoteOpenAt = 0; for (let j = 0; j < blockTokens.length; j++) { if (blockTokens[j].type === 'blockquote_open') { blockquoteOpenAt = j; detect = true; } if (blockTokens[j].type === 'blockquote_close') { detect = false; } if (!detect) { continue; } if (blockTokens[j].type === 'inline') { for (let n = 0; n < blockTokens[j].children.length; n++) { // find text token if (blockTokens[j].children[n].type !== "text") continue; // avoid matching same children[n] let nextN = n; // try to parse const m = parseBlockquoteParams(blockTokens[j].children[n].content); if (m.length === 0) continue; // render const newTokens = []; // when the content is // [invalid] [name] [time] // we want to render // // <span>[invalid]<span> // <span class="blockquoteX"> // <span class="material-symbols-outlined material-symbols-outlined-fill"> // name // </span> // <span class="material-symbols-outlined"> // time // </span> // </span> // we only add the class `blockquoteX` before the `name` or `time` // In hackMD, it only supports the format [name=blablabla] or [name= blablabla]. // However, in hmd2html, we use looser constraints, meaning it supports spaces between words. // e.g. [ name = blablabla ] let token; // parse name, time, color let color = ''; for (let s = 0; s < m.length; s++) { const property = (_a = m[s]) === null || _a === void 0 ? void 0 : _a.property; const value = (_c = (_b = m[s]) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : ''; switch (property) { case BlockquoteTokenProperty.blockquoteXStart: token = new token_1.MyToken('blockquoteX_open', 'span', 1); token.attrs = [['class', 'blockquoteX']]; newTokens.push(token); break; case BlockquoteTokenProperty.blockquoteXEnd: token = new token_1.MyToken('blockquoteX_close', 'span', -1); newTokens.push(token); break; case BlockquoteTokenProperty.name: token = new token_1.MyToken('blockquoteX_name_open', 'span', 1); token.attrs = [['class', 'material-symbols-outlined material-symbols-outlined-fill']]; newTokens.push(token); token = new token_1.MyToken('text', '', 0); nextN++; token.content = 'person'; newTokens.push(token); token = new token_1.MyToken('blockquoteX_name_close', 'span', -1); newTokens.push(token); token = new token_1.MyToken('text', '', 0); nextN++; token.content = value.trim(); newTokens.push(token); break; case BlockquoteTokenProperty.time: token = new token_1.MyToken('blockquoteX_date_open', 'span', 1); token.attrs = [['class', 'material-symbols-outlined']]; newTokens.push(token); token = new token_1.MyToken('text', '', 0); nextN++; token.content = 'schedule'; newTokens.push(token); token = new token_1.MyToken('blockquoteX_date_close', 'span', -1); newTokens.push(token); token = new token_1.MyToken('text', '', 0); nextN++; token.content = value.trim(); newTokens.push(token); break; case BlockquoteTokenProperty.text: token = new token_1.MyToken('text', '', 0); nextN++; token.content = value; newTokens.push(token); break; case BlockquoteTokenProperty.color: color = value !== null && value !== void 0 ? value : ''; } } blockTokens[j].children = md.utils.arrayReplaceAt(blockTokens[j].children, n, newTokens); if (color != '') { blockTokens[blockquoteOpenAt].attrs = [['style', 'border-color:' + color + ';']]; } n = nextN; } } } } md.core.ruler.push('blockquoteX', blockquoteX); } //# sourceMappingURL=blockquotex.js.map