@abreen/tada 1.0.2 → 1.2.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 (146) hide show
  1. package/README.md +96 -48
  2. package/bin/tada.ts +621 -0
  3. package/bin/validators.test.ts +205 -0
  4. package/bin/validators.ts +85 -0
  5. package/{webpack/apply-base-path-plugin.js → build/apply-base-path-plugin.ts} +37 -17
  6. package/build/build-manifest.test.ts +349 -0
  7. package/build/build-manifest.ts +165 -0
  8. package/build/bundle.ts +116 -0
  9. package/{webpack/code.test.js → build/code.test.ts} +10 -7
  10. package/build/colors.ts +25 -0
  11. package/build/content-watch.ts +107 -0
  12. package/build/copy.ts +118 -0
  13. package/{webpack/deflist-id-plugin.js → build/deflist-id-plugin.ts} +7 -6
  14. package/{webpack/external-links-plugin.js → build/external-links-plugin.ts} +14 -5
  15. package/build/features.ts +11 -0
  16. package/build/generate-content-assets.ts +320 -0
  17. package/build/generate-favicon.ts +172 -0
  18. package/build/generate-fonts.ts +31 -0
  19. package/build/generate-katex-assets.ts +35 -0
  20. package/{webpack/generate-manifest-plugin.js → build/generate-manifest.ts} +29 -36
  21. package/build/globals.test.ts +99 -0
  22. package/build/globals.ts +88 -0
  23. package/{webpack/heading-subtitle-plugin.js → build/heading-subtitle-plugin.ts} +4 -2
  24. package/build/json-schema.test.ts +57 -0
  25. package/build/json-schema.ts +33 -0
  26. package/build/log.test.ts +111 -0
  27. package/build/log.ts +167 -0
  28. package/build/markdown-plugins.test.ts +396 -0
  29. package/{webpack/pagefind-plugin.test.js → build/pagefind.test.ts} +74 -13
  30. package/build/pagefind.ts +339 -0
  31. package/build/pdf-text.test.ts +52 -0
  32. package/{webpack/pdf-text.js → build/pdf-text.ts} +47 -27
  33. package/build/pipeline.ts +120 -0
  34. package/{webpack/reachability.test.js → build/reachability.test.ts} +3 -3
  35. package/{webpack/reachability.js → build/reachability.ts} +77 -34
  36. package/build/serve.ts +112 -0
  37. package/build/site-variables.ts +68 -0
  38. package/{webpack/templates.js → build/templates.ts} +38 -35
  39. package/{webpack/text-to-id.js → build/text-to-id.ts} +2 -2
  40. package/build/toc-plugin.test.ts +105 -0
  41. package/{webpack/toc-plugin.js → build/toc-plugin.ts} +32 -13
  42. package/build/types.ts +181 -0
  43. package/build/util.ts +26 -0
  44. package/{webpack/utils/code.js → build/utils/code.ts} +119 -60
  45. package/{webpack/utils/content-files.js → build/utils/content-files.ts} +40 -35
  46. package/build/utils/derive-theme.test.ts +111 -0
  47. package/build/utils/derive-theme.ts +85 -0
  48. package/build/utils/file-types.test.ts +61 -0
  49. package/build/utils/file-types.ts +13 -0
  50. package/build/utils/front-matter.test.ts +77 -0
  51. package/{webpack/utils/front-matter.js → build/utils/front-matter.ts} +22 -9
  52. package/{webpack → build}/utils/jdi-runner/LiterateRunner.java +1 -1
  53. package/{webpack/utils/literate-java.js → build/utils/literate-java.ts} +68 -38
  54. package/{webpack/utils/markdown.js → build/utils/markdown.ts} +126 -49
  55. package/build/utils/paths.test.ts +91 -0
  56. package/{webpack/utils/paths.js → build/utils/paths.ts} +18 -22
  57. package/{webpack/utils/render.js → build/utils/render.ts} +208 -130
  58. package/build/utils/shiki-highlighter.ts +29 -0
  59. package/build/validate-internal-links-plugin.test.ts +106 -0
  60. package/{webpack/validate-internal-links-plugin.js → build/validate-internal-links-plugin.ts} +47 -20
  61. package/{webpack/watch-reachability-state.test.js → build/watch-reachability-state.test.ts} +8 -8
  62. package/{webpack/watch-reachability-state.js → build/watch-reachability-state.ts} +63 -24
  63. package/{webpack/watch-reload-client.js → build/watch-reload-client.ts} +3 -1
  64. package/build/watch.ts +549 -0
  65. package/fonts/google-sans-code/woff2/GoogleSansCodeVariable-Italic.woff2 +0 -0
  66. package/fonts/google-sans-code/woff2/GoogleSansCodeVariable.woff2 +0 -0
  67. package/fonts/inter/woff2/InterVariable-Italic.woff2 +0 -0
  68. package/fonts/inter/woff2/InterVariable.woff2 +0 -0
  69. package/{content → init/content}/index.md +9 -3
  70. package/{content → init/content}/lectures/index.md +1 -1
  71. package/{content → init/content}/markdown.md +28 -8
  72. package/init/content/problem_sets/index.html +14 -0
  73. package/package.json +33 -22
  74. package/{templates → schema}/nav.schema.json +1 -2
  75. package/{webpack → schema}/site.schema.json +4 -12
  76. package/src/_alerts.scss +96 -0
  77. package/src/_base.scss +145 -0
  78. package/src/{layout.scss → _layout.scss} +36 -1
  79. package/src/anchor/index.ts +0 -1
  80. package/src/anchor/style.scss +1 -9
  81. package/src/code/index.ts +3 -3
  82. package/src/code.scss +1 -1
  83. package/src/critical.scss +5 -0
  84. package/src/header/_base.scss +129 -0
  85. package/src/header/style.scss +3 -131
  86. package/src/index.ts +4 -5
  87. package/src/question/style.scss +1 -1
  88. package/src/search/index.test.ts +203 -0
  89. package/src/search/index.ts +38 -93
  90. package/src/search/pdf-utils.ts +79 -0
  91. package/src/search/style.scss +8 -28
  92. package/src/style.scss +15 -326
  93. package/src/timezone/index.ts +5 -6
  94. package/src/toc/style.scss +5 -39
  95. package/src/util.ts +9 -6
  96. package/templates/_theme.scss +38 -14
  97. package/templates/_top.html +1 -1
  98. package/tsconfig.json +10 -6
  99. package/types/dev.d.ts +1 -0
  100. package/types/file-system-access.d.ts +5 -0
  101. package/types/markdown-it-plugins.d.ts +11 -0
  102. package/types/site-variables.d.ts +6 -10
  103. package/types/untyped-modules.d.ts +47 -0
  104. package/bin/tada.js +0 -361
  105. package/config/authors.json +0 -1
  106. package/config/nav.json +0 -28
  107. package/content/problem_sets/index.md +0 -6
  108. package/types/dev.ts +0 -3
  109. package/webpack/build-state.js +0 -97
  110. package/webpack/colors.js +0 -15
  111. package/webpack/config.base.js +0 -151
  112. package/webpack/config.dev.js +0 -23
  113. package/webpack/config.prod.js +0 -32
  114. package/webpack/content-watch-plugin.js +0 -153
  115. package/webpack/features.js +0 -5
  116. package/webpack/generate-content-assets-plugin.js +0 -308
  117. package/webpack/generate-favicon-plugin.js +0 -198
  118. package/webpack/generate-fonts-plugin.js +0 -69
  119. package/webpack/globals.js +0 -74
  120. package/webpack/json-schema.js +0 -19
  121. package/webpack/log.js +0 -143
  122. package/webpack/markdown-plugins.test.js +0 -203
  123. package/webpack/pagefind-plugin.js +0 -379
  124. package/webpack/print-flair-plugin.js +0 -22
  125. package/webpack/serve.js +0 -104
  126. package/webpack/site-variables.js +0 -53
  127. package/webpack/util.js +0 -49
  128. package/webpack/utils/define-plugin.js +0 -20
  129. package/webpack/utils/file-types.js +0 -26
  130. package/webpack/utils/parse-hsl.js +0 -8
  131. package/webpack/utils/shiki-highlighter.js +0 -26
  132. package/webpack/watch.js +0 -166
  133. /package/{webpack → build}/flair.json +0 -0
  134. /package/{webpack → build}/utils/jdi-runner/LiterateRunner.class +0 -0
  135. /package/fonts/google-sans-code/{GoogleSansCodeVariable-Italic.ttf → ttf/GoogleSansCodeVariable-Italic.ttf} +0 -0
  136. /package/fonts/google-sans-code/{GoogleSansCodeVariable.ttf → ttf/GoogleSansCodeVariable.ttf} +0 -0
  137. /package/fonts/inter/{InterVariable-Italic.ttf → ttf/InterVariable-Italic.ttf} +0 -0
  138. /package/fonts/inter/{InterVariable.ttf → ttf/InterVariable.ttf} +0 -0
  139. /package/{content → init/content}/lectures/01/Pair.java.md +0 -0
  140. /package/{content → init/content}/lectures/01/Rectangle.java +0 -0
  141. /package/{content → init/content}/lectures/01/demo.py +0 -0
  142. /package/{content → init/content}/lectures/01/index.md +0 -0
  143. /package/{content → init/content}/lectures/01/lecture1.pdf +0 -0
  144. /package/{public → init/public}/avatars/alex.jpg +0 -0
  145. /package/{public → init/public}/test.txt +0 -0
  146. /package/{templates → schema}/authors.schema.json +0 -0
