Various AT Protocol integrations with obsidian
20
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor header extracting

+11 -67
+1 -66
src/commands/publishDocument.ts
··· 6 6 import { SiteStandardDocument, SiteStandardPublication } from "@atcute/standard-site"; 7 7 import { PubLeafletContent } from "@atcute/leaflet"; 8 8 import { BlogPcktContent } from "@atcute/pckt"; 9 + import { extractFirstH1 } from "lib/markdown"; 9 10 10 11 export async function publishFileAsDocument(plugin: AtmospherePlugin) { 11 12 const file = plugin.app.workspace.getActiveFile(); ··· 74 75 }); 75 76 } 76 77 77 - function extractFirstH1(markdown: string): string | undefined { 78 - const lines = markdown.split(/\r?\n/); 79 - let inFence = false; 80 - let fenceMarker: string | null = null; 81 - 82 - for (const line of lines) { 83 - const trimmed = line.trim(); 84 - const fence = trimmed.match(/^(```+|~~~+)/); 85 - if (fence && fence[1]) { 86 - const marker = fence[1].charAt(0); 87 - if (!inFence) { 88 - inFence = true; 89 - fenceMarker = marker; 90 - } else if (fenceMarker === marker) { 91 - inFence = false; 92 - fenceMarker = null; 93 - } 94 - continue; 95 - } 96 - 97 - if (inFence) { 98 - continue; 99 - } 100 - 101 - const atxMatch = line.match(/^\s*#\s+(.+?)\s*$/); 102 - if (atxMatch?.[1]) { 103 - return atxMatch[1].trim(); 104 - } 105 - } 106 - 107 - for (let i = 0; i < lines.length - 1; i++) { 108 - const line = lines[i]; 109 - const next = lines[i + 1]; 110 - if (!line || !next) { 111 - continue; 112 - } 113 - const trimmed = line.trim(); 114 - 115 - const fence = trimmed.match(/^(```+|~~~+)/); 116 - if (fence && fence[1]) { 117 - const marker = fence[1].charAt(0); 118 - if (!inFence) { 119 - inFence = true; 120 - fenceMarker = marker; 121 - } else if (fenceMarker === marker) { 122 - inFence = false; 123 - fenceMarker = null; 124 - } 125 - continue; 126 - } 127 - 128 - if (inFence) { 129 - continue; 130 - } 131 - 132 - if (!trimmed) { 133 - continue; 134 - } 135 - 136 - if (/^\s*=+\s*$/.test(next)) { 137 - return trimmed; 138 - } 139 - } 140 - 141 - return undefined; 142 - } 143 78 144 79 async function buildDocumentRecord(plugin: AtmospherePlugin, file: TFile): Promise<{ record: SiteStandardDocument.Main; docUri?: ResourceUri }> { 145 80 const full = await plugin.app.vault.read(file);
+10 -1
src/lib/markdown/index.ts
··· 1 1 import { unified } from "unified"; 2 2 import remarkParse from "remark-parse"; 3 - import type { Root, RootContent } from "mdast"; 3 + import type { Root, RootContent, Heading } from "mdast"; 4 4 5 5 export function parseMarkdown(markdown: string): Root { 6 6 return unified().use(remarkParse).parse(markdown); ··· 24 24 } 25 25 26 26 return ""; 27 + } 28 + 29 + export function extractFirstH1(markdown: string): string | undefined { 30 + const tree = parseMarkdown(markdown); 31 + const first = tree.children.find( 32 + node => node.type === "heading" && node.depth === 1 33 + ) as Heading | undefined; 34 + 35 + return first ? extractText(first) : undefined; 27 36 } 28 37 29 38 /**