Files
thzxx 5919dd9f66 feat: v0.2.5 — 内置语法高亮 + exportPDF + benchmark + CI 并行
- 新增 src/highlight.ts 零依赖轻量高亮器:13 种语言,先转义后
  着色保证安全,输出 me-hl-* 类,MeEditor.highlight 即插即用
- exportTool 新增 editor.exportPDF()(隐藏 iframe + window.print),
  exportHTML/exportPDF 共用 HTML 构建逻辑
- imagePaste 支持 maxSizeKB 限制,超限 toast 警告
- npm run bench 性能基准:parseMarkdown 1MB ≈ 51ms
- CI 测试拆分为 parser/core/rest 三个并行 job + 跨版本 verify job
- docs.html/README 补齐新 API、事件、高亮文档;取消跟踪 dist 产物;
  版本 0.2.4 → 0.2.5,测试 725 → 768
2026-08-09 08:59:55 +08:00

112 lines
2.8 KiB
JavaScript

#!/usr/bin/env node
/**
* MetonaEditor 性能基准 — 解析器吞吐测试
* 用法: npm run build && npm run bench
*/
const MeEditor = require('../dist/metona-editor.cjs');
const { parseMarkdown } = MeEditor;
const buildSample = (kb) => {
const chunk = [
'# 性能基准文档',
'',
'这是一个 **粗体** 与 *斜体* 的段落,包含 `inline code` 和 [链接](https://example.com)。',
'',
'- 列表项一',
'- 列表项二',
' - 嵌套项',
' - 嵌套项二',
'- 列表项三',
'',
'1. 有序一',
'2. 有序二',
'',
'> 引用内容',
'> 继续引用',
'',
'```js',
'function hello(name) {',
' const msg = `Hello, ${name}!`;',
' return msg;',
'}',
'```',
'',
'| 列一 | 列二 | 列三 |',
'| --- | :---: | ---: |',
'| A | B | C |',
'| D | E | F |',
'',
'---',
'',
'引用链接:[文档][ref]',
'',
'[ref]: https://example.com/docs "参考"',
'',
'脚注示例[^1]',
'',
'[^1]: 脚注内容',
'',
'## 二级标题',
'',
'$$E = mc^2$$',
'',
'H~2~O 与 x^2^,还有 :rocket: emoji。',
'',
].join('\n');
const repeat = Math.max(1, Math.ceil((kb * 1024) / chunk.length));
return chunk.repeat(repeat);
};
const median = (arr) => {
const s = [...arr].sort((a, b) => a - b);
const mid = Math.floor(s.length / 2);
return s.length % 2 ? s[mid] : (s[mid - 1] + s[mid]) / 2;
};
const benchmark = (label, fn, iterations = 5) => {
// warmup
fn();
const times = [];
for (let i = 0; i < iterations; i++) {
const t0 = process.hrtime.bigint();
fn();
const t1 = process.hrtime.bigint();
times.push(Number(t1 - t0) / 1e6);
}
const ms = median(times);
return { label, ms: ms.toFixed(1), opsPerSec: (1000 / ms).toFixed(1) };
};
console.log('MetonaEditor 性能基准');
console.log('=====================');
console.log(`版本: ${MeEditor.VERSION}`);
console.log('');
for (const size of [64, 256, 1024]) {
const sample = buildSample(size);
const r = benchmark(`parseMarkdown ${size}KB (${sample.length.toLocaleString()} chars)`, () => {
const html = parseMarkdown(sample);
if (!html) throw new Error('empty output');
});
console.log(` ${r.label}: ${r.ms} ms (${r.opsPerSec} ops/s)`);
}
console.log('');
// 语法高亮基准
try {
const code = Array.from({ length: 200 }, (_, i) =>
`function f${i}(a, b) { const s = "str${i}"; // comment\n return a + b + ${i}; }`,
).join('\n');
const r = benchmark('highlight 200 functions (js)', () => {
MeEditor.highlight(code, 'js');
});
console.log(` ${r.label}: ${r.ms} ms (${r.opsPerSec} ops/s)`);
} catch (_) {
console.log(' (highlight benchmark skipped)');
}
console.log('');
console.log('完成。');