lildocs 0.1.21 → 0.1.22

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.
@@ -850,7 +850,7 @@ html.mermaidFullscreenOpen {
850
850
  opacity: 1;
851
851
  }
852
852
 
853
- .toc a {
853
+ .tocLinks a {
854
854
  display: block;
855
855
  overflow: hidden;
856
856
  color: var(--ld-color-muted-text);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lildocs",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "description": "A lightweight CLI that turns Markdown docs into a static searchable documentation site.",
5
5
  "homepage": "https://aleclarson.github.io/lildocs/",
6
6
  "repository": {
@@ -15,16 +15,22 @@
15
15
  ],
16
16
  "type": "module",
17
17
  "scripts": {
18
- "build": "tsdown",
18
+ "build": "tsdown && node scripts/build-renderers.mjs",
19
19
  "docs:serve": "pnpm run build && node dist/cli.mjs build ./docs --out ./dist/docs && sirv ./dist/docs",
20
- "format": "prettier --write src schemas package.json tsconfig.json tsdown.config.ts vitest.config.ts .oxlintrc.json .prettierrc.json .vscode/settings.json",
21
- "format:check": "prettier --check src schemas package.json tsconfig.json tsdown.config.ts vitest.config.ts .oxlintrc.json .prettierrc.json .vscode/settings.json",
22
- "lint": "oxlint src tsdown.config.ts vitest.config.ts",
20
+ "format": "prettier --write src scripts schemas package.json tsconfig.json tsdown.config.ts vitest.config.ts .oxlintrc.json .prettierrc.json .vscode/settings.json",
21
+ "format:check": "prettier --check src scripts schemas package.json tsconfig.json tsdown.config.ts vitest.config.ts .oxlintrc.json .prettierrc.json .vscode/settings.json",
22
+ "lint": "oxlint src scripts tsdown.config.ts vitest.config.ts",
23
23
  "test": "pnpm run build && vitest run",
24
24
  "typecheck": "tsc --noEmit"
25
25
  },
26
26
  "dependencies": {
27
27
  "beautiful-mermaid": "^1.1.3",
28
+ "shiki": "^4.0.2"
29
+ },
30
+ "devDependencies": {
31
+ "@tsrx/prettier-plugin": "^0.3.93",
32
+ "@types/culori": "^4.0.1",
33
+ "@types/node": "^24.0.0",
28
34
  "cmd-ts": "^0.15.0",
29
35
  "culori": "^4.0.2",
30
36
  "entities": "^8.0.0",
@@ -33,19 +39,10 @@
33
39
  "marked": "^18.0.3",
34
40
  "marked-shiki": "^1.2.1",
35
41
  "octane": "^0.1.3",
36
- "shiki": "^4.0.2",
37
- "swup": "^4.9.0"
38
- },
39
- "peerDependencies": {
40
- "vite": "^8.0.0"
41
- },
42
- "devDependencies": {
43
- "@tsrx/prettier-plugin": "^0.3.93",
44
- "@types/culori": "^4.0.1",
45
- "@types/node": "^24.0.0",
46
42
  "oxlint": "^1.65.0",
47
43
  "prettier": "^3.9.5",
48
44
  "sirv": "^3.0.2",
45
+ "swup": "^4.9.0",
49
46
  "tsdown": "^0.22.0",
50
47
  "typescript": "^5.9.0",
51
48
  "vite": "^8.0.0",
@@ -1,380 +0,0 @@
1
- import type { Heading, Page } from "../core/content.js";
2
- import type { ResolvedLogo } from "../core/logo.js";
3
- import type { NavItem } from "../core/nav.js";
4
- import type { NavigationOptions } from "../core/theme.js";
5
- import { relativeUrl, rootRelativeUrl } from "./paths.js";
6
- import type { PageNavigation } from "./types.js";
7
-
8
- export type LayoutProps = {
9
- page: Page;
10
- nav: NavItem[];
11
- pageNavigation?: PageNavigation;
12
- css: string;
13
- searchIndexJson: string;
14
- logo: ResolvedLogo;
15
- favicon?: string;
16
- repositoryUrl?: string;
17
- projectName?: string;
18
- navigation?: NavigationOptions;
19
- clientScriptPath: string;
20
- clientStylePaths: string[];
21
- };
22
-
23
- export function Layout({
24
- page,
25
- nav,
26
- pageNavigation,
27
- searchIndexJson,
28
- logo,
29
- favicon,
30
- repositoryUrl,
31
- projectName,
32
- navigation,
33
- clientScriptPath,
34
- clientStylePaths,
35
- }: LayoutProps) @{
36
- const transition = navigation?.transition ?? "fade";
37
- const issueUrl = issueUrlForRepository(repositoryUrl);
38
- const repositoryLabel = repositoryLabelForUrl(repositoryUrl);
39
-
40
- <>
41
- <meta charSet="utf-8" />
42
- <meta name="viewport" content="width=device-width, initial-scale=1" />
43
- <title>
44
- {(projectName ? `${page.title} • ${projectName}` : page.title) as string}
45
- </title>
46
- @if (favicon) {
47
- <link rel="icon" href={assetSrc(page.route, favicon)} />
48
- }
49
- <link
50
- rel="stylesheet"
51
- href={rootRelativeUrl(page.route, "assets/tabler-icons.css")}
52
- />
53
- <link
54
- rel="stylesheet"
55
- href={rootRelativeUrl(page.route, "assets/lildocs.css")}
56
- />
57
- @for (const stylePath of clientStylePaths; key stylePath) {
58
- <link rel="stylesheet" href={assetSrc(page.route, stylePath)} />
59
- }
60
- <div class="pageShell">
61
- <aside id="lildocs-sidebar" class="sidebar">
62
- <div class="sidebarContents">
63
- <div class="sidebarHeader">
64
- <a class="brand" href={relativeUrl(page.route, "index.html")}>
65
- @if (logo.image) {
66
- <img
67
- class="brandLogo"
68
- src={assetSrc(page.route, logo.image)}
69
- alt=""
70
- />
71
- }
72
- @if (logo.text) {
73
- <span>
74
- {logo.text as string}
75
- </span>
76
- }
77
- </a>
78
- <button
79
- id="lildocs-sidebar-toggle"
80
- class="sidebarToggle"
81
- type="button"
82
- aria-label="Collapse sidebar"
83
- aria-controls="lildocs-sidebar"
84
- aria-expanded="false"
85
- >
86
- <span
87
- class="sidebarCollapseIcon ti ti-layout-sidebar-left-collapse"
88
- aria-hidden="true"
89
- />
90
- <span class="sidebarMenuIcon ti ti-menu-2" aria-hidden="true" />
91
- </button>
92
- </div>
93
- <div id="lildocs-search-root" class="searchBox">
94
- <span class="searchIcon ti ti-search" aria-hidden="true" />
95
- <input
96
- id="lildocs-search-input"
97
- type="search"
98
- placeholder="Search docs"
99
- aria-label="Search docs"
100
- />
101
- </div>
102
- <nav
103
- id="lildocs-sidebar-navigation"
104
- aria-label="Documentation navigation"
105
- >
106
- <NavList
107
- items={nav}
108
- currentRoute={page.route}
109
- pageRoute={page.route}
110
- />
111
- </nav>
112
- @if (repositoryUrl && repositoryLabel) {
113
- <a
114
- class="sidebarRepoLink"
115
- href={repositoryUrl}
116
- aria-label="View repository on GitHub"
117
- >
118
- <span class="repoIcon" aria-hidden="true" />
119
- <span>
120
- {repositoryLabel as string}
121
- </span>
122
- </a>
123
- }
124
- </div>
125
- </aside>
126
- <div class="sidebarFloatingControls">
127
- <button
128
- id="lildocs-sidebar-expand"
129
- class="sidebarToggle"
130
- type="button"
131
- aria-label="Expand sidebar"
132
- aria-controls="lildocs-sidebar"
133
- >
134
- <span class="ti ti-layout-sidebar-left-expand" aria-hidden="true" />
135
- </button>
136
- <button
137
- id="lildocs-floating-search"
138
- class="sidebarToggle"
139
- type="button"
140
- aria-label="Search docs"
141
- >
142
- <span class="ti ti-search" aria-hidden="true" />
143
- </button>
144
- </div>
145
- <div id="swup" class="contentGrid">
146
- <main class={`content transition-${transition}`}>
147
- <article>
148
- <GroupBreadcrumbs route={page.route} />
149
- <div dangerouslySetInnerHTML={{ __html: page.html ?? "" }} />
150
- </article>
151
- <PageNav pageNavigation={pageNavigation} />
152
- </main>
153
- <aside class={`toc transition-${transition}`}>
154
- <Toc
155
- headings={page.headings}
156
- repositoryUrl={repositoryUrl}
157
- repositoryLabel={repositoryLabel}
158
- />
159
- </aside>
160
- </div>
161
- </div>
162
- <script
163
- dangerouslySetInnerHTML={{
164
- __html: `window.lildocsSearchUrl = ${JSON.stringify(
165
- rootRelativeUrl(page.route, "search-index.json"),
166
- )};${
167
- issueUrl
168
- ? `window.lildocsIssueUrl = ${JSON.stringify(issueUrl)};`
169
- : ""
170
- }`,
171
- }}
172
- />
173
- <script
174
- type="application/json"
175
- id="lildocs-search-index"
176
- dangerouslySetInnerHTML={{ __html: searchIndexJson }}
177
- />
178
- <div id="lildocs-overlay-root" />
179
- <script type="module" src={assetSrc(page.route, clientScriptPath)} />
180
- </>
181
- }
182
-
183
- function issueUrlForRepository(repositoryUrl: string | undefined) {
184
- if (!repositoryUrl) {
185
- return undefined;
186
- }
187
-
188
- let url: URL;
189
- try {
190
- url = new URL(repositoryUrl);
191
- } catch {
192
- return undefined;
193
- }
194
-
195
- if (url.hostname !== "github.com") {
196
- return undefined;
197
- }
198
-
199
- const [owner, repo] = url.pathname.split("/").filter(Boolean);
200
- if (!owner || !repo) {
201
- return undefined;
202
- }
203
-
204
- return `https://github.com/${owner}/${repo}/issues/new`;
205
- }
206
-
207
- function repositoryLabelForUrl(repositoryUrl: string | undefined) {
208
- if (!repositoryUrl) {
209
- return undefined;
210
- }
211
-
212
- try {
213
- const url = new URL(repositoryUrl);
214
- if (url.hostname !== "github.com") {
215
- return undefined;
216
- }
217
-
218
- const [owner, repo] = url.pathname.split("/").filter(Boolean);
219
- return owner && repo ? `${owner}/${repo}` : undefined;
220
- } catch {
221
- return undefined;
222
- }
223
- }
224
-
225
- function assetSrc(pageRoute: string, image: string) {
226
- if (
227
- /^(?:[a-z]+:)?\/\//i.test(image) || image.startsWith("data:") ||
228
- image.startsWith("/")
229
- ) {
230
- return image;
231
- }
232
-
233
- return rootRelativeUrl(pageRoute, image);
234
- }
235
-
236
- function GroupBreadcrumbs({ route }: { route: string }) @{
237
- const dir = route.split("/").slice(0, -1);
238
- if (dir.length === 0) {
239
- return null;
240
- }
241
-
242
- <p class="groupBreadcrumbs">
243
- {dir.map(titleFromDir).join(" / ") as string}
244
- </p>
245
- }
246
-
247
- function titleFromDir(dir: string) {
248
- return dir.replace(/[-_]+/g, " ").replace(
249
- /\S+/g,
250
- (word) => `${word[0]?.toLocaleUpperCase() ?? ""}${word.slice(1)}`,
251
- );
252
- }
253
-
254
- function PageNav({ pageNavigation }: { pageNavigation?: PageNavigation }) @{
255
- if (!pageNavigation?.next) {
256
- return null;
257
- }
258
-
259
- <nav class="pageNav" aria-label="Page navigation">
260
- <p>
261
- {"Next: "}
262
- <a rel="next" href={pageNavigation.next.href}>
263
- {pageNavigation.next.title as string}
264
- </a>
265
- </p>
266
- </nav>
267
- }
268
-
269
- function NavList({
270
- items,
271
- currentRoute,
272
- pageRoute,
273
- }: {
274
- items: NavItem[];
275
- currentRoute: string;
276
- pageRoute: string;
277
- }) @{
278
- <ul class="navList">
279
- @for (const item of items; key item.route) {
280
- const isReferenceGroup = item.route === "reference/index.html";
281
- <li class={item.children.length > 0 ? "navGroup" : undefined}>
282
- @if (isReferenceGroup) {
283
- <span class="navFolder">
284
- {item.title as string}
285
- </span>
286
- } @else if (item.children.length > 0 && item.hasPage) {
287
- <details
288
- class="navDisclosure"
289
- open={isActiveBranch(item, currentRoute)}
290
- >
291
- <summary class={item.route === currentRoute ? "active" : undefined}>
292
- {item.title as string}
293
- </summary>
294
- <NavList
295
- items={item.children}
296
- currentRoute={currentRoute}
297
- pageRoute={pageRoute}
298
- />
299
- </details>
300
- } @else if (item.children.length > 0) {
301
- <span class="navFolder">
302
- {item.title as string}
303
- </span>
304
- } @else {
305
- <a
306
- class={item.route === currentRoute ? "active" : undefined}
307
- href={relativeUrl(pageRoute, item.route)}
308
- >
309
- {item.title as string}
310
- </a>
311
- }
312
- @if (item.children.length > 0 && !item.hasPage && !isReferenceGroup) {
313
- <NavList
314
- items={item.children}
315
- currentRoute={currentRoute}
316
- pageRoute={pageRoute}
317
- />
318
- }
319
- </li>
320
- }
321
- </ul>
322
- }
323
-
324
- function isActiveBranch(item: NavItem, currentRoute: string): boolean {
325
- return item.route === currentRoute ||
326
- item.children.some((child) => isActiveBranch(child, currentRoute));
327
- }
328
-
329
- function Toc({
330
- headings,
331
- repositoryUrl,
332
- repositoryLabel,
333
- }: {
334
- headings: Heading[];
335
- repositoryUrl?: string;
336
- repositoryLabel?: string;
337
- }) @{
338
- const tocHeadings = headings.filter(
339
- (heading) => heading.depth > 1 && heading.depth < 4,
340
- );
341
- if (tocHeadings.length === 0 && !repositoryLabel) {
342
- return null;
343
- }
344
-
345
- <nav aria-label="Table of contents">
346
- @if (tocHeadings.length > 0) {
347
- <>
348
- <p class="tocTitle">
349
- <span class="ti ti-align-left" aria-hidden="true" />
350
- On this page
351
- </p>
352
- <div class="tocLinks" data-toc-links>
353
- <span class="tocRail" aria-hidden="true" />
354
- <span class="tocVisibility" data-toc-visibility aria-hidden="true" />
355
- <ul>
356
- @for (const heading of tocHeadings; key heading.id) {
357
- <li class={`tocDepth${heading.depth}`}>
358
- <a href={`#${heading.id}`}>
359
- {heading.text as string}
360
- </a>
361
- </li>
362
- }
363
- </ul>
364
- </div>
365
- </>
366
- }
367
- @if (repositoryUrl && repositoryLabel) {
368
- <a
369
- class="tocRepoLink"
370
- href={repositoryUrl}
371
- aria-label="View repository on GitHub"
372
- >
373
- <span class="repoIcon" aria-hidden="true" />
374
- <span>
375
- {repositoryLabel as string}
376
- </span>
377
- </a>
378
- }
379
- </nav>
380
- }