@heroiclands/package-build 25.0.0 → 25.1.1

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 (105) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +1 -0
  3. package/bin/content-commands.mjs +30 -96
  4. package/bin/encoding-commands.mjs +146 -0
  5. package/bin/package-build.mjs +35 -24
  6. package/config.mjs +25 -0
  7. package/convert.mjs +182 -0
  8. package/docs/api.md +144 -6
  9. package/docs/authoring/links-and-markup.md +260 -481
  10. package/docs/commands.md +110 -119
  11. package/docs/configuration.md +31 -13
  12. package/docs/content-format.md +11 -4
  13. package/docs/diagnostics.md +43 -16
  14. package/docs/encoding-core.md +193 -0
  15. package/docs/guides/book.md +2 -2
  16. package/docs/guides/module-project.md +23 -1
  17. package/docs/guides/site.md +2 -2
  18. package/docs/guides/writing-in-invented-scripts.md +458 -575
  19. package/docs/reference/format-details.md +292 -404
  20. package/docs/reference/note-types.md +83 -63
  21. package/docs/source-preview.md +8 -0
  22. package/e2e.mjs +1 -1
  23. package/engine/base-compiler.mjs +27 -9
  24. package/engine/content-charset.mjs +13 -1
  25. package/engine/content-format.yaml +6 -2
  26. package/engine/content-index.mjs +6 -2
  27. package/engine/content-links.mjs +1 -0
  28. package/engine/content-scripts.mjs +614 -459
  29. package/engine/content-scroll.mjs +4 -4
  30. package/engine/content-spans.mjs +40 -9
  31. package/engine/content-verse.mjs +1 -1
  32. package/engine/converter-data.mjs +70 -0
  33. package/engine/dictionary-rows.mjs +2 -34
  34. package/engine/encoding-integrity.mjs +94 -0
  35. package/engine/encoding-language.mjs +506 -0
  36. package/engine/encoding-lexicon.mjs +701 -0
  37. package/engine/encoding-notes.mjs +186 -0
  38. package/engine/encoding-standard.mjs +42 -0
  39. package/engine/encoding-template.mjs +370 -0
  40. package/engine/encoding-terms.mjs +178 -0
  41. package/engine/encoding.mjs +952 -0
  42. package/engine/extension-attributes.mjs +2 -0
  43. package/engine/helpers.mjs +1 -1
  44. package/engine/index.mjs +7 -0
  45. package/engine/language-terms.mjs +17 -16
  46. package/engine/{logographic.mjs → language-writings.mjs} +29 -38
  47. package/engine/markup-validation.mjs +1 -1
  48. package/engine/note-vocabulary.mjs +4 -158
  49. package/engine/pdf-render.mjs +31 -3
  50. package/engine/roman-characters.mjs +135 -16
  51. package/engine/roman-run.mjs +149 -0
  52. package/engine/roman-verse.mjs +95 -0
  53. package/engine/run-rows.mjs +29 -31
  54. package/engine/run-words.mjs +2 -2
  55. package/engine/script-emphasis-terms.mjs +3 -0
  56. package/engine/script-emphasis.mjs +3 -10
  57. package/engine/script-font-delivery.mjs +9 -12
  58. package/engine/script-fonts.mjs +2 -1
  59. package/engine/site-build.mjs +14 -5
  60. package/engine/site-preview.mjs +12 -2
  61. package/engine/sql-tables.mjs +36 -31
  62. package/engine/verse-metre.mjs +1 -1
  63. package/engine/word-forms.mjs +1 -1
  64. package/engine/word-inflections.mjs +48 -0
  65. package/engine/word-rows.mjs +1 -1
  66. package/engine/word-terms.mjs +16 -17
  67. package/package.json +11 -5
  68. package/types/config.d.mts +5 -0
  69. package/types/convert.d.mts +44 -0
  70. package/types/e2e.d.mts +1 -1
  71. package/types/engine/base-compiler.d.mts +4 -2
  72. package/types/engine/content-index.d.mts +4 -1
  73. package/types/engine/content-scripts.d.mts +103 -42
  74. package/types/engine/converter-data.d.mts +11 -0
  75. package/types/engine/dictionary-rows.d.mts +1 -25
  76. package/types/engine/encoding-integrity.d.mts +14 -0
  77. package/types/engine/encoding-language.d.mts +36 -0
  78. package/types/engine/encoding-lexicon.d.mts +259 -0
  79. package/types/engine/encoding-notes.d.mts +39 -0
  80. package/types/engine/encoding-standard.d.mts +11 -0
  81. package/types/engine/encoding-template.d.mts +44 -0
  82. package/types/engine/encoding-terms.d.mts +143 -0
  83. package/types/engine/encoding.d.mts +155 -0
  84. package/types/engine/helpers.d.mts +1 -1
  85. package/types/engine/index.d.mts +4 -0
  86. package/types/engine/language-terms.d.mts +1 -1
  87. package/types/engine/{logographic.d.mts → language-writings.d.mts} +6 -6
  88. package/types/engine/markup-validation.d.mts +1 -1
  89. package/types/engine/pdf-render.d.mts +1 -1
  90. package/types/engine/roman-characters.d.mts +2 -2
  91. package/types/engine/roman-run.d.mts +101 -0
  92. package/types/engine/roman-verse.d.mts +23 -0
  93. package/types/engine/run-rows.d.mts +13 -20
  94. package/types/engine/script-emphasis-terms.d.mts +2 -0
  95. package/types/engine/script-emphasis.d.mts +1 -1
  96. package/types/engine/script-font-delivery.d.mts +2 -3
  97. package/types/engine/script-fonts.d.mts +5 -0
  98. package/types/engine/site-preview.d.mts +1 -1
  99. package/types/engine/word-inflections.d.mts +25 -0
  100. package/engine/map-lexicon.mjs +0 -1045
  101. package/engine/text-maps.mjs +0 -654
  102. package/engine/written-in.mjs +0 -204
  103. package/types/engine/map-lexicon.d.mts +0 -330
  104. package/types/engine/text-maps.d.mts +0 -189
  105. package/types/engine/written-in.d.mts +0 -76
@@ -68,6 +68,10 @@ use. Keep the note's own subject in plain text, and use plain text for later
68
68
  mentions and aliases. Bold is emphasis.
69
69
  Plain text, including capitalized words, is not searched for names.
70
70
 
