@abraca/mcp 1.8.1 → 1.9.1
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/package.json
CHANGED
|
@@ -164,6 +164,10 @@ export function parseFrontmatter(markdown: string): FrontmatterResult {
|
|
|
164
164
|
interface InlineToken {
|
|
165
165
|
text: string
|
|
166
166
|
attrs?: Record<string, unknown>
|
|
167
|
+
/** If set, emit an inline Y.XmlElement with this nodeName instead of text+marks. */
|
|
168
|
+
node?: string
|
|
169
|
+
/** Attributes for the inline node (when node is set). */
|
|
170
|
+
nodeAttrs?: Record<string, string>
|
|
167
171
|
}
|
|
168
172
|
|
|
169
173
|
function parseInline(text: string): InlineToken[] {
|
|
@@ -190,10 +194,9 @@ function parseInline(text: string): InlineToken[] {
|
|
|
190
194
|
const kbdProps = parseMdcProps(`{${match[4]}}`)
|
|
191
195
|
tokens.push({ text: kbdProps['value'] || '', attrs: { kbd: { value: kbdProps['value'] || '' } } })
|
|
192
196
|
} else if (match[5] !== undefined) {
|
|
193
|
-
// Inline wikilink [[docId]] or [[docId|label]] →
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
tokens.push({ text: displayText!, attrs: { link: { href: `/doc/${docId}` } } })
|
|
197
|
+
// Inline wikilink [[docId]] or [[docId|label]] → inline docLink node
|
|
198
|
+
// (the label is derived from the tree at render time; legacy label is dropped)
|
|
199
|
+
tokens.push({ text: '', node: 'docLink', nodeAttrs: { docId: match[5]! } })
|
|
197
200
|
} else if (match[7] !== undefined) {
|
|
198
201
|
tokens.push({ text: match[7], attrs: { strike: true } })
|
|
199
202
|
} else if (match[8] !== undefined) {
|
|
@@ -213,7 +216,7 @@ function parseInline(text: string): InlineToken[] {
|
|
|
213
216
|
if (lastIndex < stripped.length) {
|
|
214
217
|
tokens.push({ text: stripped.slice(lastIndex) })
|
|
215
218
|
}
|
|
216
|
-
return tokens.filter(t => t.text.length > 0)
|
|
219
|
+
return tokens.filter(t => t.node || t.text.length > 0)
|
|
217
220
|
}
|
|
218
221
|
|
|
219
222
|
// ── Block-level parser ───────────────────────────────────────────────────────
|
|
@@ -247,7 +250,7 @@ type Block =
|
|
|
247
250
|
| { type: 'field'; name: string; fieldType: string; required: boolean; innerBlocks: Block[] }
|
|
248
251
|
| { type: 'fieldGroup'; fields: Block[] }
|
|
249
252
|
| { type: 'image'; src: string; alt: string; width?: string; height?: string }
|
|
250
|
-
| { type: 'docEmbed'; docId: string }
|
|
253
|
+
| { type: 'docEmbed'; docId: string; seamless?: boolean }
|
|
251
254
|
| { type: 'svgEmbed'; svg: string; title: string }
|
|
252
255
|
|
|
253
256
|
function parseTableRow(line: string): string[] {
|
|
@@ -382,9 +385,11 @@ function parseBlocks(markdown: string): Block[] {
|
|
|
382
385
|
continue
|
|
383
386
|
}
|
|
384
387
|
|
|
385
|
-
const docEmbedMatch = line.match(/^!\[\[([^\]|]+?)(?:\|[^\]]*?)?\]\]\s*$/)
|
|
388
|
+
const docEmbedMatch = line.match(/^!\[\[([^\]|]+?)(?:\|[^\]]*?)?\]\](\{[^}]*\})?\s*$/)
|
|
386
389
|
if (docEmbedMatch) {
|
|
387
|
-
|
|
390
|
+
const props = parseMdcProps(docEmbedMatch[2])
|
|
391
|
+
const seamless = 'seamless' in props || props['seamless'] === 'true' || /\{[^}]*\bseamless\b[^}]*\}/.test(docEmbedMatch[2] ?? '')
|
|
392
|
+
blocks.push({ type: 'docEmbed', docId: docEmbedMatch[1]!, seamless: seamless || undefined })
|
|
388
393
|
i++
|
|
389
394
|
continue
|
|
390
395
|
}
|
|
@@ -600,17 +605,28 @@ function parseBlocks(markdown: string): Block[] {
|
|
|
600
605
|
// ── Y.js content population ──────────────────────────────────────────────────
|
|
601
606
|
|
|
602
607
|
function fillTextInto(el: Y.XmlElement, tokens: InlineToken[]): void {
|
|
603
|
-
const filtered = tokens.filter(t => t.text.length > 0)
|
|
608
|
+
const filtered = tokens.filter(t => t.node || t.text.length > 0)
|
|
604
609
|
if (!filtered.length) return
|
|
605
610
|
|
|
606
|
-
const
|
|
607
|
-
|
|
611
|
+
const children: (Y.XmlText | Y.XmlElement)[] = filtered.map((tok) => {
|
|
612
|
+
if (tok.node) {
|
|
613
|
+
const xe = new Y.XmlElement(tok.node)
|
|
614
|
+
if (tok.nodeAttrs) {
|
|
615
|
+
for (const [k, v] of Object.entries(tok.nodeAttrs)) xe.setAttribute(k, v)
|
|
616
|
+
}
|
|
617
|
+
return xe
|
|
618
|
+
}
|
|
619
|
+
return new Y.XmlText()
|
|
620
|
+
})
|
|
621
|
+
el.insert(0, children)
|
|
608
622
|
|
|
609
623
|
filtered.forEach((tok, i) => {
|
|
624
|
+
if (tok.node) return
|
|
625
|
+
const xt = children[i] as Y.XmlText
|
|
610
626
|
if (tok.attrs) {
|
|
611
|
-
|
|
627
|
+
xt.insert(0, tok.text, tok.attrs as Record<string, boolean | object>)
|
|
612
628
|
} else {
|
|
613
|
-
|
|
629
|
+
xt.insert(0, tok.text)
|
|
614
630
|
}
|
|
615
631
|
})
|
|
616
632
|
}
|
|
@@ -837,6 +853,7 @@ function fillBlock(el: Y.XmlElement, block: Block): void {
|
|
|
837
853
|
}
|
|
838
854
|
case 'docEmbed': {
|
|
839
855
|
el.setAttribute('docId', block.docId)
|
|
856
|
+
if (block.seamless) el.setAttribute('seamless', 'true')
|
|
840
857
|
break
|
|
841
858
|
}
|
|
842
859
|
case 'svgEmbed': {
|
|
@@ -38,6 +38,12 @@ function elementTextContent(el: Y.XmlElement | Y.XmlFragment): string {
|
|
|
38
38
|
if (child instanceof Y.XmlText) {
|
|
39
39
|
parts.push(xmlTextToMarkdown(child))
|
|
40
40
|
} else if (child instanceof Y.XmlElement) {
|
|
41
|
+
// Inline nodes that carry meaning at the inline level.
|
|
42
|
+
if (child.nodeName === 'docLink') {
|
|
43
|
+
const docId = child.getAttribute('docId')
|
|
44
|
+
if (docId) parts.push(`[[${docId}]]`)
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
41
47
|
parts.push(elementTextContent(child))
|
|
42
48
|
}
|
|
43
49
|
}
|
|
@@ -97,7 +103,10 @@ function serializeElement(el: Y.XmlElement, indent = ''): string {
|
|
|
97
103
|
|
|
98
104
|
case 'docEmbed': {
|
|
99
105
|
const docId = el.getAttribute('docId')
|
|
100
|
-
|
|
106
|
+
if (!docId) return ''
|
|
107
|
+
const seamlessAttr = el.getAttribute('seamless')
|
|
108
|
+
const seamless = seamlessAttr === true || seamlessAttr === 'true'
|
|
109
|
+
return seamless ? `![[${docId}]]{seamless}` : `![[${docId}]]`
|
|
101
110
|
}
|
|
102
111
|
|
|
103
112
|
case 'svgEmbed': {
|