package/README.md CHANGED
@@ -11,18 +11,19 @@ A static site generator. The successor to Presto.
11
11
  * Renders headings, alert boxes, and `<hr>` elements
12
12
  * Highlights the heading currently being viewed
13
13
  - Built-in search powered by [Pagefind][pagefind]
14
- * Only pages reachable by links on the site appear in search results
14
+ * Only pages in `content/` reachable from `/index.html` are indexed
15
15
  - Generated HTML pages for source code
16
16
  * Automatic code highlighting, clickable line numbers
17
17
  * Dynamic table of contents for each method/function
18
18
  * Converts new Markdown comment syntax ([added in Java 23][jep467]) to HTML
19
- * Indexed by Pagefind
19
+ * Indexed by Pagefind (classes, interfaces, methods, and fields)
20
20
  - PDF files are copied into `dist/`
21
21
  - Text of each PDF page is extracted using [mutool][mutool] and indexed
22
22
  - External link handling (special visual treatment for external links)
23
23
  - Internal link validation at build time (broken links fail the build)
24
24
  - Internal links automatically prefixed with base path, if specified
25
25
  - Time zone chooser (automatically adjusts `<datetime>` elements)
26
+ - LaTeX math rendered at build time via [KaTeX][katex]
26
27
  - Extended Markdown syntax
