@heroiclands/package-build 24.1.1 → 25.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +1 -0
- package/bin/content-commands.mjs +30 -96
- package/bin/encoding-commands.mjs +146 -0
- package/bin/package-build.mjs +35 -24
- package/config.mjs +25 -0
- package/convert.mjs +182 -0
- package/docs/api.md +154 -11
- package/docs/authoring/links-and-markup.md +260 -473
- package/docs/commands.md +118 -119
- package/docs/configuration.md +31 -13
- package/docs/content-format.md +11 -4
- package/docs/diagnostics.md +43 -16
- package/docs/encoding-core.md +135 -0
- package/docs/guides/book.md +2 -2
- package/docs/guides/module-project.md +23 -1
- package/docs/guides/site.md +2 -2
- package/docs/guides/writing-in-invented-scripts.md +453 -569
- package/docs/reference/format-details.md +290 -380
- package/docs/reference/note-types.md +80 -62
- package/docs/source-preview.md +8 -0
- package/e2e.mjs +1 -1
- package/engine/base-compiler.mjs +27 -9
- package/engine/content-charset.mjs +21 -1
- package/engine/content-format.yaml +7 -2
- package/engine/content-index.mjs +6 -2
- package/engine/content-links.mjs +1 -0
- package/engine/content-scripts.mjs +658 -423
- package/engine/content-scroll.mjs +4 -4
- package/engine/content-spans.mjs +40 -9
- package/engine/content-verse.mjs +1 -1
- package/engine/converter-data.mjs +70 -0
- package/engine/dictionary-rows.mjs +2 -34
- package/engine/encoding-integrity.mjs +94 -0
- package/engine/encoding-language.mjs +506 -0
- package/engine/encoding-lexicon.mjs +699 -0
- package/engine/encoding-notes.mjs +186 -0
- package/engine/encoding-standard.mjs +42 -0
- package/engine/encoding-template.mjs +313 -0
- package/engine/encoding-terms.mjs +141 -0
- package/engine/encoding.mjs +946 -0
- package/engine/extension-attributes.mjs +2 -0
- package/engine/helpers.mjs +1 -1
- package/engine/index.mjs +10 -0
- package/engine/language-data.mjs +4 -1
- package/engine/language-terms.mjs +23 -12
- package/engine/{logographic.mjs → language-writings.mjs} +29 -38
- package/engine/markup-validation.mjs +1 -1
- package/engine/note-vocabulary.mjs +4 -158
- package/engine/pdf-render.mjs +31 -3
- package/engine/roman-characters.mjs +232 -0
- package/engine/roman-run.mjs +149 -0
- package/engine/roman-verse.mjs +95 -0
- package/engine/run-rows.mjs +29 -31
- package/engine/run-words.mjs +2 -2
- package/engine/script-emphasis-terms.mjs +3 -0
- package/engine/script-emphasis.mjs +3 -10
- package/engine/script-font-delivery.mjs +9 -12
- package/engine/script-fonts.mjs +2 -1
- package/engine/site-build.mjs +14 -5
- package/engine/site-preview.mjs +12 -2
- package/engine/sql-tables.mjs +36 -31
- package/engine/verse-metre.mjs +1 -1
- package/engine/word-forms.mjs +1 -1
- package/engine/word-inflections.mjs +48 -0
- package/engine/word-rows.mjs +1 -1
- package/engine/word-terms.mjs +16 -17
- package/package.json +11 -5
- package/types/config.d.mts +5 -0
- package/types/convert.d.mts +44 -0
- package/types/e2e.d.mts +1 -1
- package/types/engine/base-compiler.d.mts +4 -2
- package/types/engine/content-charset.d.mts +8 -0
- package/types/engine/content-index.d.mts +4 -1
- package/types/engine/content-scripts.d.mts +108 -42
- package/types/engine/converter-data.d.mts +11 -0
- package/types/engine/dictionary-rows.d.mts +1 -25
- package/types/engine/encoding-integrity.d.mts +14 -0
- package/types/engine/encoding-language.d.mts +36 -0
- package/types/engine/encoding-lexicon.d.mts +259 -0
- package/types/engine/encoding-notes.d.mts +39 -0
- package/types/engine/encoding-standard.d.mts +11 -0
- package/types/engine/encoding-template.d.mts +43 -0
- package/types/engine/encoding-terms.d.mts +105 -0
- package/types/engine/encoding.d.mts +155 -0
- package/types/engine/helpers.d.mts +1 -1
- package/types/engine/index.d.mts +5 -0
- package/types/engine/language-terms.d.mts +1 -1
- package/types/engine/{logographic.d.mts → language-writings.d.mts} +6 -6
- package/types/engine/markup-validation.d.mts +1 -1
- package/types/engine/pdf-render.d.mts +1 -1
- package/types/engine/roman-characters.d.mts +45 -0
- package/types/engine/roman-run.d.mts +101 -0
- package/types/engine/roman-verse.d.mts +23 -0
- package/types/engine/run-rows.d.mts +13 -20
- package/types/engine/script-emphasis-terms.d.mts +2 -0
- package/types/engine/script-emphasis.d.mts +1 -1
- package/types/engine/script-font-delivery.d.mts +2 -3
- package/types/engine/script-fonts.d.mts +5 -0
- package/types/engine/site-preview.d.mts +1 -1
- package/types/engine/word-inflections.d.mts +25 -0
- package/engine/map-lexicon.mjs +0 -1034
- package/engine/text-maps.mjs +0 -654
- package/engine/written-in.mjs +0 -204
- package/types/engine/map-lexicon.d.mts +0 -330
- package/types/engine/text-maps.d.mts +0 -189
- package/types/engine/written-in.d.mts +0 -76
|
@@ -468,7 +468,8 @@ These fields are accepted by every note type. A field's value can still be irrel
|
|
|
468
468
|
| `data.fields` | list of `{ name, holds }` | The fields the language's words are grouped under. A language skill note only. |
|
|
469
469
|
| `data.words` | list of `{ form, class, field, gloss, … }` | The words this language states, one map each, in authored order; its automatic dictionary sorts them alphabetically. A language skill note only. See [a language's words](format-details.md#a-languages-words). |
|
|
470
470
|
| `data.affixes` | list of `{ form, gloss, attaches?, examples? }` | The affixes a word's `built` pieces may name, each with its gloss. A language skill note only. |
|
|
471
|
-
| `data.
|
|
471
|
+
| `data.roman` | a literal NFC string of additional source characters, including exact letter case and digits | The additional Roman source characters the language permits, each once. Standard punctuation and structural whitespace remain available. No ranges, case expansion or inherited inventory. An empty string declares no additions. Required on each configured language note. |
|
|
472
|
+
| `data.grammar` | a map — `{ plural?, verbs?, agreement?, participles?, native? }` | Optional noun plurals, one verb pattern, agreement, participles and the endings' native writings, for dictionary presentation, language word checks and encodings. Only the shape of supplied keys is checked; no word must follow or state a rule. A language skill note only. |
|
|
472
473
|
| `data.tongues` | list of `{ tag, meaning, language? }` | The tags a register row's `tongue` may name, each with what it means. A language skill note only. |
|
|
473
474
|
| `data.register` | list of `{ name, tongue?, kind?, built?, gloss?, why? }` | Every name the setting gives in the language's reach, with its tongue and pieces; the notes carrying each name are derived. A language skill note only. |
|
|
474
475
|
| `data.retired` | list of `{ form, instead?, why }` | The forms the setting does not write, and why. A language skill note only. |
|
|
@@ -483,8 +484,7 @@ These fields are accepted by every note type. A field's value can still be irrel
|
|
|
483
484
|
| `data.negation` | a map — `{ particle, mutation? }` | How a verb is negated. A language skill note only. |
|
|
484
485
|
| `data.naming` | a map — `{ shapes?, edges?, draws?, heldFrom?, nearName? }` | The shapes, edges and sources the language's names keep beyond its words' rules. A language skill note only. |
|
|
485
486
|
| `data.emphasis` | `words`, `rubric` or `overline` | How the language marks a stressed word, over its script's `emphasis`: `rubric` or `overline` sets `*…*` and `**…**` so in a run of the language, and `words` marks it with a word, so either is a finding. Only a skill of `subType: language` states it. |
|
|
486
|
-
| `data.
|
|
487
|
-
| `data.script` | a map — `{ fonts, emphasis, strongEmphasis?, direction? }` | A script note's faces, how it marks emphasis and the direction it is written in. Only a skill of `subType: script` states it. |
|
|
487
|
+
| `data.script` | a map — `{ fonts, emphasis, direction? }` | A script note's faces, how it marks emphasis and the direction it is written in. Only a skill of `subType: script` states it. |
|
|
488
488
|
|
|
489
489
|
**Inner keys** — a key a field's value does not declare is an error at its own line and column.
|
|
490
490
|
|
|
@@ -512,10 +512,10 @@ These fields are accepted by every note type. A field's value can still be irrel
|
|
|
512
512
|
| `data.words[].tones` | a string | no | A tone pattern, such as `LHL`. |
|
|
513
513
|
| `data.words[].root` | a string | no | A consonantal skeleton, such as `d-l-k`. |
|
|
514
514
|
| `data.words[].frame` | a frame of the language's `sounds.frames` | no | The frame a root is set in, named in the language's `sounds.frames`. |
|
|
515
|
-
| `data.words[].native` | a list of `{
|
|
516
|
-
| `data.words[].native[].
|
|
517
|
-
| `data.words[].native[].font` | a face the
|
|
518
|
-
| `data.words[].native[].text` | the word in the script, as the
|
|
515
|
+
| `data.words[].native` | a list of `{ enc, font?, text }` | no | The word's own writing for an encoding and optional face. It precedes complete parts and the encoding's rows; an entry for a face precedes an unqualified entry. Derived forms can use the stem and explicitly written grammatical endings. |
|
|
516
|
+
| `data.words[].native[].enc` | an encoding document Address | yes | The encoding the native form is written for. |
|
|
517
|
+
| `data.words[].native[].font` | a face the encoding lists | no | The one face the native form is for; unstated, it is for every face the encoding lists, and a form stated for a face wins over it there. |
|
|
518
|
+
| `data.words[].native[].text` | the word in the script, as the encoding's characters | yes | The word as the script writes it, where the encoding's rows would write it otherwise, or by an explicit native spelling. |
|
|
519
519
|
| `data.affixes[].form` | the affix as written, such as `-rith` | no | The affix as a word's `built` names it; absent on a zero affix. |
|
|
520
520
|
| `data.affixes[].zero` | `true` | no | The affix is written as nothing, such as a case with no ending; it states no `form`, prints as `∅`, and no `built` piece names it. |
|
|
521
521
|
| `data.affixes[].kind` | one of case, derivation, tense, aspect, mood, voice, name, lineage | no | What the affix makes. |
|
|
@@ -530,10 +530,10 @@ These fields are accepted by every note type. A field's value can still be irrel
|
|
|
530
530
|
| `data.affixes[].examples` | a list of strings | no | The names the affix is read from. |
|
|
531
531
|
| `data.affixes[].barredAfter` | a list of sounds | no | The sounds a stem may not close on to take the affix. |
|
|
532
532
|
| `data.affixes[].tones` | a tone pattern, such as `L` | no | The tone pattern the affix carries, written as a word's `tones` is. |
|
|
533
|
-
| `data.affixes[].native` | a list of `{
|
|
534
|
-
| `data.affixes[].native[].
|
|
535
|
-
| `data.affixes[].native[].font` | a face the
|
|
536
|
-
| `data.affixes[].native[].text` | the word in the script, as the
|
|
533
|
+
| `data.affixes[].native` | a list of `{ enc, font?, text }` | no | The affix's writing under an encoding, which a word whose `built` names the affix is written with. |
|
|
534
|
+
| `data.affixes[].native[].enc` | an encoding document Address | yes | The encoding the native form is written for. |
|
|
535
|
+
| `data.affixes[].native[].font` | a face the encoding lists | no | The one face the native form is for; unstated, it is for every face the encoding lists, and a form stated for a face wins over it there. |
|
|
536
|
+
| `data.affixes[].native[].text` | the word in the script, as the encoding's characters | yes | The word as the script writes it, where the encoding's rows would write it otherwise, or by an explicit native spelling. |
|
|
537
537
|
| `data.grammar.plural` | list of `{ ending, becomes }` | no | Default noun plurals, replacing the first matching literal ending in authored order. A word's explicit plural wins; no word is checked against this rule. |
|
|
538
538
|
| `data.grammar.plural[].ending` | a literal ending string, which may be empty | yes | The bare suffix replaced by this rule; empty matches every noun. |
|
|
539
539
|
| `data.grammar.plural[].becomes` | a literal ending string, which may be empty | yes | The bare replacement; empty removes the matching suffix. |
|
|
@@ -553,10 +553,10 @@ These fields are accepted by every note type. A field's value can still be irrel
|
|
|
553
553
|
| `data.grammar.participles` | a map — `{ root, affixes }` | no | Participles on the verb root: a verb closing on a `root` ending drops it, and each named suffix attaches to what is left; a participle closing on an `agreement` ending agrees. Read by the mapped-run word check. |
|
|
554
554
|
| `data.grammar.participles.root` | a list of closing letters, such as `[athen, ethen]` | yes | The infinitive endings a verb's citation form drops to give its root, the longest that matches first. A verb closing on none has no participle. |
|
|
555
555
|
| `data.grammar.participles.affixes` | a list of suffixes of `data.affixes`, such as `[-andar, -thos]` | yes | The participle suffixes, each attaching to the root as its own `replaces` says: `vowel` or letters take the place of the root's close, and none adds it whole. |
|
|
556
|
-
| `data.grammar.native` | a list of `{ ending,
|
|
556
|
+
| `data.grammar.native` | a list of `{ ending, enc, font?, text }` | no | Under an encoding, the signs a noun's plural or a verb's present form is written with after its stem's writing, one entry per ending, encoding and face. |
|
|
557
557
|
| `data.grammar.native[].ending` | one of plural, I, you, heShe, we, youAll, they | yes | The ending written: `plural` for a noun's plural, or a person of `verbs.persons` for a verb's present form. |
|
|
558
|
-
| `data.grammar.native[].
|
|
559
|
-
| `data.grammar.native[].font` | a face the
|
|
558
|
+
| `data.grammar.native[].enc` | an encoding document Address | yes | The encoding the ending is written for. |
|
|
559
|
+
| `data.grammar.native[].font` | a face the encoding lists | no | The one face the writing is for; unstated, it is for every face the encoding lists, and a writing stated for a face wins over it there. |
|
|
560
560
|
| `data.grammar.native[].text` | the ending in the script, as the map's characters; empty writes the stem alone | yes | The signs written after the stem's writing. |
|
|
561
561
|
| `data.tongues[].tag` | a tag such as `dunhari`, or `exonym:<tongue>` | yes | The tag a register row's `tongue` names: lowercase letters and digits, or a tag closing on `:<tongue>`, which declares one tag per tongue named after the colon. |
|
|
562
562
|
| `data.tongues[].meaning` | a string | yes | What a name of this tongue is. |
|
|
@@ -711,11 +711,8 @@ These fields are accepted by every note type. A field's value can still be irrel
|
|
|
711
711
|
| `data.naming.nearName.examples` | list of `{ near, given }` | no | Worked near names, each beside its given name. |
|
|
712
712
|
| `data.naming.nearName.examples[].near` | a near name, such as `Anlâ` | yes | The near name. |
|
|
713
713
|
| `data.naming.nearName.examples[].given` | a given name | yes | The given name it is the near name of. |
|
|
714
|
-
| `data.writtenIn.map` | a mapping note's `data.map.name` | yes | The map the language's text is written by. |
|
|
715
|
-
| `data.writtenIn.font` | an installed face's slug | yes | The face the text is set in, one the map is drawn in. |
|
|
716
714
|
| `data.script.fonts` | list of installed faces' slugs | yes | The faces the script is written in, by the slug `font=` names them by. A face belongs to one script. |
|
|
717
|
-
| `data.script.emphasis` | `rubric` or `overline` | yes | How the script marks a stressed word: `rubric` sets it in red, `overline` draws a line above it. It sets
|
|
718
|
-
| `data.script.strongEmphasis` | `rubric` or `overline` | no | The convention `**…**` takes instead of `emphasis`'s. |
|
|
715
|
+
| `data.script.emphasis` | `rubric` or `overline` | yes | How the script marks a stressed word: `rubric` sets it in red, `overline` draws a line above it. It sets `.emph` and accepted English emphasis inside a run in one of its faces, unless the run's language states its own `emphasis`. |
|
|
719
716
|
| `data.script.direction` | `vertical-rl` | no | How the script is written: `vertical-rl` is columns, top to bottom, read from the right, which a `scroll` fence sets. A script stating none is written in lines. |
|
|
720
717
|
|
|
721
718
|
**System mappings**
|
|
@@ -1000,53 +997,74 @@ Lore records in-world knowledge. A `culture` describes a people; a `custom` desc
|
|
|
1000
997
|
|
|
1001
998
|
**Subtypes:** `rules`, `userguide`, `reference`, `howto`, `concept`, `settingguide`, `post`.
|
|
1002
999
|
|
|
1003
|
-
| Field | Shape
|
|
1004
|
-
| --------------- |
|
|
1005
|
-
| `data.
|
|
1006
|
-
| `data.
|
|
1007
|
-
| `data.
|
|
1008
|
-
| `data.
|
|
1009
|
-
| `data.
|
|
1010
|
-
| `data.
|
|
1011
|
-
| `data.
|
|
1000
|
+
| Field | Shape | Meaning |
|
|
1001
|
+
| --------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1002
|
+
| `data.language` | a configured language alias | The configured language alias an encoding document writes. |
|
|
1003
|
+
| `data.font` | an installed font slug | The encoding's installed font, which supplies all glyph codes. |
|
|
1004
|
+
| `data.accepts` | a list of characters or ranges | Accepted Roman letters and additions to standard punctuation. |
|
|
1005
|
+
| `data.vowels` | a string | The letters a contextual vowel match reads as vowels. |
|
|
1006
|
+
| `data.mappings` | Roman strings to glyph codes | Roman source strings mapped to codes published by the selected font. |
|
|
1007
|
+
| `data.rules` | the closed encoding rules vocabulary | Executable normalization, matching, case, stress, vowel groups, accents and contextual mappings. |
|
|
1008
|
+
| `data.concepts` | list of `{ id, gloss, group }` | The concepts of a core vocabulary, in the order the report lists them. See [the core vocabulary](format-details.md#the-core-vocabulary). |
|
|
1009
|
+
| `data.date` | string | The day a post was published, as `YYYY-MM-DD`. Required on a `post`; no other subType states it. Posts are listed and fed newest first by it. |
|
|
1010
|
+
| `data.author` | string | Who wrote a post, as the byline prints them. A post that names none carries the site's byline, the first entry of `authors`; no other subType states it. |
|
|
1011
|
+
| `data.culture` | an Address | The culture a setting guide introduces, as a culture lore note. Required on `settingguide`; no other subType states it. |
|
|
1012
|
+
| `data.sounds` | a map — `{ letters?, marks? }` | A spelling guide's letters and the marks written on them, for every tongue of the setting: each letter row's `tongue` names the language notes that write it. |
|
|
1013
|
+
| `data.metres` | list of `{ name, beats, kind }` | The metres a verse fence's `scan=` names. A fence that states one is warned at each line that cannot have its beats. See [metres](../authoring/links-and-markup.md#metre). |
|
|
1012
1014
|
|
|
1013
1015
|
**Inner keys** — a key a field's value does not declare is an error at its own line and column.
|
|
1014
1016
|
|
|
1015
|
-
| Key
|
|
1016
|
-
|
|
|
1017
|
-
| `data.
|
|
1018
|
-
| `data.
|
|
1019
|
-
| `data.
|
|
1020
|
-
| `data.
|
|
1021
|
-
| `data.
|
|
1022
|
-
| `data.
|
|
1023
|
-
| `data.
|
|
1024
|
-
| `data.
|
|
1025
|
-
| `data.
|
|
1026
|
-
| `data.
|
|
1027
|
-
| `data.
|
|
1028
|
-
| `data.
|
|
1029
|
-
| `data.
|
|
1030
|
-
| `data.
|
|
1031
|
-
| `data.
|
|
1032
|
-
| `data.
|
|
1033
|
-
| `data.
|
|
1034
|
-
| `data.
|
|
1035
|
-
| `data.
|
|
1036
|
-
| `data.
|
|
1037
|
-
| `data.
|
|
1038
|
-
| `data.
|
|
1039
|
-
| `data.
|
|
1040
|
-
| `data.
|
|
1041
|
-
| `data.
|
|
1042
|
-
| `data.
|
|
1043
|
-
| `data.
|
|
1044
|
-
| `data.
|
|
1045
|
-
| `data.
|
|
1046
|
-
| `data.
|
|
1047
|
-
| `data.
|
|
1048
|
-
| `data.
|
|
1049
|
-
| `data.
|
|
1017
|
+
| Key | Shape | Required | Meaning |
|
|
1018
|
+
| ------------------------------------------------------ | ------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1019
|
+
| `data.rules.normalization` | "NFC" | yes | Required value: "NFC". |
|
|
1020
|
+
| `data.rules.matching` | "longest-first" | yes | Required value: "longest-first". |
|
|
1021
|
+
| `data.rules.case` | a map | no | Case handling for letters and consonant groups. |
|
|
1022
|
+
| `data.rules.case.single-letter` | "preserve" | yes | Required value: "preserve". |
|
|
1023
|
+
| `data.rules.case.consonant-group` | "lowercase-or-initial-uppercase" | yes | Required value: "lowercase-or-initial-uppercase". |
|
|
1024
|
+
| `data.rules.case.other-group-cases` | "forbidden" | yes | Required value: "forbidden". |
|
|
1025
|
+
| `data.rules.stress` | a map | no | The font's nonprinting stress modifier after an acute vowel. |
|
|
1026
|
+
| `data.rules.stress.modifier` | a string | yes | The font code for U+E0114. |
|
|
1027
|
+
| `data.rules.stress.position` | "after-stressed-vowel" | yes | Required value: "after-stressed-vowel". |
|
|
1028
|
+
| `data.rules.stress.printing` | false | yes | Required value: false. |
|
|
1029
|
+
| `data.rules.stress.effect` | "stress-only" | yes | Required value: "stress-only". |
|
|
1030
|
+
| `data.rules.stress.changes-sound` | false | yes | Required value: false. |
|
|
1031
|
+
| `data.rules.stress.changes-length` | false | yes | Required value: false. |
|
|
1032
|
+
| `data.rules.stress.vowel-group-position` | "first-vowel" | yes | Required value: "first-vowel". |
|
|
1033
|
+
| `data.rules.vowel-groups` | a map | no | Explicit recognized vowel groups and their acute placement. |
|
|
1034
|
+
| `data.rules.vowel-groups.reading` | "established" | yes | Required value: "established". |
|
|
1035
|
+
| `data.rules.vowel-groups.allow-splitting` | false | yes | Required value: false. |
|
|
1036
|
+
| `data.rules.vowel-groups.unrecognized-adjacent-vowels` | "separate" | yes | Required value: "separate". |
|
|
1037
|
+
| `data.rules.vowel-groups.groups` | a list of vowel groups | yes | The complete authored group inventory. |
|
|
1038
|
+
| `data.rules.diaeresis` | a map | no | Whether diaeresis mappings are allowed. |
|
|
1039
|
+
| `data.rules.diaeresis.allowed` | false | yes | Required value: false. |
|
|
1040
|
+
| `data.rules.grave-accent` | a map | no | Whether grave-accent mappings are allowed. |
|
|
1041
|
+
| `data.rules.grave-accent.allowed` | false | yes | Required value: false. |
|
|
1042
|
+
| `data.rules.contextual-mappings` | a list of conditional mappings | no | Before-vowel alternatives applied before unconditional mappings. |
|
|
1043
|
+
| `data.rules.contextual-mappings[].match` | a string | yes | The source sequence. |
|
|
1044
|
+
| `data.rules.contextual-mappings[].before` | "vowel" | yes | Required value: "vowel". |
|
|
1045
|
+
| `data.rules.contextual-mappings[].emit` | a glyph code or list of codes | yes | The font codes written by this alternative. |
|
|
1046
|
+
| `data.rules.y` | a map | no | The consonant reading of y. |
|
|
1047
|
+
| `data.rules.y.kind` | "consonant" | yes | Required value: "consonant". |
|
|
1048
|
+
| `data.rules.y.sound` | "y in yes" | yes | Required value: "y in yes". |
|
|
1049
|
+
| `data.rules.y.vowel-reading` | false | yes | Required value: false. |
|
|
1050
|
+
| `data.concepts[].id` | lowercase letters, digits and `-` | yes | The concept's id, which a word's `concept` names. Unique in the package. |
|
|
1051
|
+
| `data.concepts[].gloss` | a short gloss, such as `a smell; a scent` | yes | What the concept means, in brief. |
|
|
1052
|
+
| `data.concepts[].group` | a group name, such as `senses` | yes | The group the report lists the concept under. |
|
|
1053
|
+
| `data.sounds.letters` | list of `{ letters, kind, like?, place?, ipa?, tongue? }` | no | The letters the language writes, and the sounds they stand for. |
|
|
1054
|
+
| `data.sounds.letters[].letters` | a list of letters | yes | The letters or digraphs the row describes, as written. |
|
|
1055
|
+
| `data.sounds.letters[].kind` | a string, such as `consonant` or `long vowel` | yes | What kind of sound they write. |
|
|
1056
|
+
| `data.sounds.letters[].like` | a string | no | What they sound like; absent where the row states only their kind and place. |
|
|
1057
|
+
| `data.sounds.letters[].place` | a string, such as `lips` or `tongue-tip` | no | Where in the mouth they are made. |
|
|
1058
|
+
| `data.sounds.letters[].ipa` | a string in the International Phonetic Alphabet, such as `ʃ` | no | The sounds they write, in the International Phonetic Alphabet. |
|
|
1059
|
+
| `data.sounds.letters[].tongue` | a tag or a language note's Address, or a list of them | no | The tongues that write them, each a tag `data.tongues` declares or the Address of a language note; every one where absent. A `doc` note's rows name language notes only. |
|
|
1060
|
+
| `data.sounds.marks` | list of `{ mark, letters, kind, limit }` | no | The marks the language writes on its letters. |
|
|
1061
|
+
| `data.sounds.marks[].mark` | a string, such as `acute` | yes | The mark's name. |
|
|
1062
|
+
| `data.sounds.marks[].letters` | a list of letters | yes | The letters that carry it. |
|
|
1063
|
+
| `data.sounds.marks[].kind` | one of stress, length, apart | yes | What the mark says of its letter. |
|
|
1064
|
+
| `data.sounds.marks[].limit` | one of one, any | yes | How many a word may carry: `one` at most, or `any`. |
|
|
1065
|
+
| `data.metres[].name` | string | yes | What a verse fence's `scan=` names the metre by: lowercase letters, digits and `-`, unique in the package. |
|
|
1066
|
+
| `data.metres[].beats` | a whole number above zero | yes | The beats of one line. |
|
|
1067
|
+
| `data.metres[].kind` | one of accentual | yes | How the beats are counted: `accentual`, one beat for each stressed syllable the language's stress rule and the beat convention give. |
|
|
1050
1068
|
|
|
1051
1069
|
### macro
|
|
1052
1070
|
|
package/docs/source-preview.md
CHANGED
|
@@ -39,6 +39,14 @@ picture, marked text is mapped and set in its face, an icon is drawn, and a
|
|
|
39
39
|
caption is numbered with its asset's role, so a map is a **Map**. A query, which
|
|
40
40
|
a buffer cannot run, stays highlighted source in both views.
|
|
41
41
|
|
|
42
|
+
With an index, a marked-text run that cannot be set produces an error finding
|
|
43
|
+
and sets the result's `ok` to `false`. The preview still returns recoverable
|
|
44
|
+
HTML, including the Roman text of a failed native-script run. Findings identify
|
|
45
|
+
the supplied `file`, severity, message, line and column in the authored buffer,
|
|
46
|
+
including its frontmatter lines; expansion does not shift their positions.
|
|
47
|
+
Hosts can display that HTML beside the findings. Without an index, marked text
|
|
48
|
+
stays highlighted source and produces no run findings.
|
|
49
|
+
|
|
42
50
|
Wikilinks, image and portrait links retain their complete source: blue brackets,
|
|
43
51
|
purple addresses, bold foreground labels and grey attributes. Entire spans are bold, including their visible brackets and attributes.
|
|
44
52
|
Definition-list terms are bold and definitions use normal text. SQL and pagelist fences remain grey source;
|
package/e2e.mjs
CHANGED
|
@@ -799,7 +799,7 @@ export function suiteExecutables(command) {
|
|
|
799
799
|
}
|
|
800
800
|
|
|
801
801
|
/** The Chrome for Testing build shared by local and CI Cypress runs. */
|
|
802
|
-
export const CHROME_BUILD_ID = "158.0.
|
|
802
|
+
export const CHROME_BUILD_ID = "158.0.8122.0";
|
|
803
803
|
|
|
804
804
|
/**
|
|
805
805
|
* The browser cache survives reseeding and container teardown.
|
package/engine/base-compiler.mjs
CHANGED
|
@@ -633,9 +633,24 @@ export class BasePackCompiler {
|
|
|
633
633
|
* @throws {Error} When `findings` is non-empty, after reporting all of them.
|
|
634
634
|
*/
|
|
635
635
|
reportConvertBodyFindings(findings) {
|
|
636
|
+
this.externalBodyFindings ??= new Set();
|
|
636
637
|
for (const finding of findings) {
|
|
638
|
+
if (finding.file && finding.file !== this.currentNote?.absPath) {
|
|
639
|
+
const key = JSON.stringify([
|
|
640
|
+
finding.file,
|
|
641
|
+
finding.line,
|
|
642
|
+
finding.column,
|
|
643
|
+
finding.message,
|
|
644
|
+
]);
|
|
645
|
+
if (this.externalBodyFindings.has(key)) continue;
|
|
646
|
+
this.externalBodyFindings.add(key);
|
|
647
|
+
}
|
|
637
648
|
this.errorCount++;
|
|
638
|
-
this.noteError(finding.message, {
|
|
649
|
+
this.noteError(finding.message, {
|
|
650
|
+
file: finding.file,
|
|
651
|
+
line: finding.line,
|
|
652
|
+
column: finding.column,
|
|
653
|
+
});
|
|
639
654
|
}
|
|
640
655
|
if (findings.length) {
|
|
641
656
|
const error = new Error(
|
|
@@ -670,10 +685,13 @@ export class BasePackCompiler {
|
|
|
670
685
|
const bodyColumn = this.currentNote?.bodyColumn ?? 1;
|
|
671
686
|
// A finding's body position, in the file. The parser trims the body,
|
|
672
687
|
// so only its first line is offset by the column the body starts at.
|
|
673
|
-
const inFile = ({ line, column }) =>
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
688
|
+
const inFile = ({ file, line, column }) =>
|
|
689
|
+
file ?
|
|
690
|
+
{ file, line, column }
|
|
691
|
+
: {
|
|
692
|
+
line: bodyLine + line - 1,
|
|
693
|
+
column: line === 1 && column !== undefined ? bodyColumn + column - 1 : column,
|
|
694
|
+
};
|
|
677
695
|
const syntax = this.corpus?.syntax;
|
|
678
696
|
const scanned = syntax?.(body);
|
|
679
697
|
for (const secretError of [
|
|
@@ -893,12 +911,12 @@ export class BasePackCompiler {
|
|
|
893
911
|
* naming the file alone beats naming a line that is not the problem.
|
|
894
912
|
*
|
|
895
913
|
* @param {string} message - What is wrong, in one sentence.
|
|
896
|
-
* @param {{line?: number, column?: number}} [position] - Where, if known.
|
|
914
|
+
* @param {{file?: string, line?: number, column?: number}} [position] - Where, if known.
|
|
897
915
|
* @returns {void}
|
|
898
916
|
*/
|
|
899
917
|
noteWarn(message, position) {
|
|
900
918
|
emitDiagnostic({
|
|
901
|
-
file: this.currentNote?.absPath,
|
|
919
|
+
file: position?.file ?? this.currentNote?.absPath,
|
|
902
920
|
line: position?.line,
|
|
903
921
|
column: position?.column,
|
|
904
922
|
severity: "warning",
|
|
@@ -910,12 +928,12 @@ export class BasePackCompiler {
|
|
|
910
928
|
* Reports an error about the note being compiled.
|
|
911
929
|
*
|
|
912
930
|
* @param {string} message - What is wrong, in one sentence.
|
|
913
|
-
* @param {{line?: number, column?: number}} [position] - Where, if known.
|
|
931
|
+
* @param {{file?: string, line?: number, column?: number}} [position] - Where, if known.
|
|
914
932
|
* @returns {void}
|
|
915
933
|
*/
|
|
916
934
|
noteError(message, position) {
|
|
917
935
|
emitDiagnostic({
|
|
918
|
-
file: this.currentNote?.absPath,
|
|
936
|
+
file: position?.file ?? this.currentNote?.absPath,
|
|
919
937
|
line: position?.line,
|
|
920
938
|
column: position?.column,
|
|
921
939
|
severity: "error",
|
|
@@ -125,6 +125,13 @@ export function isLetterTier(cp) {
|
|
|
125
125
|
*/
|
|
126
126
|
export const TYPOGRAPHY = Object.freeze(
|
|
127
127
|
new Set([
|
|
128
|
+
0x00ab, // « outer quotation open
|
|
129
|
+
0x00bb, // » outer quotation close
|
|
130
|
+
0x2039, // ‹ inner quotation open
|
|
131
|
+
0x203a, // › inner quotation close
|
|
132
|
+
0x203c, // ‼ imperative terminal
|
|
133
|
+
0x27e6, // ⟦ codage open
|
|
134
|
+
0x27e7, // ⟧ codage close
|
|
128
135
|
0x2013, // – en dash
|
|
129
136
|
0x2014, // — em dash
|
|
130
137
|
0x2018, // ' left single quote
|
|
@@ -170,12 +177,24 @@ export const NOTATION = Object.freeze(
|
|
|
170
177
|
*/
|
|
171
178
|
const SCRIPT_BLOCKS = Object.freeze([
|
|
172
179
|
[0xf0000, 0xf2fff], // plane 15: Pirzath, Thuravark, Semaron, the reserved alphabets, Teng Chou
|
|
180
|
+
[0xf3000, 0xf3fff], // Ch'alish P'ilam Common
|
|
173
181
|
[0x1e960, 0x1ec6f], // Zethu overflow, Qalezu, Zethu
|
|
174
182
|
[0x1ecc0, 0x1ecff], // Qalezu catch-before forms
|
|
175
183
|
[0x1ed50, 0x1ed7f], // Veldikko
|
|
176
184
|
[0x13430, 0x1345f], // the Egyptian format controls Zethu uses
|
|
177
185
|
]);
|
|
178
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Whether a code point belongs to a declared setting-script encoding block.
|
|
189
|
+
* This identifies native input independently of a language's Roman inventory;
|
|
190
|
+
* a selected native face must still draw the individual character.
|
|
191
|
+
* @param {number} cp - A Unicode code point.
|
|
192
|
+
* @returns {boolean}
|
|
193
|
+
*/
|
|
194
|
+
export function isSettingScriptCodePoint(cp) {
|
|
195
|
+
return SCRIPT_BLOCKS.some(([from, to]) => cp >= from && cp <= to);
|
|
196
|
+
}
|
|
197
|
+
|
|
179
198
|
/**
|
|
180
199
|
* Whether the charset admits a code point anywhere in a note.
|
|
181
200
|
*
|
|
@@ -187,7 +206,8 @@ export function isAllowedCodePoint(cp) {
|
|
|
187
206
|
isLetterTier(cp) ||
|
|
188
207
|
TYPOGRAPHY.has(cp) ||
|
|
189
208
|
NOTATION.has(cp) ||
|
|
190
|
-
|
|
209
|
+
isSettingScriptCodePoint(cp) ||
|
|
210
|
+
(cp >= 0xe0100 && cp <= 0xe01ef)
|
|
191
211
|
);
|
|
192
212
|
}
|
|
193
213
|
|
|
@@ -200,6 +200,7 @@ types:
|
|
|
200
200
|
- other
|
|
201
201
|
skill:
|
|
202
202
|
data:
|
|
203
|
+
- roman
|
|
203
204
|
- grammar
|
|
204
205
|
- templatePriority
|
|
205
206
|
- masteryLevel
|
|
@@ -226,7 +227,6 @@ types:
|
|
|
226
227
|
- negation
|
|
227
228
|
- naming
|
|
228
229
|
- emphasis
|
|
229
|
-
- writtenIn
|
|
230
230
|
- script
|
|
231
231
|
subTypes:
|
|
232
232
|
- social
|
|
@@ -366,12 +366,17 @@ types:
|
|
|
366
366
|
- encounter
|
|
367
367
|
doc:
|
|
368
368
|
data:
|
|
369
|
+
- language
|
|
370
|
+
- font
|
|
371
|
+
- accepts
|
|
372
|
+
- vowels
|
|
373
|
+
- mappings
|
|
374
|
+
- rules
|
|
369
375
|
- culture
|
|
370
376
|
- concepts
|
|
371
377
|
- date
|
|
372
378
|
- author
|
|
373
379
|
- sounds
|
|
374
|
-
- map
|
|
375
380
|
- metres
|
|
376
381
|
subTypes:
|
|
377
382
|
- rules
|
package/engine/content-index.mjs
CHANGED
|
@@ -106,7 +106,7 @@ import { AddressLink } from "./address-values.mjs";
|
|
|
106
106
|
import { scanSpans } from "./content-spans.mjs";
|
|
107
107
|
import { rebaseNameSpans } from "./name-markup.mjs";
|
|
108
108
|
import { analyzeNameSpans } from "./names.mjs";
|
|
109
|
-
import {
|
|
109
|
+
import { fillEncodingRuns, recordRuns } from "./run-rows.mjs";
|
|
110
110
|
import fs from "node:fs";
|
|
111
111
|
import path from "node:path";
|
|
112
112
|
|
|
@@ -1074,6 +1074,8 @@ export function resolveCultures(
|
|
|
1074
1074
|
* calendar note's shortcode; see {@link module:engine/note-calendars}.
|
|
1075
1075
|
* @param {string} [options.configFile] - The configuration file, where an
|
|
1076
1076
|
* unknown `defaultCalendar` is reported.
|
|
1077
|
+
* @param {string} [options.rootDir] - Consumer package root for loading installed
|
|
1078
|
+
* encodings when filling language native-writing defaults.
|
|
1077
1079
|
* @param {Readonly<Record<string, {tag: string}>>} [options.languages] - The
|
|
1078
1080
|
* configured languages, which give each run's `lang=` its tag.
|
|
1079
1081
|
* @param {(key: string) => ({culture?: unknown}|undefined)} [options.foreignRecord] -
|
|
@@ -1095,6 +1097,7 @@ export function collectContentIndex(
|
|
|
1095
1097
|
currentDate,
|
|
1096
1098
|
defaultCalendar,
|
|
1097
1099
|
configFile,
|
|
1100
|
+
rootDir,
|
|
1098
1101
|
languages,
|
|
1099
1102
|
skipDirectories,
|
|
1100
1103
|
assetsBase,
|
|
@@ -1252,7 +1255,7 @@ export function collectContentIndex(
|
|
|
1252
1255
|
|
|
1253
1256
|
// A run marked with a language alone takes its language's script, which
|
|
1254
1257
|
// is read once every language note is recorded.
|
|
1255
|
-
|
|
1258
|
+
fillEncodingRuns(records, { languages, contentPackage, rootDir });
|
|
1256
1259
|
|
|
1257
1260
|
// Every note record exists and every Address in it is a tuple, so a parent
|
|
1258
1261
|
// is found by its canonical address. Before the sort, which reads nothing
|
|
@@ -1489,6 +1492,7 @@ export function indexRecordsFor({
|
|
|
1489
1492
|
return foreign.get(key);
|
|
1490
1493
|
};
|
|
1491
1494
|
return collectContentIndex(tree, {
|
|
1495
|
+
rootDir: resolved.rootDir,
|
|
1492
1496
|
contentPackage: resolved.contentPackage,
|
|
1493
1497
|
currentDate: resolved.currentDate,
|
|
1494
1498
|
defaultCalendar: resolved.defaultCalendar ?? undefined,
|