@helping-ai-workflow/md2doc 3.17.1 → 3.17.3
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/lib/editor/blockmap.js +65 -0
- package/lib/editor/client.js +1839 -159
- package/lib/editor/code-edit.js +27 -14
- package/lib/editor/convert-md.js +9 -2
- package/lib/editor/dot-preview.js +65 -0
- package/lib/editor/dot-worker.js +14 -0
- package/lib/editor/inline-md.js +34 -4
- package/lib/editor/list-md.js +143 -47
- package/lib/editor/server.js +52 -3
- package/lib/editor/wave-ui.js +9 -0
- package/lib/md2doc.js +25 -2
- package/lib/theme/tokens.js +4 -1
- package/package.json +1 -1
package/lib/md2doc.js
CHANGED
|
@@ -379,6 +379,9 @@ function renderEditModeList(listToken, blocks, biRef, out) {
|
|
|
379
379
|
const check = b.task
|
|
380
380
|
? `<span class="ed-li-check" data-checked="${b.checked ? 1 : 0}" role="checkbox" aria-checked="${!!b.checked}"></span>`
|
|
381
381
|
: '';
|
|
382
|
+
// v3.17.3 C10: an svg in the item's own text gets the same white plate
|
|
383
|
+
// in dark as a top-level svg block (the attribute is read by the dark CSS).
|
|
384
|
+
const svgPlate = ownTokens.some((tk) => /<svg[\s>]/i.test(String(tk.raw || ''))) ? ' data-svg-plate="1"' : '';
|
|
382
385
|
const runStart = liRunStartsHere(biRef, b) ? ' data-run-start="1"' : '';
|
|
383
386
|
const listStartAttr = listStart ? ' data-list-start="1"' : '';
|
|
384
387
|
listStart = false;
|
|
@@ -389,7 +392,7 @@ function renderEditModeList(listToken, blocks, biRef, out) {
|
|
|
389
392
|
parts.push(
|
|
390
393
|
`<div class="ed-block" data-block-id="${b.id}" data-block-type="li"` +
|
|
391
394
|
` data-list-type="${b.listType}" data-task="${b.task ? 1 : 0}" data-indent="${b.indent}"` +
|
|
392
|
-
runStart + listStartAttr + looseAttr + ` style="--ed-indent:${b.indent}">` +
|
|
395
|
+
runStart + listStartAttr + looseAttr + svgPlate + ` style="--ed-indent:${b.indent}">` +
|
|
393
396
|
`<span class="ed-li-marker" aria-hidden="true"></span>` + check +
|
|
394
397
|
`<div class="ed-li-text">${inner}</div>` +
|
|
395
398
|
`</div>`
|
|
@@ -2767,6 +2770,7 @@ const html = `<!DOCTYPE html>
|
|
|
2767
2770
|
border-radius: 3px;
|
|
2768
2771
|
}
|
|
2769
2772
|
mark.search-hit-block { display: block; }
|
|
2773
|
+
svg .svg-hit { stroke: var(--md-svg-hit); stroke-width: 6px; stroke-linejoin: round; paint-order: stroke; }
|
|
2770
2774
|
.toc {
|
|
2771
2775
|
display: flex;
|
|
2772
2776
|
flex-direction: column;
|
|
@@ -4799,6 +4803,15 @@ ${mermaidInitTag}`)
|
|
|
4799
4803
|
}
|
|
4800
4804
|
|
|
4801
4805
|
const SKIP_SELECTOR = 'svg, .mermaid, .graphviz, script, style';
|
|
4806
|
+
// v3.17.3 C11: a Markdown-native inline svg is read (its text is in the
|
|
4807
|
+
// search index); a diagram's own svg (mermaid, graphviz, draw.io, WaveDrom,
|
|
4808
|
+
// a formula) is not. Inside a native svg every text node is walked, the
|
|
4809
|
+
// ones in its title and desc elements too: the index holds those as well
|
|
4810
|
+
// (the paragraph's text tokens between the html tags), so a query that
|
|
4811
|
+
// finds the section can find them here.
|
|
4812
|
+
function isNativeSvg(el) {
|
|
4813
|
+
return el.matches('svg') && !el.closest('.mermaid, .graphviz, .drawio, .katex, .code-block, [class*="wave"], [id^="WaveDrom"]');
|
|
4814
|
+
}
|
|
4802
4815
|
|
|
4803
4816
|
function buildSnippet(section, query) {
|
|
4804
4817
|
const haystack = section.searchText || section.title || '';
|
|
@@ -4845,6 +4858,7 @@ ${mermaidInitTag}`)
|
|
|
4845
4858
|
? readerState.activeHighlights
|
|
4846
4859
|
: (readerState.activeHighlight ? [readerState.activeHighlight] : []);
|
|
4847
4860
|
marks.forEach((mark) => {
|
|
4861
|
+
if (mark.namespaceURI === 'http://www.w3.org/2000/svg') { mark.classList.remove('svg-hit'); if (!mark.getAttribute('class')) mark.removeAttribute('class'); return; }
|
|
4848
4862
|
const parent = mark.parentNode;
|
|
4849
4863
|
if (!parent) return;
|
|
4850
4864
|
while (mark.firstChild) parent.insertBefore(mark.firstChild, mark);
|
|
@@ -4975,7 +4989,8 @@ ${mermaidInitTag}`)
|
|
|
4975
4989
|
const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, {
|
|
4976
4990
|
acceptNode(node) {
|
|
4977
4991
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
4978
|
-
if (node.matches(SKIP_SELECTOR)
|
|
4992
|
+
if (node.matches(SKIP_SELECTOR) && !isNativeSvg(node)) return NodeFilter.FILTER_REJECT;
|
|
4993
|
+
if (node.matches('.reader-sidebar, .heading-anchor, button')) return NodeFilter.FILTER_REJECT;
|
|
4979
4994
|
return node.matches('br, .katex') ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
4980
4995
|
}
|
|
4981
4996
|
if (!node.nodeValue) return NodeFilter.FILTER_REJECT;
|
|
@@ -5065,6 +5080,14 @@ ${mermaidInitTag}`)
|
|
|
5065
5080
|
const marks = [];
|
|
5066
5081
|
Array.from(spans.keys()).sort((a, b) => b - a).forEach((ni) => {
|
|
5067
5082
|
const node = nodes[ni];
|
|
5083
|
+
// v3.17.3 C11: svg cannot hold a mark element; the text node's parent
|
|
5084
|
+
// (text or tspan) is flagged instead and painted by .svg-hit.
|
|
5085
|
+
if (node.nodeType === Node.TEXT_NODE && node.parentElement && node.parentElement.closest('svg')) {
|
|
5086
|
+
// Two text nodes can share one parent (a tspan or a comment splits it).
|
|
5087
|
+
node.parentElement.classList.add('svg-hit');
|
|
5088
|
+
if (marks.indexOf(node.parentElement) === -1) marks.unshift(node.parentElement);
|
|
5089
|
+
return;
|
|
5090
|
+
}
|
|
5068
5091
|
const mark = document.createElement('mark');
|
|
5069
5092
|
mark.className = 'search-hit is-selected';
|
|
5070
5093
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
package/lib/theme/tokens.js
CHANGED
|
@@ -34,6 +34,9 @@ const THEME_TOKENS = [
|
|
|
34
34
|
{ name: 'active-bg', light: ['#dbe6f3'], dark: '#24364f' },
|
|
35
35
|
{ name: 'hit-bg', light: ['#fff5c2'], dark: '#4d4417' },
|
|
36
36
|
{ name: 'mark-bg', light: ['#fde68a'], dark: '#6e5e14' },
|
|
37
|
+
// A search hit inside an inline svg is painted on the svg plate, which is white in both themes,
|
|
38
|
+
// so its halo is the same yellow in both (the dark mark-bg would read worse than no hit at all).
|
|
39
|
+
{ name: 'svg-hit', light: ['#fde68a'], dark: '#fde68a', direct: true },
|
|
37
40
|
{ name: 'code', light: ['#b93a0c'], dark: '#ff9f70' },
|
|
38
41
|
{ name: 'accent-soft', light: ['#93c5fd'], dark: '#6ea8f5' },
|
|
39
42
|
{ name: 'error', light: ['#b91c1c'], dark: '#ff8a8a' },
|
|
@@ -165,7 +168,7 @@ function themeCss() {
|
|
|
165
168
|
' ' + D + ' .content .drawio { background: #ffffff; border-radius: 6px; box-shadow: 0 0 0 10px #ffffff; }',
|
|
166
169
|
// R7 甲: a Markdown-native inline svg (wrapped in .inline-svg by the renderer) gets the
|
|
167
170
|
// same white plate; its ink stays the light text colour because the plate is always white.
|
|
168
|
-
' ' + D + ' .content .inline-svg > svg, ' + D + ' .content .ed-block[data-svg-plate="1"] > svg, ' + D + ' .content .ed-block[data-svg-plate="1"] > p > svg { background: #ffffff; color: #1f2328; border-radius: 4px; box-shadow: 0 0 0 10px #ffffff; }',
|
|
171
|
+
' ' + D + ' .content .inline-svg > svg, ' + D + ' .content .ed-block[data-svg-plate="1"] > svg, ' + D + ' .content .ed-block[data-svg-plate="1"] > p > svg, ' + D + ' .content .ed-block[data-svg-plate="1"] .ed-li-text > svg, ' + D + ' .content .ed-block[data-svg-plate="1"] .ed-li-text > p > svg { background: #ffffff; color: #1f2328; border-radius: 4px; box-shadow: 0 0 0 10px #ffffff; }',
|
|
169
172
|
' ' + D + ' .lightbox-canvas > svg[data-md2doc-recoloured] { background: var(--md-bg); }',
|
|
170
173
|
' }',
|
|
171
174
|
' .md2doc-theme-toggle { position: fixed; right: 20px; bottom: 20px; z-index: 60; width: 40px; height: 40px;',
|