@janga/norna 0.7.23 → 0.7.25

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 (82) hide show
  1. package/README.md +14 -18
  2. package/astro.config.mjs +14 -0
  3. package/bin/norna-cli.mjs +6 -0
  4. package/package.json +25 -2
  5. package/schemas/category.schema.json +2 -2
  6. package/schemas/config.schema.json +80 -15
  7. package/schemas/content-frontmatter.schema.json +7 -7
  8. package/schemas/page-theme.schema.json +26 -26
  9. package/schemas/sitewide-content.schema.json +18 -18
  10. package/schemas/theme.schema.json +246 -246
  11. package/scripts/build-site.mjs +1 -0
  12. package/scripts/check-config.mjs +16 -1
  13. package/scripts/dev-local.mjs +106 -11
  14. package/scripts/generate-search-index.mjs +57 -0
  15. package/scripts/init-site.mjs +3 -0
  16. package/scripts/lib/code-fence-metadata.mjs +228 -0
  17. package/scripts/lib/edit-source-link.mjs +102 -0
  18. package/scripts/lib/editor-language-service.mjs +32 -12
  19. package/scripts/lib/image-presentation.mjs +4 -0
  20. package/scripts/lib/navigation-model.mjs +34 -13
  21. package/scripts/lib/navigation-review.mjs +396 -0
  22. package/scripts/lib/norna-markdown-blocks.mjs +164 -26
  23. package/scripts/lib/norna-markdown-render-plugin.mjs +64 -1
  24. package/scripts/lib/page-aliases.mjs +21 -1
  25. package/scripts/lib/page-markdown.mjs +32 -1
  26. package/scripts/lib/page-move-plan.mjs +659 -0
  27. package/scripts/lib/presentation-palette-metadata.mjs +1 -1
  28. package/scripts/lib/presentation.mjs +1 -10
  29. package/scripts/lib/project-config.mjs +141 -5
  30. package/scripts/lib/public-asset-conventions.mjs +36 -2
  31. package/scripts/lib/schema-definitions.mjs +30 -5
  32. package/scripts/lib/schema-editor-metadata.mjs +36 -4
  33. package/scripts/lib/schema-value-definitions.mjs +4 -1
  34. package/scripts/lib/semantic-callouts.mjs +128 -0
  35. package/scripts/lib/site-content.mjs +2 -1
  36. package/scripts/lib/site-link-graph.mjs +33 -2
  37. package/scripts/lib/site-navigation-tree.mjs +85 -0
  38. package/scripts/lib/site-paths.mjs +14 -2
  39. package/scripts/lib/social-image-assets.mjs +30 -0
  40. package/scripts/lib/table-render-plugin.mjs +33 -0
  41. package/scripts/lib/theme-presets.mjs +2 -2
  42. package/scripts/lib/theme-profiles.mjs +0 -4
  43. package/scripts/move-site-page.mjs +256 -0
  44. package/scripts/review-navigation.mjs +32 -0
  45. package/scripts/sync-content-sections.mjs +67 -4
  46. package/scripts/sync-site-public.mjs +24 -5
  47. package/src/components/CardList.astro +1 -0
  48. package/src/components/CodeBlockCopyScript.astro +11 -5
  49. package/src/components/EditSourceLink.astro +17 -0
  50. package/src/components/ImageCarousel.astro +9 -7
  51. package/src/components/ImageStack.astro +34 -9
  52. package/src/components/ImageStackEnhancement.astro +331 -0
  53. package/src/components/NavigationPageTree.astro +66 -55
  54. package/src/components/NavigationTreeControls.astro +77 -0
  55. package/src/components/PageAliasRedirect.astro +1 -1
  56. package/src/components/PageContentsNavigation.astro +2 -3
  57. package/src/components/PageList.astro +33 -0
  58. package/src/components/PageSequenceNavigation.astro +37 -0
  59. package/src/components/SearchPage.astro +151 -0
  60. package/src/components/SectionNavigationScript.astro +45 -7
  61. package/src/components/SiteNavigation.astro +102 -51
  62. package/src/components/SitePage.astro +107 -39
  63. package/src/components/SiteSection.astro +11 -3
  64. package/src/components/SiteTreeNavigation.astro +11 -1
  65. package/src/components/TableOverflowScript.astro +251 -0
  66. package/src/components/TreeNavigationScript.astro +271 -34
  67. package/src/layouts/BaseLayout.astro +83 -2
  68. package/src/lib/generatedImages.ts +18 -0
  69. package/src/lib/sectionContent.ts +36 -30
  70. package/src/lib/siteNavigation.ts +31 -52
  71. package/src/lib/sitePages.ts +6 -3
  72. package/src/lib/sitePublicAssets.ts +1 -0
  73. package/src/pages/404.astro +110 -0
  74. package/src/pages/[...slug].astro +15 -5
  75. package/src/styles/content.css +538 -39
  76. package/src/styles/media.css +187 -8
  77. package/src/styles/navigation.css +199 -3
  78. package/src/styles/page-layout.css +481 -100
  79. package/src/styles/responsive.css +144 -28
  80. package/starters/basic/README.md +6 -19
  81. package/starters/basic/package.json +1 -0
  82. package/starters/basic/site/pages/000-home/content.md +13 -50