71
+ Inside a language run, a `.name` child contributes `{` + its text + `}` to the
72
+ chosen encoding. Write `[Name]{.name}` in Markdown; the build supplies the
73
+ standard name boundaries.
74
+
71
75
  ```markdown
72
76
  [[place-arden|Arden Vale]] stands beside the river. Arden Vale has two gates.
73
77
  [Hidden Hand]{.name} keeps watch over the crossing.
@@ -396,7 +400,7 @@ The optional `form` attribute records the author's intent; the build does not
396
400
  infer stress, rhyme or pronunciation. `numstep` numbers the logical rows, and `cols`
397
401
  sets the poem's column count; see below. `lang` names the poem's language,
398
402
  `font` the font it is set in and `map` the mapping its text is rewritten by; see
399
- [marking language, font and mapping](#marking-language-font-and-mapping). An optional `#id`
403
+ [marking language, font and encoding](#marking-language-font-and-encoding). An optional `#id`
400
404
  addresses the poem itself. There are no `title` or `lines` attributes, and no
401
405
  special punctuation for stress, pauses or refrains. A poem's metre, rhyme or
402
406
  syllable pattern is described in the note's prose. `scan` names a metre the
@@ -513,11 +517,11 @@ This sparse three-column poem leaves the middle cell empty in its first row:
513
517
 
514
518
  ````markdown
515
519
  ```verse {form=epic lang=en numstep=5 cols=3}
516
- 1 [Thiruthriman sorimamen,]{.nativefont lang=vyl}
520
+ 1 [Thiruthriman sorimamen,]{lang=vyl}
517
521
  3 [The hallowed boundary I sing,]{lang=en}
518
522
  3 [Thiruthriman sorimamen,]{lang=vyl}
519
523
 
520
- 1 [ul alathas kedis alatha valmazor, ul talothoi]{.nativefont lang=vyl}
524
+ 1 [ul alathas kedis alatha valmazor, ul talothoi]{lang=vyl}
521
525
  2 [Nothing to say]{lang=en}
522
526
  3 [and the one who walked it, and the stones]{lang=en}
523
527
  3 [ul alathas kedis alatha valmazor, ul talothoi]{lang=vyl}
@@ -527,7 +531,7 @@ This sparse three-column poem leaves the middle cell empty in its first row:
527
531
  The left cell uses Vylari's configured native script. The third cell contains
528
532
  an English reading in foreground and a separately authored Roman Vylari
529
533
  reading in grey. Language labels identify words; column numbers alone place
530
- them. `.nativefont`, `lang=`, `font=` and `map=` are written on the actual
534
+ them. `lang=`, `font=` and `enc=` are written on the actual
531
535
  runs, so a Roman repeat makes its own presentation choice. Inline links and
532
536
  mixed-language spans stay in their authored order with their spaces intact.
533
537
 
@@ -557,7 +561,7 @@ read from the right, as on a handscroll. A `scroll` fence sets a passage in one
557
561
  of these scripts:
558
562
 
559
563
  ````markdown
560
- ```scroll {rows=25 cols=12 lang=tsu map=tengchou .nativefont}
564
+ ```scroll {rows=25 cols=12 lang=tsu enc=tsutengchouenc}
561
565
  chen teng chou hing
562
566
  tan tsou dou rou
563
567
 
@@ -574,26 +578,11 @@ A scroll fence is a real code fence, so Markdown never reformats its body.
574
578
  - **`rows=`** is the number of characters in a column, and **`cols=`** the
575
579
  number of columns in a panel. Each is a whole number above zero, and either
576
580
  may be left out.
577
- - **`lang=`, `.nativefont`, `font=` and `map=`** work as they do on a verse fence. See
578
- [marking language, font and mapping](#marking-language-font-and-mapping).
579
- The text is mapped before it is laid out, so under a
580
- [logographic map](#logographic-maps) each word is written by its
581
- characters, one to a morpheme. The map's rows decide what is written
582
- between words, and a map for a script that runs its characters together
583
- writes a space as nothing. A scroll requires its own `lang=` and
584
- `.nativefont`; its font comes from that language's default or an explicit
585
- `font=`, never from the map's list of faces. For example,
586
- ` ```scroll {rows=25 cols=12 lang=tsu .nativefont} ` takes Tantsou's
587
- configured map and face;
588
- see [a language's script](#a-languages-script).
589
- - **The direction comes from the script.** The face's script note states
590
- `direction: vertical-rl` in its `data.script`; see
591
- [script notes and emphasis](../reference/format-details.md#script-notes-and-emphasis).
592
- A script that states no direction is written in lines, and a scroll fence
593
- set in it is an error. Markup never states a direction itself.
594
- - **Spans stay horizontal.** A `[…]{lang=… font=… map=… .nativefont}` span in the same
595
- script sets its characters left to right, inline, so a short phrase can sit
596
- in a line of prose.
581
+ - **`lang=`, `font=` and `enc=`** work as they do on a verse fence. See
582
+ [marking language, font and encoding](#marking-language-font-and-encoding).
583
+ The text is encoded before layout. Own and composed lexical spellings precede
584
+ rows; a written separator follows the selected definition. An explicit `enc=`
585
+ selects the document's language and font; explicit values must agree.
597
586
 
598
587
  **On the site, in the preview and in Foundry**, a scroll is a `<div
599
588
  class="scroll">` with one `<p>` for each paragraph. The stylesheet sets it
@@ -633,175 +622,97 @@ In the book, a space that a map leaves in the text takes up a whole cell.
633
622
  | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
634
623
  | `` `rows=0` is not a number of characters: `rows=` is a whole number above zero `` | Write a whole number above zero, or leave the key out. |
635
624
  | `` `cols=two` is not a number of columns: `cols=` is a whole number above zero `` | Write a whole number above zero, or leave the key out. |
636
- | `` `width=` is not a scroll attribute; a scroll takes `rows=`, `cols=`, `lang=`, `font=` and `map=` `` | Remove the key. |
637
- | ``a scroll requires `.nativefont` and an explicit `lang=` on the same construct`` | Add the class and the scroll's language. |
638
- | `` `.nativefont` has no default `font=` for `tsu`; state `font=` explicitly `` | Add `font=`, or a font default on the language note. |
625
+ | `` `width=` is not a scroll attribute; a scroll takes `rows=`, `cols=`, `lang=`, `font=` and `enc=` `` | Remove the key. |
639
626
  | ``a `scroll` fence sets a script written in columns, and the script of `semaron-kuriale` is written in lines; set it in a face whose script note states `direction: vertical-rl`, or use a div`` | Set the text in a script written in columns, or use a div. |
640
627
  | `scroll fence is empty`, `scroll fence needs a closing code fence`, `` a scroll fence takes no `#id` `` | Write the text, close the fence, or remove the id. |
641
628
 
642
629
  A fence with an error in its opening line is shown as code. A fence whose text
643
630
  has an error is set exactly as written.
644
631
 
645
- ## Marking language, font and mapping
646
-
647
- Each configured language note declares `data.roman`, a literal NFC string of
648
- permitted source characters. Include capitals, accents, digits and punctuation
649
- explicitly; an empty string declares no written characters. Spaces and line
650
- breaks are structural. `package-build lint` checks Roman source before mapping,
651
- including language-only runs and visible link labels. The configured name and
652
- its BCP 47 tag select the same inventory; external tags without a configured
653
- language note keep their ordinary behavior.
654
-
655
- `lang=` identifies the language. It preserves the authored spelling and the
656
- surrounding prose font. Add **`.nativefont`** to request native script:
657
-
658
- - **`lang=`** names the language and gives the element its language tag.
659
- Existing language and vocabulary checks apply in either presentation.
660
- - **`.nativefont`** requires an explicit `lang=` on that same construct. It
661
- selects the language note's `data.writtenIn` map and font. A surrounding
662
- language annotation does not satisfy this requirement.
663
- - **`font=`** overrides the native font independently of the map. Without
664
- `.nativefont`, only the Roman families `mono`, `serif` and `sans` are allowed.
665
- - **`map=`** overrides the native mapping independently of the font and
666
- requires `.nativefont`.
667
-
668
- These attributes go on a span, a fenced div, a verse fence or a
669
- [scroll fence](#scrolls). A native run needs a font from its language or an explicit `font=`. A
670
- configured map is selected unless `map=` overrides it; without a configured
671
- or explicit map, directly typed script code points are kept as written. A mismatch between the selected map and font is an error.
672
-
673
- A note records Unicode characters. A face draws its own code points, so text in
674
- a face is either typed in those code points (with a keyboard layout for the
675
- face) or typed in roman letters and mapped into them.
676
-
677
- A span in a language:
678
-
679
- ```markdown
680
- The greeting at the door is [Daimela, helthos.]{lang=vyl}
681
- ```
682
-
683
- Vylari typed in roman letters, mapped into Semaron Kuriale and set in it:
632
+ ## Standard Roman punctuation
633
+
634
+ Every configured language's text uses the shared Roman punctuation standard.
635
+ The language note's `data.roman` adds its letters, accents, catch and digits;
636
+ it does not repeat the shared marks. An uppercase letter is accepted only
637
+ where the language's additions include it. Roman display retains the spelling
638
+ and case the author typed.
639
+
640
+ | Mark | Meaning |
641
+ | ----- | ----------------------------------------------------------------- |
642
+ | `.` | ends a declarative sentence |
643
+ | `?` | ends an interrogative sentence |
644
+ | `‼` | ends an imperative sentence |
645
+ | `!` | ends an exclamative sentence |
646
+ | `,` | pauses within a sentence |
647
+ | `«…»` | quotes an outer passage |
648
+ | `‹…›` | quotes inside that passage; alternate the pairs at further depths |
649
+ | `—` | interrupts a sentence |
650
+ | `…` | resumes a sentence at its start, or abandons it later |
651
+ | `/` | separates verse lines when verse is written inline |
652
+ | `^` | indents at the beginning of a line; repeat for further levels |
653
+ | `{…}` | marks a name in the text handed to an encoding |
654
+ | `⟦…⟧` | encloses literal codes interpreted by the chosen encoding |
655
+
656
+ A terminal is optional: a run without one is accepted as written. Within a
657
+ run, an interruption or abandoning ellipsis is immediately followed by a
658
+ terminal. At the end of the run it can stand alone. Closing a quotation does
659
+ not terminate the surrounding sentence. Quote pairs balance, including across
660
+ presentation-only `.emph` children.
661
+
662
+ Use `,` instead of `;` or `:` for a pause, and `.` between complete sentences.
663
+ Use the guillemet pairs instead of English double quotation marks or `<<` and
664
+ `>>`; write `…` instead of three periods.
665
+
666
+ Whitespace is every Unicode space-separator (`Zs`) and U+0009 through U+000D.
667
+ A contiguous run of that whitespace is one word separator, written as the
668
+ chosen encoding specifies. A newline in prose is whitespace. In verse, line
669
+ endings and blank lines supply line and stanza boundaries; a line of only
670
+ `--- {.canto}` supplies a canto boundary. Visual verse indentation stays
671
+ layout, outside the encoded letters. Do not type `/` inside a verse fence.
672
+
673
+ Native characters in a language run are written through literal codage:
674
+ `⟦U+F0230⟧`, or a name the encoding defines between `⟦` and `⟧`. Directly
675
+ pasting a setting-script character is a finding even when the selected font
676
+ draws it. Inside the markers, only the encoding's codes and notation apply.
677
+ Markdown escapes are resolved before encoding; a refusal still points at the
678
+ original character. Write a literal backslash as `\\`.
679
+
680
+ `!` immediately before `[` is Markdown image syntax. Leave a space, or escape
681
+ that `!`, when an exclamative terminal immediately precedes another span.
682
+
683
+ ## Marking language, font and encoding
684
+
685
+ `enc=` names an encoding document, with `doc` as its default Address type:
686
+ `[say.]{enc=aelwsemaronenc}` selects `doc-aelwsemaronenc`. That document supplies
687
+ its configured `language` and single `font`; an explicit `lang=` must identify
688
+ the same language, and an explicit `font=` must be that font. Another face is
689
+ a separate encoding document.
690
+
691
+ `enc=default` leaves Roman text as written and is the default when no encoding
692
+ is selected. `lang=` still identifies the text and selects its language's
693
+ vocabulary; `font=mono`, `serif`, `sans` or an installed font selects its face
694
+ without encoding it. Language identification does not select an encoding.
684
695
 
685
696
  ```markdown
686
- The lintel is cut with [Zaron tholmeza]{lang=vyl font=semaron-kuriale map=semaron .nativefont}.
697
+ [say.]{enc=aelwsemaronenc}
698
+ [say.]{enc=doc-aelwsemaronenc lang=aelw font=semaron-kuriale}
699
+ [say.]{lang=aelw enc=default}
687
700
  ```
688
701
 
689
- A named reference takes the same keys directly after its wikilink. This
690
- example identifies the name while retaining Roman spelling:
702
+ Class-only emphasis and name children belong to the parent's complete logical
703
+ text; encoding preserves their rendered wrappers. A child with its own run
704
+ keys makes a separate presentation choice. `enc=default` inside an encoded
705
+ parent keeps the inherited language but does not inherit its inferred script
706
+ face. An explicitly authored font remains a font choice.
691
707
 
692
- ```markdown
693
- [Keeper of the open book, ]{lang=en}[[lore-marendasdty|Marendas]]{lang=vyl}[, hear us.]{lang=en}
694
- ```
695
-
696
- The reference's language, font and mapping apply to its visible name. Its
697
- navigation, spoiler styling and draft cue are preserved. Keep surrounding
698
- prose in adjacent spans, including their spaces and punctuation; a longer
699
- span of declared-language prose cannot contain a link.
700
-
701
- A language-marked reference stays in Roman spelling unless it opts in:
702
-
703
- ```markdown
704
- [[lore-marendasdty|Marendas]]{lang=vyl}
705
- [[lore-marendasdty|Marendas]]{lang=vyl .nativefont}
706
- ```
707
-
708
- The second reference uses Vylari's configured native defaults. Its visible name
709
- alone takes the mapping and font; URLs, Foundry UUIDs, draft cues and book page
710
- references retain their existing behavior. `.secret` and `.show` work normally.
711
-
712
- Text already typed in the script's code points also uses `.nativefont`, an
713
- explicit language and a font. A configured or explicit map still applies;
714
- its rows leave code points with no matching row unchanged. Without a map, the
715
- typed code points reach the font unchanged.
716
-
717
- A passage of several paragraphs is a fenced div:
718
-
719
- ```markdown
720
- ::: {lang=vyl font=semaron-kuriale map=semaron .nativefont}
721
- Zaron tholmeza.
722
-
723
- Daimela, helthos.
724
- :::
725
- ```
726
-
727
- A poem takes the keys on its fence, beside its other attributes:
728
-
729
- ````markdown
730
- ```verse {form=epic lang=vyl font=semaron-kuriale map=semaron .nativefont}
731
- Zaron tholmeza,
732
- daimela, helthos.
733
- ```
734
- ````
735
-
736
- **Unmarked text follows its passage; a marked child chooses its own
737
- presentation.** A language-only span stays Roman even inside a native passage,
738
- including when its language matches the passage. To set a child in native
739
- script, give that child both its own `lang=` and `.nativefont`.
740
-
741
- ```markdown
742
- ::: {lang=vyl .nativefont}
743
- Zaron tholmeza, [an oath, a vow]{lang=en font=serif}.
744
- [Zaron tholmeza]{lang=vyl} gives the Roman reading.
745
- [Zaron tholmeza]{lang=vyl .nativefont} gives the native reading.
746
- :::
747
- ```
748
-
749
- An unmarked span inherits the surrounding language for validation. A child
750
- `.nativefont` does not inherit its parent's explicit map or font: its own
751
- language supplies the defaults, and its own overrides choose the alternatives.
708
+ A name's braces use the shared name controls. Resolved references encode only
709
+ their visible labels, retaining URLs and presentation cues. These keys apply
710
+ to spans, divs, verse fences and scroll fences. A scroll's selected font must
711
+ belong to a script whose note declares `direction: vertical-rl`.
752
712
 
753
713
  ### A language's script
754
714
 
755
- A language note can name the script its language is written in, as one map and
756
- one face, in `data.writtenIn`:
757
-
758
- ```yaml
759
- data:
760
- writtenIn: { map: semaron, font: semaron-kuriale }
761
- ```
762
-
763
- The defaults are used only when the run explicitly opts into native
764
- presentation. With Vylari's note stating the default above, the first span
765
- stays Roman and the next two display the same native text:
766
-
767
- ```markdown
768
- [Zaron tholmeza]{lang=vyl}
769
- [Zaron tholmeza]{lang=vyl .nativefont}
770
- [Zaron tholmeza]{lang=vyl .nativefont font=semaron-kuriale map=semaron}
771
- ```
772
-
773
- This applies to divs, verse fences, [scroll fences](#scrolls) and standalone
774
- wikilinks. The overrides are independent:
775
-
776
- | A native run states | It takes from its language |
777
- | ------------------- | --------------------------- |
778
- | neither override | the configured map and font |
779
- | `font=` alone | the configured map |
780
- | `map=` alone | the configured font |
781
- | both | neither default |
782
-
783
- A missing font default is an error naming the required `font=` override.
784
- An incompatible pair is an error; the build does not drop one half or guess a
785
- replacement. A language written in several scripts states its usual one in
786
- `data.writtenIn`, then uses both overrides for another:
787
- `[Gar-Anlagh]{lang=khel .nativefont font=qalezu-hand map=qalezu}`.
788
-
789
- `[Zaron]{lang=vyl font=serif}` stays Roman in the page's serif. Adding
790
- `.nativefont` selects native mapping; a generic Roman font is not an escape
791
- from the native map/font compatibility check.
792
-
793
- `lint` checks the key on the language note: `map` must be the `data.map.name`
794
- of a mapping note in the package, and `font` one of the faces that map lists.
795
- Each is an error at its value, and the default then fills no run:
796
-
797
- > `` `data.writtenIn.map` is `semoran`, which no mapping note's `data.map.name` declares; did you mean `semaron`? ``
798
- >
799
- > `` `data.writtenIn.font` is `teng-chou`, which the map `semaron` is not drawn in; it is drawn in `semaron-kuriale` ``
800
- >
801
- > `` `data.writtenIn` names the script a language is written in, and this note's `subType` is not `language` ``
802
-
803
- The face a language's script names is delivered with the package's fonts, as a
804
- face named by `font=` is.
715
+ The encoding document states the language and font for one written form.
805
716
 
806
717
  ### What `lang=` takes
807
718
 
@@ -820,7 +731,7 @@ language. When such a value is within one edit of a declared name (a letter
820
731
  added, dropped or changed, two neighbours swapped, or a different case), `lint`
821
732
  warns and names the declared language. A configured language with a `note`
822
733
  checks its words whether the run stays Roman or opts into native presentation;
823
- see [a mapped run's words](#a-mapped-runs-words).
734
+ see [a mapped run's words](#an-encoded-runs-words).
824
735
 
825
736
  ### What `font=` takes
826
737
 
@@ -845,74 +756,96 @@ After the map, every other character in text set in a face is an error at the
845
756
  character it came from, so a box never reaches a reader. The generic families
846
757
  are not checked.
847
758
 
848
- ### What `map=` takes
849
-
850
- `map=` is the `data.map.name` of a [mapping note](#mapping-notes) in this
851
- package. The map is applied to the run's text before anything else, and what
852
- it writes is what the face draws. A map belongs to a script and serves every
853
- language written in it; it lists the faces it is drawn in, and a run's `font=`
854
- is one of them.
855
-
856
- **With `lang=`, the language's dictionary comes first.** Where
857
- [`languages.<name>.note`](../configuration.md#languages) names the language's
858
- note, each word of the run is looked up in its `data.words` and the words of
859
- its `data.family` chain. The nearest exact NFC form supplies the entire word
860
- entry, including variants and native spellings; an override replaces the whole
861
- ancestor entry. Case and word separators remain part of that identity.
862
- Grammar, registered names and the default writing script remain the daughter's
863
- own. An inherited native spelling applies only to the map and face it names:
864
-
865
- 1. **A word whose entry states a `native` form for the map** is written by it:
866
- the form stated for the run's face where there is one, else the form stated
867
- for no face.
868
- 2. **Every other word is spelled by the rows**: coinages, names, and every
869
- derived form, so a plural or a verb ending of an exception word is spelled
870
- by the rows too.
871
-
872
- A word is a run of letters, marks and digits, with an apostrophe, a hyphen or
873
- an en dash joining two such runs into one word; everything between words is
874
- spelled by the rows. A word is looked up as written and then in lowercase.
875
- **A capitalised word found in lowercase** takes its capital from the rows: its
876
- first sound, mapped as written and in lowercase, replaces the beginning of the
877
- native form where the native form begins as the rows begin the word. A native
878
- form that begins otherwise cannot be capitalised by the rows, and the
879
- capitalised word is an error; state it as a word of its own, `Orlan` beside
880
- `orlan`, with its own native form.
881
-
882
- A native run with an explicit bare BCP 47 tag, such as `lang=und`, or a
883
- declared language with no `note`, uses the rows alone. It still requires
884
- `.nativefont` and an effective font.
885
-
886
- Take Vylari's `zaron`, an oath, written in Semaron. With no exception stated,
887
- the rows spell it letter by letter, as they spell any word:
759
+ ### What `enc=` takes
760
+
761
+ An encoding is a `doc` note. Its `data.language` is a configured language
762
+ alias, `data.font` is one installed font slug, and `data.mappings` maps Roman
763
+ strings to a font glyph code or a sequence of codes. `data.rules` holds the
764
+ closed executable rules. Optional `data.accepts` states accepted characters
765
+ or ranges and `data.vowels` states contextual vowels. The note body explains
766
+ the spelling to a reader.
767
+
768
+ The font supplies each glyph's `code` beside its `codepoint` in `fonts.json`.
769
+ Codes belong to the selected font; the note never repeats a code table.
770
+ Unknown fields, glyph codes, languages and fonts are positioned findings.
771
+ An encoding's output must decode unambiguously, including across adjacent
772
+ mappings and spaces. The compiler refuses indistinguishable spellings rather
773
+ than choosing a guessed reading. See [the executable rules](../encoding-core.md).
774
+
775
+ Mappings match longest first; contextual before-vowel rules precede their
776
+ unconditional alternatives. A case rule may allow lowercase and initial-capital
777
+ groups while refusing other mixed or uppercase group spellings. Encoding keeps
778
+ authored case and never rewrites a word's Roman spelling.
779
+
780
+ Outside literal markers, a run of Unicode Zs characters or U+0009 through
781
+ U+000D writes one space. Other whitespace needs an explicit mapping. Standard
782
+ Roman punctuation, verse and name controls are inherited from the shared
783
+ standard; an explicit mapping can give a standard source its font glyph.
784
+
785
+ #### Literal codes
786
+
787
+ Inside an encoded run, `⟦…⟧` writes the selected font's glyph codes or exact
788
+ Unicode scalars: `[⟦MAN⟧]{enc=khelzethuenc}` where `MAN` is defined, and
789
+ `[⟦U+00E1⟧]{enc=vylsemaronenc}` for an exact character. A Unicode code takes four to
790
+ six uppercase hexadecimal digits, U+0000 through U+10FFFF excluding
791
+ surrogates. Codes come only from the font; Unicode database
792
+ names are not inferred. Whitespace between codes writes nothing. Nested or
793
+ unmatched markers, unknown codes and standard marks absent from the font
794
+ code table are errors. Without an encoding, a literal marker is a finding.
795
+
796
+ Each outer marker writes its own invisible control. Payload occurrences of
797
+ those controls or the literal escape are quoted with U+E0115. Decoding
798
+ unquotes the payload before reading code rows and uses `U+XXXX` for scalars
799
+ with no code name. Variation selectors U+E0100 through U+E01EF are valid
800
+ encoded characters and carry distinctions the visible font does not draw.
801
+
802
+ ### The lexicon under an encoding
803
+
804
+ Every encoding uses the same order for a language word: its own `native`
805
+ entry for that encoding and face; otherwise the writings of all its parts;
806
+ otherwise the encoding's rows. A face-specific entry precedes an entry for no
807
+ face. Exact lexical forms precede folded lookup, so separately authored
808
+ capitalized spellings keep their own native text. A flat variant is a lexical
809
+ form; it does not assign a grammatical role by itself.
888
810
 
889
811
  ```yaml
890
- - form: zaron
891
- class: n
892
- field: "Law, the court and the written act"
893
- gloss: an oath
812
+ words:
813
+ - form: halzi
814
+ class: n
815
+ gloss: heart
816
+ field: Words
817
+ native:
818
+ - { enc: zethu, text: "\U0001EABB" }
819
+ - form: halzunet
820
+ class: n
821
+ gloss: the account
822
+ field: Words
823
+ built: [halzi, -unet]
824
+ affixes:
825
+ - form: -unet
826
+ gloss: a thing made of
827
+ native:
828
+ - { enc: zethu, text: "\U0001EBC7" }
894
829
  ```
895
830
 
896
- Where the chancery writes the word another way, the entry states that once,
897
- and `[zaron]{lang=vyl font=semaron-kuriale map=semaron .nativefont}` is written by it:
831
+ A built part is an exact word or affix, then the same form with joining
832
+ hyphens removed. Parts can themselves be built. A plural or present form can
833
+ use the stem's writing followed by its explicitly named ending from
834
+ `grammar.native`, whose entries use `{ending, enc, font?, text}`. These
835
+ writings work under every encoding. Missing parts do not invent signs, and
836
+ recursive parts terminate without a writing. Entries with genuinely different
837
+ writings remain an ambiguity naming every matching gloss.
898
838
 
899
- ```yaml
900
- - form: zaron
901
- class: n
902
- field: "Law, the court and the written act"
903
- gloss: an oath
904
- native:
905
- - { map: semaron, text: "\U000F024F\U000F0230\U000F023F\U000F023C" }
906
- ```
839
+ An encoding accepting no letters, such as `zethu` or `chalish-pilam`, needs a
840
+ lexical writing or literal codes for a word. The refusal names the word,
841
+ language and encoding and points to that word.
907
842
 
908
- A native form that is what the rows give already is an error ("states what the
909
- rows already give"), so a lexicon carries its exceptions and nothing else.
910
- `package-build lexicon vyl --map semaron` lists every word with its native form
911
- and whether it is an exception, and `package-build transliterate semaron --lang
912
- vyl zaron` converts a passage, both through the build's own code; see
913
- [the command reference](../commands.md#package-build-transliterate-map-text).
843
+ `package-build lexicon vyl --enc vylsemaronenc` lists lexical spellings.
844
+ `package-build encode --enc vylsemaronenc "zaron"` converts through the bare
845
+ encoding; the browser API also reads language vocabulary.
846
+ See [the command reference](../commands.md#package-build-encode-text).
914
847
 
915
- ### A mapped run's words
848
+ ### An encoded run's words
916
849
 
917
850
  **Every word of a run with `lang=` is a word of its language**, where
918
851
  the language's [`note`](../configuration.md#languages) names its language note.
@@ -985,7 +918,7 @@ With those, a run accepts:
985
918
 
986
919
  _-andar_ closes on no agreement ending, so _dokandar_ does not agree. A
987
920
  near miss such as _alathe_ or _dokendar_ is still an unknown word.
988
- `package-build lexicon vyl --map semaron --derived` lists every form the rules
921
+ `package-build lexicon vyl --enc vylsemaronenc --derived` lists every form the rules
989
922
  give, each beside the word it comes from, so a puzzling finding can be checked
990
923
  against what the rules produce.
991
924
 
@@ -1025,228 +958,80 @@ register:
1025
958
  A bare BCP 47 tag and a declared language with no `note` are not
1026
959
  checked.
1027
960
 
1028
- ### Logographic maps
1029
-
1030
- **A script that writes meanings is written from the dictionary, never by
1031
- sound.** Its mapping note states `logographic: true`, and every word of a run
1032
- under it is written from the language's lexicon. The map's rows write only the
1033
- text between words: the spaces, the points, and anything else with no letter
1034
- in it. A word never falls through to the rows, so a word the lexicon gives no
1035
- writing is an error rather than a guess.
1036
-
1037
- A word of the run is written by the first of these that gives a writing:
1038
-
1039
- 1. **The word's own `native` entry** for the map, the one for the run's face
1040
- where an entry names one, else the one for no face. A word written its own
1041
- way, such as a set compound, states this even where its parts would give
1042
- another writing.
1043
- 2. **Its parts.**
1044
- - **A word stating `built`** is written by its pieces' writings joined in
1045
- order. A piece is a word of the lexicon, matched exactly and then with its
1046
- joining hyphens taken off, or an affix of `data.affixes` with a `native`
1047
- entry of its own. A word piece is written by this same rule, so a compound
1048
- of compounds resolves all the way down.
1049
- - **A noun's plural and a verb's present forms** are written by the stem's
1050
- writing followed by the ending's, which `data.grammar.native` states once
1051
- per ending: `plural`, or one of the persons `I`, `you`, `heShe`, `we`,
1052
- `youAll` and `they`. The forms themselves are the ones the language's
1053
- rules give, as for the lexicon check.
1054
- - **A hyphenated word no entry states** is written by each of its parts in
1055
- turn, so `Gar-halzunet` is `Gar-`'s writing followed by `halzunet`'s.
1056
- 3. **Otherwise the word is an error** at the word. Coin the word or give it a
1057
- writing, or write the signs directly.
1058
-
1059
- A word is matched case folded, because the script has no capitals: `Halzi` and
1060
- `halzi` both find the entries `Halzi` and `halzi`. **Where one roman form
1061
- stands for entries written differently**, or where one has a writing and
1062
- another has none, the run cannot tell which sense is meant, and the word is an
1063
- error naming every entry's gloss. Write that word directly in signs, picking
1064
- the sense by its gloss from `package-build lexicon khel --map zethu`. Signs typed
1065
- in the run are no word, and pass through as typed. Entries that share a form
1066
- and are written alike are written so.
1067
-
1068
- Khelathi in Zethu, with its roots, an affix and the plural written once:
961
+ ### Native spellings and parts
962
+
963
+ Every encoding uses the same order for a language word: its own `native`
964
+ entry for that encoding and face; otherwise the writings of all its parts;
965
+ otherwise the encoding's rows. A face-specific entry precedes an entry for no
966
+ face. Exact lexical forms precede folded lookup, so separately authored
967
+ capitalized spellings keep their own native text. A flat variant is a lexical
968
+ form; it does not assign a grammatical role by itself.
1069
969
 
1070
970
  ```yaml
1071
- affixes:
1072
- - form: "-unet"
1073
- gloss: "a thing made of"
1074
- native:
1075
- - { map: zethu, text: "\U0001EBC7" }
1076
- grammar:
1077
- plural:
1078
- - { ending: "", becomes: "im" }
1079
- native:
1080
- - { ending: plural, map: zethu, text: "\U0001EBE1" }
1081
971
  words:
1082
972
  - form: halzi
1083
973
  class: n
1084
- field: "The body"
1085
974
  gloss: heart
975
+ field: Words
1086
976
  native:
1087
- - { map: zethu, text: "\U0001EABB" }
977
+ - { enc: zethu, text: "\U0001EABB" }
1088
978
  - form: halzunet
1089
979
  class: n
1090
- field: "Counting-house and water-works"
1091
980
  gloss: the account
981
+ field: Words
1092
982
  built: [halzi, -unet]
1093
- ```
1094
-
1095
- `[halzi halzunet halziim]{lang=khel font=khelathi-zethu-glyphs map=zethu .nativefont}` is
1096
- written U+1EABB, then U+1EABB U+1EBC7, then U+1EABB U+1EBE1, with the spaces
1097
- the rows write between them. A word of the run that resolves to nothing is
1098
- reported once per run:
1099
-
1100
- > `` `zamlu` has no `zethu` writing in the `khel` lexicon, and its parts do not give one; state one, or write the word directly in signs ``
1101
-
1102
- The lexicon check still applies: every word of the run is a word of its
1103
- language, a registered name or a regular form of one. A registered name is
1104
- written like any other word, so a name with no writing is an error; a foreign
1105
- name is written deliberately, in signs or through a map that rewrites a
1106
- sign-by-sign notation.
1107
-
1108
- An affix's `native` and `data.grammar.native` are read only under a logographic
1109
- map, so either one naming any other map is an error at the entry, and an ending
1110
- of a person is an error where `data.grammar.verbs` states no `persons`. A
1111
- word's `native` under a logographic map is not held to what the rows give,
1112
- because the rows spell no word. `package-build lexicon khel --map zethu` lists
1113
- every word with its writing and where it comes from, and marks the words that
1114
- have none.
983
+ affixes:
984
+ - form: -unet
985
+ gloss: a thing made of
986
+ native:
987
+ - { enc: zethu, text: "\U0001EBC7" }
988
+ ```
989
+
990
+ A built part is an exact word or affix, then the same form with joining
991
+ hyphens removed. Parts can themselves be built. A plural or present form can
992
+ use the stem's writing followed by its explicitly named ending from
993
+ `grammar.native`, whose entries use `{ending, enc, font?, text}`. These
994
+ writings work under every encoding. Missing parts do not invent signs, and
995
+ recursive parts terminate without a writing. Entries with genuinely different
996
+ writings remain an ambiguity naming every matching gloss.
997
+
998
+ An encoding accepting no letters, such as `zethu` or `chalish-pilam`, needs a
999
+ lexical writing or literal codes for a word. The refusal names the word,
1000
+ language and encoding and points to that word.
1001
+
1002
+ #### Reading script text
1003
+
1004
+ Without a language, decoding is exactly the encoding's longest-output match.
1005
+ With a language, explicit native and composed writings are tried first,
1006
+ longest first; a shared writing uses the first listed sense. Literal marker
1007
+ spans decode through their inline codes. Unknown unmarked signs in a script
1008
+ accepting no letters become `⟦codes⟧` with a finding.
1009
+
1010
+ For an unmarked word, the lexicon can recover its unwritten sounds from the
1011
+ plain decoded skeleton. A unique skeleton gives its form; a shared skeleton
1012
+ gives the first authored form. Each word's citation precedes its variants and derived forms, before the next word's citation. Registered names retain their authored order. Complete names are matched longest first across word separators and receive one pair of braces. A known ordinary word keeps its encoded case without a false unknown-word finding. An unknown skeleton keeps the
1013
+ plain decoding and produces a located finding. This is decided per word: a
1014
+ passage can mix typed words with encoded words. A word carrying any invisible
1015
+ mark keeps exact decoding without skeleton recovery; an explicit authored
1016
+ native exception still has precedence. Stress marks are preserved by exact
1017
+ rows. Names are represented with braces according to the language's rules.
1115
1018
 
1116
- ### Mapping notes
1019
+ ### Emphasis in a script
1117
1020
 
1118
- A mapping note is a `doc` note whose `data.map` lists the rewrites:
1021
+ Mark a stressed word inside a language run with `[word]{.emph}`:
1119
1022
 
1120
- ```yaml
1121
- ---
1122
- type: doc
1123
- subType: reference
1124
- shortcode: semaronmap
1125
- name:
1126
- full: Vylari in Semaron Kuriale
1127
- data:
1128
- map:
1129
- name: semaron
1130
- vowels: "aeiouAEIOU"
1131
- fonts:
1132
- - font: semaron-kuriale
1133
- - font: semaron-carved
1134
- rows:
1135
- - [th, "\U000F0251"] # the carved th
1136
- rows:
1137
- - [a, "\U000F0230"]
1138
- - [aa, "\U000F0248"] # long a, its own letter
1139
- - [t, "\U000F0241"]
1140
- - [h, "\U000F0236"]
1141
- - [th, "\U000F0250"]
1142
- - [y, "\U000F0245"]
1143
- - { from: y, to: "\U000F0237", before: consonant }
1144
- ---
1145
- How Vylari's roman spelling is written in the Semaron chancery hand.
1146
- ```
1147
-
1148
- - **`name`** is what `map=` names it by: lowercase letters, digits and `-`,
1149
- unique in the package.
1150
- - **`fonts`** lists the faces the map is drawn in, at least one, each by the
1151
- slug `font=` names it by. A face may carry `rows` of its own, which a run in
1152
- that face tries first, the longest match among them, before the shared
1153
- `rows`. `mono`, `serif` and `sans` are not listed. Every listed face must draw
1154
- every character its own rows, the shared rows it reaches, and the lexicons'
1155
- native forms for it write; `lint` reports a gap at the row or the entry.
1156
- - **`rows`** is a list. A row is `[from, to]`, or
1157
- `{from, to, before?, at?}`. `from` is one or more characters and `to` any
1158
- number of them, none included: a map that drops a language's vowels writes
1159
- `[a, ""]`. A double-quoted YAML string writes a code point by its escape:
1160
- the fonts' scripts sit in plane 15, so their code points take the
1161
- eight-digit `\U`, as `"\U000F0200"` for U+F0200, and the four-digit `\u`
1162
- reaches only code points up to U+FFFF. A row matches and writes whole code
1163
- points.
1164
- - **`vowels`** lists the characters `before: vowel` reads as vowels.
1165
- - **`logographic: true`** marks a script that writes meanings: every word of
1166
- a run is written from the lexicon, and the rows write only the text between
1167
- words; see [logographic maps](#logographic-maps). A row whose `from` holds a
1168
- letter could never apply on such a map, and is an error at the row.
1169
-
1170
- How a map reads text:
1171
-
1172
- - **The longest match wins.** `th` above is one letter, and `t` and `h` are
1173
- read only where `th` does not match. Among rows of the same length, a row
1174
- with a condition that holds comes before a row with none, and otherwise the
1175
- earlier row wins.
1176
- - **A row whose condition fails is skipped.**
1177
- - `before: vowel` holds when the next character is one of `vowels`;
1178
- `before: consonant` when it is any other letter. Neither holds at the end
1179
- of the text.
1180
- - `at: start` holds at the first character of the run, or after whitespace
1181
- or punctuation; `at: end` holds at the last, or before whitespace or
1182
- punctuation.
1183
- - **A character no row matches passes through unchanged**, so a map for a face
1184
- that draws nothing on roman code points lists every letter the spelling
1185
- uses, and anything left over is reported.
1186
- - `rows` is a list rather than a keyed map, so `A` and `a` are two rows. Each
1187
- row is a row of the [`maps` relation](../reference/format-details.md#content-tables).
1188
-
1189
- The body describes the mapping for a reader; nothing reads it. See
1190
- [mapping notes](../reference/format-details.md#mapping-notes) for every
1191
- finding the lint reports in `data.map`.
1192
-
1193
- ### How marked text is set
1194
-
1195
- Every target rewrites marked text first, so a page, a Foundry journal and a
1196
- book all show the same thing.
1197
-
1198
- | Marking | The text | The element |
1199
- | -------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------- |
1200
- | `lang=` alone | As written | Tagged with the language's tag, `lang="art-x-vyl"` |
1201
- | `lang=… .nativefont` | Rewritten by the configured or overridden map | Native font and language tag |
1202
- | `lang=… .nativefont font=…` | Mapped text | The tag, `script` and the face's class; not indexed by the site's search |
1203
- | `font=mono`, `serif`, `sans` | As written, or as the map wrote it | The tag and `font-mono`, `font-serif` or `font-sans` |
1204
- | A div or fence in a right-to-left face | As above | Also `dir="rtl"`; a div also carries `script-block` |
1205
- | A scroll fence | Each paragraph on one line | `scroll`, the tag, `script` and the face's class; see [scrolls](#scrolls) |
1206
-
1207
- No target writes `<bdo>`, `<bdi>` or a Unicode direction control character: a
1208
- right-to-left face's code points carry their own direction. Text with an error
1209
- in it is left as written.
1210
-
1211
- In a book, a real language's tag sets the language of the text so its
1212
- hyphenation follows; an invented language's tag leaves the book's language
1213
- alone. A block or verse in a right-to-left face is set right to left.
1214
-
1215
- ### Plain text
1216
-
1217
- Text marked with `font=` or `map=`, or with a language the package declares, is
1218
- plain text.
1219
-
1220
- - **A span or a verse line** holds no link, image, footnote, wikilink, code or
1221
- HTML, and no unmarked nested span. Marked spans may be nested. English may
1222
- use Markdown emphasis; emphasis inside a span with an effective non-English
1223
- language is an error. A standalone wikilink may carry language, font and map
1224
- keys directly after it, as above; only its label is set. See [emphasis in a
1225
- script](#emphasis-in-a-script).
1226
- - **A div** holds paragraphs and line breaks only: no heading, list, block
1227
- quote, code fence, verse fence, table, rule, footnote definition or nested
1228
- block. Mark a poem's own fence instead of a div around it.
1229
-
1230
- The text is read as written, so characters a run types need no escaping: `[`
1231
- and `]`, `"`, `<<` and `>>`, `!`, and `@ # $ % ^ &`. A pair of brackets is two
1232
- characters unless what follows makes it markup: `(` makes a link, `{` a span,
1233
- and a doubled `[[` a wikilink. `[^id]` is a footnote only where the note
1234
- defines `[^id]:`. A bracket with no partner takes a backslash, `\[`.
1235
-
1236
- Text marked with a real language's tag alone keeps its Markdown, so
1237
- English text and spans may use emphasis. Any actual bold or italic Markdown
1238
- inside a span whose effective language is not English is an error, whether the
1239
- span marks a real language or an invented one, and whether it declares the
1240
- language itself or inherits it from a surrounding div or fence. English (`en`)
1241
- and English BCP 47 tags such as `en-US` remain eligible. Escaped delimiter
1242
- characters are literal text, not emphasis. This restriction applies throughout
1243
- the note, including outside verse.
1023
+ ```markdown
1024
+ [the milk cow is all [dried up]{.emph}]{lang=aelw}
1025
+ ```
1244
1026
 
1245
- ### Emphasis in a script
1027
+ The inner span inherits the language and presentation of the surrounding text.
1028
+ In a native run its letters are encoded by the same rules. Emphasis changes
1029
+ presentation, while the script's characters stay the same.
1246
1030
 
1247
- Inside a run set in a face, `*…*` and `**…**` are written exactly as in
1248
- English. No script marks a stressed word by a bold or a slant, so the build sets
1249
- emphasis by the scribal convention the text's language or its script states:
1031
+ In English, `[word]{.emph}` equals `*word*`, and `[word]{.strong}` equals
1032
+ `**word**`. A non-English span accepts `.emph` only: Markdown stars and
1033
+ underscores, and `.strong`, are findings. A span takes one emphasis class.
1034
+ The build sets accepted emphasis by the language's or script's convention:
1250
1035
 
1251
1036
  | Convention | On the site and in Foundry | In the book |
1252
1037
  | ---------- | -------------------------------------------------- | --------------------- |
@@ -1275,17 +1060,13 @@ data:
1275
1060
  ---
1276
1061
  ```
1277
1062
 
1278
- So a tongue that states nothing takes its script's convention. A script may
1279
- still define how accepted emphasis renders, but a span with an effective
1280
- non-English language cannot use Markdown emphasis even when that convention is
1281
- `rubric` or `overline`.
1063
+ A tongue that states nothing takes its script's convention. `.emph` uses that
1064
+ convention in a non-English span, including when the language is inherited.
1282
1065
 
1283
1066
  **A language may mark emphasis with a word** instead of a mark:
1284
1067
  `data.emphasis: words` on its language note. Emphasis in a run of that language
1285
- is an error; for a non-English language, the span restriction also applies
1286
- regardless of its `data.emphasis` value. A language may state `rubric` or
1287
- `overline`, which it takes in every script it is written in, but marked
1288
- emphasis remains disallowed inside its non-English spans.
1068
+ is an error, including `.emph`. A language may instead state `rubric` or
1069
+ `overline`, which `.emph` takes in every script it is written in.
1289
1070
 
1290
1071
  `_…_` is emphasis equal to `*…*`, and `__…__` equal to `**…**`, so a note keeps
1291
1072
  its meaning when a formatter rewrites one pair to the other. A strikethrough is
@@ -1300,27 +1081,22 @@ Each of these is an error at its line and column, reported by `lint`, the site
1300
1081
  build, the Foundry compile and the book, except the last row, which is a warning
1301
1082
  that `lint` reports and that fails nothing:
1302
1083
 
1303
- | Message | Fix |
1304
- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
1305
- | `` `q` is not a declared language (`languages` in package-build.config.yaml) or a BCP 47 tag `` | Declare the name, or write a real language's tag. A near name is suggested. |
1306
- | `` `semaron-kurial` is not a font: `font=` names an installed face, or `mono`, `serif` or `sans`; did you mean `semaron-kuriale`? `` | Write an installed face or a generic family. |
1307
- | `` `semaron-kuriale` is not a font: `font=` names `mono`, `serif` or `sans`, or a face of @heroiclands/fonts, which this package has not installed `` | Install `@heroiclands/fonts`. |
1308
- | `` `semron` is not a map: `map=` names the `data.map.name` of a mapping note; did you mean `semaron`? `` | Write the name a mapping note declares. |
1309
- | `` `x` (U+0078) is not drawn by the font `semaron-kuriale` `` | Type the face's code points, or add `map=`. |
1310
- | `` `x` (U+0078) is not drawn by the font `semaron-kuriale`, and the map `semaron` has no row for it `` | Add a row for it, or remove the character. |
1311
- | `` `ch` maps to U+F0299 in the map `semaron`, which the font `semaron-kuriale` does not draw `` | Correct the row's `to`. |
1312
- | `` `zaron` is written U+F0299 by the lexicon of `vyl` for the map `semaron`, which the font `semaron-kuriale` does not draw `` | Correct the word's `native` text. |
1313
- | `` `Orlan` is capitalised, and the native form the lexicon of `vyl` states for `orlan` under the map `semaron` does not begin as the rows spell its first letter, so the rows cannot capitalise it; state `Orlan` as a word of its own with its native form `` | State the capitalised word as a lexicon word of its own with its native form. |
1314
- | `` `zamlu` has no `zethu` writing in the `khel` lexicon, and its parts do not give one; state one, or write the word directly in signs `` | Give the word, or its pieces and endings, a writing for the map, or write its signs directly. |
1315
- | `` `nelgir` stands for 2 words of the `khel` lexicon that the map `zethu` writes differently, “a god” and “god”; write the word directly in signs, choosing by its sense in `package-build lexicon khel --map zethu` `` | Write the signs of the sense meant, from the lexicon listing. |
1316
- | `` `halzi` has no `zethu` writing: the map `zethu` is logographic, and the run names no `lang=` whose lexicon writes it; mark the run with its language, or write the word directly in signs `` | Mark the run with `lang=`, or write its signs directly. |
1317
- | `` `thiruthrimar` is not a word of the `vyl` lexicon, a registered name, or a regular form of one; coin it in the lexicon (or register the name) first `` | Coin the word in the language note's `data.words`, register the name in its own `data.register`, or correct the spelling. |
1318
- | `` `thuravark-carved` is not a font of the map `semaron`; it is for `semaron-kuriale` `` | Set the run in a face the map lists, or list the face in `data.map.fonts`. |
1319
- | ``a span in non-English language `vyl` holds no bold or italic markup`` | Remove the markup, or escape its delimiter characters. |
1320
- | `` `vyl` marks emphasis with a word, not a mark; write the word `` | Remove the emphasis marks and write the word the language stresses with. |
1321
- | ``a div marked `lang=vyl font=semaron-kuriale map=semaron` holds paragraphs and line breaks only, not a list`` | Move the list out of the div. |
1322
- | `` `font=` is read on a span, a div or a verse fence, not on a secret block `` | Put a marked div inside the secret block. |
1323
- | `` `vly` is read as a BCP 47 tag; did you mean the declared language `vyl`? `` (a warning) | Write the declared name, or ignore it when the tag is meant. |
1084
+ | Message | Fix |
1085
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
1086
+ | `` `q` is not a declared language (`languages` in package-build.config.yaml) or a BCP 47 tag `` | Declare the name, or write a real language's tag. A near name is suggested. |
1087
+ | `` `semaron-kurial` is not a font: `font=` names an installed face, or `mono`, `serif` or `sans`; did you mean `semaron-kuriale`? `` | Write an installed face or a generic family. |
1088
+ | `` `semaron-kuriale` is not a font: `font=` names `mono`, `serif` or `sans`, or a face of @heroiclands/fonts, which this package has not installed `` | Install `@heroiclands/fonts`. |
1089
+ | `` `semron` is not an encoding document `` | Write the name an installed encoding declares. |
1090
+ | `` `ch` encodes to U+F0299 in `semaron`, which the font `semaron-kuriale` does not draw `` | Select a compatible face or correct the encoding row. |
1091
+ | `` `zaron` is written U+F0299 by the lexicon of `vyl` for the encoding `semaron`, which the font `semaron-kuriale` does not draw `` | Correct the word's `native` text. |
1092
+ | ``The encoding cannot capitalize the native writing of `orlan`; author `Orlan` with its own native entry`` | Record the capitalized word with its own native writing. |
1093
+ | `` `thiruthrimar` is not a word of the `vyl` lexicon, a registered name, or a regular form of one; coin it in the lexicon (or register the name) first `` | Coin the word in the language note's `data.words`, register the name in its own `data.register`, or correct the spelling. |
1094
+ | `` `thuravark-carved` is not a font of encoding `semaron`; it is for `semaron-kuriale` `` | Set the run in a face the encoding lists, or list the face in the encoding definition's `fonts`. |
1095
+ | ``a span in non-English language `vyl` holds no bold or italic markup`` | Remove the markup, or escape its delimiter characters. |
1096
+ | `` `vyl` marks emphasis with a word, not a mark; write the word `` | Remove the emphasis marks and write the word the language stresses with. |
1097
+ | ``a div marked `lang=vyl font=semaron-kuriale enc=vylsemaronenc` holds paragraphs and line breaks only, not a list`` | Move the list out of the div. |
1098
+ | `` `font=` is read on a span, a div or a verse fence, not on a secret block `` | Put a marked div inside the secret block. |
1099
+ | `` `vly` is read as a BCP 47 tag; did you mean the declared language `vyl`? `` (a warning) | Write the declared name, or ignore it when the tag is meant. |
1324
1100
 
1325
1101
  A character the face does not draw is reported once per run, at its first
1326
1102
  place; through a map it is located at the start of the matched `from`.
@@ -1498,9 +1274,8 @@ A column's heading is its SQL alias, so `AS "Name"` is what a reader sees. A cel
1498
1274
  | `entries` | Every note, stubs included. |
1499
1275
  | `events` | One row per event a `lore`, `place` or `affiliation` note writes in `data.events`, with `whenSort` to order them by date. |
1500
1276
  | `names` | Each authored `.name` span, with its containing NOTE Address, visible text, optional type/subtype and source line/column. |
1501
- | `runs` | Each span, div and verse fence marked with `lang=`, `font=` or `map=`, with its containing NOTE Address, its `kind`, `lang` as written, the `tag` it resolves to, the `font` and `map` it is set with (its own, inherited, or its language's [script](#a-languages-script)), and source line/column. See [marking language, font and mapping](#marking-language-font-and-mapping). |
1502
- | `maps` | One row per row of a mapping note's `data.map`, with its containing NOTE Address, the map's `name`, the `font` whose own row it is (`NULL` for a shared row), the row's 1-based place as `"row"`, and its `"from"`, `"to"`, `before` and `"at"`. See [mapping notes](#mapping-notes). |
1503
- | `natives` | One row per native form a language note's word states in `native`, with that note as its `language`, the word's place as `word`, its `form`, the entry's place as `native`, and its `map`, `font` and `"text"`. See [what `map=` takes](#what-map-takes). |
1277
+ | `runs` | Each span, div and verse fence marked with `lang=`, `font=` or `enc=`, with its containing NOTE Address, its `kind`, `lang` as written, the `tag` it resolves to, the `font` and `enc` it is set with (its own, inherited, or its language's [script](#a-languages-script)), and source line/column. See [marking language, font and encoding](#marking-language-font-and-encoding). |
1278
+ | `natives` | One row per native form a language note's word states in `native`, with that note as its `language`, the word's place as `word`, its `form`, the entry's place as `native`, and its `enc`, `font` and `"text"`. See [what `enc=` takes](#what-enc-takes). |
1504
1279
  | `words` | One row per word a language note writes in `data.words`, with that note as its `language`, its `position` and what it is built from. |
1505
1280
  | `affixes` | One row per affix a language note writes in `data.affixes`, with that note as its `language`, its `position`, and each key the affix states: `form` (`NULL` on a zero affix), `zero`, `kind`, `given`, `"where"`, `gloss`, `attaches`, `replaces`, `attachesTo`, `lengthens`, `front`, `examples`, `barredAfter` and `tones`, then `written`, the form as a table prints it, `∅` for a zero affix. |
1506
1281
  | `fields` | One row per field a language note writes in `data.fields`, with that note as its `language`, its `position`, and the field's `name` and what it `holds`. |
@@ -1541,6 +1316,10 @@ A column's heading is its SQL alias, so `AS "Name"` is what a reader sees. A cel
1541
1316
  | `market` | The market scale as three columns — `value`, `name`, `trade` — so a table can print `village` beside the number a note wrote. |
1542
1317
  | `<package>.notes` | The same relations — `notes`, `entries`, `events`, `names`, `runs`, `maps`, `natives`, `words`, `affixes`, `fields`, `glossary`, `language_lineage`, `dictionary`, `terms`, `register`, `tongues`, `retired`, `scope`, `letters`, `edges`, `clusters`, `stress`, `finals`, `syllables`, `joining`, `joins`, `marks`, `skeleton`, `frames`, `read_past`, `mutations`, `cluster_groups`, `sound_changes`, `elements`, `roots`, `cognates`, `calling_names`, `older`, `negation`, `name_shapes`, `name_edges`, `name_draws`, `held_from` and `near_names` — for each package this one declares a dependency on, in a schema named for it. |
1543
1318
 
1319
+ The `natives.enc` SQL column preserves the authored reference. Conversion
1320
+ inputs resolve native encoding references to canonical Addresses in each
1321
+ source note's own package.
1322
+
1544
1323
  Nested frontmatter is addressed exactly as a note writes it: `name.full`, `sohl.weight`, `data.born`. Every Address is a string — the full canonical Address, as in `list_contains(data.parents, 'thalorna-note-place-xerathia')` — whichever package published it. Every note carries a computed `state` column of `full`, `draft` or `stub`, and a `nameSort` column holding its `name.sort` or, without one, its `name.full`, to `ORDER BY`. Notes tagged `gm` are absent from the relations on public surfaces.
1545
1324
 
1546
1325
  ### Sections the build adds