@heroiclands/package-build 23.7.0 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @heroiclands/package-build
2
2
 
3
+ ## 23.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ **Language notes**
8
+
9
+ - A language note can state its sound mutations, group its clusters as common or sparing, give each vowel's front partner, and say where each letter is made.
10
+ - An affix can say what it makes, who a name closing on it is given to, which stem endings bar it and where a second spelling stands, and a zero affix states no form and prints as ∅.
11
+ - A name element can say which kind of name it builds, the word it comes from and its genitive, and a register name can carry its meaning.
12
+ - A language can state how long each class of name runs and the openings and closings only its names keep.
13
+ - It can say which elements each kind of name draws on, what a place name takes from what it is held from, and its near names.
14
+ - A language can also list the forms older than its rules, name its negative particle and say which form its sound changes start from, each set back as a table from an `sql` fence.
15
+
3
16
  ## 23.7.0
4
17
 
5
18
  ### Minor Changes
@@ -309,41 +309,50 @@ A column's heading is its SQL alias, so `AS "Name"` is what a reader sees. A cel
309
309
 
310
310
  ### What a query can read
311
311
 
312
- | Relation | What it holds |
313
- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
314
- | `notes` | Every note except a stub. This is the one to use unless a stub is wanted. |
315
- | `entries` | Every note, stubs included. |
316
- | `events` | One row per event a `lore`, `place` or `affiliation` note writes in `data.events`, with `whenSort` to order them by date. |
317
- | `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. |
318
- | `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`, `gloss`, `attaches`, `replaces`, `lengthens`, `front`, `examples` and `tones`. |
319
- | `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`. |
320
- | `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. |
321
- | `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. |
322
- | `dictionary` | One row per word per language it is listed under, inherited words included, with its `depth`. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
323
- | `terms` | One row per glossary entry, rank or office per note that owns it, with the `cultures` it reaches. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
324
- | `register` | One row per name a language note writes in `data.register`, with its `tongue`, `kind` and `why`, its pieces as `built_text`, and the `notes` carrying the name, derived from the index. |
325
- | `tongues` | One row per tag a language note writes in `data.tongues`: `tag`, `meaning` and `tongue_language`. |
326
- | `retired` | One row per form a language note writes in `data.retired`: `form`, `instead` as a list, and `why`. |
327
- | `scope` | One row per value of a language note's `data.scope`: the `kind` it is under and the `value`. |
328
- | `letters` | One row per entry of a language note's `data.sounds.letters`: `letters` as a list, `kind`, `like` and `tongue`. |
329
- | `edges` | One row per entry of a language note's `data.sounds.edges`: the `edge` and its `sounds` as a list. |
330
- | `clusters` | One row per language note stating `data.sounds.clusters`, with its `max`. |
331
- | `stress` | One row per language note stating `data.sounds.stress`, with its `stress`. |
332
- | `finals` | One row per entry of a language note's `data.sounds.finals`: `final` and `like`. |
333
- | `syllables` | One row per language note stating `data.sounds.syllables`: each rule a column, the harmony as `harmony_back`, `harmony_front`, `harmony_neutral` and `harmony_neutralAs`. |
334
- | `joining` | One row per entry of a language note's `data.sounds.joining`: `first`, `second`, `written` and `example`. |
335
- | `joins` | One row per entry of a language note's `data.sounds.joins`: `meeting`, `rule`, `letters` and `"where"`. |
336
- | `marks` | One row per entry of a language note's `data.sounds.marks`: `mark`, `letters`, `kind` and `"limit"`. |
337
- | `skeleton` | One row per entry of a language note's `data.sounds.skeleton`: `second` and `between`. |
338
- | `frames` | One row per frame of a language note's `data.sounds.frames`: `frame`, `shape`, `class`, `makes` and `examples` as `{ root, form }`. |
339
- | `read_past` | One row per entry of a language note's `data.sounds.readPast`: `written`, `readAs` and `what`. |
340
- | `sound_changes` | One row per step of each set in a language note's `data.soundChanges`: the set's `position`, `name`, `from_language` and `to_language`, then `step_position`, `step`, `change` and `"where"`. |
341
- | `elements` | One row per element of a language note's `data.elements`: `form`, `variants`, `element_position`, `sense` and `examples`. |
342
- | `roots` | One row per root of a language note's `data.roots`: `root`, `sense` and `field`. |
343
- | `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`. |
344
- | `calling_names` | One row per closing of a language note's `data.callingNames`: `form`, `doubled`, `usual` and the language's `min_syllables`. |
345
- | `market` | The market scale as three columns — `value`, `name`, `trade` — so a table can print `village` beside the number a note wrote. |
346
- | `<package>.notes` | The same relations — `notes`, `entries`, `events`, `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`, `sound_changes`, `elements`, `roots`, `cognates` and `calling_names` — for each package this one declares a dependency on, in a schema named for it. |
312
+ | Relation | What it holds |
313
+ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
314
+ | `notes` | Every note except a stub. This is the one to use unless a stub is wanted. |
315
+ | `entries` | Every note, stubs included. |
316
+ | `events` | One row per event a `lore`, `place` or `affiliation` note writes in `data.events`, with `whenSort` to order them by date. |
317
+ | `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. |
318
+ | `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. |
319
+ | `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`. |
320
+ | `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. |
321
+ | `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. |
322
+ | `dictionary` | One row per word per language it is listed under, inherited words included, with its `depth`. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
323
+ | `terms` | One row per glossary entry, rank or office per note that owns it, with the `cultures` it reaches. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
324
+ | `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. |
325
+ | `tongues` | One row per tag a language note writes in `data.tongues`: `tag`, `meaning` and `tongue_language`. |
326
+ | `retired` | One row per form a language note writes in `data.retired`: `form`, `instead` as a list, and `why`. |
327
+ | `scope` | One row per value of a language note's `data.scope`: the `kind` it is under and the `value`. |
328
+ | `letters` | One row per entry of a language note's `data.sounds.letters`: `letters` as a list, `kind`, `like`, `place` and `tongue`. |
329
+ | `edges` | One row per entry of a language note's `data.sounds.edges`: the `edge` and its `sounds` as a list. |
330
+ | `clusters` | One row per language note stating `data.sounds.clusters`, with its `max`. |
331
+ | `cluster_groups` | One row per group of a language note's `data.sounds.clusters.groups`: `what`, `clusters` as a list, and `use`. |
332
+ | `stress` | One row per language note stating `data.sounds.stress`, with its `stress`. |
333
+ | `finals` | One row per entry of a language note's `data.sounds.finals`: `final` and `like`. |
334
+ | `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 }`. |
335
+ | `joining` | One row per entry of a language note's `data.sounds.joining`: `first`, `second`, `written` and `example`. |
336
+ | `joins` | One row per entry of a language note's `data.sounds.joins`: `meeting`, `rule`, `letters` and `"where"`. |
337
+ | `marks` | One row per entry of a language note's `data.sounds.marks`: `mark`, `letters`, `kind` and `"limit"`. |
338
+ | `skeleton` | One row per entry of a language note's `data.sounds.skeleton`: `second` and `between`. |
339
+ | `frames` | One row per frame of a language note's `data.sounds.frames`: `frame`, `shape`, `class`, `makes` and `examples` as `{ root, form }`. |
340
+ | `read_past` | One row per entry of a language note's `data.sounds.readPast`: `written`, `readAs` and `what`. |
341
+ | `mutations` | One row per entry of a language note's `data.sounds.mutations`: `mutation`, `sound`, `becomes` and `example`. |
342
+ | `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"`. |
343
+ | `elements` | One row per element of a language note's `data.elements`: `form`, `variants`, `element_position`, `kind`, `sense`, `examples`, `word` and `genitive`. |
344
+ | `roots` | One row per root of a language note's `data.roots`: `root`, `sense` and `field`. |
345
+ | `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`. |
346
+ | `calling_names` | One row per closing of a language note's `data.callingNames`: `form`, `doubled`, `usual` and the language's `min_syllables`. |
347
+ | `older` | One row per form of a language note's `data.older`: `form`, `gloss` and `layer`. |
348
+ | `negation` | One row per language note stating `data.negation`: its `particle` and `mutation`. |
349
+ | `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`. |
350
+ | `name_edges` | One row per entry of a language note's `data.naming.edges`: `edge`, `sounds` as a list, `vowel` and `of`. |
351
+ | `name_draws` | One row per entry of a language note's `data.naming.draws`: `kind` and `elements` as a list. |
352
+ | `held_from` | One row per entry of a language note's `data.naming.heldFrom`: `source`, `takes`, `clip`, and `genitive` and `elements` as lists. |
353
+ | `near_names` | One row per worked example of a language note's `data.naming.nearName`: `near`, `given` and the language's `min_syllables`. |
354
+ | `market` | The market scale as three columns — `value`, `name`, `trade` — so a table can print `village` beside the number a note wrote. |
355
+ | `<package>.notes` | The same relations — `notes`, `entries`, `events`, `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. |
347
356
 
348
357
  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`. Notes tagged `gm` are absent from the relations on public surfaces.
