@livemark/markdown 0.0.0-stage → 0.45.0

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.
Files changed (184) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +5 -2
  3. package/build/actions/markdown/compile.d.ts +27 -0
  4. package/build/actions/markdown/compile.js +48 -0
  5. package/build/actions/processor/create.d.ts +17 -0
  6. package/build/actions/processor/create.js +212 -0
  7. package/build/components/Abbr.d.ts +5 -0
  8. package/build/components/Abbr.js +7 -0
  9. package/build/components/AnsiCode.d.ts +4 -0
  10. package/build/components/AnsiCode.js +7 -0
  11. package/build/components/Audio.d.ts +4 -0
  12. package/build/components/Audio.js +9 -0
  13. package/build/components/Badge.d.ts +5 -0
  14. package/build/components/Badge.js +7 -0
  15. package/build/components/Button.d.ts +7 -0
  16. package/build/components/Button.js +11 -0
  17. package/build/components/Callout.d.ts +8 -0
  18. package/build/components/Callout.js +41 -0
  19. package/build/components/Card.d.ts +7 -0
  20. package/build/components/Card.js +16 -0
  21. package/build/components/Cards.d.ts +4 -0
  22. package/build/components/Cards.js +6 -0
  23. package/build/components/CodeBlock.d.ts +1 -0
  24. package/build/components/CodeBlock.js +50 -0
  25. package/build/components/CodeTabs.d.ts +6 -0
  26. package/build/components/CodeTabs.js +48 -0
  27. package/build/components/Column.d.ts +4 -0
  28. package/build/components/Column.js +6 -0
  29. package/build/components/Columns.d.ts +5 -0
  30. package/build/components/Columns.js +8 -0
  31. package/build/components/DefinitionList.d.ts +7 -0
  32. package/build/components/DefinitionList.js +14 -0
  33. package/build/components/Details.d.ts +5 -0
  34. package/build/components/Details.js +10 -0
  35. package/build/components/Filetree.d.ts +4 -0
  36. package/build/components/Filetree.js +22 -0
  37. package/build/components/FootnoteRef.d.ts +4 -0
  38. package/build/components/FootnoteRef.js +33 -0
  39. package/build/components/Heading.d.ts +8 -0
  40. package/build/components/Heading.js +18 -0
  41. package/build/components/Icon.d.ts +5 -0
  42. package/build/components/Icon.js +10 -0
  43. package/build/components/Markdown.d.ts +13 -0
  44. package/build/components/Markdown.js +75 -0
  45. package/build/components/Mermaid.d.ts +4 -0
  46. package/build/components/Mermaid.js +10 -0
  47. package/build/components/MermaidRenderer.d.ts +4 -0
  48. package/build/components/MermaidRenderer.js +44 -0
  49. package/build/components/PackageTabs.d.ts +9 -0
  50. package/build/components/PackageTabs.js +26 -0
  51. package/build/components/SortableTable.d.ts +5 -0
  52. package/build/components/SortableTable.js +63 -0
  53. package/build/components/Tab.d.ts +5 -0
  54. package/build/components/Tab.js +6 -0
  55. package/build/components/Tabs.d.ts +5 -0
  56. package/build/components/Tabs.js +46 -0
  57. package/build/components/Toc.d.ts +4 -0
  58. package/build/components/Toc.js +14 -0
  59. package/build/components/Video.d.ts +4 -0
  60. package/build/components/Video.js +13 -0
  61. package/build/components/ZoomImage.d.ts +4 -0
  62. package/build/components/ZoomImage.js +26 -0
  63. package/build/elements/badge.d.ts +7 -0
  64. package/build/elements/badge.js +36 -0
  65. package/build/elements/button.d.ts +8 -0
  66. package/build/elements/button.js +37 -0
  67. package/build/elements/card.d.ts +11 -0
  68. package/build/elements/card.js +25 -0
  69. package/build/elements/collapsible.d.ts +5 -0
  70. package/build/elements/collapsible.js +13 -0
  71. package/build/elements/hover-card.d.ts +5 -0
  72. package/build/elements/hover-card.js +14 -0
  73. package/build/elements/separator.d.ts +3 -0
  74. package/build/elements/separator.js +8 -0
  75. package/build/elements/table.d.ts +9 -0
  76. package/build/elements/table.js +28 -0
  77. package/build/elements/tooltip.d.ts +6 -0
  78. package/build/elements/tooltip.js +17 -0
  79. package/build/helpers/ansi.d.ts +3 -0
  80. package/build/helpers/ansi.js +208 -0
  81. package/build/helpers/article-link.d.ts +7 -0
  82. package/build/helpers/article-link.js +8 -0
  83. package/build/helpers/code-icon.d.ts +2 -0
  84. package/build/helpers/code-icon.js +57 -0
  85. package/build/helpers/content-warnings.d.ts +8 -0
  86. package/build/helpers/content-warnings.js +47 -0
  87. package/build/helpers/dynamic-icon-resolver.d.ts +5 -0
  88. package/build/helpers/dynamic-icon-resolver.js +11 -0
  89. package/build/helpers/dynamic-icon.d.ts +5 -0
  90. package/build/helpers/dynamic-icon.js +14 -0
  91. package/build/helpers/frontmatter.d.ts +5 -0
  92. package/build/helpers/frontmatter.js +16 -0
  93. package/build/helpers/icon-names.d.ts +11 -0
  94. package/build/helpers/icon-names.js +35 -0
  95. package/build/helpers/message-format.d.ts +2 -0
  96. package/build/helpers/message-format.js +7 -0
  97. package/build/helpers/node-text.d.ts +9 -0
  98. package/build/helpers/node-text.js +9 -0
  99. package/build/helpers/site-messages.d.ts +86 -0
  100. package/build/helpers/site-messages.js +7 -0
  101. package/build/helpers/toc-context.d.ts +5 -0
  102. package/build/helpers/toc-context.js +8 -0
  103. package/build/helpers/toc-outline.d.ts +3 -0
  104. package/build/helpers/toc-outline.js +16 -0
  105. package/build/helpers/youtube-id.d.ts +2 -0
  106. package/build/helpers/youtube-id.js +25 -0
  107. package/build/hooks/icons.d.ts +13 -0
  108. package/build/hooks/icons.js +12 -0
  109. package/build/hooks/messages.d.ts +95 -0
  110. package/build/hooks/messages.js +17 -0
  111. package/build/models/message.d.ts +177 -0
  112. package/build/models/message.js +88 -0
  113. package/build/models/plugins.d.ts +10 -0
  114. package/build/models/plugins.js +6 -0
  115. package/build/models/theme.d.ts +76 -0
  116. package/build/models/theme.js +71 -0
  117. package/build/models/toc.d.ts +5 -0
  118. package/build/models/toc.js +2 -0
  119. package/build/plugins/twoslash.d.ts +13 -0
  120. package/build/plugins/twoslash.js +146 -0
  121. package/package.json +63 -3
  122. package/source/actions/markdown/compile.ts +82 -0
  123. package/source/actions/processor/create.ts +235 -0
  124. package/source/components/Abbr.tsx +13 -0
  125. package/source/components/AnsiCode.tsx +17 -0
  126. package/source/components/Audio.tsx +18 -0
  127. package/source/components/Badge.tsx +9 -0
  128. package/source/components/Button.tsx +33 -0
  129. package/source/components/Callout.tsx +68 -0
  130. package/source/components/Card.tsx +48 -0
  131. package/source/components/Cards.tsx +8 -0
  132. package/source/components/CodeBlock.tsx +144 -0
  133. package/source/components/CodeTabs.tsx +81 -0
  134. package/source/components/Column.tsx +4 -0
  135. package/source/components/Columns.tsx +10 -0
  136. package/source/components/DefinitionList.tsx +18 -0
  137. package/source/components/Details.tsx +30 -0
  138. package/source/components/Filetree.tsx +63 -0
  139. package/source/components/FootnoteRef.tsx +52 -0
  140. package/source/components/Heading.tsx +20 -0
  141. package/source/components/Icon.tsx +10 -0
  142. package/source/components/Markdown.tsx +89 -0
  143. package/source/components/Mermaid.tsx +20 -0
  144. package/source/components/MermaidRenderer.tsx +48 -0
  145. package/source/components/PackageTabs.tsx +72 -0
  146. package/source/components/SortableTable.tsx +81 -0
  147. package/source/components/Tab.tsx +4 -0
  148. package/source/components/Tabs.tsx +75 -0
  149. package/source/components/Toc.tsx +30 -0
  150. package/source/components/Video.tsx +28 -0
  151. package/source/components/ZoomImage.tsx +25 -0
  152. package/source/elements/badge.tsx +53 -0
  153. package/source/elements/button.tsx +61 -0
  154. package/source/elements/card.tsx +102 -0
  155. package/source/elements/collapsible.tsx +15 -0
  156. package/source/elements/hover-card.tsx +47 -0
  157. package/source/elements/separator.tsx +22 -0
  158. package/source/elements/table.tsx +103 -0
  159. package/source/elements/tooltip.tsx +60 -0
  160. package/source/helpers/ansi.ts +210 -0
  161. package/source/helpers/article-link.ts +11 -0
  162. package/source/helpers/code-icon.ts +59 -0
  163. package/source/helpers/content-warnings.ts +56 -0
  164. package/source/helpers/dynamic-icon-resolver.tsx +9 -0
  165. package/source/helpers/dynamic-icon.tsx +19 -0
  166. package/source/helpers/frontmatter.ts +16 -0
  167. package/source/helpers/icon-names.ts +37 -0
  168. package/source/helpers/message-format.ts +5 -0
  169. package/source/helpers/node-text.ts +14 -0
  170. package/source/helpers/site-messages.ts +8 -0
  171. package/source/helpers/toc-context.ts +10 -0
  172. package/source/helpers/toc-outline.ts +23 -0
  173. package/source/helpers/youtube-id.ts +23 -0
  174. package/source/hooks/icons.ts +18 -0
  175. package/source/hooks/messages.ts +28 -0
  176. package/source/models/message.ts +96 -0
  177. package/source/models/plugins.ts +11 -0
  178. package/source/models/theme.ts +78 -0
  179. package/source/models/toc.ts +5 -0
  180. package/source/plugins/twoslash.ts +163 -0
  181. package/source/standalone.css +7 -0
  182. package/source/styles/general.css +214 -0
  183. package/source/styles/markdown.css +231 -0
  184. package/source/styles/shape.css +14 -0
