Strip Markdown in TOC (#887)
parent
f22b370a4d
commit
0e2553839c
|
@ -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 "";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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],
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue