diff --git a/src/index.ts b/src/index.ts index c94dcca..3b7a211 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,14 +4,27 @@ import { toHast } from "mdast-util-to-hast" import { toHtml } from "hast-util-to-html" import { toString } from 'mdast-util-to-string'; import { FindAndReplaceList, findAndReplace as mdastFindReplace } from "mdast-util-find-and-replace" +import type { Callout, Root, Tag } from "mdast"; declare module 'mdast' { - interface Tag extends Literal { + interface Tag extends Literal + { type: "tag"; data?: TagData | undefined; } interface TagData extends Data {} + interface Callout extends Parent + { + type: "callout"; + data?: CalloutData | undefined; + } + interface CalloutData extends Data + { + type: string; + title?: string; + fold?: boolean; + } interface PhrasingContentMap { tag: Tag; @@ -19,6 +32,7 @@ declare module 'mdast' interface RootContentMap { tag: Tag; + callout: Callout; } } @@ -139,9 +153,9 @@ function pathToRoot(slug: string) { } export default function ofm() { - return function (tree: any, file: any) { + return function (tree: Root, file: any) { const base = pathToRoot(file?.data?.slug ?? ''); - const replacements: FindAndReplaceList = [] + const replacements: FindAndReplaceList = []; replacements.push([ wikilinkRegex, @@ -164,7 +178,7 @@ export default function ofm() { ], } }, - ]) + ]); replacements.push([ highlightRegex, @@ -175,7 +189,7 @@ export default function ofm() { value: `${inner}`, } }, - ]) + ]); replacements.push([ commentRegex, @@ -186,7 +200,7 @@ export default function ofm() { value: `${inner}`, } }, - ]) + ]); replacements.push([ tagRegex, @@ -210,11 +224,11 @@ export default function ofm() { { type: 'text', value: tag } ] } - } + } as Tag; }, - ]) + ]); - visit(tree, "html", (node) => { + /*visit(tree, "html", (node) => { for (const [regex, replace] of replacements) { if (typeof replace === "string") { node.value = node.value.replace(regex, replace) @@ -233,93 +247,48 @@ export default function ofm() { }) } } - }) + })*/ mdastFindReplace(tree, replacements); - visit(tree, "blockquote", (node) => { - if (node.children.length === 0) { - return + visit(tree, "blockquote", (node, index, parent) => { + if (node.children.length === 0 || parent === null || index === null) { + return; } // find first line - const firstChild = node.children[0] + const firstChild = node.children[0]; if (firstChild.type !== "paragraph" || firstChild.children[0]?.type !== "text") { - return + return; } - const text = firstChild.children[0].value - const restChildren = firstChild.children.slice(1) - const [firstLine, ...remainingLines] = text.split("\n") - const remainingText = remainingLines.join("\n") + const text = firstChild.children[0].value; + const [firstLine, ...remainingLines] = text.split("\n"); const match = firstLine.match(/^\[\!(\w+)\]([+-]?)/); if (match && match.input) { - const [calloutDirective, typeString, collapseChar] = match - const calloutType = canonicalizeCallout( + const [calloutTitle, typeString, foldChar] = match; + const type = canonicalizeCallout( typeString.toLowerCase() as keyof typeof calloutMapping, - ) - const collapse = collapseChar === "+" || collapseChar === "-" - const defaultState = collapseChar === "-" ? "collapsed" : "expanded" - const titleContent = - match.input.slice(calloutDirective.length).trim() || capitalize(calloutType) - const titleNode = { - type: "paragraph", - children: [{ type: "text", value: titleContent + " " }, ...restChildren], - } - const title = mdastToHtml(titleNode) + ); + const fold = foldChar === "+" || foldChar === "-" ? foldChar === "-" : undefined; + const title = match.input.slice(calloutTitle.length).trim() || capitalize(type); - const toggleIcon = ` - - ` - - const titleHtml = { - type: "html", - value: `
-
${callouts[calloutType]}
-
${title}
- ${collapse ? toggleIcon : ""} -
`, - } - - const blockquoteContent: any[] = [titleHtml] - if (remainingText.length > 0) { - blockquoteContent.push({ - type: "paragraph", - hProperties: { className: "callout-content" }, - children: [ - { - type: "text", - value: remainingText, - }, - ], - }) - } - - // replace first line of blockquote with title and rest of the paragraph text - node.children.splice(0, 1, ...blockquoteContent) - - // add properties to base blockquote - node.data = { - hProperties: { - ...(node.data?.hProperties ?? {}), - className: `callout ${collapse ? "is-collapsible" : ""} ${defaultState === "collapsed" ? "is-collapsed" : "" - }`, - "data-callout": calloutType, - "data-callout-fold": collapse, - }, - } - } - }) - - visit(tree, "code", (node) => { - if (node.lang === "mermaid") { - node.data = { - hProperties: { - className: ["mermaid"], + firstChild.children[0].value = remainingLines.join('\n'); + parent.children[index] = { + type: 'callout', + data: { + type, + fold, + title, + hName: 'callout', + hProperties: { + type, + fold, + title, + }, }, + children: firstChild.children, } } })