feat(parser): v0.1.15 — parser short+medium term improvements
Short-term fixes: - Fix ***bold italic*** / ___bold italic___ triple emphasis - Fix link text inline formatting (recursive renderInline on [**bold**](url)) - Fix backtick inline code nesting (CommonMark-compliant extractInlineCodes) - Fix tab indentation stripping in indented code blocks Medium-term improvements: - parseTokens() / renderTokens() separation API for token-level transform - registerBlockHandler() table-driven block handler registry - Backslash escape support (\* \_ \) Also: - Add 48 new test cases (583 total, 7 suites, all passing) - Parser coverage: 95.43% stmts / 91.38% branches / 100% funcs / 98.25% lines - Update README.md, site/, package.json to v0.1.15
This commit is contained in:
+9
-5
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📝</text></svg>"/>
|
||||
<title>MetonaEditor v0.1.14 — 全功能演示</title>
|
||||
<title>MetonaEditor v0.1.15 — 全功能演示</title>
|
||||
<style>
|
||||
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
||||
:root{--app-bg:#f5f6f8;--app-text:#1a1a2e;--app-card:#fff;--app-border:#e5e7eb;--app-accent:#3b82f6;--app-accent2:#8b5cf6;--header-bg:linear-gradient(135deg,#1e293b 0%,#0f172a 100%);--header-text:#f1f5f9;--badge-bg:rgba(255,255,255,.12);--badge-text:#e2e8f0}
|
||||
@@ -47,9 +47,9 @@ body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Micr
|
||||
<header class="header">
|
||||
<h1><span class="grad">Metona</span>Editor</h1>
|
||||
<div class="badges">
|
||||
<span class="badge">v0.1.14</span>
|
||||
<span class="badge">v0.1.15</span>
|
||||
<span class="badge">零依赖</span>
|
||||
<span class="badge">535 tests</span>
|
||||
<span class="badge">558 tests</span>
|
||||
<span class="badge">6 插件</span>
|
||||
<span class="badge">中文优先</span>
|
||||
</div>
|
||||
@@ -79,7 +79,8 @@ body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Micr
|
||||
</div>
|
||||
|
||||
<div class="info-grid">
|
||||
<div class="info-card"><div class="icon">🎨</div><h4>语法高亮编辑区</h4><p>标题/粗体/斜体/代码/链接/图片/列表等 10 种语法实时着色</p></div>
|
||||
<div class="info-card"><div class="icon">🎨</div><h4>三重强调 + 链接内格式</h4><p>***粗斜体*** / [**粗体链接**](url) 等语法正确渲染 ← v0.1.15</p></div>
|
||||
<div class="info-card"><div class="icon">🔧</div><h4>块级处理器表驱动</h4><p>registerBlockHandler 注册自定义语法,parseTokens/renderTokens 分离</p></div>
|
||||
<div class="info-card"><div class="icon">📂</div><h4>磁盘文件读写</h4><p>File System Access API 打开/保存真实磁盘 .md 文件</p></div>
|
||||
<div class="info-card"><div class="icon">🔢</div><h4>行号装订线</h4><p>当前行高亮,与编辑区滚动同步</p></div>
|
||||
<div class="info-card"><div class="icon">🧘</div><h4>Zen 专注模式</h4><p>工具栏自动隐藏,鼠标移到顶部滑入</p></div>
|
||||
@@ -90,7 +91,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Micr
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
MetonaEditor v0.1.14 ·
|
||||
MetonaEditor v0.1.15 ·
|
||||
<a href="index.html">首页</a> ·
|
||||
<a href="docs.html">API 文档</a> ·
|
||||
<a href="https://git.metona.cn/MetonaTeam/MetonaEditor" target="_blank" rel="noopener">源码仓库</a> · MIT
|
||||
@@ -135,6 +136,7 @@ var demoMd=[
|
||||
'',
|
||||
'| 版本 | 日期 | 测试 | 主题 |',
|
||||
'| :--- | :---: | ---: | --- |',
|
||||
'| v0.1.15 | 2026-07 | 558 | 三重强调+链接格式+转义+Token分离+块级表驱动 |',
|
||||
'| v0.1.14 | 2026-07 | 535+ | 语法高亮+Mermaid+文件系统 |',
|
||||
'| v0.1.12 | 2026-07 | 535 | A11y+Zen+滚动同步 |',
|
||||
'| v0.1.7 | 2026-07 | 532 | 编辑体验 |',
|
||||
@@ -174,8 +176,10 @@ var demoMd=[
|
||||
'## 🎨 文本样式',
|
||||
'',
|
||||
'- **粗体** / __另一种粗体__',
|
||||
'- ***粗斜体*** / ___另一种粗斜体___ ← v0.1.15',
|
||||
'- *斜体* / _另一种斜体_',
|
||||
'- ~~删除线~~ / ==高亮标记==',
|
||||
'- 链接内格式:[**粗体链接**](https://example.com) ← v0.1.15',
|
||||
'- 化学:H~2~O / 数学:x^2^',
|
||||
'- 代码:`const x = 42;`',
|
||||
'- Emoji::smile: :rocket: :fire: :rainbow: :coffee: :hamburger:',
|
||||
|
||||
+45
-4
@@ -176,7 +176,7 @@
|
||||
|
||||
<header class="docs-header">
|
||||
<h1><span class="grad">文档</span></h1>
|
||||
<p class="sub">MetonaEditor v0.1.14 完整 API、配置与使用指南</p>
|
||||
<p class="sub">MetonaEditor v0.1.15 完整 API、配置与使用指南</p>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
@@ -201,6 +201,7 @@
|
||||
<a href="#static-api">顶层函数</a>
|
||||
<div class="toc-group">语法参考</div>
|
||||
<a href="#syntax">解析器语法</a>
|
||||
<a href="#parser-api">解析器 API(v0.1.15)</a>
|
||||
<div class="toc-group">插件</div>
|
||||
<a href="#plugins">插件约定</a>
|
||||
<a href="#preset-plugins">预设插件</a>
|
||||
@@ -475,6 +476,7 @@ MeEditor<span class="c-punc">.</span><span class="c-fn">destroy</span><span clas
|
||||
<tr><td>标题</td><td><code># H1</code> ~ <code>###### H6</code></td><td><code><h1></code> ~ <code><h6></code></td></tr>
|
||||
<tr><td>段落</td><td>纯文本</td><td><code><p></code></td></tr>
|
||||
<tr><td>粗体</td><td><code>**bold**</code> <code>__bold__</code></td><td><code><strong></code></td></tr>
|
||||
<tr><td>粗斜体 <span class="badge">v0.1.15</span></td><td><code>***text***</code> <code>___text___</code></td><td><code><em><strong></code></td></tr>
|
||||
<tr><td>斜体</td><td><code>*italic*</code> <code>_italic_</code></td><td><code><em></code></td></tr>
|
||||
<tr><td>删除线</td><td><code>~~text~~</code></td><td><code><del></code></td></tr>
|
||||
<tr><td>高亮标记</td><td><code>==text==</code></td><td><code><mark></code></td></tr>
|
||||
@@ -488,16 +490,55 @@ MeEditor<span class="c-punc">.</span><span class="c-fn">destroy</span><span clas
|
||||
<tr><td>任务列表</td><td><code>- [x] done</code></td><td><code><li class="me-task-item"></code></td></tr>
|
||||
<tr><td>水平线</td><td><code>---</code> <code>***</code> <code>___</code></td><td><code><hr></code></td></tr>
|
||||
<tr><td>表格</td><td><code>| a | b |</code></td><td><code><table></code>(支持 <code>:---:</code> 列对齐)</td></tr>
|
||||
<tr><td>链接</td><td><code>[text](url)</code></td><td><code><a></code></td></tr>
|
||||
<tr><td>链接 v0.1.15</td><td><code>[**text**](url)</code></td><td>链接文本内支持行内格式</td></tr>
|
||||
<tr><td>图片</td><td><code></code></td><td><code><img></code></td></tr>
|
||||
<tr><td>自动链接</td><td><code><https://...></code></td><td><code><a></code></td></tr>
|
||||
<tr><td>Emoji</td><td><code>:smile:</code> <code>:rocket:</code></td><td>😊 🚀(80+ 常用)</td></tr>
|
||||
<tr><td>Emoji</td><td><code>:smile:</code> <code>:rocket:</code></td><td>😊 🚀(150+ 常用)</td></tr>
|
||||
<tr><td>反斜杠转义 <span class="badge">v0.1.15</span></td><td><code>\*</code> <code>\_</code> <code>\\</code></td><td>取消标点特殊含义</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>XSS 防护</h3>
|
||||
<p>所有文本经 HTML 转义。URL 自动过滤 <code>javascript:</code> <code>vbscript:</code> <code>file:</code> 及非图片 <code>data:</code> 协议。</p>
|
||||
</section>
|
||||
|
||||
<!-- ======== 解析器 API v0.1.15 ======== -->
|
||||
<section id="parser-api">
|
||||
<h2>解析器 API <span class="badge">v0.1.15 新增</span></h2>
|
||||
|
||||
<h3>parseTokens / renderTokens(解析与渲染分离)</h3>
|
||||
<p>将 Markdown 解析为中间 Token 数组,可在渲染前变换,再输出 HTML。</p>
|
||||
<pre><span class="c-kw">import</span> <span class="c-punc">{</span> parseTokens<span class="c-punc">,</span> renderTokens <span class="c-punc">}</span> <span class="c-kw">from</span> <span class="c-str">'@metona-team/metona-editor'</span><span class="c-punc">;</span>
|
||||
|
||||
<span class="c-com">// 解析为 Token 数组</span>
|
||||
<span class="c-kw">const</span> <span class="c-punc">{</span> tokens<span class="c-punc">,</span> footnotes <span class="c-punc">}</span> <span class="c-punc">=</span> <span class="c-fn">parseTokens</span><span class="c-punc">(</span><span class="c-str">'# Hello\n\n**world**'</span><span class="c-punc">);</span>
|
||||
<span class="c-com">// tokens = [</span>
|
||||
<span class="c-com">// { type: 'heading', level: 1, text: 'Hello' },</span>
|
||||
<span class="c-com">// { type: 'paragraph', text: '**world**' }</span>
|
||||
<span class="c-com">// ]</span>
|
||||
|
||||
<span class="c-com">// 你可以在渲染前变换 token 数组</span>
|
||||
tokens<span class="c-punc">.</span><span class="c-fn">unshift</span><span class="c-punc">({</span> type<span class="c-punc">:</span> <span class="c-str">'hr'</span> <span class="c-punc">});</span>
|
||||
|
||||
<span class="c-com">// 渲染为 HTML</span>
|
||||
<span class="c-kw">const</span> html <span class="c-punc">=</span> <span class="c-fn">renderTokens</span><span class="c-punc">(</span>tokens<span class="c-punc">,</span> env<span class="c-punc">,</span> footnotes<span class="c-punc">);</span></pre>
|
||||
|
||||
<h3>registerBlockHandler(注册自定义块级语法)</h3>
|
||||
<p>无需替换整个解析器,按优先级注册自定义块级语法处理器。</p>
|
||||
<pre><span class="c-kw">import</span> <span class="c-punc">{</span> registerBlockHandler <span class="c-punc">}</span> <span class="c-kw">from</span> <span class="c-str">'@metona-team/metona-editor'</span><span class="c-punc">;</span>
|
||||
|
||||
<span class="c-fn">registerBlockHandler</span><span class="c-punc">({</span>
|
||||
name<span class="c-punc">:</span> <span class="c-str">'customAlert'</span><span class="c-punc">,</span>
|
||||
priority<span class="c-punc">:</span> <span class="c-num">8.5</span><span class="c-punc">,</span> <span class="c-com">// 越小越先尝试</span>
|
||||
test<span class="c-punc">:</span> <span class="c-punc">(</span>line<span class="c-punc">)</span> <span class="c-punc">=></span> line<span class="c-punc">.</span><span class="c-fn">match</span><span class="c-punc">(</span><span class="c-re">/^:::(\w+)/</span><span class="c-punc">),</span>
|
||||
parse<span class="c-punc">:</span> <span class="c-punc">(</span>lines<span class="c-punc">,</span> i<span class="c-punc">,</span> match<span class="c-punc">)</span> <span class="c-punc">=></span> <span class="c-punc">{</span>
|
||||
<span class="c-com">// 返回 { token: {...}, newIndex }</span>
|
||||
<span class="c-kw">return</span> <span class="c-punc">{</span> token<span class="c-punc">:</span> <span class="c-punc">{</span> type<span class="c-punc">:</span> <span class="c-str">'alert'</span><span class="c-punc">,</span> alertType<span class="c-punc">:</span> match<span class="c-punc">[</span><span class="c-num">1</span><span class="c-punc">]</span> <span class="c-punc">},</span> newIndex<span class="c-punc">:</span> j <span class="c-punc">};</span>
|
||||
<span class="c-punc">},</span>
|
||||
<span class="c-punc">});</span></pre>
|
||||
|
||||
<p>TIP:如果自定义 token 的 <code>type</code> 不被 <code>renderTokens</code> 识别,可以在渲染前通过 <code>tokens.map()</code> 转换为已知 type,或自行实现渲染逻辑。</p>
|
||||
</section>
|
||||
|
||||
<!-- ======== 插件 ======== -->
|
||||
<section id="plugins">
|
||||
<h2>插件约定</h2>
|
||||
@@ -619,7 +660,7 @@ i18nUtils<span class="c-punc">.</span><span class="c-fn">formatDate</span><span
|
||||
|
||||
<footer>
|
||||
<div class="container">
|
||||
MetonaEditor v0.1.14 · <a href="https://git.metona.cn/MetonaTeam/MetonaEditor" target="_blank" rel="noopener">源码仓库</a> · MIT License
|
||||
MetonaEditor v0.1.15 · <a href="https://git.metona.cn/MetonaTeam/MetonaEditor" target="_blank" rel="noopener">源码仓库</a> · MIT License
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
+2
-2
@@ -421,8 +421,8 @@
|
||||
<div class="stat-label">运行时依赖</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-num">390+</div>
|
||||
<div class="stat-label">单元测试</div>
|
||||
<div class="stat-num">558+</div>
|
||||
<div class="stat-label">单元测试</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-num">80%+</div>
|
||||
|
||||
Reference in New Issue
Block a user