You've already forked obsidian-visualiser
Change shared files naming. Rework tree structure and item management rendering.
This commit is contained in:
81
shared/markdown.ts
Normal file
81
shared/markdown.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import type { Element, Root, RootContent } from "hast";
|
||||
import { dom, text, type Class, type Node } from "#shared/dom";
|
||||
import prose, { a, blockquote, tag, h1, h2, h3, h4, h5, hr, li, small, table, td, th, callout, type Prose } from "#shared/proses";
|
||||
import { heading } from "hast-util-heading";
|
||||
import { headingRank } from "hast-util-heading-rank";
|
||||
import { parseId } from "#shared/general";
|
||||
import { async } from "#shared/components";
|
||||
|
||||
export const defaultProses = { a, blockquote, tag, callout, h1, h2, h3, h4, h5, hr, li, small, table, td, th };
|
||||
export function renderMarkdown(markdown: Root, proses: Record<string, Prose>)
|
||||
{
|
||||
return dom('div', {}, markdown.children.map(e => renderContent(e, proses)));
|
||||
}
|
||||
export function renderMDAsText(markdown: string): string
|
||||
{
|
||||
return useMarkdown().text(markdown);
|
||||
}
|
||||
|
||||
function renderContent(node: RootContent, proses: Record<string, Prose>): Node
|
||||
{
|
||||
if(node.type === 'text' && node.value.length > 0 && node.value !== '\n')
|
||||
{
|
||||
return text(node.value);
|
||||
}
|
||||
else if(node.type === 'comment' && node.value.length > 0 && node.value !== '\n')
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
else if(node.type === 'element')
|
||||
{
|
||||
const children = node.children.map(e => renderContent(e, proses)), properties = { ...node.properties, class: node.properties.className as string | string[] };
|
||||
if(node.tagName in proses)
|
||||
return prose(node.tagName, proses[node.tagName] ?? { class: '' }, children, properties);
|
||||
else
|
||||
return dom(node.tagName as keyof HTMLElementTagNameMap, properties, children);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export interface MDProperties
|
||||
{
|
||||
class?: Class;
|
||||
style?: string | Record<string, string>;
|
||||
tags?: Record<string, Prose>;
|
||||
includeLowers?: boolean;
|
||||
}
|
||||
export function filterMarkdown(data: Root, filter: string, includeLowers: boolean = true)
|
||||
{
|
||||
const start = data?.children.findIndex(e => heading(e) && parseId(e.properties.id as string | undefined) === filter) ?? -1;
|
||||
|
||||
if(start !== -1)
|
||||
{
|
||||
let end = start;
|
||||
const rank = headingRank(data.children[start]!)!;
|
||||
while(end < data.children.length)
|
||||
{
|
||||
end++;
|
||||
if(heading(data.children[end]) && (!includeLowers || headingRank(data.children[end]!)! <= rank))
|
||||
break;
|
||||
}
|
||||
return { ...data, children: data.children.slice(start, end) };
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
export function markdownReference(content: string, filter?: string, properties?: MDProperties)
|
||||
{
|
||||
const state = async('large', useMarkdown().parse(content).then(data => {
|
||||
if(filter) data = filterMarkdown(data, filter, properties?.includeLowers);
|
||||
|
||||
const el = dom('div', properties, data.children.map(e => renderContent(e, Object.assign({}, { a, blockquote, tag, callout, h1, h2, h3, h4, h5, hr, li, small, table, td, th }, properties?.tags))));
|
||||
|
||||
return el;
|
||||
}));
|
||||
return state;
|
||||
}
|
||||
export default function(content: string, filter?: string, properties?: MDProperties)
|
||||
{
|
||||
return markdownReference(content, filter, properties).current;
|
||||
}
|
||||
Reference in New Issue
Block a user