livemark 0.22.0 → 0.24.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 (236) hide show
  1. package/README.md +1 -1
  2. package/build/actions/changelog/build.js +4 -8
  3. package/build/actions/config/load.js +1 -1
  4. package/build/actions/config/load.unit.js +1 -1
  5. package/build/actions/target/build.js +2 -5
  6. package/build/commands/build.js +1 -1
  7. package/build/commands/escape.js +1 -1
  8. package/build/commands/preview.js +1 -1
  9. package/build/commands/start.js +1 -1
  10. package/build/components/Abbr.js +2 -2
  11. package/build/components/Article.js +2 -2
  12. package/build/components/BlogIndex.js +2 -4
  13. package/build/components/Callout.js +1 -1
  14. package/build/components/ChangelogIndex.js +1 -1
  15. package/build/components/CodeBlock.js +3 -5
  16. package/build/components/CodeTabs.js +1 -1
  17. package/build/components/Columns.js +2 -4
  18. package/build/components/Content.js +2 -2
  19. package/build/components/ContentTab.js +1 -1
  20. package/build/components/ContentTabs.js +1 -1
  21. package/build/components/DefinitionList.js +1 -1
  22. package/build/components/FileTree.js +1 -1
  23. package/build/components/FootnoteRef.js +2 -2
  24. package/build/components/InlineToc.js +1 -1
  25. package/build/components/Layout.js +1 -1
  26. package/build/components/LinkButton.js +1 -1
  27. package/build/components/Mermaid.js +1 -1
  28. package/build/components/PackageTabs.js +2 -2
  29. package/build/components/PageToolbar.js +9 -7
  30. package/build/components/PrevNext.js +3 -7
  31. package/build/components/SearchDialog.js +1 -1
  32. package/build/components/SectionHeader.js +1 -1
  33. package/build/components/Sidebar.js +2 -2
  34. package/build/components/SidebarArticles.js +2 -2
  35. package/build/components/SidebarLinks.js +2 -2
  36. package/build/components/TagIndex.js +2 -4
  37. package/build/components/Toc.js +1 -1
  38. package/build/content/article.js +1 -1
  39. package/build/content-collections.js +2 -4
  40. package/build/elements/alert-dialog.js +4 -4
  41. package/build/elements/alert.js +1 -1
  42. package/build/elements/avatar.d.ts +1 -1
  43. package/build/elements/avatar.js +2 -2
  44. package/build/elements/badge.js +1 -1
  45. package/build/elements/breadcrumb.js +1 -1
  46. package/build/elements/button-group.d.ts +1 -1
  47. package/build/elements/button-group.js +2 -2
  48. package/build/elements/calendar.js +4 -4
  49. package/build/elements/carousel.js +1 -1
  50. package/build/elements/chart.js +4 -14
  51. package/build/elements/collapsible.js +3 -3
  52. package/build/elements/command.js +1 -1
  53. package/build/elements/context-menu.js +4 -4
  54. package/build/elements/dialog.js +1 -1
  55. package/build/elements/direction.d.ts +1 -1
  56. package/build/elements/direction.js +2 -2
  57. package/build/elements/drawer.js +1 -1
  58. package/build/elements/dropdown-menu.js +2 -2
  59. package/build/elements/empty.d.ts +1 -1
  60. package/build/elements/empty.js +2 -2
  61. package/build/elements/field.js +1 -1
  62. package/build/elements/hover-card.js +2 -2
  63. package/build/elements/input-group.js +1 -1
  64. package/build/elements/item.js +1 -1
  65. package/build/elements/menubar.js +1 -1
  66. package/build/elements/native-select.js +1 -1
  67. package/build/elements/navigation-menu.js +1 -1
  68. package/build/elements/pagination.js +2 -2
  69. package/build/elements/popover.js +1 -1
  70. package/build/elements/progress.d.ts +1 -1
  71. package/build/elements/progress.js +2 -2
  72. package/build/elements/resizable.js +2 -2
  73. package/build/elements/scroll-area.js +1 -1
  74. package/build/elements/select.js +1 -1
  75. package/build/elements/sheet.js +1 -1
  76. package/build/elements/sidebar.js +2 -3
  77. package/build/elements/table.js +1 -1
  78. package/build/elements/toggle-group.js +1 -1
  79. package/build/elements/tooltip.js +1 -1
  80. package/build/helpers/changelog-source.js +1 -1
  81. package/build/helpers/dynamic-icon-resolver.js +1 -1
  82. package/build/helpers/resolve-asset-path.unit.js +1 -1
  83. package/build/helpers/resolve-base.unit.js +2 -2
  84. package/build/helpers/resolve-includes.js +2 -2
  85. package/build/helpers/resolve-includes.unit.js +1 -1
  86. package/build/helpers/rss.js +2 -4
  87. package/build/helpers/rss.unit.js +1 -1
  88. package/build/helpers/section.js +2 -3
  89. package/build/helpers/section.unit.js +4 -13
  90. package/build/helpers/toc.unit.js +2 -4
  91. package/build/plugins/rehype-inline-code.js +2 -2
  92. package/build/plugins/rehype-task-list-a11y.js +1 -1
  93. package/build/plugins/remark-abbr.js +2 -4
  94. package/build/plugins/remark-ansi.js +2 -4
  95. package/build/plugins/remark-ansi.unit.js +1 -1
  96. package/build/plugins/remark-badge.js +2 -4
  97. package/build/plugins/remark-button.unit.js +1 -1
  98. package/build/plugins/remark-callout.js +1 -1
  99. package/build/plugins/remark-card.js +1 -1
  100. package/build/plugins/remark-code-tabs.js +4 -8
  101. package/build/plugins/remark-columns.js +1 -1
  102. package/build/plugins/remark-custom-heading-id.unit.js +1 -1
  103. package/build/plugins/remark-deflist.js +1 -1
  104. package/build/plugins/remark-details.js +2 -4
  105. package/build/plugins/remark-filetree.js +1 -1
  106. package/build/plugins/remark-filetree.unit.js +1 -1
  107. package/build/plugins/remark-media.js +3 -7
  108. package/build/plugins/remark-media.unit.js +1 -1
  109. package/build/plugins/remark-steps.unit.js +1 -1
  110. package/build/plugins/remark-tab.js +4 -2
  111. package/build/plugins/remark-tab.unit.js +3 -7
  112. package/build/plugins/remark-toc.unit.js +1 -1
  113. package/build/plugins/shiki-icon.js +1 -1
  114. package/build/plugins/shiki-line-highlight.js +1 -1
  115. package/build/plugins/vite-livemark.js +1 -1
  116. package/build/plugins/vite-robots.js +1 -1
  117. package/build/plugins/vite-robots.unit.js +1 -1
  118. package/build/routes/$.js +1 -1
  119. package/build/vite.config.js +3 -8
  120. package/package.json +2 -2
  121. package/skills/authoring/SKILL.md +1 -1
  122. package/skills/configuration/SKILL.md +1 -3
  123. package/source/actions/changelog/build.ts +4 -20
  124. package/source/actions/config/load.ts +1 -3
  125. package/source/actions/config/load.unit.ts +2 -7
  126. package/source/actions/target/build.ts +1 -4
  127. package/source/commands/build.ts +1 -7
  128. package/source/commands/escape.ts +3 -8
  129. package/source/commands/preview.ts +1 -7
  130. package/source/commands/start.ts +1 -7
  131. package/source/components/Abbr.tsx +1 -5
  132. package/source/components/Article.tsx +1 -5
  133. package/source/components/BlogIndex.tsx +3 -9
  134. package/source/components/Callout.tsx +1 -6
  135. package/source/components/ChangelogIndex.tsx +1 -3
  136. package/source/components/CodeBlock.tsx +4 -14
  137. package/source/components/CodeTabs.tsx +1 -3
  138. package/source/components/Columns.tsx +1 -3
  139. package/source/components/Content.tsx +1 -5
  140. package/source/components/ContentTab.tsx +1 -4
  141. package/source/components/ContentTabs.tsx +3 -10
  142. package/source/components/DefinitionList.tsx +1 -4
  143. package/source/components/FileTree.tsx +1 -5
  144. package/source/components/FootnoteRef.tsx +1 -5
  145. package/source/components/InlineToc.tsx +1 -4
  146. package/source/components/Layout.tsx +3 -10
  147. package/source/components/LinkButton.tsx +1 -7
  148. package/source/components/Mermaid.tsx +1 -3
  149. package/source/components/PackageTabs.tsx +1 -5
  150. package/source/components/PageToolbar.tsx +10 -14
  151. package/source/components/PrevNext.tsx +2 -6
  152. package/source/components/SearchDialog.tsx +2 -6
  153. package/source/components/SectionHeader.tsx +1 -7
  154. package/source/components/Sidebar.tsx +2 -7
  155. package/source/components/SidebarArticles.tsx +4 -20
  156. package/source/components/SidebarLinks.tsx +2 -6
  157. package/source/components/TagIndex.tsx +3 -9
  158. package/source/components/Toc.tsx +2 -7
  159. package/source/content/article.ts +1 -2
  160. package/source/content-collections.ts +2 -5
  161. package/source/elements/alert-dialog.tsx +7 -29
  162. package/source/elements/alert.tsx +1 -4
  163. package/source/elements/avatar.tsx +4 -20
  164. package/source/elements/badge.tsx +2 -4
  165. package/source/elements/breadcrumb.tsx +3 -13
  166. package/source/elements/button-group.tsx +1 -6
  167. package/source/elements/calendar.tsx +6 -23
  168. package/source/elements/carousel.tsx +3 -10
  169. package/source/elements/chart.tsx +8 -33
  170. package/source/elements/collapsible.tsx +2 -6
  171. package/source/elements/command.tsx +3 -12
  172. package/source/elements/context-menu.tsx +7 -24
  173. package/source/elements/dialog.tsx +3 -13
  174. package/source/elements/direction.tsx +1 -4
  175. package/source/elements/drawer.tsx +3 -9
  176. package/source/elements/dropdown-menu.tsx +4 -18
  177. package/source/elements/empty.tsx +2 -12
  178. package/source/elements/field.tsx +2 -6
  179. package/source/elements/hover-card.tsx +1 -3
  180. package/source/elements/input-group.tsx +14 -27
  181. package/source/elements/item.tsx +3 -12
  182. package/source/elements/menubar.tsx +4 -13
  183. package/source/elements/native-select.tsx +3 -14
  184. package/source/elements/navigation-menu.tsx +1 -4
  185. package/source/elements/pagination.tsx +3 -13
  186. package/source/elements/popover.tsx +1 -4
  187. package/source/elements/progress.tsx +3 -15
  188. package/source/elements/resizable.tsx +3 -11
  189. package/source/elements/scroll-area.tsx +1 -5
  190. package/source/elements/select.tsx +3 -13
  191. package/source/elements/sheet.tsx +2 -9
  192. package/source/elements/sidebar.tsx +6 -24
  193. package/source/elements/table.tsx +3 -12
  194. package/source/elements/toggle-group.tsx +1 -3
  195. package/source/elements/tooltip.tsx +2 -9
  196. package/source/helpers/changelog-source.ts +1 -3
  197. package/source/helpers/dynamic-icon-resolver.tsx +1 -4
  198. package/source/helpers/resolve-asset-path.unit.ts +6 -12
  199. package/source/helpers/resolve-base.unit.ts +1 -2
  200. package/source/helpers/resolve-includes.ts +2 -8
  201. package/source/helpers/resolve-includes.unit.ts +9 -36
  202. package/source/helpers/rss.ts +3 -9
  203. package/source/helpers/rss.unit.ts +1 -3
  204. package/source/helpers/section.ts +1 -4
  205. package/source/helpers/section.unit.ts +5 -18
  206. package/source/helpers/toc.unit.ts +1 -3
  207. package/source/plugins/rehype-inline-code.ts +5 -21
  208. package/source/plugins/rehype-task-list-a11y.ts +1 -2
  209. package/source/plugins/remark-abbr.ts +1 -3
  210. package/source/plugins/remark-ansi.ts +2 -5
  211. package/source/plugins/remark-ansi.unit.ts +6 -18
  212. package/source/plugins/remark-badge.ts +1 -3
  213. package/source/plugins/remark-button.unit.ts +3 -9
  214. package/source/plugins/remark-callout.ts +35 -40
  215. package/source/plugins/remark-card.ts +25 -29
  216. package/source/plugins/remark-code-tabs.ts +3 -7
  217. package/source/plugins/remark-columns.ts +13 -17
  218. package/source/plugins/remark-custom-heading-id.unit.ts +2 -6
  219. package/source/plugins/remark-deflist.ts +1 -2
  220. package/source/plugins/remark-details.ts +28 -34
  221. package/source/plugins/remark-filetree.ts +28 -34
  222. package/source/plugins/remark-filetree.unit.ts +1 -4
  223. package/source/plugins/remark-media.ts +2 -6
  224. package/source/plugins/remark-media.unit.ts +2 -6
  225. package/source/plugins/remark-steps.unit.ts +2 -7
  226. package/source/plugins/remark-tab.ts +26 -30
  227. package/source/plugins/remark-tab.unit.ts +2 -6
  228. package/source/plugins/remark-toc.unit.ts +1 -3
  229. package/source/plugins/shiki-icon.ts +1 -4
  230. package/source/plugins/shiki-line-highlight.ts +4 -11
  231. package/source/plugins/vite-livemark.ts +3 -10
  232. package/source/plugins/vite-robots.ts +1 -6
  233. package/source/plugins/vite-robots.unit.ts +1 -3
  234. package/source/routes/$.tsx +1 -3
  235. package/source/styles/general.css +1 -5
  236. package/source/vite.config.ts +2 -7
