@janga/norna 0.7.18 → 0.7.23

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 (615) hide show
  1. package/README.md +22 -12
  2. package/astro.config.mjs +25 -0
  3. package/bin/norna-cli.mjs +8 -2
  4. package/package.json +60 -13
  5. package/schemas/category.schema.json +20 -0
  6. package/schemas/config.schema.json +22 -14
  7. package/schemas/content-frontmatter.schema.json +25 -5
  8. package/schemas/manifest.json +2 -1
  9. package/schemas/page-theme.schema.json +58 -30
  10. package/schemas/sitewide-content.schema.json +20 -19
  11. package/schemas/theme.schema.json +542 -243
  12. package/scripts/add-site-node.mjs +251 -0
  13. package/scripts/check-config.mjs +32 -4
  14. package/scripts/deploy-site.mjs +5 -9
  15. package/scripts/dev-local.mjs +175 -112
  16. package/scripts/generate-images.mjs +11 -15
  17. package/scripts/generate-schemas.mjs +4 -1
  18. package/scripts/init-site.mjs +35 -0
  19. package/scripts/lib/astro-command.mjs +14 -9
  20. package/scripts/lib/content-sync-apply.mjs +34 -0
  21. package/scripts/lib/content-sync-plan.mjs +179 -0
  22. package/scripts/lib/editor-language-service.mjs +156 -177
  23. package/scripts/lib/heading-ids.mjs +4 -2
  24. package/scripts/lib/image-presentation.mjs +2 -0
  25. package/scripts/lib/markdown-links.mjs +182 -0
  26. package/scripts/lib/navigation-model.mjs +36 -19
  27. package/scripts/lib/norna-markdown-blocks.mjs +65 -145
  28. package/scripts/lib/norna-markdown-render-plugin.mjs +37 -0
  29. package/scripts/lib/object.mjs +28 -0
  30. package/scripts/lib/page-aliases.mjs +164 -0
  31. package/scripts/lib/page-markdown.mjs +332 -0
  32. package/scripts/lib/presentation-contract.mjs +266 -0
  33. package/scripts/lib/presentation-palette-metadata.mjs +51 -0
  34. package/scripts/lib/presentation.mjs +508 -79
  35. package/scripts/lib/project-config.mjs +78 -10
  36. package/scripts/lib/schema-definitions.mjs +67 -16
  37. package/scripts/lib/schema-editor-metadata.mjs +126 -24
  38. package/scripts/lib/schema-value-definitions.mjs +30 -12
  39. package/scripts/lib/site-content.mjs +46 -239
  40. package/scripts/lib/site-link-graph.mjs +326 -0
  41. package/scripts/lib/site-page-urls.mjs +10 -0
  42. package/scripts/lib/site-paths.mjs +2 -3
  43. package/scripts/lib/site-structure.mjs +189 -0
  44. package/scripts/lib/sitemap.mjs +34 -0
  45. package/scripts/lib/theme-presets.mjs +118 -119
  46. package/scripts/lib/theme-profiles.mjs +223 -0
  47. package/scripts/lib/typography.mjs +220 -35
  48. package/scripts/lib/yaml-config.mjs +50 -6
  49. package/scripts/lib/yaml-indentation.mjs +86 -0
  50. package/scripts/show-typography.mjs +2 -3
  51. package/scripts/sync-content-sections.mjs +158 -244
  52. package/scripts/sync-site-public.mjs +23 -2
  53. package/src/components/CodeBlockCopyScript.astro +92 -0
  54. package/src/components/DisplaySettings.astro +107 -0
  55. package/src/components/ImageCarousel.astro +38 -13
  56. package/src/components/NavigationPageTree.astro +103 -88
  57. package/src/components/PageAliasRedirect.astro +49 -0
  58. package/src/components/PageContentsNavigation.astro +21 -0
  59. package/src/components/SectionNavigationScript.astro +112 -2
  60. package/src/components/SiteBreadcrumbs.astro +15 -12
  61. package/src/components/SiteNavigation.astro +104 -41
  62. package/src/components/SitePage.astro +76 -40
  63. package/src/components/SiteSection.astro +40 -191
  64. package/src/components/SiteTreeNavigation.astro +10 -10
  65. package/src/content.config.ts +5 -2
  66. package/src/layouts/BaseLayout.astro +55 -9
  67. package/src/lib/generatedImages.ts +0 -7
  68. package/src/lib/readerPreferencesScript.mjs +141 -0
  69. package/src/lib/sectionContent.ts +119 -201
  70. package/src/lib/siteNavigation.ts +36 -18
  71. package/src/lib/sitePages.ts +92 -20
  72. package/src/pages/[...slug].astro +35 -8
  73. package/src/styles/content.css +494 -0
  74. package/src/styles/foundations.css +284 -0
  75. package/src/styles/global.css +6 -2047
  76. package/src/styles/media.css +523 -0
  77. package/src/styles/navigation.css +495 -0
  78. package/src/styles/page-layout.css +437 -0
  79. package/src/styles/responsive.css +525 -0
  80. package/starters/basic/README.md +3 -3
  81. package/docs/README.md +0 -137
  82. package/docs/assets/norna-dog-shelter.jpg +0 -0
  83. package/docs/commands.md +0 -189
  84. package/docs/configuration.md +0 -142
  85. package/docs/content.md +0 -351
  86. package/docs/design/command-organization.md +0 -414
  87. package/docs/design/navigation-and-theme-plan.md +0 -186
  88. package/docs/design/norna-diagram-design.md +0 -159
  89. package/docs/design/site-examples-structure.md +0 -119
  90. package/docs/engine-development.md +0 -215
  91. package/docs/getting-started.md +0 -206
  92. package/docs/how-to/embedded-site.md +0 -35
  93. package/docs/images-and-metadata.md +0 -188
  94. package/docs/local-development.md +0 -82
  95. package/docs/pages.md +0 -190
  96. package/docs/public-files.md +0 -118
  97. package/docs/publishing.md +0 -117
  98. package/docs/requirements.md +0 -54
  99. package/docs/site-files.md +0 -152
  100. package/docs/sitewide-content.md +0 -73
  101. package/docs/theme.md +0 -237
  102. package/docs/typography.md +0 -168
  103. package/examples/README.md +0 -49
  104. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +0 -35
  105. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +0 -97
  106. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +0 -852
  107. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-assets.mjs +0 -4
  108. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-modules.mjs +0 -1
  109. package/examples/complete-sites/dog-shelter-multi-page/.astro/content.d.ts +0 -183
  110. package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +0 -1
  111. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev-local.json +0 -8
  112. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.json +0 -13
  113. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +0 -36
  114. package/examples/complete-sites/dog-shelter-multi-page/.astro/settings.json +0 -5
  115. package/examples/complete-sites/dog-shelter-multi-page/.astro/types.d.ts +0 -2
  116. package/examples/complete-sites/dog-shelter-multi-page/README.md +0 -24
  117. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/_metadata.json +0 -74
  118. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  119. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  120. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  121. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  122. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  123. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  124. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  125. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  126. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  127. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  128. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  129. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  130. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  131. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  132. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  133. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  134. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/package.json +0 -3
  135. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  136. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  137. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  138. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  139. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  140. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  141. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  142. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  143. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  144. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  145. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  146. package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +0 -98
  147. package/examples/complete-sites/dog-shelter-multi-page/site/config.yaml +0 -1
  148. package/examples/complete-sites/dog-shelter-multi-page/site/pages/000-home/content.md +0 -23
  149. package/examples/complete-sites/dog-shelter-multi-page/site/pages/000-home/images/shelter-dog.jpg +0 -0
  150. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/content.md +0 -21
  151. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rex.jpg +0 -0
  152. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rover.jpg +0 -0
  153. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/content.md +0 -22
  154. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/images/adoption-dog.jpg +0 -0
  155. package/examples/complete-sites/dog-shelter-multi-page/site/public/favicon.svg +0 -10
  156. package/examples/complete-sites/dog-shelter-multi-page/site/public/logo.svg +0 -9
  157. package/examples/complete-sites/dog-shelter-multi-page/site/public/robots.txt +0 -2
  158. package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +0 -4
  159. package/examples/complete-sites/dog-shelter-multi-page/site/theme.yaml +0 -1
  160. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/site.schema.json +0 -35
  161. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/sitewide.schema.json +0 -97
  162. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/theme.schema.json +0 -852
  163. package/examples/complete-sites/dog-shelter-single-page/.astro/content-assets.mjs +0 -4
  164. package/examples/complete-sites/dog-shelter-single-page/.astro/content-modules.mjs +0 -1
  165. package/examples/complete-sites/dog-shelter-single-page/.astro/content.d.ts +0 -183
  166. package/examples/complete-sites/dog-shelter-single-page/.astro/data-store.json +0 -1
  167. package/examples/complete-sites/dog-shelter-single-page/.astro/dev-local.json +0 -8
  168. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.json +0 -13
  169. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.log +0 -18
  170. package/examples/complete-sites/dog-shelter-single-page/.astro/settings.json +0 -5
  171. package/examples/complete-sites/dog-shelter-single-page/.astro/types.d.ts +0 -2
  172. package/examples/complete-sites/dog-shelter-single-page/README.md +0 -24
  173. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/_metadata.json +0 -74
  174. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  175. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  176. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  177. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  178. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  179. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  180. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  181. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  182. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  183. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  184. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  185. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  186. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  187. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  188. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  189. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  190. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/package.json +0 -3
  191. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  192. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  193. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  194. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  195. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  196. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  197. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  198. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  199. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  200. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  201. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  202. package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +0 -50
  203. package/examples/complete-sites/dog-shelter-single-page/site/config.yaml +0 -1
  204. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/content.md +0 -37
  205. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/images/foster-dog.jpg +0 -0
  206. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/images/rescue-dog.jpg +0 -0
  207. package/examples/complete-sites/dog-shelter-single-page/site/public/favicon.svg +0 -10
  208. package/examples/complete-sites/dog-shelter-single-page/site/public/logo.svg +0 -9
  209. package/examples/complete-sites/dog-shelter-single-page/site/public/robots.txt +0 -2
  210. package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +0 -4
  211. package/examples/complete-sites/dog-shelter-single-page/site/theme.yaml +0 -1
  212. package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +0 -35
  213. package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +0 -97
  214. package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +0 -844
  215. package/examples/feature-demos/media-and-surfaces/.astro/content-assets.mjs +0 -4
  216. package/examples/feature-demos/media-and-surfaces/.astro/content-modules.mjs +0 -1
  217. package/examples/feature-demos/media-and-surfaces/.astro/content.d.ts +0 -183
  218. package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +0 -1
  219. package/examples/feature-demos/media-and-surfaces/.astro/dev.log +0 -14
  220. package/examples/feature-demos/media-and-surfaces/.astro/settings.json +0 -5
  221. package/examples/feature-demos/media-and-surfaces/.astro/types.d.ts +0 -2
  222. package/examples/feature-demos/media-and-surfaces/README.md +0 -21
  223. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +0 -80
  224. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  225. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  226. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  227. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  228. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  229. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  230. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  231. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  232. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  233. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  234. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  235. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  236. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js +0 -1389
  237. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  238. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  239. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  240. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  241. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  242. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/package.json +0 -3
  243. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  244. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  245. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  246. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  247. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  248. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  249. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  250. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  251. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  252. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  253. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  254. package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +0 -66
  255. package/examples/feature-demos/media-and-surfaces/site/config.yaml +0 -1
  256. package/examples/feature-demos/media-and-surfaces/site/pages/000-home/content.md +0 -15
  257. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/content.md +0 -71
  258. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-carousel.svg +0 -11
  259. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-stack.svg +0 -9
  260. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-surfaces.svg +0 -8
  261. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-one.svg +0 -8
  262. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-three.svg +0 -13
  263. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-two.svg +0 -8
  264. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-one.svg +0 -8
  265. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-two.svg +0 -9
  266. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/content.md +0 -42
  267. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/theme.yaml +0 -2
  268. package/examples/feature-demos/media-and-surfaces/site/public/robots.txt +0 -2
  269. package/examples/feature-demos/media-and-surfaces/site/sitewide-content.yaml +0 -2
  270. package/examples/feature-demos/media-and-surfaces/site/theme.yaml +0 -1
  271. package/examples/feature-demos/sitewide-content/.astro/collections/site.schema.json +0 -59
  272. package/examples/feature-demos/sitewide-content/.astro/collections/sitewide.schema.json +0 -138
  273. package/examples/feature-demos/sitewide-content/.astro/collections/theme.schema.json +0 -755
  274. package/examples/feature-demos/sitewide-content/.astro/content-assets.mjs +0 -1
  275. package/examples/feature-demos/sitewide-content/.astro/content-modules.mjs +0 -1
  276. package/examples/feature-demos/sitewide-content/.astro/content.d.ts +0 -183
  277. package/examples/feature-demos/sitewide-content/.astro/data-store.json +0 -1
  278. package/examples/feature-demos/sitewide-content/.astro/dev.json +0 -13
  279. package/examples/feature-demos/sitewide-content/.astro/dev.log +0 -18
  280. package/examples/feature-demos/sitewide-content/.astro/settings.json +0 -5
  281. package/examples/feature-demos/sitewide-content/.astro/types.d.ts +0 -2
  282. package/examples/feature-demos/sitewide-content/README.md +0 -26
  283. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/_metadata.json +0 -74
  284. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  285. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  286. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  287. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  288. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  289. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  290. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  291. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  292. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  293. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  294. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  295. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  296. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  297. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  298. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  299. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  300. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/package.json +0 -3
  301. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  302. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  303. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  304. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  305. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  306. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  307. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  308. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  309. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  310. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  311. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  312. package/examples/feature-demos/sitewide-content/site/.norna/generated-images.json +0 -1
  313. package/examples/feature-demos/sitewide-content/site/config.yaml +0 -1
  314. package/examples/feature-demos/sitewide-content/site/pages/000-home/content.md +0 -17
  315. package/examples/feature-demos/sitewide-content/site/pages/010-logo-and-navigation/content.md +0 -17
  316. package/examples/feature-demos/sitewide-content/site/pages/020-notices/content.md +0 -23
  317. package/examples/feature-demos/sitewide-content/site/pages/030-footer/content.md +0 -18
  318. package/examples/feature-demos/sitewide-content/site/public/logo.svg +0 -6
  319. package/examples/feature-demos/sitewide-content/site/public/robots.txt +0 -2
  320. package/examples/feature-demos/sitewide-content/site/sitewide-content.yaml +0 -14
  321. package/examples/feature-demos/sitewide-content/site/theme.yaml +0 -1
  322. package/examples/feature-demos/theme-preset-documentation/README.md +0 -16
  323. package/examples/feature-demos/theme-preset-documentation/site/.norna/generated-images.json +0 -74
  324. package/examples/feature-demos/theme-preset-documentation/site/config.yaml +0 -1
  325. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/content.md +0 -30
  326. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/black-schnauzer.jpg +0 -0
  327. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/retriever-portrait.jpg +0 -0
  328. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/schnauzer-portrait.jpg +0 -0
  329. package/examples/feature-demos/theme-preset-documentation/site/public/robots.txt +0 -2
  330. package/examples/feature-demos/theme-preset-documentation/site/sitewide-content.yaml +0 -3
  331. package/examples/feature-demos/theme-preset-documentation/site/theme.yaml +0 -1
  332. package/examples/feature-demos/theme-preset-portfolio/README.md +0 -16
  333. package/examples/feature-demos/theme-preset-portfolio/site/.norna/generated-images.json +0 -74
  334. package/examples/feature-demos/theme-preset-portfolio/site/config.yaml +0 -1
  335. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/content.md +0 -31
  336. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/puppy-portrait.jpg +0 -0
  337. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/shepherd-portrait.jpg +0 -0
  338. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/white-puppy.jpg +0 -0
  339. package/examples/feature-demos/theme-preset-portfolio/site/public/robots.txt +0 -2
  340. package/examples/feature-demos/theme-preset-portfolio/site/sitewide-content.yaml +0 -3
  341. package/examples/feature-demos/theme-preset-portfolio/site/theme.yaml +0 -1
  342. package/examples/feature-demos/theme-preset-project/.astro/collections/routeTheme.schema.json +0 -746
  343. package/examples/feature-demos/theme-preset-project/.astro/collections/site.schema.json +0 -59
  344. package/examples/feature-demos/theme-preset-project/.astro/collections/sitewide.schema.json +0 -138
  345. package/examples/feature-demos/theme-preset-project/.astro/collections/theme.schema.json +0 -755
  346. package/examples/feature-demos/theme-preset-project/.astro/content-assets.mjs +0 -4
  347. package/examples/feature-demos/theme-preset-project/.astro/content-modules.mjs +0 -1
  348. package/examples/feature-demos/theme-preset-project/.astro/content.d.ts +0 -183
  349. package/examples/feature-demos/theme-preset-project/.astro/data-store.json +0 -1
  350. package/examples/feature-demos/theme-preset-project/.astro/dev-local.json +0 -8
  351. package/examples/feature-demos/theme-preset-project/.astro/dev.json +0 -15
  352. package/examples/feature-demos/theme-preset-project/.astro/dev.log +0 -164
  353. package/examples/feature-demos/theme-preset-project/.astro/settings.json +0 -5
  354. package/examples/feature-demos/theme-preset-project/.astro/types.d.ts +0 -2
  355. package/examples/feature-demos/theme-preset-project/README.md +0 -16
  356. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/_metadata.json +0 -80
  357. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  358. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  359. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  360. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  361. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  362. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  363. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  364. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  365. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  366. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  367. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  368. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  369. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/embla-carousel.js +0 -1389
  370. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  371. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  372. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  373. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  374. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  375. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/package.json +0 -3
  376. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  377. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  378. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  379. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  380. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  381. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  382. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  383. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  384. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  385. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  386. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  387. package/examples/feature-demos/theme-preset-project/site/.norna/generated-images.json +0 -74
  388. package/examples/feature-demos/theme-preset-project/site/config.yaml +0 -1
  389. package/examples/feature-demos/theme-preset-project/site/pages/000-home/content.md +0 -31
  390. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/boxer-portrait.jpg +0 -0
  391. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/grass-puppy.jpg +0 -0
  392. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/grey-street-dog.jpg +0 -0
  393. package/examples/feature-demos/theme-preset-project/site/public/robots.txt +0 -2
  394. package/examples/feature-demos/theme-preset-project/site/sitewide-content.yaml +0 -3
  395. package/examples/feature-demos/theme-preset-project/site/theme.yaml +0 -1
  396. package/examples/feature-demos/theme-preset-statement/README.md +0 -16
  397. package/examples/feature-demos/theme-preset-statement/site/.norna/generated-images.json +0 -74
  398. package/examples/feature-demos/theme-preset-statement/site/config.yaml +0 -1
  399. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/content.md +0 -31
  400. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/black-pedigree.jpg +0 -0
  401. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/sheepdog-grass.jpg +0 -0
  402. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/sheepdog-wide.jpg +0 -0
  403. package/examples/feature-demos/theme-preset-statement/site/public/robots.txt +0 -2
  404. package/examples/feature-demos/theme-preset-statement/site/sitewide-content.yaml +0 -3
  405. package/examples/feature-demos/theme-preset-statement/site/theme.yaml +0 -1
  406. package/fixtures/basic/site/.norna/generated-images.json +0 -1
  407. package/fixtures/basic/site/config.yaml +0 -1
  408. package/fixtures/basic/site/pages/000-home/content.md +0 -14
  409. package/fixtures/basic/site/pages/000-home/images/.gitkeep +0 -1
  410. package/fixtures/basic/site/public/robots.txt +0 -2
  411. package/fixtures/basic/site/sitewide-content.yaml +0 -3
  412. package/fixtures/basic/site/theme.yaml +0 -1
  413. package/fixtures/content-model-v2/.astro/collections/site.schema.json +0 -776
  414. package/fixtures/content-model-v2/.astro/collections/theme.schema.json +0 -668
  415. package/fixtures/content-model-v2/.astro/content-assets.mjs +0 -4
  416. package/fixtures/content-model-v2/.astro/content-modules.mjs +0 -1
  417. package/fixtures/content-model-v2/.astro/content.d.ts +0 -175
  418. package/fixtures/content-model-v2/.astro/data-store.json +0 -1
  419. package/fixtures/content-model-v2/.astro/dev-local.json +0 -8
  420. package/fixtures/content-model-v2/.astro/dev.json +0 -13
  421. package/fixtures/content-model-v2/.astro/dev.log +0 -231
  422. package/fixtures/content-model-v2/.astro/settings.json +0 -5
  423. package/fixtures/content-model-v2/.astro/types.d.ts +0 -2
  424. package/fixtures/content-model-v2/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +0 -1
  425. package/fixtures/content-model-v2/dist/_astro/SitePage.BbfZub4g.css +0 -1
  426. package/fixtures/content-model-v2/dist/guide/index.html +0 -3
  427. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-480.webp +0 -0
  428. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-768.webp +0 -0
  429. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-971.webp +0 -0
  430. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-480.webp +0 -0
  431. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-768.webp +0 -0
  432. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-971.webp +0 -0
  433. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-480.webp +0 -0
  434. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-768.webp +0 -0
  435. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-971.webp +0 -0
  436. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1080.webp +0 -0
  437. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1440.webp +0 -0
  438. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1600.webp +0 -0
  439. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-480.webp +0 -0
  440. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-768.webp +0 -0
  441. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-480.webp +0 -0
  442. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-768.webp +0 -0
  443. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp +0 -0
  444. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1080.webp +0 -0
  445. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1440.webp +0 -0
  446. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1600.webp +0 -0
  447. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-480.webp +0 -0
  448. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-768.webp +0 -0
  449. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1080.webp +0 -0
  450. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1440.webp +0 -0
  451. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1600.webp +0 -0
  452. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-480.webp +0 -0
  453. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-768.webp +0 -0
  454. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1080.webp +0 -0
  455. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1440.webp +0 -0
  456. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1600.webp +0 -0
  457. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-480.webp +0 -0
  458. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-768.webp +0 -0
  459. package/fixtures/content-model-v2/dist/index.html +0 -8
  460. package/fixtures/content-model-v2/node_modules/.vite/deps/_metadata.json +0 -80
  461. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  462. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  463. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  464. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  465. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  466. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  467. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  468. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  469. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  470. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  471. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  472. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  473. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js +0 -1389
  474. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  475. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  476. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  477. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  478. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  479. package/fixtures/content-model-v2/node_modules/.vite/deps/package.json +0 -3
  480. package/fixtures/content-model-v2/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  481. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  482. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  483. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  484. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  485. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  486. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  487. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  488. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  489. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  490. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  491. package/fixtures/content-model-v2/site/.norna/generated-images.json +0 -210
  492. package/fixtures/content-model-v2/site/config.yaml +0 -1
  493. package/fixtures/content-model-v2/site/pages/000-home/content.md +0 -79
  494. package/fixtures/content-model-v2/site/pages/000-home/images/adopt.svg +0 -9
  495. package/fixtures/content-model-v2/site/pages/000-home/images/detail.jpg +0 -0
  496. package/fixtures/content-model-v2/site/pages/000-home/images/duplicate.jpg +0 -0
  497. package/fixtures/content-model-v2/site/pages/000-home/images/foster.svg +0 -12
  498. package/fixtures/content-model-v2/site/pages/000-home/images/hero.jpg +0 -0
  499. package/fixtures/content-model-v2/site/pages/000-home/images/image.jpg +0 -0
  500. package/fixtures/content-model-v2/site/pages/000-home/images/slide-one.jpg +0 -0
  501. package/fixtures/content-model-v2/site/pages/000-home/images/slide-three.jpg +0 -0
  502. package/fixtures/content-model-v2/site/pages/000-home/images/slide-two.jpg +0 -0
  503. package/fixtures/content-model-v2/site/pages/010-guide/content.md +0 -18
  504. package/fixtures/content-model-v2/site/pages/010-guide/images/duplicate.jpg +0 -0
  505. package/fixtures/content-model-v2/site/theme.yaml +0 -4
  506. package/fixtures/nested-pages/.astro/collections/site.schema.json +0 -35
  507. package/fixtures/nested-pages/.astro/collections/sitewide.schema.json +0 -97
  508. package/fixtures/nested-pages/.astro/collections/theme.schema.json +0 -844
  509. package/fixtures/nested-pages/.astro/content-assets.mjs +0 -4
  510. package/fixtures/nested-pages/.astro/content-modules.mjs +0 -1
  511. package/fixtures/nested-pages/.astro/content.d.ts +0 -183
  512. package/fixtures/nested-pages/.astro/data-store.json +0 -1
  513. package/fixtures/nested-pages/.astro/dev-local.json +0 -8
  514. package/fixtures/nested-pages/.astro/dev.log +0 -1128
  515. package/fixtures/nested-pages/.astro/settings.json +0 -5
  516. package/fixtures/nested-pages/.astro/types.d.ts +0 -2
  517. package/fixtures/nested-pages/node_modules/.vite/deps/_metadata.json +0 -74
  518. package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  519. package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  520. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  521. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  522. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  523. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  524. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  525. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  526. package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  527. package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  528. package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  529. package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  530. package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  531. package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  532. package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  533. package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  534. package/fixtures/nested-pages/node_modules/.vite/deps/package.json +0 -3
  535. package/fixtures/nested-pages/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  536. package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  537. package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  538. package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  539. package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  540. package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  541. package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  542. package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  543. package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  544. package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  545. package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  546. package/fixtures/nested-pages/site/.norna/generated-images.json +0 -10
  547. package/fixtures/nested-pages/site/config.yaml +0 -3
  548. package/fixtures/nested-pages/site/pages/000-home/content.md +0 -15
  549. package/fixtures/nested-pages/site/pages/010-guides/content.md +0 -15
  550. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/content.md +0 -21
  551. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/images/diagram.svg +0 -21
  552. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +0 -18
  553. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/theme.yaml +0 -2
  554. package/fixtures/nested-pages/site/pages/010-guides/pages/020-workflows/content.md +0 -11
  555. package/fixtures/nested-pages/site/pages/010-guides/pages/030-release-notes/content.md +0 -9
  556. package/fixtures/nested-pages/site/pages/010-guides/pages/040-configuration/content.md +0 -3
  557. package/fixtures/nested-pages/site/pages/010-guides/pages/050-content/content.md +0 -3
  558. package/fixtures/nested-pages/site/pages/010-guides/pages/060-themes/content.md +0 -3
  559. package/fixtures/nested-pages/site/pages/010-guides/pages/070-images/content.md +0 -3
  560. package/fixtures/nested-pages/site/pages/010-guides/pages/080-cards/content.md +0 -3
  561. package/fixtures/nested-pages/site/pages/010-guides/pages/090-notes/content.md +0 -3
  562. package/fixtures/nested-pages/site/pages/010-guides/pages/100-validation/content.md +0 -3
  563. package/fixtures/nested-pages/site/pages/010-guides/pages/110-synchronization/content.md +0 -3
  564. package/fixtures/nested-pages/site/pages/010-guides/pages/120-building/content.md +0 -3
  565. package/fixtures/nested-pages/site/pages/010-guides/pages/130-publishing/content.md +0 -3
  566. package/fixtures/nested-pages/site/pages/010-guides/pages/140-troubleshooting/content.md +0 -3
  567. package/fixtures/nested-pages/site/pages/010-guides/pages/150-migration/content.md +0 -3
  568. package/fixtures/nested-pages/site/pages/010-guides/pages/160-accessibility/content.md +0 -3
  569. package/fixtures/nested-pages/site/pages/010-guides/pages/170-performance/content.md +0 -3
  570. package/fixtures/nested-pages/site/pages/010-guides/pages/180-security/content.md +0 -3
  571. package/fixtures/nested-pages/site/pages/010-guides/pages/190-localization/content.md +0 -3
  572. package/fixtures/nested-pages/site/pages/010-guides/pages/200-upgrading/content.md +0 -3
  573. package/fixtures/nested-pages/site/pages/010-guides/pages/210-faq/content.md +0 -3
  574. package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +0 -7
  575. package/fixtures/nested-pages/site/pages/020-reference/content.md +0 -10
  576. package/fixtures/nested-pages/site/pages/020-reference/pages/010-installation/content.md +0 -11
  577. package/fixtures/nested-pages/site/theme.yaml +0 -1
  578. package/scripts/build-pages.mjs +0 -69
  579. package/scripts/lib/example-sites.mjs +0 -49
  580. package/scripts/lib/frontmatter-yaml.mjs +0 -113
  581. package/scripts/lib/git-status.mjs +0 -7
  582. package/scripts/release.mjs +0 -153
  583. package/scripts/test-banner-visibility.mjs +0 -80
  584. package/scripts/test-ci-lockfile.mjs +0 -65
  585. package/scripts/test-cli-discovery.mjs +0 -124
  586. package/scripts/test-client-javascript.mjs +0 -225
  587. package/scripts/test-content-check.mjs +0 -621
  588. package/scripts/test-content-model-v2.mjs +0 -1693
  589. package/scripts/test-documentation.mjs +0 -189
  590. package/scripts/test-editor-language-service.mjs +0 -305
  591. package/scripts/test-engine-commands.mjs +0 -204
  592. package/scripts/test-examples.mjs +0 -53
  593. package/scripts/test-heading-ids.mjs +0 -68
  594. package/scripts/test-navigation-model.mjs +0 -63
  595. package/scripts/test-navigation-preview.mjs +0 -108
  596. package/scripts/test-navigation.mjs +0 -157
  597. package/scripts/test-nested-pages.mjs +0 -125
  598. package/scripts/test-package-check.mjs +0 -500
  599. package/scripts/test-page-model.mjs +0 -108
  600. package/scripts/test-project-config.mjs +0 -139
  601. package/scripts/test-schemas.mjs +0 -169
  602. package/scripts/test-site-public.mjs +0 -85
  603. package/scripts/test-theme-presets.mjs +0 -188
  604. package/src/components/SiteNotesScript.astro +0 -43
  605. package/starters/project/.github/workflows/deploy.yml +0 -64
  606. package/starters/project/README.md +0 -84
  607. package/starters/project/package-lock.json +0 -4296
  608. package/starters/project/package.json +0 -37
  609. package/starters/project/site/config.yaml +0 -1
  610. package/starters/project/site/pages/000-home/content.md +0 -119
  611. package/starters/project/site/pages/010-guide/content.md +0 -80
  612. package/starters/project/site/public/robots.txt +0 -2
  613. package/starters/project/site/sitewide-content.yaml +0 -3
  614. package/starters/project/site/theme.yaml +0 -1
  615. package/tsconfig.json +0 -5