27
28
  * `<<< details ... <<<` renders a collapsible box
28
29
  * `::: section ... :::` renders a special section with a fancy background
@@ -69,22 +70,27 @@ Visit [http://localhost:8080/index.html](http://localhost:8080/index.html).
69
70
  ### `tada init <dirname>`
70
71
 
71
72
  Create a new Tada site in a new directory. Prompts for:
72
- - **Site title** --- displayed in the header and `<title>` tag
73
- - **Symbol** --- short text (1-5 uppercase characters) shown in the logo and favicon
74
- - **Theme color** --- HSL color, e.g. `hsl(195 70% 40%)`
75
- - **Background tint hue** --- hue (0-360) for background/foreground tinting (defaults to `20`)
76
- - **Background tint amount** --- percentage (0-100) of tint to apply (defaults to `100`)
77
- - **Default time zone** --- for `<datetime>` elements (defaults to your system zone)
78
- - **Production base URL** --- e.g. `https://example.edu`
79
- - **Production base path** --- e.g. `/cs101` (defaults to `/`)
73
+ - **Site title**: displayed in the header and `<title>` tag
74
+ - **Symbol**: short text (1-5 uppercase characters) shown in the logo and favicon
75
+ - **Theme color**: HSL color, e.g. `hsl(195 70% 40%)`
76
+ - **Background tint hue**: hue (0-360) for background/foreground tinting (defaults to `20`)
77
+ - **Background tint amount**: percentage (0-100) of tint to apply (defaults to `100`)
78
+ - **Default time zone**: for `<time>` elements (defaults to your system zone)
79
+ - **Production base URL**: e.g. `https://example.edu`
80
+ - **Production base path**: e.g. `/cs101` (defaults to `/`)
80
81
 
81
- Pass `--default` to use the default values for all options without being
82
- prompted.
82
+ Pass `--no-interactive` to skip prompts and use default values for all options.
83
+ You can also override specific defaults with flags:
84
+
85
+ tada init mysite --no-interactive --prod-base https://example.edu --prod-base-path /cs101
86
+
87
+ Available flags: `--title`, `--symbol`, `--theme-color`, `--tint-hue`,
88
+ `--tint-amount`, `--default-time-zone`, `--prod-base`, `--prod-base-path`.
83
89
 
84
90
 
85
91
  ### `tada dev`
86
92
 
87
- Build the site for local development (using `config/site.dev.json`)
93
+ Build the site for local development (using `site.dev.json`)
88
94
  into the `dist/` directory.
89
95
 
90
96
 
@@ -101,12 +107,69 @@ Start a development web server, watch for changes and rebuild automatically.
101
107
 
102
108
  ### `tada clean`
103
109
 
104
- Remove the `dist/` directory.
110
+ Remove the `dist/` directory. Pass `--prod` to also prune old production
111
+ builds (keeps the latest two versions).
105
112
 
106
113
 
107
114
  ### `tada prod`
108
115
 
109
- Build the site for production (uses `config/site.prod.json`).
116
+ Build the site for production (uses `site.prod.json`). Each prod build is
117
+ saved to a versioned directory under `dist-prod/` (e.g., `dist-prod/v1/`,
118
+ `dist-prod/v2/`) with a manifest file that records the SHA-256 hash of every
119
+ output file.
120
+
121
+
122
+ ### `tada diff`
123
+
124
+ Compare two production builds and list added, changed, and removed files.
125
+ With no arguments, compares the last two builds. You can also specify version
126
+ numbers explicitly:
127
+
128
+ tada diff # compare latest two builds
129
+ tada diff 1 3 # compare v1 and v3
130
+
131
+ Use `--copy <dir>` to copy only the changed and added files to a directory:
132
+
133
+ tada diff --copy upload/
134
+
135
+ The output directory will also include a `manifest.json` for the newer build.
136
+
137
+
138
+ ## Development vs. production builds
139
+
140
+ `tada dev` and `tada watch` build to the `dist/` directory using
141
+ `site.dev.json` (typically `localhost` URLs). `tada watch` includes a
142
+ development server with live reload; `tada serve` is a standalone server
143
+ for previewing a `tada dev` build. Dev builds overwrite `dist/` each time.
144
+
145
+ `tada prod` builds to a new versioned directory under `dist-prod/` each time
146
+ it runs. Previous production builds are preserved, so you can compare any
147
+ two versions with `tada diff`.
148
+
149
+
150
+ ## Deploying to S3
151
+
152
+ If you host your site in an S3 bucket, `tada diff --copy` lets you upload
153
+ only the files that changed between prod builds instead of re-uploading
154
+ everything.
155
+
156
+ First time:
157
+
158
+ ```
159
+ tada prod
160
+ # Upload the entire dist-prod/v1/ directory to your S3 bucket
161
+ ```
162
+
163
+ After making changes:
164
+
165
+ ```
166
+ tada prod
167
+ tada diff --copy upload/
168
+ # Upload just the upload/ directory to S3 (only changed files)
169
+ ```
170
+
171
+ If `tada diff` reports removed files, delete those from your S3 bucket
172
+ manually.
110
173
 
111
174
 
112
175
  ## Prerequisites
@@ -125,10 +188,10 @@ Build the site for production (uses `config/site.prod.json`).
125
188
 
126
189
  Build-time site config lives in:
127
190
 
128
- - `config/site.dev.json` (used by `tada dev` / `tada watch`)
129
- - `config/site.prod.json` (used by `tada prod`)
130
- - `config/nav.json` (navigation structure)
131
- - `config/authors.json` (author data)
191
+ - `site.dev.json` (used by `tada dev` / `tada watch`)
192
+ - `site.prod.json` (used by `tada prod`)
193
+ - `nav.json` (navigation structure)
194
+ - `authors.json` (author data)
132
195
 
133
196
  Example site configuration JSON file:
134
197
 
@@ -156,7 +219,7 @@ Example site configuration JSON file:
156
219
  | `title` | Title for the whole site (also used to derive `titlePostfix`) |
157
220
  | `titlePostfix` | *Optional*, the string to append to each page's `title` |
158
221
  | `symbol` | Text (1-5 chars) displayed in header (also used as the favicon symbol) |
159
- | `themeColor` | HSL theme color for the site, e.g. `"hsl(195 70% 40%)"` |
222
+ | `themeColor` | Theme color for the site (e.g., `"tomato"`, `"#c04040"`, `"hsl(195 70% 40%)"`) |
160
223
  | `tintHue` | *Optional*, hue (0-360) for background and foreground tinting (default `20`) |
161
224
  | `tintAmount` | *Optional*, percentage (0-100) of tint to apply (default `100`) |
162
225
  | `faviconSymbol` | *Optional*, the text to use instead of `symbol` in the favicon |
@@ -167,7 +230,7 @@ Example site configuration JSON file:
167
230
  | `basePath` | URL prefix for deployment under a subpath (e.g., `"/cs101"`), use `"/"` at root |
168
231
  | `internalDomains` | Domain names treated as internal by link processing (not marked external) |
169
232
  | `codeLanguages` | Map file extension to Shiki language (e.g., `"java": "java"`) |
170
- | `faviconColor` | *Optional*, HSL color override for favicon (defaults to `themeColor`) |
233
+ | `faviconColor` | *Optional*, background color for favicon (defaults to `themeColor`) |
171
234
  | `faviconFontWeight` | *Optional*, font weight used for favicon text (default `700`) |
172
235
  | `vars` | Arbitrary key/value variables exposed to templates/content (e.g., `<%= staffEmail %>`) |
173
236
 
@@ -224,27 +287,15 @@ with `name`, `avatar`, and optionally `url`.
224
287
  ```
225
288
 
226
289
 
227
- ### Log level
228
-
229
- Set the `TADA_LOG_LEVEL` environment variable to control build log verbosity.
230
- Valid levels (from most to least verbose): `debug`, `info`, `warn`, `error`.
231
- The default level is `info`. To see *all* logs generated by Tada, set the env
232
- var to `debug`:
233
-
234
- ```
235
- TADA_LOG_LEVEL=debug tada dev
236
- ```
237
-
238
-
239
290
  ## Content
240
291
 
241
292
  Site content lives in the `content/` directory. Markdown is converted to HTML.
242
- HTML files should contain front matter and are also built, but not processed
243
- like Markdown files are.
293
+ HTML files should contain front matter and are also built.
294
+
295
+ Any other kinds of files are copied into `dist/` in the same locations.
244
296
 
245
- PDF, `.txt`, ZIP, images, and other kinds of files are copied into `dist/`
246
- in the same locations. All files in `public/` are copied directly into `dist/`
247
- with zero processing.
297
+ All files in `public/` are copied directly into `dist/` with zero processing.
298
+ Files in `public/` are **not** included in the search index.
248
299
 
249
300
 
250
301
  ### Front matter fields
@@ -256,31 +307,27 @@ list of variables parsed using the [`front-matter`][front-matter] library).
256
307
  |-------|-------------|
257
308
  | `title` (required) | Page title (`<title>` tag and page heading) |
258
309
  | `skip` | Set to `true` to skip building this page completely |
259
- | `author` | Author handle (e.g. `jsmith`) resolved to a full object via `config/authors.json` |
310
+ | `author` | Author handle (e.g. `jsmith`) resolved to a full object via `authors.json` |
260
311
  | `description` | Meta description for the page |
261
312
  | `toc` | Set to `true` to show a table of contents |
262
313
  | `parent` & `parentLabel` | URL and label for a breadcrumb link displayed above the title |
263
314
  | `published` | Year, month, and day of publishing (e.g, `2025-09-09`) |
264
315
 
316
+ You may also add arbitrary fields in a page's front matter, and access them
317
+ using Lodash syntax (see below).
318
+
265
319
 
266
320
  ### Variable substitution
267
321
 
268
322
  Plain text content (e.g., HTML and Markdown) are processed using [Lodash
269
323
  templates][lodash].
270
324
 
271
- - Site config values are available under `site` (e.g., `site.title`, `site.symbol`)
272
- - Page variables (from front matter) are available under `page` (e.g., `page.author`)
325
+ - Site config values are available under `site` (e.g., `site.title`)
326
+ - Page variables (from front matter) are available under `page`
273
327
  - Custom variables from the `"vars"` property of the config are available
274
328
  without any prefix (e.g., `<%= staffEmail %>`)
275
329
 
276
330
 
277
- ## Templates
278
-
279
- HTML page layouts are internal to the Tada package. You don't need to modify
280
- them; they are designed to work with the client-side components and styles
281
- bundled in the package.
282
-
283
-
284
331
 
285
332
  [inter]: https://fonts.google.com/specimen/Inter
286
333
  [lodash]: https://lodash.info/doc/template
@@ -288,3 +335,4 @@ bundled in the package.
288
335
  [pagefind]: https://pagefind.app/
289
336
  [mutool]: https://mupdf.readthedocs.io/en/latest/tools/mutool.html
290
337
  [jep467]: https://openjdk.org/jeps/467
338
+ [katex]: https://katex.org/