349
358
 
@@ -460,9 +469,41 @@ ORDER BY position
460
469
 
461
470
  `ORDER BY position` keeps the order the note states them in. The same shape serves `fields`, with `name` and `holds`.
462
471
 
472
+ An affix's `kind` picks one table out of the list. A table of case suffixes in a language with vowel harmony sets the back form beside its `front` form:
473
+
474
+ ````markdown
475
+ ```sql
476
+ SELECT gloss AS "Case", '_' || form || '_' AS "Back", '_' || coalesce(front, form) || '_' AS "Front",
477
+ array_to_string(list_transform(examples, x -> '_' || x || '_'), ', ') AS "Example"
478
+ FROM affixes
479
+ WHERE language = 'thalorna-note-skill-sinalelng' AND kind = 'case'
480
+ ORDER BY position
481
+ ```
482
+ ````
483
+
484
+ A given name's endings say who each is `given` to, and an affix written two ways keeps each form on its own row, the conditioned one saying `"where"` it stands; `string_agg` sets the two back on one line:
485
+
486
+ ````markdown
487
+ ```sql
488
+ SELECT given AS "Given to", string_agg('`' || form || '`', ', ' ORDER BY position) AS "Ending"
489
+ FROM affixes
490
+ WHERE language = 'thalorna-note-skill-nordmalng' AND kind = 'name'
491
+ GROUP BY given ORDER BY min(position)
492
+ ```
493
+
494
+ ```sql
495
+ SELECT gloss AS "Prefix",
496
+ coalesce(max('`' || form || '`') FILTER (WHERE "where" = 'before a stop'), max('`' || form || '`')) AS "Before a stop",
497
+ max('`' || form || '`') FILTER (WHERE "where" IS NULL) AS "Otherwise", kind AS "Kind"
498
+ FROM affixes
499
+ WHERE language = 'thalorna-note-skill-khazarlng' AND kind IN ('aspect', 'voice')
500
+ GROUP BY gloss, kind ORDER BY min(position)
501
+ ```
502
+ ````
503
+
463
504
  ### A language's register, sounds and history