package/README.md CHANGED
@@ -76,8 +76,8 @@ site/
76
76
  - `theme.yaml` normally selects one complete visual preset.
77
77
  - `sitewide-content.yaml` holds shared logo display settings, banners, and
78
78
  footer content.
79
- - `config.yaml` holds the public URL and optional language, navigation model,
80
- and scroll behavior.
79
+ - `config.yaml` holds the public URL and optional language, local and remote
80
+ source links, navigation model, static search, and scroll behavior.
81
81
  - `public/` holds static files copied without processing.
82
82
 
83
83
  Norna validates this structure, processes managed images when needed, and
@@ -93,26 +93,22 @@ builds the generated website into `dist/`.
93
93
  reviewed, versioned, and edited with the tools you already use.
94
94
  - **A complete publishing path.** The starter includes validation, static
95
95
  builds, and an integrated GitHub Pages workflow.
96
+ - **Static search without a service.** One optional setting indexes the
97
+ completed pages and adds section-level search results.
96
98
 
97
99
  ## Examples
98
100
 
99
101
  Every example is built in the repository test suite and published with the
100
- documentation.
101
-
102
- | Example | Live site | Source |
103
- | --- | --- | --- |
104
- | Theme explorer | [Combine presets and palettes](https://janga.github.io/norna/examples/theme-presets/) | See the four preset sources below |
105
- | Dog shelter, single page | [Open demo](https://janga.github.io/norna/examples/complete-sites/dog-shelter-single-page/) | [View files](examples/complete-sites/dog-shelter-single-page/) |
106
- | Dog shelter, multi-page | [Open demo](https://janga.github.io/norna/examples/complete-sites/dog-shelter-multi-page/) | [View files](examples/complete-sites/dog-shelter-multi-page/) |
107
- | Portfolio preset | [Open demo](https://janga.github.io/norna/examples/feature-demos/theme-preset-portfolio/) | [View files](examples/feature-demos/theme-preset-portfolio/) |
108
- | Documentation preset | [Open demo](https://janga.github.io/norna/examples/feature-demos/theme-preset-documentation/) | [View files](examples/feature-demos/theme-preset-documentation/) |
109
- | Project preset | [Open demo](https://janga.github.io/norna/examples/feature-demos/theme-preset-project/) | [View files](examples/feature-demos/theme-preset-project/) |
110
- | Statement preset | [Open demo](https://janga.github.io/norna/examples/feature-demos/theme-preset-statement/) | [View files](examples/feature-demos/theme-preset-statement/) |
111
- | Media and surfaces | [Open demo](https://janga.github.io/norna/examples/feature-demos/media-and-surfaces/) | [View files](examples/feature-demos/media-and-surfaces/) |
112
- | Sitewide content | [Open demo](https://janga.github.io/norna/examples/feature-demos/sitewide-content/) | [View files](examples/feature-demos/sitewide-content/) |
113
-
114
- See [examples/README.md](examples/README.md) for what each example is intended
115
- to demonstrate and how to run it locally.
102
+ documentation. Start with the
103
+ [single-page](https://janga.github.io/norna/examples/complete-sites/dog-shelter-single-page/)
104
+ and [multi-page](https://janga.github.io/norna/examples/complete-sites/dog-shelter-multi-page/)
105
+ dog-shelter sites to inspect complete projects. Use the
106
+ [Theme explorer](https://janga.github.io/norna/examples/theme-presets/) to
107
+ compare presets and palettes against unchanged representative content.
108
+
109
+ The [example source index](examples/README.md) describes every maintained
110
+ complete site and feature demonstration, links its live result, and shows how
111
+ to run it locally.
116
112
 
117
113
  ## Is Norna A Good Fit?
118
114
 
package/astro.config.mjs CHANGED
@@ -5,7 +5,9 @@ import { promisify } from 'node:util';
5
5
  import { defineConfig } from 'astro/config';
6
6
  import { satteri } from '@astrojs/markdown-satteri';
7
7
  import { getBasePathRedirectLocation } from './scripts/lib/base-path-redirect.mjs';
8
+ import { nornaCodeFenceTransformer } from './scripts/lib/code-fence-metadata.mjs';
8
9
  import { nornaMarkdownRenderPlugin } from './scripts/lib/norna-markdown-render-plugin.mjs';
10
+ import { nornaTableRenderPlugin } from './scripts/lib/table-render-plugin.mjs';
9
11
  import {
10
12
  astroCacheDir,
11
13
  astroDistDir,
@@ -136,8 +138,20 @@ export default defineConfig({
136
138
  base: projectConfig.site.basePath,
137
139
  cacheDir: astroCacheDir,
138
140
  markdown: {
141
+ shikiConfig: {
142
+ transformers: [nornaCodeFenceTransformer],
143
+ },
139
144
  processor: satteri({
145
+ features: {
146
+ gfm: {
147
+ footnotes: {
148
+ label: projectConfig.locale.labels.footnotes,
149
+ backLabel: projectConfig.locale.labels.footnoteBackReference,
150
+ },
151
+ },
152
+ },
140
153
  mdastPlugins: [nornaMarkdownRenderPlugin],
154
+ hastPlugins: [nornaTableRenderPlugin],
141
155
  }),
142
156
  },
143
157
  outDir: astroDistDir,
package/bin/norna-cli.mjs CHANGED
@@ -18,6 +18,7 @@ Commands:
18
18
  config:check Validate site/config.yaml
19
19
  content:check Validate page content and managed image references
20
20
  content:sync Move misplaced Norna-managed images and refresh generated images
21
+ navigation:review Review the derived navigation structure without changing files
21
22
  theme:presets List available theme presets and their intended uses
22
23
  theme:export Export a commented theme preset reference
23
24
  typography profiles Show built-in typography profile values
@@ -28,6 +29,7 @@ Commands:
28
29
  engine:version Show installed engine and Astro versions
29
30
  init Create a new site project from the starter
30
31
  page:add Add a page to the site page tree
32
+ page:move Move a page subtree and update internal links
31
33
  category:add Add a non-routable category to the site page tree
32
34
  build Build the selected site
33
35
  build:local Build and restart local dev server
@@ -139,6 +141,8 @@ try {
139
141
  } else if (command === 'content:sync') {
140
142
  await runScript('scripts/sync-content-sections.mjs', ['--write', ...rest]);
141
143
  await runScript('scripts/generate-images.mjs', rest);
144
+ } else if (command === 'navigation:review') {
145
+ await runScript('scripts/review-navigation.mjs', rest);
142
146
  } else if (command === 'theme:presets') {
143
147
  await runScript('scripts/list-theme-presets.mjs', rest);
144
148
  } else if (command === 'theme:export') {
@@ -163,6 +167,8 @@ try {
163
167
  await runScript('scripts/init-site.mjs', rest);
164
168
  } else if (command === 'page:add') {
165
169
  await runScript('scripts/add-site-node.mjs', ['page', ...rest]);
170
+ } else if (command === 'page:move') {
171
+ await runScript('scripts/move-site-page.mjs', rest);
166
172
  } else if (command === 'category:add') {
167
173
  await runScript('scripts/add-site-node.mjs', ['category', ...rest]);
168
174
  } else if (command === 'build') {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@janga/norna",
3
3
  "description": "An opinionated CLI for building responsive websites from Markdown, images, and theme presets.",
4
4
  "type": "module",
5
- "version": "0.7.23",
5
+ "version": "0.7.25",
6
6
  "license": "GPL-3.0-only",
7
7
  "repository": {
8
8
  "type": "git",
@@ -42,12 +42,15 @@
42
42
  "scripts/export-theme-preset.mjs",
43
43
  "scripts/generate-images.mjs",
44
44
  "scripts/generate-schemas.mjs",
45
+ "scripts/generate-search-index.mjs",
45
46
  "scripts/init-site.mjs",
46
47
  "scripts/lib/",
47
48
  "!scripts/lib/documentation-preset-candidates.mjs",
48
49
  "!scripts/lib/example-sites.mjs",
49
50
  "!scripts/lib/git-status.mjs",
50
51
  "scripts/list-theme-presets.mjs",
52
+ "scripts/move-site-page.mjs",
53
+ "scripts/review-navigation.mjs",
51
54
  "scripts/show-typography.mjs",
52
55
  "scripts/sync-content-sections.mjs",
53
56
  "scripts/sync-site-public.mjs",
@@ -69,9 +72,17 @@
69
72
  "dev:status": "node bin/norna.mjs dev:status",
70
73
  "dev:logs": "node bin/norna.mjs dev:logs",
71
74
  "dev:stop": "node bin/norna.mjs dev:stop",
75
+ "review:start": "node scripts/review-environments.mjs start",
76
+ "review:status": "node scripts/review-environments.mjs status",
77
+ "review:logs": "node scripts/review-environments.mjs logs",
78
+ "review:stop": "node scripts/review-environments.mjs stop",
79
+ "review:test": "node scripts/review-environments.mjs test",
80
+ "review:capture": "node scripts/review-environments.mjs capture",
81
+ "review:scratch": "node scripts/review-environments.mjs scratch",
72
82
  "config:check": "node bin/norna.mjs config:check",
73
83
  "content:check": "node bin/norna.mjs content:check",
74
84
  "content:sync": "node bin/norna.mjs content:sync",
85
+ "navigation:review": "node bin/norna.mjs navigation:review",
75
86
  "theme:presets": "node bin/norna.mjs theme:presets",
76
87
  "theme:export": "node bin/norna.mjs theme:export",
77
88
  "typography:profiles": "node bin/norna.mjs typography profiles",
@@ -88,7 +99,7 @@
88
99
  "deploy:watch": "node bin/norna.mjs deploy:watch",
89
100
  "doctor": "node bin/norna.mjs doctor",
90
101
  "demo:build": "node scripts/build-demo.mjs",
91
- "test": "npm run schemas:check && npm run test:dead-code && npm run test:schemas && npm run test:page-model && npm run test:page-markdown && npm run test:site-links && npm run test:page-aliases && npm run test:sitemap && npm run test:site-node-commands && npm run test:nested-pages && npm run test:heading-ids && npm run test:navigation-model && npm run test:project-config && npm run test:editor-language && npm run test:content-check && npm run test:content-sync-plan && npm run test:content-model && npm run test:theme-presets && npm run test:presentation-contract && npm run test:preset-baselines && npm run test:documentation-preset-review && npm run test:site-public && npm run test:cli-discovery && npm run test:dev-local && npm run test:engine-commands && npm run test:documentation && npm run test:ci-lockfile && npm run test:banner-visibility && npm run test:client-javascript && npm run test:fixture:build && npm run test:examples && npm run package:check",
102
+ "test": "npm run schemas:check && npm run test:dead-code && npm run test:schemas && npm run test:page-model && npm run test:page-markdown && npm run test:site-links && npm run test:page-aliases && npm run test:sitemap && npm run test:not-found-page && npm run test:site-node-commands && npm run test:page-move && npm run test:navigation-review && npm run test:nested-pages && npm run test:heading-ids && npm run test:navigation-model && npm run test:project-config && npm run test:edit-source-link && npm run test:static-search && npm run test:editor-language && npm run test:content-check && npm run test:content-sync-plan && npm run test:content-model && npm run test:theme-presets && npm run test:presentation-contract && npm run test:presentation-review && npm run test:preset-baselines && npm run test:documentation-preset-review && npm run test:site-public && npm run test:cli-discovery && npm run test:dev-local && npm run test:review-environments && npm run test:engine-commands && npm run test:documentation && npm run test:ci-lockfile && npm run test:banner-visibility && npm run test:client-javascript && npm run test:fixture:build && npm run test:examples && npm run package:check",
92
103
  "test:fixture:build": "node scripts/test-basic-fixture-build.mjs",
93
104
  "test:examples": "node scripts/test-examples.mjs",
94
105
  "test:page-model": "node scripts/test-page-model.mjs",
@@ -96,12 +107,17 @@
96
107
  "test:site-links": "node scripts/test-site-link-graph.mjs",
97
108
  "test:page-aliases": "node scripts/test-page-aliases.mjs",
98
109
  "test:sitemap": "node scripts/test-sitemap.mjs",
110
+ "test:not-found-page": "node scripts/test-not-found-page.mjs",
99
111
  "test:site-node-commands": "node scripts/test-site-node-commands.mjs",
112
+ "test:page-move": "node scripts/test-page-move.mjs",
113
+ "test:navigation-review": "node scripts/test-navigation-review.mjs",
100
114
  "test:nested-pages": "node scripts/test-nested-pages.mjs",
101
115
  "test:heading-ids": "node scripts/test-heading-ids.mjs",
102
116
  "test:navigation-model": "node scripts/test-navigation-model.mjs",
103
117
  "test:schemas": "node scripts/test-schemas.mjs",
104
118
  "test:project-config": "node scripts/test-project-config.mjs",
119
+ "test:edit-source-link": "node scripts/test-edit-source-link.mjs",
120
+ "test:static-search": "node scripts/test-static-search.mjs",
105
121
  "test:content-check": "node scripts/test-content-check.mjs",
106
122
  "test:content-sync-plan": "node scripts/test-content-sync-plan.mjs",
107
123
  "test:content-model": "npm run test:page-content && npm run test:managed-media && npm run test:content-sync && npm run test:markdown-constructs",
@@ -111,7 +127,10 @@
111
127
  "test:markdown-constructs": "node scripts/test-markdown-constructs.mjs",
112
128
  "test:theme-presets": "node scripts/test-theme-presets.mjs",
113
129
  "test:presentation-contract": "node scripts/test-presentation-contract.mjs",
130
+ "test:presentation-review": "node scripts/test-presentation-review-fixture.mjs",
114
131
  "test:presentation:browser": "node scripts/test-navigation.mjs --site-dir fixtures/preset-baseline/site tests/presentation-contract.spec.ts",
132
+ "test:table-layout:top": "node scripts/test-navigation.mjs --site-dir fixtures/top-navigation/site tests/table-width-top.spec.ts",
133
+ "test:table-context:browser": "node scripts/test-navigation.mjs --site-dir fixtures/presentation-review/site tests/table-responsive-context.spec.ts",
115
134
  "test:navigation-surfaces:browser": "npm run test:navigation-surfaces:top && npm run test:navigation-surfaces:tree",
116
135
  "test:navigation-surfaces:top": "node scripts/test-navigation.mjs --site-dir fixtures/content-model-v2/site tests/navigation-surfaces-top.spec.ts",
117
136
  "test:navigation-surfaces:tree": "node scripts/test-navigation.mjs --site-dir fixtures/preset-baseline/site tests/presentation-contract.spec.ts",
@@ -125,6 +144,8 @@
125
144
  "test:site-public": "node scripts/test-site-public.mjs",
126
145
  "test:cli-discovery": "node scripts/test-cli-discovery.mjs",
127
146
  "test:dev-local": "node scripts/test-dev-local.mjs",
147
+ "test:review-environments": "node scripts/test-review-environments.mjs",
148
+ "test:review-environments:browser": "node scripts/test-review-environments-browser.mjs",
128
149
  "test:engine-commands": "node scripts/test-engine-commands.mjs",
129
150
  "test:editor-language": "node scripts/test-editor-language-service.mjs && npm --prefix editors/vscode run check",
130
151
  "test:editor-integration": "npm --prefix editors/vscode run test:integration",
@@ -136,6 +157,7 @@
136
157
  "test:dead-code": "knip --include files,exports",
137
158
  "test:navigation": "node scripts/test-navigation.mjs",
138
159
  "test:navigation:tree": "node scripts/test-navigation.mjs --site-dir fixtures/nested-pages/site tests/navigation-tree.spec.ts",
160
+ "test:navigation:placement": "node scripts/test-navigation.mjs --site-dir fixtures/nested-pages/site tests/page-contents-placement.spec.ts",
139
161
  "test:navigation:stress": "node scripts/test-navigation.mjs tests/navigation-stress.spec.ts",
140
162
  "test:navigation:preview": "node scripts/test-navigation-preview.mjs",
141
163
  "package:check": "node scripts/test-package-check.mjs",
@@ -152,6 +174,7 @@
152
174
  "astro": "^7.1.3",
153
175
  "embla-carousel": "^8.6.0",
154
176
  "js-yaml": "^4.3.1",
177
+ "pagefind": "1.5.2",
155
178
  "satteri": "^0.9.1"
156
179
  },
157
180
  "devDependencies": {
@@ -6,7 +6,7 @@
6
6
  "type": "string",
7
7
  "minLength": 1,
8
8
  "description": "Navigation label for this non-routable page category.",
9
- "markdownDescription": "```yaml\nlabel: Guides\n```\n\nThe category label shown in global navigation, tree navigation, mobile navigation, and breadcrumbs.\n\n[Navigation category reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation-categories)"
9
+ "markdownDescription": "```yaml\nlabel: Guides\n```\n\nThe category label shown in global navigation, tree navigation, mobile navigation, and breadcrumbs.\n\n[Navigation category reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation-categories)"
10
10
  }
11
11
  },
12
12
  "required": [
@@ -16,5 +16,5 @@
16
16
  "description": "A non-routable navigation category containing child pages.",
17
17
  "$id": "https://janga.github.io/norna/schemas/category.schema.json",
18
18
  "title": "Norna page category",
19
- "markdownDescription": "```yaml\nlabel: Guides\n```\n\n`category.yaml` creates a navigation-only group for child pages. It has no page content and produces no URL of its own.\n\n[Navigation category reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation-categories)"
19
+ "markdownDescription": "```yaml\nlabel: Guides\n```\n\n`category.yaml` creates a navigation-only group for child pages. It has no page content and produces no URL of its own.\n\n[Navigation category reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation-categories)"
20
20
  }
@@ -6,7 +6,7 @@
6
6
  "type": "string",
7
7
  "format": "uri",
8
8
  "description": "Absolute public URL for the built site.",
9
- "markdownDescription": "```yaml\nurl: https://example.com/\n```\n\nThe absolute public URL. Its path also determines the base path for generated links and assets.\n\n[Public URL reference](https://github.com/janga/norna/blob/v0.7.23/docs/configuration.md#url)",
9
+ "markdownDescription": "```yaml\nurl: https://example.com/\n```\n\nThe absolute public URL. Its path also determines the base path for generated links and assets.\n\n[Public URL reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#url)",
10
10
  "examples": [
11
11
  "https://example.com/",
12
12
  "https://owner.github.io/repository-name/"
@@ -28,13 +28,13 @@
28
28
  "const": "en",
29
29
  "title": "English",
30
30
  "description": "Use Norna's built-in English interface text.",
31
- "markdownDescription": "Use Norna's built-in English interface text.\n\n[Language reference](https://github.com/janga/norna/blob/v0.7.23/docs/configuration.md#language)"
31
+ "markdownDescription": "Use Norna's built-in English interface text.\n\n[Language reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#language)"
32
32
  },
33
33
  {
34
34
  "const": "sv",
35
35
  "title": "Swedish",
36
36
  "description": "Use Norna's built-in Swedish interface text.",
37
- "markdownDescription": "Use Norna's built-in Swedish interface text.\n\n[Language reference](https://github.com/janga/norna/blob/v0.7.23/docs/configuration.md#language)"
37
+ "markdownDescription": "Use Norna's built-in Swedish interface text.\n\n[Language reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#language)"
38
38
  },
39
39
  {
40
40
  "type": "string",
@@ -43,7 +43,62 @@
43
43
  "description": "Use an English or Swedish regional language tag such as en-GB or sv-SE."
44
44
  }
45
45
  ],
46
- "markdownDescription": "```yaml\nlanguage: en-GB\n```\n\nSets the page language and selects Norna's built-in English or Swedish interface text. The default is `en`.\n\n[Language reference](https://github.com/janga/norna/blob/v0.7.23/docs/configuration.md#language)"
46
+ "markdownDescription": "```yaml\nlanguage: en-GB\n```\n\nSets the page language and selects Norna's built-in English or Swedish interface text. The default is `en`.\n\n[Language reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#language)"
47
+ },
48
+ "editLink": {
49
+ "type": "object",
50
+ "properties": {
51
+ "baseUrl": {
52
+ "type": "string",
53
+ "format": "uri",
54
+ "description": "Absolute edit URL prefix containing the repository, branch, and any repository subdirectory.",
55
+ "markdownDescription": "```yaml\neditLink:\n baseUrl: https://github.com/owner/repository/edit/main/\n```\n\nOptional absolute remote edit URL prefix. Include any repository subdirectory and branch. Norna adds the project-relative path to each page's `content.md` file. This destination is used by published output and LAN previews.\n\n[Edit-link reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#edit-link)",
56
+ "examples": [
57
+ "https://github.com/owner/repository/edit/main/"
58
+ ]
59
+ },
60
+ "localEditor": {
61
+ "description": "Editor used by source links in a development preview opened through a loopback address.",
62
+ "type": "string",
63
+ "oneOf": [
64
+ {
65
+ "const": "vscode",
66
+ "title": "Visual Studio Code",
67
+ "description": "Open the current page source in the locally installed Visual Studio Code application.",
68
+ "markdownDescription": "Open the current page source in the locally installed Visual Studio Code application.\n\n[Edit-link reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#edit-link)"
69
+ }
70
+ ],
71
+ "markdownDescription": "```yaml\neditLink:\n localEditor: vscode\n```\n\nOptional editor for a development preview opened through localhost or another loopback address. `vscode` opens the absolute page source path through VS Code's registered URL handler. The setting is never emitted as a local path in published output.\n\n[Edit-link reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#edit-link)",
72
+ "examples": [
73
+ "vscode"
74
+ ]
75
+ }
76
+ },
77
+ "additionalProperties": false,
78
+ "description": "Optional local and remote links from rendered pages to their Markdown source files.",
79
+ "markdownDescription": "```yaml\neditLink:\n localEditor: vscode\n baseUrl: https://github.com/owner/repository/edit/main/\n```\n\nLinks each rendered page to its `content.md` source. A loopback development preview uses the explicitly selected local editor; published output and LAN previews use the optional remote base URL. Specify either destination or both.\n\n[Edit-link reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#edit-link)",
80
+ "anyOf": [
81
+ {
82
+ "required": [
83
+ "localEditor"
84
+ ]
85
+ },
86
+ {
87
+ "required": [
88
+ "baseUrl"
89
+ ]
90
+ }
91
+ ],
92
+ "defaultSnippets": [
93
+ {
94
+ "label": "Local and remote source links",
95
+ "markdownDescription": "Open page source in VS Code during same-computer development and on the remote source host elsewhere.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#edit-link)",
96
+ "body": {
97
+ "localEditor": "vscode",
98
+ "baseUrl": "https://github.com/${1:owner}/${2:repository}/edit/${3:main}/"
99
+ }
100
+ }
101
+ ]
47
102
  },
48
103
  "navigation": {
49
104
  "type": "object",
@@ -55,29 +110,29 @@
55
110
  {
56
111
  "const": "automatic",
57
112
  "title": "Automatic",
58
- "description": "Choose sections for one page, top navigation for Home and independent top-level pages, and tree navigation inside branches with listed children or categories.",
59
- "markdownDescription": "Choose sections for one page, top navigation for Home and independent top-level pages, and tree navigation inside branches with listed children or categories.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation)"
113
+ "description": "Choose sections for one page, top navigation for a flat multi-page site, and a stable left rail throughout a site with listed child pages or categories.",
114
+ "markdownDescription": "Choose sections for one page, top navigation for a flat multi-page site, and a stable left rail throughout a site with listed child pages or categories.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation)"
60
115
  },
61
116
  {
62
117
  "const": "sections",
63
118
  "title": "Sections",
64
119
  "description": "Navigate the sections of the current page.",
65
- "markdownDescription": "Navigate the sections of the current page.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation)"
120
+ "markdownDescription": "Navigate the sections of the current page.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation)"
66
121
  },
67
122
  {
68
123
  "const": "top",
69
124
  "title": "Top",
70
125
  "description": "Use pages in the top navigation and sections below them.",
71
- "markdownDescription": "Use pages in the top navigation and sections below them.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation)"
126
+ "markdownDescription": "Use pages in the top navigation and sections below them.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation)"
72
127
  },
73
128
  {
74
129
  "const": "tree",
75
130
  "title": "Tree",
76
131
  "description": "Use a left page rail and a separate right H2/H3 contents rail where the page has enough headings.",
77
- "markdownDescription": "Use a left page rail and a separate right H2/H3 contents rail where the page has enough headings.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation)"
132
+ "markdownDescription": "Use a left page rail and a separate right H2/H3 contents rail where the page has enough headings.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation)"
78
133
  }
79
134
  ],
80
- "markdownDescription": "```yaml\nnavigation:\n mode: automatic\n```\n\nNavigation model. Omit this to let Norna choose from the site structure.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation)",
135
+ "markdownDescription": "```yaml\nnavigation:\n mode: automatic\n```\n\nNavigation model. Omit this to let Norna choose from the site structure.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation)",
81
136
  "examples": [
82
137
  "automatic",
83
138
  "sections",
@@ -88,7 +143,17 @@
88
143
  },
89
144
  "additionalProperties": false,
90
145
  "description": "Site-wide navigation behavior.",
91
- "markdownDescription": "```yaml\nnavigation:\n mode: automatic\n```\n\nSets the site-wide navigation policy. `automatic` selects an effective mode for each page from its active top-level branch.\n\n[Navigation reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation)"
146
+ "markdownDescription": "```yaml\nnavigation:\n mode: automatic\n```\n\nSets the site-wide navigation policy. `automatic` uses sections for one page, top navigation for a flat multi-page site, and a stable left rail throughout a hierarchical site.\n\n[Navigation reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation)"
147
+ },
148
+ "search": {
149
+ "default": false,
150
+ "description": "Generate a static site search page and Pagefind index. The default is false.",
151
+ "type": "boolean",
152
+ "markdownDescription": "```yaml\nsearch: true\n```\n\nGenerates a localized `/search/` page and a static Pagefind index during each build. Search is off by default, and only the search page loads the search JavaScript.\n\n[Search reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#search)",
153
+ "examples": [
154
+ true,
155
+ false
156
+ ]
92
157
  },
93
158
  "scrollBehavior": {
94
159
  "default": "instant",
@@ -99,16 +164,16 @@
99
164
  "const": "instant",
100
165
  "title": "Instant",
101
166
  "description": "Jump directly to anchors without animated scrolling. This is the default.",
102
- "markdownDescription": "Jump directly to anchors without animated scrolling. This is the default.\n\n[Scroll behavior reference](https://github.com/janga/norna/blob/v0.7.23/docs/configuration.md#scrollbehavior)"
167
+ "markdownDescription": "Jump directly to anchors without animated scrolling. This is the default.\n\n[Scroll behavior reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#scrollbehavior)"
103
168
  },
104
169
  {
105
170
  "const": "smooth",
106
171
  "title": "Browser smooth",
107
172
  "description": "Use the browser's native smooth scrolling for anchor navigation.",
108
- "markdownDescription": "Use the browser's native smooth scrolling for anchor navigation.\n\n[Scroll behavior reference](https://github.com/janga/norna/blob/v0.7.23/docs/configuration.md#scrollbehavior)"
173
+ "markdownDescription": "Use the browser's native smooth scrolling for anchor navigation.\n\n[Scroll behavior reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#scrollbehavior)"
109
174
  }
110
175
  ],
111
- "markdownDescription": "```yaml\nscrollBehavior: smooth\n```\n\nControls same-page anchor movement. `instant` is the default; `smooth` uses the browser's native smooth scrolling.\n\n[Scroll behavior reference](https://github.com/janga/norna/blob/v0.7.23/docs/configuration.md#scrollbehavior)",
176
+ "markdownDescription": "```yaml\nscrollBehavior: smooth\n```\n\nControls same-page anchor movement. `instant` is the default; `smooth` uses the browser's native smooth scrolling.\n\n[Scroll behavior reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md#scrollbehavior)",
112
177
  "examples": [
113
178
  "instant",
114
179
  "smooth"
@@ -122,5 +187,5 @@
122
187
  "description": "Technical settings for one Norna site. Additional pages cannot provide technical configuration.",
123
188
  "$id": "https://janga.github.io/norna/schemas/config.schema.json",
124
189
  "title": "Norna site configuration",
125
- "markdownDescription": "```yaml\nurl: https://example.com/\n```\n\n`config.yaml` contains the few technical settings shared by the complete site.\n\n[Configuration reference](https://github.com/janga/norna/blob/v0.7.23/docs/configuration.md)"
190
+ "markdownDescription": "```yaml\nurl: https://example.com/\n```\n\n`config.yaml` contains the few technical settings shared by the complete site.\n\n[Configuration reference](https://github.com/janga/norna/blob/v0.7.25/docs/configuration.md)"
126
191
  }
@@ -9,7 +9,7 @@
9
9
  "description": "Optional page-specific meta description.",
10
10
  "type": "string",
11
11
  "minLength": 1,
12
- "markdownDescription": "```yaml\npage:\n description: About this project.\n```\n\nAn optional page-specific description rendered as `<meta name=\"description\">`. It is not visible in page content.\n\n[Page title and frontmatter reference](https://github.com/janga/norna/blob/v0.7.23/docs/content.md#page-title-and-frontmatter)",
12
+ "markdownDescription": "```yaml\npage:\n description: About this project.\n```\n\nAn optional page-specific description rendered as `<meta name=\"description\">`. It is not visible in page content.\n\n[Page title and frontmatter reference](https://github.com/janga/norna/blob/v0.7.25/docs/content.md#page-title-and-frontmatter)",
13
13
  "examples": [
14
14
  "About this project."
15
15
  ]
@@ -22,12 +22,12 @@
22
22
  "type": "string",
23
23
  "pattern": "^\\/(?:[a-z0-9]+(?:-[a-z0-9]+)*\\/)+$",
24
24
  "description": "Previous site-relative URL that permanently identifies this page.",
25
- "markdownDescription": "```yaml\npage:\n aliases:\n - /old-about/\n```\n\nUse a previous Norna page URL. Start and end with `/`; use lowercase ASCII letters, numbers, and single hyphens; do not include the configured base path, a query string, or a fragment.\n\n[Alias path rules](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#preserve-old-page-urls)",
25
+ "markdownDescription": "```yaml\npage:\n aliases:\n - /old-about/\n```\n\nUse a previous Norna page URL. Start and end with `/`; use lowercase ASCII letters, numbers, and single hyphens; do not include the configured base path, a query string, or a fragment.\n\n[Alias path rules](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#preserve-old-page-urls)",
26
26
  "examples": [
27
27
  "/old-about/"
28
28
  ]
29
29
  },
30
- "markdownDescription": "```yaml\npage:\n aliases:\n - /old-about/\n```\n\nLists previous site-relative URLs that permanently identify this page. The page containing the list is always the target. Paths omit the configured base path and are excluded from the sitemap.\n\n[Preserve old page URLs](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#preserve-old-page-urls)",
30
+ "markdownDescription": "```yaml\npage:\n aliases:\n - /old-about/\n```\n\nLists previous site-relative URLs that permanently identify this page. The page containing the list is always the target. Paths omit the configured base path and are excluded from the sitemap.\n\n[Preserve old page URLs](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#preserve-old-page-urls)",
31
31
  "examples": [
32
32
  [
33
33
  "/old-about/"
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "additionalProperties": false,
39
39
  "description": "Optional metadata for this homepage or additional page. The Markdown H1 supplies the page title.",
40
- "markdownDescription": "```yaml\npage:\n description: About this project.\n aliases:\n - /old-about/\n```\n\nContains optional metadata for the current homepage or additional page. The Markdown H1 supplies its title. An alias records an old URL for this same page.\n\n[Page title and frontmatter reference](https://github.com/janga/norna/blob/v0.7.23/docs/content.md#page-title-and-frontmatter)"
40
+ "markdownDescription": "```yaml\npage:\n description: About this project.\n aliases:\n - /old-about/\n```\n\nContains optional metadata for the current homepage or additional page. The Markdown H1 supplies its title. An alias records an old URL for this same page.\n\n[Page title and frontmatter reference](https://github.com/janga/norna/blob/v0.7.25/docs/content.md#page-title-and-frontmatter)"
41
41
  },
42
42
  "navigation": {
43
43
  "description": "Optional navigation metadata for this page.",
@@ -47,7 +47,7 @@
47
47
  "default": true,
48
48
  "description": "List this page in site navigation. The page remains public when false.",
49
49
  "type": "boolean",
50
- "markdownDescription": "```yaml\nnavigation:\n listed: false\n```\n\nList this page in site navigation. The page remains public when false.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation)",
50
+ "markdownDescription": "```yaml\nnavigation:\n listed: false\n```\n\nList this page in site navigation. The page remains public when false.\n\n[Read the relevant reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation)",
51
51
  "examples": [
52
52
  true,
53
53
  false
@@ -55,12 +55,12 @@
55
55
  }
56
56
  },
57
57
  "additionalProperties": false,
58
- "markdownDescription": "```yaml\nnavigation:\n listed: false\n```\n\nOptionally excludes an additional page from site navigation without removing its public URL.\n\n[Site navigation reference](https://github.com/janga/norna/blob/v0.7.23/docs/pages.md#navigation)"
58
+ "markdownDescription": "```yaml\nnavigation:\n listed: false\n```\n\nOptionally excludes an additional page from site navigation without removing its public URL.\n\n[Site navigation reference](https://github.com/janga/norna/blob/v0.7.25/docs/pages.md#navigation)"
59
59
  }
60
60
  },
61
61
  "additionalProperties": false,
62
62
  "description": "Frontmatter for a homepage or additional page content.md file.",
63
63
  "$id": "https://janga.github.io/norna/schemas/content-frontmatter.schema.json",
64
64
  "title": "Norna page frontmatter",
65
- "markdownDescription": "```yaml\n---\npage:\n description: About this project.\n---\n```\n\nContent frontmatter is optional. Write the page title as the single Markdown H1; use frontmatter only for optional metadata or navigation settings.\n\n[Page title and frontmatter reference](https://github.com/janga/norna/blob/v0.7.23/docs/content.md#page-title-and-frontmatter)"
65
+ "markdownDescription": "```yaml\n---\npage:\n description: About this project.\n---\n```\n\nContent frontmatter is optional. Write the page title as the single Markdown H1; use frontmatter only for optional metadata or navigation settings.\n\n[Page title and frontmatter reference](https://github.com/janga/norna/blob/v0.7.25/docs/content.md#page-title-and-frontmatter)"
66
66
  }