@@ -0,0 +1,96 @@
1
+ import { z } from "zod"
2
+
3
+ /** UI strings; each default is the English text, so `Messages.parse({})` is English. */
4
+ export type Messages = z.infer<typeof Messages>
5
+ export const Messages = z.strictObject({
6
+ "nav.docs": z.string().default("Docs"),
7
+ "nav.more": z.string().default("More"),
8
+ "nav.navigation": z.string().default("Navigation"),
9
+ "nav.chooseSection": z.string().default("Choose section"),
10
+ "nav.section": z.string().default("Section"),
11
+ "nav.toggleSubmenu": z.string().default("Toggle {title} submenu"),
12
+ "nav.previous": z.string().default("Previous"),
13
+ "nav.next": z.string().default("Next"),
14
+ "nav.backToTop": z.string().default("Back to top"),
15
+ "nav.close": z.string().default("Close"),
16
+ "nav.sections": z.string().default("Sections"),
17
+ "nav.articles": z.string().default("Articles"),
18
+ "nav.links": z.string().default("Links"),
19
+ "nav.releases": z.string().default("Releases"),
20
+ "nav.posts": z.string().default("Posts"),
21
+ "nav.tags": z.string().default("Tags"),
22
+ "nav.breadcrumbs": z.string().default("Breadcrumbs"),
23
+ "language.choose": z.string().default("Choose language"),
24
+ "language.untranslated": z.string().default("Not translated yet"),
25
+ "theme.change": z.string().default("Change theme"),
26
+ "theme.light": z.string().default("Light"),
27
+ "theme.dark": z.string().default("Dark"),
28
+ "theme.system": z.string().default("System"),
29
+ "shortcuts.title": z.string().default("Keyboard shortcuts"),
30
+ "shortcuts.search": z.string().default("Search"),
31
+ "shortcuts.theme": z.string().default("Toggle theme"),
32
+ "shortcuts.sidebar": z.string().default("Toggle sidebar"),
33
+ "shortcuts.scrollDown": z.string().default("Scroll down"),
34
+ "shortcuts.scrollUp": z.string().default("Scroll up"),
35
+ "shortcuts.top": z.string().default("Back to top"),
36
+ "shortcuts.bottom": z.string().default("Go to bottom"),
37
+ "shortcuts.next": z.string().default("Next page"),
38
+ "shortcuts.previous": z.string().default("Previous page"),
39
+ "search.label": z.string().default("Search"),
40
+ "search.description": z.string().default("Search documentation"),
41
+ "search.placeholder": z.string().default("Search docs..."),
42
+ "search.empty": z.string().default("No results found."),
43
+ "search.hint": z.string().default("Type to search across all contents."),
44
+ "search.close": z.string().default("Close search"),
45
+ "search.pages": z.string().default("Pages"),
46
+ "search.button": z.string().default("Search..."),
47
+ "search.navigate": z.string().default("navigate"),
48
+ "search.select": z.string().default("select"),
49
+ "search.dismiss": z.string().default("close"),
50
+ "toc.title": z.string().default("On this page"),
51
+ "toc.contents": z.string().default("Contents"),
52
+ "toc.actions": z.string().default("Actions"),
53
+ "toc.inline": z.string().default("Table of Contents"),
54
+ "page.updated": z.string().default("Updated {date}"),
55
+ "page.published": z.string().default("Published {date}"),
56
+ "page.edit": z.string().default("Edit on GitHub"),
57
+ "page.view": z.string().default("View on GitHub"),
58
+ "page.copyMarkdown": z.string().default("Copy Markdown"),
59
+ "page.openChatGpt": z.string().default("Open in ChatGPT"),
60
+ "page.openClaude": z.string().default("Open in Claude"),
61
+ "page.llmPrompt": z.string().default("Read {url}, I want to ask questions about it."),
62
+ "code.copy": z.string().default("Copy code"),
63
+ "code.copied": z.string().default("Copied!"),
64
+ "code.wrapOn": z.string().default("Enable wrap"),
65
+ "code.wrapOff": z.string().default("Disable wrap"),
66
+ "code.expand": z.string().default("Expand"),
67
+ "callout.note": z.string().default("Note"),
68
+ "callout.info": z.string().default("Info"),
69
+ "callout.tip": z.string().default("Tip"),
70
+ "callout.warning": z.string().default("Warning"),
71
+ "callout.danger": z.string().default("Danger"),
72
+ "blog.title": z.string().default("Blog"),
73
+ "blog.allPosts": z.string().default("All Posts"),
74
+ "blog.recentPosts": z.string().default("Recent Posts"),
75
+ "blog.rssFeed": z.string().default("RSS Feed"),
76
+ "blog.tagged": z.string().default("Posts tagged '{tag}'"),
77
+ "changelog.title": z.string().default("Changelog"),
78
+ "changelog.allReleases": z.string().default("All Releases"),
79
+ "changelog.recentReleases": z.string().default("Recent Releases"),
80
+ "error.notFound": z.string().default("The page you're looking for doesn't exist."),
81
+ "error.goBack": z.string().default("Go Back"),
82
+ "error.tryAgain": z.string().default("Try Again"),
83
+ "error.home": z.string().default("Home"),
84
+ "media.loadingDiagram": z.string().default("Loading diagram…"),
85
+ "media.youtube": z.string().default("YouTube video"),
86
+ "media.soundcloud": z.string().default("SoundCloud audio"),
87
+ "footnote.missing": z.string().default("Footnote not found"),
88
+ "footer.createdWith": z.string().default("Created with {heart} and {livemark}"),
89
+ })
90
+
91
+ /** A key of {@link Messages}. */
92
+ export type MessageKey = keyof Messages
93
+
94
+ /** Per-key overrides a project sets for one language; unknown keys are rejected. */
95
+ export type MessageOverrides = z.infer<typeof MessageOverrides>
96
+ export const MessageOverrides = z.partialRecord(Messages.keyof(), z.string())
@@ -0,0 +1,11 @@
1
+ import type { Pluggable } from "textlane"
2
+ import { z } from "zod"
3
+
4
+ /** Plugins added to the Markdown pipeline: unified-style attachers or native textlane
5
+ * plugins. `md` runs on the Markdown tree before heading ids and components, `html` on
6
+ * the HTML tree before heading slugs and the table of contents. */
7
+ export type MarkdownPlugins = z.infer<typeof MarkdownPlugins>
8
+ export const MarkdownPlugins = z.strictObject({
9
+ md: z.array(z.custom<Pluggable>()).optional(),
10
+ html: z.array(z.custom<Pluggable>()).optional(),
11
+ })
@@ -0,0 +1,78 @@
1
+ import { z } from "zod"
2
+
3
+ /** Light syntax highlighting theme (Shiki) */
4
+ /** A light Shiki theme name. */
5
+ export type CodeThemeLight = z.infer<typeof CodeThemeLight>
6
+ export const CodeThemeLight = z.enum([
7
+ "ayu-light",
8
+ "catppuccin-latte",
9
+ "everforest-light",
10
+ "github-light",
11
+ "github-light-default",
12
+ "github-light-high-contrast",
13
+ "gruvbox-light-hard",
14
+ "gruvbox-light-medium",
15
+ "gruvbox-light-soft",
16
+ "horizon-bright",
17
+ "kanagawa-lotus",
18
+ "light-plus",
19
+ "material-theme-lighter",
20
+ "min-light",
21
+ "night-owl-light",
22
+ "one-light",
23
+ "rose-pine-dawn",
24
+ "slack-ochin",
25
+ "snazzy-light",
26
+ "solarized-light",
27
+ "vitesse-light",
28
+ ])
29
+
30
+ /** Dark syntax highlighting theme (Shiki) */
31
+ /** A dark Shiki theme name. */
32
+ export type CodeThemeDark = z.infer<typeof CodeThemeDark>
33
+ export const CodeThemeDark = z.enum([
34
+ "andromeeda",
35
+ "aurora-x",
36
+ "ayu-dark",
37
+ "ayu-mirage",
38
+ "catppuccin-frappe",
39
+ "catppuccin-macchiato",
40
+ "catppuccin-mocha",
41
+ "dark-plus",
42
+ "dracula",
43
+ "dracula-soft",
44
+ "everforest-dark",
45
+ "github-dark",
46
+ "github-dark-default",
47
+ "github-dark-dimmed",
48
+ "github-dark-high-contrast",
49
+ "gruvbox-dark-hard",
50
+ "gruvbox-dark-medium",
51
+ "gruvbox-dark-soft",
52
+ "horizon",
53
+ "houston",
54
+ "kanagawa-dragon",
55
+ "kanagawa-wave",
56
+ "laserwave",
57
+ "material-theme",
58
+ "material-theme-darker",
59
+ "material-theme-ocean",
60
+ "material-theme-palenight",
61
+ "min-dark",
62
+ "monokai",
63
+ "night-owl",
64
+ "nord",
65
+ "one-dark-pro",
66
+ "plastic",
67
+ "poimandres",
68
+ "red",
69
+ "rose-pine",
70
+ "rose-pine-moon",
71
+ "slack-dark",
72
+ "solarized-dark",
73
+ "synthwave-84",
74
+ "tokyo-night",
75
+ "vesper",
76
+ "vitesse-black",
77
+ "vitesse-dark",
78
+ ])
@@ -0,0 +1,5 @@
1
+ export interface TocItem {
2
+ url: string
3
+ title: string
4
+ depth: number
5
+ }
@@ -0,0 +1,163 @@
1
+ import { Worker } from "node:worker_threads"
2
+ import type { Element, ElementContent, Root, RootContent } from "hast"
3
+ import { readNodeText } from "../helpers/node-text.ts"
4
+
5
+ /** A fenced code block whose meta names `twoslash` */
6
+ export const TWOSLASH_FENCE = /^[ \t>]*(?:`{3,}|~{3,})[^\n]*\btwoslash\b/m
7
+
8
+ const TWOSLASH = /(?:^|\s)twoslash(?:\s|$)/
9
+
10
+ /** Re-highlight the code blocks whose meta names `twoslash` with Shiki's twoslash
11
+ * transformer: the one stage textlane cannot run natively, as it needs TypeScript. */
12
+ export function twoslashStage(options: { themes: { light: string; dark: string } }) {
13
+ return async (tree: Root) => {
14
+ const blocks: { node: Element; meta: string; lang: string }[] = []
15
+ for (const node of walkElements(tree)) {
16
+ if (node.tagName !== "pre") continue
17
+ const meta = node.properties["data-meta"] ?? node.properties.dataMeta
18
+ if (typeof meta !== "string" || !TWOSLASH.test(meta)) continue
19
+ blocks.push({ node, meta, lang: readLanguage(node) })
20
+ }
21
+ const themes = options.themes
22
+ await Promise.all(
23
+ blocks.map(async block => {
24
+ const pre = await renderBlock({
25
+ ...block,
26
+ code: readNodeText(block.node),
27
+ themes,
28
+ })
29
+ if (!pre) return
30
+ block.node.properties = structuredClone(pre.properties)
31
+ block.node.children = structuredClone(pre.children) as ElementContent[]
32
+ }),
33
+ )
34
+ }
35
+ }
36
+
37
+ /** Start TypeScript in the twoslash worker now, so it is ready once a block needs it */
38
+ export function warmTwoslash() {
39
+ readWorker()
40
+ }
41
+
42
+ interface BlockRequest {
43
+ code: string
44
+ lang: string
45
+ meta: string
46
+ themes: { light: string; dark: string }
47
+ }
48
+
49
+ // Translated pages repeat the same blocks, which twoslash would check again
50
+ const rendered = new Map<string, Promise<Element | undefined>>()
51
+
52
+ function renderBlock(request: BlockRequest) {
53
+ const key = JSON.stringify([request.lang, request.meta, request.themes, request.code])
54
+ let pre = rendered.get(key)
55
+ if (!pre) {
56
+ pre = callWorker(request)
57
+ rendered.set(key, pre)
58
+ }
59
+ return pre
60
+ }
61
+
62
+ interface Pending {
63
+ resolve: (pre: Element | undefined) => void
64
+ reject: (error: Error) => void
65
+ }
66
+
67
+ // TypeScript takes ~0.8 s to start on the thread twoslash runs on; a worker keeps it
68
+ // off the main thread, where textlane compiles every other article meanwhile
69
+ let worker: { thread: Worker; pending: Map<number, Pending>; next: number } | undefined
70
+
71
+ function readWorker() {
72
+ if (worker) return worker
73
+ const thread = new Worker(WORKER_SOURCE, {
74
+ eval: true,
75
+ // an eval'd worker resolves bare specifiers from the cwd, so it imports the
76
+ // packages this module resolves rather than resolving them itself
77
+ workerData: {
78
+ shiki: import.meta.resolve("shiki"),
79
+ twoslash: import.meta.resolve("@shikijs/twoslash"),
80
+ },
81
+ })
82
+ const pending = new Map<number, Pending>()
83
+ thread.on("message", (message: { id: number; pre?: Element; error?: string }) => {
84
+ const call = pending.get(message.id)
85
+ pending.delete(message.id)
86
+ if (pending.size === 0) thread.unref()
87
+ if (message.error) call?.reject(new Error(message.error))
88
+ else call?.resolve(message.pre)
89
+ })
90
+ thread.on("error", error => {
91
+ for (const call of pending.values()) call.reject(error)
92
+ pending.clear()
93
+ worker = undefined
94
+ })
95
+ // Only a worker with blocks in flight keeps the build alive; `on("message")` refs it
96
+ thread.unref()
97
+ worker = { thread, pending, next: 0 }
98
+ return worker
99
+ }
100
+
101
+ function callWorker(request: BlockRequest) {
102
+ const current = readWorker()
103
+ const id = current.next++
104
+ return new Promise<Element | undefined>((resolve, reject) => {
105
+ current.pending.set(id, { resolve, reject })
106
+ current.thread.ref()
107
+ current.thread.postMessage({ id, ...request })
108
+ })
109
+ }
110
+
111
+ // The first twoslash call builds TypeScript's program over `lib.*.d.ts`; one throwaway
112
+ // block pays that while the main thread still has other articles to compile
113
+ const WORKER_SOURCE = `
114
+ const { parentPort, workerData } = require("node:worker_threads")
115
+ const ready = (async () => {
116
+ const { bundledLanguages, getSingletonHighlighter } = await import(workerData.shiki)
117
+ const { transformerTwoslash } = await import(workerData.twoslash)
118
+ const transformer = transformerTwoslash({ explicitTrigger: true })
119
+ const highlighter = await getSingletonHighlighter({ themes: [], langs: ["ts"] })
120
+ highlighter.codeToHast("const a = 1", {
121
+ lang: "ts",
122
+ theme: "none",
123
+ meta: { __raw: "twoslash" },
124
+ transformers: [transformer],
125
+ })
126
+ return { bundledLanguages, highlighter, transformer }
127
+ })()
128
+ parentPort.on("message", async request => {
129
+ try {
130
+ const { bundledLanguages, highlighter, transformer } = await ready
131
+ const lang = request.lang in bundledLanguages ? request.lang : "ts"
132
+ await highlighter.loadLanguage(lang)
133
+ await highlighter.loadTheme(request.themes.light, request.themes.dark)
134
+ const fragment = highlighter.codeToHast(request.code, {
135
+ lang,
136
+ themes: request.themes,
137
+ meta: { __raw: request.meta, "data-meta": request.meta },
138
+ transformers: [transformer],
139
+ })
140
+ const pre = fragment.children[0]
141
+ parentPort.postMessage({ id: request.id, pre: pre && pre.type === "element" ? pre : undefined })
142
+ } catch (error) {
143
+ parentPort.postMessage({ id: request.id, error: String((error && error.stack) || error) })
144
+ }
145
+ })
146
+ `
147
+
148
+ // addLanguageClass put `language-<name>` on the block's `<code>`
149
+ function readLanguage(pre: Element) {
150
+ const code = pre.children.find(
151
+ (child): child is Element => child.type === "element" && child.tagName === "code",
152
+ )
153
+ const classes = code?.properties.className
154
+ const name = Array.isArray(classes)
155
+ ? classes.find(item => typeof item === "string" && item.startsWith("language-"))
156
+ : undefined
157
+ return typeof name === "string" ? name.slice("language-".length) : "ts"
158
+ }
159
+
160
+ function* walkElements(node: Root | RootContent): Generator<Element> {
161
+ if (node.type === "element") yield node
162
+ if ("children" in node) for (const child of node.children) yield* walkElements(child)
163
+ }
@@ -0,0 +1,7 @@
1
+ /* What an app outside Livemark loads: the shape scale, the Markdown styles, and the
2
+ sources Tailwind must scan, named from here since the app cannot see this package */
3
+ @import "./styles/shape.css";
4
+ @import "./styles/markdown.css";
5
+ @source "./components";
6
+ @source "./elements";
7
+ @source "./helpers";
@@ -0,0 +1,214 @@
1
+ @import "tailwindcss";
2
+ @import "tw-animate-css";
3
+ @import "./shape.css";
4
+ @plugin "@tailwindcss/typography";
5
+
6
+ @custom-variant dark (&:is(.dark *));
7
+ @custom-variant sidebar-collapsed ([data-slot="sidebar"][data-state="collapsed"] ~ [data-slot="sidebar-inset"] &);
8
+
9
+ /* The page content's width on a 100rem (1600px) viewport, where it spans from the header
10
+ nav's first link to the PageToc under the search; it stops growing beyond that */
11
+ [data-slot="sidebar-inset"] {
12
+ --content-max-width: calc(
13
+ 100rem - var(--sidebar-width, 16rem) - var(--toc-width, 14rem) - 13.5rem
14
+ );
15
+ }
16
+ [data-slot="sidebar"][data-state="collapsed"] ~ [data-slot="sidebar-inset"] {
17
+ --content-max-width: calc(100rem - var(--toc-width, 14rem) - 13.5rem);
18
+ }
19
+
20
+ :root {
21
+ --background: oklch(1 0 0);
22
+ --foreground: oklch(0.145 0 0);
23
+ --card: oklch(1 0 0);
24
+ --card-foreground: oklch(0.145 0 0);
25
+ --popover: oklch(1 0 0);
26
+ --popover-foreground: oklch(0.145 0 0);
27
+ --primary: oklch(54.6% 0.245 262.881);
28
+ --primary-foreground: oklch(0.985 0 0);
29
+ --secondary: oklch(54.1% 0.281 293.009);
30
+ --secondary-foreground: oklch(0.985 0 0);
31
+ --banner: oklch(89.4% 0.057 293.283);
32
+ --banner-foreground: oklch(0.205 0 0);
33
+ --muted: oklch(0.985 0 0);
34
+ --muted-foreground: oklch(0.5 0 0);
35
+ --accent: oklch(0.97 0 0);
36
+ --accent-foreground: oklch(0.205 0 0);
37
+ --positive: oklch(0.648 0.2 131.684);
38
+ --positive-foreground: oklch(0.205 0 0);
39
+ --positive-tint: oklch(96.7% 0.067 122.328);
40
+ --positive-tint-foreground: oklch(53.2% 0.157 131.589);
41
+ --warning: oklch(79.5% 0.184 86.047);
42
+ --warning-foreground: oklch(0.205 0 0);
43
+ --warning-tint: oklch(97.3% 0.071 103.193);
44
+ --warning-tint-foreground: oklch(47.6% 0.114 61.907);
45
+ --highlight: oklch(90.5% 0.182 98.111);
46
+ --highlight-foreground: oklch(0.205 0 0);
47
+ --destructive: oklch(0.55 0.2 25);
48
+ --destructive-foreground: oklch(0.985 0 0);
49
+ --destructive-tint: oklch(93.6% 0.032 17.717);
50
+ --destructive-tint-foreground: oklch(50.5% 0.213 27.518);
51
+ --border: oklch(0.922 0 0);
52
+ --input: oklch(0.922 0 0);
53
+ --ring: oklch(0.708 0 0);
54
+ --chart-1: oklch(0.646 0.222 41.116);
55
+ --chart-2: oklch(0.6 0.118 184.704);
56
+ --chart-3: oklch(0.398 0.07 227.392);
57
+ --chart-4: oklch(0.828 0.189 84.429);
58
+ --chart-5: oklch(0.769 0.188 70.08);
59
+ --radius: 0.625rem;
60
+ --sidebar: var(--muted);
61
+ --sidebar-foreground: oklch(0.145 0 0);
62
+ --sidebar-primary: oklch(0.205 0 0);
63
+ --sidebar-primary-foreground: oklch(0.985 0 0);
64
+ --sidebar-accent: oklch(0.97 0 0);
65
+ --sidebar-accent-foreground: oklch(0.205 0 0);
66
+ --sidebar-border: oklch(0.922 0 0);
67
+ --sidebar-ring: oklch(0.708 0 0);
68
+ }
69
+
70
+ .dark {
71
+ --background: oklch(0.145 0 0);
72
+ --foreground: oklch(0.985 0 0);
73
+ --card: oklch(0.145 0 0);
74
+ --card-foreground: oklch(0.985 0 0);
75
+ --popover: oklch(0.145 0 0);
76
+ --popover-foreground: oklch(0.985 0 0);
77
+ --primary: oklch(0.623 0.214 259.815);
78
+ --primary-foreground: oklch(0.985 0 0);
79
+ --secondary: oklch(60.6% 0.25 292.717);
80
+ --secondary-foreground: oklch(0.985 0 0);
81
+ --banner: oklch(0.269 0 0);
82
+ --banner-foreground: oklch(0.985 0 0);
83
+ --muted: oklch(0.205 0 0);
84
+ --muted-foreground: oklch(0.708 0 0);
85
+ --accent: oklch(0.269 0 0);
86
+ --accent-foreground: oklch(0.985 0 0);
87
+ --positive: oklch(0.841 0.238 128.85);
88
+ --positive-foreground: oklch(0.205 0 0);
89
+ --positive-tint: oklch(27.4% 0.072 132.109);
90
+ --positive-tint-foreground: oklch(84.1% 0.238 128.85);
91
+ --warning: oklch(85.2% 0.199 91.936);
92
+ --warning-foreground: oklch(0.22 0.04 70);
93
+ --warning-tint: oklch(28.6% 0.066 53.813);
94
+ --warning-tint-foreground: oklch(85.2% 0.199 91.936);
95
+ --highlight: oklch(55.4% 0.135 66.442);
96
+ --highlight-foreground: oklch(0.985 0 0);
97
+ --destructive: oklch(0.7 0.17 25);
98
+ --destructive-foreground: oklch(0.2 0.03 25);
99
+ --destructive-tint: oklch(25.8% 0.092 26.042);
100
+ --destructive-tint-foreground: oklch(70.4% 0.191 22.216);
101
+ --border: oklch(0.269 0 0);
102
+ --input: oklch(0.269 0 0);
103
+ --ring: oklch(0.439 0 0);
104
+ --chart-1: oklch(0.488 0.243 264.376);
105
+ --chart-2: oklch(0.696 0.17 162.48);
106
+ --chart-3: oklch(0.769 0.188 70.08);
107
+ --chart-4: oklch(0.627 0.265 303.9);
108
+ --chart-5: oklch(0.645 0.246 16.439);
109
+ --sidebar: var(--muted);
110
+ --sidebar-foreground: oklch(0.985 0 0);
111
+ --sidebar-primary: oklch(0.488 0.243 264.376);
112
+ --sidebar-primary-foreground: oklch(0.985 0 0);
113
+ --sidebar-accent: oklch(0.269 0 0);
114
+ --sidebar-accent-foreground: oklch(0.985 0 0);
115
+ --sidebar-border: oklch(0.269 0 0);
116
+ --sidebar-ring: oklch(0.439 0 0);
117
+ }
118
+
119
+ @theme inline {
120
+ --color-background: var(--background);
121
+ --color-foreground: var(--foreground);
122
+ --color-card: var(--card);
123
+ --color-card-foreground: var(--card-foreground);
124
+ --color-popover: var(--popover);
125
+ --color-popover-foreground: var(--popover-foreground);
126
+ --color-primary: var(--primary);
127
+ --color-primary-foreground: var(--primary-foreground);
128
+ --color-secondary: var(--secondary);
129
+ --color-secondary-foreground: var(--secondary-foreground);
130
+ --color-banner: var(--banner);
131
+ --color-banner-foreground: var(--banner-foreground);
132
+ --color-muted: var(--muted);
133
+ --color-muted-foreground: var(--muted-foreground);
134
+ --color-accent: var(--accent);
135
+ --color-accent-foreground: var(--accent-foreground);
136
+ --color-positive: var(--positive);
137
+ --color-positive-foreground: var(--positive-foreground);
138
+ --color-positive-tint: var(--positive-tint);
139
+ --color-positive-tint-foreground: var(--positive-tint-foreground);
140
+ --color-warning: var(--warning);
141
+ --color-warning-foreground: var(--warning-foreground);
142
+ --color-warning-tint: var(--warning-tint);
143
+ --color-warning-tint-foreground: var(--warning-tint-foreground);
144
+ --color-highlight: var(--highlight);
145
+ --color-highlight-foreground: var(--highlight-foreground);
146
+ --color-destructive: var(--destructive);
147
+ --color-destructive-foreground: var(--destructive-foreground);
148
+ --color-destructive-tint: var(--destructive-tint);
149
+ --color-destructive-tint-foreground: var(--destructive-tint-foreground);
150
+ --color-border: var(--border);
151
+ --color-input: var(--input);
152
+ --color-ring: var(--ring);
153
+ --color-chart-1: var(--chart-1);
154
+ --color-chart-2: var(--chart-2);
155
+ --color-chart-3: var(--chart-3);
156
+ --color-chart-4: var(--chart-4);
157
+ --color-chart-5: var(--chart-5);
158
+ --radius-sm: calc(var(--radius) - 4px);
159
+ --radius-md: calc(var(--radius) - 2px);
160
+ --radius-lg: var(--radius);
161
+ --radius-xl: calc(var(--radius) + 4px);
162
+ --color-sidebar: var(--sidebar);
163
+ --color-sidebar-foreground: var(--sidebar-foreground);
164
+ --color-sidebar-primary: var(--sidebar-primary);
165
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
166
+ --color-sidebar-accent: var(--sidebar-accent);
167
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
168
+ --color-sidebar-border: var(--sidebar-border);
169
+ --color-sidebar-ring: var(--sidebar-ring);
170
+ }
171
+
172
+ @layer base {
173
+ * {
174
+ @apply border-border outline-ring/50;
175
+ }
176
+ body {
177
+ @apply bg-background text-foreground;
178
+ }
179
+
180
+ html {
181
+ scroll-behavior: smooth;
182
+ scrollbar-color: #ddd transparent;
183
+ scrollbar-gutter: stable;
184
+ }
185
+
186
+ button:not([disabled]),
187
+ [role="button"]:not([disabled]) {
188
+ cursor: pointer;
189
+ }
190
+
191
+ [data-slot="sidebar-content"] {
192
+ scrollbar-width: thin;
193
+ scrollbar-color: transparent transparent;
194
+ transition: scrollbar-color 0.2s;
195
+ }
196
+ [data-slot="sidebar-content"]:hover,
197
+ [data-slot="sidebar-content"]:focus-within {
198
+ scrollbar-color: color-mix(in oklch, var(--sidebar-foreground) 20%, transparent)
199
+ transparent;
200
+ }
201
+
202
+ [data-slot="sidebar-content"]::-webkit-scrollbar {
203
+ width: 8px;
204
+ }
205
+ [data-slot="sidebar-content"]::-webkit-scrollbar-thumb {
206
+ background: transparent;
207
+ border-radius: 9999px;
208
+ transition: background 0.2s;
209
+ }
210
+ [data-slot="sidebar-content"]:hover::-webkit-scrollbar-thumb,
211
+ [data-slot="sidebar-content"]:focus-within::-webkit-scrollbar-thumb {
212
+ background: color-mix(in oklch, var(--sidebar-foreground) 20%, transparent);
213
+ }
214
+ }