@heroiclands/package-build 23.6.1 → 23.7.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.
@@ -451,48 +451,217 @@ These fields are accepted by every note type. A field's value can still be irrel
451
451
 
452
452
  **Subtypes:** `social`, `nature`, `craft`, `lore`, `language`, `script`, `mystical`, `physical`, `combat`, `combattechnique`.
453
453
 
454
- | Field | Shape | Meaning |
455
- | ----------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
456
- | `data.icon` | an Address | The document's profile art — an `icon` address, resolved into `img`. |
457
- | `data.templatePriority` | number | Template priority; unset means the note is not a template. |
458
- | `data.masteryLevel` | number | Mastery before any modifier. |
459
- | `data.parentSkill` | an Address | The skill this one specialises. |
460
- | `data.names` | a language's name lists | How this language's speakers are named, for `package-build npc new`: `pattern` builds a name from placeholders such as "{given} {clan}" and literal text, `given` maps a gender to a list of given names, `female` and `male` required, and every other key is a list of names a placeholder of the same name draws from. A language skill note only. See [name lists](format-details.md#name-lists). |
461
- | `data.family` | an Address | The parent language, as a language skill note: this language reads the parent's words, and its parents' in turn, as its own. A language skill note only. See [a language's words](format-details.md#a-languages-words). |
462
- | `data.abbreviation` | a string, such as `Prov.` | The tag a dictionary prints for the language, beside an entry's class and in an etymology, as `Prov.`; the language's full name where unstated. A language skill note only. See [a language's words](format-details.md#a-languages-words). |
463
- | `data.classModifiers` | list of word class modifiers | The class modifiers the language uses, from the master word classes. A word's class may carry only these. Empty when unstated. A language skill note only. |
464
- | `data.fields` | list of `{ name, holds }` | The fields the language's words are grouped under. A language skill note only. |
465
- | `data.words` | list of `{ form, class, field, gloss, … }` | The language's words, one map each, in the order they print. A language skill note only. See [a language's words](format-details.md#a-languages-words). |
466
- | `data.affixes` | list of `{ form, gloss, attaches?, examples? }` | The affixes a word's `built` pieces may name, each with its gloss. A language skill note only. |
454
+ | Field | Shape | Meaning |
455
+ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
456
+ | `data.icon` | an Address | The document's profile art — an `icon` address, resolved into `img`. |
457
+ | `data.templatePriority` | number | Template priority; unset means the note is not a template. |
458
+ | `data.masteryLevel` | number | Mastery before any modifier. |
459
+ | `data.parentSkill` | an Address | The skill this one specialises. |
460
+ | `data.names` | a language's name lists | How this language's speakers are named, for `package-build npc new`: `pattern` builds a name from placeholders such as "{given} {clan}" and literal text, `given` maps a gender to a list of given names, `female` and `male` required, and every other key is a list of names a placeholder of the same name draws from. A language skill note only. See [name lists](format-details.md#name-lists). |
461
+ | `data.family` | an Address | The parent language, as a language skill note: this language reads the parent's words, and its parents' in turn, as its own. A language skill note only. See [a language's words](format-details.md#a-languages-words). |
462
+ | `data.abbreviation` | a string, such as `Prov.` | The tag a dictionary prints for the language, beside an entry's class and in an etymology, as `Prov.`; the language's full name where unstated. A language skill note only. See [a language's words](format-details.md#a-languages-words). |
463
+ | `data.classModifiers` | list of word class modifiers | The class modifiers the language uses, from the master word classes. A word's class may carry only these. Empty when unstated. A language skill note only. |
464
+ | `data.fields` | list of `{ name, holds }` | The fields the language's words are grouped under. A language skill note only. |
465
+ | `data.words` | list of `{ form, class, field, gloss, … }` | The language's words, one map each, in the order they print. A language skill note only. See [a language's words](format-details.md#a-languages-words). |
466
+ | `data.affixes` | list of `{ form, gloss, attaches?, examples? }` | The affixes a word's `built` pieces may name, each with its gloss. A language skill note only. |
467
+ | `data.tongues` | list of `{ tag, meaning, language? }` | The tags a register row's `tongue` may name, each with what it means. A language skill note only. |
468
+ | `data.register` | list of `{ name, tongue?, kind?, built?, gloss?, why? }` | Every name the setting gives in the language's reach, with its tongue and pieces; the notes carrying each name are derived. A language skill note only. |
469
+ | `data.retired` | list of `{ form, instead?, why }` | The forms the setting does not write, and why. A language skill note only. |
470
+ | `data.scope` | a map — `{ folders?, cultures?, lore?, parents?, addresses?, paths?, types?, skip? }` | The notes the register covers. A language skill note only. |
471
+ | `data.sounds` | a map — `{ letters?, edges?, clusters?, stress?, finals?, syllables?, joining?, joins?, marks?, skeleton?, frames?, readPast?, mutations? }` | The letters the language writes and the rules its words keep. A language skill note only. |
472
+ | `data.soundChanges` | list of `{ name, from?, to?, takes?, steps }` | Named sets of ordered changes, each making one tongue's words from another's. A language skill note only. |
473
+ | `data.elements` | list of `{ form, variants?, position?, kind?, sense, examples?, word?, genitive? }` | The elements the language's names are built from. A language skill note only. |
474
+ | `data.roots` | list of `{ root, sense, field? }` | The consonantal roots the language's words are set from. A language skill note only. |
475
+ | `data.cognates` | list of `{ forms, proto?, gloss }` | Sets of forms one older word takes in several languages, stated on the eldest. A language skill note only. |
476
+ | `data.callingNames` | a map — `{ closings, minSyllables }` | The short name a long given name is called by. A language skill note only. |
477
+ | `data.older` | list of `{ form, gloss?, layer? }` | The words and names older than the language's rules, which no sound or name rule holds. A language skill note only. |
478
+ | `data.negation` | a map — `{ particle, mutation? }` | How a verb is negated. A language skill note only. |
479
+ | `data.naming` | a map — `{ shapes?, edges?, draws?, heldFrom?, nearName? }` | The shapes, edges and sources the language's names keep beyond its words' rules. A language skill note only. |
467
480
 
468
481
  **Inner keys** — a key a field's value does not declare is an error at its own line and column.
469
482
 
470
- | Key | Shape | Required | Meaning |
471
- | ------------------------------ | --------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
472
- | `data.names.pattern` | a pattern such as "{given} {clan}", a list of them, or a map of genders to either | yes | How a name is built: each `{list}` placeholder is filled from the list of that name, `{given.<gender>}` from that gender's given names, and the text around them is written as it stands. A list states every form a name may take; a map keyed by gender states each gender's forms, and a gender with none takes every pattern stated. |
473
- | `data.names.given` | a map of genders to lists of names | yes | Given names by gender word. A gender with no list draws from every given list together. |
474
- | `data.fields[].name` | a string | yes | The field's name, which a word's `field` names. |
475
- | `data.fields[].holds` | a string | yes | What the field holds. |
476
- | `data.words[].form` | the word as cited, bare | yes | The word as cited, with no backticks. |
477
- | `data.words[].name_sort` | a string | no | The sort key; the form when unstated. |
478
- | `data.words[].class` | a word class, base first, such as `n I f` | yes | A class from the master word classes: a base, then the modifiers the language declares in `classModifiers`. |
479
- | `data.words[].field` | one of the language's `fields` names | yes | The field the word is grouped under, named in the language's `fields`. |
480
- | `data.words[].gloss` | a string | yes | The meaning, in brief. |
481
- | `data.words[].source` | a map — `{ kind, language?, form? }` | no | Where the word comes from. |
482
- | `data.words[].source.kind` | one of inherited, borrowed, kept, worn, coined, substrate, island | yes | How the word came into the tongue. |
483
- | `data.words[].source.language` | a language skill Address | no | The tongue the word was borrowed from; required for `borrowed`. |
484
- | `data.words[].source.form` | a string | no | The form the word had in its source, bare. |
485
- | `data.words[].built` | a list of pieces | no | The pieces the word is built from, in order, as the language's words and affixes write them; absent for a root word. |
486
- | `data.words[].attested` | a list of Addresses | no | The notes the word is cited from. |
487
- | `data.words[].pronunciation` | a respelling such as `sol-MEH-reh` | no | A respelling in hyphen-separated syllables, the stressed one in capitals: letters, apostrophes and hyphens only, and at most one capitalised syllable. |
488
- | `data.words[].tones` | a string | no | A tone pattern, such as `LHL`. |
489
- | `data.words[].root` | a string | no | A consonantal skeleton, such as `d-l-k`. |
490
- | `data.words[].frame` | a string | no | The frame a root is set in. |
491
- | `data.affixes[].form` | the affix as written, such as `-rith` | yes | The affix as a word's `built` names it. |
492
- | `data.affixes[].gloss` | a string | yes | What the affix means. |
493
- | `data.affixes[].attaches` | a string | no | How it attaches, such as `replaces a closing vowel`. |
494
- | `data.affixes[].examples` | a list of strings | no | The names the affix is read from. |
495
- | `data.affixes[].tones` | a tone pattern, such as `L` | no | The tone pattern the affix carries, written as a word's `tones` is. |
483
+ | Key | Shape | Required | Meaning |
484
+ | ----------------------------------------- | --------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
485
+ | `data.names.pattern` | a pattern such as "{given} {clan}", a list of them, or a map of genders to either | yes | How a name is built: each `{list}` placeholder is filled from the list of that name, `{given.<gender>}` from that gender's given names, and the text around them is written as it stands. A list states every form a name may take; a map keyed by gender states each gender's forms, and a gender with none takes every pattern stated. |
486
+ | `data.names.given` | a map of genders to lists of names | yes | Given names by gender word. A gender with no list draws from every given list together. |
487
+ | `data.fields[].name` | a string | yes | The field's name, which a word's `field` names. |
488
+ | `data.fields[].holds` | a string | yes | What the field holds. |
489
+ | `data.words[].form` | the word as cited, bare | yes | The word as cited, with no backticks. |
490
+ | `data.words[].variants` | a list of forms | no | The word's other forms, such as a long form beside a short one; a marked use of one cites the word. |
491
+ | `data.words[].name_sort` | a string | no | The sort key; the form when unstated. |
492
+ | `data.words[].class` | a word class, base first, such as `n I f` | yes | A class from the master word classes: a base, then the modifiers the language declares in `classModifiers`. |
493
+ | `data.words[].field` | one of the language's `fields` names | yes | The field the word is grouped under, named in the language's `fields`. |
494
+ | `data.words[].gloss` | a string, or a list of senses | yes | The meaning, in brief; a list states one sense per entry, which a dictionary numbers. |
495
+ | `data.words[].source` | a map — `{ kind, language?, form? }` | no | Where the word comes from. |
496
+ | `data.words[].source.kind` | one of inherited, borrowed, kept, worn, coined, substrate, island | yes | How the word came into the tongue. |
497
+ | `data.words[].source.language` | a language skill Address | no | The tongue the word was borrowed from; required for `borrowed`. |
498
+ | `data.words[].source.form` | a string | no | The form the word had in its source, bare. |
499
+ | `data.words[].built` | a list of pieces | no | The pieces the word is built from, in order, as the language's words and affixes write them; absent for a root word. |
500
+ | `data.words[].note` | a string | no | What a source says of the word beyond its pieces, such as a cognate it is read with. |
501
+ | `data.words[].pronunciation` | a respelling such as `sol-MEH-reh` | no | A respelling in hyphen-separated syllables, the stressed one in capitals: letters, apostrophes and hyphens only, and at most one capitalised syllable. |
502
+ | `data.words[].tones` | a string | no | A tone pattern, such as `LHL`. |
503
+ | `data.words[].root` | a string | no | A consonantal skeleton, such as `d-l-k`. |
504
+ | `data.words[].frame` | a frame of the language's `sounds.frames` | no | The frame a root is set in, named in the language's `sounds.frames`. |
505
+ | `data.affixes[].form` | the affix as written, such as `-rith` | no | The affix as a word's `built` names it; absent on a zero affix. |
506
+ | `data.affixes[].zero` | `true` | no | The affix is written as nothing, such as a case with no ending; it states no `form`, prints as `∅`, and no `built` piece names it. |
507
+ | `data.affixes[].kind` | one of case, derivation, tense, aspect, mood, voice, name, lineage | no | What the affix makes. |
508
+ | `data.affixes[].given` | one of man, woman, either | no | Who a given name closing on it belongs to; an affix of kind `name` only. |
509
+ | `data.affixes[].where` | a string, such as `before a stop` | no | Where this form stands, for an affix written two ways; everywhere where absent. |
510
+ | `data.affixes[].gloss` | a string | yes | What the affix means. |
511
+ | `data.affixes[].attaches` | a string | no | How it attaches, in words, such as `replaces a closing vowel`. |
512
+ | `data.affixes[].replaces` | `vowel`, or the letters, such as `a` | no | What it takes the place of at the close of the stem: `vowel` for any closing vowel, or the letters it replaces; added to the whole stem where absent. |
513
+ | `data.affixes[].lengthens` | `true` or `false` | no | Whether the stem's last vowel lengthens before the affix; `false` where unstated. An affix that `replaces` the stem's close does not also lengthen it. |
514
+ | `data.affixes[].front` | the affix as written, such as `-ür` | no | Its form after front vowels, where the language keeps vowel harmony. |
515
+ | `data.affixes[].examples` | a list of strings | no | The names the affix is read from. |
516
+ | `data.affixes[].barredAfter` | a list of sounds | no | The sounds a stem may not close on to take the affix. |
517
+ | `data.affixes[].tones` | a tone pattern, such as `L` | no | The tone pattern the affix carries, written as a word's `tones` is. |
518
+ | `data.tongues[].tag` | a tag such as `dunhari`, or `exonym:<tongue>` | yes | The tag a register row's `tongue` names: lowercase letters and digits, or a tag closing on `:<tongue>`, which declares one tag per tongue named after the colon. |
519
+ | `data.tongues[].meaning` | a string | yes | What a name of this tongue is. |
520
+ | `data.tongues[].language` | a language skill Address | no | The language note the tag names, where it is one. |
521
+ | `data.register[].name` | a name as the setting writes it | yes | A name the setting gives, as it is written. |
522
+ | `data.register[].tongue` | a tag of `data.tongues`, or `translation` | no | The tongue the name is in, as a tag `data.tongues` declares, or `translation`. A row states a `tongue`, a `kind`, or both. |
523
+ | `data.register[].kind` | one of byname, given, place | no | What kind of name it is, in a language that sorts its names by kind. |
524
+ | `data.register[].built` | a list of pieces | no | The pieces the name is built from, in order, as a word's `built` writes them. |
525
+ | `data.register[].gloss` | a string | no | What the name means, where the pages give its sense. |
526
+ | `data.register[].why` | a string | no | Why the name stands outside the pattern the language's names are built by. |
527
+ | `data.retired[].form` | a string | yes | The form the setting does not write. |
528
+ | `data.retired[].instead` | a string, or a list of them | no | What is written in its place, one form or several; absent where nothing is. |
529
+ | `data.retired[].why` | a string | yes | Why the setting does not write it. |
530
+ | `data.scope.folders` | a list of folder Addresses | no | Every note whose `data.packFolder` is one of these folders. |
531
+ | `data.scope.cultures` | a list of culture Addresses | no | Every note whose `data.culture` is one of these cultures. |
532
+ | `data.scope.lore` | a list of lore Addresses | no | Every note whose `data.lore` names one of these notes. |
533
+ | `data.scope.parents` | a list of Addresses | no | Every note whose `data.parents` names one of these notes. |
534
+ | `data.scope.addresses` | a list of Addresses | no | These notes themselves. |
535
+ | `data.scope.paths` | a list of content paths | no | Every note whose file sits below one of these paths of the content tree. |
536
+ | `data.scope.types` | a list of note types | no | The note types the register covers; where stated, a note of another type is out of scope whatever else catches it. |
537
+ | `data.scope.skip` | a list of Addresses | no | Notes out of scope whatever else catches them. |
538
+ | `data.sounds.letters` | list of `{ letters, kind, like, tongue? }` | no | The letters the language writes, and the sounds they stand for. |
539
+ | `data.sounds.letters[].letters` | a list of letters | yes | The letters or digraphs the row describes, as written. |
540
+ | `data.sounds.letters[].kind` | a string, such as `consonant` or `long vowel` | yes | What kind of sound they write. |
541
+ | `data.sounds.letters[].like` | a string | no | What they sound like; absent where the row states only their kind and place. |
542
+ | `data.sounds.letters[].place` | a string, such as `lips` or `tongue-tip` | no | Where in the mouth they are made. |
543
+ | `data.sounds.letters[].tongue` | a tag, or a list of them | no | The tongues that write them, as tags `data.tongues` declares; every one where absent. |
544
+ | `data.sounds.edges` | list of `{ edge, sounds }` | no | The sounds that may stand at each edge of a word, one entry per edge. |
545
+ | `data.sounds.edges[].edge` | one of openConsonant, openCluster, closeConsonant, closeCluster, innerCluster, vowelPair, glide, syllabic | yes | Which edge of a word the sounds stand at. |
546
+ | `data.sounds.edges[].sounds` | a list of sounds, or `any` | yes | The sounds, as written; `any` for every one, and an empty list for none. |
547
+ | `data.sounds.clusters` | a map — `{ max, groups? }` | no | How many consonants may stand together. |
548
+ | `data.sounds.clusters.max` | a whole number | yes | The most consonants that stand together inside a word. |
549
+ | `data.sounds.clusters.groups` | list of `{ what, clusters, use }` | no | The clusters that may stand inside a word, in groups; a language stating them states no `innerCluster` edge. |
550
+ | `data.sounds.clusters.groups[].what` | a string, such as `a nasal and a fricative` | yes | What the clusters of the group are made of. |
551
+ | `data.sounds.clusters.groups[].clusters` | a list of clusters | yes | The clusters, as written; a digraph counts as one consonant. |
552
+ | `data.sounds.clusters.groups[].use` | one of common, sparing | yes | How often the group's clusters stand inside a word. |
553
+ | `data.sounds.stress` | one of first syllable, penultimate or final, by weight, as marked | no | Where a word's stress falls. |
554
+ | `data.sounds.finals` | list of `{ final, like }` | no | The syllable finals, for a language whose syllables are parsed by them. |
555
+ | `data.sounds.finals[].final` | a final as written, such as `ang` | yes | The final. |
556
+ | `data.sounds.finals[].like` | a string | yes | What it sounds like. |
557
+ | `data.sounds.syllables` | a map of syllable rules | no | What a syllable and a word may open and close on. |
558
+ | `data.sounds.syllables.onsets` | one of single | no | What a syllable opens on: `single`, a single consonant. |
559
+ | `data.sounds.syllables.codas` | a list of sounds, or `any` | no | The consonants that may close a syllable; `any` for every one. |
560
+ | `data.sounds.syllables.finals` | a list of sounds, or `any` | no | The consonants that may close a word; `any` for every one. |
561
+ | `data.sounds.syllables.doubled` | a list of letters | no | The doubled consonants a word may hold; none where empty. |
562
+ | `data.sounds.syllables.vowelPairs` | a list of vowel pairs | no | The vowels that may stand together; none where empty. |
563
+ | `data.sounds.syllables.initialVowel` | `true` or `false` | no | Whether a word may open on a vowel. |
564
+ | `data.sounds.syllables.finalVowel` | `true` or `false` | no | Whether a word may close on a vowel; `true` where unstated. |
565
+ | `data.sounds.syllables.neverInitial` | a list of letters | no | The letters that never open a word. |
566
+ | `data.sounds.syllables.signature` | a list of letters | no | The letters that mark a word as the language's own. |
567
+ | `data.sounds.syllables.harmony` | a map — `{ back, front, neutral?, neutralAs?, partners? }` | no | The vowel harmony a word keeps. |
568
+ | `data.sounds.syllables.harmony.back` | a list of vowels | yes | The back vowels. |
569
+ | `data.sounds.syllables.harmony.front` | a list of vowels | yes | The front vowels. |
570
+ | `data.sounds.syllables.harmony.neutral` | a list of vowels | no | The vowels of neither set. |
571
+ | `data.sounds.syllables.harmony.neutralAs` | one of back, front | no | The set a word of neutral vowels alone counts as. |
572
+ | `data.sounds.syllables.harmony.partners` | a map of vowels to front vowels | no | The front vowel each vowel turns to in an affix's front form, keyed by the vowel; every key is a vowel of the harmony and every value one of its `front` vowels. |
573
+ | `data.sounds.joining` | list of `{ first, second, written, example? }` | no | How two parts are written where the first closes and the second opens on the given sounds. |
574
+ | `data.sounds.joining[].first` | a list of sounds | yes | The sounds the first part closes on. |
575
+ | `data.sounds.joining[].second` | a list of sounds | yes | The sounds the second part opens on. |
576
+ | `data.sounds.joining[].written` | a string, such as `â` or `y+` | yes | What is written where they meet: the sound that stands for both, or a join closing on `+`, which keeps both and sets it between. |
577
+ | `data.sounds.joining[].example` | a string | no | A word joined so. |
578
+ | `data.sounds.joins` | list of `{ meeting, rule, letters?, where? }` | no | What happens where two parts of a word meet, one entry per meeting. |
579
+ | `data.sounds.joins[].meeting` | one of C+C, V+C, V+V | yes | Which sounds meet: a consonant `C` or a vowel `V` closing the first part, then opening the second. |
580
+ | `data.sounds.joins[].rule` | one of merge, insert, drop, double | yes | What happens where they meet. |
581
+ | `data.sounds.joins[].letters` | a list of letters | no | The letters the rule takes: what `insert` sets between, or what `double` doubles. |
582
+ | `data.sounds.joins[].where` | a string, such as `between stems` | no | Where the rule holds; everywhere where absent. |
583
+ | `data.sounds.marks` | list of `{ mark, letters, kind, limit }` | no | The marks the language writes on its letters. |
584
+ | `data.sounds.marks[].mark` | a string, such as `acute` | yes | The mark's name. |
585
+ | `data.sounds.marks[].letters` | a list of letters | yes | The letters that carry it. |
586
+ | `data.sounds.marks[].kind` | one of stress, length | yes | What the mark says of its letter. |
587
+ | `data.sounds.marks[].limit` | one of one, any | yes | How many a word may carry: `one` at most, or `any`. |
588
+ | `data.sounds.skeleton` | list of `{ second, between? }` | no | The vowel set between a root's second and third consonants. |
589
+ | `data.sounds.skeleton[].second` | a list of sounds, or `any` | yes | The second consonants of a root the row holds for; `any` for every other. |
590
+ | `data.sounds.skeleton[].between` | a vowel, such as `a` | no | The vowel set between the second and third consonants; nothing where absent. |
591
+ | `data.sounds.frames` | list of `{ frame, shape, class, makes, examples? }` | no | The patterns a root is set in. |
592
+ | `data.sounds.frames[].frame` | a string, such as `bare` | yes | The frame's name, which a word's `frame` names. |
593
+ | `data.sounds.frames[].shape` | a pattern, such as `K1aK2K3` | yes | The pattern, the root's consonants numbered `K1`, `K2`, `K3`. |
594
+ | `data.sounds.frames[].class` | a list of word class bases | yes | The classes of word the frame makes, each a base of the master word classes. |
595
+ | `data.sounds.frames[].makes` | a string | yes | What the frame makes of a root. |
596
+ | `data.sounds.frames[].examples` | a map of roots to forms | no | The form a root takes in the frame, keyed by the root. |
597
+ | `data.sounds.readPast` | list of `{ written, readAs?, what }` | no | Marks and spellings a word is read through before the sound rules hold it. |
598
+ | `data.sounds.readPast[].written` | a string | yes | A mark or spelling the pages write. |
599
+ | `data.sounds.readPast[].readAs` | a string | no | What a word is read with in its place; absent where it is read as nothing. |
600
+ | `data.sounds.readPast[].what` | a string | yes | What the mark or spelling is. |
601
+ | `data.sounds.mutations` | list of `{ mutation, sound, becomes, example? }` | no | The sounds a word changes where a named mutation holds, one entry per sound, such as a stop worn to a fricative or a consonant voiced inside a compound. |
602
+ | `data.sounds.mutations[].mutation` | a string, such as `wearing` | yes | The mutation's name; its rows share it, and `data.negation` names it. |
603
+ | `data.sounds.mutations[].sound` | a sound as written, such as `p` | yes | The sound as it stands where the mutation does not hold; once per mutation. |
604
+ | `data.sounds.mutations[].becomes` | a sound as written, such as `v` | yes | What the sound becomes where the mutation holds. |
605
+ | `data.sounds.mutations[].example` | a string | no | A word that shows it. |
606
+ | `data.soundChanges[].name` | a string, such as `From Helonic to Byzarian` | yes | The set's name, which no other set of the note shares. |
607
+ | `data.soundChanges[].from` | a language skill Address | no | The language whose words the steps start from. |
608
+ | `data.soundChanges[].to` | a language skill Address | no | The language whose words the steps make. |
609
+ | `data.soundChanges[].takes` | a case, such as `accusative` | no | The form of the older word the steps start from; its citation form where absent. |
610
+ | `data.soundChanges[].steps` | list of `{ step, change, where? }` | yes | The steps, in the order they apply; no step label stands twice in a set. |
611
+ | `data.soundChanges[].steps[].step` | a string, such as `A1` or `"1"` | yes | The step's label, in the order the changes apply. |
612
+ | `data.soundChanges[].steps[].change` | a change in arrow notation, such as `` `ph` > `f`; `kh` > `h` `` | yes | The change, in arrow notation: one or more `` `sources` > `targets` `` rules separated by `;`, or the operation a step names in words. |
613
+ | `data.soundChanges[].steps[].where` | a string, such as `word end` | no | Where the change holds; everywhere where absent. |
614
+ | `data.elements[].form` | the element as written, such as `arn-` | yes | The element a name is built from. |
615
+ | `data.elements[].variants` | a list of forms | no | The element's other forms, such as `aldr-` beside `ald-`. |
616
+ | `data.elements[].position` | one of opening, closing, either, link | no | Where in a name the element stands. |
617
+ | `data.elements[].kind` | one of byname, given, place | no | The kind of name the element builds, in a language that keeps one set of elements per kind; every kind where absent. |
618
+ | `data.elements[].sense` | a string | yes | What the element means. |
619
+ | `data.elements[].examples` | a list of names | no | The names the element is read from. |
620
+ | `data.elements[].word` | a form of the language's words | no | The word the element is the stem of, a form of `data.words` of the language or an ancestor. |
621
+ | `data.elements[].genitive` | the element as written, such as `-borgar` | no | The element in the genitive, where a name governing another word takes it. |
622
+ | `data.roots[].root` | a consonantal skeleton, such as `d-l-k` | yes | The root. |
623
+ | `data.roots[].sense` | a string | yes | What the root means. |
624
+ | `data.roots[].field` | a string, such as `stone` | no | The field the root belongs to. |
625
+ | `data.cognates[].forms` | a map of language Addresses to forms | yes | The form the set takes in each language, keyed by the language note's Address. |
626
+ | `data.cognates[].proto` | a form, bare | no | The reconstructed form the set descends from, in no attested language; printed with an asterisk. |
627
+ | `data.cognates[].gloss` | a string | yes | What the forms mean. |
628
+ | `data.callingNames.closings` | list of `{ form?, doubled?, usual }` | yes | What a calling name closes on. |
629
+ | `data.callingNames.closings[].form` | an ending, such as `-u` | no | The ending; a row states `form` or `doubled`, never both. |
630
+ | `data.callingNames.closings[].doubled` | `true` | no | The calling name doubles the first syllable rather than taking an ending. |
631
+ | `data.callingNames.closings[].usual` | one of man, woman, either | yes | Whose name it usually makes. |
632
+ | `data.callingNames.minSyllables` | a whole number | yes | The fewest syllables a given name has that the pages give a calling name. |
633
+ | `data.older[].form` | a form as the setting writes it | yes | A word or name whose shape the language's rules do not make. |
634
+ | `data.older[].gloss` | a string | no | What it means. |
635
+ | `data.older[].layer` | a string, such as `Primordial` | no | The historical layer it belongs to. |
636
+ | `data.negation.particle` | a form of the language's words | yes | The particle that stands before a verb to negate it, a form of `data.words` of the language or an ancestor. |
637
+ | `data.negation.mutation` | a mutation of `data.sounds.mutations` | no | The mutation the negated verb takes, named in `data.sounds.mutations`. |
638
+ | `data.naming.shapes` | list of `{ of, syllables?, perVowel? }` | no | How long each class of name runs. |
639
+ | `data.naming.shapes[].of` | one of name, given, clan, bound, compound | yes | The class of name the shape holds for; once per class. |
640
+ | `data.naming.shapes[].syllables` | a map — `{ min, max }` | no | How many syllables a name of the class runs to. |
641
+ | `data.naming.shapes[].syllables.min` | a whole number | yes | The fewest syllables a name of the class runs to. |
642
+ | `data.naming.shapes[].syllables.max` | a whole number | yes | The most syllables a name of the class runs to; never below `min`. |
643
+ | `data.naming.shapes[].perVowel` | a map — `{ min, max }` | no | How many consonants a name of the class carries to each vowel; a shape states this, `syllables`, or both. |
644
+ | `data.naming.shapes[].perVowel.min` | a number | yes | The fewest consonants a name of the class carries to each vowel. |
645
+ | `data.naming.shapes[].perVowel.max` | a number | yes | The most consonants a name of the class carries to each vowel; never below `min`. |
646
+ | `data.naming.edges` | list of `{ edge, sounds, vowel?, of? }` | no | The sounds a name may open and close on, where names keep edges ordinary words do not; an edge stands once for each class of name. |
647
+ | `data.naming.edges[].edge` | one of openConsonant, openCluster, closeConsonant, closeCluster, innerCluster, vowelPair, glide, syllabic | yes | Which edge of a name the sounds stand at. |
648
+ | `data.naming.edges[].sounds` | a list of sounds, or `any` | yes | The sounds, as written; `any` for every one, and an empty list for none. |
649
+ | `data.naming.edges[].vowel` | `true` or `false` | no | Whether a vowel may stand at the edge too; `false` where unstated. |
650
+ | `data.naming.edges[].of` | one of name, given, clan, bound, compound | no | The class of name the edge holds for; `name`, every name, where absent. |
651
+ | `data.naming.draws` | list of `{ kind, elements }` | no | The element kinds each kind of name is built from. |
652
+ | `data.naming.draws[].kind` | one of byname, given, place | yes | The kind of name; once per kind. |
653
+ | `data.naming.draws[].elements` | a list of element kinds | yes | The kinds of element, as `data.elements` states them, the name is built from. |
654
+ | `data.naming.heldFrom` | list of `{ source, takes, clip?, genitive?, elements? }` | no | What a place name takes first, by what the place is held from. |
655
+ | `data.naming.heldFrom[].source` | a string, such as `a founder` | yes | What the place is held from. |
656
+ | `data.naming.heldFrom[].takes` | one of stem, godName, givenName, element | yes | What stands first: a name-stem in any grade, a god's name, a founder's given name, or one of `elements`. |
657
+ | `data.naming.heldFrom[].clip` | one of first | no | How the name is clipped: `first`, to its first element; whole where absent. |
658
+ | `data.naming.heldFrom[].genitive` | a list of endings | no | The genitive endings, one of which stands at the seam after the name. |
659
+ | `data.naming.heldFrom[].elements` | a list of elements | no | The elements that may stand first, for a row that takes an `element`. |
660
+ | `data.naming.nearName` | a map — `{ minSyllables, examples? }` | no | The near name a long given name carries. |
661
+ | `data.naming.nearName.minSyllables` | a whole number | yes | The fewest syllables a given name has that carries a near name. |
662
+ | `data.naming.nearName.examples` | list of `{ near, given }` | no | Worked near names, each beside its given name. |
663
+ | `data.naming.nearName.examples[].near` | a near name, such as `Anlâ` | yes | The near name. |
664
+ | `data.naming.nearName.examples[].given` | a given name | yes | The given name it is the near name of. |
496
665
 
497
666
  **System mappings**
498
667
 
@@ -211,6 +211,19 @@ types:
211
211
  - fields
212
212
  - words
213
213
  - affixes
214
+ - tongues
215
+ - register
216
+ - retired
217
+ - scope
218
+ - sounds
219
+ - soundChanges
220
+ - elements
221
+ - roots
222
+ - cognates
223
+ - callingNames
224
+ - older
225
+ - negation
226
+ - naming
214
227
  subTypes:
215
228
  - social
216
229
  - nature
@@ -113,6 +113,7 @@ import { addressSlug, canonicalKey } from "./content-address.mjs";
113
113
  import { isAddressTuple, ownDocumentSystem, readCanonicalKey, renderAddress } from "./address.mjs";
114
114
  import { NOTE_SYSTEM } from "./systems.mjs";
115
115
  import { dictionaryAndTermRows, serializeRows } from "./dictionary-rows.mjs";
116
+ import { attachCitations } from "./word-citations.mjs";
116
117
  import { assetAddressIndex } from "./art-fields.mjs";
117
118
  import { embedRole } from "./content-embeds.mjs";
118
119
  // One reader for a note's anchors, shared with the link checker and with the
@@ -1112,6 +1113,8 @@ export function collectContentIndex(
1112
1113
  contentPackage,
1113
1114
  );
1114
1115
 
1116
+ // Each recorded note with its body, for the words its prose cites.
1117
+ const bodies = [];
1115
1118
  for (const { frontmatter, body, bodyLine, absPath } of parsedNotes) {
1116
1119
  // Before the index derives anything onto the frontmatter, so a later
1117
1120
  // pass reads the note as authored.
@@ -1120,20 +1123,20 @@ export function collectContentIndex(
1120
1123
  applyComputedBeingAge(fm, present, dates);
1121
1124
  const relPath = path.relative(contentBase, absPath);
1122
1125
  try {
1123
- records.push(
1124
- ...indexRecordsForNote({
1125
- frontmatter: fm,
1126
- relPath,
1127
- absPath,
1128
- contentPackage,
1129
- body,
1130
- bodyLine,
1131
- manifest,
1132
- addressContext: decodeContext,
1133
- dateContext: dates,
1134
- resolveRole,
1135
- }),
1136
- );
1126
+ const made = indexRecordsForNote({
1127
+ frontmatter: fm,
1128
+ relPath,
1129
+ absPath,
1130
+ contentPackage,
1131
+ body,
1132
+ bodyLine,
1133
+ manifest,
1134
+ addressContext: decodeContext,
1135
+ dateContext: dates,
1136
+ resolveRole,
1137
+ });
1138
+ records.push(...made);
1139
+ bodies.push({ record: made[0], body });
1137
1140
  } catch (err) {
1138
1141
  if (fm.shortcode && !isAddressSegment(fm.shortcode) && err.keyPath) {
1139
1142
  err.identity = { type: fm.type, shortcode: fm.shortcode };
@@ -1176,6 +1179,10 @@ export function collectContentIndex(
1176
1179
  }
1177
1180
  }
1178
1181
 
1182
+ // The words each note's prose cites, read once every language's words
1183
+ // are recorded; the index keeps the citing Addresses and no text.
1184
+ attachCitations(records, bodies);
1185
+
1179
1186
  // Every note record exists and every Address in it is a tuple, so a parent
1180
1187
  // is found by its canonical address. Before the sort, which reads nothing
1181
1188
  // the pass writes.
@@ -22,7 +22,8 @@
22
22
  * surface sets it as it sets a note:
23
23
  *
24
24
  * - **the key**, once, at the head unless the fence sets `key=false`: the abbreviations this rendering uses,
25
- * each with its expansion, then the common mark where an entry carries it;
25
+ * each with its expansion, then the common mark where an entry carries it.
26
+ * A fence setting `key=only` prints the key alone;
26
27
  * - **a heading per letter**, from `letter`, at the fence's `section-level`;
27
28
  * - **one paragraph per entry**: the common mark, the bold headword, the
28
29
  * pronunciation between slashes, the language tag (and for a word its
@@ -92,7 +93,8 @@ function sentence(text) {
92
93
  * @property {object} [addressContext] - Address resolution context.
93
94
  * @property {(address: string) => string|undefined} [labelOf] - A note's
94
95
  * `name.full`, by its Address.
95
- * @property {boolean} [showKey=true] - Whether the key is printed.
96
+ * @property {boolean|"only"} [showKey=true] - Whether the key is printed;
97
+ * `"only"` prints the key and nothing else.
96
98
  * @property {string} [pageLanguage] - The language of the page the fence is
97
99
  * on, which no entry is tagged with.
98
100
  */
@@ -286,7 +288,9 @@ function render(
286
288
  if (usedModifiers.has(modifier.token))
287
289
  key.push(`_${modifier.abbreviation}_ ${modifier.expansion}`);
288
290
  if (anyCommon) key.push(`${COMMON_MARK} ${COMMON_KEY}`);
289
- if (showKey && key.length) paragraphs.unshift(`**Key:** ${key.join("; ")}.`);
291
+ const line = key.length ? `**Key:** ${key.join("; ")}.` : "";
292
+ if (showKey === "only") return line;
293
+ if (showKey && line) paragraphs.unshift(line);
290
294
  return paragraphs.join("\n\n");
291
295
  }
292
296