@@ -93,10 +93,7 @@ function SidebarProvider({
93
93
  // Adds a keyboard shortcut to toggle the sidebar.
94
94
  React.useEffect(() => {
95
95
  const handleKeyDown = (event: KeyboardEvent) => {
96
- if (
97
- event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
98
- (event.metaKey || event.ctrlKey)
99
- ) {
96
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
100
97
  event.preventDefault()
101
98
  toggleSidebar()
102
99
  }
@@ -312,10 +309,7 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
312
309
  )
313
310
  }
314
311
 
315
- function SidebarInput({
316
- className,
317
- ...props
318
- }: React.ComponentProps<typeof Input>) {
312
+ function SidebarInput({ className, ...props }: React.ComponentProps<typeof Input>) {
319
313
  return (
320
314
  <Input
321
315
  data-slot="sidebar-input"
@@ -435,10 +429,7 @@ function SidebarGroupAction({
435
429
  })
436
430
  }
437
431
 
438
- function SidebarGroupContent({
439
- className,
440
- ...props
441
- }: React.ComponentProps<"div">) {
432
+ function SidebarGroupContent({ className, ...props }: React.ComponentProps<"div">) {
442
433
  return (
443
434
  <div
444
435
  data-slot="sidebar-group-content"
@@ -577,10 +568,7 @@ function SidebarMenuAction({
577
568
  })
578
569
  }
579
570
 
580
- function SidebarMenuBadge({
581
- className,
582
- ...props
583
- }: React.ComponentProps<"div">) {
571
+ function SidebarMenuBadge({ className, ...props }: React.ComponentProps<"div">) {
584
572
  return (
585
573
  <div
586
574
  data-slot="sidebar-menu-badge"
@@ -614,10 +602,7 @@ function SidebarMenuSkeleton({
614
602
  {...props}
615
603
  >
616
604
  {showIcon && (
617
- <Skeleton
618
- className="size-4 rounded-md"
619
- data-sidebar="menu-skeleton-icon"
620
- />
605
+ <Skeleton className="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />
621
606
  )}
622
607
  <Skeleton
623
608
  className="h-4 max-w-(--skeleton-width) flex-1"
@@ -646,10 +631,7 @@ function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
646
631
  )
647
632
  }
648
633
 
649
- function SidebarMenuSubItem({
650
- className,
651
- ...props
652
- }: React.ComponentProps<"li">) {
634
+ function SidebarMenuSubItem({ className, ...props }: React.ComponentProps<"li">) {
653
635
  return (
654
636
  <li
655
637
  data-slot="sidebar-menu-sub-item"
@@ -2,10 +2,7 @@ import { cn } from "../utils/style.ts"
2
2
 
3
3
  function Table({ className, ...props }: React.ComponentProps<"table">) {
4
4
  return (
5
- <div
6
- data-slot="table-container"
7
- className="relative w-full overflow-x-auto"
8
- >
5
+ <div data-slot="table-container" className="relative w-full overflow-x-auto">
9
6
  <table
10
7
  data-slot="table"
11
8
  className={cn("w-full caption-bottom text-sm", className)}
@@ -39,10 +36,7 @@ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
39
36
  return (
40
37
  <tfoot
41
38
  data-slot="table-footer"
42
- className={cn(
43
- "bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
44
- className,
45
- )}
39
+ className={cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className)}
46
40
  {...props}
47
41
  />
48
42
  )
@@ -87,10 +81,7 @@ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
87
81
  )
88
82
  }
89
83
 
90
- function TableCaption({
91
- className,
92
- ...props
93
- }: React.ComponentProps<"caption">) {
84
+ function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
94
85
  return (
95
86
  <caption
96
87
  data-slot="table-caption"
@@ -45,9 +45,7 @@ function ToggleGroup({
45
45
  )}
46
46
  {...props}
47
47
  >
48
- <ToggleGroupContext.Provider
49
- value={{ variant, size, spacing, orientation }}
50
- >
48
+ <ToggleGroupContext.Provider value={{ variant, size, spacing, orientation }}>
51
49
  {children}
52
50
  </ToggleGroupContext.Provider>
53
51
  </ToggleGroupPrimitive>
@@ -1,16 +1,9 @@
1
1
  import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip"
2
2
  import { cn } from "../utils/style.ts"
3
3
 
4
- function TooltipProvider({
5
- delay = 0,
6
- ...props
7
- }: TooltipPrimitive.Provider.Props) {
4
+ function TooltipProvider({ delay = 0, ...props }: TooltipPrimitive.Provider.Props) {
8
5
  return (
9
- <TooltipPrimitive.Provider
10
- data-slot="tooltip-provider"
11
- delay={delay}
12
- {...props}
13
- />
6
+ <TooltipPrimitive.Provider data-slot="tooltip-provider" delay={delay} {...props} />
14
7
  )
15
8
  }
16
9
 
@@ -5,9 +5,7 @@ export function isGitHubUrl(source: string) {
5
5
 
6
6
  /** Extract `{ owner, repo }` from a GitHub URL. Returns undefined if unparseable */
7
7
  export function parseGitHubRepo(source: string) {
8
- const match = source.match(
9
- /^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/]+)\/([^/#?]+)/,
10
- )
8
+ const match = source.match(/^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/]+)\/([^/#?]+)/)
11
9
  if (!match) return undefined
12
10
  const owner = match[1]
13
11
  const repo = match[2]?.replace(/\.git$/, "")
@@ -8,10 +8,7 @@ function toPascalCase(name: string) {
8
8
  }
9
9
 
10
10
  /** Resolves a Lucide icon by kebab-case name from the full registry */
11
- export default function DynamicIconResolver(props: {
12
- name: string
13
- className?: string
14
- }) {
11
+ export default function DynamicIconResolver(props: { name: string; className?: string }) {
15
12
  const key = toPascalCase(props.name)
16
13
  if (!(key in icons)) return null
17
14
  const Icon = icons[key as keyof typeof icons]
@@ -6,15 +6,11 @@ describe("resolveAssetPath", () => {
6
6
  const filePath = "/site/docs/page.md"
7
7
 
8
8
  it("should resolve a sibling relative path", () => {
9
- expect(resolveAssetPath("./logo.png", filePath, root)).toBe(
10
- "/docs/logo.png",
11
- )
9
+ expect(resolveAssetPath("./logo.png", filePath, root)).toBe("/docs/logo.png")
12
10
  })
13
11
 
14
12
  it("should resolve a parent relative path", () => {
15
- expect(resolveAssetPath("../assets/x.png", filePath, root)).toBe(
16
- "/assets/x.png",
17
- )
13
+ expect(resolveAssetPath("../assets/x.png", filePath, root)).toBe("/assets/x.png")
18
14
  })
19
15
 
20
16
  it("should pass through a root-relative url", () => {
@@ -40,9 +36,7 @@ describe("resolveAssetPath", () => {
40
36
  })
41
37
 
42
38
  it("should prefix a root-relative url with base", () => {
43
- expect(resolveAssetPath("/foo.png", filePath, root, "/repo")).toBe(
44
- "/repo/foo.png",
45
- )
39
+ expect(resolveAssetPath("/foo.png", filePath, root, "/repo")).toBe("/repo/foo.png")
46
40
  })
47
41
 
48
42
  it("should not double-prefix an already-prefixed url", () => {
@@ -52,8 +46,8 @@ describe("resolveAssetPath", () => {
52
46
  })
53
47
 
54
48
  it("should not prefix external urls when base is set", () => {
55
- expect(
56
- resolveAssetPath("https://x.com/y.png", filePath, root, "/repo"),
57
- ).toBe("https://x.com/y.png")
49
+ expect(resolveAssetPath("https://x.com/y.png", filePath, root, "/repo")).toBe(
50
+ "https://x.com/y.png",
51
+ )
58
52
  })
59
53
  })
@@ -43,8 +43,7 @@ describe("resolveBase", () => {
43
43
  })
44
44
 
45
45
  it("should handle a function returning undefined", () => {
46
- const fn = (cmd: "build" | "serve") =>
47
- cmd === "serve" ? undefined : "prod"
46
+ const fn = (cmd: "build" | "serve") => (cmd === "serve" ? undefined : "prod")
48
47
  expect(resolveBase(fn, "serve")).toBeUndefined()
49
48
  expect(resolveBase(fn, "build")).toBe("/prod")
50
49
  })
@@ -76,9 +76,7 @@ function resolveDirective(
76
76
  const filename = file.split("/").pop()!
77
77
  const title = `title="${filename}"`
78
78
  const meta = attrs.meta ? ` ${attrs.meta}` : ""
79
- return (
80
- "```" + lang + " " + title + meta + "\n" + included.trimEnd() + "\n```"
81
- )
79
+ return "```" + lang + " " + title + meta + "\n" + included.trimEnd() + "\n```"
82
80
  }
83
81
 
84
82
  included = included.replace(FRONTMATTER_RE, "")
@@ -89,11 +87,7 @@ function resolveDirective(
89
87
  }
90
88
 
91
89
  /** Resolves ::include{file="..."} directives by replacing them with referenced file contents */
92
- export function resolveIncludes(
93
- content: string,
94
- filePath: string,
95
- depth = 0,
96
- ): string {
90
+ export function resolveIncludes(content: string, filePath: string, depth = 0): string {
97
91
  if (depth > 5) return content
98
92
 
99
93
  const fileDir = dirname(filePath)
@@ -8,23 +8,14 @@ describe("resolveIncludes", () => {
8
8
  it("should replace include directive with file content", () => {
9
9
  const dir = temporaryDirectory()
10
10
  writeFileSync(join(dir, "snippet.md"), "Hello from snippet")
11
- const result = resolveIncludes(
12
- '::include{file="snippet.md"}',
13
- join(dir, "main.md"),
14
- )
11
+ const result = resolveIncludes('::include{file="snippet.md"}', join(dir, "main.md"))
15
12
  expect(result).toBe("Hello from snippet")
16
13
  })
17
14
 
18
15
  it("should strip frontmatter from included files", () => {
19
16
  const dir = temporaryDirectory()
20
- writeFileSync(
21
- join(dir, "snippet.md"),
22
- "---\ntitle: Test\n---\nContent here",
23
- )
24
- const result = resolveIncludes(
25
- '::include{file="snippet.md"}',
26
- join(dir, "main.md"),
27
- )
17
+ writeFileSync(join(dir, "snippet.md"), "---\ntitle: Test\n---\nContent here")
18
+ const result = resolveIncludes('::include{file="snippet.md"}', join(dir, "main.md"))
28
19
  expect(result).toBe("Content here")
29
20
  })
30
21
 
@@ -39,10 +30,7 @@ describe("resolveIncludes", () => {
39
30
  })
40
31
 
41
32
  it("should keep directive when file is missing", () => {
42
- const result = resolveIncludes(
43
- '::include{file="nonexistent.md"}',
44
- "/tmp/main.md",
45
- )
33
+ const result = resolveIncludes('::include{file="nonexistent.md"}', "/tmp/main.md")
46
34
  expect(result).toBe('::include{file="nonexistent.md"}')
47
35
  })
48
36
 
@@ -50,20 +38,14 @@ describe("resolveIncludes", () => {
50
38
  const dir = temporaryDirectory()
51
39
  writeFileSync(join(dir, "inner.md"), "Inner content")
52
40
  writeFileSync(join(dir, "outer.md"), '::include{file="inner.md"}')
53
- const result = resolveIncludes(
54
- '::include{file="outer.md"}',
55
- join(dir, "main.md"),
56
- )
41
+ const result = resolveIncludes('::include{file="outer.md"}', join(dir, "main.md"))
57
42
  expect(result).toBe("Inner content")
58
43
  })
59
44
 
60
45
  it("should limit recursion depth", () => {
61
46
  const dir = temporaryDirectory()
62
47
  writeFileSync(join(dir, "recursive.md"), '::include{file="recursive.md"}')
63
- const result = resolveIncludes(
64
- '::include{file="recursive.md"}',
65
- join(dir, "main.md"),
66
- )
48
+ const result = resolveIncludes('::include{file="recursive.md"}', join(dir, "main.md"))
67
49
  expect(result).toBe('::include{file="recursive.md"}')
68
50
  })
69
51
 
@@ -72,10 +54,7 @@ describe("resolveIncludes", () => {
72
54
  mkdirSync(join(dir, "sub"))
73
55
  writeFileSync(join(dir, "sub", "child.md"), "Child content")
74
56
  writeFileSync(join(dir, "parent.md"), '::include{file="sub/child.md"}')
75
- const result = resolveIncludes(
76
- '::include{file="parent.md"}',
77
- join(dir, "main.md"),
78
- )
57
+ const result = resolveIncludes('::include{file="parent.md"}', join(dir, "main.md"))
79
58
  expect(result).toBe("Child content")
80
59
  })
81
60
 
@@ -93,10 +72,7 @@ describe("resolveIncludes", () => {
93
72
  it("should wrap code files in fenced blocks", () => {
94
73
  const dir = temporaryDirectory()
95
74
  writeFileSync(join(dir, "example.ts"), 'const x = 1\nconst y = "hello"')
96
- const result = resolveIncludes(
97
- '::include{file="example.ts"}',
98
- join(dir, "main.md"),
99
- )
75
+ const result = resolveIncludes('::include{file="example.ts"}', join(dir, "main.md"))
100
76
  expect(result).toBe(
101
77
  '```typescript title="example.ts"\nconst x = 1\nconst y = "hello"\n```',
102
78
  )
@@ -117,10 +93,7 @@ describe("resolveIncludes", () => {
117
93
  it("should treat unknown extensions as markdown", () => {
118
94
  const dir = temporaryDirectory()
119
95
  writeFileSync(join(dir, "notes.txt"), "Plain text")
120
- const result = resolveIncludes(
121
- '::include{file="notes.txt"}',
122
- join(dir, "main.md"),
123
- )
96
+ const result = resolveIncludes('::include{file="notes.txt"}', join(dir, "main.md"))
124
97
  expect(result).toBe("Plain text")
125
98
  })
126
99
  })
@@ -37,19 +37,13 @@ export function renderRssFeed(feed: RssFeed) {
37
37
  lines.push(` <link>${escapeXml(item.link)}</link>`)
38
38
  lines.push(` <guid isPermaLink="true">${escapeXml(item.guid)}</guid>`)
39
39
  if (item.description) {
40
- lines.push(
41
- ` <description>${escapeXml(item.description)}</description>`,
42
- )
40
+ lines.push(` <description>${escapeXml(item.description)}</description>`)
43
41
  }
44
42
  if (item.pubDate) {
45
- lines.push(
46
- ` <pubDate>${escapeXml(toRfc822(item.pubDate))}</pubDate>`,
47
- )
43
+ lines.push(` <pubDate>${escapeXml(toRfc822(item.pubDate))}</pubDate>`)
48
44
  }
49
45
  if (item.author) {
50
- const author = Array.isArray(item.author)
51
- ? item.author.join(", ")
52
- : item.author
46
+ const author = Array.isArray(item.author) ? item.author.join(", ") : item.author
53
47
  lines.push(` <author>${escapeXml(author)}</author>`)
54
48
  }
55
49
  if (item.categories) {
@@ -106,9 +106,7 @@ describe("renderRssFeed", () => {
106
106
  },
107
107
  ],
108
108
  })
109
- expect(xml).toContain(
110
- "<title>Title &amp; &quot;quoted&quot; &lt;tag&gt;</title>",
111
- )
109
+ expect(xml).toContain("<title>Title &amp; &quot;quoted&quot; &lt;tag&gt;</title>")
112
110
  expect(xml).toContain("<description>A &amp; B</description>")
113
111
  expect(xml).toContain("<title>1 &lt; 2 &amp; 3 &gt; 0</title>")
114
112
  expect(xml).toContain("<description>It&apos;s fine</description>")
@@ -63,10 +63,7 @@ export function matchSection<S extends { prefix: string }>(
63
63
  let best: S | undefined
64
64
  let bestLen = 0
65
65
  for (const section of sections) {
66
- if (
67
- articlePath.startsWith(section.prefix) &&
68
- section.prefix.length > bestLen
69
- ) {
66
+ if (articlePath.startsWith(section.prefix) && section.prefix.length > bestLen) {
70
67
  best = section
71
68
  bestLen = section.prefix.length
72
69
  }
@@ -53,14 +53,8 @@ describe("partitionBySection", () => {
53
53
 
54
54
  it("should split articles into section buckets", () => {
55
55
  const result = partitionBySection(articles, sections)
56
- expect(result.get("/")?.map(a => a.path)).toEqual([
57
- "/getting-started/",
58
- "/guide/",
59
- ])
60
- expect(result.get("/api/")?.map(a => a.path)).toEqual([
61
- "/api/users/",
62
- "/api/auth/",
63
- ])
56
+ expect(result.get("/")?.map(a => a.path)).toEqual(["/getting-started/", "/guide/"])
57
+ expect(result.get("/api/")?.map(a => a.path)).toEqual(["/api/users/", "/api/auth/"])
64
58
  })
65
59
 
66
60
  it("should put unmatched articles in __default__ bucket", () => {
@@ -70,10 +64,7 @@ describe("partitionBySection", () => {
70
64
  "/getting-started/",
71
65
  "/guide/",
72
66
  ])
73
- expect(result.get("/api/")?.map(a => a.path)).toEqual([
74
- "/api/users/",
75
- "/api/auth/",
76
- ])
67
+ expect(result.get("/api/")?.map(a => a.path)).toEqual(["/api/users/", "/api/auth/"])
77
68
  })
78
69
  })
79
70
 
@@ -152,16 +143,12 @@ describe("activeSiteSection", () => {
152
143
  })
153
144
 
154
145
  it("should return the custom section matching by internal url", () => {
155
- expect(activeSiteSection("/api/v2/users/", [docs, apiCustom])?.title).toBe(
156
- "API",
157
- )
146
+ expect(activeSiteSection("/api/v2/users/", [docs, apiCustom])?.title).toBe("API")
158
147
  })
159
148
 
160
149
  it("should pick the longest match among overlapping prefixes", () => {
161
150
  expect(activeSiteSection("/blog/post/", [docs, blog])?.title).toBe("Blog")
162
- expect(activeSiteSection("/api/v2/foo/", [docs, apiCustom])?.title).toBe(
163
- "API",
164
- )
151
+ expect(activeSiteSection("/api/v2/foo/", [docs, apiCustom])?.title).toBe("API")
165
152
  })
166
153
 
167
154
  it("should ignore custom sections with absolute URLs", () => {
@@ -35,9 +35,7 @@ describe("extractToc", () => {
35
35
  it("should handle code formatting with custom ids", () => {
36
36
  const content = "## `config` Options [#config-opts]"
37
37
  const toc = extractToc(content)
38
- expect(toc).toEqual([
39
- { url: "#config-opts", title: "config Options", depth: 2 },
40
- ])
38
+ expect(toc).toEqual([{ url: "#config-opts", title: "config Options", depth: 2 }])
41
39
  })
42
40
 
43
41
  it("should skip h1 headings", () => {
@@ -1,23 +1,13 @@
1
1
  import type { Plugin } from "unified"
2
2
  import { visit } from "unist-util-visit"
3
- import {
4
- type BundledLanguage,
5
- bundledLanguages,
6
- getSingletonHighlighter,
7
- } from "shiki"
3
+ import { type BundledLanguage, bundledLanguages, getSingletonHighlighter } from "shiki"
8
4
 
9
5
  interface HastText {
10
6
  type: "text"
11
7
  value: string
12
8
  }
13
9
 
14
- type PropertyValue =
15
- | boolean
16
- | number
17
- | string
18
- | null
19
- | undefined
20
- | Array<string | number>
10
+ type PropertyValue = boolean | number | string | null | undefined | Array<string | number>
21
11
 
22
12
  interface HastElement {
23
13
  type: "element"
@@ -56,15 +46,10 @@ export const rehypeInlineCode: Plugin<[], HastRoot> = () => {
56
46
  visit(
57
47
  tree,
58
48
  "element",
59
- (
60
- node: HastNode,
61
- _index: number | undefined,
62
- parent: HastNode | undefined,
63
- ) => {
49
+ (node: HastNode, _index: number | undefined, parent: HastNode | undefined) => {
64
50
  if (node.type !== "element") return
65
51
  if (node.tagName !== "code") return
66
- if (parent && parent.type === "element" && parent.tagName === "pre")
67
- return
52
+ if (parent && parent.type === "element" && parent.tagName === "pre") return
68
53
 
69
54
  const textChild = node.children[0]
70
55
  if (!textChild || textChild.type !== "text") return
@@ -92,8 +77,7 @@ export const rehypeInlineCode: Plugin<[], HastRoot> = () => {
92
77
  const codeEl = pre.children[0]
93
78
  if (codeEl && codeEl.type === "element" && "children" in codeEl) {
94
79
  node.children = codeEl.children.filter(
95
- (c): c is HastElement | HastText =>
96
- c.type === "element" || c.type === "text",
80
+ (c): c is HastElement | HastText => c.type === "element" || c.type === "text",
97
81
  )
98
82
  node.properties = {
99
83
  ...node.properties,
@@ -14,8 +14,7 @@ export function rehypeTaskListA11y() {
14
14
  visit(tree, "element", (node: HastNode) => {
15
15
  if (node.tagName !== "li") return
16
16
  const classes = node.properties?.className
17
- const hasTaskClass =
18
- Array.isArray(classes) && classes.includes("task-list-item")
17
+ const hasTaskClass = Array.isArray(classes) && classes.includes("task-list-item")
19
18
  if (!hasTaskClass) return
20
19
 
21
20
  for (const child of node.children ?? []) {
@@ -8,9 +8,7 @@ export function transformAbbrDirectives(tree: Root) {
8
8
  visit(tree, "textDirective", (node: TextDirective, index, parent) => {
9
9
  if (node.name !== "abbr" || index === undefined || !parent) return
10
10
 
11
- const text = node.children
12
- .map(c => ("value" in c ? String(c.value) : ""))
13
- .join("")
11
+ const text = node.children.map(c => ("value" in c ? String(c.value) : "")).join("")
14
12
 
15
13
  const title = node.attributes?.title ?? ""
16
14
 
@@ -41,8 +41,7 @@ function color256(n: number): string | undefined {
41
41
  const r = Math.floor(idx / 36)
42
42
  const g = Math.floor((idx % 36) / 6)
43
43
  const b = idx % 6
44
- const toHex = (v: number) =>
45
- (v === 0 ? 0 : 55 + v * 40).toString(16).padStart(2, "0")
44
+ const toHex = (v: number) => (v === 0 ? 0 : 55 + v * 40).toString(16).padStart(2, "0")
46
45
  return `#${toHex(r)}${toHex(g)}${toHex(b)}`
47
46
  }
48
47
  if (n < 256) {
@@ -192,9 +191,7 @@ export function ansiToHtml(input: string): string {
192
191
 
193
192
  const rawParams = match[1]!
194
193
  const params =
195
- rawParams === ""
196
- ? [0]
197
- : rawParams.split(";").map(s => Number.parseInt(s, 10))
194
+ rawParams === "" ? [0] : rawParams.split(";").map(s => Number.parseInt(s, 10))
198
195
  applyParams(state, params)
199
196
  lastIndex = match.index + match[0].length
200
197
  match = sgr.exec(input)
@@ -17,9 +17,7 @@ describe("ansiToHtml", () => {
17
17
 
18
18
  it("should render standard foreground colors", () => {
19
19
  const input = "\x1b[31mred text\x1b[0m"
20
- expect(ansiToHtml(input)).toBe(
21
- '<span style="color:#bf616a">red text</span>',
22
- )
20
+ expect(ansiToHtml(input)).toBe('<span style="color:#bf616a">red text</span>')
23
21
  })
24
22
 
25
23
  it("should render bold text", () => {
@@ -29,9 +27,7 @@ describe("ansiToHtml", () => {
29
27
 
30
28
  it("should render italic text", () => {
31
29
  const input = "\x1b[3mitalic\x1b[0m"
32
- expect(ansiToHtml(input)).toBe(
33
- '<span style="font-style:italic">italic</span>',
34
- )
30
+ expect(ansiToHtml(input)).toBe('<span style="font-style:italic">italic</span>')
35
31
  })
36
32
 
37
33
  it("should render underline text", () => {
@@ -69,9 +65,7 @@ describe("ansiToHtml", () => {
69
65
 
70
66
  it("should handle bright foreground colors", () => {
71
67
  const input = "\x1b[91mbright red\x1b[0m"
72
- expect(ansiToHtml(input)).toBe(
73
- '<span style="color:#bf616a">bright red</span>',
74
- )
68
+ expect(ansiToHtml(input)).toBe('<span style="color:#bf616a">bright red</span>')
75
69
  })
76
70
 
77
71
  it("should handle bright background colors", () => {
@@ -88,9 +82,7 @@ describe("ansiToHtml", () => {
88
82
 
89
83
  it("should handle 256-color background", () => {
90
84
  const input = "\x1b[48;5;21mbg\x1b[0m"
91
- expect(ansiToHtml(input)).toBe(
92
- '<span style="background-color:#0000ff">bg</span>',
93
- )
85
+ expect(ansiToHtml(input)).toBe('<span style="background-color:#0000ff">bg</span>')
94
86
  })
95
87
 
96
88
  it("should handle 24-bit RGB foreground", () => {
@@ -100,16 +92,12 @@ describe("ansiToHtml", () => {
100
92
 
101
93
  it("should handle 24-bit RGB background", () => {
102
94
  const input = "\x1b[48;2;0;128;255mbg\x1b[0m"
103
- expect(ansiToHtml(input)).toBe(
104
- '<span style="background-color:#0080ff">bg</span>',
105
- )
95
+ expect(ansiToHtml(input)).toBe('<span style="background-color:#0080ff">bg</span>')
106
96
  })
107
97
 
108
98
  it("should handle reset via empty escape", () => {
109
99
  const input = "\x1b[31mred\x1b[mnormal"
110
- expect(ansiToHtml(input)).toBe(
111
- '<span style="color:#bf616a">red</span>normal',
112
- )
100
+ expect(ansiToHtml(input)).toBe('<span style="color:#bf616a">red</span>normal')
113
101
  })
114
102
 
115
103
  it("should handle multiple segments", () => {
@@ -8,9 +8,7 @@ export function transformBadgeDirectives(tree: Root) {
8
8
  visit(tree, "textDirective", (node: TextDirective, index, parent) => {
9
9
  if (node.name !== "badge" || index === undefined || !parent) return
10
10
 
11
- const label = node.children
12
- .map(c => ("value" in c ? String(c.value) : ""))
13
- .join("")
11
+ const label = node.children.map(c => ("value" in c ? String(c.value) : "")).join("")
14
12
 
15
13
  const variant = node.attributes?.variant
16
14
 
@@ -47,9 +47,7 @@ describe("transformButtonDirectives", () => {
47
47
 
48
48
  it("should convert ::button with label attribute to LinkButton JSX element", () => {
49
49
  const tree = process(
50
- makeTree(
51
- makeLeafDirective("button", { href: "/docs", label: "Read Docs" }),
52
- ),
50
+ makeTree(makeLeafDirective("button", { href: "/docs", label: "Read Docs" })),
53
51
  )
54
52
  const node = tree.children[0]
55
53
  expect(node).toMatchObject({
@@ -122,17 +120,13 @@ describe("transformButtonDirectives", () => {
122
120
  })
123
121
 
124
122
  it("should skip button directive without href", () => {
125
- const tree = process(
126
- makeTree(makeLeafDirective("button", { label: "No Link" })),
127
- )
123
+ const tree = process(makeTree(makeLeafDirective("button", { label: "No Link" })))
128
124
  const node = tree.children[0]
129
125
  expect(node).toMatchObject({ type: "leafDirective", name: "button" })
130
126
  })
131
127
 
132
128
  it("should skip button directive without label or bracket text", () => {
133
- const tree = process(
134
- makeTree(makeLeafDirective("button", { href: "/no-label" })),
135
- )
129
+ const tree = process(makeTree(makeLeafDirective("button", { href: "/no-label" })))
136
130
  const node = tree.children[0]
137
131
  expect(node).toMatchObject({ type: "leafDirective", name: "button" })
138
132
  })