@@ -0,0 +1,182 @@
1
+ const getNodeRange = (node) => {
2
+ const start = node.position?.start.offset;
3
+ const end = node.position?.end.offset;
4
+ return Number.isInteger(start) && Number.isInteger(end)
5
+ ? { start, end }
6
+ : null;
7
+ };
8
+
9
+ const visitNodes = (node, visit) => {
10
+ if (!node || typeof node !== 'object') return;
11
+ visit(node);
12
+ if (!Array.isArray(node.children)) return;
13
+ for (const child of node.children) visitNodes(child, visit);
14
+ };
15
+
16
+ const scanDestination = (source, start, end) => {
17
+ let cursor = start;
18
+ while (cursor < end && /\s/.test(source[cursor] ?? '')) cursor += 1;
19
+
20
+ if (source[cursor] === '<') {
21
+ const targetStart = cursor + 1;
22
+ for (cursor = targetStart; cursor < end; cursor += 1) {
23
+ if (source[cursor] === '>' && source[cursor - 1] !== '\\') {
24
+ return { start: targetStart, end: cursor };
25
+ }
26
+ }
27
+ return null;
28
+ }
29
+
30
+ const targetStart = cursor;
31
+ let parenthesisDepth = 0;
32
+ let escaped = false;
33
+ for (; cursor < end; cursor += 1) {
34
+ const character = source[cursor] ?? '';
35
+ if (escaped) {
36
+ escaped = false;
37
+ continue;
38
+ }
39
+ if (character === '\\') {
40
+ escaped = true;
41
+ continue;
42
+ }
43
+ if (character === '(') {
44
+ parenthesisDepth += 1;
45
+ continue;
46
+ }
47
+ if (character === ')') {
48
+ if (parenthesisDepth === 0) break;
49
+ parenthesisDepth -= 1;
50
+ continue;
51
+ }
52
+ if (/\s/.test(character) && parenthesisDepth === 0) break;
53
+ }
54
+
55
+ return { start: targetStart, end: cursor };
56
+ };
57
+
58
+ const getInlineLinkTargetRange = (source, node) => {
59
+ const nodeRange = getNodeRange(node);
60
+ if (!nodeRange) return null;
61
+ const childEnd = Array.isArray(node.children)
62
+ ? Math.max(nodeRange.start, ...node.children.map((child) => child.position?.end.offset ?? nodeRange.start))
63
+ : nodeRange.start;
64
+ const delimiter = source.indexOf('](', childEnd);
65
+ if (delimiter < 0 || delimiter >= nodeRange.end) return null;
66
+ return scanDestination(source, delimiter + 2, nodeRange.end);
67
+ };
68
+
69
+ const getDefinitionTargetRange = (source, node) => {
70
+ const nodeRange = getNodeRange(node);
71
+ if (!nodeRange) return null;
72
+ const delimiter = source.indexOf(']:', nodeRange.start);
73
+ if (delimiter < 0 || delimiter >= nodeRange.end) return null;
74
+ return scanDestination(source, delimiter + 2, nodeRange.end);
75
+ };
76
+
77
+ const getSourceTarget = (source, range, fallback) => range
78
+ ? source.slice(range.start, range.end)
79
+ : fallback;
80
+
81
+ export const extractMarkdownLinks = ({ source, tree, lineOffset = 0 }) => {
82
+ const definitions = new Map();
83
+ visitNodes(tree, (node) => {
84
+ if (node.type !== 'definition') return;
85
+ definitions.set(node.identifier, node);
86
+ });
87
+
88
+ const links = [];
89
+ visitNodes(tree, (node) => {
90
+ if (node.type === 'link') {
91
+ const range = getNodeRange(node);
92
+ const targetRange = getInlineLinkTargetRange(source, node);
93
+ links.push({
94
+ kind: 'markdown-link',
95
+ column: node.position?.start.column ?? 1,
96
+ line: lineOffset + (node.position?.start.line ?? 1),
97
+ range,
98
+ target: node.url ?? '',
99
+ targetRange,
100
+ targetSource: getSourceTarget(source, targetRange, node.url ?? ''),
101
+ });
102
+ return;
103
+ }
104
+
105
+ if (node.type !== 'linkReference') return;
106
+ const definition = definitions.get(node.identifier);
107
+ if (!definition) return;
108
+ const targetRange = getDefinitionTargetRange(source, definition);
109
+ links.push({
110
+ kind: 'markdown-reference-link',
111
+ column: node.position?.start.column ?? 1,
112
+ definitionLine: lineOffset + (definition.position?.start.line ?? 1),
113
+ line: lineOffset + (node.position?.start.line ?? 1),
114
+ range: getNodeRange(node),
115
+ target: definition.url ?? '',
116
+ targetRange,
117
+ targetSource: getSourceTarget(source, targetRange, definition.url ?? ''),
118
+ });
119
+ });
120
+
121
+ return links;
122
+ };
123
+
124
+ const getLineOffsets = (source) => {
125
+ const offsets = [0];
126
+ for (let index = 0; index < source.length; index += 1) {
127
+ if (source[index] === '\n') offsets.push(index + 1);
128
+ }
129
+ return offsets;
130
+ };
131
+
132
+ const getCardLinkTargetRange = (source, lineStart) => {
133
+ const lineEnd = source.indexOf('\n', lineStart);
134
+ const end = lineEnd < 0 ? source.length : lineEnd;
135
+ const line = source.slice(lineStart, end);
136
+ const match = line.match(/^\s*link:\s*(.*?)\s*$/);
137
+ if (!match) return null;
138
+
139
+ const value = match[1] ?? '';
140
+ let valueStart = lineStart + (match.index ?? 0) + match[0].indexOf(value);
141
+ let valueEnd = valueStart + value.length;
142
+ if (
143
+ value.length >= 2
144
+ && (value[0] === '"' || value[0] === "'")
145
+ && value.at(-1) === value[0]
146
+ ) {
147
+ valueStart += 1;
148
+ valueEnd -= 1;
149
+ }
150
+
151
+ return { start: valueStart, end: valueEnd };
152
+ };
153
+
154
+ export const extractNornaBlockLinks = ({ source, blocks, lineOffset = 0 }) => {
155
+ const lineOffsets = getLineOffsets(source);
156
+ const links = [];
157
+
158
+ for (const block of blocks) {
159
+ if (block.type !== 'card-list') continue;
160
+ for (const card of block.cards) {
161
+ if (!card.link || !card.linkLine) continue;
162
+ const localLine = card.linkLine - lineOffset;
163
+ const lineStart = lineOffsets[localLine - 1];
164
+ const targetRange = Number.isInteger(lineStart)
165
+ ? getCardLinkTargetRange(source, lineStart)
166
+ : null;
167
+ links.push({
168
+ kind: 'card-link',
169
+ column: targetRange && Number.isInteger(lineStart)
170
+ ? targetRange.start - lineStart + 1
171
+ : 3,
172
+ line: card.linkLine,
173
+ range: targetRange,
174
+ target: card.link,
175
+ targetRange,
176
+ targetSource: getSourceTarget(source, targetRange, card.link),
177
+ });
178
+ }
179
+ }
180
+
181
+ return links;
182
+ };
@@ -13,39 +13,56 @@ const assertNavigationMode = (mode) => {
13
13
  return mode;
14
14
  };
