Strip Markdown in TOC (#887)

pull/893/head
MrMugame 2024-06-12 20:05:29 +02:00 committed by GitHub
parent f22b370a4d
commit 0e2553839c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 143 additions and 3 deletions

135
plug-api/lib/markdown.ts Normal file
View File

@ -0,0 +1,135 @@
import { findNodeOfType, ParseTree, renderToText } from "$sb/lib/tree.ts";
export function stripMarkdown(
tree: ParseTree,
): string {
if (tree.type?.endsWith("Mark") || tree.type?.endsWith("Delimiter")) {
return "";
}
const stripArray = (arr: ParseTree[]) => arr.map(stripMarkdown).join("");
switch (tree.type) {
case "Document":
case "Emphasis":
case "Highlight":
case "Strikethrough":
case "InlineCode":
case "StrongEmphasis":
case "Superscript":
case "Subscript":
case "Paragraph":
case "ATXHeading1":
case "ATXHeading2":
case "ATXHeading3":
case "ATXHeading4":
case "ATXHeading5":
case "ATXHeading6":
case "Blockquote":
case "BulletList":
case "OrderedList":
case "ListItem":
case "Table":
case "TableHeader":
case "TableCell":
case "TableRow":
case "Task":
case "HTMLTag": {
return stripArray(tree.children!);
}
case "FencedCode":
case "CodeBlock": {
tree.children = tree.children!.filter((c) => c.type);
return stripArray(tree.children!);
}
case "Link": {
const linkTextChildren = tree.children!.slice(1, -4);
return stripArray(linkTextChildren);
}
case "Image": {
const altTextNode = findNodeOfType(tree, "WikiLinkAlias") ||
tree.children![1];
let altText = altTextNode && altTextNode.type !== "LinkMark"
? renderToText(altTextNode)
: "<Image>";
const dimReg = /\d*[^\|\s]*?[xX]\d*[^\|\s]*/.exec(altText);
if (dimReg) {
altText = altText.replace(dimReg[0], "").replace("|", "");
}
return altText;
}
case "WikiLink": {
const aliasNode = findNodeOfType(tree, "WikiLinkAlias");
let linkText;
if (aliasNode) {
linkText = aliasNode.children![0].text!;
} else {
const ref = findNodeOfType(tree, "WikiLinkPage")!.children![0].text!;
linkText = ref.split("/").pop()!;
}
return linkText;
}
case "NakedURL": {
const url = tree.children![0].text!;
return url;
}
case "CommandLink": {
const aliasNode = findNodeOfType(tree, "CommandLinkAlias");
let command;
if (aliasNode) {
command = aliasNode.children![0].text!;
} else {
command = tree.children![1].children![0].text!;
}
return command;
}
case "TaskState": {
return tree.children![1].text!;
}
case "Escape": {
return tree.children![0].text!.slice(1);
}
case "CodeText":
case "Entity": {
return tree.children![0].text!;
}
case "TemplateDirective":
case "DeadlineDate": {
return renderToText(tree);
}
case "CodeInfo":
case "CommentBlock":
case "FrontMatter":
case "Hashtag":
case "HardBreak":
case "HorizontalRule":
case "NamedAnchor":
case "Attribute": {
return "";
}
case undefined:
return tree.text!;
default:
console.log("Unknown tree type: ", tree.type);
return "";
}
}

View File

@ -1,6 +1,7 @@
import { editor, markdown, YAML } from "$sb/syscalls.ts"; import { editor, markdown, YAML } from "$sb/syscalls.ts";
import { CodeWidgetContent } from "../../plug-api/types.ts"; import { CodeWidgetContent } from "$sb/types.ts";
import { renderToText, traverseTree } from "$sb/lib/tree.ts"; import { stripMarkdown } from "$sb/lib/markdown.ts";
import { traverseTree } from "$sb/lib/tree.ts";
type Header = { type Header = {
name: string; name: string;
@ -31,7 +32,11 @@ export async function widget(
traverseTree(tree, (n) => { traverseTree(tree, (n) => {
if (n.type?.startsWith("ATXHeading")) { if (n.type?.startsWith("ATXHeading")) {
headers.push({ headers.push({
name: n.children!.slice(1).map(renderToText).join("").trim(), name: n.children!
.slice(1)
.map(stripMarkdown)
.join("")
.trim(),
pos: n.from!, pos: n.from!,
level: +n.type[n.type.length - 1], level: +n.type[n.type.length - 1],
}); });