@janga/norna 0.7.24 → 0.7.26
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.
- package/README.md +5 -4
- package/astro.config.mjs +27 -11
- package/bin/norna-cli.mjs +12 -0
- package/package.json +26 -5
- package/schemas/card-list.schema.json +121 -0
- package/schemas/category.schema.json +2 -2
- package/schemas/config.schema.json +342 -33
- package/schemas/content-frontmatter.schema.json +7 -7
- package/schemas/image-carousel.schema.json +43 -0
- package/schemas/image-stack.schema.json +43 -0
- package/schemas/manifest.json +6 -1
- package/schemas/page-theme.schema.json +26 -26
- package/schemas/sitewide-content.schema.json +18 -18
- package/schemas/theme.schema.json +237 -262
- package/scripts/check-config.mjs +5 -1
- package/scripts/dev-local.mjs +130 -13
- package/scripts/generate-schemas.mjs +15 -3
- package/scripts/init-site.mjs +2 -0
- package/scripts/lib/category-destinations.mjs +48 -0
- package/scripts/lib/code-fence-metadata.mjs +25 -43
- package/scripts/lib/content-tabs.mjs +155 -0
- package/scripts/lib/details-headings.mjs +58 -0
- package/scripts/lib/docusaurus-migration-audit.mjs +603 -0
- package/scripts/lib/edit-source-link.mjs +53 -0
- package/scripts/lib/editor-language-service.mjs +238 -116
- package/scripts/lib/locale-registry.mjs +597 -0
- package/scripts/lib/locales/az-Latn.mjs +78 -0
- package/scripts/lib/locales/be.mjs +78 -0
- package/scripts/lib/locales/bg.mjs +78 -0
- package/scripts/lib/locales/bs.mjs +78 -0
- package/scripts/lib/locales/ca.mjs +78 -0
- package/scripts/lib/locales/cnr.mjs +78 -0
- package/scripts/lib/locales/cs.mjs +78 -0
- package/scripts/lib/locales/da.mjs +78 -0
- package/scripts/lib/locales/de.mjs +78 -0
- package/scripts/lib/locales/el.mjs +78 -0
- package/scripts/lib/locales/en.mjs +78 -0
- package/scripts/lib/locales/es.mjs +78 -0
- package/scripts/lib/locales/et.mjs +78 -0
- package/scripts/lib/locales/fi.mjs +78 -0
- package/scripts/lib/locales/fil.mjs +78 -0
- package/scripts/lib/locales/fr.mjs +78 -0
- package/scripts/lib/locales/ga.mjs +78 -0
- package/scripts/lib/locales/ha.mjs +78 -0
- package/scripts/lib/locales/hr.mjs +78 -0
- package/scripts/lib/locales/hu.mjs +78 -0
- package/scripts/lib/locales/id.mjs +78 -0
- package/scripts/lib/locales/is.mjs +78 -0
- package/scripts/lib/locales/it.mjs +78 -0
- package/scripts/lib/locales/jv.mjs +78 -0
- package/scripts/lib/locales/lb.mjs +78 -0
- package/scripts/lib/locales/lt.mjs +78 -0
- package/scripts/lib/locales/lv.mjs +78 -0
- package/scripts/lib/locales/mk.mjs +78 -0
- package/scripts/lib/locales/mt.mjs +78 -0
- package/scripts/lib/locales/nb.mjs +78 -0
- package/scripts/lib/locales/nl.mjs +78 -0
- package/scripts/lib/locales/nn.mjs +78 -0
- package/scripts/lib/locales/pcm.mjs +78 -0
- package/scripts/lib/locales/pl.mjs +78 -0
- package/scripts/lib/locales/pt.mjs +78 -0
- package/scripts/lib/locales/ro.mjs +78 -0
- package/scripts/lib/locales/ru.mjs +78 -0
- package/scripts/lib/locales/sk.mjs +78 -0
- package/scripts/lib/locales/sl.mjs +78 -0
- package/scripts/lib/locales/sq.mjs +78 -0
- package/scripts/lib/locales/sr-Cyrl.mjs +78 -0
- package/scripts/lib/locales/sr-Latn.mjs +78 -0
- package/scripts/lib/locales/sv.mjs +78 -0
- package/scripts/lib/locales/sw.mjs +78 -0
- package/scripts/lib/locales/tr.mjs +78 -0
- package/scripts/lib/locales/uk.mjs +78 -0
- package/scripts/lib/locales/vi.mjs +78 -0
- package/scripts/lib/markdown-links.mjs +4 -25
- package/scripts/lib/markdown-notes-render-plugin.mjs +75 -0
- package/scripts/lib/markdown-notes.mjs +165 -0
- package/scripts/lib/navigation-model.mjs +1 -1
- package/scripts/lib/norna-markdown-blocks.mjs +123 -447
- package/scripts/lib/norna-markdown-render-plugin.mjs +4 -0
- package/scripts/lib/page-aliases.mjs +12 -1
- package/scripts/lib/page-markdown.mjs +63 -16
- package/scripts/lib/page-move-plan.mjs +22 -5
- package/scripts/lib/pagefind-translations.mjs +620 -0
- package/scripts/lib/presentation-contract.mjs +6 -1
- package/scripts/lib/presentation.mjs +29 -30
- package/scripts/lib/project-config.mjs +22 -163
- package/scripts/lib/schema-definitions.mjs +13 -12
- package/scripts/lib/schema-editor-metadata.mjs +42 -46
- package/scripts/lib/schema-value-definitions.mjs +7 -8
- package/scripts/lib/semantic-callouts.mjs +4 -2
- package/scripts/lib/site-content.mjs +4 -2
- package/scripts/lib/site-link-graph.mjs +16 -6
- package/scripts/lib/site-navigation-tree.mjs +0 -11
- package/scripts/lib/site-paths.mjs +14 -2
- package/scripts/lib/sitemap.mjs +5 -3
- package/scripts/lib/structured-blocks.mjs +108 -0
- package/scripts/lib/table-render-plugin.mjs +76 -0
- package/scripts/lib/table-row-headers.mjs +218 -0
- package/scripts/lib/theme-presets.mjs +3 -10
- package/scripts/lib/yaml-config.mjs +2 -6
- package/scripts/migrate-check.mjs +19 -0
- package/scripts/sync-content-sections.mjs +39 -10
- package/scripts/sync-site-public.mjs +7 -1
- package/src/components/CardList.astro +1 -0
- package/src/components/CodeBlockCopyScript.astro +49 -6
- package/src/components/ContentBlocks.astro +39 -0
- package/src/components/ContentTabsScript.astro +60 -0
- package/src/components/DisplaySettings.astro +17 -19
- package/src/components/ImageCarousel.astro +4 -1
- package/src/components/ImageStack.astro +34 -9
- package/src/components/ImageStackEnhancement.astro +331 -0
- package/src/components/NavigationPageTree.astro +1 -1
- package/src/components/NoteNavigationScript.astro +4 -0
- package/src/components/PageAliasRedirect.astro +5 -4
- package/src/components/PageContentsNavigation.astro +2 -3
- package/src/components/SearchNavigationScript.astro +4 -0
- package/src/components/SearchPage.astro +43 -2
- package/src/components/SectionNavigationScript.astro +86 -16
- package/src/components/SiteBreadcrumbs.astro +1 -1
- package/src/components/SiteNavigation.astro +98 -65
- package/src/components/SitePage.astro +73 -33
- package/src/components/SiteSection.astro +5 -81
- package/src/components/SiteTreeNavigation.astro +5 -2
- package/src/components/TableOverflowScript.astro +579 -0
- package/src/components/TopPageMenu.astro +47 -0
- package/src/components/TreeNavigationScript.astro +86 -23
- package/src/layouts/BaseLayout.astro +34 -12
- package/src/lib/generatedImages.ts +18 -0
- package/src/lib/navigationFollowing.ts +142 -0
- package/src/lib/noteNavigation.ts +50 -0
- package/src/lib/searchNavigation.ts +107 -0
- package/src/lib/sectionContent.ts +23 -116
- package/src/lib/siteNavigation.ts +0 -5
- package/src/lib/sitePages.ts +18 -4
- package/src/lib/table-sort-tooltip.ts +109 -0
- package/src/pages/[...slug].astro +16 -6
- package/src/styles/content.css +563 -26
- package/src/styles/foundations.css +9 -0
- package/src/styles/media.css +192 -3
- package/src/styles/navigation.css +214 -60
- package/src/styles/page-layout.css +55 -16
- package/src/styles/responsive.css +62 -20
|
@@ -87,16 +87,16 @@ const presentationPalettes = Object.freeze({
|
|
|
87
87
|
modes: Object.freeze({
|
|
88
88
|
light: createPaletteMode({
|
|
89
89
|
appearance: 'light',
|
|
90
|
-
page: { backgroundColor: '#
|
|
90
|
+
page: { backgroundColor: '#e8f1f8', textColor: '#202932' },
|
|
91
91
|
surfaces: {
|
|
92
|
-
base: { backgroundColor: '#
|
|
92
|
+
base: { backgroundColor: '#e8f1f8', textColor: '#202932' },
|
|
93
93
|
soft: { backgroundColor: '#e4eaf0', textColor: '#202932' },
|
|
94
94
|
emphasis: { backgroundColor: '#d3dee8', textColor: '#202932' },
|
|
95
95
|
},
|
|
96
|
-
frame: { backgroundColor: '#
|
|
96
|
+
frame: { backgroundColor: '#e8f1f8', textColor: '#202932' },
|
|
97
97
|
css: {
|
|
98
98
|
surface: '#e9eef2',
|
|
99
|
-
muted: '#
|
|
99
|
+
muted: '#56636f',
|
|
100
100
|
soft: '#d5dfe7',
|
|
101
101
|
accent: '#2a5877',
|
|
102
102
|
border: 'rgb(32 41 50 / 16%)',
|
|
@@ -127,13 +127,13 @@ const presentationPalettes = Object.freeze({
|
|
|
127
127
|
modes: Object.freeze({
|
|
128
128
|
light: createPaletteMode({
|
|
129
129
|
appearance: 'light',
|
|
130
|
-
page: { backgroundColor: '#
|
|
130
|
+
page: { backgroundColor: '#e3f1eb', textColor: '#203631' },
|
|
131
131
|
surfaces: {
|
|
132
|
-
base: { backgroundColor: '#
|
|
132
|
+
base: { backgroundColor: '#e3f1eb', textColor: '#203631' },
|
|
133
133
|
soft: { backgroundColor: '#dce9e4', textColor: '#203631' },
|
|
134
134
|
emphasis: { backgroundColor: '#c8ddd5', textColor: '#203631' },
|
|
135
135
|
},
|
|
136
|
-
frame: { backgroundColor: '#
|
|
136
|
+
frame: { backgroundColor: '#e3f1eb', textColor: '#203631' },
|
|
137
137
|
css: {
|
|
138
138
|
surface: '#e3ece8',
|
|
139
139
|
muted: '#536560',
|
|
@@ -167,16 +167,16 @@ const presentationPalettes = Object.freeze({
|
|
|
167
167
|
modes: Object.freeze({
|
|
168
168
|
light: createPaletteMode({
|
|
169
169
|
appearance: 'light',
|
|
170
|
-
page: { backgroundColor: '#
|
|
170
|
+
page: { backgroundColor: '#f0e8f8', textColor: '#2e2736' },
|
|
171
171
|
surfaces: {
|
|
172
|
-
base: { backgroundColor: '#
|
|
172
|
+
base: { backgroundColor: '#f0e8f8', textColor: '#2e2736' },
|
|
173
173
|
soft: { backgroundColor: '#ebe4f1', textColor: '#2e2736' },
|
|
174
174
|
emphasis: { backgroundColor: '#ddd3e8', textColor: '#2e2736' },
|
|
175
175
|
},
|
|
176
|
-
frame: { backgroundColor: '#
|
|
176
|
+
frame: { backgroundColor: '#f0e8f8', textColor: '#2e2736' },
|
|
177
177
|
css: {
|
|
178
178
|
surface: '#eee8f3',
|
|
179
|
-
muted: '#
|
|
179
|
+
muted: '#655b6c',
|
|
180
180
|
soft: '#ded5e7',
|
|
181
181
|
accent: '#604678',
|
|
182
182
|
border: 'rgb(46 39 54 / 16%)',
|
|
@@ -207,13 +207,13 @@ const presentationPalettes = Object.freeze({
|
|
|
207
207
|
modes: Object.freeze({
|
|
208
208
|
light: createPaletteMode({
|
|
209
209
|
appearance: 'light',
|
|
210
|
-
page: { backgroundColor: '#
|
|
210
|
+
page: { backgroundColor: '#fdf6e3', textColor: '#272522' },
|
|
211
211
|
surfaces: {
|
|
212
|
-
base: { backgroundColor: '#
|
|
212
|
+
base: { backgroundColor: '#fdf6e3', textColor: '#272522' },
|
|
213
213
|
soft: { backgroundColor: '#ebe5d9', textColor: '#272522' },
|
|
214
214
|
emphasis: { backgroundColor: '#ded4c5', textColor: '#272522' },
|
|
215
215
|
},
|
|
216
|
-
frame: { backgroundColor: '#
|
|
216
|
+
frame: { backgroundColor: '#fdf6e3', textColor: '#272522' },
|
|
217
217
|
css: {
|
|
218
218
|
surface: '#f0ebe1',
|
|
219
219
|
muted: '#6b655b',
|
|
@@ -247,13 +247,13 @@ const presentationPalettes = Object.freeze({
|
|
|
247
247
|
modes: Object.freeze({
|
|
248
248
|
light: createPaletteMode({
|
|
249
249
|
appearance: 'light',
|
|
250
|
-
page: { backgroundColor: '#
|
|
250
|
+
page: { backgroundColor: '#fbf1c7', textColor: '#34291c' },
|
|
251
251
|
surfaces: {
|
|
252
|
-
base: { backgroundColor: '#
|
|
252
|
+
base: { backgroundColor: '#fbf1c7', textColor: '#34291c' },
|
|
253
253
|
soft: { backgroundColor: '#eadbb8', textColor: '#34291c' },
|
|
254
254
|
emphasis: { backgroundColor: '#d8c18c', textColor: '#34291c' },
|
|
255
255
|
},
|
|
256
|
-
frame: { backgroundColor: '#
|
|
256
|
+
frame: { backgroundColor: '#fbf1c7', textColor: '#34291c' },
|
|
257
257
|
css: {
|
|
258
258
|
surface: '#efe2c4',
|
|
259
259
|
muted: '#6c5e4c',
|
|
@@ -287,13 +287,13 @@ const presentationPalettes = Object.freeze({
|
|
|
287
287
|
modes: Object.freeze({
|
|
288
288
|
light: createPaletteMode({
|
|
289
289
|
appearance: 'light',
|
|
290
|
-
page: { backgroundColor: '#
|
|
290
|
+
page: { backgroundColor: '#f8e9e7', textColor: '#3c2929' },
|
|
291
291
|
surfaces: {
|
|
292
|
-
base: { backgroundColor: '#
|
|
292
|
+
base: { backgroundColor: '#f8e9e7', textColor: '#3c2929' },
|
|
293
293
|
soft: { backgroundColor: '#ecdeda', textColor: '#3c2929' },
|
|
294
294
|
emphasis: { backgroundColor: '#ddc7c1', textColor: '#3c2929' },
|
|
295
295
|
},
|
|
296
|
-
frame: { backgroundColor: '#
|
|
296
|
+
frame: { backgroundColor: '#f8e9e7', textColor: '#3c2929' },
|
|
297
297
|
css: {
|
|
298
298
|
surface: '#f0e3e0',
|
|
299
299
|
muted: '#6d5558',
|
|
@@ -327,13 +327,13 @@ const presentationPalettes = Object.freeze({
|
|
|
327
327
|
modes: Object.freeze({
|
|
328
328
|
light: createPaletteMode({
|
|
329
329
|
appearance: 'light',
|
|
330
|
-
page: { backgroundColor: '#
|
|
330
|
+
page: { backgroundColor: '#eaf0da', textColor: '#263225' },
|
|
331
331
|
surfaces: {
|
|
332
|
-
base: { backgroundColor: '#
|
|
332
|
+
base: { backgroundColor: '#eaf0da', textColor: '#263225' },
|
|
333
333
|
soft: { backgroundColor: '#e1e6d2', textColor: '#263225' },
|
|
334
334
|
emphasis: { backgroundColor: '#cbd5b7', textColor: '#263225' },
|
|
335
335
|
},
|
|
336
|
-
frame: { backgroundColor: '#
|
|
336
|
+
frame: { backgroundColor: '#eaf0da', textColor: '#263225' },
|
|
337
337
|
css: {
|
|
338
338
|
surface: '#e7eadb',
|
|
339
339
|
muted: '#52604c',
|
|
@@ -367,16 +367,16 @@ const presentationPalettes = Object.freeze({
|
|
|
367
367
|
modes: Object.freeze({
|
|
368
368
|
light: createPaletteMode({
|
|
369
369
|
appearance: 'light',
|
|
370
|
-
page: { backgroundColor: '#
|
|
370
|
+
page: { backgroundColor: '#e8ebfa', textColor: '#25243a' },
|
|
371
371
|
surfaces: {
|
|
372
|
-
base: { backgroundColor: '#
|
|
372
|
+
base: { backgroundColor: '#e8ebfa', textColor: '#25243a' },
|
|
373
373
|
soft: { backgroundColor: '#e2e6f3', textColor: '#25243a' },
|
|
374
374
|
emphasis: { backgroundColor: '#d0d7eb', textColor: '#25243a' },
|
|
375
375
|
},
|
|
376
|
-
frame: { backgroundColor: '#
|
|
376
|
+
frame: { backgroundColor: '#e8ebfa', textColor: '#25243a' },
|
|
377
377
|
css: {
|
|
378
378
|
surface: '#e8eaf5',
|
|
379
|
-
muted: '#
|
|
379
|
+
muted: '#5b5d73',
|
|
380
380
|
soft: '#d5daec',
|
|
381
381
|
accent: '#3b568f',
|
|
382
382
|
border: 'rgb(37 36 58 / 16%)',
|
|
@@ -467,7 +467,6 @@ export const resolveThemePresentation = (theme, sourceLabel = 'theme.yaml') => {
|
|
|
467
467
|
const paletteName = normalizedTheme.palette ?? 'near-monochrome';
|
|
468
468
|
const palette = getPresentationPalette(paletteName);
|
|
469
469
|
const appearance = normalizedTheme.appearance ?? {};
|
|
470
|
-
const readerControls = normalizedTheme.readerControls ?? {};
|
|
471
470
|
const defaultAppearance = appearance.default ?? 'system';
|
|
472
471
|
if (!appearanceNames.includes(defaultAppearance)) {
|
|
473
472
|
throw new Error(`appearance.default must be one of ${appearanceNames.join(', ')} in ${sourceLabel}.`);
|
|
@@ -488,9 +487,9 @@ export const resolveThemePresentation = (theme, sourceLabel = 'theme.yaml') => {
|
|
|
488
487
|
},
|
|
489
488
|
readerPreferences: {
|
|
490
489
|
controls: {
|
|
491
|
-
appearance:
|
|
490
|
+
appearance: true,
|
|
492
491
|
readingWidth: true,
|
|
493
|
-
focusReading:
|
|
492
|
+
focusReading: false,
|
|
494
493
|
},
|
|
495
494
|
defaults: {
|
|
496
495
|
appearance: defaultAppearance,
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
siteConfigPath,
|
|
14
14
|
siteThemeLabel,
|
|
15
15
|
} from './site-paths.mjs';
|
|
16
|
-
import { normalizeEditLinkBaseUrl } from './edit-source-link.mjs';
|
|
16
|
+
import { localEditorNames, normalizeEditLinkBaseUrl } from './edit-source-link.mjs';
|
|
17
|
+
import { resolveLocale } from './locale-registry.mjs';
|
|
17
18
|
import { readThemeConfig } from './theme-config.mjs';
|
|
18
19
|
import { resolveThemeConfig } from './theme-presets.mjs';
|
|
19
20
|
import { parseYamlConfig } from './yaml-config.mjs';
|
|
@@ -197,156 +198,6 @@ const readSiteUrl = (config) => {
|
|
|
197
198
|
return url;
|
|
198
199
|
};
|
|
199
200
|
|
|
200
|
-
const localeLabels = Object.freeze({
|
|
201
|
-
en: Object.freeze({
|
|
202
|
-
breadcrumb: 'Breadcrumb',
|
|
203
|
-
appearance: 'Appearance',
|
|
204
|
-
appearanceDark: 'Dark',
|
|
205
|
-
appearanceLight: 'Light',
|
|
206
|
-
appearanceSystem: 'System',
|
|
207
|
-
codeCopied: 'Copied',
|
|
208
|
-
codeCopyFailed: 'Could not copy code',
|
|
209
|
-
copyCode: 'Copy code',
|
|
210
|
-
calloutCaution: 'Caution',
|
|
211
|
-
calloutDanger: 'Danger',
|
|
212
|
-
calloutImportant: 'Important',
|
|
213
|
-
calloutNote: 'Note',
|
|
214
|
-
calloutTip: 'Tip',
|
|
215
|
-
calloutWarning: 'Warning',
|
|
216
|
-
editSource: 'Edit this page',
|
|
217
|
-
displaySettings: 'Display',
|
|
218
|
-
focusReading: 'Focus reading',
|
|
219
|
-
footnoteBackReference: 'Back to reference {reference}',
|
|
220
|
-
footnotes: 'Footnotes',
|
|
221
|
-
readingWidth: 'Reading width',
|
|
222
|
-
readingWidthNarrow: 'Narrow',
|
|
223
|
-
readingWidthStandard: 'Standard',
|
|
224
|
-
readingWidthWide: 'Wide',
|
|
225
|
-
resetDisplaySettings: 'Reset',
|
|
226
|
-
dismissBanner: 'Dismiss notice',
|
|
227
|
-
built: 'Built',
|
|
228
|
-
images: 'Images',
|
|
229
|
-
imageCarousel: 'image carousel',
|
|
230
|
-
navigationCollapsedAll: 'All navigation items collapsed.',
|
|
231
|
-
navigationCollapseAll: 'Collapse all',
|
|
232
|
-
navigationControls: 'Navigation tree controls',
|
|
233
|
-
navigationChildren: 'Child pages',
|
|
234
|
-
navigationExpandedAll: 'All navigation items expanded.',
|
|
235
|
-
navigationExpandAll: 'Expand all',
|
|
236
|
-
navigationFilter: 'Filter pages and groups',
|
|
237
|
-
navigationFilterEmpty: 'No matching pages or groups. The current page remains available.',
|
|
238
|
-
navigationFilterMatches: 'Matching navigation items: {count}',
|
|
239
|
-
navigationLocatedCurrent: 'Current page located.',
|
|
240
|
-
navigationLocateCurrent: 'Locate current page',
|
|
241
|
-
navigationMenu: 'Menu',
|
|
242
|
-
nextImage: 'Next image',
|
|
243
|
-
nextPage: 'Next page',
|
|
244
|
-
note: 'Note',
|
|
245
|
-
notFound: 'Page not found',
|
|
246
|
-
notFoundText: 'The requested page does not exist or may have moved.',
|
|
247
|
-
pageMoved: 'Page moved',
|
|
248
|
-
pageMovedText: 'This address now identifies',
|
|
249
|
-
pageNavigation: 'Page contents',
|
|
250
|
-
pageSequence: 'Page sequence',
|
|
251
|
-
pageSections: 'Sections',
|
|
252
|
-
previousImage: 'Previous image',
|
|
253
|
-
previousPage: 'Previous page',
|
|
254
|
-
returnHome: 'Go to the homepage',
|
|
255
|
-
search: 'Search',
|
|
256
|
-
searchDescription: 'Search the published content on this site.',
|
|
257
|
-
searchLoading: 'Loading search…',
|
|
258
|
-
searchNoScript: 'Search requires JavaScript. Use the page navigation when JavaScript is unavailable.',
|
|
259
|
-
searchUnavailable: 'Search is unavailable. During local work, run norna build:local to create or refresh the search index.',
|
|
260
|
-
siteBanners: 'Site notices',
|
|
261
|
-
siteNavigation: 'Pages',
|
|
262
|
-
skipToContent: 'Skip to content',
|
|
263
|
-
}),
|
|
264
|
-
sv: Object.freeze({
|
|
265
|
-
breadcrumb: 'Brödsmulor',
|
|
266
|
-
appearance: 'Utseende',
|
|
267
|
-
appearanceDark: 'Mörkt',
|
|
268
|
-
appearanceLight: 'Ljust',
|
|
269
|
-
appearanceSystem: 'System',
|
|
270
|
-
codeCopied: 'Kopierat',
|
|
271
|
-
codeCopyFailed: 'Kunde inte kopiera koden',
|
|
272
|
-
copyCode: 'Kopiera kod',
|
|
273
|
-
calloutCaution: 'Var försiktig',
|
|
274
|
-
calloutDanger: 'Fara',
|
|
275
|
-
calloutImportant: 'Viktigt',
|
|
276
|
-
calloutNote: 'Notera',
|
|
277
|
-
calloutTip: 'Tips',
|
|
278
|
-
calloutWarning: 'Varning',
|
|
279
|
-
editSource: 'Redigera den här sidan',
|
|
280
|
-
displaySettings: 'Visning',
|
|
281
|
-
focusReading: 'Fokuserad läsning',
|
|
282
|
-
footnoteBackReference: 'Tillbaka till referens {reference}',
|
|
283
|
-
footnotes: 'Fotnoter',
|
|
284
|
-
readingWidth: 'Textbredd',
|
|
285
|
-
readingWidthNarrow: 'Smal',
|
|
286
|
-
readingWidthStandard: 'Standard',
|
|
287
|
-
readingWidthWide: 'Bred',
|
|
288
|
-
resetDisplaySettings: 'Återställ',
|
|
289
|
-
dismissBanner: 'Stäng meddelande',
|
|
290
|
-
built: 'Byggd',
|
|
291
|
-
images: 'Bilder',
|
|
292
|
-
imageCarousel: 'bildkarusell',
|
|
293
|
-
navigationCollapsedAll: 'Alla navigationsposter har fällts ihop.',
|
|
294
|
-
navigationCollapseAll: 'Fäll ihop alla',
|
|
295
|
-
navigationControls: 'Kontroller för navigationsträdet',
|
|
296
|
-
navigationChildren: 'Undersidor',
|
|
297
|
-
navigationExpandedAll: 'Alla navigationsposter har fällts ut.',
|
|
298
|
-
navigationExpandAll: 'Fäll ut alla',
|
|
299
|
-
navigationFilter: 'Filtrera sidor och grupper',
|
|
300
|
-
navigationFilterEmpty: 'Inga sidor eller grupper matchar. Den aktuella sidan är fortfarande tillgänglig.',
|
|
301
|
-
navigationFilterMatches: 'Matchande navigationsposter: {count}',
|
|
302
|
-
navigationLocatedCurrent: 'Den aktuella sidan har hittats.',
|
|
303
|
-
navigationLocateCurrent: 'Hitta aktuell sida',
|
|
304
|
-
navigationMenu: 'Meny',
|
|
305
|
-
nextImage: 'Nästa bild',
|
|
306
|
-
nextPage: 'Nästa sida',
|
|
307
|
-
note: 'Not',
|
|
308
|
-
notFound: 'Sidan hittades inte',
|
|
309
|
-
notFoundText: 'Den begärda sidan finns inte eller kan ha flyttats.',
|
|
310
|
-
pageMoved: 'Sidan har flyttats',
|
|
311
|
-
pageMovedText: 'Den här adressen identifierar nu',
|
|
312
|
-
pageNavigation: 'Sidinnehåll',
|
|
313
|
-
pageSequence: 'Sidföljd',
|
|
314
|
-
pageSections: 'Avsnitt',
|
|
315
|
-
previousImage: 'Föregående bild',
|
|
316
|
-
previousPage: 'Föregående sida',
|
|
317
|
-
returnHome: 'Gå till startsidan',
|
|
318
|
-
search: 'Sök',
|
|
319
|
-
searchDescription: 'Sök i det publicerade innehållet på webbplatsen.',
|
|
320
|
-
searchLoading: 'Laddar sökning…',
|
|
321
|
-
searchNoScript: 'Sökning kräver JavaScript. Använd sidnavigeringen när JavaScript inte är tillgängligt.',
|
|
322
|
-
searchUnavailable: 'Sökningen är inte tillgänglig. Kör norna build:local under lokalt arbete för att skapa eller uppdatera sökindexet.',
|
|
323
|
-
siteBanners: 'Meddelanden',
|
|
324
|
-
siteNavigation: 'Sidor',
|
|
325
|
-
skipToContent: 'Hoppa till innehållet',
|
|
326
|
-
}),
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
const readLocale = (config) => {
|
|
330
|
-
const lang = config.language ?? 'en';
|
|
331
|
-
|
|
332
|
-
if (typeof lang !== 'string' || !/^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]+)*$/.test(lang.trim())) {
|
|
333
|
-
throw new Error(`language must be a valid language tag such as "en" or "sv" in ${siteConfigLabel}.`);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
const normalizedLang = lang.trim();
|
|
337
|
-
const languageKey = normalizedLang.toLowerCase().split('-')[0];
|
|
338
|
-
const labels = localeLabels[languageKey];
|
|
339
|
-
|
|
340
|
-
if (!labels) {
|
|
341
|
-
throw new Error(`language "${normalizedLang}" has no built-in Norna UI text. Supported languages: ${Object.keys(localeLabels).join(', ')}.`);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
return Object.freeze({
|
|
345
|
-
lang: normalizedLang,
|
|
346
|
-
labels,
|
|
347
|
-
});
|
|
348
|
-
};
|
|
349
|
-
|
|
350
201
|
const rawConfig = assertObject(siteConfig, 'config YAML');
|
|
351
202
|
const rawTheme = assertObject(themeConfig, 'theme YAML', siteThemeLabel);
|
|
352
203
|
const siteUrl = readSiteUrl(rawConfig);
|
|
@@ -541,22 +392,30 @@ export const resolveEditLinkConfig = (config, sourceLabel = siteConfigLabel) =>
|
|
|
541
392
|
if (config.editLink === undefined) return null;
|
|
542
393
|
|
|
543
394
|
const rawEditLink = assertObject(config.editLink, 'editLink', sourceLabel);
|
|
544
|
-
|
|
545
|
-
throw new Error(`editLink.baseUrl is required when editLink is configured in ${sourceLabel}.`);
|
|
546
|
-
}
|
|
547
|
-
const unknownKeys = Object.keys(rawEditLink).filter((key) => key !== 'baseUrl');
|
|
395
|
+
const unknownKeys = Object.keys(rawEditLink).filter((key) => !['baseUrl', 'localEditor'].includes(key));
|
|
548
396
|
if (unknownKeys.length > 0) {
|
|
549
397
|
throw new Error(`editLink.${unknownKeys[0]} is not a valid setting in ${sourceLabel}.`);
|
|
550
398
|
}
|
|
399
|
+
if (!Object.hasOwn(rawEditLink, 'baseUrl') && !Object.hasOwn(rawEditLink, 'localEditor')) {
|
|
400
|
+
throw new Error(`editLink must specify baseUrl, localEditor, or both in ${sourceLabel}.`);
|
|
401
|
+
}
|
|
551
402
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
403
|
+
let baseUrl = null;
|
|
404
|
+
if (Object.hasOwn(rawEditLink, 'baseUrl')) {
|
|
405
|
+
try {
|
|
406
|
+
baseUrl = normalizeEditLinkBaseUrl(rawEditLink.baseUrl, 'editLink.baseUrl');
|
|
407
|
+
} catch (error) {
|
|
408
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
409
|
+
throw new Error(`${message.replace(/\.$/, '')} in ${sourceLabel}.`);
|
|
410
|
+
}
|
|
559
411
|
}
|
|
412
|
+
|
|
413
|
+
return Object.freeze({
|
|
414
|
+
baseUrl,
|
|
415
|
+
localEditor: Object.hasOwn(rawEditLink, 'localEditor')
|
|
416
|
+
? readEnum(rawEditLink, 'localEditor', 'editLink', localEditorNames, undefined, sourceLabel)
|
|
417
|
+
: null,
|
|
418
|
+
});
|
|
560
419
|
};
|
|
561
420
|
|
|
562
421
|
export const projectConfig = Object.freeze({
|
|
@@ -579,7 +438,7 @@ export const projectConfig = Object.freeze({
|
|
|
579
438
|
'instant',
|
|
580
439
|
),
|
|
581
440
|
}),
|
|
582
|
-
locale:
|
|
441
|
+
locale: resolveLocale(rawConfig.language, siteConfigLabel),
|
|
583
442
|
});
|
|
584
443
|
|
|
585
444
|
export default projectConfig;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from 'astro/zod';
|
|
2
|
+
import { localEditorNames } from './edit-source-link.mjs';
|
|
2
3
|
import { imagePresentationNames } from './image-presentation.mjs';
|
|
4
|
+
import { supportedLocaleTagPattern } from './locale-registry.mjs';
|
|
3
5
|
import { navigationModeNames } from './navigation-model.mjs';
|
|
4
6
|
import { presentationPaletteNames } from './presentation-palette-metadata.mjs';
|
|
5
7
|
import { themePresetNames } from './theme-presets.mjs';
|
|
@@ -24,13 +26,6 @@ const themeAppearance = z.object({
|
|
|
24
26
|
(value) => value.default !== undefined,
|
|
25
27
|
'Specify default.',
|
|
26
28
|
).describe('Site-wide initial appearance. The default is system.');
|
|
27
|
-
const readerControls = z.object({
|
|
28
|
-
appearance: z.boolean().optional().describe('Show an Appearance control that lets readers choose System, Light, or Dark.'),
|
|
29
|
-
focusReading: z.boolean().optional().describe('Show a Focus reading control that lets readers hide navigation, breadcrumbs, and the footer. Sites with tree navigation always show this control.'),
|
|
30
|
-
}).strict().refine(
|
|
31
|
-
(value) => value.appearance !== undefined || value.focusReading !== undefined,
|
|
32
|
-
'Specify appearance, focusReading, or both.',
|
|
33
|
-
).describe('Optional controls for the site-wide Display panel.');
|
|
34
29
|
const spacingDensity = z.enum(['compact', 'normal', 'airy']).describe('Coordinated spacing density. Omit this to use the selected preset.');
|
|
35
30
|
const contentSpacing = z.enum(['compact', 'normal', 'spacious']).describe('Vertical spacing between page sections and structured content blocks.');
|
|
36
31
|
const backgroundPattern = z.enum(['uniform', 'alternating', 'accented']).describe('How coordinated backgrounds are assigned to H2 sections. Non-uniform patterns are unavailable with tree navigation.');
|
|
@@ -51,8 +46,15 @@ const editLink = z.object({
|
|
|
51
46
|
return false;
|
|
52
47
|
}
|
|
53
48
|
}, 'Use an absolute http or https URL without credentials, a query string, or a fragment.')
|
|
54
|
-
.describe('Absolute edit URL prefix containing the repository, branch, and any repository subdirectory.')
|
|
55
|
-
|
|
49
|
+
.describe('Absolute edit URL prefix containing the repository, branch, and any repository subdirectory.')
|
|
50
|
+
.optional(),
|
|
51
|
+
localEditor: z.enum(localEditorNames)
|
|
52
|
+
.optional()
|
|
53
|
+
.describe('Editor used by source links in a development preview opened through a loopback address.'),
|
|
54
|
+
}).strict().refine(
|
|
55
|
+
(value) => value.baseUrl !== undefined || value.localEditor !== undefined,
|
|
56
|
+
'Specify baseUrl, localEditor, or both.',
|
|
57
|
+
).describe('Optional local and remote links from rendered pages to their Markdown source files.');
|
|
56
58
|
const createLineHeight = (minimum, role) => z.number()
|
|
57
59
|
.min(minimum, `Use a unitless ${role} line height of at least ${minimum}.`)
|
|
58
60
|
.max(3, `Use a unitless ${role} line height of at most 3.`)
|
|
@@ -188,7 +190,7 @@ const themeBlocks = z.object({
|
|
|
188
190
|
'Specify cardList.',
|
|
189
191
|
).describe('Optional site-wide defaults for structured Norna content blocks.');
|
|
190
192
|
const configNavigation = z.object({
|
|
191
|
-
mode: navigationMode.optional().describe('
|
|
193
|
+
mode: navigationMode.optional().describe('How Norna presents the discovered page and heading hierarchy. Omit this to select automatic.'),
|
|
192
194
|
}).strict().describe('Site-wide navigation behavior.');
|
|
193
195
|
const themeSections = z.object({
|
|
194
196
|
backgroundPattern: backgroundPattern.optional().describe('Section background pattern. Alternating and accented create full-width bands with sections or top navigation; tree navigation requires uniform.'),
|
|
@@ -236,7 +238,7 @@ const sitewideFooter = z.object({
|
|
|
236
238
|
|
|
237
239
|
const configShape = {
|
|
238
240
|
url: z.string().url().describe('Absolute public URL for the built site.'),
|
|
239
|
-
language: z.string().regex(
|
|
241
|
+
language: z.string().regex(supportedLocaleTagPattern).optional().describe('Site language tag selecting one complete built-in Norna interface language; the default is en.'),
|
|
240
242
|
editLink: editLink.optional(),
|
|
241
243
|
navigation: configNavigation.optional(),
|
|
242
244
|
search: z.boolean().optional().default(false).describe('Generate a static site search page and Pagefind index. The default is false.'),
|
|
@@ -251,7 +253,6 @@ const siteShape = {
|
|
|
251
253
|
const themeVisualShape = {
|
|
252
254
|
preset: themePreset.optional().describe('Complete visual starting point. Add only the overrides the site actually needs.'),
|
|
253
255
|
appearance: themeAppearance.optional(),
|
|
254
|
-
readerControls: readerControls.optional(),
|
|
255
256
|
corners: cornerTreatment.optional().describe('Site-wide corner treatment. Omit this to use the selected preset.'),
|
|
256
257
|
layout: themeLayout.optional(),
|
|
257
258
|
images: themeImages.optional(),
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { documentationLink } from './documentation-links.mjs';
|
|
2
|
+
import {
|
|
3
|
+
localeDefinitions,
|
|
4
|
+
supportedQualifiedLocaleTagPatternSource,
|
|
5
|
+
} from './locale-registry.mjs';
|
|
2
6
|
import { presentationPaletteNames } from './presentation-palette-metadata.mjs';
|
|
3
7
|
import { getSchemaValueDefinition } from './schema-value-definitions.mjs';
|
|
4
8
|
|
|
@@ -105,20 +109,21 @@ const addValueDescriptions = (schema) => {
|
|
|
105
109
|
const addLanguageSuggestions = (jsonSchema) => {
|
|
106
110
|
const language = jsonSchema.properties?.language;
|
|
107
111
|
if (!language) throw new Error('Generated config schema has no language property.');
|
|
108
|
-
const definition = getSchemaValueDefinition(['en', 'sv']);
|
|
109
112
|
language.default = 'en';
|
|
110
|
-
language.examples = ['en', 'sv', 'en-GB', '
|
|
113
|
+
language.examples = ['en', 'sv', 'es', 'el', 'uk', 'sr-Cyrl', 'en-GB', 'pt-BR'];
|
|
111
114
|
language.oneOf = [
|
|
112
|
-
...
|
|
113
|
-
const:
|
|
114
|
-
title:
|
|
115
|
-
description:
|
|
115
|
+
...localeDefinitions.map(({ tag, name, nativeName, script, requiresScript }) => ({
|
|
116
|
+
const: tag,
|
|
117
|
+
title: nativeName === name ? name : `${nativeName} — ${name}`,
|
|
118
|
+
description: requiresScript
|
|
119
|
+
? `Use Norna's built-in ${name} interface text in the ${script} script.`
|
|
120
|
+
: `Use Norna's built-in ${name} interface text.`,
|
|
116
121
|
})),
|
|
117
122
|
{
|
|
118
123
|
type: 'string',
|
|
119
|
-
pattern:
|
|
120
|
-
title: 'Regional
|
|
121
|
-
description: '
|
|
124
|
+
pattern: supportedQualifiedLocaleTagPatternSource,
|
|
125
|
+
title: 'Regional or script-qualified tag',
|
|
126
|
+
description: 'Add a region to a supported language, such as en-GB, pt-BR, or sr-Cyrl-RS. Norna preserves the complete tag in generated HTML.',
|
|
122
127
|
},
|
|
123
128
|
];
|
|
124
129
|
};
|
|
@@ -156,34 +161,51 @@ const addConfigHelp = (jsonSchema) => {
|
|
|
156
161
|
], ['https://example.com/', 'https://owner.github.io/repository-name/']);
|
|
157
162
|
addHelp(jsonSchema, 'language', [
|
|
158
163
|
yamlExample('language: en-GB'),
|
|
159
|
-
'Sets the
|
|
164
|
+
'Sets the language of the complete site and selects the matching built-in Norna interface text. Regional tags are preserved. The default is `en`; editorial Markdown is not translated.',
|
|
160
165
|
documentationLink('Language reference', 'configuration.md', 'language'),
|
|
161
|
-
], ['en', 'sv', 'en-GB', '
|
|
166
|
+
], ['en', 'sv', 'es', 'el', 'uk', 'sr-Cyrl', 'en-GB', 'pt-BR']);
|
|
162
167
|
addHelp(jsonSchema, 'editLink', [
|
|
163
|
-
yamlExample('editLink:\n baseUrl: https://github.com/owner/repository/edit/main/'),
|
|
164
|
-
'
|
|
168
|
+
yamlExample('editLink:\n localEditor: vscode\n baseUrl: https://github.com/owner/repository/edit/main/'),
|
|
169
|
+
'Links 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.',
|
|
165
170
|
documentationLink('Edit-link reference', 'configuration.md', 'edit-link'),
|
|
166
171
|
]);
|
|
172
|
+
const editLink = schemaProperty(jsonSchema, 'editLink');
|
|
173
|
+
editLink.anyOf = [{ required: ['localEditor'] }, { required: ['baseUrl'] }];
|
|
174
|
+
addSnippets(jsonSchema, 'editLink', [schemaSnippet({
|
|
175
|
+
label: 'Local and remote source links',
|
|
176
|
+
body: {
|
|
177
|
+
localEditor: 'vscode',
|
|
178
|
+
baseUrl: 'https://github.com/${1:owner}/${2:repository}/edit/${3:main}/',
|
|
179
|
+
},
|
|
180
|
+
description: 'Open page source in VS Code during same-computer development and on the remote source host elsewhere.',
|
|
181
|
+
file: 'configuration.md',
|
|
182
|
+
anchor: 'edit-link',
|
|
183
|
+
})]);
|
|
167
184
|
addHelp(jsonSchema, 'editLink.baseUrl', [
|
|
168
185
|
yamlExample('editLink:\n baseUrl: https://github.com/owner/repository/edit/main/'),
|
|
169
|
-
'
|
|
186
|
+
'Optional 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.',
|
|
170
187
|
documentationLink('Edit-link reference', 'configuration.md', 'edit-link'),
|
|
171
188
|
], ['https://github.com/owner/repository/edit/main/']);
|
|
189
|
+
addHelp(jsonSchema, 'editLink.localEditor', [
|
|
190
|
+
yamlExample('editLink:\n localEditor: vscode'),
|
|
191
|
+
'Optional 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.',
|
|
192
|
+
documentationLink('Edit-link reference', 'configuration.md', 'edit-link'),
|
|
193
|
+
], ['vscode']);
|
|
172
194
|
addHelp(jsonSchema, 'navigation', [
|
|
173
195
|
yamlExample('navigation:\n mode: automatic'),
|
|
174
|
-
'
|
|
175
|
-
documentationLink('Navigation reference', '
|
|
196
|
+
'Chooses how Norna presents the discovered page and heading hierarchy. Keep `automatic` unless the site deliberately needs to retain one presentation as its structure changes.',
|
|
197
|
+
documentationLink('Navigation setting reference', 'configuration.md', 'navigation'),
|
|
176
198
|
]);
|
|
177
199
|
addHelp(jsonSchema, 'search', [
|
|
178
200
|
yamlExample('search: true'),
|
|
179
|
-
'Generates a localized `/search/` page and a static Pagefind index during each build. Search is off by default
|
|
201
|
+
'Generates a localized `/search/` page and a static Pagefind index during each build. Search is off by default. Only the search page loads the search engine and index; a small navigation script remembers where readers opened it.',
|
|
180
202
|
documentationLink('Search reference', 'configuration.md', 'search'),
|
|
181
203
|
], [true, false]);
|
|
182
204
|
addFieldHelp(
|
|
183
205
|
jsonSchema,
|
|
184
206
|
'navigation.mode',
|
|
185
207
|
'navigation:\n mode: automatic',
|
|
186
|
-
'
|
|
208
|
+
'configuration.md',
|
|
187
209
|
'navigation',
|
|
188
210
|
['automatic', 'sections', 'top', 'tree'],
|
|
189
211
|
);
|
|
@@ -261,7 +283,7 @@ const addThemeHelp = (jsonSchema) => {
|
|
|
261
283
|
], presentationPaletteNames);
|
|
262
284
|
addHelp(jsonSchema, 'appearance', [
|
|
263
285
|
yamlExample('appearance:\n default: system'),
|
|
264
|
-
'Selects the initial Appearance. Omit this setting to follow the visitor\'s system preference.
|
|
286
|
+
'Selects the initial Appearance. The Appearance choice is always available in the site-wide Display panel. Omit this setting to follow the visitor\'s system preference.',
|
|
265
287
|
documentationLink('Appearance', 'theme.md', 'appearance'),
|
|
266
288
|
]);
|
|
267
289
|
addFieldHelp(jsonSchema, 'appearance.default', 'appearance:\n default: system', 'theme.md', 'appearance', ['system', 'light', 'dark']);
|
|
@@ -272,32 +294,6 @@ const addThemeHelp = (jsonSchema) => {
|
|
|
272
294
|
file: 'theme.md',
|
|
273
295
|
anchor: 'appearance',
|
|
274
296
|
})]);
|
|
275
|
-
addHelp(jsonSchema, 'readerControls', [
|
|
276
|
-
yamlExample('readerControls:\n appearance: true\n focusReading: true'),
|
|
277
|
-
'Choose which optional controls readers can use in the site-wide Display panel.',
|
|
278
|
-
'`appearance: true` lets readers choose System, Light, or Dark. `focusReading: true` lets them hide navigation, breadcrumbs, and the footer while reading.',
|
|
279
|
-
'Reading width is always included. Sites with tree navigation always include Focus reading, even when it is not enabled here.',
|
|
280
|
-
documentationLink('Reader Display controls', 'theme.md', 'reader-display-controls'),
|
|
281
|
-
]);
|
|
282
|
-
for (const [propertyPath, example] of [
|
|
283
|
-
['readerControls.appearance', 'readerControls:\n appearance: true'],
|
|
284
|
-
['readerControls.focusReading', 'readerControls:\n focusReading: true'],
|
|
285
|
-
]) {
|
|
286
|
-
addFieldHelp(
|
|
287
|
-
jsonSchema,
|
|
288
|
-
propertyPath,
|
|
289
|
-
example,
|
|
290
|
-
'theme.md',
|
|
291
|
-
'reader-display-controls',
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
addSnippets(jsonSchema, 'readerControls', [schemaSnippet({
|
|
295
|
-
label: 'Configure the Display panel',
|
|
296
|
-
body: 'readerControls:\n appearance: ${1:true}\n focusReading: ${2:true}',
|
|
297
|
-
description: 'Show optional Appearance and Focus reading controls. Reading width is already included, and tree navigation always includes Focus reading.',
|
|
298
|
-
file: 'theme.md',
|
|
299
|
-
anchor: 'reader-display-controls',
|
|
300
|
-
})]);
|
|
301
297
|
addHelp(jsonSchema, 'sections', [
|
|
302
298
|
yamlExample('sections:\n backgroundPattern: alternating'),
|
|
303
299
|
'Chooses whether H2 section backgrounds stay uniform, alternate between two backgrounds or move from base to soft to emphasis and back through soft. Non-uniform patterns are available with sections and top navigation; tree navigation requires uniform.',
|
|
@@ -611,7 +607,7 @@ const addContentHelp = (jsonSchema) => {
|
|
|
611
607
|
const addCategoryHelp = (jsonSchema) => {
|
|
612
608
|
jsonSchema.markdownDescription = [
|
|
613
609
|
yamlExample('label: Guides'),
|
|
614
|
-
'`category.yaml`
|
|
610
|
+
'`category.yaml` groups child pages without editorial content. Its URL opens the first listed direct page, or a generated child list when the first child is a category.',
|
|
615
611
|
documentationLink('Navigation category reference', 'pages.md', 'navigation-categories'),
|
|
616
612
|
].join('\n\n');
|
|
617
613
|
addHelp(jsonSchema, 'label', [
|
|
@@ -23,14 +23,13 @@ export const schemaValueDefinitions = Object.freeze([
|
|
|
23
23
|
smooth: option('Browser smooth', 'Use the browser\'s native smooth scrolling for anchor navigation.'),
|
|
24
24
|
}),
|
|
25
25
|
definition(['automatic', 'sections', 'top', 'tree'], {
|
|
26
|
-
automatic: option('Automatic', 'Choose
|
|
27
|
-
sections: option('Sections', '
|
|
28
|
-
top: option('Top', '
|
|
29
|
-
tree: option('Tree', '
|
|
30
|
-
}),
|
|
31
|
-
definition(['
|
|
32
|
-
|
|
33
|
-
sv: option('Swedish', 'Use Norna\'s built-in Swedish interface text.'),
|
|
26
|
+
automatic: option('Automatic', 'Choose one site-wide navigation presentation from the listed page hierarchy. This is the default.'),
|
|
27
|
+
sections: option('Sections', 'Keep a one-page site title and its H2 sections in sticky page navigation.'),
|
|
28
|
+
top: option('Top', 'Keep top-level pages in the global row and give the current page section navigation when needed.'),
|
|
29
|
+
tree: option('Tree', 'Keep top-level areas global and add a persistent left page tree. Deep branches can add a right H2/H3 contents rail.'),
|
|
30
|
+
}),
|
|
31
|
+
definition(['vscode'], {
|
|
32
|
+
vscode: option('Visual Studio Code', 'Open the current page source in the locally installed Visual Studio Code application.'),
|
|
34
33
|
}),
|
|
35
34
|
definition(['left', 'center', 'right'], {
|
|
36
35
|
left: option('Left', 'Align text with the left edge of its text area.'),
|