dsh-paste-code-block 0.1.3 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +118 -112
- package/README.zh-CN.md +118 -112
- package/cordis.patch.yml +4 -4
- package/docs/design.md +373 -205
- package/docs/images/hero.svg +3 -3
- package/docs/images/languages.svg +3 -3
- package/docs/images/render.cjs +20 -20
- package/docs/images/workflow.svg +3 -3
- package/package.json +5 -4
- package/src/chip-nodes.js +46 -46
- package/src/client.js +856 -16
- package/src/i18n.js +140 -121
- package/src/index.js +11 -11
- package/src/parse.js +223 -6
- package/src/projection.js +54 -54
- package/tests/chip-nodes.test.js +71 -0
- package/tests/fixtures.js +9 -0
- package/tests/fold-smoke.test.js +642 -0
- package/tests/fold.test.js +147 -0
- package/tests/i18n.test.js +112 -0
- package/tests/lexical-chip-probe.mjs +109 -0
- package/tests/parse.test.js +183 -0
- package/tests/projection.test.js +64 -0
package/docs/images/hero.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="700" viewBox="0 0 1200 700">
|
|
2
|
-
<rect width="1200" height="700" fill="#0d1220"/>
|
|
3
|
-
<text x="40" y="56" font-size="26" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">粘贴长代码 / 长文本 → 输入框里只留一张整洁卡片</text><text x="40" y="86" font-size="14.5" fill="#93a3c0" font-family="Noto Sans SC">Paste long code or text into the DSH composer — it lands as a tidy, collapsible card, never a wall of text</text><rect x="40" y="112" width="720" height="516" rx="16" fill="#151c2f"/><rect x="40" y="112" width="720" height="516" rx="16" fill="none" stroke="#2a3450" stroke-width="1"/><text x="64" y="140" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">DSH Web · 输入框 / composer</text><rect x="64" y="152" width="672" height="96" rx="10" fill="#10162a"/><rect x="64" y="152" width="672" height="96" rx="10" fill="none" stroke="#232c45" stroke-width="1"/><rect x="80" y="168" width="126" height="27" rx="7" fill="#151e3c"/><rect x="80" y="168" width="126" height="27" rx="7" fill="none" stroke="#263777" stroke-width="1"/><text x="89" y="185.5" font-size="10.5" fill="#7aa2ff" font-family="JetBrains Mono" font-weight="700"></></text><text x="112" y="186" font-size="12.5" fill="#8fb0ff" font-family="Noto Sans SC">代码块 1</text><text x="196" y="187" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="214" y="168" width="126" height="27" rx="7" fill="#1d2742"/><rect x="214" y="168" width="126" height="27" rx="7" fill="none" stroke="#3a4a75" stroke-width="1"/><text x="223" y="185.5" font-size="10.5" fill="#93a3c0" font-family="Noto Sans SC" font-weight="700">Aa</text><text x="243" y="186" font-size="12.5" fill="#cdd9f2" font-family="Noto Sans SC">文本块 1</text><text x="330" y="187" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="348" y="168" width="126" height="27" rx="7" fill="#151e3c"/><rect x="348" y="168" width="126" height="27" rx="7" fill="none" stroke="#263777" stroke-width="1"/><text x="357" y="185.5" font-size="10.5" fill="#7aa2ff" font-family="JetBrains Mono" font-weight="700"></></text><text x="380" y="186" font-size="12.5" fill="#8fb0ff" font-family="Noto Sans SC">代码块 2</text><text x="464" y="187" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><circle cx="464" cy="181.5" r="11" fill="none" stroke="#ff7b7b" stroke-width="1.6" stroke-dasharray="4 3"/><text x="80" y="234" font-size="13" fill="#5b6a8a" font-family="Noto Sans SC">帮我分析这段代码,重点是并发问题…</text><rect x="64" y="268" width="672" height="312" rx="12" fill="#131a2c"/><rect x="64" y="268" width="672" height="312" rx="12" fill="none" stroke="#232c45" stroke-width="1"/><rect x="80" y="282" width="60" height="22" rx="8" fill="#1c2b4d"/><text x="90" y="297" font-size="11.5" fill="#7aa2ff" font-family="JetBrains Mono">python</text><text x="154" y="297" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">42 行</text><path d="M 610 291 L 617 284.5 L 624 291" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="642" y="284" width="11" height="13" rx="2" fill="none"/><rect x="642" y="284" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><rect x="647" y="288" width="11" height="13" rx="2" fill="#131a2c"/><rect x="647" y="288" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><path d="M 680 284.5 L 673.5 290.5 L 680 297" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="708" y="296.5" font-size="16" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><circle cx="708" cy="291" r="12" fill="none" stroke="#ff7b7b" stroke-width="1.6" stroke-dasharray="4 3"/><rect x="80" y="318" width="640" height="240" rx="8" fill="#0b1120"/><text x="98" y="348" font-size="13" fill="#c792ea" font-family="JetBrains Mono">def </text><text x="132" y="348" font-size="13" fill="#7aa2ff" font-family="JetBrains Mono">analyze</text><text x="180" y="348" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">(chunks):</text><text x="98" y="376" font-size="13" fill="#d6deeb" font-family="JetBrains Mono"> total = 0</text><text x="98" y="404" font-size="13" fill="#d6deeb" font-family="JetBrains Mono"> results = []</text><text x="98" y="432" font-size="13" fill="#c792ea" font-family="JetBrains Mono"> for </text><text x="132" y="432" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">c</text><text x="143" y="432" font-size="13" fill="#c792ea" font-family="JetBrains Mono"> in </text><text x="164" y="432" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">chunks</text><text x="213" y="432" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">:</text><text x="224" y="432" font-size="13" fill="#5b6a8a" font-family="JetBrains Mono"># 42 rows total — full, editable</text><text x="98" y="460" font-size="13" fill="#d6deeb" font-family="JetBrains Mono"> total += len(c.text)</text><text x="98" y="488" font-size="13" fill="#c792ea" font-family="JetBrains Mono"> return </text><text x="148" y="488" font-size="13" fill="#7aa2ff" font-family="JetBrains Mono">sorted</text><text x="198" y="488" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">(results)[-5:]</text><rect x="98" y="504" width="520" height="1.6" fill="#232c45"/><text x="98" y="528" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">卡片内直接编辑 · 编辑后的文本即发送内容</text><rect x="664" y="596" width="72" height="28" rx="8" fill="#3b5bdb"/><text x="700" y="615" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">发送</text><path d="M 806 168 C 675.5 168, 675.5 182, 545 182" stroke="#5b6a8a" stroke-width="1.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="820" cy="168" r="13" fill="#3b5bdb"/><text x="820" y="172.5" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">1</text><text x="842" y="169" font-size="15" fill="#e6ecf8" font-family="Noto Sans SC">点击芯片 → 展开 / 收起详情卡</text><text x="842" y="189" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">click a chip to open its card</text><path d="M 806 262 C 753 262, 753 291, 700 291" stroke="#5b6a8a" stroke-width="1.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="820" cy="268" r="13" fill="#3b5bdb"/><text x="820" y="272.5" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">2</text><text x="842" y="269" font-size="15" fill="#e6ecf8" font-family="Noto Sans SC">× 一键删除对应块,编号自动回收复用</text><text x="842" y="289" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">one-click remove · the number is recycled</text><path d="M 806 372 C 764 372, 764 430, 722 430" stroke="#5b6a8a" stroke-width="1.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="820" cy="372" r="13" fill="#3b5bdb"/><text x="820" y="376.5" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">3</text><text x="842" y="373" font-size="15" fill="#e6ecf8" font-family="Noto Sans SC">详情卡:编辑 / 复制 / 折叠</text><text x="842" y="393" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">edit, copy, collapse — all inline</text><line x1="756" y1="612" x2="806" y2="612" stroke="#5b6a8a" stroke-width="1.4"/><path d="M 806 612 l -8 -4 v 8 z" stroke="#5b6a8a" stroke-width="1" fill="#5b6a8a" stroke-linecap="round" stroke-linejoin="round"/><rect x="812" y="470" width="348" height="150" rx="12" fill="#10162a"/><rect x="812" y="470" width="348" height="150" rx="12" fill="none" stroke="#232c45" stroke-width="1"/><text x="832" y="496" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">发送后 · on send</text><text x="832" y="524" font-size="12.5" fill="#93a3c0" font-family="JetBrains Mono">```python</text><text x="832" y="548" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono">def analyze(chunks):</text><text x="832" y="572" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> ...完整原始文本...</text><text x="832" y="596" font-size="12.5" fill="#93a3c0" font-family="JetBrains Mono">```</text><circle cx="820" cy="662" r="13" fill="#3b5bdb"/><text x="820" y="666.5" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">4</text><text x="842" y="663" font-size="15" fill="#e6ecf8" font-family="Noto Sans SC">发送时自动还原为围栏代码块</text><text x="842" y="683" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">restored as a fenced code block on send</text><text x="40" y="662" font-size="12.5" fill="#5b6a8a" font-family="Noto Sans SC">PC 与移动端 Web 通用 · 深浅主题自适应 · 标签随 DSH 界面语言自动切换(中文 / English)</text>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="700" viewBox="0 0 1200 700">
|
|
2
|
+
<rect width="1200" height="700" fill="#0d1220"/>
|
|
3
|
+
<text x="40" y="56" font-size="26" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">粘贴长代码 / 长文本 → 输入框里只留一张整洁卡片</text><text x="40" y="86" font-size="14.5" fill="#93a3c0" font-family="Noto Sans SC">Paste long code or text into the DSH composer — it lands as a tidy, collapsible card, never a wall of text</text><rect x="40" y="112" width="720" height="516" rx="16" fill="#151c2f"/><rect x="40" y="112" width="720" height="516" rx="16" fill="none" stroke="#2a3450" stroke-width="1"/><text x="64" y="140" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">DSH Web · 输入框 / composer</text><rect x="64" y="152" width="672" height="96" rx="10" fill="#10162a"/><rect x="64" y="152" width="672" height="96" rx="10" fill="none" stroke="#232c45" stroke-width="1"/><rect x="80" y="168" width="126" height="27" rx="7" fill="#151e3c"/><rect x="80" y="168" width="126" height="27" rx="7" fill="none" stroke="#263777" stroke-width="1"/><text x="89" y="185.5" font-size="10.5" fill="#7aa2ff" font-family="JetBrains Mono" font-weight="700"></></text><text x="112" y="186" font-size="12.5" fill="#8fb0ff" font-family="Noto Sans SC">代码块 1</text><text x="196" y="187" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="214" y="168" width="126" height="27" rx="7" fill="#1d2742"/><rect x="214" y="168" width="126" height="27" rx="7" fill="none" stroke="#3a4a75" stroke-width="1"/><text x="223" y="185.5" font-size="10.5" fill="#93a3c0" font-family="Noto Sans SC" font-weight="700">Aa</text><text x="243" y="186" font-size="12.5" fill="#cdd9f2" font-family="Noto Sans SC">文本块 1</text><text x="330" y="187" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="348" y="168" width="126" height="27" rx="7" fill="#151e3c"/><rect x="348" y="168" width="126" height="27" rx="7" fill="none" stroke="#263777" stroke-width="1"/><text x="357" y="185.5" font-size="10.5" fill="#7aa2ff" font-family="JetBrains Mono" font-weight="700"></></text><text x="380" y="186" font-size="12.5" fill="#8fb0ff" font-family="Noto Sans SC">代码块 2</text><text x="464" y="187" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><circle cx="464" cy="181.5" r="11" fill="none" stroke="#ff7b7b" stroke-width="1.6" stroke-dasharray="4 3"/><text x="80" y="234" font-size="13" fill="#5b6a8a" font-family="Noto Sans SC">帮我分析这段代码,重点是并发问题…</text><rect x="64" y="268" width="672" height="312" rx="12" fill="#131a2c"/><rect x="64" y="268" width="672" height="312" rx="12" fill="none" stroke="#232c45" stroke-width="1"/><rect x="80" y="282" width="60" height="22" rx="8" fill="#1c2b4d"/><text x="90" y="297" font-size="11.5" fill="#7aa2ff" font-family="JetBrains Mono">python</text><text x="154" y="297" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">42 行</text><path d="M 610 291 L 617 284.5 L 624 291" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="642" y="284" width="11" height="13" rx="2" fill="none"/><rect x="642" y="284" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><rect x="647" y="288" width="11" height="13" rx="2" fill="#131a2c"/><rect x="647" y="288" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><path d="M 680 284.5 L 673.5 290.5 L 680 297" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="708" y="296.5" font-size="16" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><circle cx="708" cy="291" r="12" fill="none" stroke="#ff7b7b" stroke-width="1.6" stroke-dasharray="4 3"/><rect x="80" y="318" width="640" height="240" rx="8" fill="#0b1120"/><text x="98" y="348" font-size="13" fill="#c792ea" font-family="JetBrains Mono">def </text><text x="132" y="348" font-size="13" fill="#7aa2ff" font-family="JetBrains Mono">analyze</text><text x="180" y="348" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">(chunks):</text><text x="98" y="376" font-size="13" fill="#d6deeb" font-family="JetBrains Mono"> total = 0</text><text x="98" y="404" font-size="13" fill="#d6deeb" font-family="JetBrains Mono"> results = []</text><text x="98" y="432" font-size="13" fill="#c792ea" font-family="JetBrains Mono"> for </text><text x="132" y="432" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">c</text><text x="143" y="432" font-size="13" fill="#c792ea" font-family="JetBrains Mono"> in </text><text x="164" y="432" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">chunks</text><text x="213" y="432" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">:</text><text x="224" y="432" font-size="13" fill="#5b6a8a" font-family="JetBrains Mono"># 42 rows total — full, editable</text><text x="98" y="460" font-size="13" fill="#d6deeb" font-family="JetBrains Mono"> total += len(c.text)</text><text x="98" y="488" font-size="13" fill="#c792ea" font-family="JetBrains Mono"> return </text><text x="148" y="488" font-size="13" fill="#7aa2ff" font-family="JetBrains Mono">sorted</text><text x="198" y="488" font-size="13" fill="#d6deeb" font-family="JetBrains Mono">(results)[-5:]</text><rect x="98" y="504" width="520" height="1.6" fill="#232c45"/><text x="98" y="528" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">卡片内直接编辑 · 编辑后的文本即发送内容</text><rect x="664" y="596" width="72" height="28" rx="8" fill="#3b5bdb"/><text x="700" y="615" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">发送</text><path d="M 806 168 C 675.5 168, 675.5 182, 545 182" stroke="#5b6a8a" stroke-width="1.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="820" cy="168" r="13" fill="#3b5bdb"/><text x="820" y="172.5" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">1</text><text x="842" y="169" font-size="15" fill="#e6ecf8" font-family="Noto Sans SC">点击芯片 → 展开 / 收起详情卡</text><text x="842" y="189" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">click a chip to open its card</text><path d="M 806 262 C 753 262, 753 291, 700 291" stroke="#5b6a8a" stroke-width="1.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="820" cy="268" r="13" fill="#3b5bdb"/><text x="820" y="272.5" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">2</text><text x="842" y="269" font-size="15" fill="#e6ecf8" font-family="Noto Sans SC">× 一键删除对应块,编号自动回收复用</text><text x="842" y="289" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">one-click remove · the number is recycled</text><path d="M 806 372 C 764 372, 764 430, 722 430" stroke="#5b6a8a" stroke-width="1.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="820" cy="372" r="13" fill="#3b5bdb"/><text x="820" y="376.5" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">3</text><text x="842" y="373" font-size="15" fill="#e6ecf8" font-family="Noto Sans SC">详情卡:编辑 / 复制 / 折叠</text><text x="842" y="393" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">edit, copy, collapse — all inline</text><line x1="756" y1="612" x2="806" y2="612" stroke="#5b6a8a" stroke-width="1.4"/><path d="M 806 612 l -8 -4 v 8 z" stroke="#5b6a8a" stroke-width="1" fill="#5b6a8a" stroke-linecap="round" stroke-linejoin="round"/><rect x="812" y="470" width="348" height="150" rx="12" fill="#10162a"/><rect x="812" y="470" width="348" height="150" rx="12" fill="none" stroke="#232c45" stroke-width="1"/><text x="832" y="496" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">发送后 · on send</text><text x="832" y="524" font-size="12.5" fill="#93a3c0" font-family="JetBrains Mono">```python</text><text x="832" y="548" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono">def analyze(chunks):</text><text x="832" y="572" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> ...完整原始文本...</text><text x="832" y="596" font-size="12.5" fill="#93a3c0" font-family="JetBrains Mono">```</text><circle cx="820" cy="662" r="13" fill="#3b5bdb"/><text x="820" y="666.5" font-size="13.5" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">4</text><text x="842" y="663" font-size="15" fill="#e6ecf8" font-family="Noto Sans SC">发送时自动还原为围栏代码块</text><text x="842" y="683" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">restored as a fenced code block on send</text><text x="40" y="662" font-size="12.5" fill="#5b6a8a" font-family="Noto Sans SC">PC 与移动端 Web 通用 · 深浅主题自适应 · 标签随 DSH 界面语言自动切换(中文 / English)</text>
|
|
4
4
|
</svg>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="464" viewBox="0 0 1200 464">
|
|
2
|
-
<rect width="1200" height="464" fill="#0d1220"/>
|
|
3
|
-
<text x="40" y="50" font-size="22" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">块名称跟随 DSH 界面语言 · Block names follow the UI language</text><rect x="36" y="84" width="548" height="296" rx="14" fill="#151c2f"/><rect x="36" y="84" width="548" height="296" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><rect x="60" y="108" width="226" height="28" rx="14" fill="#0b1120"/><rect x="60" y="108" width="226" height="28" rx="14" fill="none" stroke="#232c45" stroke-width="1"/><text x="76" y="126" font-size="12.5" fill="#93a3c0" font-family="Noto Sans SC">设置 → 语言:中文</text><rect x="60" y="158" width="126" height="27" rx="7" fill="#1a2341"/><rect x="60" y="158" width="126" height="27" rx="7" fill="none" stroke="#2a3b7a" stroke-width="1"/><text x="69" y="175.5" font-size="10.5" fill="#7aa2ff" font-family="JetBrains Mono" font-weight="700"></></text><text x="92" y="176" font-size="12.5" fill="#8fb0ff" font-family="Noto Sans SC">代码块 1</text><text x="176" y="177" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="194" y="158" width="126" height="27" rx="7" fill="#1d2742"/><rect x="194" y="158" width="126" height="27" rx="7" fill="none" stroke="#3a4a75" stroke-width="1"/><text x="203" y="175.5" font-size="10.5" fill="#93a3c0" font-family="Noto Sans SC" font-weight="700">Aa</text><text x="223" y="176" font-size="12.5" fill="#cdd9f2" font-family="Noto Sans SC">文本块 1</text><text x="310" y="177" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="60" y="206" width="500" height="148" rx="10" fill="#131a2c"/><rect x="60" y="206" width="500" height="148" rx="10" fill="none" stroke="#232c45" stroke-width="1"/><rect x="76" y="220" width="62" height="20" rx="7" fill="#1c2b4d"/><text x="86" y="234" font-size="11" fill="#7aa2ff" font-family="JetBrains Mono">python</text><text x="152" y="234" font-size="11" fill="#5b6a8a" font-family="Noto Sans SC">18 行</text><path d="M 436 229 L 443 222.5 L 450 229" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="468" y="222" width="11" height="13" rx="2" fill="none"/><rect x="468" y="222" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><rect x="473" y="226" width="11" height="13" rx="2" fill="#131a2c"/><rect x="473" y="226" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><path d="M 506 222.5 L 499.5 228.5 L 506 235" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="534" y="234.5" font-size="16" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><text x="76" y="266" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono">def analyze(chunks):</text><text x="76" y="290" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> total = 0</text><text x="76" y="314" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> return sorted(results)</text><rect x="616" y="84" width="548" height="296" rx="14" fill="#151c2f"/><rect x="616" y="84" width="548" height="296" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><rect x="640" y="108" width="226" height="28" rx="14" fill="#0b1120"/><rect x="640" y="108" width="226" height="28" rx="14" fill="none" stroke="#232c45" stroke-width="1"/><text x="656" y="126" font-size="12.5" fill="#93a3c0" font-family="Noto Sans SC">Settings → Language: English</text><rect x="640" y="158" width="122" height="27" rx="7" fill="#1a2341"/><rect x="640" y="158" width="122" height="27" rx="7" fill="none" stroke="#2a3b7a" stroke-width="1"/><text x="649" y="175.5" font-size="10.5" fill="#7aa2ff" font-family="JetBrains Mono" font-weight="700"></></text><text x="672" y="176" font-size="12.5" fill="#8fb0ff" font-family="Noto Sans SC">Code #1</text><text x="751" y="177" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="770" y="158" width="122" height="27" rx="7" fill="#1d2742"/><rect x="770" y="158" width="122" height="27" rx="7" fill="none" stroke="#3a4a75" stroke-width="1"/><text x="779" y="175.5" font-size="10.5" fill="#93a3c0" font-family="Noto Sans SC" font-weight="700">Aa</text><text x="799" y="176" font-size="12.5" fill="#cdd9f2" font-family="Noto Sans SC">Text #1</text><text x="881" y="177" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="640" y="206" width="500" height="148" rx="10" fill="#131a2c"/><rect x="640" y="206" width="500" height="148" rx="10" fill="none" stroke="#232c45" stroke-width="1"/><rect x="656" y="220" width="62" height="20" rx="7" fill="#1c2b4d"/><text x="666" y="234" font-size="11" fill="#7aa2ff" font-family="JetBrains Mono">python</text><text x="732" y="234" font-size="11" fill="#5b6a8a" font-family="Noto Sans SC">18 lines</text><path d="M 1016 229 L 1023 222.5 L 1030 229" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="1048" y="222" width="11" height="13" rx="2" fill="none"/><rect x="1048" y="222" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><rect x="1053" y="226" width="11" height="13" rx="2" fill="#131a2c"/><rect x="1053" y="226" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><path d="M 1086 222.5 L 1079.5 228.5 L 1086 235" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="1114" y="234.5" font-size="16" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><text x="656" y="266" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono">def analyze(chunks):</text><text x="656" y="290" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> total = 0</text><text x="656" y="314" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> return sorted(results)</text><path d="M 590 226 h 20 m -7 -6 l 7 6 l -7 6 M 610 246 h -20 m 7 6 l -7 -6 l 7 -6" stroke="#7aa2ff" stroke-width="2.2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="600" y="284" font-size="11" fill="#5b6a8a" font-family="Noto Sans SC" text-anchor="middle">切换</text><text x="600" y="300" font-size="10.5" fill="#5b6a8a" font-family="Noto Sans SC" text-anchor="middle">live</text><text x="40" y="416" font-size="13.5" fill="#93a3c0" font-family="Noto Sans SC">语言切换即时生效:新粘贴的块用新语言命名,已插入的芯片也会同步改名</text><text x="40" y="438" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">Switch anytime — new pastes land in the new language, existing chips retitle live</text>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="464" viewBox="0 0 1200 464">
|
|
2
|
+
<rect width="1200" height="464" fill="#0d1220"/>
|
|
3
|
+
<text x="40" y="50" font-size="22" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">块名称跟随 DSH 界面语言 · Block names follow the UI language</text><rect x="36" y="84" width="548" height="296" rx="14" fill="#151c2f"/><rect x="36" y="84" width="548" height="296" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><rect x="60" y="108" width="226" height="28" rx="14" fill="#0b1120"/><rect x="60" y="108" width="226" height="28" rx="14" fill="none" stroke="#232c45" stroke-width="1"/><text x="76" y="126" font-size="12.5" fill="#93a3c0" font-family="Noto Sans SC">设置 → 语言:中文</text><rect x="60" y="158" width="126" height="27" rx="7" fill="#1a2341"/><rect x="60" y="158" width="126" height="27" rx="7" fill="none" stroke="#2a3b7a" stroke-width="1"/><text x="69" y="175.5" font-size="10.5" fill="#7aa2ff" font-family="JetBrains Mono" font-weight="700"></></text><text x="92" y="176" font-size="12.5" fill="#8fb0ff" font-family="Noto Sans SC">代码块 1</text><text x="176" y="177" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="194" y="158" width="126" height="27" rx="7" fill="#1d2742"/><rect x="194" y="158" width="126" height="27" rx="7" fill="none" stroke="#3a4a75" stroke-width="1"/><text x="203" y="175.5" font-size="10.5" fill="#93a3c0" font-family="Noto Sans SC" font-weight="700">Aa</text><text x="223" y="176" font-size="12.5" fill="#cdd9f2" font-family="Noto Sans SC">文本块 1</text><text x="310" y="177" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="60" y="206" width="500" height="148" rx="10" fill="#131a2c"/><rect x="60" y="206" width="500" height="148" rx="10" fill="none" stroke="#232c45" stroke-width="1"/><rect x="76" y="220" width="62" height="20" rx="7" fill="#1c2b4d"/><text x="86" y="234" font-size="11" fill="#7aa2ff" font-family="JetBrains Mono">python</text><text x="152" y="234" font-size="11" fill="#5b6a8a" font-family="Noto Sans SC">18 行</text><path d="M 436 229 L 443 222.5 L 450 229" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="468" y="222" width="11" height="13" rx="2" fill="none"/><rect x="468" y="222" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><rect x="473" y="226" width="11" height="13" rx="2" fill="#131a2c"/><rect x="473" y="226" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><path d="M 506 222.5 L 499.5 228.5 L 506 235" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="534" y="234.5" font-size="16" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><text x="76" y="266" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono">def analyze(chunks):</text><text x="76" y="290" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> total = 0</text><text x="76" y="314" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> return sorted(results)</text><rect x="616" y="84" width="548" height="296" rx="14" fill="#151c2f"/><rect x="616" y="84" width="548" height="296" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><rect x="640" y="108" width="226" height="28" rx="14" fill="#0b1120"/><rect x="640" y="108" width="226" height="28" rx="14" fill="none" stroke="#232c45" stroke-width="1"/><text x="656" y="126" font-size="12.5" fill="#93a3c0" font-family="Noto Sans SC">Settings → Language: English</text><rect x="640" y="158" width="122" height="27" rx="7" fill="#1a2341"/><rect x="640" y="158" width="122" height="27" rx="7" fill="none" stroke="#2a3b7a" stroke-width="1"/><text x="649" y="175.5" font-size="10.5" fill="#7aa2ff" font-family="JetBrains Mono" font-weight="700"></></text><text x="672" y="176" font-size="12.5" fill="#8fb0ff" font-family="Noto Sans SC">Code #1</text><text x="751" y="177" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="770" y="158" width="122" height="27" rx="7" fill="#1d2742"/><rect x="770" y="158" width="122" height="27" rx="7" fill="none" stroke="#3a4a75" stroke-width="1"/><text x="779" y="175.5" font-size="10.5" fill="#93a3c0" font-family="Noto Sans SC" font-weight="700">Aa</text><text x="799" y="176" font-size="12.5" fill="#cdd9f2" font-family="Noto Sans SC">Text #1</text><text x="881" y="177" font-size="15" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><rect x="640" y="206" width="500" height="148" rx="10" fill="#131a2c"/><rect x="640" y="206" width="500" height="148" rx="10" fill="none" stroke="#232c45" stroke-width="1"/><rect x="656" y="220" width="62" height="20" rx="7" fill="#1c2b4d"/><text x="666" y="234" font-size="11" fill="#7aa2ff" font-family="JetBrains Mono">python</text><text x="732" y="234" font-size="11" fill="#5b6a8a" font-family="Noto Sans SC">18 lines</text><path d="M 1016 229 L 1023 222.5 L 1030 229" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="1048" y="222" width="11" height="13" rx="2" fill="none"/><rect x="1048" y="222" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><rect x="1053" y="226" width="11" height="13" rx="2" fill="#131a2c"/><rect x="1053" y="226" width="11" height="13" rx="2" fill="none" stroke="#93a3c0" stroke-width="1"/><path d="M 1086 222.5 L 1079.5 228.5 L 1086 235" stroke="#93a3c0" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="1114" y="234.5" font-size="16" fill="#ff7b7b" font-family="Noto Sans SC" text-anchor="middle">×</text><text x="656" y="266" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono">def analyze(chunks):</text><text x="656" y="290" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> total = 0</text><text x="656" y="314" font-size="12.5" fill="#d6deeb" font-family="JetBrains Mono"> return sorted(results)</text><path d="M 590 226 h 20 m -7 -6 l 7 6 l -7 6 M 610 246 h -20 m 7 6 l -7 -6 l 7 -6" stroke="#7aa2ff" stroke-width="2.2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="600" y="284" font-size="11" fill="#5b6a8a" font-family="Noto Sans SC" text-anchor="middle">切换</text><text x="600" y="300" font-size="10.5" fill="#5b6a8a" font-family="Noto Sans SC" text-anchor="middle">live</text><text x="40" y="416" font-size="13.5" fill="#93a3c0" font-family="Noto Sans SC">语言切换即时生效:新粘贴的块用新语言命名,已插入的芯片也会同步改名</text><text x="40" y="438" font-size="12" fill="#5b6a8a" font-family="Noto Sans SC">Switch anytime — new pastes land in the new language, existing chips retitle live</text>
|
|
4
4
|
</svg>
|
package/docs/images/render.cjs
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
// Regenerate the README mockup PNGs from the SVG sources in this folder.
|
|
2
|
-
// Dev-only helper (not loaded by the plugin). Requires: npm i @resvg/resvg-js
|
|
3
|
-
// and the fonts referenced below (apt: fonts-noto-cjk fonts-jetbrains-mono).
|
|
4
|
-
const fs = require('fs')
|
|
5
|
-
const path = require('path')
|
|
6
|
-
const { Resvg } = require('@resvg/resvg-js')
|
|
7
|
-
|
|
8
|
-
const FONTS = [
|
|
9
|
-
'/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc',
|
|
10
|
-
'/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc',
|
|
11
|
-
'/usr/share/fonts/truetype/jetbrains-mono/JetBrainsMono-Regular.ttf',
|
|
12
|
-
'/usr/share/fonts/truetype/jetbrains-mono/JetBrainsMono-Bold.ttf',
|
|
13
|
-
]
|
|
14
|
-
for (const name of ['hero', 'languages', 'workflow']) {
|
|
15
|
-
let src = fs.readFileSync(path.join(__dirname, name + '.svg'), 'utf8')
|
|
16
|
-
src = src.split('font-family="Noto Sans SC"').join('font-family="Noto Sans CJK SC"')
|
|
17
|
-
const r = new Resvg(src, { fitTo: { mode: 'zoom', value: 2 }, font: { fontFiles: FONTS, loadSystemFonts: false, defaultFontFamily: 'Noto Sans CJK SC', sansSerifFamily: 'Noto Sans CJK SC', monospaceFamily: 'JetBrains Mono' } })
|
|
18
|
-
fs.writeFileSync(path.join(__dirname, name + '.png'), r.render().asPng())
|
|
19
|
-
console.log('rendered', name + '.png')
|
|
20
|
-
}
|
|
1
|
+
// Regenerate the README mockup PNGs from the SVG sources in this folder.
|
|
2
|
+
// Dev-only helper (not loaded by the plugin). Requires: npm i @resvg/resvg-js
|
|
3
|
+
// and the fonts referenced below (apt: fonts-noto-cjk fonts-jetbrains-mono).
|
|
4
|
+
const fs = require('fs')
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const { Resvg } = require('@resvg/resvg-js')
|
|
7
|
+
|
|
8
|
+
const FONTS = [
|
|
9
|
+
'/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc',
|
|
10
|
+
'/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc',
|
|
11
|
+
'/usr/share/fonts/truetype/jetbrains-mono/JetBrainsMono-Regular.ttf',
|
|
12
|
+
'/usr/share/fonts/truetype/jetbrains-mono/JetBrainsMono-Bold.ttf',
|
|
13
|
+
]
|
|
14
|
+
for (const name of ['hero', 'languages', 'workflow']) {
|
|
15
|
+
let src = fs.readFileSync(path.join(__dirname, name + '.svg'), 'utf8')
|
|
16
|
+
src = src.split('font-family="Noto Sans SC"').join('font-family="Noto Sans CJK SC"')
|
|
17
|
+
const r = new Resvg(src, { fitTo: { mode: 'zoom', value: 2 }, font: { fontFiles: FONTS, loadSystemFonts: false, defaultFontFamily: 'Noto Sans CJK SC', sansSerifFamily: 'Noto Sans CJK SC', monospaceFamily: 'JetBrains Mono' } })
|
|
18
|
+
fs.writeFileSync(path.join(__dirname, name + '.png'), r.render().asPng())
|
|
19
|
+
console.log('rendered', name + '.png')
|
|
20
|
+
}
|
package/docs/images/workflow.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="360" viewBox="0 0 1200 360">
|
|
2
|
-
<rect width="1200" height="360" fill="#0d1220"/>
|
|
3
|
-
<text x="40" y="52" font-size="22" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">使用只要四步 · Four steps, zero noise</text><rect x="40" y="92" width="247" height="190" rx="14" fill="#151c2f"/><rect x="40" y="92" width="247" height="190" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><circle cx="74" cy="132" r="17" fill="#3b5bdb"/><text x="74" y="138" font-size="17" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">1</text><text x="102" y="139" font-size="18" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">复制</text><rect x="196" y="118" width="26" height="30" rx="4" fill="none"/><rect x="196" y="118" width="26" height="30" rx="4" fill="none" stroke="#7aa2ff" stroke-width="1"/><rect x="202" y="113" width="14" height="10" rx="3" fill="#151c2f"/><rect x="202" y="113" width="14" height="10" rx="3" fill="none" stroke="#7aa2ff" stroke-width="1"/><line x1="202" y1="127" x2="216" y2="127" stroke="#93a3c0" stroke-width="1.5"/><line x1="202" y1="134" x2="216" y2="134" stroke="#93a3c0" stroke-width="1.5"/><line x1="202" y1="141" x2="212" y2="141" stroke="#93a3c0" stroke-width="1.5"/><text x="62" y="186" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">在任意应用里复制一段代码或长文本</text><text x="62" y="226" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">Copy code or long text anywhere</text><path d="M 295 187 h 60 m -10 -7 l 10 7 l -10 7" stroke="#5b6a8a" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="331" y="92" width="247" height="190" rx="14" fill="#151c2f"/><rect x="331" y="92" width="247" height="190" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><circle cx="365" cy="132" r="17" fill="#3b5bdb"/><text x="365" y="138" font-size="17" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">2</text><text x="393" y="139" font-size="18" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">粘贴</text><rect x="481" y="122" width="44" height="24" rx="6" fill="#0b1120"/><rect x="481" y="122" width="44" height="24" rx="6" fill="none" stroke="#232c45" stroke-width="1"/><line x1="489" y1="129" x2="489" y2="139" stroke="#7aa2ff" stroke-width="2"/><text x="353" y="186" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">粘到 DSH 输入框(Ctrl+V</text><text x="353" y="206" font-size="13" fill="#93a3c0" font-family="Noto Sans SC"> / 长按)</text><text x="353" y="246" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">Paste into the DSH composer</text><path d="M 586 187 h 60 m -10 -7 l 10 7 l -10 7" stroke="#5b6a8a" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="622" y="92" width="247" height="190" rx="14" fill="#151c2f"/><rect x="622" y="92" width="247" height="190" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><circle cx="656" cy="132" r="17" fill="#3b5bdb"/><text x="656" y="138" font-size="17" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">3</text><text x="684" y="139" font-size="18" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">整理</text><rect x="772" y="122" width="44" height="24" rx="12" fill="#1d2742"/><rect x="772" y="122" width="44" height="24" rx="12" fill="none" stroke="#3a4a75" stroke-width="1"/><text x="780" y="139" font-size="11" fill="#d6deeb" font-family="Noto Sans SC">Aa</text><text x="806" y="140" font-size="13" fill="#ff7b7b" font-family="Noto Sans SC">×</text><text x="644" y="186" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">自动收成卡片:点芯片看详情,× 删</text><text x="644" y="206" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">除</text><text x="644" y="246" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">Auto card: open · edit · remove ×</text><path d="M 877 187 h 60 m -10 -7 l 10 7 l -10 7" stroke="#5b6a8a" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="913" y="92" width="247" height="190" rx="14" fill="#151c2f"/><rect x="913" y="92" width="247" height="190" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><circle cx="947" cy="132" r="17" fill="#3b5bdb"/><text x="947" y="138" font-size="17" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">4</text><text x="975" y="139" font-size="18" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">发送</text><path d="M 1063 134 L 1103 120 L 1089 142 L 1083 134 Z" stroke="#7aa2ff" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="935" y="186" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">还原为 ```lang 围栏代码块</text><text x="935" y="206" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">发出</text><text x="935" y="246" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">Sent back as fenced code</text><text x="40" y="326" font-size="12.5" fill="#5b6a8a" font-family="Noto Sans SC">代码 / Markdown / 普通长文本自动识别;短普通文本照常粘贴,不打扰</text>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="360" viewBox="0 0 1200 360">
|
|
2
|
+
<rect width="1200" height="360" fill="#0d1220"/>
|
|
3
|
+
<text x="40" y="52" font-size="22" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">使用只要四步 · Four steps, zero noise</text><rect x="40" y="92" width="247" height="190" rx="14" fill="#151c2f"/><rect x="40" y="92" width="247" height="190" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><circle cx="74" cy="132" r="17" fill="#3b5bdb"/><text x="74" y="138" font-size="17" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">1</text><text x="102" y="139" font-size="18" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">复制</text><rect x="196" y="118" width="26" height="30" rx="4" fill="none"/><rect x="196" y="118" width="26" height="30" rx="4" fill="none" stroke="#7aa2ff" stroke-width="1"/><rect x="202" y="113" width="14" height="10" rx="3" fill="#151c2f"/><rect x="202" y="113" width="14" height="10" rx="3" fill="none" stroke="#7aa2ff" stroke-width="1"/><line x1="202" y1="127" x2="216" y2="127" stroke="#93a3c0" stroke-width="1.5"/><line x1="202" y1="134" x2="216" y2="134" stroke="#93a3c0" stroke-width="1.5"/><line x1="202" y1="141" x2="212" y2="141" stroke="#93a3c0" stroke-width="1.5"/><text x="62" y="186" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">在任意应用里复制一段代码或长文本</text><text x="62" y="226" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">Copy code or long text anywhere</text><path d="M 295 187 h 60 m -10 -7 l 10 7 l -10 7" stroke="#5b6a8a" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="331" y="92" width="247" height="190" rx="14" fill="#151c2f"/><rect x="331" y="92" width="247" height="190" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><circle cx="365" cy="132" r="17" fill="#3b5bdb"/><text x="365" y="138" font-size="17" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">2</text><text x="393" y="139" font-size="18" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">粘贴</text><rect x="481" y="122" width="44" height="24" rx="6" fill="#0b1120"/><rect x="481" y="122" width="44" height="24" rx="6" fill="none" stroke="#232c45" stroke-width="1"/><line x1="489" y1="129" x2="489" y2="139" stroke="#7aa2ff" stroke-width="2"/><text x="353" y="186" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">粘到 DSH 输入框(Ctrl+V</text><text x="353" y="206" font-size="13" fill="#93a3c0" font-family="Noto Sans SC"> / 长按)</text><text x="353" y="246" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">Paste into the DSH composer</text><path d="M 586 187 h 60 m -10 -7 l 10 7 l -10 7" stroke="#5b6a8a" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="622" y="92" width="247" height="190" rx="14" fill="#151c2f"/><rect x="622" y="92" width="247" height="190" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><circle cx="656" cy="132" r="17" fill="#3b5bdb"/><text x="656" y="138" font-size="17" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">3</text><text x="684" y="139" font-size="18" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">整理</text><rect x="772" y="122" width="44" height="24" rx="12" fill="#1d2742"/><rect x="772" y="122" width="44" height="24" rx="12" fill="none" stroke="#3a4a75" stroke-width="1"/><text x="780" y="139" font-size="11" fill="#d6deeb" font-family="Noto Sans SC">Aa</text><text x="806" y="140" font-size="13" fill="#ff7b7b" font-family="Noto Sans SC">×</text><text x="644" y="186" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">自动收成卡片:点芯片看详情,× 删</text><text x="644" y="206" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">除</text><text x="644" y="246" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">Auto card: open · edit · remove ×</text><path d="M 877 187 h 60 m -10 -7 l 10 7 l -10 7" stroke="#5b6a8a" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><rect x="913" y="92" width="247" height="190" rx="14" fill="#151c2f"/><rect x="913" y="92" width="247" height="190" rx="14" fill="none" stroke="#2a3450" stroke-width="1"/><circle cx="947" cy="132" r="17" fill="#3b5bdb"/><text x="947" y="138" font-size="17" fill="#fff" font-family="Noto Sans SC" text-anchor="middle">4</text><text x="975" y="139" font-size="18" fill="#e6ecf8" font-family="Noto Sans SC" font-weight="700">发送</text><path d="M 1063 134 L 1103 120 L 1089 142 L 1083 134 Z" stroke="#7aa2ff" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/><text x="935" y="186" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">还原为 ```lang 围栏代码块</text><text x="935" y="206" font-size="13" fill="#93a3c0" font-family="Noto Sans SC">发出</text><text x="935" y="246" font-size="11.5" fill="#5b6a8a" font-family="Noto Sans SC">Sent back as fenced code</text><text x="40" y="326" font-size="12.5" fill="#5b6a8a" font-family="Noto Sans SC">代码 / Markdown / 普通长文本自动识别;短普通文本照常粘贴,不打扰</text>
|
|
4
4
|
</svg>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-paste-code-block",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Cherry Studio-style paste for DSH Web: pasted text/code becomes a bordered, collapsible, language-tagged card with localized names (中文/English) and a one-click remove button; restored as a fenced code block on send.",
|
|
3
|
+
"version": "0.2.6",
|
|
4
|
+
"description": "Cherry Studio-style paste for DSH Web: pasted text/code becomes a bordered, collapsible, language-tagged card with localized names (中文/English) and a one-click remove button; restored as a fenced code block on send — and folded back into collapsed, expandable cards in the conversation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "DSH paste-code-block contributors",
|
|
7
7
|
"repository": {
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"src/",
|
|
38
|
+
"tests/",
|
|
38
39
|
"docs/",
|
|
39
40
|
"cordis.patch.yml",
|
|
40
41
|
"README.md",
|
|
@@ -85,8 +86,8 @@
|
|
|
85
86
|
"node": ">=20"
|
|
86
87
|
},
|
|
87
88
|
"scripts": {
|
|
88
|
-
"check": "node --check src/index.js && node --check src/i18n.js && node --check src/chip-nodes.js && node --check src/projection.js && node --check src/client.js",
|
|
89
|
-
"test": "node --test
|
|
89
|
+
"check": "node --check src/index.js && node --check src/parse.js && node --check src/i18n.js && node --check src/chip-nodes.js && node --check src/projection.js && node --check src/client.js",
|
|
90
|
+
"test": "node --test",
|
|
90
91
|
"render:images": "node docs/images/render.cjs"
|
|
91
92
|
}
|
|
92
93
|
}
|
package/src/chip-nodes.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chip-node helpers for the composer editor.
|
|
3
|
-
*
|
|
4
|
-
* DSH renders each reference (our pasted block) as a Lexical decorator chip.
|
|
5
|
-
* The input shell exposes no per-reference delete verb, so removal reaches the
|
|
6
|
-
* node map (`editor.getEditorState()._nodeMap`) and drops the matching node.
|
|
7
|
-
*
|
|
8
|
-
* The node map is keyed by NodeKey and its VALUES ARE THE NODES THEMSELVES
|
|
9
|
-
* (Lexical >= 0.21, verified against 0.49.0 by tests/lexical-chip-probe.mjs).
|
|
10
|
-
* The older `NodeState` wrapper with a `.node` field is gone, so reading
|
|
11
|
-
* `value.node` yields undefined for every entry — which is exactly how v0.1.2's
|
|
12
|
-
* delete turned into a silent no-op instead of deleting the block.
|
|
13
|
-
*
|
|
14
|
-
* Pure and dependency-free so the shape rule is unit-testable; keep the
|
|
15
|
-
* embedded copy in src/client.js in sync (same rule as parse.js/i18n.js).
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Normalize one node-map value to a chip-like node.
|
|
20
|
-
* @param value - raw node-map value (a node, or a legacy NodeState wrapper).
|
|
21
|
-
* @returns the node when it exposes the chip accessors, else null.
|
|
22
|
-
*/
|
|
23
|
-
export function chipNodeOf(value) {
|
|
24
|
-
if (!value) return null
|
|
25
|
-
if (typeof value.getSource === 'function') return value
|
|
26
|
-
const wrapped = value.node
|
|
27
|
-
return wrapped && typeof wrapped.getSource === 'function' ? wrapped : null
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Collect the chip node(s) belonging to one source + ref.
|
|
32
|
-
* @param values - node-map values (`map.values()`).
|
|
33
|
-
* @param source - owning reference source (e.g. 'paste-code-block').
|
|
34
|
-
* @param ref - owner-scoped reference id (the block id).
|
|
35
|
-
* @returns matching nodes, in map order (usually exactly one).
|
|
36
|
-
*/
|
|
37
|
-
export function collectChipNodes(values, source, ref) {
|
|
38
|
-
const hits = []
|
|
39
|
-
if (!values) return hits
|
|
40
|
-
for (const value of values) {
|
|
41
|
-
const node = chipNodeOf(value)
|
|
42
|
-
if (!node || typeof node.getReference !== 'function') continue
|
|
43
|
-
if (node.getSource() === source && node.getReference() === ref) hits.push(node)
|
|
44
|
-
}
|
|
45
|
-
return hits
|
|
46
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Chip-node helpers for the composer editor.
|
|
3
|
+
*
|
|
4
|
+
* DSH renders each reference (our pasted block) as a Lexical decorator chip.
|
|
5
|
+
* The input shell exposes no per-reference delete verb, so removal reaches the
|
|
6
|
+
* node map (`editor.getEditorState()._nodeMap`) and drops the matching node.
|
|
7
|
+
*
|
|
8
|
+
* The node map is keyed by NodeKey and its VALUES ARE THE NODES THEMSELVES
|
|
9
|
+
* (Lexical >= 0.21, verified against 0.49.0 by tests/lexical-chip-probe.mjs).
|
|
10
|
+
* The older `NodeState` wrapper with a `.node` field is gone, so reading
|
|
11
|
+
* `value.node` yields undefined for every entry — which is exactly how v0.1.2's
|
|
12
|
+
* delete turned into a silent no-op instead of deleting the block.
|
|
13
|
+
*
|
|
14
|
+
* Pure and dependency-free so the shape rule is unit-testable; keep the
|
|
15
|
+
* embedded copy in src/client.js in sync (same rule as parse.js/i18n.js).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Normalize one node-map value to a chip-like node.
|
|
20
|
+
* @param value - raw node-map value (a node, or a legacy NodeState wrapper).
|
|
21
|
+
* @returns the node when it exposes the chip accessors, else null.
|
|
22
|
+
*/
|
|
23
|
+
export function chipNodeOf(value) {
|
|
24
|
+
if (!value) return null
|
|
25
|
+
if (typeof value.getSource === 'function') return value
|
|
26
|
+
const wrapped = value.node
|
|
27
|
+
return wrapped && typeof wrapped.getSource === 'function' ? wrapped : null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Collect the chip node(s) belonging to one source + ref.
|
|
32
|
+
* @param values - node-map values (`map.values()`).
|
|
33
|
+
* @param source - owning reference source (e.g. 'paste-code-block').
|
|
34
|
+
* @param ref - owner-scoped reference id (the block id).
|
|
35
|
+
* @returns matching nodes, in map order (usually exactly one).
|
|
36
|
+
*/
|
|
37
|
+
export function collectChipNodes(values, source, ref) {
|
|
38
|
+
const hits = []
|
|
39
|
+
if (!values) return hits
|
|
40
|
+
for (const value of values) {
|
|
41
|
+
const node = chipNodeOf(value)
|
|
42
|
+
if (!node || typeof node.getReference !== 'function') continue
|
|
43
|
+
if (node.getSource() === source && node.getReference() === ref) hits.push(node)
|
|
44
|
+
}
|
|
45
|
+
return hits
|
|
46
|
+
}
|