starlight-obsidian 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/components/Tags.astro +36 -0
- package/components/Twitter.astro +11 -0
- package/components/Youtube.astro +11 -0
- package/index.ts +125 -0
- package/libs/fs.ts +37 -0
- package/libs/html.ts +18 -0
- package/libs/integration.ts +21 -0
- package/libs/markdown.ts +43 -0
- package/libs/obsidian.ts +225 -0
- package/libs/path.ts +39 -0
- package/libs/plugin.ts +8 -0
- package/libs/rehype.ts +74 -0
- package/libs/remark.ts +670 -0
- package/libs/starlight.ts +263 -0
- package/overrides/PageTitle.astro +14 -0
- package/package.json +77 -0
- package/schema.ts +8 -0
- package/styles.css +42 -0
package/libs/rehype.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Element, ElementContent, Root } from 'hast'
|
|
2
|
+
import type { Literal } from 'mdast'
|
|
3
|
+
import { CONTINUE, SKIP, visit } from 'unist-util-visit'
|
|
4
|
+
|
|
5
|
+
const blockIdentifierRegex = /(?<identifier> *\^(?<name>[\w-]+))$/
|
|
6
|
+
|
|
7
|
+
export function rehypeStarlightObsidian() {
|
|
8
|
+
return function transformer(tree: Root) {
|
|
9
|
+
// Blocks are supported in paragraphs, list items, and blockquotes.
|
|
10
|
+
// https://help.obsidian.md/Linking+notes+and+files/Internal+links#Link%20to%20a%20block%20in%20a%20note
|
|
11
|
+
visit(tree, 'element', (node) => {
|
|
12
|
+
// Handle blockqoutes first as they are block which can contain paragraphs or list items and we want to hoist
|
|
13
|
+
// the IDs to the blockquote element.
|
|
14
|
+
if (node.tagName === 'blockquote') {
|
|
15
|
+
const lastChild = node.children.at(-1)
|
|
16
|
+
|
|
17
|
+
if (
|
|
18
|
+
!lastChild ||
|
|
19
|
+
lastChild.type !== 'element' ||
|
|
20
|
+
!(lastChild.tagName === 'p' || lastChild.tagName === 'ul' || lastChild.tagName === 'ol')
|
|
21
|
+
) {
|
|
22
|
+
return CONTINUE
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const lastGrandChild = lastChild.children.at(-1)
|
|
26
|
+
|
|
27
|
+
if (lastChild.tagName === 'p') {
|
|
28
|
+
transformBlockIdentifier(node, lastGrandChild)
|
|
29
|
+
} else if (lastGrandChild?.type === 'element' && lastGrandChild.tagName === 'li') {
|
|
30
|
+
transformBlockIdentifier(node, lastGrandChild.children.at(-1))
|
|
31
|
+
}
|
|
32
|
+
} else if (node.tagName === 'p' || node.tagName === 'li') {
|
|
33
|
+
transformBlockIdentifier(node, node.children.at(-1))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return CONTINUE
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function transformBlockIdentifier(reference: Element, node: ElementContent | undefined) {
|
|
42
|
+
if (!isNodeWithValue(node)) {
|
|
43
|
+
return CONTINUE
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const identifier = getBlockIdentifer(node)
|
|
47
|
+
|
|
48
|
+
if (!identifier) {
|
|
49
|
+
return CONTINUE
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
node.value = node.value.slice(0, identifier.length * -1)
|
|
53
|
+
reference.properties['id'] = `block-${identifier.name}`
|
|
54
|
+
|
|
55
|
+
return SKIP
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isNodeWithValue(node: ElementContent | undefined): node is NodeWithValue {
|
|
59
|
+
return node !== undefined && 'value' in node
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getBlockIdentifer(node: NodeWithValue): { length: number; name: string } | undefined {
|
|
63
|
+
const match = node.value.match(blockIdentifierRegex)
|
|
64
|
+
const identifier = match?.groups?.['identifier']
|
|
65
|
+
const name = match?.groups?.['name']
|
|
66
|
+
|
|
67
|
+
if (!identifier || !name) {
|
|
68
|
+
return undefined
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { length: identifier.length, name }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type NodeWithValue = ElementContent & Literal
|