464
505
 
465
- A language note states its register, tongues, the forms it does not write, scope, letters, sound rules, sound changes, name elements, roots and cognates in frontmatter, and each is a relation, so the page sets every table back with a fence. Each row carries the note as its `language`, and a list's entries their `position`, so `WHERE language = '…' ORDER BY position` keeps the order the note states. A list column, such as `sounds` or `instead`, prints its entries joined by commas; `array_to_string` and `list_transform` set them otherwise.
506
+ A language note states its register, tongues, the forms it does not write, scope, letters, sound rules, mutations, sound changes, name elements, roots, cognates, the forms older than its rules and its negation in frontmatter, and each is a relation, so the page sets every table back with a fence. Each row carries the note as its `language`, and a list's entries their `position`, so `WHERE language = '…' ORDER BY position` keeps the order the note states. A list column, such as `sounds` or `instead`, prints its entries joined by commas; `array_to_string` and `list_transform` set them otherwise.
466
507
 
467
508
  The tags the register uses:
468
509
 
@@ -529,6 +570,57 @@ FROM clusters WHERE language = 'thalorna-note-skill-dunharlng'
529
570
  ```
530
571
  ````
531
572
 
573
+ A letter that states its `place` sets a grid of consonants back by manner and place, one `kind` to a row:
574
+
575
+ ````markdown
576
+ ```sql
577
+ SELECT '**' || kind || '**' AS " ",
578
+ coalesce(string_agg(array_to_string(list_transform(letters, x -> '_' || x || '_'), ', '), ', ') FILTER (WHERE place = 'lips'), '') AS "lips",
579
+ coalesce(string_agg(array_to_string(list_transform(letters, x -> '_' || x || '_'), ', '), ', ') FILTER (WHERE place = 'tongue-tip'), '') AS "tongue-tip",
580
+ coalesce(string_agg(array_to_string(list_transform(letters, x -> '_' || x || '_'), ', '), ', ') FILTER (WHERE place = 'back'), '') AS "back"
581
+ FROM letters WHERE language = 'thalorna-note-skill-sinalelng' AND place IS NOT NULL
582
+ GROUP BY kind ORDER BY min(position)
583
+ ```
584
+ ````
585
+
586
+ The groups of clusters that stand inside a word, and the diphthongs by harmony set. A diphthong is a `vowelPairs` entry, and the set it belongs to is the harmony list holding it:
587
+
588
+ ````markdown
589
+ ```sql
590
+ SELECT what AS "Kind", array_to_string(list_transform(clusters, x -> '_' || x || '_'), ', ') AS "Clusters", use AS "Use"
591
+ FROM cluster_groups WHERE language = 'thalorna-note-skill-sinalelng' ORDER BY position
592
+ ```
593
+
594
+ ```sql
595
+ SELECT 'back' AS "Set", array_to_string(list_transform(list_filter(vowelPairs, p -> list_contains(harmony_back, p)), x -> '_' || x || '_'), ', ') AS "Diphthongs"
596
+ FROM syllables WHERE language = 'thalorna-note-skill-sinalelng'
597
+ UNION ALL
598
+ SELECT 'neutral', array_to_string(list_transform(list_filter(vowelPairs, p -> list_contains(harmony_neutral, p)), x -> '_' || x || '_'), ', ')
599
+ FROM syllables WHERE language = 'thalorna-note-skill-sinalelng'
600
+ UNION ALL
601
+ SELECT 'front', array_to_string(list_transform(list_filter(vowelPairs, p -> list_contains(harmony_front, p)), x -> '_' || x || '_'), ', ')
602
+ FROM syllables WHERE language = 'thalorna-note-skill-sinalelng'
603
+ ```
604
+ ````
605
+
606
+ The vowel partners an affix's front form takes. `harmony_partners` is a list of `{ vowel, partner }`, so `unnest` sets it out one row to a vowel:
607
+
608
+ ````markdown
609
+ ```sql
610
+ SELECT '_' || p.vowel || '_' AS "Vowel", '_' || p.partner || '_' AS "In a suffix's front form"
611
+ FROM (SELECT unnest(harmony_partners) AS p FROM syllables WHERE language = 'thalorna-note-skill-sinalelng')
612
+ ```
613
+ ````
614
+
615
+ A mutation, one table per name. `mutation` picks the rows:
616
+
617
+ ````markdown
618
+ ```sql
619
+ SELECT '_' || sound || '_' AS "Radical", '_' || becomes || '_' AS "Worn", coalesce(example, '—') AS "Example"
620
+ FROM mutations WHERE language = 'thalorna-note-skill-sinalelng' AND mutation = 'wearing' ORDER BY position
621
+ ```
622
+ ````
623
+
532
624
  The marks and spellings a word is read through:
533
625
 
534
626
  ````markdown
@@ -641,6 +733,93 @@ GROUP BY position, gloss ORDER BY position
641
733
  ```
