"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.renderTikzjax = void0; const node_tikzjax_1 = __importDefault(require("node-tikzjax")); const common_1 = require("./common"); const queue_1 = __importDefault(require("./queue")); /** * Extract TikZ code blocks from post content and render them into SVGs with `node-tikzjax`. * The generated SVGs are saved in cache with a hash as their keys for better performance. */ asyncfunctionrenderTikzjax(data) { const config = this.config.tikzjax; if (!data.tikzjax && !config.every_page) { return; } // Set up loggers. const logPrefix = '[hexo-filter-tikzjax]'; constdebug = (...args) => this.log.debug.apply(this.log, [logPrefix, ...args]); consterror = (...args) => this.log.error.apply(this.log, [logPrefix, ...args]); queue_1.default.setLogger({ debug, error }); // Find all TikZ and TikZ-cd code blocks in Markdown source. const regex = /```tikz(cd)?\n([\s\S]+?)```/g; const matches = data.content.matchAll(regex); forawait (const match of matches) { // Generate a hash for each TikZ code block as its cache key. const hash = (0, common_1.md5)(JSON.stringify(match[0]) + JSON.stringify(config)); let svg = common_1.localStorage.getItem(hash); if (!svg) { const input = match[2]?.trim(); //match[0]=full string, match[1]=empty or cd, match[2]=tex codes if (!input) { continue; } // Since `node-tikzjax` does not allow concurrent calls, // we have to use a task queue to make sure that only one call is running at a time. // This could be a bottleneck when generating a large number of posts. debug('Processing TikZ graphic...', hash); svg = awaitnewPromise((resolve) => { queue_1.default.enqueue(async () => { const svg = await (0, node_tikzjax_1.default)(input, { showConsole: this.env.debug, ...config.tikzjax_options, }); resolve(svg); }); }); if (svg) { common_1.localStorage.setItem(hash, svg); debug('TikZ graphic saved in cache.', hash); } else { debug('TikZ graphic not generated. Skipped.', hash); } } else { debug('TikZ graphic found in cache. Skip rendering.', hash); } // Replace the TikZ or TikZ-cd code block with a placeholder // so that we can insert the SVG later in `insertSvg` function. if (match[1]) { const placeholder = `<!-- tikzjax-cd-placeholder-${hash} -->`; data.content = data.content.replace(match[0], placeholder); } else { const placeholder = `<!-- tikzjax-placeholder-${hash} -->`; data.content = data.content.replace(match[0], placeholder); } } return data; } exports.renderTikzjax = renderTikzjax;
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.insertSvg = void0; const common_1 = require("./common"); /** * Insert generated SVGs into HTML of the post as inline tags. * * We separate this function from `renderTikzjax` and run them in different filters, * since we need the Markdown source to render TikZ graphics (in `before_post_render`). * But insert SVGs into Markdown source will cause problems, so we wait until the Markdown * source is rendered into HTML, then insert SVGs into HTML (in `after_render:html`). * * Since we need to process archive/tags/categories pages too, if they contains posts which * have TikZ graphs in it, the `after_post_render` filter is not sufficient. */ functioninsertSvg(html, locals) { const config = this.config.tikzjax; const page = locals.page; const indexContains = page.__index && page.posts.toArray().find((post) => post.tikzjax); // Only process if a post contains TikZ, or it's an index page and one of the posts contains TikZ. if (!page.tikzjax && !config.every_page && !indexContains) { return; } // Prepend CSS for TikZJax. html = html.replace(/<head>(?!<\/head>).+?<\/head>/s, (str) => str.replace('</head>', `<link rel="stylesheet" type="text/css" href="${config.font_css_url}" />` + (config.inline_style ? `<style>${config.inline_style}</style>` : '') + '</head>')); // Find all TikZ placeholders inserted by `renderTikzjax`. const regex = /<!-- tikzjax-(cd-)?placeholder-(\w+?) -->/g; const matches = html.matchAll(regex); constdebug = (...args) => this.log.debug('[hexo-filter-tikzjax]', ...args); for (const match of matches) { const hash = match[2]?.trim(); if (!hash) { continue; } const svg = common_1.localStorage.getItem(hash); debug('Looking for SVG in cache...', hash); if (svg) { if (match[1]) { const svg_cd = svg.replace('g stroke="#000"', 'g stroke="#000" fill="#000"') .replaceAll('#000', 'currentColor') .replace(/\b(width|height)=["']([\d.]+)["']/g, (match, attr, value) => { const scaledValue = parseFloat(value) * 1.5; return`${attr}="${scaledValue.toFixed(3)}"`; }) html = html.replace(match[0], `<p><span class="tikzjax">${svg_cd}</span></p>`); debug('SVG commutative diagram inserted!', hash); } else { html = html.replace(match[0], `<p><span class="tikzjax">${svg}</span></p>`); debug('SVG inserted!', hash); } } else { debug('SVG not found in cache. Skipped.', hash); } } return html; } exports.insertSvg = insertSvg;
于是现在只需要使用 tikzcd 代码块就能画出想要的交换图:
ker0kerker00X0XX0000Y0YY00coker0cokercoker00fguv±
本来以为事情到这里就结束了, 结果经过仔细观察, 这字符的间距是不是不太对? 它好像把我的 ker 拆成了 k-er, 把我的 coker 拆成了 cok-er, 所以 k 和 e 的间距变小了一点. 这是不能容忍的, 必须要出重拳!