markmap-lib
Version:
Visualize your Markdown as mindmaps with Markmap
315 lines (314 loc) • 10.5 kB
JavaScript
import { Hook, buildJSItem, buildCSSItem, noop, wrapFunction } from "markmap-common";
import { parse } from "yaml";
import hljs from "highlight.js";
import katexPluginModule from "@vscode/markdown-it-katex";
function createTransformHooks(transformer) {
return {
transformer,
parser: new Hook(),
beforeParse: new Hook(),
afterParse: new Hook(),
retransform: new Hook()
};
}
function definePlugin(plugin2) {
return plugin2;
}
const svgMarked = '<svg width="16" height="16" viewBox="0 -3 24 24"><path d="M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2m-9 14-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8z"/></svg>\n';
const svgUnmarked = '<svg width="16" height="16" viewBox="0 -3 24 24"><path fill-rule="evenodd" d="M6 5a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1zM3 6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3v-5z" clip-rule="evenodd"/></svg>\n';
const name$5 = "checkbox";
const images = {
" ": svgUnmarked.trim(),
x: svgMarked.trim()
};
const plugin$3 = definePlugin({
name: name$5,
transform(transformHooks) {
transformHooks.parser.tap((md) => {
md.core.ruler.before("inline", "checkbox", (state) => {
for (let i = 2; i < state.tokens.length; i += 1) {
const token = state.tokens[i];
if (token.type === "inline" && token.content) {
const prevType = state.tokens[i - 1].type;
const prevPrevType = state.tokens[i - 2].type;
if (prevType === "heading_open" || prevType === "paragraph_open" && prevPrevType === "list_item_open") {
token.content = token.content.replace(
/^\[(.)\] /,
(m, g) => images[g] ? `${images[g]} ` : m
);
}
}
}
return false;
});
});
return {};
}
});
const name$4 = "frontmatter";
const pluginFrontmatter = definePlugin({
name: name$4,
transform(transformHooks) {
transformHooks.beforeParse.tap((_md, context) => {
var _a;
const { content } = context;
if (!/^---\r?\n/.test(content)) return;
const match = /\n---\r?\n/.exec(content);
if (!match) return;
const raw = content.slice(4, match.index).trimEnd();
let frontmatter;
try {
frontmatter = parse(raw.replace(/\r?\n|\r/g, "\n"));
if (frontmatter == null ? void 0 : frontmatter.markmap) {
frontmatter.markmap = normalizeMarkmapJsonOptions(
frontmatter.markmap
);
}
} catch {
return;
}
context.frontmatter = frontmatter;
context.parserOptions = {
...context.parserOptions,
...(_a = frontmatter == null ? void 0 : frontmatter.markmap) == null ? void 0 : _a.htmlParser
};
context.frontmatterInfo = {
lines: content.slice(0, match.index).split("\n").length + 1,
offset: match.index + match[0].length
};
});
return {};
}
});
function normalizeMarkmapJsonOptions(options) {
if (!options) return;
["color", "extraJs", "extraCss"].forEach((key) => {
if (options[key] != null) options[key] = normalizeStringArray(options[key]);
});
["duration", "maxWidth", "initialExpandLevel"].forEach((key) => {
if (options[key] != null) options[key] = normalizeNumber(options[key]);
});
return options;
}
function normalizeStringArray(value) {
let result;
if (typeof value === "string") result = [value];
else if (Array.isArray(value))
result = value.filter((item) => item && typeof item === "string");
return (result == null ? void 0 : result.length) ? result : void 0;
}
function normalizeNumber(value) {
if (isNaN(+value)) return;
return +value;
}
const name$3 = "hljs";
const preloadScripts$1 = [
`@highlightjs/cdn-assets@${"11.11.1"}/highlight.min.js`
].map((path) => buildJSItem(path));
const styles$1 = [
`@highlightjs/cdn-assets@${"11.11.1"}/styles/default.min.css`
].map((path) => buildCSSItem(path));
const config$1 = {
versions: {
hljs: "11.11.1"
},
preloadScripts: preloadScripts$1,
styles: styles$1
};
const plugin$2 = definePlugin({
name: name$3,
config: config$1,
transform(transformHooks) {
var _a;
let enableFeature = noop;
transformHooks.parser.tap((md) => {
md.set({
highlight: (str, language) => {
enableFeature();
return hljs.highlightAuto(str, language ? [language] : void 0).value;
}
});
});
transformHooks.beforeParse.tap((_, context) => {
enableFeature = () => {
context.features[name$3] = true;
};
});
return {
styles: (_a = plugin$2.config) == null ? void 0 : _a.styles
};
}
});
var define_define_KATEX_RESOURCES_default = ["katex@0.16.18/dist/fonts/KaTeX_AMS-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Caligraphic-Bold.woff2", "katex@0.16.18/dist/fonts/KaTeX_Caligraphic-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Fraktur-Bold.woff2", "katex@0.16.18/dist/fonts/KaTeX_Fraktur-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Main-Bold.woff2", "katex@0.16.18/dist/fonts/KaTeX_Main-BoldItalic.woff2", "katex@0.16.18/dist/fonts/KaTeX_Main-Italic.woff2", "katex@0.16.18/dist/fonts/KaTeX_Main-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Math-BoldItalic.woff2", "katex@0.16.18/dist/fonts/KaTeX_Math-Italic.woff2", "katex@0.16.18/dist/fonts/KaTeX_SansSerif-Bold.woff2", "katex@0.16.18/dist/fonts/KaTeX_SansSerif-Italic.woff2", "katex@0.16.18/dist/fonts/KaTeX_SansSerif-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Script-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Size1-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Size2-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Size3-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Size4-Regular.woff2", "katex@0.16.18/dist/fonts/KaTeX_Typewriter-Regular.woff2"];
const name$2 = "katex";
const preloadScripts = [
`katex@${"0.16.18"}/dist/katex.min.js`
].map((path) => buildJSItem(path));
const webfontloader = buildJSItem(
`webfontloader@${"1.6.28"}/webfontloader.js`
);
webfontloader.data.defer = true;
const styles = [`katex@${"0.16.18"}/dist/katex.min.css`].map(
(path) => buildCSSItem(path)
);
const config = {
versions: {
katex: "0.16.18",
webfontloader: "1.6.28"
},
preloadScripts,
scripts: [
{
type: "iife",
data: {
fn: (getMarkmap) => {
window.WebFontConfig = {
custom: {
families: [
"KaTeX_AMS",
"KaTeX_Caligraphic:n4,n7",
"KaTeX_Fraktur:n4,n7",
"KaTeX_Main:n4,n7,i4,i7",
"KaTeX_Math:i4,i7",
"KaTeX_Script",
"KaTeX_SansSerif:n4,n7,i4",
"KaTeX_Size1",
"KaTeX_Size2",
"KaTeX_Size3",
"KaTeX_Size4",
"KaTeX_Typewriter"
]
},
active: () => {
getMarkmap().refreshHook.call();
}
};
},
getParams({ getMarkmap }) {
return [getMarkmap];
}
}
},
webfontloader
],
styles,
resources: define_define_KATEX_RESOURCES_default
};
function interop(mod) {
return mod.default || mod;
}
const katexPlugin = interop(katexPluginModule);
const plugin$1 = definePlugin({
name: name$2,
config,
transform(transformHooks) {
var _a, _b;
let enableFeature = noop;
transformHooks.parser.tap((md) => {
md.use(katexPlugin);
["math_block", "math_inline"].forEach((key) => {
const fn = md.renderer.rules[key];
if (fn) {
md.renderer.rules[key] = wrapFunction(fn, (render, ...args) => {
enableFeature();
return render(...args);
});
}
});
});
transformHooks.beforeParse.tap((_, context) => {
enableFeature = () => {
context.features[name$2] = true;
};
});
return {
styles: (_a = plugin$1.config) == null ? void 0 : _a.styles,
scripts: (_b = plugin$1.config) == null ? void 0 : _b.scripts
};
}
});
const name$1 = "npmUrl";
const pluginNpmUrl = definePlugin({
name: name$1,
transform(transformHooks) {
transformHooks.afterParse.tap((_, context) => {
const { frontmatter } = context;
const markmap = frontmatter == null ? void 0 : frontmatter.markmap;
if (markmap) {
["extraJs", "extraCss"].forEach((key) => {
const value = markmap[key];
if (value) {
markmap[key] = value.map((path) => {
if (path.startsWith("npm:")) {
return transformHooks.transformer.urlBuilder.getFullUrl(
path.slice(4)
);
}
return path;
});
}
});
}
});
return {};
}
});
const name = "sourceLines";
const plugin = definePlugin({
name,
transform(transformHooks) {
let frontmatterLines = 0;
transformHooks.beforeParse.tap((_md, context) => {
var _a;
frontmatterLines = ((_a = context.frontmatterInfo) == null ? void 0 : _a.lines) || 0;
});
transformHooks.parser.tap((md) => {
md.renderer.renderAttrs = wrapFunction(
md.renderer.renderAttrs,
(renderAttrs, token) => {
if (token.block && token.map) {
const lineRange = token.map.map((line) => line + frontmatterLines);
token.attrSet("data-lines", lineRange.join(","));
}
return renderAttrs(token);
}
);
if (md.renderer.rules.fence) {
md.renderer.rules.fence = wrapFunction(
md.renderer.rules.fence,
(fence, tokens, idx, ...rest) => {
let result = fence(tokens, idx, ...rest);
const token = tokens[idx];
if (result.startsWith("<pre>") && token.map) {
const lineRange = token.map.map(
(line) => line + frontmatterLines
);
result = result.slice(0, 4) + ` data-lines="${lineRange.join(",")}"` + result.slice(4);
}
return result;
}
);
}
});
return {};
}
});
const plugins = [
pluginFrontmatter,
plugin$1,
plugin$2,
pluginNpmUrl,
plugin$3,
plugin
];
export {
createTransformHooks,
definePlugin,
plugin$3 as pluginCheckbox,
pluginFrontmatter,
plugin$2 as pluginHljs,
plugin$1 as pluginKatex,
pluginNpmUrl,
plugin as pluginSourceLines,
plugins
};