642
734
  ````
643
735
 
736
+ An element's `kind` keeps one set of elements apart from another, and a place's generic gives its `genitive`:
737
+
738
+ ````markdown
739
+ ```sql
740
+ SELECT '`' || form || '`' AS "Generic", sense AS "What it names", coalesce('`' || genitive || '`', '—') AS "In the genitive"
741
+ FROM elements WHERE language = 'thalorna-note-skill-nordmalng' AND kind = 'place' ORDER BY position
742
+ ```
743
+ ````
744
+
745
+ A daughter's inheriting set says what it `takes`, so a parent's table of its daughters is read from `language_lineage`, which follows each daughter's `data.family`, and from that set. An empty label after the `|` prints the daughter's own name:
746
+
747
+ ````markdown
748
+ ```sql
749
+ SELECT '[[' || l.language || '|]]' AS "Daughter", l.depth AS "Generations",
750
+ coalesce(max(s.takes), 'nominative') AS "Takes"
751
+ FROM language_lineage l LEFT JOIN sound_changes s ON s.language = l.language AND s.takes IS NOT NULL
752
+ WHERE l.ancestor = 'thalorna-note-skill-vylarilng' AND l.depth > 0
753
+ GROUP BY l.language, l.depth ORDER BY l.depth, l.language
754
+ ```
755
+ ````
756
+
757
+ A zero affix has no `form`; `written` is the form as a table prints it, `∅` for a zero affix. Sinalë's case table, nominative first:
758
+
759
+ ````markdown
760
+ ```sql
761
+ SELECT gloss AS "Case", '_' || written || '_' AS "Back", '_' || coalesce(front, written) || '_' AS "Front"
762
+ FROM affixes WHERE language = 'thalorna-note-skill-sinalelng' AND kind = 'case' ORDER BY position
763
+ ```
764
+ ````
765
+
766
+ A language's names keep shapes and edges its words do not. A name's openings split by length, and `vowel` adds the row for a name that opens on a vowel; the shapes set a band table back, one row per class of name:
767
+
768
+ ````markdown
769
+ ```sql
770
+ SELECT consonants AS "consonants", openings AS "the openings" FROM (
771
+ SELECT CASE WHEN edge = 'openConsonant' THEN 'one sound' WHEN max(length(s)) = 2 THEN 'two' ELSE 'three' END AS consonants,
772
+ string_agg('`' || s || '`', ' ') AS openings, min(position) * 10 + max(length(s)) AS ord
773
+ FROM (SELECT edge, position, unnest(sounds) AS s FROM name_edges
774
+ WHERE language = 'thalorna-note-skill-nordmalng' AND edge IN ('openConsonant', 'openCluster') AND of = 'name')
775
+ GROUP BY edge, CASE WHEN edge = 'openCluster' THEN length(s) END
776
+ UNION ALL
777
+ SELECT 'none', 'a vowel stands first', 1000 FROM name_edges
778
+ WHERE language = 'thalorna-note-skill-nordmalng' AND edge = 'openConsonant' AND of = 'name' AND vowel
779
+ ) ORDER BY ord
780
+ ```
781
+
782
+ ```sql
783
+ SELECT of AS "class of name", '`' || printf('%.1f', per_vowel_min) || '` to `' || printf('%.1f', per_vowel_max) || '`' AS "consonants per vowel",
784
+ coalesce('`' || syllables_min || '` to `' || syllables_max || '`', '—') AS "syllables"
785
+ FROM name_shapes WHERE language = 'thalorna-note-skill-nordmalng' ORDER BY position
786
+ ```
787
+ ````
788
+
789
+ The sources a place name is held from, and the near names:
790
+
791
+ ````markdown
792
+ ```sql
793
+ SELECT source AS "held from",
794
+ CASE takes WHEN 'stem' THEN 'a name-stem, in any of its three grades'
795
+ WHEN 'element' THEN array_to_string(list_transform(elements, x -> '`' || x || '`'), ', ')
796
+ ELSE (CASE takes WHEN 'godName' THEN 'that god''s name' ELSE 'that founder''s given name' END)
797
+ || coalesce(', clipped to its ' || clip || ' element', '')
798
+ || coalesce(', with a genitive ' || array_to_string(list_transform(genitive, x -> '`' || x || '`'), ' or '), '')
799
+ END AS "what stands first"
800
+ FROM held_from WHERE language = 'thalorna-note-skill-nordmalng' ORDER BY position
801
+ ```
802
+
803
+ ```sql
804
+ SELECT '`' || near || '`' AS "Near name", '`' || given || '`' AS "Given name"
805
+ FROM near_names WHERE language = 'thalorna-note-skill-khelathlng' ORDER BY position
806
+ ```
807
+ ````
808
+
809
+ The forms older than the rules, and the negative particle:
810
+
811
+ ````markdown
812
+ ```sql
813
+ SELECT '_' || form || '_' AS "Form", coalesce(gloss, '—') AS "Gloss", coalesce(layer, '—') AS "Layer"
814
+ FROM older WHERE language = 'thalorna-note-skill-sinalelng' ORDER BY position
815
+ ```
816
+
817
+ ```sql
818
+ SELECT '_' || particle || '_' AS "Particle", coalesce(mutation, '—') AS "The verb takes"
819
+ FROM negation WHERE language = 'thalorna-note-skill-sinalelng'
820
+ ```
821
+ ````
822
+
644
823
  See [a language's register, sounds and history](../reference/format-details.md#a-languages-register-sounds-and-history) for every key and what the lint holds it to.
645
824
 
646
825
  ### Fence attributes
@@ -143,6 +143,6 @@ Places, affiliations, lore and beings may name their culture in `data.culture`,
143
143
 
144
144
  An affiliation may name the trade, temple or order tongue it keeps in its own `data.language`. An affiliation that reaches no culture is a warning, in a tree holding a culture note. A language needs no culture and no affiliation. See [type: affiliation](reference/format-details.md#type-affiliation).
145
145
 
146
- A language note (`type: skill`, `subType: language`) states its words in frontmatter: `data.words` states each word as a map of its form, class, field and gloss — one sense or a list of them, which a dictionary numbers — with its source, its variant forms, the pieces it is built from and a note, beside `data.classModifiers`, `data.fields` and `data.affixes`. The notes a word is cited from are derived, not written: a note cites a word by marking it in italics in its prose, matched by form or a variant with diacritics and case set aside. The language of a word is the note it sits on, and none of it reaches the compiled Item. A daughter language names its parent in `data.family` and reads the parent's words as its own; the `language_lineage` relation joins a language to its ancestors. Classes come from the [master word classes](reference/format-details.md#word-classes). A culture or an affiliation states its own glossary terms in `data.glossary`, and every entry resolves to a language — its own `language`, else the affiliation's, its parents' or its culture's, else the culture's — or is an error at the entry. The `words`, `affixes`, `fields`, `glossary` and `language_lineage` relations hold them for `sql` fences, the `dictionary` relation lists each word under every language that has it, inherited words included, and the `terms` relation each glossary entry, rank and office with the cultures it reaches; a fence sets them with `layout=dictionary` or `layout=glossary`. A language note names the tag a dictionary prints for it in `data.abbreviation`. Every fact a check reads about a language's names, sounds and history is frontmatter too: `data.tongues` and `data.register` (every name the setting gives in the language's reach, the notes carrying each derived from the index), `data.retired`, `data.scope`, `data.sounds` (letters, word edges from a closed list, the cluster limit, the stress rule, syllable finals, syllable rules and vowel harmony, the joining of parts, written marks, a root's skeleton vowel and frames, and the spellings read past), `data.soundChanges` (named sets of ordered steps), `data.elements` (each standing `opening`, `closing`, `either` or `link`), `data.roots`, `data.cognates` (with a reconstructed `proto` form) and `data.callingNames`, each a relation — `sounds` as `letters`, `edges`, `clusters`, `stress`, `finals`, `syllables`, `joining`, `joins`, `marks`, `skeleton`, `frames` and `read_past`, `soundChanges` as `sound_changes`, `callingNames` as `calling_names` — that a fence sets back on the page. A word's citations also come from a note whose name, alias or rank or office title spells it whole. See [a language's words](reference/format-details.md#a-languages-words), [a language's register, sounds and history](reference/format-details.md#a-languages-register-sounds-and-history), [glossary terms](reference/format-details.md#glossary-terms) and [dictionaries and glossaries](reference/format-details.md#dictionaries-and-glossaries).
146
+ A language note (`type: skill`, `subType: language`) states its words in frontmatter: `data.words` states each word as a map of its form, class, field and gloss — one sense or a list of them, which a dictionary numbers — with its source, its variant forms, the pieces it is built from and a note, beside `data.classModifiers`, `data.fields` and `data.affixes`, each affix with the `kind` it makes, for a given name's ending who the name is `given` to, and the stem closes it is barred after; a zero affix states `zero: true` and no form. The notes a word is cited from are derived, not written: a note cites a word by marking it in italics in its prose, matched by form or a variant with diacritics and case set aside. The language of a word is the note it sits on, and none of it reaches the compiled Item. A daughter language names its parent in `data.family` and reads the parent's words as its own; the `language_lineage` relation joins a language to its ancestors. Classes come from the [master word classes](reference/format-details.md#word-classes). A culture or an affiliation states its own glossary terms in `data.glossary`, and every entry resolves to a language — its own `language`, else the affiliation's, its parents' or its culture's, else the culture's — or is an error at the entry. The `words`, `affixes`, `fields`, `glossary` and `language_lineage` relations hold them for `sql` fences, the `dictionary` relation lists each word under every language that has it, inherited words included, and the `terms` relation each glossary entry, rank and office with the cultures it reaches; a fence sets them with `layout=dictionary` or `layout=glossary`. A language note names the tag a dictionary prints for it in `data.abbreviation`. Every fact a check reads about a language's names, sounds and history is frontmatter too: `data.tongues` and `data.register` (every name the setting gives in the language's reach, the notes carrying each derived from the index), `data.retired`, `data.scope`, `data.sounds` (letters with their place, word edges from a closed list, the cluster limit and the groups of clusters inside a word, the stress rule, syllable finals, syllable rules and vowel harmony with each vowel's front partner, the joining of parts, written marks, a root's skeleton vowel and frames, the spellings read past, and named mutations such as wearing and voicing), `data.soundChanges` (named sets of ordered steps), `data.elements` (each standing `opening`, `closing`, `either` or `link`, for one kind of name, with the word it is the stem of and its genitive), `data.roots`, `data.cognates` (with a reconstructed `proto` form), `data.callingNames`, `data.older` (the forms older than the rules), `data.negation` (the negative particle and the mutation it brings) and `data.naming` (how long each class of name runs, the edges names keep that words do not, the element kinds each kind of name draws on, what a place name takes from what it is held from, and the near name), each a relation — `sounds` as `letters`, `edges`, `clusters`, `cluster_groups`, `stress`, `finals`, `syllables`, `joining`, `joins`, `marks`, `skeleton`, `frames`, `read_past` and `mutations`, `soundChanges` as `sound_changes`, `callingNames` as `calling_names` — that a fence sets back on the page. A word's citations also come from a note whose name, alias or rank or office title spells it whole. See [a language's words](reference/format-details.md#a-languages-words), [a language's register, sounds and history](reference/format-details.md#a-languages-register-sounds-and-history), [glossary terms](reference/format-details.md#glossary-terms) and [dictionaries and glossaries](reference/format-details.md#dictionaries-and-glossaries).
147
147
 
148
148
  Blockquote alerts use `[!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]`, or `[!]`, with optional attributes after the marker. They replace the former info and warn div fences; secret blocks remain supported. See [alerts](authoring/links-and-markup.md#alerts).