15
15
 
16
- const getListedPages = (pages) => pages.filter((page) => page.isHome || page.listed !== false);
16
+ const getListedNodes = (nodes) => nodes.filter((node) => node.isHome || node.listed !== false);
17
17
 
18
- const getPageNavigationDepth = (page) => {
19
- const pageDepth = page.depth ?? 1;
20
- return (page.headings ?? []).reduce((maximum, heading) => (
21
- Math.max(maximum, pageDepth + heading.depth - 1)
22
- ), pageDepth);
18
+ const getNodeDepth = (node) => node.depth ?? 1;
19
+
20
+ const getTopLevelPagePath = (pagePath) => pagePath?.split('/')[0] ?? '';
21
+
22
+ const branchNeedsPageRail = (nodes, pagePath) => {
23
+ const rootPath = getTopLevelPagePath(pagePath);
24
+ if (!rootPath) return false;
25
+
26
+ return nodes.some((node) => (
27
+ (node.pagePath === rootPath && node.kind === 'category')
28
+ || node.pagePath?.startsWith(`${rootPath}/`)
29
+ ));
23
30
  };
24
31
 
25
- export const getAutomaticNavigationMode = (pages) => {
26
- const listedPages = getListedPages(pages);
27
- if (listedPages.length <= 1) return 'sections';
32
+ export const getAutomaticNavigationMode = (nodes, currentPage = null) => {
33
+ const listedNodes = getListedNodes(nodes);
34
+ if (listedNodes.length <= 1) return 'sections';
28
35
 
29
- const maximumDepth = listedPages.reduce((maximum, page) => (
30
- Math.max(maximum, getPageNavigationDepth(page))
31
- ), 1);
36
+ if (currentPage) {
37
+ if (currentPage.isHome) return 'top';
38
+ return branchNeedsPageRail(listedNodes, currentPage.pagePath) ? 'tree' : 'top';
39
+ }
32
40
 
33
- return maximumDepth <= 2 ? 'top' : 'tree';
41
+ return listedNodes.some((node) => node.kind === 'category' || getNodeDepth(node) > 1)
42
+ ? 'tree'
43
+ : 'top';
34
44
  };
35
45
 
36
- export const resolveNavigationModel = ({ mode = 'automatic', pages }) => {
46
+ export const resolveNavigationModel = ({ mode = 'automatic', nodes, currentPage = null }) => {
37
47
  const requestedMode = assertNavigationMode(mode);
38
- const listedPages = getListedPages(pages);
39
- const maximumDepth = listedPages.reduce((maximum, page) => (
40
- Math.max(maximum, getPageNavigationDepth(page))
48
+ const listedNodes = getListedNodes(nodes);
49
+ const hasCategories = listedNodes.some((node) => node.kind === 'category');
50
+ if (hasCategories && requestedMode !== 'automatic' && requestedMode !== 'tree') {
51
+ throw new Error(`Navigation categories require tree navigation. Remove navigation.mode: ${requestedMode}, or set navigation.mode: tree.`);
52
+ }
53
+ const maximumDepth = listedNodes.reduce((maximum, node) => (
54
+ Math.max(maximum, getNodeDepth(node))
41
55
  ), 1);
56
+ const hasNestedPages = listedNodes.some((node) => getNodeDepth(node) > 1);
42
57
 
43
58
  return Object.freeze({
44
59
  mode: requestedMode === 'automatic'
45
- ? getAutomaticNavigationMode(listedPages)
60
+ ? getAutomaticNavigationMode(listedNodes, currentPage)
46
61
  : requestedMode,
47
62
  requestedMode,
48
- listedPageCount: listedPages.length,
63
+ listedNodeCount: listedNodes.length,
64
+ hasCategories,
65
+ hasNestedPages,
49
66
  maximumDepth,
50
67
  });
51
68
  };
@@ -1,4 +1,3 @@
1
- import { Buffer } from 'node:buffer';
2
1
  import { documentationLink } from './documentation-links.mjs';
3
2
 
4
3
  const field = (description, options = {}) => Object.freeze({ description, ...options });
@@ -55,13 +54,12 @@ export const nornaMarkdownBlockDefinitions = Object.freeze({
55
54
  xl: value('Extra large', 'Use the largest card and image size.'),
56
55
  }),
57
56
  }),
58
- width: field('Limit the width of the complete card list. Defaults to normal.', {
59
- default: 'normal',
57
+ width: field('Override the root theme\'s maximum width for this card list.', {
60
58
  values: Object.freeze({
61
- text: value('Text', 'Match the active body-text width.'),
62
- narrow: value('Narrow', 'Use a narrow card-list width.'),
63
- normal: value('Normal', 'Use the balanced default card-list width.'),
64
- wide: value('Wide', 'Allow the card list to use more horizontal space.'),
59
+ text: value('Text', 'Match the active body-text width, including a reader-selected reading width.'),
60
+ narrow: value('Narrow', 'Limit the complete card list to at most 48rem.'),
61
+ normal: value('Normal', 'Limit the complete card list to at most 56rem.'),
62
+ wide: value('Wide', 'Allow the complete card list to use the available page-layout width.'),
65
63
  }),
66
64
  }),
67
65
  }),
@@ -87,7 +85,6 @@ const blockTypeLabels = {
87
85
 
88
86
  const knownBlockTypeList = Array.from(nornaBlockTypes).join(', ');
89
87
  const imageNameRegex = /^[a-z0-9][a-z0-9.-]*\.(jpe?g|png|svg)$/i;
90
- const markerTagName = 'norna-block';
91
88
  const imageStackExample = [
92
89
  '```norna-image-stack',
93
90
  '- image: filename.jpg',
@@ -98,7 +95,6 @@ const cardListExample = [
98
95
  'layout: image-top',
99
96
  'flow: grid',
100
97
  'size: m',
101
- 'width: normal',
102
98
  '',
103
99
  '- title: Adopt',
104
100
  ' text: Give a dog a new home.',
@@ -203,6 +199,35 @@ const getFenceCloseInfo = (line, opening) => {
203
199
  return fence;
204
200
  };
205
201
 
202
+ export const getOpenMarkdownFenceAtLine = (markdown, lineIndex) => {
203
+ const lines = normalizeLines(markdown);
204
+ let open = null;
205
+
206
+ for (let index = 0; index <= Math.min(lineIndex, lines.length - 1); index += 1) {
207
+ const fence = getFenceInfo(lines[index]);
208
+ if (!fence || fence.length < 3) continue;
209
+
210
+ if (!open) {
211
+ open = {
212
+ character: fence.markerCharacter,
213
+ length: fence.length,
214
+ line: index,
215
+ type: fence.info.split(/\s+/)[0] ?? '',
216
+ };
217
+ continue;
218
+ }
219
+
220
+ if (getFenceCloseInfo(lines[index], {
221
+ length: open.length,
222
+ markerCharacter: open.character,
223
+ })) {
224
+ open = null;
225
+ }
226
+ }
227
+
228
+ return open;
229
+ };
230
+
206
231
  const getNornaLineAttempt = (line) => {
207
232
  const match = line.match(/^ {0,3}([`~]{0,2})(norna-[a-z0-9-]+)\s*$/);
208
233
  if (!match) return null;
@@ -226,7 +251,14 @@ const getUnclosedNornaBlockMessage = (opening) =>
226
251
  `This Norna block was started on line ${opening.line} but not closed. Add a closing ${opening.markerCharacter.repeat(opening.length)} line after the last entry.`;
227
252
 
228
253
  const scanMarkdownFencedBlocks = (markdown, options = {}) => {
229
- const lines = normalizeLines(markdown);
254
+ const normalizedMarkdown = markdown.replace(/\r\n?/g, '\n');
255
+ const lines = normalizedMarkdown.split('\n');
256
+ const lineOffsets = [];
257
+ let nextLineOffset = 0;
258
+ for (const line of lines) {
259
+ lineOffsets.push(nextLineOffset);
260
+ nextLineOffset += line.length + 1;
261
+ }
230
262
  const lineOffset = options.lineOffset ?? 0;
231
263
  const blocks = [];
232
264
  const errors = [];
@@ -242,6 +274,7 @@ const scanMarkdownFencedBlocks = (markdown, options = {}) => {
242
274
  if (attempt) {
243
275
  errors.push({
244
276
  blockType: attempt.type,
277
+ code: 'invalid-norna-block-start',
245
278
  line: lineNumber,
246
279
  source: '',
247
280
  message: failMessage(getNornaFenceStartMessage(attempt.type, attempt.marker), { ...options, line: lineNumber }),
@@ -257,6 +290,7 @@ const scanMarkdownFencedBlocks = (markdown, options = {}) => {
257
290
  if (attempt) {
258
291
  errors.push({
259
292
  blockType: attempt.type,
293
+ code: 'invalid-norna-block-start',
260
294
  line: lineNumber,
261
295
  source: '',
262
296
  message: failMessage(getNornaFenceStartMessage(attempt.type, attempt.marker), { ...options, line: lineNumber }),
@@ -288,7 +322,10 @@ const scanMarkdownFencedBlocks = (markdown, options = {}) => {
288
322
  if (isNornaLike) {
289
323
  errors.push({
290
324
  blockType: type,
325
+ code: 'unclosed-norna-block',
326
+ endOffset: normalizedMarkdown.length,
291
327
  line: lineNumber,
328
+ startOffset: lineOffsets[index],
292
329
  source: lines.slice(bodyStartIndex).join('\n'),
293
330
  message: failMessage(getUnclosedNornaBlockMessage(opening), { ...options, line: lineNumber }),
294
331
  });
@@ -301,13 +338,19 @@ const scanMarkdownFencedBlocks = (markdown, options = {}) => {
301
338
  if (nornaBlockTypes.has(type)) {
302
339
  blocks.push({
303
340
  blockType: type,
341
+ endLine: lineOffset + closingIndex + 1,
342
+ endOffset: lineOffsets[closingIndex] + lines[closingIndex].length,
304
343
  line: lineNumber,
344
+ startOffset: lineOffsets[index],
305
345
  source,
346
+ sourceEndOffset: lineOffsets[closingIndex],
306
347
  sourceLine: lineNumber + 1,
348
+ sourceStartOffset: lineOffsets[bodyStartIndex],
307
349
  });
308
350
  } else {
309
351
  errors.push({
310
352
  blockType: type,
353
+ code: 'unknown-norna-block',
311
354
  line: lineNumber,
312
355
  source,
313
356
  message: failMessage(getUnknownNornaBlockMessage(type), { ...options, line: lineNumber }),
@@ -337,7 +380,7 @@ const parseImageListBlock = (source, options = {}) => {
337
380
  const lineNumber = (options.line ?? 1) + index;
338
381
  const itemMatch = line.match(/^(\s*)-\s+image:\s*(.*?)\s*$/);
339
382
  if (itemMatch) {
340
- current = { image: decodeScalar(itemMatch[2]) };
383
+ current = { image: decodeScalar(itemMatch[2]), line: lineNumber };
341
384
  images.push(current);
342
385
  continue;
343
386
  }
@@ -375,7 +418,7 @@ const parseCardListBlock = (source, options = {}) => {
375
418
  let layout = cardListDefinition.options.layout.default;
376
419
  let flow = cardListDefinition.options.flow.default;
377
420
  let size = cardListDefinition.options.size.default;
378
- let width = cardListDefinition.options.width.default;
421
+ let width;
379
422
  let current = null;
380
423
 
381
424
  for (const [index, line] of normalizeLines(source).entries()) {
@@ -384,7 +427,7 @@ const parseCardListBlock = (source, options = {}) => {
384
427
  const lineNumber = (options.line ?? 1) + index;
385
428
  const itemMatch = line.match(/^(\s*)-\s+title:\s*(.*?)\s*$/);
386
429
  if (itemMatch) {
387
- current = { title: decodeScalar(itemMatch[2]) };
430
+ current = { title: decodeScalar(itemMatch[2]), line: lineNumber };
388
431
  cards.push(current);
389
432
  continue;
390
433
  }
@@ -452,6 +495,7 @@ const parseCardListBlock = (source, options = {}) => {
452
495
  }
453
496
 
454
497
  current[entry.key] = entry.value;
498
+ if (entry.key === 'link') current.linkLine = lineNumber;
455
499
  }
456
500
 
457
501
  for (const card of cards) {
@@ -486,26 +530,6 @@ export const parseNornaMarkdownBlock = (type, source, options = {}) => {
486
530
 
487
531
  const getLineNumber = (source, index) => source.slice(0, index).split(/\r?\n/).length;
488
532
 
489
- export const extractNornaMarkdownBlocks = (markdown, options = {}) => {
490
- const blocks = [];
491
- const { blocks: scannedBlocks, errors } = scanMarkdownFencedBlocks(markdown, options);
492
-
493
- if (errors.length > 0) {
494
- throw new Error(errors[0].message);
495
- }
496
-
497
- for (const block of scannedBlocks) {
498
- blocks.push({
499
- ...parseNornaMarkdownBlock(block.blockType, block.source, { ...options, line: block.sourceLine }),
500
- blockType: block.blockType,
501
- line: block.line,
502
- source: block.source,
503
- });
504
- }
505
-
506
- return blocks;
507
- };
508
-
509
533
  export const extractNornaMarkdownBlockDiagnostics = (markdown, options = {}) => {
510
534
  const blocks = [];
511
535
  const { blocks: scannedBlocks, errors } = scanMarkdownFencedBlocks(markdown, options);
@@ -515,12 +539,18 @@ export const extractNornaMarkdownBlockDiagnostics = (markdown, options = {}) =>
515
539
  blocks.push({
516
540
  ...parseNornaMarkdownBlock(block.blockType, block.source, { ...options, line: block.sourceLine }),
517
541
  blockType: block.blockType,
542
+ endLine: block.endLine,
543
+ endOffset: block.endOffset,
518
544
  line: block.line,
545
+ startOffset: block.startOffset,
519
546
  source: block.source,
547
+ sourceEndOffset: block.sourceEndOffset,
548
+ sourceStartOffset: block.sourceStartOffset,
520
549
  });
521
550
  } catch (error) {
522
551
  errors.push({
523
552
  blockType: block.blockType,
553
+ code: 'invalid-norna-block',
524
554
  line: block.line,
525
555
  source: block.source,
526
556
  message: error instanceof Error ? error.message : String(error),
@@ -570,18 +600,6 @@ const maskFencedCodeBlocks = (markdown) => {
570
600
  const isExternalImageTarget = (target) => /^[a-z][a-z0-9+.-]*:/i.test(target) || target.startsWith('//');
571
601
  const isRootRelativePublicTarget = (target) => target.startsWith('/');
572
602
 
573
- const stripTags = (value) => value.replace(/<[^>]*>/g, '');
574
-
575
- const decodeHtmlEntities = (value) =>
576
- value
577
- .replace(/&amp;/g, '&')
578
- .replace(/&lt;/g, '<')
579
- .replace(/&gt;/g, '>')
580
- .replace(/&quot;/g, '"')
581
- .replace(/&#39;/g, "'")
582
- .replace(/&#x([0-9a-f]+);/gi, (_match, hex) => String.fromCodePoint(Number.parseInt(hex, 16)))
583
- .replace(/&#(\d+);/g, (_match, decimal) => String.fromCodePoint(Number.parseInt(decimal, 10)));
584
-
585
603
  export const extractMarkdownImageReferences = (markdown) => {
586
604
  const masked = maskFencedCodeBlocks(markdown);
587
605
  const references = [];
@@ -610,7 +628,7 @@ export const getNornaBlockImageReferences = (blocks) =>
610
628
  alt: card.title,
611
629
  blockType: block.blockType,
612
630
  blockDisplayType: block.type,
613
- line: block.line,
631
+ line: card.line ?? block.line,
614
632
  }));
615
633
  }
616
634
 
@@ -618,54 +636,10 @@ export const getNornaBlockImageReferences = (blocks) =>
618
636
  ...image,
619
637
  blockType: block.blockType,
620
638
  blockDisplayType: block.type,
621
- line: block.line,
639
+ line: image.line ?? block.line,
622
640
  }));
623
641
  });
624
642
 
625
- export const createNornaMarkdownBlockMarker = (type, source) => {
626
- const encodedSource = Buffer.from(source, 'utf8').toString('base64');
627
- return `<${markerTagName} data-type="${type}" data-source="${encodedSource}"></${markerTagName}>`;
628
- };
629
-
630
- export const splitNornaMarkdownBlockMarkers = (html, options = {}) => {
631
- const blocks = [];
632
- const markerRegex = /<norna-block\s+data-type="([^"]+)"\s+data-source="([^"]*)"\s*><\/norna-block>|<pre\b([^>]*)>\s*<code\b([^>]*)>([\s\S]*?)<\/code>\s*<\/pre>/g;
633
- let cursor = 0;
634
-
635
- for (const match of html.matchAll(markerRegex)) {
636
- const start = match.index ?? 0;
637
- if (start > cursor) {
638
- blocks.push({ type: 'html', html: html.slice(cursor, start) });
639
- }
640
-
641
- if (match[1]) {
642
- const blockType = match[1];
643
- const source = Buffer.from(match[2] ?? '', 'base64').toString('utf8');
644
- blocks.push(parseNornaMarkdownBlock(blockType, source, options));
645
- } else {
646
- const attributes = `${match[3] ?? ''} ${match[4] ?? ''}`;
647
- const blockType = attributes.match(/\blanguage-(norna-[a-z0-9-]+)\b/)?.[1]
648
- ?? attributes.match(/\bdata-language="(norna-[a-z0-9-]+)"/)?.[1];
649
- if (!nornaBlockTypes.has(blockType)) {
650
- blocks.push({ type: 'html', html: match[0] });
651
- } else {
652
- const source = decodeHtmlEntities(stripTags(match[5] ?? ''));
653
- blocks.push(parseNornaMarkdownBlock(blockType, source, options));
654
- }
655
- }
656
-
657
- cursor = start + match[0].length;
658
- }
659
-
660
- if (cursor < html.length) {
661
- blocks.push({ type: 'html', html: html.slice(cursor) });
662
- }
663
-
664
- return blocks.filter((block) => block.type !== 'html' || block.html.trim());
665
- };
666
-
667
- const normalizeBlockSource = (source) => source.replace(/\r\n?/g, '\n').trim();
668
-
669
643
  const inlineNoteReferenceRegex = /\{note-ref\}/g;
670
644
  const inlineNoteDeclarationOpeningRegex = /^\s*\{note:\s*(.*)$/;
671
645
  const inlineNoteDeclarationClosingRegex = /^(.*?)\}\s*$/;
@@ -918,57 +892,3 @@ export const extractInlineNoteDiagnostics = (markdown, options = {}) => {
918
892
 
919
893
  return { notes, errors };
920
894
  };
921
-
922
- export const splitNornaRenderedCodeBlocks = (html, rawBlocks, options = {}) => {
923
- const blocks = [];
924
- const renderedCodeRegex = /<pre\b[^>]*>\s*<code\b[^>]*>([\s\S]*?)<\/code>\s*<\/pre>/g;
925
- let cursor = 0;
926
- let rawIndex = 0;
927
-
928
- for (const match of html.matchAll(renderedCodeRegex)) {
929
- const start = match.index ?? 0;
930
- if (start > cursor) {
931
- blocks.push({ type: 'html', html: html.slice(cursor, start) });
932
- }
933
-
934
- const rawBlock = rawBlocks[rawIndex];
935
- const renderedSource = normalizeBlockSource(decodeHtmlEntities(stripTags(match[1] ?? '')));
936
- const rawSource = normalizeBlockSource(rawBlock?.source ?? '');
937
-
938
- if (rawBlock && renderedSource === rawSource) {
939
- blocks.push(parseNornaMarkdownBlock(rawBlock.blockType, rawBlock.source, options));
940
- rawIndex += 1;
941
- } else {
942
- blocks.push({ type: 'html', html: match[0] });
943
- }
944
-
945
- cursor = start + match[0].length;
946
- }
947
-
948
- if (cursor < html.length) {
949
- blocks.push({ type: 'html', html: html.slice(cursor) });
950
- }
951
-
952
- return blocks.filter((block) => block.type !== 'html' || block.html.trim());
953
- };
954
-
955
- const visitCodeBlocks = (node) => {
956
- if (!node || typeof node !== 'object') return;
957
-
958
- if (Array.isArray(node.children)) {
959
- for (const child of node.children) {
960
- visitCodeBlocks(child);
961
- }
962
- }
963
-
964
- if (node.type !== 'code' || !nornaBlockTypes.has(node.lang)) return;
965
-
966
- node.type = 'html';
967
- node.value = createNornaMarkdownBlockMarker(node.lang, node.value ?? '');
968
- delete node.lang;
969
- delete node.meta;
970
- };
971
-
972
- export const nornaMarkdownBlocksRemarkPlugin = () => (tree) => {
973
- visitCodeBlocks(tree);
974
- };
@@ -0,0 +1,37 @@
1
+ import { defineMdastPlugin } from 'satteri';
2
+ import { nornaBlockTypes } from './norna-markdown-blocks.mjs';
3
+
4
+ const stateKey = 'nornaMarkdownRender';
5
+
6
+ const getState = (context) => {
7
+ if (!context.data[stateKey]) {
8
+ context.data[stateKey] = { blockIndex: 0, regionIndex: 0 };
9
+ }
10
+ return context.data[stateKey];
11
+ };
12
+
13
+ export const nornaMarkdownRenderPlugin = defineMdastPlugin({
14
+ name: 'norna-markdown-render',
15
+ code(node, context) {
16
+ if (!nornaBlockTypes.has(node.lang)) return;
17
+
18
+ const state = getState(context);
19
+ const blockIndex = state.blockIndex;
20
+ state.blockIndex += 1;
21
+ context.replaceNode(node, {
22
+ type: 'html',
23
+ value: `<norna-block data-index="${blockIndex}"></norna-block>`,
24
+ });
25
+ },
26
+ heading(node, context) {
27
+ if (node.depth !== 1 && node.depth !== 2) return;
28
+ const state = getState(context);
29
+ const regionIndex = state.regionIndex;
30
+ state.blockIndex = 0;
31
+ state.regionIndex += 1;
32
+ context.replaceNode(node, {
33
+ type: 'html',
34
+ value: `<norna-region data-index="${regionIndex}"></norna-region>`,
35
+ });
36
+ },
37
+ });
@@ -0,0 +1,28 @@
1
+ export const isPlainObject = (value) => (
2
+ value !== null
3
+ && typeof value === 'object'
4
+ && !Array.isArray(value)
5
+ );
6
+
7
+ export const freezeDeep = (value) => {
8
+ if (value === null || typeof value !== 'object' || Object.isFrozen(value)) return value;
9
+
10
+ for (const child of Object.values(value)) freezeDeep(child);
11
+ return Object.freeze(value);
12
+ };
13
+
14
+ export const mergeDeep = (base, override) => {
15
+ if (!isPlainObject(override)) return structuredClone(base);
16
+
17
+ const merged = structuredClone(base);
18
+
19
+ for (const [key, value] of Object.entries(override)) {
20
+ if (isPlainObject(value) && isPlainObject(merged[key])) {
21
+ merged[key] = mergeDeep(merged[key], value);
22
+ } else if (value !== undefined) {
23
+ merged[key] = value;
24
+ }
25
+ }
26
+
27
+ return merged;
28
+ };