@heroiclands/package-build 23.12.6 → 23.12.7
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 +12 -0
- package/assets/styles/content-base.css +25 -0
- package/bin/content-commands.mjs +264 -3
- package/bin/package-build.mjs +25 -0
- package/content-config.mjs +72 -0
- package/docs/api.md +10 -9
- package/docs/authoring/links-and-markup.md +439 -47
- package/docs/commands.md +127 -0
- package/docs/configuration.md +66 -3
- package/docs/content-format.md +3 -1
- package/docs/guides/book.md +11 -0
- package/docs/guides/module-project.md +16 -0
- package/docs/guides/site.md +19 -0
- package/docs/reference/format-details.md +372 -6
- package/docs/reference/note-types.md +36 -11
- package/engine/base-compiler.mjs +2 -0
- package/engine/bundles.mjs +7 -2
- package/engine/compile-corpus.mjs +3 -1
- package/engine/content-charset.mjs +21 -2
- package/engine/content-format.yaml +1 -0
- package/engine/content-index.mjs +12 -0
- package/engine/content-poetry.mjs +22 -4
- package/engine/content-scripts.mjs +1219 -0
- package/engine/content-session.mjs +2 -0
- package/engine/data-keys.mjs +5 -1
- package/engine/dictionary-layout.mjs +18 -12
- package/engine/dictionary-rows.mjs +11 -2
- package/engine/helpers.mjs +8 -2
- package/engine/index-records.mjs +1 -0
- package/engine/journals.mjs +14 -3
- package/engine/language-data.mjs +137 -1
- package/engine/language-tag.mjs +103 -0
- package/engine/language-terms.mjs +16 -4
- package/engine/map-lexicon.mjs +762 -0
- package/engine/markup-validation.mjs +17 -3
- package/engine/names.mjs +1 -1
- package/engine/note-vocabulary.mjs +113 -0
- package/engine/pdf-build.mjs +28 -10
- package/engine/pdf-render.mjs +116 -11
- package/engine/run-rows.mjs +119 -0
- package/engine/run-words.mjs +266 -0
- package/engine/scenes.mjs +1 -0
- package/engine/script-font-delivery.mjs +321 -0
- package/engine/script-fonts.mjs +172 -0
- package/engine/site-build.mjs +10 -3
- package/engine/site-config.mjs +5 -0
- package/engine/site-root.mjs +19 -5
- package/engine/sql-tables.mjs +111 -1
- package/engine/text-maps.mjs +607 -0
- package/engine/verb-pattern.mjs +99 -0
- package/engine/word-pattern.mjs +27 -0
- package/engine/word-rows.mjs +8 -2
- package/engine/word-terms.mjs +44 -0
- package/hugo-theme/layouts/_default/baseof.html +3 -0
- package/hugo-theme/static/css/style.css +10 -0
- package/manifest.mjs +9 -1
- package/package.json +1 -1
- package/types/content-config.d.mts +26 -0
- package/types/engine/compile-corpus.d.mts +2 -1
- package/types/engine/content-index.d.mts +11 -3
- package/types/engine/content-poetry.d.mts +7 -0
- package/types/engine/content-scripts.d.mts +226 -0
- package/types/engine/data-keys.d.mts +2 -2
- package/types/engine/dictionary-rows.d.mts +15 -0
- package/types/engine/helpers.d.mts +5 -1
- package/types/engine/journals.d.mts +7 -2
- package/types/engine/language-data.d.mts +2 -0
- package/types/engine/language-tag.d.mts +8 -0
- package/types/engine/language-terms.d.mts +2 -1
- package/types/engine/map-lexicon.d.mts +274 -0
- package/types/engine/markup-validation.d.mts +7 -2
- package/types/engine/pdf-build.d.mts +26 -3
- package/types/engine/pdf-render.d.mts +17 -2
- package/types/engine/run-rows.d.mts +89 -0
- package/types/engine/run-words.d.mts +86 -0
- package/types/engine/script-font-delivery.d.mts +134 -0
- package/types/engine/script-fonts.d.mts +168 -0
- package/types/engine/site-build.d.mts +2 -1
- package/types/engine/site-root.d.mts +11 -3
- package/types/engine/text-maps.d.mts +175 -0
- package/types/engine/verb-pattern.d.mts +65 -0
- package/types/engine/word-pattern.d.mts +13 -0
- package/types/engine/word-terms.d.mts +6 -0
|
@@ -383,7 +383,9 @@ The optional `form`, `meter` and `rhyme` attributes record the author's intent;
|
|
|
383
383
|
the build does not infer stress, rhyme or pronunciation. `syllables` gives a
|
|
384
384
|
positive count for each verse line in order, separated by commas, with blank
|
|
385
385
|
stanza lines omitted. The build checks the number of counts, not the syllables
|
|
386
|
-
spoken. `lang`
|
|
386
|
+
spoken. `lang` names the poem's language, `font` the font it is set in and
|
|
387
|
+
`map` the mapping its text is rewritten by; see
|
|
388
|
+
[marking language, font and mapping](#marking-language-font-and-mapping). An optional `#id`
|
|
387
389
|
addresses the poem itself. There are no `title` or `lines` attributes, and no
|
|
388
390
|
special punctuation for stress, pauses or refrains.
|
|
389
391
|
|
|
@@ -400,6 +402,390 @@ The lantern marks the shore.
|
|
|
400
402
|
|
|
401
403
|
This uses the **Poem** counter, so `{{ref "#watch-song"}}` reads **Poem 1**. Use `:` for a caption without a number.
|
|
402
404
|
|
|
405
|
+
## Marking language, font and mapping
|
|
406
|
+
|
|
407
|
+
Three keys go in the attribute block a span, a fenced div or a poetry fence
|
|
408
|
+
already takes. Each is optional, and each does one thing:
|
|
409
|
+
|
|
410
|
+
- **`lang=`** names the language of the text. It becomes the element's
|
|
411
|
+
language tag and changes nothing else.
|
|
412
|
+
- **`font=`** names the font the text is set in: one of the faces of
|
|
413
|
+
`@heroiclands/fonts`, or `mono`, `serif` or `sans`.
|
|
414
|
+
- **`map=`** names a [mapping note](#mapping-notes), which rewrites the text
|
|
415
|
+
before it is set. Without `map=`, the text is set exactly as typed.
|
|
416
|
+
|
|
417
|
+
A note records Unicode characters. A face draws its own code points, so text in
|
|
418
|
+
a face is either typed in those code points (with a keyboard layout for the
|
|
419
|
+
face) or typed in roman letters and mapped into them.
|
|
420
|
+
|
|
421
|
+
A span in a language:
|
|
422
|
+
|
|
423
|
+
```markdown
|
|
424
|
+
The greeting at the door is [Daimela, helthos.]{lang=vyl}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
Vylari typed in roman letters, mapped into Semaron Kuriale and set in it:
|
|
428
|
+
|
|
429
|
+
```markdown
|
|
430
|
+
The lintel is cut with [Zaron tholmeza]{lang=vyl font=semaron-kuriale map=semaron}.
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Text typed in the face's own code points, with a keyboard layout for the face,
|
|
434
|
+
takes no map: `[…]{font=semaron-kuriale}` sets those code points as they are.
|
|
435
|
+
|
|
436
|
+
A passage of several paragraphs is a fenced div:
|
|
437
|
+
|
|
438
|
+
```markdown
|
|
439
|
+
::: {lang=vyl font=semaron-kuriale map=semaron}
|
|
440
|
+
Zaron tholmeza.
|
|
441
|
+
|
|
442
|
+
Daimela, helthos.
|
|
443
|
+
:::
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
A poem takes the keys on its fence, beside its other attributes:
|
|
447
|
+
|
|
448
|
+
````markdown
|
|
449
|
+
```poetry {form=epic lang=vyl font=semaron-kuriale map=semaron}
|
|
450
|
+
Zaron tholmeza,
|
|
451
|
+
daimela, helthos.
|
|
452
|
+
```
|
|
453
|
+
````
|
|
454
|
+
|
|
455
|
+
**A run inside a div or a poetry fence inherits its keys**, and its own keys
|
|
456
|
+
override them. Here the gloss keeps the passage's language and map, and is set
|
|
457
|
+
in the page's serif:
|
|
458
|
+
|
|
459
|
+
```markdown
|
|
460
|
+
::: {lang=vyl font=semaron-kuriale map=semaron}
|
|
461
|
+
Zaron tholmeza, [an oath, a vow]{lang=en font=serif}.
|
|
462
|
+
:::
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### What `lang=` takes
|
|
466
|
+
|
|
467
|
+
`lang=` is read in this order:
|
|
468
|
+
|
|
469
|
+
1. **A name declared in [`languages`](../configuration.md#languages).**
|
|
470
|
+
`lang=vyl` is Vylari, tagged with the configured `art-x-vyl`.
|
|
471
|
+
2. **Otherwise, a BCP 47 language tag** for a real language: `la`, `grc`,
|
|
472
|
+
`en-GB`. The tag is checked for its form alone, by the rules of RFC 5646
|
|
473
|
+
that need no registry; whether each subtag is registered is not checked.
|
|
474
|
+
|
|
475
|
+
A declared name wins over a tag spelled the same way. A value that is neither is
|
|
476
|
+
an error. Because a tag is checked only for its form, a misspelled name that is
|
|
477
|
+
still a well-formed tag, such as `vly` for `vyl`, is read as the tag of a real
|
|
478
|
+
language. When such a value is within one edit of a declared name (a letter
|
|
479
|
+
added, dropped or changed, two neighbours swapped, or a different case), `lint`
|
|
480
|
+
warns and names the declared language. Text marked with `lang=` alone is not
|
|
481
|
+
checked against any lexicon; a run with `lang=` and `map=` is, as
|
|
482
|
+
[a mapped run's words](#a-mapped-runs-words) describes.
|
|
483
|
+
|
|
484
|
+
### What `font=` takes
|
|
485
|
+
|
|
486
|
+
`font=` is one of:
|
|
487
|
+
|
|
488
|
+
- **a face of the `@heroiclands/fonts` package this package installs**, named
|
|
489
|
+
by its class without `hl-`: the face whose class is `hl-semaron-kuriale` is
|
|
490
|
+
`font=semaron-kuriale`. package-build does not depend on the fonts package;
|
|
491
|
+
a package that sets text in a face adds it to its own `devDependencies`:
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
npm install --save-dev @heroiclands/fonts
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
- **`mono`, `serif` or `sans`**, the generic families. On the site `serif` and
|
|
498
|
+
`mono` are the site's own body and code faces and `sans` is the reader's
|
|
499
|
+
sans-serif; in Foundry they are the reader's generic families; in a book
|
|
500
|
+
they are the book's own serif, sans and mono, as `pdf.fonts` names them.
|
|
501
|
+
|
|
502
|
+
**A face draws only the code points its `fonts.json` lists**, and whitespace.
|
|
503
|
+
After the map, every other character in text set in a face is an error at the
|
|
504
|
+
character it came from, so a box never reaches a reader. The generic families
|
|
505
|
+
are not checked.
|
|
506
|
+
|
|
507
|
+
### What `map=` takes
|
|
508
|
+
|
|
509
|
+
`map=` is the `data.map.name` of a [mapping note](#mapping-notes) in this
|
|
510
|
+
package. The map is applied to the run's text before anything else, and what
|
|
511
|
+
it writes is what the face draws. A map belongs to a script and serves every
|
|
512
|
+
language written in it; it lists the faces it is drawn in, and a run's `font=`
|
|
513
|
+
is one of them.
|
|
514
|
+
|
|
515
|
+
**With `lang=`, the language's dictionary comes first.** Where
|
|
516
|
+
[`languages.<name>.note`](../configuration.md#languages) names the language's
|
|
517
|
+
note, each word of the run is looked up in its `data.words`:
|
|
518
|
+
|
|
519
|
+
1. **A word whose entry states a `native` form for the map** is written by it:
|
|
520
|
+
the form stated for the run's face where there is one, else the form stated
|
|
521
|
+
for no face.
|
|
522
|
+
2. **Every other word is spelled by the rows**: coinages, names, and every
|
|
523
|
+
derived form, so a plural or a verb ending of an exception word is spelled
|
|
524
|
+
by the rows too.
|
|
525
|
+
|
|
526
|
+
A word is a run of letters, marks and digits, with an apostrophe, a hyphen or
|
|
527
|
+
an en dash joining two such runs into one word; everything between words is
|
|
528
|
+
spelled by the rows. A word is looked up as written and then in lowercase.
|
|
529
|
+
**A capitalised word found in lowercase** takes its capital from the rows: its
|
|
530
|
+
first sound, mapped as written and in lowercase, replaces the beginning of the
|
|
531
|
+
native form where the native form begins as the rows begin the word. A native
|
|
532
|
+
form that begins otherwise cannot be capitalised by the rows, and the
|
|
533
|
+
capitalised word is an error; state it as a word of its own, `Orlan` beside
|
|
534
|
+
`orlan`, with its own native form.
|
|
535
|
+
|
|
536
|
+
With `map=` and no `lang=`, a bare tag, or a declared language with no `note`,
|
|
537
|
+
the rows alone apply.
|
|
538
|
+
|
|
539
|
+
Take Vylari's `zaron`, an oath, written in Semaron. With no exception stated,
|
|
540
|
+
the rows spell it letter by letter, as they spell any word:
|
|
541
|
+
|
|
542
|
+
```yaml
|
|
543
|
+
- form: zaron
|
|
544
|
+
class: n
|
|
545
|
+
field: "Law, the court and the written act"
|
|
546
|
+
gloss: an oath
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
Where the chancery writes the word another way, the entry states that once,
|
|
550
|
+
and `[zaron]{lang=vyl font=semaron-kuriale map=semaron}` is written by it:
|
|
551
|
+
|
|
552
|
+
```yaml
|
|
553
|
+
- form: zaron
|
|
554
|
+
class: n
|
|
555
|
+
field: "Law, the court and the written act"
|
|
556
|
+
gloss: an oath
|
|
557
|
+
native:
|
|
558
|
+
- { map: semaron, text: "\U000F024F\U000F0230\U000F023F\U000F023C" }
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
A native form that is what the rows give already is an error ("states what the
|
|
562
|
+
rows already give"), so a lexicon carries its exceptions and nothing else.
|
|
563
|
+
`package-build lexicon vyl --map semaron` lists every word with its native form
|
|
564
|
+
and whether it is an exception, and `package-build transliterate semaron --lang
|
|
565
|
+
vyl zaron` converts a passage, both through the build's own code; see
|
|
566
|
+
[the command reference](../commands.md#package-build-transliterate-map-text).
|
|
567
|
+
|
|
568
|
+
### A mapped run's words
|
|
569
|
+
|
|
570
|
+
**Every word of a run with `lang=` and `map=` is a word of its language**, where
|
|
571
|
+
the language's [`note`](../configuration.md#languages) names its language note.
|
|
572
|
+
Each word, case folded, is one of:
|
|
573
|
+
|
|
574
|
+
1. **a lexicon word**: a `data.words[].form` of the language;
|
|
575
|
+
2. **a word of a registered name**: a word of a `name` in the language note's
|
|
576
|
+
own `data.register`, under any `tongue` but `translation`. A name of several
|
|
577
|
+
words is checked word by word, so `Revothar Baremzator` admits `Revothar`
|
|
578
|
+
and `Baremzator`. A foreign name the run uses is listed in the language's
|
|
579
|
+
own register first, as `other:<tongue>` (`{ name: Epistémion, tongue:
|
|
580
|
+
"other:helonic" }` in Vylari's), and that row is checked against the Helonic
|
|
581
|
+
register in turn; see
|
|
582
|
+
[a language's register](../reference/format-details.md#a-languages-register-sounds-and-history);
|
|
583
|
+
3. **a regular form of a lexicon word**, made by one rule the language states:
|
|
584
|
+
- the plural `data.grammar.plural` gives a noun, or the noun's own `plural`;
|
|
585
|
+
- a verb's form with one ending of `data.grammar.verbs.persons`, which
|
|
586
|
+
takes the place of a closing `data.grammar.verbs.replaces` where the
|
|
587
|
+
pattern states one, so `lokathen` with `replaces: then` gives `lokazor`;
|
|
588
|
+
- a suffix of `data.affixes` that states `replaces`, or its `front` form.
|
|
589
|
+
`replaces: vowel` takes the place of a closing vowel (a letter whose base
|
|
590
|
+
is `a`, `e`, `i`, `o` or `u`), letters such as `replaces: a` take the
|
|
591
|
+
place of those letters, and a stem that closes otherwise takes the suffix
|
|
592
|
+
whole. An affix that states no `replaces` makes no form here, whatever its
|
|
593
|
+
`attaches` says, because `attaches` is prose.
|
|
594
|
+
|
|
595
|
+
A compound that is not a word whole is split at its hyphens and en dashes, and
|
|
596
|
+
each part is checked, so `zaron-lonak` passes when `zaron` and `lonak` do. An
|
|
597
|
+
apostrophe joins a word: `k'aralzon` is one word, and `’` reads as `'`. A word
|
|
598
|
+
with no letter, such as a numeral, is not checked.
|
|
599
|
+
|
|
600
|
+
Any other word is an error at its first character, reported once per run and
|
|
601
|
+
naming the language as `lang=` writes it:
|
|
602
|
+
|
|
603
|
+
> `` `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 ``
|
|
604
|
+
|
|
605
|
+
The check recognises a form and never requires one: a noun stated with its own
|
|
606
|
+
plural and the plural the rule gives both pass, and nothing checks that a word
|
|
607
|
+
takes the right ending.
|
|
608
|
+
|
|
609
|
+
**To coin a word**, add it to the language note's `data.words` with its class,
|
|
610
|
+
field and gloss:
|
|
611
|
+
|
|
612
|
+
```yaml
|
|
613
|
+
words:
|
|
614
|
+
- form: thiruthrimar
|
|
615
|
+
class: n
|
|
616
|
+
field: "Law, the court and the written act"
|
|
617
|
+
gloss: a sworn witness
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
**To register a name**, add a row to the `data.register` of the language it is
|
|
621
|
+
in, with its tongue:
|
|
622
|
+
|
|
623
|
+
```yaml
|
|
624
|
+
register:
|
|
625
|
+
- { name: Revothar Baremzator, tongue: vylari }
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
A run with `lang=` and no `map=`, a run with `map=` and no
|
|
629
|
+
`lang=`, a bare BCP 47 tag and a declared language with no `note` are not
|
|
630
|
+
checked.
|
|
631
|
+
|
|
632
|
+
### Mapping notes
|
|
633
|
+
|
|
634
|
+
A mapping note is a `doc` note whose `data.map` lists the rewrites:
|
|
635
|
+
|
|
636
|
+
```yaml
|
|
637
|
+
---
|
|
638
|
+
type: doc
|
|
639
|
+
subType: reference
|
|
640
|
+
shortcode: semaronmap
|
|
641
|
+
name:
|
|
642
|
+
full: Vylari in Semaron Kuriale
|
|
643
|
+
data:
|
|
644
|
+
map:
|
|
645
|
+
name: semaron
|
|
646
|
+
vowels: "aeiouAEIOU"
|
|
647
|
+
fonts:
|
|
648
|
+
- font: semaron-kuriale
|
|
649
|
+
- font: semaron-carved
|
|
650
|
+
rows:
|
|
651
|
+
- [th, "\U000F0251"] # the carved th
|
|
652
|
+
rows:
|
|
653
|
+
- [a, "\U000F0230"]
|
|
654
|
+
- [aa, "\U000F0248"] # long a, its own letter
|
|
655
|
+
- [t, "\U000F0241"]
|
|
656
|
+
- [h, "\U000F0236"]
|
|
657
|
+
- [th, "\U000F0250"]
|
|
658
|
+
- [y, "\U000F0245"]
|
|
659
|
+
- { from: y, to: "\U000F0237", before: consonant }
|
|
660
|
+
---
|
|
661
|
+
How Vylari's roman spelling is written in the Semaron chancery hand.
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
- **`name`** is what `map=` names it by: lowercase letters, digits and `-`,
|
|
665
|
+
unique in the package.
|
|
666
|
+
- **`fonts`** lists the faces the map is drawn in, at least one, each by the
|
|
667
|
+
slug `font=` names it by. A face may carry `rows` of its own, which a run in
|
|
668
|
+
that face tries first, the longest match among them, before the shared
|
|
669
|
+
`rows`. `mono`, `serif` and `sans` are not listed. Every listed face must draw
|
|
670
|
+
every character its own rows, the shared rows it reaches, and the lexicons'
|
|
671
|
+
native forms for it write; `lint` reports a gap at the row or the entry.
|
|
672
|
+
- **`rows`** is a list. A row is `[from, to]`, or
|
|
673
|
+
`{from, to, before?, at?}`. `from` is one or more characters and `to` any
|
|
674
|
+
number of them, none included: a map that drops a language's vowels writes
|
|
675
|
+
`[a, ""]`. A double-quoted YAML string writes a code point by its escape:
|
|
676
|
+
the fonts' scripts sit in plane 15, so their code points take the
|
|
677
|
+
eight-digit `\U`, as `"\U000F0200"` for U+F0200, and the four-digit `\u`
|
|
678
|
+
reaches only code points up to U+FFFF. A row matches and writes whole code
|
|
679
|
+
points.
|
|
680
|
+
- **`vowels`** lists the characters `before: vowel` reads as vowels.
|
|
681
|
+
|
|
682
|
+
How a map reads text:
|
|
683
|
+
|
|
684
|
+
- **The longest match wins.** `th` above is one letter, and `t` and `h` are
|
|
685
|
+
read only where `th` does not match. Among rows of the same length, a row
|
|
686
|
+
with a condition that holds comes before a row with none, and otherwise the
|
|
687
|
+
earlier row wins.
|
|
688
|
+
- **A row whose condition fails is skipped.**
|
|
689
|
+
- `before: vowel` holds when the next character is one of `vowels`;
|
|
690
|
+
`before: consonant` when it is any other letter. Neither holds at the end
|
|
691
|
+
of the text.
|
|
692
|
+
- `at: start` holds at the first character of the run, or after whitespace
|
|
693
|
+
or punctuation; `at: end` holds at the last, or before whitespace or
|
|
694
|
+
punctuation.
|
|
695
|
+
- **A character no row matches passes through unchanged**, so a map for a face
|
|
696
|
+
that draws nothing on roman code points lists every letter the spelling
|
|
697
|
+
uses, and anything left over is reported.
|
|
698
|
+
- `rows` is a list rather than a keyed map, so `A` and `a` are two rows. Each
|
|
699
|
+
row is a row of the [`maps` relation](../reference/format-details.md#content-tables).
|
|
700
|
+
|
|
701
|
+
The body describes the mapping for a reader; nothing reads it. See
|
|
702
|
+
[mapping notes](../reference/format-details.md#mapping-notes) for every
|
|
703
|
+
finding the lint reports in `data.map`.
|
|
704
|
+
|
|
705
|
+
### How marked text is set
|
|
706
|
+
|
|
707
|
+
Every target rewrites marked text first, so a page, a Foundry journal and a
|
|
708
|
+
book all show the same thing.
|
|
709
|
+
|
|
710
|
+
| Marking | The text | The element |
|
|
711
|
+
| -------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------ |
|
|
712
|
+
| `lang=` alone | As written | Tagged with the language's tag, `lang="art-x-vyl"` |
|
|
713
|
+
| `map=` | Rewritten by the map, line by line | As below |
|
|
714
|
+
| `font=` a face | As written, or as the map wrote it | The tag, `script` and the face's class; not indexed by the site's search |
|
|
715
|
+
| `font=mono`, `serif`, `sans` | As written, or as the map wrote it | The tag and `font-mono`, `font-serif` or `font-sans` |
|
|
716
|
+
| A div or fence in a right-to-left face | As above | Also `dir="rtl"`; a div also carries `script-block` |
|
|
717
|
+
|
|
718
|
+
No target writes `<bdo>`, `<bdi>` or a Unicode direction control character: a
|
|
719
|
+
right-to-left face's code points carry their own direction. Text with an error
|
|
720
|
+
in it is left as written.
|
|
721
|
+
|
|
722
|
+
In a book, a real language's tag sets the language of the text so its
|
|
723
|
+
hyphenation follows; an invented language's tag leaves the book's language
|
|
724
|
+
alone. A block or verse in a right-to-left face is set right to left.
|
|
725
|
+
|
|
726
|
+
### Plain text
|
|
727
|
+
|
|
728
|
+
Text marked with `font=` or `map=`, or with a language the package declares, is
|
|
729
|
+
plain text.
|
|
730
|
+
|
|
731
|
+
- **A span or a verse line** holds no emphasis, link, image, footnote,
|
|
732
|
+
wikilink, code or HTML, and no span but a marked one inside a div or a fence.
|
|
733
|
+
- **A div** holds paragraphs and line breaks only: no heading, list, block
|
|
734
|
+
quote, code fence, poetry fence, table, rule, footnote definition or nested
|
|
735
|
+
block. Mark a poem's own fence instead of a div around it.
|
|
736
|
+
|
|
737
|
+
The text is read as written, so characters a run types need no escaping: `[`
|
|
738
|
+
and `]`, `"`, `<<` and `>>`, `!`, and `@ # $ % ^ &`. A pair of brackets is two
|
|
739
|
+
characters unless what follows makes it markup: `(` makes a link, `{` a span,
|
|
740
|
+
and a doubled `[[` a wikilink. `[^id]` is a footnote only where the note
|
|
741
|
+
defines `[^id]:`. A bracket with no partner takes a backslash, `\[`.
|
|
742
|
+
|
|
743
|
+
Text marked with a real language's tag alone keeps its Markdown, so
|
|
744
|
+
`[ad _astra_]{lang=la}` and an English poem with emphasis are both accepted.
|
|
745
|
+
|
|
746
|
+
### Errors
|
|
747
|
+
|
|
748
|
+
Each of these is an error at its line and column, reported by `lint`, the site
|
|
749
|
+
build, the Foundry compile and the book, except the last row, which is a warning
|
|
750
|
+
that `lint` reports and that fails nothing:
|
|
751
|
+
|
|
752
|
+
| Message | Fix |
|
|
753
|
+
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
754
|
+
| `` `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. |
|
|
755
|
+
| `` `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. |
|
|
756
|
+
| `` `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`. |
|
|
757
|
+
| `` `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. |
|
|
758
|
+
| `` `x` (U+0078) is not drawn by the font `semaron-kuriale` `` | Type the face's code points, or add `map=`. |
|
|
759
|
+
| `` `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. |
|
|
760
|
+
| `` `ch` maps to U+F0299 in the map `semaron`, which the font `semaron-kuriale` does not draw `` | Correct the row's `to`. |
|
|
761
|
+
| `` `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. |
|
|
762
|
+
| `` `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. |
|
|
763
|
+
| `` `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. |
|
|
764
|
+
| `` `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`. |
|
|
765
|
+
| ``text marked `lang=vyl` is plain text and holds no emphasis`` | Remove the markup, or escape the character with a backslash. |
|
|
766
|
+
| ``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. |
|
|
767
|
+
| `` `font=` is read on a span, a div or a poetry fence, not on a secret block `` | Put a marked div inside the secret block. |
|
|
768
|
+
| `` `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. |
|
|
769
|
+
|
|
770
|
+
A character the face does not draw is reported once per run, at its first
|
|
771
|
+
place; through a map it is located at the start of the matched `from`.
|
|
772
|
+
|
|
773
|
+
### Finding marked text
|
|
774
|
+
|
|
775
|
+
Every marked span, div and fence is a row of the `runs` relation, so a table can
|
|
776
|
+
list them:
|
|
777
|
+
|
|
778
|
+
````markdown
|
|
779
|
+
```sql
|
|
780
|
+
SELECT owner, kind, tag, font, line FROM runs WHERE lang = 'vyl' ORDER BY owner, line
|
|
781
|
+
```
|
|
782
|
+
````
|
|
783
|
+
|
|
784
|
+
Its columns are `owner`, `kind` (`span`, `block` or `poetry`), `lang` as written,
|
|
785
|
+
the `tag` it resolves to (`NULL` when it resolves to none), `font`, `map`, `line`
|
|
786
|
+
and `column`. A run inside a div or a fence records the keys it inherits. See
|
|
787
|
+
[the `runs` relation](../reference/format-details.md#content-tables).
|
|
788
|
+
|
|
403
789
|
## Footnotes and definition lists
|
|
404
790
|
|
|
405
791
|
Write a footnote reference as `[^id]` and its definition as `[^id]: text`.
|
|
@@ -497,51 +883,54 @@ A column's heading is its SQL alias, so `AS "Name"` is what a reader sees. A cel
|
|
|
497
883
|
|
|
498
884
|
### What a query can read
|
|
499
885
|
|
|
500
|
-
| Relation | What it holds
|
|
501
|
-
| ------------------ |
|
|
502
|
-
| `notes` | Every note except a stub. This is the one to use unless a stub is wanted.
|
|
503
|
-
| `entries` | Every note, stubs included.
|
|
504
|
-
| `events` | One row per event a `lore`, `place` or `affiliation` note writes in `data.events`, with `whenSort` to order them by date.
|
|
505
|
-
| `names` | Each authored `.name` span, with its containing NOTE Address, visible text, optional type/subtype and source line/column.
|
|
506
|
-
| `
|
|
507
|
-
| `
|
|
508
|
-
| `
|
|
509
|
-
| `
|
|
510
|
-
| `
|
|
511
|
-
| `
|
|
512
|
-
| `
|
|
513
|
-
| `
|
|
514
|
-
| `
|
|
515
|
-
| `
|
|
516
|
-
| `
|
|
517
|
-
| `
|
|
518
|
-
| `
|
|
519
|
-
| `
|
|
520
|
-
| `
|
|
521
|
-
| `
|
|
522
|
-
| `
|
|
523
|
-
| `
|
|
524
|
-
| `
|
|
525
|
-
| `
|
|
526
|
-
| `
|
|
527
|
-
| `
|
|
528
|
-
| `
|
|
529
|
-
| `
|
|
530
|
-
| `
|
|
531
|
-
| `
|
|
532
|
-
| `
|
|
533
|
-
| `
|
|
534
|
-
| `
|
|
535
|
-
| `
|
|
536
|
-
| `
|
|
537
|
-
| `
|
|
538
|
-
| `
|
|
539
|
-
| `
|
|
540
|
-
| `
|
|
541
|
-
| `
|
|
542
|
-
| `
|
|
543
|
-
| `
|
|
544
|
-
|
|
|
886
|
+
| Relation | What it holds |
|
|
887
|
+
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
888
|
+
| `notes` | Every note except a stub. This is the one to use unless a stub is wanted. |
|
|
889
|
+
| `entries` | Every note, stubs included. |
|
|
890
|
+
| `events` | One row per event a `lore`, `place` or `affiliation` note writes in `data.events`, with `whenSort` to order them by date. |
|
|
891
|
+
| `names` | Each authored `.name` span, with its containing NOTE Address, visible text, optional type/subtype and source line/column. |
|
|
892
|
+
| `runs` | Each span, div and poetry fence marked with `lang=`, `font=` or `map=`, with its containing NOTE Address, its `kind`, `lang` as written, the `tag` it resolves to, `font`, `map`, and source line/column. See [marking language, font and mapping](#marking-language-font-and-mapping). |
|
|
893
|
+
| `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). |
|
|
894
|
+
| `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). |
|
|
895
|
+
| `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. |
|
|
896
|
+
| `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`, `lengthens`, `front`, `examples`, `barredAfter` and `tones`, then `written`, the form as a table prints it, `∅` for a zero affix. |
|
|
897
|
+
| `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`. |
|
|
898
|
+
| `glossary` | One row per entry a culture or an affiliation writes in `data.glossary`, with the `note` it belongs to and the `language` it resolves to. |
|
|
899
|
+
| `language_lineage` | One row per language note and each language it inherits words from through `data.family`, itself included at `depth` 0. Join it to `words` for a language's words with inherited ones. |
|
|
900
|
+
| `dictionary` | One row per word per language it is listed under, inherited words included, with its `depth`. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
|
|
901
|
+
| `terms` | One row per glossary entry, rank or office per note that owns it, with its `cultures` associations. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
|
|
902
|
+
| `register` | One row per name a language note writes in `data.register`, with its `tongue`, `kind`, `gloss` and `why`, its pieces as `built_text`, and the `notes` carrying the name, derived from the index. |
|
|
903
|
+
| `tongues` | One row per tag a language note writes in `data.tongues`: `tag`, `meaning` and `tongue_language`. |
|
|
904
|
+
| `retired` | One row per form a language note writes in `data.retired`: `form`, `instead` as a list, and `why`. |
|
|
905
|
+
| `scope` | One row per value of a language note's `data.scope`: the `kind` it is under and the `value`. |
|
|
906
|
+
| `letters` | One row per entry of a language note's `data.sounds.letters`: `letters` as a list, `kind`, `like`, `place` and `tongue`. |
|
|
907
|
+
| `edges` | One row per entry of a language note's `data.sounds.edges`: the `edge` and its `sounds` as a list. |
|
|
908
|
+
| `clusters` | One row per language note stating `data.sounds.clusters`, with its `max`. |
|
|
909
|
+
| `cluster_groups` | One row per group of a language note's `data.sounds.clusters.groups`: `what`, `clusters` as a list, and `use`. |
|
|
910
|
+
| `stress` | One row per language note stating `data.sounds.stress`, with its `stress`. |
|
|
911
|
+
| `finals` | One row per entry of a language note's `data.sounds.finals`: `final` and `like`. |
|
|
912
|
+
| `syllables` | One row per language note stating `data.sounds.syllables`: each rule a column, the harmony as `harmony_back`, `harmony_front`, `harmony_neutral`, `harmony_neutralAs` and `harmony_partners`, a list of `{ vowel, partner }`. |
|
|
913
|
+
| `joining` | One row per entry of a language note's `data.sounds.joining`: `first`, `second`, `written` and `example`. |
|
|
914
|
+
| `joins` | One row per entry of a language note's `data.sounds.joins`: `meeting`, `rule`, `letters` and `"where"`. |
|
|
915
|
+
| `marks` | One row per entry of a language note's `data.sounds.marks`: `mark`, `letters`, `kind` and `"limit"`. |
|
|
916
|
+
| `skeleton` | One row per entry of a language note's `data.sounds.skeleton`: `second` and `between`. |
|
|
917
|
+
| `frames` | One row per frame of a language note's `data.sounds.frames`: `frame`, `shape`, `class`, `makes` and `examples` as `{ root, form }`. |
|
|
918
|
+
| `read_past` | One row per entry of a language note's `data.sounds.readPast`: `written`, `readAs` and `what`. |
|
|
919
|
+
| `mutations` | One row per entry of a language note's `data.sounds.mutations`: `mutation`, `sound`, `becomes` and `example`. |
|
|
920
|
+
| `sound_changes` | One row per step of each set in a language note's `data.soundChanges`: the set's `position`, `name`, `from_language`, `to_language` and `takes`, then `step_position`, `step`, `change` and `"where"`. |
|
|
921
|
+
| `elements` | One row per element of a language note's `data.elements`: `form`, `variants`, `element_position`, `kind`, `sense`, `examples`, `word` and `joining`. |
|
|
922
|
+
| `roots` | One row per root of a language note's `data.roots`: `root`, `sense` and `field`. |
|
|
923
|
+
| `cognates` | One row per form of each set in a language note's `data.cognates`: the set's `position`, `gloss` and `proto`, the `form_language` and the `form`. |
|
|
924
|
+
| `calling_names` | One row per closing of a language note's `data.callingNames`: `form`, `doubled`, `usual` and the language's `min_syllables`. |
|
|
925
|
+
| `older` | One row per form of a language note's `data.older`: `form`, `gloss` and `layer`. |
|
|
926
|
+
| `negation` | One row per language note stating `data.negation`: its `particle` and `mutation`. |
|
|
927
|
+
| `name_shapes` | One row per entry of a language note's `data.naming.shapes`: `of`, `syllables_min`, `syllables_max`, `per_vowel_min` and `per_vowel_max`. |
|
|
928
|
+
| `name_edges` | One row per entry of a language note's `data.naming.edges`: `edge`, `sounds` as a list, `vowel` and `of`. |
|
|
929
|
+
| `name_draws` | One row per entry of a language note's `data.naming.draws`: `kind` and `elements` as a list. |
|
|
930
|
+
| `held_from` | One row per entry of a language note's `data.naming.heldFrom`: `source`, `takes`, `clip`, and `joining` and `elements` as lists. |
|
|
931
|
+
| `near_names` | One row per worked example of a language note's `data.naming.nearName`: `near`, `given` and the language's `min_syllables`. |
|
|
932
|
+
| `market` | The market scale as three columns — `value`, `name`, `trade` — so a table can print `village` beside the number a note wrote. |
|
|
933
|
+
| `<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. |
|
|
545
934
|
|
|
546
935
|
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.
|
|
547
936
|
|
|
@@ -1087,7 +1476,10 @@ where one is available: **marendos** _n. m., pl. marendoi_. An explicit
|
|
|
1087
1476
|
word plural wins; otherwise the language's optional `grammar.plural` rule
|
|
1088
1477
|
replaces the first matching literal ending. The language's optional
|
|
1089
1478
|
`grammar.verbs` pattern prints once as a small head table, after the key and
|
|
1090
|
-
before the letters.
|
|
1479
|
+
before the letters. Each ending is added to the citation form, or, where the
|
|
1480
|
+
pattern states `replaces`, takes the place of those closing letters, and the
|
|
1481
|
+
table's heading says which. Empty verb endings print as "unchanged", or as
|
|
1482
|
+
the letters they drop. Grammar is
|
|
1091
1483
|
never inherited through `family`, and absent grammar leaves the dictionary
|
|
1092
1484
|
unchanged. The [worked noun and verb example](../reference/format-details.md#optional-noun-and-verb-forms)
|
|
1093
1485
|
shows both declarations. Only supplied shapes are checked; words are never
|