@hawkeyexl/manni 4.9.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{batch-W5GXL2P4.js → batch-UAULUMGH.js} +18 -14
- package/dist/{build-Q56FEXR6.js → build-QSPNK5AL.js} +14 -11
- package/dist/calibrate-KXN4URPM.js +40 -0
- package/dist/{capture-GMYH4ATL.js → capture-JHTSUPUC.js} +16 -13
- package/dist/{check-OAJWC3WD.js → check-MDGXEUWL.js} +5 -5
- package/dist/{check-KUBELO5G.js → check-VELUQAUW.js} +17 -14
- package/dist/{check-KUBELO5G.js.map → check-VELUQAUW.js.map} +1 -1
- package/dist/check-WOQRKNZK.js +29 -0
- package/dist/{check-ZE5HIDOW.js → check-YEOYBFST.js} +14 -11
- package/dist/{chunk-FGUXMZXO.js → chunk-2DRHT73U.js} +7 -7
- package/dist/{chunk-XHFHXOQQ.js → chunk-2IAZEB45.js} +8 -8
- package/dist/{chunk-35WTFPQS.js → chunk-2IR4T5PO.js} +2 -2
- package/dist/{chunk-KX5IYIOO.js → chunk-2MJ62AYQ.js} +2 -2
- package/dist/chunk-2MJ62AYQ.js.map +1 -0
- package/dist/{chunk-OWSNXPPX.js → chunk-4CK6ZSOK.js} +6 -6
- package/dist/{chunk-YUZ2ECZY.js → chunk-4D5IZSXM.js} +3 -3
- package/dist/{chunk-RFSGKF4O.js → chunk-4VBSTXN6.js} +4 -4
- package/dist/{chunk-3XMG4CZY.js → chunk-54F74XR3.js} +15 -13
- package/dist/{chunk-3XMG4CZY.js.map → chunk-54F74XR3.js.map} +1 -1
- package/dist/{chunk-IN6DWNVE.js → chunk-6HWBRZIN.js} +47 -191
- package/dist/chunk-6HWBRZIN.js.map +1 -0
- package/dist/{chunk-GEMXGXPR.js → chunk-ADMEPUBT.js} +3 -3
- package/dist/{chunk-23UAGEKP.js → chunk-B7XYNRJQ.js} +2 -2
- package/dist/{chunk-QKE3XS2L.js → chunk-BBT6AVUG.js} +2 -2
- package/dist/{chunk-VKWZCEWB.js → chunk-BKVHX6FU.js} +4 -4
- package/dist/{chunk-X6WLCNKC.js → chunk-D4N2V43Z.js} +4 -4
- package/dist/{chunk-XXDXIIQ4.js → chunk-EFW7CAG4.js} +2 -2
- package/dist/{chunk-UDUHRXJ4.js → chunk-EIFCP6CZ.js} +2 -2
- package/dist/{chunk-KPXOJMQ6.js → chunk-FBMZJEB3.js} +2 -2
- package/dist/{chunk-HRXDM6H6.js → chunk-FQXWVS6J.js} +8 -8
- package/dist/{chunk-76I6I5N2.js → chunk-FUCPZVRY.js} +2 -2
- package/dist/{chunk-DTGIUMZV.js → chunk-GDVZ5VII.js} +4 -4
- package/dist/{chunk-QCCAHV6A.js → chunk-GV56WGL2.js} +321 -3308
- package/dist/chunk-GV56WGL2.js.map +1 -0
- package/dist/{chunk-TKTRIZT4.js → chunk-HA6MQMOY.js} +6 -6
- package/dist/{chunk-ECVQNGTH.js → chunk-HQR2ZBHW.js} +3 -3
- package/dist/{chunk-MHAYLDBK.js → chunk-IGSHYP74.js} +4 -4
- package/dist/{chunk-YEUQ7OKT.js → chunk-J6IDQGJL.js} +4 -4
- package/dist/{chunk-5LBEQ4ZU.js → chunk-JPQDNYXH.js} +2 -2
- package/dist/{chunk-6KKZXB2O.js → chunk-JROBZ7JA.js} +2 -2
- package/dist/{chunk-TMI2YF6D.js → chunk-KGEQJ5CC.js} +15 -26
- package/dist/{chunk-TMI2YF6D.js.map → chunk-KGEQJ5CC.js.map} +1 -1
- package/dist/{chunk-2EHDJ47Y.js → chunk-LBSCW232.js} +4 -4
- package/dist/{chunk-M6GH3FGJ.js → chunk-LKP7QDFN.js} +4 -4
- package/dist/{chunk-5EB6RIXJ.js → chunk-LPIF5LIE.js} +2 -2
- package/dist/chunk-M42DZCOU.js +164 -0
- package/dist/chunk-M42DZCOU.js.map +1 -0
- package/dist/{chunk-ND2S5BXB.js → chunk-MSRU4D4P.js} +2 -2
- package/dist/{chunk-BSTXARMY.js → chunk-NSBXVPZL.js} +11 -11
- package/dist/{chunk-Q45PZX2D.js → chunk-ODRPL3WB.js} +2 -2
- package/dist/{chunk-FSBIPCWE.js → chunk-OPXWPJDA.js} +10 -10
- package/dist/chunk-PCQ7ELJH.js +3081 -0
- package/dist/chunk-PCQ7ELJH.js.map +1 -0
- package/dist/{chunk-QAKJNPY3.js → chunk-PCS4VJBV.js} +6 -6
- package/dist/{chunk-GRILZZGS.js → chunk-PWBH7DCQ.js} +3 -3
- package/dist/{chunk-XKBEHKWO.js → chunk-QLWC7MKD.js} +34 -32
- package/dist/chunk-QLWC7MKD.js.map +1 -0
- package/dist/{chunk-XTAHZTES.js → chunk-R4WXQIOZ.js} +6 -6
- package/dist/{chunk-3CDZWY6M.js → chunk-RLT5SEML.js} +5 -5
- package/dist/{chunk-XG6PVB5S.js → chunk-SSQZB5SQ.js} +1 -11
- package/dist/chunk-SSQZB5SQ.js.map +1 -0
- package/dist/chunk-T7JAOYE5.js +393 -0
- package/dist/chunk-T7JAOYE5.js.map +1 -0
- package/dist/chunk-TU2WUBVZ.js +2 -0
- package/dist/{chunk-Q2H7J3FF.js → chunk-U7CTFN2J.js} +12 -10
- package/dist/{chunk-Q2H7J3FF.js.map → chunk-U7CTFN2J.js.map} +1 -1
- package/dist/{chunk-3XGGF5JW.js → chunk-VSEBFHAY.js} +10 -7
- package/dist/{chunk-3XGGF5JW.js.map → chunk-VSEBFHAY.js.map} +1 -1
- package/dist/{chunk-OVOYKWCM.js → chunk-WDWXAYVH.js} +4 -4
- package/dist/{chunk-5WME4CB6.js → chunk-Y6DOMTQD.js} +10 -8
- package/dist/{chunk-5WME4CB6.js.map → chunk-Y6DOMTQD.js.map} +1 -1
- package/dist/chunk-ZMECS2IJ.js +27 -0
- package/dist/chunk-ZMECS2IJ.js.map +1 -0
- package/dist/chunk-ZPLVANY2.js +15 -0
- package/dist/chunk-ZPLVANY2.js.map +1 -0
- package/dist/{cli-MEPJTS2V.js → cli-3BTCK4AB.js} +18 -15
- package/dist/{cli-MEPJTS2V.js.map → cli-3BTCK4AB.js.map} +1 -1
- package/dist/{cli-EMQXRN6E.js → cli-4MF37HAQ.js} +16 -12
- package/dist/{cli-EMQXRN6E.js.map → cli-4MF37HAQ.js.map} +1 -1
- package/dist/{cli-YDMMIL2U.js → cli-6KZTHWGP.js} +17 -14
- package/dist/{cli-YDMMIL2U.js.map → cli-6KZTHWGP.js.map} +1 -1
- package/dist/{cli-ZJRHU7MO.js → cli-DRMZBZLB.js} +39 -34
- package/dist/cli-DRMZBZLB.js.map +1 -0
- package/dist/{cli-J35OPSTP.js → cli-I62SRH3R.js} +10 -8
- package/dist/cli-JJMOVIKS.js +83 -0
- package/dist/cli-JJMOVIKS.js.map +1 -0
- package/dist/{cli-TPONWND4.js → cli-O4ABTN4Z.js} +25 -21
- package/dist/{cli-TPONWND4.js.map → cli-O4ABTN4Z.js.map} +1 -1
- package/dist/{cli-URNPOMOH.js → cli-ONTC5PKT.js} +3 -3
- package/dist/{cli-BJ7JXJ2U.js → cli-RORDPAPE.js} +17 -14
- package/dist/{cli-BJ7JXJ2U.js.map → cli-RORDPAPE.js.map} +1 -1
- package/dist/{cli-B7SFJDZA.js → cli-VID7PJS3.js} +17 -13
- package/dist/{cli-B7SFJDZA.js.map → cli-VID7PJS3.js.map} +1 -1
- package/dist/cli-VUKMWSSF.js +839 -0
- package/dist/cli-VUKMWSSF.js.map +1 -0
- package/dist/cli.js +24 -11
- package/dist/cli.js.map +1 -1
- package/dist/{config-YWSNBFEE.js → config-XDA42RJL.js} +3 -3
- package/dist/docmeta.js +9 -7
- package/dist/docmeta.js.map +1 -1
- package/dist/github-RY3FRA6P.js +29 -0
- package/dist/github-YKQSH7FS.js +34 -0
- package/dist/index.d.ts +1023 -915
- package/dist/index.js +107 -81
- package/dist/index.js.map +1 -1
- package/dist/{json-JIUPGOUQ.js → json-BXY44ED7.js} +13 -10
- package/dist/lint-YJ2L22BW.js +33 -0
- package/dist/list-NSG24VVX.js +31 -0
- package/dist/list-V6EGCSHX.js +34 -0
- package/dist/{page-WQ3GQF76.js → page-EV7OUBAU.js} +12 -9
- package/dist/{prepare-ZUTYXTUZ.js → prepare-JHJDJB6I.js} +17 -14
- package/dist/{prepare-ZUTYXTUZ.js.map → prepare-JHJDJB6I.js.map} +1 -1
- package/dist/{pretty-Q3C433DW.js → pretty-Q5Y2PA64.js} +14 -11
- package/dist/{pretty-CBV5XSMZ.js → pretty-SCRK66M5.js} +13 -10
- package/dist/{reporters-DH5HPFXJ.js → reporters-A5ADKDYR.js} +12 -9
- package/dist/{reporters-TTYGOUAF.js → reporters-RBYTASMI.js} +5 -5
- package/dist/run-BUE2DDXN.js +36 -0
- package/dist/{term-DL3YFL43.js → term-CQAGNG3Q.js} +17 -14
- package/dist/{term-DL3YFL43.js.map → term-CQAGNG3Q.js.map} +1 -1
- package/dist/{validate-UVDMC5LT.js → validate-ZBW44RHT.js} +6 -5
- package/dist/validate-ZBW44RHT.js.map +1 -0
- package/package.json +1 -1
- package/plugin/manni/.claude-plugin/plugin.json +1 -1
- package/dist/calibrate-XFE56P4M.js +0 -36
- package/dist/check-HBRX4FOR.js +0 -26
- package/dist/chunk-IN6DWNVE.js.map +0 -1
- package/dist/chunk-KX5IYIOO.js.map +0 -1
- package/dist/chunk-QCCAHV6A.js.map +0 -1
- package/dist/chunk-XG6PVB5S.js.map +0 -1
- package/dist/chunk-XKBEHKWO.js.map +0 -1
- package/dist/cli-ZJRHU7MO.js.map +0 -1
- package/dist/github-63CZJGZS.js +0 -31
- package/dist/github-IYOVHWHG.js +0 -26
- package/dist/lint-TBE35CCW.js +0 -29
- package/dist/list-IZ4RIM72.js +0 -30
- package/dist/list-TNEJ3J77.js +0 -28
- package/dist/run-LZXKVTM7.js +0 -32
- /package/dist/{batch-W5GXL2P4.js.map → batch-UAULUMGH.js.map} +0 -0
- /package/dist/{build-Q56FEXR6.js.map → build-QSPNK5AL.js.map} +0 -0
- /package/dist/{calibrate-XFE56P4M.js.map → calibrate-KXN4URPM.js.map} +0 -0
- /package/dist/{capture-GMYH4ATL.js.map → capture-JHTSUPUC.js.map} +0 -0
- /package/dist/{check-HBRX4FOR.js.map → check-MDGXEUWL.js.map} +0 -0
- /package/dist/{check-OAJWC3WD.js.map → check-WOQRKNZK.js.map} +0 -0
- /package/dist/{check-ZE5HIDOW.js.map → check-YEOYBFST.js.map} +0 -0
- /package/dist/{chunk-FGUXMZXO.js.map → chunk-2DRHT73U.js.map} +0 -0
- /package/dist/{chunk-XHFHXOQQ.js.map → chunk-2IAZEB45.js.map} +0 -0
- /package/dist/{chunk-35WTFPQS.js.map → chunk-2IR4T5PO.js.map} +0 -0
- /package/dist/{chunk-OWSNXPPX.js.map → chunk-4CK6ZSOK.js.map} +0 -0
- /package/dist/{chunk-YUZ2ECZY.js.map → chunk-4D5IZSXM.js.map} +0 -0
- /package/dist/{chunk-RFSGKF4O.js.map → chunk-4VBSTXN6.js.map} +0 -0
- /package/dist/{chunk-GEMXGXPR.js.map → chunk-ADMEPUBT.js.map} +0 -0
- /package/dist/{chunk-23UAGEKP.js.map → chunk-B7XYNRJQ.js.map} +0 -0
- /package/dist/{chunk-QKE3XS2L.js.map → chunk-BBT6AVUG.js.map} +0 -0
- /package/dist/{chunk-VKWZCEWB.js.map → chunk-BKVHX6FU.js.map} +0 -0
- /package/dist/{chunk-X6WLCNKC.js.map → chunk-D4N2V43Z.js.map} +0 -0
- /package/dist/{chunk-XXDXIIQ4.js.map → chunk-EFW7CAG4.js.map} +0 -0
- /package/dist/{chunk-UDUHRXJ4.js.map → chunk-EIFCP6CZ.js.map} +0 -0
- /package/dist/{chunk-KPXOJMQ6.js.map → chunk-FBMZJEB3.js.map} +0 -0
- /package/dist/{chunk-HRXDM6H6.js.map → chunk-FQXWVS6J.js.map} +0 -0
- /package/dist/{chunk-76I6I5N2.js.map → chunk-FUCPZVRY.js.map} +0 -0
- /package/dist/{chunk-DTGIUMZV.js.map → chunk-GDVZ5VII.js.map} +0 -0
- /package/dist/{chunk-TKTRIZT4.js.map → chunk-HA6MQMOY.js.map} +0 -0
- /package/dist/{chunk-ECVQNGTH.js.map → chunk-HQR2ZBHW.js.map} +0 -0
- /package/dist/{chunk-MHAYLDBK.js.map → chunk-IGSHYP74.js.map} +0 -0
- /package/dist/{chunk-YEUQ7OKT.js.map → chunk-J6IDQGJL.js.map} +0 -0
- /package/dist/{chunk-5LBEQ4ZU.js.map → chunk-JPQDNYXH.js.map} +0 -0
- /package/dist/{chunk-6KKZXB2O.js.map → chunk-JROBZ7JA.js.map} +0 -0
- /package/dist/{chunk-2EHDJ47Y.js.map → chunk-LBSCW232.js.map} +0 -0
- /package/dist/{chunk-M6GH3FGJ.js.map → chunk-LKP7QDFN.js.map} +0 -0
- /package/dist/{chunk-5EB6RIXJ.js.map → chunk-LPIF5LIE.js.map} +0 -0
- /package/dist/{chunk-ND2S5BXB.js.map → chunk-MSRU4D4P.js.map} +0 -0
- /package/dist/{chunk-BSTXARMY.js.map → chunk-NSBXVPZL.js.map} +0 -0
- /package/dist/{chunk-Q45PZX2D.js.map → chunk-ODRPL3WB.js.map} +0 -0
- /package/dist/{chunk-FSBIPCWE.js.map → chunk-OPXWPJDA.js.map} +0 -0
- /package/dist/{chunk-QAKJNPY3.js.map → chunk-PCS4VJBV.js.map} +0 -0
- /package/dist/{chunk-GRILZZGS.js.map → chunk-PWBH7DCQ.js.map} +0 -0
- /package/dist/{chunk-XTAHZTES.js.map → chunk-R4WXQIOZ.js.map} +0 -0
- /package/dist/{chunk-3CDZWY6M.js.map → chunk-RLT5SEML.js.map} +0 -0
- /package/dist/{cli-J35OPSTP.js.map → chunk-TU2WUBVZ.js.map} +0 -0
- /package/dist/{chunk-OVOYKWCM.js.map → chunk-WDWXAYVH.js.map} +0 -0
- /package/dist/{config-YWSNBFEE.js.map → cli-I62SRH3R.js.map} +0 -0
- /package/dist/{cli-URNPOMOH.js.map → cli-ONTC5PKT.js.map} +0 -0
- /package/dist/{github-63CZJGZS.js.map → config-XDA42RJL.js.map} +0 -0
- /package/dist/{github-IYOVHWHG.js.map → github-RY3FRA6P.js.map} +0 -0
- /package/dist/{json-JIUPGOUQ.js.map → github-YKQSH7FS.js.map} +0 -0
- /package/dist/{lint-TBE35CCW.js.map → json-BXY44ED7.js.map} +0 -0
- /package/dist/{list-IZ4RIM72.js.map → lint-YJ2L22BW.js.map} +0 -0
- /package/dist/{list-TNEJ3J77.js.map → list-NSG24VVX.js.map} +0 -0
- /package/dist/{page-WQ3GQF76.js.map → list-V6EGCSHX.js.map} +0 -0
- /package/dist/{pretty-CBV5XSMZ.js.map → page-EV7OUBAU.js.map} +0 -0
- /package/dist/{pretty-Q3C433DW.js.map → pretty-Q5Y2PA64.js.map} +0 -0
- /package/dist/{reporters-DH5HPFXJ.js.map → pretty-SCRK66M5.js.map} +0 -0
- /package/dist/{reporters-TTYGOUAF.js.map → reporters-A5ADKDYR.js.map} +0 -0
- /package/dist/{run-LZXKVTM7.js.map → reporters-RBYTASMI.js.map} +0 -0
- /package/dist/{validate-UVDMC5LT.js.map → run-BUE2DDXN.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/term/cli.ts","../src/term/core/writers/documents.ts","../src/term/core/writers/page.ts","../src/term/core/writers/csv.ts","../src/term/core/writers/json.ts","../src/term/core/writers/skos.ts","../src/term/core/writers/tbx.ts","../src/term/core/writers/vale.ts","../src/term/core/writers/interchange.ts","../src/term/core/writers/index.ts","../src/term/commands/formats.ts","../src/term/commands/get.ts","../src/term/core/lint.ts","../src/term/core/vale.ts","../src/term/commands/lint.ts","../src/term/commands/write.ts","../src/term/reporters/csv.ts","../src/term/reporters/sarif.ts","../src/term/reporters/junit.ts","../src/term/commands/labels.ts"],"sourcesContent":["/**\n * The `term` domain's commander program. Mounted by `src/cli.ts` under\n * `manni term`; no entry point of its own. Grammar per proposal 0034: the verbs\n * are `list`, `get`, `check`, `lint`, `write` and `formats`, and there is no\n * default subcommand.\n *\n * Follows clig.dev as the family does: primary output to stdout, diagnostics\n * and notices to stderr, colour only on a TTY and never under\n * `NO_COLOR`/`--no-color`, exit `0` clean, `1` an error-severity finding or a\n * `--check` that found drift, `2` operational/usage.\n */\nimport { Command } from \"commander\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport { collect, readStdin, splitList } from \"../shared/cli-options.js\";\nimport { shouldColor } from \"../shared/color.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice } from \"../shared/warn.js\";\nimport { OMITTED_WHEN_CLEAN, STDIN_TOKEN } from \"../meta/internal.js\";\nimport { runCheck } from \"./commands/check.js\";\nimport { FINDING_FORMATS, type FindingFormat, type TermReport } from \"./commands/findings.js\";\nimport { FORMATS_FORMATS, listFormats } from \"./commands/formats.js\";\nimport { GET_FORMATS, runGet } from \"./commands/get.js\";\nimport { runLint } from \"./commands/lint.js\";\nimport { LIST_FORMATS, runList } from \"./commands/list.js\";\nimport { formatChoice, type TermCommandOptions } from \"./commands/run.js\";\nimport { runWrite, writeFormats } from \"./commands/write.js\";\nimport { renderListCsv } from \"./reporters/csv.js\";\nimport { renderFindingsGithub } from \"./reporters/github.js\";\nimport { renderFindingsJson, renderFormatsJson, renderGetJson, renderListJson } from \"./reporters/json.js\";\nimport { renderFindingsJunit } from \"./reporters/junit.js\";\nimport {\n renderFindingsPretty,\n renderFormatsPretty,\n renderGetPretty,\n renderListPretty,\n renderValeWiring,\n renderWritePretty,\n} from \"./reporters/pretty.js\";\nimport { renderFindingsSarif } from \"./reporters/sarif.js\";\nimport { registerTermLabelSource } from \"../shared/term-labels.js\";\nimport { termLabels } from \"./commands/labels.js\";\n\n// The umbrella loads this module, so under the `manni` bin `meta fill` offers\n// the termbase's labels. The `docmeta` bin never loads it, and offers none.\nregisterTermLabelSource(termLabels);\n\n/** What commander hands every verb that reads terms. */\ninterface InputCliOptions {\n as?: string;\n /** `--ext <list>`, comma-separated and given once. */\n ext?: string;\n /** `--exclude <glob>`, repeatable; commander's default value is `[]`. */\n exclude: string[];\n /** `--allow-empty`. */\n allowEmpty?: boolean;\n /** `--no-gitignore`: `false` when given. */\n gitignore: boolean;\n /** `--collection <name>`, repeatable; commander's default value is `[]`. */\n collection: string[];\n config?: string;\n /** `--no-color`: `false` when given. */\n color: boolean;\n}\n\ninterface FormatCliOptions extends InputCliOptions {\n format: string;\n}\n\ninterface CheckCliOptions extends FormatCliOptions {\n baseline?: boolean;\n}\n\ninterface WriteCliOptions extends InputCliOptions {\n format?: string;\n out?: string;\n check?: boolean;\n dryRun?: boolean;\n}\n\n/** Colour for a verb's pretty output: off under `--no-color` or `NO_COLOR`, on only for a TTY. */\nfunction colorFor(options: InputCliOptions): boolean {\n return shouldColor({ noColor: !options.color, isTTY: process.stdout.isTTY });\n}\n\n/** The core's shared options from commander's, with stdin read once when `-` is among the paths. */\nasync function coreOptions(paths: string[], options: InputCliOptions): Promise<TermCommandOptions> {\n return {\n inputs: paths,\n ...(paths.includes(STDIN_TOKEN) ? { stdin: await readStdin() } : {}),\n ...(options.as === undefined ? {} : { as: options.as }),\n ...(options.ext === undefined ? {} : { exts: splitList(options.ext) }),\n exclude: options.exclude,\n collection: options.collection,\n ...(options.allowEmpty === true ? { allowEmpty: true } : {}),\n ...(options.gitignore ? {} : { noGitignore: true }),\n ...(options.config === undefined ? {} : { configPath: options.config }),\n onNotice: notice,\n };\n}\n\n/** The shared input flags, declared once so every verb spells them alike. */\nfunction withInputs(command: Command): Command {\n return command\n .option(\"--as <format>\", \"input format for stdin (-)\")\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--collection <name>\", \"configured collection to read; repeatable\", collect, [])\n .option(\"--allow-empty\", \"treat a missing path, no matched files or no terms as success\")\n .option(\"--no-gitignore\", \"read files .gitignore covers\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-color\", \"disable colored output\");\n}\n\nfunction print(text: string): void {\n process.stdout.write(`${text}\\n`);\n}\n\nfunction renderFindings(report: TermReport, format: FindingFormat, options: InputCliOptions, references: boolean): void {\n let text: string;\n switch (format) {\n case \"pretty\":\n text = renderFindingsPretty(report, { color: colorFor(options), references });\n break;\n case \"json\":\n text = renderFindingsJson(report);\n break;\n case \"github\":\n text = renderFindingsGithub(report);\n break;\n case \"sarif\":\n text = renderFindingsSarif(report, { onNotice: notice });\n break;\n case \"junit\":\n text = renderFindingsJunit(report);\n break;\n }\n if (text.length > 0 || !OMITTED_WHEN_CLEAN.has(format)) print(text);\n process.exitCode = report.summary.failed > 0 ? 1 : 0;\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"term\")\n .description(\"Check, lint and render a docset's terms and the references into them.\")\n .version(pkg.version, \"-V, --version\")\n // A pointer, not the whole help screen: the message that precedes it\n // already names the offending flag.\n .showHelpAfterError(\"(add --help for usage)\")\n // MUST come before the `.command()` calls below: commander copies the exit\n // callback into each subcommand by value when the subcommand is created.\n .exitOverride();\n\n withInputs(\n program\n .command(\"list\")\n .description(\"List the resolved entries\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `output: ${LIST_FORMATS.join(\" | \")}`, \"pretty\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni term list # every collection\",\n \" manni term list docs/terms/ # one directory\",\n \" manni term list -f csv | head -2 # for a script\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: FormatCliOptions) => {\n try {\n const format = formatChoice(options.format, LIST_FORMATS);\n const { terms } = await runList(await coreOptions(paths, options));\n print(format === \"json\" ? renderListJson(terms) : format === \"csv\" ? renderListCsv(terms) : renderListPretty(terms));\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n withInputs(\n program\n .command(\"get\")\n .description(\"Show one entry\")\n .argument(\"<term>\", \"the entry's id, or its label or an alt-label in any case\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `output: ${GET_FORMATS.join(\" | \")}`, \"pretty\")\n .addHelpText(\n \"after\",\n [\"\", \"Examples:\", \" manni term get progressive-lens\", ' manni term get \"progressive lens\" -f json'].join(\"\\n\"),\n )\n .action(async (term: string, paths: string[], options: FormatCliOptions) => {\n try {\n const format = formatChoice(options.format, GET_FORMATS);\n const found = await runGet({ ...(await coreOptions(paths, options)), term });\n print(\n format === \"json\"\n ? renderGetJson(found.term)\n : renderGetPretty(found.term, { color: colorFor(options), others: found.others }),\n );\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n withInputs(\n program\n .command(\"check\")\n .description(\"Check the set and every reference into it\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `output: ${FINDING_FORMATS.join(\" | \")}`, \"pretty\")\n .option(\"--baseline\", \"record the findings on the first run; after that, fail only on new ones\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni term check # every collection\",\n \" manni term check -f github # CI annotations\",\n \" manni term check --baseline # ramp in on an existing docset\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: CheckCliOptions) => {\n try {\n const format = formatChoice(options.format, FINDING_FORMATS);\n const report = await runCheck({\n ...(await coreOptions(paths, options)),\n ...(options.baseline === true ? { baseline: true } : {}),\n });\n renderFindings(report, format, options, true);\n } catch (err) {\n fail(err);\n }\n });\n\n withInputs(\n program\n .command(\"lint\")\n .description(\"Run Vale over the definitions\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `output: ${FINDING_FORMATS.join(\" | \")}`, \"pretty\")\n .addHelpText(\n \"after\",\n [\"\", \"Examples:\", \" manni term lint\", \" manni term lint -f github\"].join(\"\\n\"),\n )\n .action(async (paths: string[], options: FormatCliOptions) => {\n try {\n const format = formatChoice(options.format, FINDING_FORMATS);\n const report = await runLint(await coreOptions(paths, options));\n renderFindings(report, format, options, false);\n } catch (err) {\n fail(err);\n }\n });\n\n withInputs(\n program\n .command(\"write\")\n .description(\"Write the set back, or render it elsewhere\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `render as: ${writeFormats().join(\" | \")} (default: each entry's own, in place)`)\n .option(\"-o, --out <path>\", \"file or directory to render into; a trailing / means a directory\")\n .option(\"--check\", \"write nothing; exit 1 when the target differs from the render\")\n .option(\"--dry-run\", \"write nothing; print what would change\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni term write # each entry back to its source\",\n \" manni term write -f json -o build/terms.json\",\n \" manni term write -f vale # into Vale's styles directory\",\n \" manni term write -f vale --check # keep the style in step\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: WriteCliOptions) => {\n try {\n const report = await runWrite({\n ...(await coreOptions(paths, options)),\n ...(options.format === undefined ? {} : { format: options.format }),\n ...(options.out === undefined ? {} : { out: options.out }),\n ...(options.check === true ? { check: true } : {}),\n ...(options.dryRun === true ? { dryRun: true } : {}),\n });\n print(renderWritePretty(report));\n if (report.wiring !== undefined) process.stderr.write(`${renderValeWiring(report.wiring)}\\n`);\n process.exitCode = report.check && report.changes.length > 0 ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"formats\")\n .description(\"List the constructs read and written, per format\")\n .option(\"-f, --format <format>\", `output: ${FORMATS_FORMATS.join(\" | \")}`, \"pretty\")\n .action((options: { format: string }) => {\n try {\n const format = formatChoice(options.format, FORMATS_FORMATS);\n const rows = listFormats();\n print(format === \"json\" ? renderFormatsJson(rows) : renderFormatsPretty(rows));\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n return program;\n}\n","/**\n * Writers for the seven document formats. The target's shape decides the\n * construct: a directory gets one term page per term (a DITA glossentry topic\n * for DITA), a file gets every term in the format's list construct. DocBook\n * has no one-term construct, so it is written as a file only.\n *\n * A set in more than one language puts each page under a directory named for\n * its language. A list construct holds one language, so a file gets the first\n * term's, and the render reports the terms in any other.\n */\nimport { join } from \"node:path\";\nimport { TermError } from \"../../errors.js\";\nimport {\n TERM_FIELDS,\n type Term,\n type TermField,\n type TermRender,\n type TermShape,\n type TermTarget,\n type TermWriteFormat,\n type TermWriter,\n} from \"../../types.js\";\nimport {\n DITA_HOLDS,\n DOCBOOK_HOLDS,\n LIST_HOLDS,\n asciidocEntry,\n ditaEntry,\n docbookEntry,\n htmlDlEntry,\n markdownEntry,\n rstEntry,\n} from \"./entries.js\";\nimport { fileOf, reindent, sharedLanguage, xmlAttribute } from \"./markup.js\";\nimport { htmlPage, metadataPage, yamlFrontmatter } from \"./page.js\";\nimport { droppedFields, isMultilingual, languageKey, languageOf, requireShape } from \"./render-util.js\";\n\n/** Characters no file name may hold on any platform manni runs on. */\nconst UNSAFE_NAME = /[/\\\\:*?\"<>|]/;\n\ninterface DocumentSpec {\n format: TermWriteFormat;\n extension: string;\n file: {\n holds: readonly TermField[];\n render: (terms: readonly Term[]) => string;\n /**\n * Whether the file's construct reads an entry only when it has a\n * definition. A Markdown or AsciiDoc list and a `.. glossary::` skip one\n * with none, and a `<dl>` folds its `<dt>`s into the next entry's, so a\n * term with no definition is left out rather than written unreadable.\n */\n needsDefinition: boolean;\n };\n directory?: { holds: readonly TermField[]; render: (term: Term) => string };\n}\n\n/**\n * One path per term: `<id><ext>`, or `<lang>/<id><ext>` when the set holds\n * more than one language. A language's directory is spelled as its first term\n * spells it.\n */\nfunction pagePaths(terms: readonly Term[], target: TermTarget, extension: string): string[] {\n const multilingual = isMultilingual(terms);\n const spelling = new Map<string, string>();\n const seen = new Set<string>();\n return terms.map((term) => {\n if (UNSAFE_NAME.test(term.id) || term.id === \".\" || term.id === \"..\") {\n throw new TermError(`the id \"${term.id}\" cannot name a file. Give the term an id without path characters.`);\n }\n if (!multilingual) {\n if (seen.has(term.id)) {\n throw new TermError(`two terms have the id \"${term.id}\", and a directory holds one file per id.`);\n }\n seen.add(term.id);\n return join(target.path, `${term.id}${extension}`);\n }\n const key = languageKey(term);\n const language = spelling.get(key) ?? languageOf(term);\n spelling.set(key, language);\n if (UNSAFE_NAME.test(language) || language === \".\" || language === \"..\") {\n throw new TermError(\n `the language \"${language}\" cannot name a directory. Give the term a language without path characters.`,\n );\n }\n if (seen.has(`${key} ${term.id}`)) {\n throw new TermError(\n `two terms have the id \"${term.id}\" in ${language}, and a directory holds one file per id in each language.`,\n );\n }\n seen.add(`${key} ${term.id}`);\n return join(target.path, language, `${term.id}${extension}`);\n });\n}\n\n/** The terms a one-language construct writes: the first term's language. The rest are reported. */\nfunction firstLanguage(terms: readonly Term[]): { kept: Term[]; otherLanguages?: TermRender[\"otherLanguages\"] } {\n const [first] = terms;\n if (first === undefined || !isMultilingual(terms)) return { kept: [...terms] };\n const key = languageKey(first);\n return {\n kept: terms.filter((t) => languageKey(t) === key),\n otherLanguages: {\n written: languageOf(first),\n terms: terms.filter((t) => languageKey(t) !== key).map((t) => ({ id: t.id, language: languageOf(t) })),\n },\n };\n}\n\nfunction documentWriter(spec: DocumentSpec): TermWriter {\n const { directory } = spec;\n return {\n format: spec.format,\n shapes: directory === undefined ? [\"file\"] : [\"file\", \"directory\"],\n holds: (shape: TermShape) => (shape === \"directory\" && directory !== undefined ? directory.holds : spec.file.holds),\n render(terms, target): TermRender {\n if (target.shape === \"directory\" && directory !== undefined) {\n const paths = pagePaths(terms, target, spec.extension);\n return {\n files: terms.map((term, i) => ({ path: paths[i] ?? \"\", content: directory.render(term) })),\n removals: [],\n dropped: droppedFields(terms, directory.holds),\n skipped: [],\n };\n }\n requireShape(spec.format, target, \"file\");\n const { kept, otherLanguages } = firstLanguage(terms);\n const written = spec.file.needsDefinition ? kept.filter((t) => t.record.definition !== undefined) : kept;\n return {\n files: [{ path: target.path, content: spec.file.render(written) }],\n removals: [],\n dropped: droppedFields(written, spec.file.holds),\n skipped: kept.filter((t) => !written.includes(t)).map((t) => t.id),\n ...(otherLanguages === undefined ? {} : { otherLanguages }),\n };\n },\n };\n}\n\n/** Entries at indentation zero, a blank line between them, each indented to `indent`. */\nfunction entriesBlock(entries: readonly string[], indent = \"\"): string[] {\n return entries.flatMap((entry, i) => [\n ...(i === 0 ? [] : [\"\"]),\n `${indent}${reindent(entry, indent, \"\\n\")}`,\n ]);\n}\n\n/** Every line of each entry indented, no blank line between: markup keeps its entries adjacent. */\nfunction markupBlock(entries: readonly string[], indent: string): string[] {\n return entries.map((entry) => `${indent}${reindent(entry, indent, \"\\n\")}`);\n}\n\nfunction textPage(format: string): (term: Term) => string {\n return (term) => metadataPage(format, term);\n}\n\n/** The frontmatter a many-per-file text document opens with, or none when it would be empty. */\nfunction listFrontmatter(terms: readonly Term[], type: boolean): string[] {\n const metadata: Record<string, unknown> = {};\n if (type) metadata[\"type\"] = \"term-set\";\n const language = sharedLanguage(terms);\n if (language !== undefined) metadata[\"language\"] = language;\n if (Object.keys(metadata).length === 0) return [];\n return [yamlFrontmatter(metadata).replace(/\\n$/, \"\"), \"\"];\n}\n\nfunction markdownList(terms: readonly Term[]): string {\n return fileOf([...listFrontmatter(terms, true), ...entriesBlock(terms.map((t) => markdownEntry(t.record)))]);\n}\n\nconst XML_DECLARATION = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>';\n\nfunction langAttribute(language: string | undefined): string {\n return language === undefined ? \"\" : ` xml:lang=\"${xmlAttribute(language)}\"`;\n}\n\nexport const markdownWriter = documentWriter({\n format: \"markdown\",\n extension: \".md\",\n file: { holds: LIST_HOLDS, render: markdownList, needsDefinition: true },\n directory: { holds: TERM_FIELDS, render: textPage(\"markdown\") },\n});\n\nexport const mdxWriter = documentWriter({\n format: \"mdx\",\n extension: \".mdx\",\n file: { holds: LIST_HOLDS, render: markdownList, needsDefinition: true },\n directory: { holds: TERM_FIELDS, render: textPage(\"mdx\") },\n});\n\nexport const asciidocWriter = documentWriter({\n format: \"asciidoc\",\n extension: \".adoc\",\n file: {\n holds: LIST_HOLDS,\n needsDefinition: true,\n render: (terms) =>\n fileOf([...listFrontmatter(terms, false), \"[glossary]\", ...entriesBlock(terms.map((t) => asciidocEntry(t.record)))]),\n },\n directory: { holds: TERM_FIELDS, render: textPage(\"asciidoc\") },\n});\n\nexport const rstWriter = documentWriter({\n format: \"rst\",\n extension: \".rst\",\n file: {\n holds: LIST_HOLDS,\n needsDefinition: true,\n render: (terms) =>\n fileOf([\n ...listFrontmatter(terms, false),\n \".. glossary::\",\n \"\",\n ...entriesBlock(\n terms.map((t) => rstEntry(t.record)),\n \" \",\n ),\n ]),\n },\n directory: { holds: TERM_FIELDS, render: textPage(\"rst\") },\n});\n\nexport const htmlWriter = documentWriter({\n format: \"html\",\n extension: \".html\",\n file: {\n holds: LIST_HOLDS,\n needsDefinition: true,\n render: (terms) => {\n const language = sharedLanguage(terms);\n return fileOf([\n \"<!DOCTYPE html>\",\n \"<html>\",\n \" <head>\",\n \" <title>Glossary</title>\",\n ' <meta name=\"type\" content=\"term-set\">',\n ...(language === undefined ? [] : [` <meta name=\"language\" content=\"${xmlAttribute(language)}\">`]),\n \" </head>\",\n \" <body>\",\n \" <dl>\",\n ...markupBlock(terms.map(htmlDlEntry), \" \"),\n \" </dl>\",\n \" </body>\",\n \"</html>\",\n ]);\n },\n },\n directory: { holds: TERM_FIELDS, render: htmlPage },\n});\n\nexport const ditaWriter = documentWriter({\n format: \"dita\",\n extension: \".dita\",\n file: {\n holds: DITA_HOLDS,\n needsDefinition: false,\n render: (terms) =>\n fileOf([\n XML_DECLARATION,\n '<!DOCTYPE glossgroup PUBLIC \"-//OASIS//DTD DITA 2.0 Glossary Group//EN\" \"glossgroup.dtd\">',\n `<glossgroup id=\"glossary\"${langAttribute(sharedLanguage(terms))}>`,\n \" <title>Glossary</title>\",\n ...markupBlock(terms.map((t) => ditaEntry(t)), \" \"),\n \"</glossgroup>\",\n ]),\n },\n directory: {\n holds: DITA_HOLDS,\n render: (term) =>\n fileOf([\n XML_DECLARATION,\n '<!DOCTYPE glossentry PUBLIC \"-//OASIS//DTD DITA 2.0 Glossary Entry//EN\" \"glossentry.dtd\">',\n ditaEntry(term, term.language),\n ]),\n },\n});\n\nexport const docbookWriter = documentWriter({\n format: \"docbook\",\n extension: \".xml\",\n file: {\n holds: DOCBOOK_HOLDS,\n needsDefinition: false,\n render: (terms) =>\n fileOf([\n XML_DECLARATION,\n `<glossary xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\"${langAttribute(sharedLanguage(terms))}>`,\n \" <title>Glossary</title>\",\n ...markupBlock(terms.map(docbookEntry), \" \"),\n \"</glossary>\",\n ]),\n },\n});\n\nexport const DOCUMENT_WRITERS: readonly TermWriter[] = [\n markdownWriter,\n mdxWriter,\n asciidocWriter,\n rstWriter,\n htmlWriter,\n ditaWriter,\n docbookWriter,\n];\n","/**\n * A term page: one term per file, its record in the file's metadata channel\n * and an empty body. The metadata reads `title` (the label), `description`\n * (the abstract, when there is one), `type: term`, `id`, `language` (when the\n * term has one), then every terminology field in the vocabulary's order.\n */\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { extractorByName } from \"../../../meta/internal.js\";\nimport { TermError } from \"../../errors.js\";\nimport { TERM_FIELDS, type Term } from \"../../types.js\";\nimport { fileOf, xmlAttribute, xmlText } from \"./markup.js\";\n\nexport function pageMetadata(term: Term): Record<string, unknown> {\n const { record } = term;\n const metadata: Record<string, unknown> = { title: record.label };\n if (record.abstract !== undefined) metadata[\"description\"] = record.abstract;\n metadata[\"type\"] = \"term\";\n metadata[\"id\"] = term.id;\n if (term.language !== undefined) metadata[\"language\"] = term.language;\n for (const field of TERM_FIELDS) {\n const value = record[field];\n if (value !== undefined) metadata[field] = value;\n }\n return metadata;\n}\n\n/**\n * A Markdown, MDX, AsciiDoc or reStructuredText term page: a fenced YAML block\n * and no body. The block is written by the format's own extractor, the one an\n * in-place write goes through, so a render and a write-back agree on how a\n * value is spelled.\n */\nexport function metadataPage(format: string, term: Term): string {\n const apply = extractorByName(format)?.apply;\n if (apply === undefined) throw new TermError(`manni cannot write ${format} metadata.`);\n return apply(\"---\\n---\\n\", pageMetadata(term));\n}\n\n/** A fenced YAML block, which Markdown, MDX, AsciiDoc and reStructuredText all read. */\nexport function yamlFrontmatter(metadata: Record<string, unknown>): string {\n return `---\\n${stringifyYaml(metadata, { lineWidth: 0 })}---\\n`;\n}\n\n/**\n * A `<meta content>` value as the HTML extractor reads it back: the value is\n * parsed as a YAML scalar, so a string that would parse as anything else, and\n * every list, is written as JSON, which is YAML and stays on one line.\n */\nfunction metaContent(value: unknown): string {\n if (typeof value === \"string\" && !value.includes(\"\\n\")) {\n try {\n if (parseYaml(value) === value) return value;\n } catch {\n // Not plain YAML: JSON below.\n }\n }\n return JSON.stringify(value);\n}\n\nexport function htmlPage(term: Term): string {\n const metadata = pageMetadata(term);\n const metas = Object.entries(metadata)\n .filter(([key]) => key !== \"title\")\n .map(([key, value]) => ` <meta name=\"${xmlAttribute(key)}\" content=\"${xmlAttribute(metaContent(value))}\">`);\n return fileOf([\n \"<!DOCTYPE html>\",\n \"<html>\",\n \" <head>\",\n ` <title>${xmlText(term.record.label)}</title>`,\n ...metas,\n \" </head>\",\n \" <body></body>\",\n \"</html>\",\n ]);\n}\n","/**\n * `term write -f csv`: one row per id, for a translation or terminology\n * system to import. The headers describe themselves, so a system maps columns\n * by name: `ID`, then six columns per language the set holds, each filled\n * from that language's term, then the four language-neutral relation columns,\n * which take the first term's value.\n */\nimport type { MergeConflict, Term, TermField, TermRecord, TermShape, TermWriter } from \"../../types.js\";\nimport { conceptGroups, mergeFirst } from \"./merge.js\";\nimport { droppedFields, languageKey, languageOf, requireShape } from \"./render-util.js\";\n\n/** The fields the columns hold: the ten of terminology 1.0.0. Every other field is reported dropped. */\nconst HOLDS = [\n \"label\",\n \"definition\",\n \"abstract\",\n \"alt-labels\",\n \"hidden-labels\",\n \"broader\",\n \"narrower\",\n \"related-terms\",\n \"see\",\n \"scope-note\",\n] as const satisfies readonly TermField[];\ntype CsvField = (typeof HOLDS)[number];\n\n/** The per-language columns, in order, with their header names. */\nconst LANGUAGE_COLUMNS: readonly (readonly [CsvField, string])[] = [\n [\"label\", \"Term\"],\n [\"definition\", \"Definition\"],\n [\"abstract\", \"Abstract\"],\n [\"alt-labels\", \"Alt labels\"],\n [\"hidden-labels\", \"Hidden labels\"],\n [\"scope-note\", \"Scope note\"],\n];\n\n/** The columns every language shares: they name other terms, not words in a language. */\nconst NEUTRAL_COLUMNS: readonly (readonly [CsvField, string])[] = [\n [\"broader\", \"Broader\"],\n [\"narrower\", \"Narrower\"],\n [\"related-terms\", \"Related terms\"],\n [\"see\", \"See\"],\n];\n\n/**\n * The one separator a list field is joined with inside its cell. A value that\n * itself contains ` | ` cannot be split back apart; that is the price of one\n * cell per field, which is what a translation system imports.\n */\nconst LIST_SEPARATOR = \" | \";\n\n/** RFC 4180 quoting: a cell holding a quote, comma or line break is quoted, with quotes doubled. */\nfunction cell(value: string): string {\n return /[\",\\r\\n]/.test(value) ? `\"${value.replaceAll('\"', '\"\"')}\"` : value;\n}\n\nfunction fieldText(record: Partial<Pick<TermRecord, CsvField>>, field: CsvField): string {\n const value = record[field];\n if (value === undefined) return \"\";\n return typeof value === \"string\" ? value : value.join(LIST_SEPARATOR);\n}\n\n/**\n * The set joined on id: one row per id, holding at most one term per\n * language. A second term with an id and language a row already holds starts\n * a row of its own, so a repeated id in one language is written, not lost.\n */\nfunction rowsOf(terms: readonly Term[]): Term[][] {\n return conceptGroups(terms).flatMap((group) => {\n const rows: Term[][] = [];\n for (const term of group) {\n const row = rows.find((r) => !r.some((t) => languageKey(t) === languageKey(term)));\n if (row === undefined) rows.push([term]);\n else row.push(term);\n }\n return rows;\n });\n}\n\nexport const csvWriter: TermWriter = {\n format: \"csv\",\n shapes: [\"file\"],\n holds: (_shape: TermShape) => HOLDS,\n render(terms, target) {\n requireShape(\"csv\", target, \"file\");\n // Languages in order of first appearance, so the columns follow the set.\n const languages = new Map<string, string>();\n for (const term of terms) {\n if (!languages.has(languageKey(term))) languages.set(languageKey(term), languageOf(term));\n }\n\n const header = [\n \"ID\",\n ...[...languages.values()].flatMap((language) => LANGUAGE_COLUMNS.map(([, name]) => `${name} [${language}]`)),\n ...NEUTRAL_COLUMNS.map(([, name]) => name),\n ];\n const conflicts: MergeConflict[] = [];\n const rows = rowsOf(terms).map((row) => {\n const [first] = row;\n const id = first?.id ?? \"\";\n // The neutral columns name other terms, so the row holds them once.\n const neutral = mergeFirst(\n id,\n row.map((t) => Object.fromEntries(NEUTRAL_COLUMNS.map(([field]) => [field, t.record[field]]))),\n );\n conflicts.push(...neutral.conflicts);\n return [\n id,\n ...[...languages.keys()].flatMap((language) => {\n const own = row.find((t) => languageKey(t) === language);\n return LANGUAGE_COLUMNS.map(([field]) => (own === undefined ? \"\" : fieldText(own.record, field)));\n }),\n ...NEUTRAL_COLUMNS.map(([field]) => fieldText(neutral.merged, field)),\n ];\n });\n\n const content = [header, ...rows].map((row) => `${row.map(cell).join(\",\")}\\n`).join(\"\");\n return {\n files: [{ path: target.path, content }],\n removals: [],\n dropped: droppedFields(terms, HOLDS),\n skipped: [],\n ...(conflicts.length === 0 ? {} : { conflicts }),\n };\n },\n};\n","/**\n * `term write -f json`: the set as `{ \"terms\": [...] }`, one object per term\n * holding its id, its language when it has one, and every record field in the\n * vocabulary's order. It is the shape `term list -f json` prints, so it holds\n * every field.\n */\nimport { TERM_FIELDS, type TermShape, type TermWriter } from \"../../types.js\";\nimport { droppedFields, requireShape } from \"./render-util.js\";\n\nexport const jsonWriter: TermWriter = {\n format: \"json\",\n shapes: [\"file\"],\n holds: (_shape: TermShape) => TERM_FIELDS,\n render(terms, target) {\n requireShape(\"json\", target, \"file\");\n const entries = terms.map((term) => {\n const entry: Record<string, unknown> = { id: term.id };\n if (term.language !== undefined) entry[\"language\"] = term.language;\n for (const field of TERM_FIELDS) {\n const value = term.record[field];\n if (value !== undefined) entry[field] = value;\n }\n return entry;\n });\n const content = `${JSON.stringify({ terms: entries }, null, 2)}\\n`;\n return {\n files: [{ path: target.path, content }],\n removals: [],\n dropped: droppedFields(terms, TERM_FIELDS),\n skipped: [],\n };\n },\n};\n","/**\n * `term write -f skos`: the set as a SKOS concept scheme in JSON-LD. The\n * document is the scheme, and each term is a concept at `#<id>` within it.\n *\n * A relation (`broader`, `narrower`, `related-terms`) names another term by\n * label or id, and becomes a reference to that concept. A value naming no term\n * is left out: a dangling reference is `check`'s finding, not a field this\n * format cannot hold.\n */\nimport type { Term, TermField, TermShape, TermWriter } from \"../../types.js\";\nimport { droppedFields, requireShape } from \"./render-util.js\";\n\nconst HOLDS: readonly TermField[] = [\n \"label\",\n \"definition\",\n \"alt-labels\",\n \"hidden-labels\",\n \"broader\",\n \"narrower\",\n \"related-terms\",\n \"scope-note\",\n];\n\nconst CONTEXT = {\n skos: \"http://www.w3.org/2004/02/skos/core#\",\n dcterms: \"http://purl.org/dc/terms/\",\n};\n\n/** The scheme's `@id`: the document itself, which the concepts' `#<id>` fragments sit in. */\nconst SCHEME_ID = \"\";\n\ntype Literal = string | { \"@value\": string; \"@language\": string };\n\nfunction literal(term: Term, value: string): Literal {\n return term.language === undefined ? value : { \"@value\": value, \"@language\": term.language };\n}\n\n/** The term a relation value names: a label first, then an id, compared case-insensitively. Never `self`. */\nfunction resolve(terms: readonly Term[], self: Term, value: string): Term | undefined {\n const wanted = value.toLowerCase();\n const others = terms.filter((t) => t !== self);\n return (\n others.find((t) => t.record.label.toLowerCase() === wanted) ?? others.find((t) => t.id.toLowerCase() === wanted)\n );\n}\n\nfunction references(terms: readonly Term[], self: Term, values: readonly string[] | undefined): { \"@id\": string }[] {\n const ids: string[] = [];\n for (const value of values ?? []) {\n const target = resolve(terms, self, value);\n if (target !== undefined && !ids.includes(target.id)) ids.push(target.id);\n }\n return ids.map((id) => ({ \"@id\": `#${id}` }));\n}\n\nfunction concept(terms: readonly Term[], term: Term): Record<string, unknown> {\n const { record } = term;\n const node: Record<string, unknown> = {\n \"@id\": `#${term.id}`,\n \"@type\": \"skos:Concept\",\n \"skos:inScheme\": { \"@id\": SCHEME_ID },\n \"skos:prefLabel\": literal(term, record.label),\n };\n if (record[\"alt-labels\"] !== undefined) node[\"skos:altLabel\"] = record[\"alt-labels\"].map((v) => literal(term, v));\n if (record[\"hidden-labels\"] !== undefined) {\n node[\"skos:hiddenLabel\"] = record[\"hidden-labels\"].map((v) => literal(term, v));\n }\n if (record.definition !== undefined) node[\"skos:definition\"] = literal(term, record.definition);\n if (record[\"scope-note\"] !== undefined) node[\"skos:scopeNote\"] = literal(term, record[\"scope-note\"]);\n const relations = [\n [\"skos:broader\", record.broader],\n [\"skos:narrower\", record.narrower],\n [\"skos:related\", record[\"related-terms\"]],\n ] as const;\n for (const [key, values] of relations) {\n const refs = references(terms, term, values);\n if (refs.length > 0) node[key] = refs;\n }\n return node;\n}\n\nexport const skosWriter: TermWriter = {\n format: \"skos\",\n shapes: [\"file\"],\n holds: (_shape: TermShape) => HOLDS,\n render(terms, target) {\n requireShape(\"skos\", target, \"file\");\n const document = {\n \"@context\": CONTEXT,\n \"@graph\": [\n {\n \"@id\": SCHEME_ID,\n \"@type\": \"skos:ConceptScheme\",\n \"dcterms:description\": \"Generated by manni term write.\",\n },\n ...terms.map((term) => concept(terms, term)),\n ],\n };\n const content = `${JSON.stringify(document, null, 2)}\\n`;\n return {\n files: [{ path: target.path, content }],\n removals: [],\n dropped: droppedFields(terms, HOLDS),\n skipped: [],\n };\n },\n};\n","/**\n * `term write -f tbx` and `-f tbx3`: the set as a TBX v2 (`<martif>`) or v3\n * (`<tbx>`) termbase, the exchange format translation memory and terminology\n * systems import (proposal 0084).\n *\n * One entry per id, in first-appearance order, with a language section per\n * term in set order, written in `tbx-model.ts`'s canonical form. Where terms\n * sharing an id disagree on `concept-entry`, the first term's value is kept\n * and the render reports it.\n *\n * The header depends on where the terms came from:\n * - all from one TBX file, at the version `-f` names: that file, with\n * unchanged entries and everything outside them copied byte for byte;\n * - all from one TBX file at the other version: canonical entries, under a\n * header holding the source header's children, and the source's back\n * matter after them, `refObjectList` (v2) renamed `refObjectSec` (v3) or\n * back, since entries' `target`s point into it;\n * - anything else: manni's own header, and each TBX source is reported as a\n * header dropped.\n */\nimport { TERM_FIELDS, type MergeConflict, type Term, type TermField, type TermShape, type TermWriter } from \"../../types.js\";\nimport { exportTbxSource } from \"../readers/tbx.js\";\nimport {\n TBX_V3_NAMESPACE,\n escapeAttribute,\n lf,\n tbxEntryLines,\n tbxSourceOf,\n type TbxDocument,\n type TbxVersion,\n} from \"../readers/tbx-model.js\";\nimport { reindent } from \"./markup.js\";\nimport { conceptGroups, mergeFirst } from \"./merge.js\";\nimport { DEFAULT_LANGUAGE, droppedFields, requireShape } from \"./render-util.js\";\n\n/** TBX-Basic has no category for these. */\nconst NOT_HELD: readonly TermField[] = [\"abstract\", \"broader\", \"narrower\", \"related-terms\", \"see\", \"scope-note\"];\nconst HOLDS: readonly TermField[] = TERM_FIELDS.filter((field) => !NOT_HELD.includes(field));\n\n/** The designation fields only TBX-Linguist defines. A v3 file carrying one declares itself TBX-Linguist. */\nconst LINGUIST_FIELDS = [\"register\", \"reading\", \"reading-note\", \"grammatical-number\", \"transfer-comments\"] as const;\n\n/** Where the body's entries start: inside `<text><body>`. */\nconst ENTRY_INDENT = \" \";\n\n/** manni's own header content, at the header's children's indentation. */\nconst OWN_HEADER = [\" <fileDesc>\", \" <sourceDesc>\", \" <p>manni term write</p>\", \" </sourceDesc>\", \" </fileDesc>\"];\n\nfunction isLinguist(terms: readonly Term[]): boolean {\n return terms.some((t) => (t.record.designations ?? []).some((d) => LINGUIST_FIELDS.some((f) => d[f] !== undefined)));\n}\n\n/** The TBX document every term was read from, when there is one and only one. */\nfunction soleSource(terms: readonly Term[]): { document: TbxDocument; file: string } | undefined {\n let found: { document: TbxDocument; file: string } | undefined;\n for (const term of terms) {\n const source = tbxSourceOf(term);\n if (source === undefined || (found !== undefined && found.document !== source.document)) return undefined;\n found ??= { document: source.document, file: term.location.file };\n }\n return found?.document.body === undefined ? undefined : found;\n}\n\n/** The TBX files the terms came from, as their terms name them, in order of first appearance. */\nexport function tbxHeaderFiles(terms: readonly Term[]): string[] {\n const files = new Map<TbxDocument, string>();\n for (const term of terms) {\n const source = tbxSourceOf(term);\n if (source !== undefined && !files.has(source.document)) files.set(source.document, term.location.file);\n }\n return [...files.values()];\n}\n\n/**\n * An element's children from the source, at `indent` and LF, or `undefined`\n * when it has none. Blank lines around them are trimmed, and one between them\n * is kept, empty.\n */\nfunction carried(document: TbxDocument, span: { start: number; end: number } | undefined, indent: string): string[] | undefined {\n if (span === undefined) return undefined;\n const raw = lf(document.content.slice(span.start, span.end));\n if (raw.trim() === \"\") return undefined;\n const lines = raw.replace(/^(?:[ \\t]*\\n)+/, \"\").replace(/(?:\\n[ \\t]*)+$/, \"\").split(\"\\n\");\n const blank = (line: string): boolean => line.trim() === \"\";\n const strip = Math.min(...lines.filter((line) => !blank(line)).map((line) => /^[ \\t]*/.exec(line)?.[0].length ?? 0));\n return lines.map((line) => (blank(line) ? \"\" : `${indent}${line.slice(strip).trimEnd()}`));\n}\n\n/** The source's `<back>` at the other version: the one element v3 renamed is renamed, and the rest is carried as it is. */\nfunction carriedBack(document: TbxDocument, version: TbxVersion): string[] {\n if (document.back === undefined) return [];\n const [from, to] = version === 3 ? [\"refObjectList\", \"refObjectSec\"] : [\"refObjectSec\", \"refObjectList\"];\n const rename = new RegExp(`(</?)${from}(?=[\\\\s/>])`, \"g\");\n const lines = carried(document, document.back, \" \")?.map((line) => line.replace(rename, `$1${to}`));\n return lines === undefined ? [\" <back/>\"] : [\" <back>\", ...lines, \" </back>\"];\n}\n\n/** Every entry, canonical, at the body's indentation; and where terms sharing an id disagree on `concept-entry`. */\nfunction entries(terms: readonly Term[], version: TbxVersion): { lines: string[]; conflicts: MergeConflict[] } {\n const lines: string[] = [];\n const conflicts: MergeConflict[] = [];\n for (const group of conceptGroups(terms)) {\n const [head, ...rest] = group;\n if (head === undefined) continue;\n const merge = mergeFirst(\n head.id,\n group.map((t) => t.record[\"concept-entry\"]),\n \"concept-entry.\",\n );\n conflicts.push(...merge.conflicts);\n const { \"concept-entry\": _concept, ...record } = head.record;\n const joined: Term = {\n ...head,\n record: Object.keys(merge.merged).length === 0 ? record : { ...record, \"concept-entry\": merge.merged },\n };\n const text = tbxEntryLines([joined, ...rest], { version, style: \"dca\" }).join(\"\\n\");\n lines.push(`${ENTRY_INDENT}${reindent(text, ENTRY_INDENT, \"\\n\")}`);\n }\n return { lines, conflicts };\n}\n\nfunction rootOpen(version: TbxVersion, terms: readonly Term[]): string {\n // The file's default language is the first term's; each language section states its own anyway.\n const language = escapeAttribute(terms[0]?.language ?? DEFAULT_LANGUAGE);\n if (version === 2) return `<martif type=\"TBX\" xml:lang=\"${language}\">`;\n const type = isLinguist(terms) ? \"TBX-Linguist\" : \"TBX-Basic\";\n return `<tbx type=\"${type}\" style=\"dca\" xml:lang=\"${language}\" xmlns=\"${TBX_V3_NAMESPACE}\">`;\n}\n\nfunction tbxWriterFor(format: \"tbx\" | \"tbx3\", version: TbxVersion): TermWriter {\n return {\n format,\n shapes: [\"file\"],\n holds: (_shape: TermShape) => HOLDS,\n render(terms, target) {\n requireShape(format, target, \"file\");\n const dropped = droppedFields(terms, HOLDS);\n const source = soleSource(terms);\n if (source?.document.version === version) {\n const exported = exportTbxSource(source.document, source.file, terms);\n return {\n files: [{ path: target.path, content: exported.content }],\n removals: [],\n dropped,\n skipped: [],\n ...(exported.conflicts.length === 0 ? {} : { conflicts: exported.conflicts }),\n droppedHeaders: [],\n };\n }\n const header = (source === undefined ? undefined : carried(source.document, source.document.header, \" \")) ?? OWN_HEADER;\n const [root, headerTag] = version === 2 ? [\"martif\", \"martifHeader\"] : [\"tbx\", \"tbxHeader\"];\n const body = entries(terms, version);\n const lines = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n rootOpen(version, terms),\n ` <${headerTag}>`,\n ...header,\n ` </${headerTag}>`,\n \" <text>\",\n \" <body>\",\n ...body.lines,\n \" </body>\",\n ...(source === undefined ? [] : carriedBack(source.document, version)),\n \" </text>\",\n `</${root}>`,\n ];\n return {\n files: [{ path: target.path, content: lines.map((line) => `${line}\\n`).join(\"\") }],\n removals: [],\n dropped,\n skipped: [],\n ...(body.conflicts.length === 0 ? {} : { conflicts: body.conflicts }),\n droppedHeaders: source === undefined ? tbxHeaderFiles(terms) : [],\n };\n },\n };\n}\n\nexport const tbxWriter = tbxWriterFor(\"tbx\", 2);\nexport const tbx3Writer = tbxWriterFor(\"tbx3\", 3);\n","/**\n * `term write -f vale`: a Vale style named `Terms`, written into a styles\n * directory (proposal 0052 § 6). Every rule shape here was chosen against a\n * real Vale 3.20.0 run.\n *\n * - `Terms/Casing.yml` enforces the exact form of a designation that starts\n * with a capital or a non-letter: `Kubernetes`, `K8s`, `.Net`.\n * - `Terms/Lowercase.yml` enforces an all-lowercase designation, allowing a\n * capital first letter so a sentence can start with it.\n * - `Terms/SentenceStart.yml` enforces a designation that starts lowercase and\n * holds a capital later (`iPhone`, `meta-schema URI`), allowing a capital\n * first letter the same way.\n * - `Terms/Deprecated.yml` swaps each hidden-label for its term's label.\n * - `Terms/<ACRONYM>.yml` asks for an all-caps alt-label to be spelled out on\n * first use, as `<label> (<ACRONYM>)`.\n *\n * An all-caps designation gets no casing rule: enforcing the case of `IT` fires\n * on nearly every paragraph. manni owns `Terms/`: every file opens with the\n * marker line, a file without it is someone else's and stops the write, and a\n * marked file the set no longer produces is removed.\n */\nimport { isAbsolute, join, relative, sep } from \"node:path\";\nimport { stringify } from \"yaml\";\nimport { TermError } from \"../../errors.js\";\nimport type { RenderedFile, TermField, TermShape, TermWriter } from \"../../types.js\";\nimport { droppedFields, requireShape } from \"./render-util.js\";\n\nexport const VALE_MARKER = \"# Generated by manni term write. Edit the terms, not this file.\";\nconst STYLE = \"Terms\";\nconst HOLDS: readonly TermField[] = [\"label\", \"alt-labels\", \"hidden-labels\"];\n/** The style's own files, which an acronym file may not replace. */\nconst OWN_FILES = [\"Casing\", \"Lowercase\", \"SentenceStart\", \"Deprecated\"] as const;\n\nconst REGEX_METACHARACTERS = /[\\\\^$.|?*+()[\\]{}]/g;\n\nfunction escapeRegex(value: string): string {\n return value.replace(REGEX_METACHARACTERS, \"\\\\$&\");\n}\n\n/**\n * A swap value as Vale reads it. Vale matches the value as a pattern against\n * the text it found, so a value holding a metacharacter is escaped, and only\n * then: the `%s` in the message prints the value, so the escape shows in that\n * message (`Use 'C\\+\\+' instead of 'c++'`). An exact message is worth more for\n * the common case than for the rare one.\n */\nfunction swapValue(value: string): string {\n return value.search(REGEX_METACHARACTERS) === -1 ? value : escapeRegex(value);\n}\n\n/**\n * A YAML scalar Vale's parser reads back as the same string. YAML 1.1 rules\n * quote `yes`, `on` and friends, which a 1.1 parser would read as booleans.\n * A line break cannot sit in a one-line key, so such a string is written as a\n * JSON string, which is valid double-quoted YAML.\n */\nfunction scalar(value: string): string {\n if (/[\\r\\n]/.test(value)) return JSON.stringify(value);\n const out = stringify(value, { version: \"1.1\", lineWidth: 0 });\n return out.endsWith(\"\\n\") ? out.slice(0, -1) : out;\n}\n\n/** A YAML double-quoted scalar on one line: a raw line break would fold to a space. */\nfunction doubleQuoted(value: string): string {\n const escaped = value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll('\"', '\\\\\"')\n .replaceAll(\"\\n\", \"\\\\n\")\n .replaceAll(\"\\r\", \"\\\\r\");\n return `\"${escaped}\"`;\n}\n\n/** A YAML single-quoted scalar, which keeps backslashes literal for a regex. */\nfunction singleQuoted(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\").replaceAll(/[\\r\\n]+/g, \" \")}'`;\n}\n\n/** Vale formats a message with Go's `fmt`, so a literal `%` is doubled. */\nfunction messageText(value: string): string {\n return value.replaceAll(\"%\", \"%%\");\n}\n\ntype Casing = \"none\" | \"all-caps\" | \"lowercase\" | \"lowercase-initial\" | \"mixed\";\n\nfunction casingOf(value: string): Casing {\n if (!/[\\p{Lu}\\p{Ll}\\p{Lt}]/u.test(value)) return \"none\";\n const letters = value.match(/\\p{L}/gu)?.length ?? 0;\n if (letters >= 2 && !/[\\p{Ll}\\p{Lt}]/u.test(value)) return \"all-caps\";\n if (!/[\\p{Lu}\\p{Lt}]/u.test(value)) return \"lowercase\";\n // `iPhone`: a mixed designation whose first character is a lowercase letter.\n if (/^\\p{Ll}/u.test(value)) return \"lowercase-initial\";\n return \"mixed\";\n}\n\n/** `progressive lens` → `[Pp]rogressive lens`: the first letter may be a capital, to start a sentence. */\nfunction sentenceStartPattern(value: string): string {\n const [first = \"\", ...rest] = Array.from(value);\n const upper = first.toUpperCase();\n const head = upper !== first && Array.from(upper).length === 1 ? `[${upper}${first}]` : escapeRegex(first);\n return `${head}${escapeRegex(rest.join(\"\"))}`;\n}\n\n/** A swap list in insertion order. A key already present keeps its first value, as YAML allows one. */\nclass Swaps {\n private readonly entries = new Map<string, string>();\n add(key: string, value: string): void {\n if (!this.entries.has(key)) this.entries.set(key, value);\n }\n get size(): number {\n return this.entries.size;\n }\n lines(): string[] {\n return [...this.entries].map(([key, value]) => ` ${scalar(key)}: ${scalar(value)}`);\n }\n}\n\n/**\n * A swap key with its own word boundaries. Vale wraps every key in `\\b…\\b`\n * unless a rule sets `nonword`, and Go regular expressions give `\\b` ASCII\n * word semantics. So a term whose first or last character is not an ASCII word\n * character never matched: `c++` before a space, `Café` before a full stop. A\n * real Vale 3.20.0 run confirmed `c++` went unflagged. Each edge is `\\b` beside\n * an ASCII word character and `\\B` beside anything else, which is exactly\n * Vale's default for an ordinary word and the right boundary for the rest.\n */\nconst ASCII_WORD = /^[A-Za-z0-9_]$/;\n\nfunction bounded(pattern: string, text: string): string {\n const chars = Array.from(text);\n const edge = (char: string | undefined): string =>\n char !== undefined && ASCII_WORD.test(char) ? \"\\\\b\" : \"\\\\B\";\n return `${edge(chars[0])}${pattern}${edge(chars.at(-1))}`;\n}\n\nfunction substitution(message: string, level: string, options: string[], swaps: Swaps): string {\n return [\n VALE_MARKER,\n \"extends: substitution\",\n `message: ${doubleQuoted(message)}`,\n `level: ${level}`,\n \"ignorecase: true\",\n \"nonword: true\",\n ...options,\n \"swap:\",\n ...swaps.lines(),\n ]\n .map((line) => `${line}\\n`)\n .join(\"\");\n}\n\nfunction acronymRule(acronym: string, label: string): string {\n const expansion = escapeRegex(label).replaceAll(/[\\r\\n]+/g, \" \");\n return [\n VALE_MARKER,\n \"extends: conditional\",\n `message: ${doubleQuoted(messageText(`Spell out '${acronym}' on first use, as '${label} (${acronym})'.`))}`,\n \"level: warning\",\n \"ignorecase: false\",\n `first: ${singleQuoted(`\\\\b(${escapeRegex(acronym)})\\\\b`)}`,\n `second: ${singleQuoted(`(?i)${expansion} \\\\((${escapeRegex(acronym)})\\\\)`)}`,\n ]\n .map((line) => `${line}\\n`)\n .join(\"\");\n}\n\n/** An acronym as a file name: anything a path or a Vale rule name cannot carry becomes `-`. */\nfunction acronymFileName(acronym: string): string {\n return acronym.replaceAll(/[^\\p{L}\\p{N}_-]/gu, \"-\");\n}\n\nfunction firstLine(content: string): string {\n const end = content.search(/\\r?\\n/);\n return end === -1 ? content : content.slice(0, end);\n}\n\nexport const valeWriter: TermWriter = {\n format: \"vale\",\n shapes: [\"directory\"],\n holds: (_shape: TermShape) => HOLDS,\n render(terms, target, context) {\n requireShape(\"vale\", target, \"directory\");\n const termsDir = join(target.path, STYLE);\n\n // Someone else's file in Terms/ stops the write before anything is computed.\n const marked: string[] = [];\n for (const [path, content] of context.existing) {\n const rel = relative(termsDir, path);\n if (rel === \"\" || rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) continue;\n if (firstLine(content) !== VALE_MARKER) {\n throw new TermError(`${path} was not written by manni. Move it, or pass -o <styles directory>.`);\n }\n if (!rel.includes(sep) && !rel.includes(\"/\")) marked.push(path);\n }\n\n const casing = new Swaps();\n const lowercase = new Swaps();\n const sentenceStart = new Swaps();\n const deprecated = new Swaps();\n const acronyms: { acronym: string; name: string; content: string }[] = [];\n const labels = new Set(terms.map((t) => t.record.label));\n\n for (const term of terms) {\n const { label } = term.record;\n const labelIsAllCaps = casingOf(label) === \"all-caps\";\n for (const designation of [label, ...(term.record[\"alt-labels\"] ?? [])]) {\n const kind = casingOf(designation);\n if (kind === \"lowercase\") lowercase.add(bounded(escapeRegex(designation), designation), sentenceStartPattern(designation));\n if (kind === \"lowercase-initial\") {\n sentenceStart.add(bounded(escapeRegex(designation.toLowerCase()), designation), sentenceStartPattern(designation));\n }\n if (kind === \"mixed\") casing.add(bounded(escapeRegex(designation.toLowerCase()), designation), swapValue(designation));\n if (kind !== \"all-caps\" || designation === label || labelIsAllCaps || labels.has(designation)) continue;\n const name = acronymFileName(designation);\n const own = OWN_FILES.find((file) => file.toLowerCase() === name.toLowerCase());\n if (own !== undefined) {\n throw new TermError(`the acronym \"${designation}\" would replace Terms/${own}.yml. Rename the alt-label.`);\n }\n const taken = acronyms.find((a) => a.name.toLowerCase() === name.toLowerCase());\n // The same acronym on a second term keeps the first term's rule.\n if (taken?.acronym === designation) continue;\n if (taken !== undefined) {\n throw new TermError(\n `the acronyms \"${taken.acronym}\" and \"${designation}\" would both write Terms/${taken.name}.yml. Rename one.`,\n );\n }\n acronyms.push({ acronym: designation, name, content: acronymRule(designation, label) });\n }\n for (const hidden of term.record[\"hidden-labels\"] ?? []) {\n deprecated.add(bounded(escapeRegex(hidden), hidden), swapValue(label));\n }\n }\n\n const files: RenderedFile[] = [];\n const add = (name: string, content: string): void => {\n files.push({ path: join(termsDir, `${name}.yml`), content });\n };\n if (casing.size > 0) {\n add(\"Casing\", substitution(\"Use '%s' instead of '%s'.\", \"error\", [\"vocab: false\"], casing));\n }\n if (lowercase.size > 0) {\n add(\n \"Lowercase\",\n substitution(\"Write '%[2]s' in lowercase, except to start a sentence.\", \"error\", [\"vocab: false\"], lowercase),\n );\n }\n if (sentenceStart.size > 0) {\n // Not Casing.yml: its message prints the value, which here is a pattern.\n add(\n \"SentenceStart\",\n substitution(\n \"Write '%[2]s' as the term list spells it, with a capital only to start a sentence.\",\n \"error\",\n [\"vocab: false\"],\n sentenceStart,\n ),\n );\n }\n if (deprecated.size > 0) {\n add(\"Deprecated\", substitution(\"Use '%s' instead of '%s'.\", \"warning\", [\"matchcase: true\"], deprecated));\n }\n for (const acronym of acronyms) add(acronym.name, acronym.content);\n\n // Compared without case: on a case-insensitive disk `pal.yml` and `PAL.yml`\n // are one file, and removing the old name would delete the new one.\n const produced = new Set(files.map((f) => relative(termsDir, f.path).toLowerCase()));\n const removals = marked.filter((path) => !produced.has(relative(termsDir, path).toLowerCase())).sort();\n\n return { files, removals, dropped: droppedFields(terms, HOLDS), skipped: [] };\n },\n};\n","/**\n * Writers for the formats a termbase leaves the docs in: TBX v2 and v3, SKOS, CSV, JSON,\n * and a Vale style.\n */\nimport type { TermWriter } from \"../../types.js\";\nimport { csvWriter } from \"./csv.js\";\nimport { jsonWriter } from \"./json.js\";\nimport { skosWriter } from \"./skos.js\";\nimport { tbx3Writer, tbxWriter } from \"./tbx.js\";\nimport { valeWriter } from \"./vale.js\";\n\nexport const INTERCHANGE_WRITERS: readonly TermWriter[] = [tbxWriter, tbx3Writer, skosWriter, csvWriter, jsonWriter, valeWriter];\n","/** Every term writer, one per `term write -f` value. */\nimport type { TermWriteFormat, TermWriter } from \"../../types.js\";\nimport { DOCUMENT_WRITERS } from \"./documents.js\";\nimport { INTERCHANGE_WRITERS } from \"./interchange.js\";\n\nexport const TERM_WRITERS: readonly TermWriter[] = [...DOCUMENT_WRITERS, ...INTERCHANGE_WRITERS];\n\nexport function writerFor(\n format: TermWriteFormat,\n writers: readonly TermWriter[] = TERM_WRITERS,\n): TermWriter | undefined {\n return writers.find((writer) => writer.format === format);\n}\n","/**\n * `manni term formats`: what is read and written, from the registries alone. A\n * construct a reader does not exist for is not listed, and `write` appears\n * only where a reader has `apply` or a registered document writer renders the\n * construct, so the listing never promises more than the build does.\n */\nimport { TERM_READERS } from \"../core/readers/index.js\";\nimport { TERM_WRITERS } from \"../core/writers/index.js\";\nimport type { TermConstruct, TermReader, TermShape, TermWriteFormat, TermWriter } from \"../types.js\";\n\nexport const FORMATS_FORMATS = [\"pretty\", \"json\"] as const;\nexport type FormatsFormat = (typeof FORMATS_FORMATS)[number];\n\nexport interface FormatRow {\n /** The input format a reader reads (`markdown`, `xml`), or a `write -f` value. */\n format: string;\n /** The construct, for a reader's row. */\n construct?: TermConstruct;\n /** What the construct or the render is called: `definition list`, `TBX v2`; empty for none. */\n label: string;\n read: boolean;\n write: boolean;\n}\n\n/**\n * The construct each document `-f` value renders, per shape, and the input\n * format that construct is read back from. A directory holds one entry per\n * file, which is a page; a file holds them all, in the format's list construct.\n */\nexport const DOCUMENT_RENDERS: Partial<\n Record<TermWriteFormat, { input: string; shapes: Partial<Record<TermShape, TermConstruct>> }>\n> = {\n markdown: { input: \"markdown\", shapes: { directory: \"page\", file: \"markdown-deflist\" } },\n mdx: { input: \"mdx\", shapes: { directory: \"page\", file: \"markdown-deflist\" } },\n asciidoc: { input: \"asciidoc\", shapes: { directory: \"page\", file: \"asciidoc-glossary\" } },\n rst: { input: \"rst\", shapes: { directory: \"page\", file: \"rst-glossary\" } },\n html: { input: \"html\", shapes: { directory: \"page\", file: \"html-dl\" } },\n dita: { input: \"xml\", shapes: { directory: \"dita-glossentry\", file: \"dita-glossgroup\" } },\n docbook: { input: \"xml\", shapes: { file: \"docbook-glossary\" } },\n};\n\n/** What `formats` calls an interchange render. */\nconst INTERCHANGE_LABELS: Partial<Record<TermWriteFormat, string>> = {\n tbx: \"TBX v2\",\n tbx3: \"TBX v3\",\n skos: \"JSON-LD\",\n vale: \"style\",\n};\n\nfunction rendered(writers: readonly TermWriter[], format: string, construct: TermConstruct): boolean {\n return writers.some((writer) => {\n const render = DOCUMENT_RENDERS[writer.format];\n if (render?.input !== format) return false;\n return writer.shapes.some((shape) => render.shapes[shape] === construct);\n });\n}\n\nexport function listFormats(\n opts: { readers?: readonly TermReader[]; writers?: readonly TermWriter[] } = {},\n): FormatRow[] {\n const readers = opts.readers ?? TERM_READERS;\n const writers = opts.writers ?? TERM_WRITERS;\n\n // Input formats in order of first appearance, then each format's readers in registry order.\n const formats: string[] = [];\n for (const reader of readers) {\n for (const format of reader.formats) if (!formats.includes(format)) formats.push(format);\n }\n const rows: FormatRow[] = [];\n for (const format of formats) {\n for (const reader of readers.filter((r) => r.formats.includes(format))) {\n rows.push({\n format,\n construct: reader.construct,\n label: reader.label,\n read: true,\n write: reader.apply !== undefined || rendered(writers, format, reader.construct),\n });\n }\n }\n for (const writer of writers) {\n if (DOCUMENT_RENDERS[writer.format] !== undefined) continue;\n rows.push({ format: writer.format, label: INTERCHANGE_LABELS[writer.format] ?? \"\", read: false, write: true });\n }\n return rows;\n}\n","/**\n * `manni term get <term>`: one entry, matched by id, else by label without\n * case, else by alt-label without case. A miss is a usage error that says how\n * big the set is and, when some id or label is a few edits away, which one,\n * because a typo is the likely cause.\n */\nimport { TermError } from \"../errors.js\";\nimport type { Term } from \"../types.js\";\nimport { loadTerms, plural, type TermCommandOptions } from \"./run.js\";\n\nexport const GET_FORMATS = [\"pretty\", \"json\"] as const;\nexport type GetFormat = (typeof GET_FORMATS)[number];\n\nexport interface GetOptions extends TermCommandOptions {\n /** The `<term>` argument: an id, a label or an alt-label. */\n term: string;\n}\n\n/**\n * The entry `query` names: an exact id first, then a label compared without\n * case, then an alt-label compared without case. Each pass takes the first\n * entry in set order.\n */\nexport function findTerm(terms: readonly Term[], query: string): Term | undefined {\n const folded = query.toLowerCase();\n return (\n terms.find((t) => t.id === query) ??\n terms.find((t) => t.record.label.toLowerCase() === folded) ??\n terms.find((t) => (t.record[\"alt-labels\"] ?? []).some((alt) => alt.toLowerCase() === folded))\n );\n}\n\n/** Levenshtein distance. */\nfunction editDistance(a: string, b: string): number {\n let prev = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i++) {\n const row = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n row.push(Math.min((row[j - 1] ?? 0) + 1, (prev[j] ?? 0) + 1, (prev[j - 1] ?? 0) + cost));\n }\n prev = row;\n }\n return prev[b.length] ?? 0;\n}\n\n/**\n * The name nearest `query` by edit distance, the first on a tie, when it is\n * within `max(2, floor(query.length / 3))` edits; `undefined` otherwise. A\n * name further off than that is not a typo of `query`, and suggesting it\n * points at an unrelated entry.\n */\nexport function closestName(query: string, names: readonly string[]): string | undefined {\n const limit = Math.max(2, Math.floor(query.length / 3));\n let best: string | undefined;\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const name of names) {\n const distance = editDistance(query, name);\n if (distance < bestDistance) {\n best = name;\n bestDistance = distance;\n }\n }\n return bestDistance <= limit ? best : undefined;\n}\n\nexport interface GetReport {\n term: Term;\n /** The set's other terms with the same id: the entry in its other languages, in set order. */\n others: Term[];\n}\n\nexport async function runGet(opts: GetOptions): Promise<GetReport> {\n const { set } = await loadTerms(opts);\n const found = findTerm(set.terms, opts.term);\n if (found !== undefined) return { term: found, others: set.terms.filter((t) => t.id === found.id && t !== found) };\n const nearest = closestName(\n opts.term,\n set.terms.flatMap((t) => [t.id, t.record.label]),\n );\n const hint = nearest === undefined ? \".\" : `; did you mean \"${nearest}\"?`;\n throw new TermError(`no term \"${opts.term}\". ${plural(set.terms.length, \"term\")}${hint}`);\n}\n","/**\n * `term lint`: the definitions against the house voice (proposal 0052 § 6).\n *\n * Each entry's `definition`, `abstract` and `scope-note` is written to a\n * temporary `<id>.<field>.md`, and Vale runs once over the directory holding\n * them. The file name is the voice switch: a `[*.definition.md]` section in the\n * user's own `.vale.ini` applies to definitions alone. One file per field keeps\n * a document-wide rule from reaching across unrelated entries.\n *\n * Vale is given the directory rather than the file list so a large set does not\n * run into the platform's command-line length limit; the directory holds only\n * the files written here.\n */\nimport { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Term, TermField, TermFinding, TermSet } from \"../types.js\";\nimport { foldValeSeverity, proseRuleId } from \"./severity.js\";\nimport { runValeJson } from \"./vale.js\";\n\nexport interface LintTermSetOptions {\n /** Absolute; from `valeConfigPath(run.tools, run.configDir)`. */\n valeConfig?: string;\n /** Where Vale runs, and so where it looks for its own config. */\n cwd?: string;\n runVale?: typeof runValeJson;\n}\n\n/** The prose fields `lint` reads, in the order it writes them. */\nexport const PROSE_FIELDS = [\"definition\", \"abstract\", \"scope-note\"] as const satisfies readonly TermField[];\ntype ProseField = (typeof PROSE_FIELDS)[number];\n\ninterface Written {\n term: Term;\n field: ProseField;\n value: string;\n}\n\n/** A term id made safe as a file name component. */\nfunction fileStem(id: string): string {\n const safe = id.replace(/[^A-Za-z0-9._-]/g, \"_\");\n return safe === \"\" ? \"_\" : safe;\n}\n\n/** The last component of a path printed by Vale, whichever separator it used. */\nfunction baseName(path: string): string {\n const parts = path.split(/[\\\\/]/);\n return parts[parts.length - 1] ?? path;\n}\n\n/** The source line a line of a field's prose sits on. */\nfunction sourceLine(written: Written, proseLine: number): number {\n const { term, field, value } = written;\n const fieldLine = term.location.fieldLines[field] ?? term.location.line;\n if (!value.includes(\"\\n\")) return fieldLine;\n const { construct } = term.location;\n return construct === \"page\" || construct === \"manifest\" ? fieldLine + proseLine : fieldLine + proseLine - 1;\n}\n\nfunction compareFindings(a: TermFinding, b: TermFinding): number {\n if (a.file !== b.file) return a.file < b.file ? -1 : 1;\n const lineA = a.line ?? 0;\n const lineB = b.line ?? 0;\n if (lineA !== lineB) return lineA - lineB;\n if (a.ruleId !== b.ruleId) return a.ruleId < b.ruleId ? -1 : 1;\n if (a.message !== b.message) return a.message < b.message ? -1 : 1;\n return 0;\n}\n\nexport async function lintTermSet(set: TermSet, opts: LintTermSetOptions = {}): Promise<TermFinding[]> {\n // Keyed by lowercased file name: Vale may print the path in another case, and\n // a case-insensitive file system would fold `API` and `api` onto one file.\n const byName = new Map<string, Written>();\n const files: { name: string; content: string }[] = [];\n const stemCount = new Map<string, number>();\n\n for (const term of set.terms) {\n const fields = PROSE_FIELDS.filter((field) => term.record[field] !== undefined);\n if (fields.length === 0) continue;\n const stem = fileStem(term.id);\n const seen = (stemCount.get(stem.toLowerCase()) ?? 0) + 1;\n stemCount.set(stem.toLowerCase(), seen);\n // A repeated id is suffixed before the field, so `*.definition.md` still matches it.\n const prefix = seen === 1 ? stem : `${stem}.${String(seen)}`;\n for (const field of fields) {\n const value = term.record[field];\n if (value === undefined) continue;\n const name = `${prefix}.${field}.md`;\n byName.set(name.toLowerCase(), { term, field, value });\n files.push({ name, content: `${value}\\n` });\n }\n }\n\n if (files.length === 0) return [];\n\n const runVale = opts.runVale ?? runValeJson;\n const dir = await mkdtemp(join(tmpdir(), \"manni-term-lint-\"));\n try {\n for (const file of files) await writeFile(join(dir, file.name), file.content, \"utf8\");\n const alerts = await runVale([dir], { config: opts.valeConfig, cwd: opts.cwd });\n\n const findings: TermFinding[] = [];\n for (const [path, list] of Object.entries(alerts)) {\n const written = byName.get(baseName(path).toLowerCase());\n if (written === undefined) continue;\n for (const alert of list) {\n findings.push({\n ruleId: proseRuleId(alert.Check),\n severity: foldValeSeverity(alert.Severity),\n message: alert.Message,\n file: written.term.location.file,\n line: sourceLine(written, alert.Line),\n id: written.term.id,\n tool: \"vale\",\n check: alert.Check,\n toolSeverity: alert.Severity,\n field: written.field,\n });\n }\n }\n return findings.sort(compareFindings);\n } finally {\n await rm(dir, { recursive: true, force: true });\n }\n}\n","/**\n * The Vale process seam (proposal 0052 § 6). The only module that starts Vale.\n *\n * manni asks Vale rather than reading its files: `vale --output=JSON` for the\n * alerts, `vale ls-config` for the resolved configuration. Vale is started with\n * an argv, never a shell string, and what it prints is validated here, because\n * it crosses a process boundary.\n */\nimport { execFile } from \"node:child_process\";\nimport type { ValeSeverity } from \"../types.js\";\nimport { TermError } from \"../errors.js\";\n\n/** One alert, as `vale --output=JSON` prints it, trimmed to the fields manni reads. */\nexport interface ValeAlert {\n Check: string;\n Message: string;\n Line: number;\n Span: [number, number];\n Severity: ValeSeverity;\n}\n\n/** `vale --output=JSON`: the path Vale printed for each file, to its alerts. */\nexport type ValeAlerts = Record<string, ValeAlert[]>;\n\n/** What `vale ls-config` resolved. */\nexport interface ValeResolvedConfig {\n /** The project's styles directory: the last entry of Vale's `Paths`. */\n stylesPath: string;\n /** The config file Vale resolved. */\n rootIni: string;\n /** Each section glob to its `BasedOnStyles`. */\n baseStyles: Record<string, string[]>;\n}\n\nexport interface ValeProcessResult {\n /** Vale's exit code; `null` when a signal ended it. */\n code: number | null;\n /**\n * The signal that ended it, when one did, and `code` is then null. Optional\n * because absent means what it says: the run was not killed.\n */\n signal?: string | null;\n stdout: string;\n stderr: string;\n}\n\n/**\n * Start `vale` with `args` and wait for it. Resolves for any exit; rejects when\n * the process could not start, with an error whose `code` is `ENOENT` when\n * there is no `vale` on PATH. Tests inject a stub.\n */\nexport type ValeSpawn = (args: string[], opts: { cwd?: string }) => Promise<ValeProcessResult>;\n\nconst MAX_BUFFER = 64 * 1024 * 1024;\n\nconst SEVERITIES: readonly ValeSeverity[] = [\"error\", \"warning\", \"suggestion\"];\n\nexport const spawnVale: ValeSpawn = (args, opts) =>\n new Promise((settle, reject) => {\n execFile(\n \"vale\",\n args,\n { cwd: opts.cwd, windowsHide: true, maxBuffer: MAX_BUFFER, encoding: \"utf8\" },\n (error, stdout, stderr) => {\n if (!error) {\n settle({ code: 0, stdout, stderr });\n return;\n }\n if (typeof error.code === \"number\") {\n settle({ code: error.code, stdout, stderr });\n return;\n }\n // Killed by a signal. Node reports the exit code as **null** here,\n // not as undefined, so testing for undefined never matched: a killed\n // run fell through to `reject` and surfaced as though Vale could not\n // start. Settling instead keeps whatever Vale managed to write, which\n // is the part a reader can act on.\n if (error.code == null && typeof error.signal === \"string\") {\n settle({ code: null, signal: error.signal, stdout, stderr });\n return;\n }\n // A start failure (ENOENT) or an output over the buffer.\n const failure: Error = error;\n reject(failure);\n },\n );\n });\n\nfunction isEnoent(err: unknown): boolean {\n return typeof err === \"object\" && err !== null && \"code\" in err && err.code === \"ENOENT\";\n}\n\nasync function start(\n spawn: ValeSpawn,\n args: string[],\n cwd: string | undefined,\n missing: string,\n): Promise<ValeProcessResult> {\n try {\n return await spawn(args, { cwd });\n } catch (err) {\n if (isEnoent(err)) throw new TermError(missing);\n throw err;\n }\n}\n\nfunction isMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Vale's own account of a failure. Under `--output=JSON` it prints its error\n * as a JSON object whose `Text` is the message; otherwise the stderr is the\n * message.\n */\nfunction failureText(result: ValeProcessResult): string {\n const stderr = result.stderr.trim();\n try {\n const parsed: unknown = JSON.parse(stderr);\n if (isMapping(parsed) && typeof parsed[\"Text\"] === \"string\") return parsed[\"Text\"].trim();\n } catch {\n // Not JSON: the stderr is the message.\n }\n if (stderr !== \"\") return stderr;\n // Vale said nothing, so the ending is the only account there is. A signal\n // leaves no message behind, and \"exit code null\" names nothing a reader can\n // act on.\n if (result.signal != null) return `killed by ${result.signal}`;\n return `exit code ${String(result.code)}`;\n}\n\nfunction parseJson(stdout: string, what: string): unknown {\n try {\n return JSON.parse(stdout) as unknown;\n } catch {\n throw new TermError(`vale printed ${what} that is not JSON: ${stdout.trim().slice(0, 200)}`);\n }\n}\n\nfunction parseAlert(raw: unknown, path: string): ValeAlert {\n const unreadable = (): TermError =>\n new TermError(`vale printed an alert for ${path} that manni cannot read: ${JSON.stringify(raw)}`);\n if (!isMapping(raw)) throw unreadable();\n const { Check, Message, Line, Span, Severity } = raw;\n if (typeof Check !== \"string\" || typeof Message !== \"string\" || typeof Line !== \"number\") throw unreadable();\n if (!Array.isArray(Span) || Span.length !== 2) throw unreadable();\n const span: unknown[] = Span;\n const [from, to] = span;\n if (typeof from !== \"number\" || typeof to !== \"number\") throw unreadable();\n const severity = SEVERITIES.find((s) => s === Severity);\n if (severity === undefined) throw unreadable();\n return { Check, Message, Line, Span: [from, to], Severity: severity };\n}\n\nfunction parseAlerts(stdout: string): ValeAlerts {\n const parsed = parseJson(stdout, \"alerts\");\n if (!isMapping(parsed)) throw new TermError(\"vale printed alerts that are not a JSON object.\");\n const alerts: ValeAlerts = {};\n for (const [path, list] of Object.entries(parsed)) {\n if (!Array.isArray(list)) throw new TermError(`vale printed alerts for ${path} that are not a list.`);\n alerts[path] = list.map((raw: unknown) => parseAlert(raw, path));\n }\n return alerts;\n}\n\n/**\n * `vale --output=JSON [--config <config>] <files...>`. Exit 0 (no error-level\n * alert) and exit 1 (at least one) both carry alerts; any other exit means\n * Vale could not run.\n */\nexport async function runValeJson(\n files: string[],\n opts: { config?: string; cwd?: string },\n spawn: ValeSpawn = spawnVale,\n): Promise<ValeAlerts> {\n const args = [\"--output=JSON\", ...(opts.config === undefined ? [] : [\"--config\", opts.config]), ...files];\n const result = await start(spawn, args, opts.cwd, \"vale is not on PATH. Install Vale to lint definitions.\");\n if (result.code !== 0 && result.code !== 1) {\n throw new TermError(`vale could not lint definitions: ${failureText(result)}`);\n }\n return parseAlerts(result.stdout);\n}\n\nconst NO_CONFIG = /no config file found|\\.vale\\.ini not found/i;\n\nfunction stringList(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const list: string[] = [];\n for (const item of value as unknown[]) {\n if (typeof item !== \"string\") return undefined;\n list.push(item);\n }\n return list;\n}\n\n/**\n * `vale [--config <config>] ls-config`, run in `cwd`. `null` when Vale finds no\n * config file, which is a state the caller reports, not a failure to run.\n */\nexport async function valeLsConfig(\n opts: { config?: string; cwd: string },\n spawn: ValeSpawn = spawnVale,\n): Promise<ValeResolvedConfig | null> {\n const args = [...(opts.config === undefined ? [] : [\"--config\", opts.config]), \"ls-config\"];\n const result = await start(\n spawn,\n args,\n opts.cwd,\n \"vale is not on PATH. Install Vale, or pass -o <styles directory>.\",\n );\n if (result.code !== 0) {\n const text = failureText(result);\n if (NO_CONFIG.test(text)) return null;\n throw new TermError(`vale could not resolve its configuration: ${text}`);\n }\n\n const parsed = parseJson(result.stdout, \"a configuration\");\n if (!isMapping(parsed)) throw new TermError(\"vale printed a configuration that is not a JSON object.\");\n\n const paths = stringList(parsed[\"Paths\"]);\n const stylesPath = paths?.[paths.length - 1];\n if (stylesPath === undefined || stylesPath === \"\") {\n throw new TermError(\n \"vale's configuration names no styles directory. Set StylesPath in it, or pass -o <styles directory>.\",\n );\n }\n\n // Under --config, Vale 3.20.0 leaves RootINI empty and names the file in ConfigFiles.\n const root = parsed[\"RootINI\"];\n const configFiles = stringList(parsed[\"ConfigFiles\"]);\n const rootIni =\n typeof root === \"string\" && root !== \"\" ? root : (configFiles?.[configFiles.length - 1] ?? opts.config ?? \"\");\n\n const baseStyles: Record<string, string[]> = {};\n const sections = parsed[\"SBaseStyles\"];\n if (sections !== null && sections !== undefined) {\n if (!isMapping(sections)) throw new TermError(\"vale printed SBaseStyles that is not a JSON object.\");\n for (const [glob, styles] of Object.entries(sections)) {\n const list = stringList(styles);\n if (list === undefined) throw new TermError(`vale printed styles for ${glob} that are not a list of names.`);\n baseStyles[glob] = list;\n }\n }\n\n return { stylesPath, rootIni, baseStyles };\n}\n","/**\n * `manni term lint`: each entry's prose through Vale (proposal 0052 § 6). The\n * process seam is `lintTermSet`'s; this core resolves Vale's config from the\n * family `tools:` and shapes the report `check` shares.\n */\nimport { lintTermSet, type LintTermSetOptions } from \"../core/lint.js\";\nimport { summarize, toResults, reportedFindings, type TermReport } from \"./findings.js\";\nimport { loadTerms, valeConfigFor, type TermCommandOptions } from \"./run.js\";\n\nexport interface LintOptions extends TermCommandOptions {\n /** The Vale seam. Tests hand in a stub. */\n runVale?: LintTermSetOptions[\"runVale\"];\n}\n\nexport async function runLint(opts: LintOptions): Promise<TermReport> {\n const { cwd, run, set } = await loadTerms(opts);\n const valeConfig = valeConfigFor(run);\n const findings = await lintTermSet(set, {\n cwd,\n ...(valeConfig === undefined ? {} : { valeConfig }),\n ...(opts.runVale === undefined ? {} : { runVale: opts.runVale }),\n });\n const { results, origin } = toResults(set, findings);\n return {\n findings: reportedFindings(results, origin),\n results,\n summary: summarize(results),\n frame: { cwd, base: run.configDir ?? cwd, runBase: run.base },\n terms: set.terms.length,\n references: set.references.length,\n found: findings.length,\n cwd,\n };\n}\n","/**\n * `manni term write` (proposal 0052 § 5): the set written back to its sources,\n * or rendered somewhere new.\n *\n * With no `-f`, each file's entries go back through the reader that read them,\n * construct by construct. With `-f`, the registered writer renders the whole\n * set into `-o`, whose spelling decides the shape: a trailing separator, an\n * existing directory, or the Vale style make it a directory; anything else is\n * a file. `-f vale` without `-o` asks Vale where its styles live.\n *\n * Writers are pure, so `--check` and `--dry-run` run the same render a write\n * does and differ only in what happens to the result.\n */\nimport { existsSync, statSync } from \"node:fs\";\nimport { lstat, mkdir, readdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, extname, join, resolve } from \"node:path\";\nimport { extractorForExtension } from \"../../meta/internal.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { MANIFEST_FORMAT, extractInput, tbxInput } from \"../core/load-set.js\";\nimport { TERM_READERS, readerForConstruct } from \"../core/readers/index.js\";\nimport { valeLsConfig, type ValeResolvedConfig } from \"../core/vale.js\";\nimport { TERM_WRITERS } from \"../core/writers/index.js\";\nimport { tbxHeaderFiles } from \"../core/writers/tbx.js\";\nimport { TermError } from \"../errors.js\";\nimport {\n TERM_WRITE_FORMATS,\n type DroppedField,\n type MergeConflict,\n type RenderedFile,\n type Term,\n type TermConstruct,\n type TermInput,\n type TermReader,\n type TermRender,\n type TermShape,\n type TermTarget,\n type TermWriteFormat,\n type TermWriter,\n} from \"../types.js\";\nimport { DOCUMENT_RENDERS } from \"./formats.js\";\nimport { displayPath, formatChoice, loadTerms, valeConfigFor, type TermCommandOptions } from \"./run.js\";\n\nexport interface WriteOptions extends TermCommandOptions {\n /** `-f, --format`. Absent writes in place. */\n format?: string;\n /** `-o, --out <path>`. */\n out?: string;\n /** `--check`. */\n check?: boolean;\n /** `--dry-run`. */\n dryRun?: boolean;\n /** The writers to render with. Tests hand in their own. */\n writers?: readonly TermWriter[];\n /** `vale ls-config`. Tests hand in a stub. */\n lsConfig?: (opts: { config?: string; cwd: string }) => Promise<ValeResolvedConfig | null>;\n}\n\n/** One file the write would change, as a person in `cwd` would name it. */\nexport interface WriteChange {\n path: string;\n action: \"create\" | \"change\" | \"remove\";\n}\n\n/** The `BasedOnStyles` line the notice suggests, when no section uses `Terms`. */\nexport interface ValeWiring {\n /** The config file Vale resolved, relative to cwd. */\n rootIni: string;\n /** The section glob to add the style to: the first Vale reports, or `*.md` when it reports none. */\n section: string;\n /** The section's styles with `Terms` appended. `[\"Terms\"]` when Vale reports no section. */\n styles: string[];\n /** True when Vale reports no section with `BasedOnStyles`, so the notice says to add `section`. */\n addSection: boolean;\n}\n\n/** The section glob the notice suggests when Vale's config has none. */\nconst SUGGESTED_SECTION = \"*.md\";\n\nexport interface WriteReport {\n mode: \"in-place\" | \"render\";\n format?: TermWriteFormat;\n shape?: TermShape;\n /** `-o` as typed, or the Vale style directory; relative to cwd. */\n target?: string;\n terms: number;\n /** Files that differ from disk. Under `--check` and `--dry-run` nothing was written. */\n changes: WriteChange[];\n /** The rendered files, relative to cwd, with their content. */\n files: RenderedFile[];\n dropped: DroppedField[];\n /** What a dropped field was dropped from, and a skipped term left out of: `a definition list`, `tbx`. */\n droppedFrom?: string;\n /** Ids of the terms left out because the target construct cannot read them back, in set order. */\n skipped: string[];\n /** The terms left out because the target construct holds one language, and the language it holds. */\n otherLanguages?: TermRender[\"otherLanguages\"];\n /** The fields where terms sharing an id disagree, and the render kept the first term's value. */\n conflicts?: MergeConflict[];\n /** The TBX files whose header the render left behind, as their terms name them. */\n droppedHeaders?: string[];\n check: boolean;\n dryRun: boolean;\n wiring?: ValeWiring;\n}\n\nconst STYLE = \"Terms\";\n\n/** The registered `-f` values, in the order the reference lists them. */\nexport function writeFormats(writers: readonly TermWriter[] = TERM_WRITERS): TermWriteFormat[] {\n return TERM_WRITE_FORMATS.filter((format) => writers.some((writer) => writer.format === format));\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * The largest file under a render target a write reads into the render context.\n * A larger one is there as an empty string: a render never produces an empty\n * file, so it still differs, and the Vale writer refuses it as not its own.\n */\nexport const MAX_EXISTING_FILE_BYTES = 1024 * 1024;\n\n/** Every regular file under `dir`. A symlink is skipped, never followed. */\nasync function filesUnder(dir: string, into: Map<string, string>): Promise<void> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const path = join(dir, entry.name);\n // A Dirent describes the entry itself, so a symlink is neither of these.\n if (entry.isDirectory()) await filesUnder(path, into);\n else if (entry.isFile()) {\n const { size } = await lstat(path);\n into.set(path, size > MAX_EXISTING_FILE_BYTES ? \"\" : await readFile(path, \"utf8\"));\n }\n }\n}\n\nasync function existingFor(target: TermTarget): Promise<Map<string, string>> {\n const existing = new Map<string, string>();\n if (target.shape === \"directory\") {\n await filesUnder(target.path, existing);\n } else if (existsSync(target.path) && !isDirectory(target.path)) {\n existing.set(target.path, await readFile(target.path, \"utf8\"));\n }\n return existing;\n}\n\n/** A writer's refusal, with every absolute path it names spelled from cwd. */\nfunction relativized(error: TermError, paths: readonly string[], cwd: string): TermError {\n let message = error.message;\n for (const path of [...paths].sort((a, b) => b.length - a.length)) {\n if (message.includes(path)) message = message.replaceAll(path, displayPath(path, cwd));\n }\n return message === error.message ? error : new TermError(message);\n}\n\n/** The noun a dropped field was dropped from. */\nfunction droppedFrom(format: TermWriteFormat, shape: TermShape, readers: readonly TermReader[]): string {\n const construct = DOCUMENT_RENDERS[format]?.shapes[shape];\n const reader = construct === undefined ? undefined : readerForConstruct(construct, readers);\n return reader === undefined ? format : `a ${reader.label}`;\n}\n\nasync function applyChanges(\n files: readonly RenderedFile[],\n removals: readonly string[],\n existing: ReadonlyMap<string, string>,\n cwd: string,\n write: boolean,\n): Promise<WriteChange[]> {\n const changes: WriteChange[] = [];\n for (const file of files) {\n const before = existing.get(file.path) ?? (existsSync(file.path) ? await readFile(file.path, \"utf8\") : undefined);\n if (before === file.content) continue;\n changes.push({ path: displayPath(file.path, cwd), action: before === undefined ? \"create\" : \"change\" });\n if (write) {\n await mkdir(dirname(file.path), { recursive: true });\n await writeFile(file.path, file.content, \"utf8\");\n }\n }\n for (const path of removals) {\n if (!existsSync(path)) continue;\n changes.push({ path: displayPath(path, cwd), action: \"remove\" });\n if (write) await rm(path, { force: true });\n }\n return changes;\n}\n\nexport async function runWrite(opts: WriteOptions): Promise<WriteReport> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const writers = opts.writers ?? TERM_WRITERS;\n const readers = opts.readers ?? TERM_READERS;\n const check = opts.check === true;\n const dryRun = opts.dryRun === true;\n if (check && dryRun) throw new TermError(\"--check and --dry-run cannot be combined.\");\n\n if (opts.format === undefined) {\n if (opts.out !== undefined) throw new TermError(\"-o needs -f <format>.\");\n return writeInPlace({ ...opts, cwd, readers }, check, dryRun);\n }\n\n const format = formatChoice(opts.format, writeFormats(writers));\n const writer = writers.find((w) => w.format === format);\n if (writer === undefined) throw new TermError(`unknown format \"${format}\".`);\n if (opts.out === undefined && format !== \"vale\") {\n throw new TermError(`-f ${format} needs -o <path>.`);\n }\n\n const { run, set } = await loadTerms({ ...opts, cwd, readers });\n\n // Where the render goes, and in which shape.\n let targetPath: string;\n let wiring: ValeWiring | undefined;\n if (opts.out === undefined) {\n const lsConfig = opts.lsConfig ?? ((o) => valeLsConfig(o));\n const config = valeConfigFor(run);\n const resolved = await lsConfig({ cwd, ...(config === undefined ? {} : { config }) });\n if (resolved === null) {\n throw new TermError(\n \"Vale found no config file. Set tools.vale.config in manni.config.yaml, or pass -o <styles directory>.\",\n );\n }\n targetPath = resolve(cwd, resolved.stylesPath);\n if (!Object.values(resolved.baseStyles).some((styles) => styles.includes(STYLE))) {\n const first = Object.entries(resolved.baseStyles)[0];\n const [section, styles] = first ?? [SUGGESTED_SECTION, []];\n wiring = {\n rootIni: displayPath(resolve(cwd, resolved.rootIni), cwd),\n section,\n styles: [...styles, STYLE],\n addSection: first === undefined,\n };\n }\n } else {\n targetPath = resolve(cwd, opts.out);\n }\n const shape: TermShape =\n format === \"vale\" || /[\\\\/]$/.test(opts.out ?? \"\") || isDirectory(targetPath) ? \"directory\" : \"file\";\n const target: TermTarget = { path: targetPath, shape };\n const existing = await existingFor(target);\n\n let render;\n try {\n render = writer.render(set.terms, target, { existing });\n } catch (error) {\n if (error instanceof TermError) throw relativized(error, [...existing.keys(), targetPath], cwd);\n throw error;\n }\n\n const changes = await applyChanges(render.files, render.removals, existing, cwd, !check && !dryRun);\n const shown =\n format === \"vale\" ? displayPath(join(targetPath, STYLE), cwd) : (opts.out ?? displayPath(targetPath, cwd));\n return {\n mode: \"render\",\n format,\n shape,\n target: shown,\n terms: set.terms.length,\n changes,\n files: render.files.map((file) => ({ path: displayPath(file.path, cwd), content: file.content })),\n // A Vale style holds designations only, by design; its dropped definitions are not news.\n dropped: format === \"vale\" ? [] : render.dropped,\n droppedFrom: droppedFrom(format, shape, readers),\n skipped: render.skipped,\n ...(render.otherLanguages === undefined ? {} : { otherLanguages: render.otherLanguages }),\n ...(render.conflicts === undefined ? {} : { conflicts: render.conflicts }),\n // A Vale style is not a termbase, so a header it does not hold is not news either.\n ...(format === \"vale\" ? {} : { droppedHeaders: render.droppedHeaders ?? tbxHeaderFiles(set.terms) }),\n check,\n dryRun,\n ...(wiring === undefined ? {} : { wiring }),\n };\n}\n\n/** The `TermInput` a construct's reader reads from `content`, rebuilt as the loader built it. */\nfunction inputFor(content: string, path: string, construct: TermConstruct, file: string): TermInput {\n if (construct === \"manifest\") {\n return { content, file, path, format: MANIFEST_FORMAT, metadata: {}, lineFor: () => undefined };\n }\n if (construct === \"tbx-entry\") return tbxInput(content, file, path);\n const extractor = extractorForExtension(extname(path));\n if (extractor === undefined) throw new TermError(`${file}: no reader for its extension.`);\n return extractInput(content, file, path, extractor.name);\n}\n\n/**\n * The caller's records carried onto `current`, the entries a construct's reader\n * read from content an earlier construct rewrote. An entry is matched by `id`;\n * where the id repeats in either list, by its position within the construct.\n * An entry the caller left out keeps the record it was read with.\n */\nfunction carryRecords(current: readonly Term[], edited: readonly Term[]): Term[] {\n const count = (terms: readonly Term[], id: string): number => terms.filter((t) => t.id === id).length;\n return current.map((entry, index) => {\n const unique = count(current, entry.id) === 1 && count(edited, entry.id) === 1;\n const match = unique ? edited.find((t) => t.id === entry.id) : edited[index];\n return match?.id === entry.id ? { ...entry, record: match.record } : entry;\n });\n}\n\n/**\n * One file's content with each construct's entries written back through its\n * reader, in order. A field the terms of one entry disagree on goes onto `conflicts`.\n */\nexport function applyInPlace(\n original: string,\n path: string,\n file: string,\n constructs: ReadonlyMap<TermConstruct, readonly Term[]>,\n readers: readonly TermReader[],\n conflicts?: MergeConflict[],\n): string {\n let content = original;\n let first = true;\n for (const [construct, terms] of constructs) {\n const reader = readerForConstruct(construct, readers);\n if (reader?.apply === undefined) continue;\n const input = inputFor(content, path, construct, file);\n // The loaded terms carry offsets into the file as it was read. Once an\n // earlier construct has rewritten it, this one's entries are read again for\n // offsets that are the content's own, and the caller's records carried over.\n content = reader.apply(input, first ? terms : carryRecords(reader.read(input).terms, terms), conflicts);\n first = false;\n }\n return content;\n}\n\nasync function writeInPlace(\n opts: WriteOptions & { cwd: string; readers: readonly TermReader[] },\n check: boolean,\n dryRun: boolean,\n): Promise<WriteReport> {\n const { cwd, readers } = opts;\n const { set } = await loadTerms(opts);\n\n // Every file's terms, per construct, in load order.\n const byPath = new Map<string, { file: string; constructs: Map<TermConstruct, Term[]> }>();\n for (const term of set.terms) {\n const { path, construct } = term.location;\n if (path === undefined) {\n throw new TermError(`${term.location.file} has nowhere to write back to. Pass -f <format> -o <path>.`);\n }\n const reader = readerForConstruct(construct, readers);\n if (reader?.apply === undefined) {\n const name = reader?.label ?? construct;\n throw new TermError(\n `${displayPath(term.location.file, cwd)}: a ${name} cannot be written in place. Pass -f <format> -o <path>.`,\n );\n }\n const entry = byPath.get(path) ?? { file: term.location.file, constructs: new Map<TermConstruct, Term[]>() };\n entry.constructs.set(construct, [...(entry.constructs.get(construct) ?? []), term]);\n byPath.set(path, entry);\n }\n\n const files: RenderedFile[] = [];\n const existing = new Map<string, string>();\n const conflicts: MergeConflict[] = [];\n for (const [path, { file, constructs }] of byPath) {\n let original: string;\n try {\n original = await readFile(path, \"utf8\");\n } catch (error) {\n throw new TermError(`${file}: could not be read: ${errorMessage(error)}`);\n }\n existing.set(path, original);\n files.push({ path, content: applyInPlace(original, path, file, constructs, readers, conflicts) });\n }\n\n const changes = await applyChanges(files, [], existing, cwd, !check && !dryRun);\n return {\n mode: \"in-place\",\n terms: set.terms.length,\n changes,\n files: files.map((f) => ({ path: displayPath(f.path, cwd), content: f.content })),\n dropped: [],\n skipped: [],\n ...(conflicts.length === 0 ? {} : { conflicts }),\n check,\n dryRun,\n };\n}\n","/**\n * `term list -f csv`: one row per term for a script,\n * `id,label,alt-labels,abstract,language`. A term with no language has an empty\n * language cell.\n * A list is joined with `|`, and a cell is quoted as RFC 4180 says.\n */\nimport type { Term } from \"../types.js\";\n\nconst LIST_SEPARATOR = \"|\";\n\nfunction cell(value: string): string {\n return /[\",\\r\\n]/.test(value) ? `\"${value.replaceAll('\"', '\"\"')}\"` : value;\n}\n\nexport function renderListCsv(terms: readonly Term[]): string {\n const rows = [\n [\"id\", \"label\", \"alt-labels\", \"abstract\", \"language\"],\n ...terms.map((t) => [\n t.id,\n t.record.label,\n (t.record[\"alt-labels\"] ?? []).join(LIST_SEPARATOR),\n t.record.abstract ?? \"\",\n t.language ?? \"\",\n ]),\n ];\n return rows.map((row) => row.map(cell).join(\",\")).join(\"\\n\");\n}\n","/**\n * SARIF for `check` and `lint`. Meta's renderer builds the envelope, the\n * repository-relative uris and the fingerprints the baseline shares, from the\n * adapted results. What it cannot know is what a term rule is: it describes\n * every rule as a schema keyword, links meta's fix page, and prefixes each\n * message with the JSON Pointer of the field, `(root)` for a finding about a\n * whole entry. This renderer replaces those three with the term rule's own\n * description, a link to its section of the rules page, and the finding's own\n * message.\n */\nimport { renderSarif } from \"../../meta/index.js\";\nimport { RULE_ID_PREFIX, isTermRule } from \"../core/severity.js\";\nimport type { TermReport } from \"../commands/findings.js\";\nimport { TERM_FIELDS, type TermRule } from \"../types.js\";\n\nconst INFORMATION_URI = \"https://hawkeyexl.github.io/manni/term/\";\n\n/** The rules reference, whose sections are anchored by rule name. */\nconst RULES_URI = \"https://hawkeyexl.github.io/manni/term/reference/rules/\";\n\n/** What each `check` rule is, as the rules reference's table says it. */\nconst RULE_DESCRIPTIONS: Readonly<Record<TermRule, string>> = {\n \"undefined-term\": \"A page's concepts: names a label no entry claims as its preferred label.\",\n \"duplicate-id\": \"Two entries share an id.\",\n \"label-collision\": \"Two entries claim the same preferred label, ignoring case.\",\n \"alt-label-collision\": \"An entry's alt-label is another entry's preferred label, ignoring case.\",\n \"dangling-reference\": \"A value of broader, narrower, related-terms or see names no entry, by label or by id.\",\n \"broader-cycle\": \"A chain of broader returns to where it started.\",\n \"see-not-empty\": \"An entry with see also carries a definition.\",\n \"asymmetric-hierarchy\": \"A names B as broader, and B omits A from narrower, or the reverse.\",\n \"abstract-too-long\": \"An abstract is longer than term.abstractMaxLength.\",\n \"unused-term\": \"No page's concepts: names the entry's preferred label.\",\n};\n\nconst PROSE_PREFIX = `${RULE_ID_PREFIX}/prose/`;\n\n/**\n * The label meta's reporters put before a message: `(root) ` for a finding\n * about the whole entry, `/<field> ` for one about a field. Nothing else ever\n * opens a term finding's adapted message.\n */\nexport const FIELD_LABEL = new RegExp(`^(?:\\\\(root\\\\)|/(?:${TERM_FIELDS.join(\"|\")})) `);\n\ninterface SarifRule {\n id: string;\n shortDescription: { text: string };\n helpUri?: string;\n}\n\ninterface SarifLog {\n runs: {\n tool: { driver: { informationUri: string; rules: SarifRule[] } };\n results: { message: { text: string } }[];\n }[];\n}\n\n/** A rule as the term tool describes it: a check rule links its section, a Vale rule links nothing manni documents. */\nfunction describe(rule: SarifRule): SarifRule {\n if (rule.id.startsWith(PROSE_PREFIX)) {\n const check = rule.id.slice(PROSE_PREFIX.length);\n return { id: rule.id, shortDescription: { text: `Vale's ${check} rule flagged the prose of an entry's field.` } };\n }\n const name = rule.id.slice(RULE_ID_PREFIX.length + 1);\n if (!isTermRule(name)) return rule;\n return { id: rule.id, shortDescription: { text: RULE_DESCRIPTIONS[name] }, helpUri: `${RULES_URI}#${name}` };\n}\n\nexport function renderFindingsSarif(report: TermReport, opts: { onNotice?: (message: string) => void } = {}): string {\n const log = JSON.parse(\n renderSarif(report.results, {\n frame: report.frame,\n ...(opts.onNotice === undefined ? {} : { onNotice: opts.onNotice }),\n }),\n ) as SarifLog;\n for (const run of log.runs) {\n run.tool.driver.informationUri = INFORMATION_URI;\n run.tool.driver.rules = run.tool.driver.rules.map(describe);\n for (const result of run.results) result.message.text = result.message.text.replace(FIELD_LABEL, \"\");\n }\n return JSON.stringify(log, null, 2);\n}\n","/**\n * JUnit for `check` and `lint`: meta's renderer over the adapted results,\n * under the `manni.term` classname, with each failure's message the finding's\n * own. Meta's renderer opens every message with the field's JSON Pointer,\n * `(root)` for a finding about a whole entry, which says nothing about a term.\n * The failure's `type` is already the rule id.\n */\nimport { renderJunit } from \"../../meta/index.js\";\nimport { JUNIT_CLASSNAME, type TermReport } from \"../commands/findings.js\";\nimport { FIELD_LABEL } from \"./sarif.js\";\n\n/** A `message=\"` attribute's opening label. The value is escaped, so `message=\"` opens nothing else. */\nconst MESSAGE_LABEL = new RegExp(`message=\"${FIELD_LABEL.source.slice(1)}`, \"g\");\n\nexport function renderFindingsJunit(report: TermReport): string {\n return renderJunit(report.results, { frame: report.frame, classname: JUNIT_CLASSNAME }).replace(\n MESSAGE_LABEL,\n 'message=\"',\n );\n}\n","/**\n * The termbase as `meta fill` reads it: each term's label and id, from the\n * same config and the same files `manni term check` reads. Registered as the\n * family's term label source by this domain's CLI module (see\n * `src/shared/term-labels.ts`).\n */\nimport type { TermLabel, TermLabelRequest } from \"../../shared/term-labels.js\";\nimport { resolveTermRun } from \"../core/config.js\";\nimport { loadSet } from \"./run.js\";\n\nexport async function termLabels(request: TermLabelRequest): Promise<TermLabel[]> {\n const run = await resolveTermRun({\n cwd: request.cwd,\n inputs: [],\n ...(request.configPath === undefined ? {} : { configPath: request.configPath }),\n ...(request.noConfig === true ? { noConfig: true } : {}),\n });\n // No collection and no manifest names a file, so there is no termbase.\n if (run.inputs.length === 0 && run.manifests.length === 0) return [];\n const set = await loadSet(run, { inputs: [], allowEmpty: true });\n return set.terms.map((term) => ({ label: term.record.label, id: term.id }));\n}\n"],"mappings":"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","names":["entries","entries","HOLDS","HOLDS","join","HOLDS","join","join","join","rm","writeFile","join","resolve","STYLE","entries","join","writeFile","rm","resolve","LIST_SEPARATOR","cell","references"]}
|
|
1
|
+
{"version":3,"sources":["../src/term/cli.ts","../src/term/core/writers/documents.ts","../src/term/core/writers/page.ts","../src/term/core/writers/csv.ts","../src/term/core/writers/json.ts","../src/term/core/writers/skos.ts","../src/term/core/writers/tbx.ts","../src/term/core/writers/vale.ts","../src/term/core/writers/interchange.ts","../src/term/core/writers/index.ts","../src/term/commands/formats.ts","../src/term/commands/get.ts","../src/term/core/lint.ts","../src/term/core/vale.ts","../src/term/commands/lint.ts","../src/term/commands/write.ts","../src/term/reporters/csv.ts","../src/term/reporters/sarif.ts","../src/term/reporters/junit.ts","../src/term/commands/labels.ts"],"sourcesContent":["/**\n * The `term` domain's commander program. Mounted by `src/cli.ts` under\n * `manni term`; no entry point of its own. Grammar per proposal 0034: the verbs\n * are `list`, `get`, `check`, `lint`, `write` and `formats`, and there is no\n * default subcommand.\n *\n * Follows clig.dev as the family does: primary output to stdout, diagnostics\n * and notices to stderr, colour only on a TTY and never under\n * `NO_COLOR`/`--no-color`, exit `0` clean, `1` an error-severity finding or a\n * `--check` that found drift, `2` operational/usage.\n */\nimport { Command } from \"commander\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport { collect, readStdin, splitList } from \"../shared/cli-options.js\";\nimport { shouldColor } from \"../shared/color.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice } from \"../shared/warn.js\";\nimport { OMITTED_WHEN_CLEAN, STDIN_TOKEN } from \"../meta/internal.js\";\nimport { runCheck } from \"./commands/check.js\";\nimport { FINDING_FORMATS, type FindingFormat, type TermReport } from \"./commands/findings.js\";\nimport { FORMATS_FORMATS, listFormats } from \"./commands/formats.js\";\nimport { GET_FORMATS, runGet } from \"./commands/get.js\";\nimport { runLint } from \"./commands/lint.js\";\nimport { LIST_FORMATS, runList } from \"./commands/list.js\";\nimport { formatChoice, type TermCommandOptions } from \"./commands/run.js\";\nimport { runWrite, writeFormats } from \"./commands/write.js\";\nimport { renderListCsv } from \"./reporters/csv.js\";\nimport { renderFindingsGithub } from \"./reporters/github.js\";\nimport { renderFindingsJson, renderFormatsJson, renderGetJson, renderListJson } from \"./reporters/json.js\";\nimport { renderFindingsJunit } from \"./reporters/junit.js\";\nimport {\n renderFindingsPretty,\n renderFormatsPretty,\n renderGetPretty,\n renderListPretty,\n renderValeWiring,\n renderWritePretty,\n} from \"./reporters/pretty.js\";\nimport { renderFindingsSarif } from \"./reporters/sarif.js\";\nimport { registerTermLabelSource } from \"../shared/term-labels.js\";\nimport { termLabels } from \"./commands/labels.js\";\n\n// The umbrella loads this module, so under the `manni` bin `meta fill` offers\n// the termbase's labels. The `docmeta` bin never loads it, and offers none.\nregisterTermLabelSource(termLabels);\n\n/** What commander hands every verb that reads terms. */\ninterface InputCliOptions {\n as?: string;\n /** `--ext <list>`, comma-separated and given once. */\n ext?: string;\n /** `--exclude <glob>`, repeatable; commander's default value is `[]`. */\n exclude: string[];\n /** `--allow-empty`. */\n allowEmpty?: boolean;\n /** `--no-gitignore`: `false` when given. */\n gitignore: boolean;\n /** `--collection <name>`, repeatable; commander's default value is `[]`. */\n collection: string[];\n config?: string;\n /** `--no-color`: `false` when given. */\n color: boolean;\n}\n\ninterface FormatCliOptions extends InputCliOptions {\n format: string;\n}\n\ninterface CheckCliOptions extends FormatCliOptions {\n baseline?: boolean;\n}\n\ninterface WriteCliOptions extends InputCliOptions {\n format?: string;\n out?: string;\n check?: boolean;\n dryRun?: boolean;\n}\n\n/** Colour for a verb's pretty output: off under `--no-color` or `NO_COLOR`, on only for a TTY. */\nfunction colorFor(options: InputCliOptions): boolean {\n return shouldColor({ noColor: !options.color, isTTY: process.stdout.isTTY });\n}\n\n/** The core's shared options from commander's, with stdin read once when `-` is among the paths. */\nasync function coreOptions(paths: string[], options: InputCliOptions): Promise<TermCommandOptions> {\n return {\n inputs: paths,\n ...(paths.includes(STDIN_TOKEN) ? { stdin: await readStdin() } : {}),\n ...(options.as === undefined ? {} : { as: options.as }),\n ...(options.ext === undefined ? {} : { exts: splitList(options.ext) }),\n exclude: options.exclude,\n collection: options.collection,\n ...(options.allowEmpty === true ? { allowEmpty: true } : {}),\n ...(options.gitignore ? {} : { noGitignore: true }),\n ...(options.config === undefined ? {} : { configPath: options.config }),\n onNotice: notice,\n };\n}\n\n/** The shared input flags, declared once so every verb spells them alike. */\nfunction withInputs(command: Command): Command {\n return command\n .option(\"--as <format>\", \"input format for stdin (-)\")\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--collection <name>\", \"configured collection to read; repeatable\", collect, [])\n .option(\"--allow-empty\", \"treat a missing path, no matched files or no terms as success\")\n .option(\"--no-gitignore\", \"read files .gitignore covers\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-color\", \"disable colored output\");\n}\n\nfunction print(text: string): void {\n process.stdout.write(`${text}\\n`);\n}\n\nfunction renderFindings(report: TermReport, format: FindingFormat, options: InputCliOptions, references: boolean): void {\n let text: string;\n switch (format) {\n case \"pretty\":\n text = renderFindingsPretty(report, { color: colorFor(options), references });\n break;\n case \"json\":\n text = renderFindingsJson(report);\n break;\n case \"github\":\n text = renderFindingsGithub(report);\n break;\n case \"sarif\":\n text = renderFindingsSarif(report, { onNotice: notice });\n break;\n case \"junit\":\n text = renderFindingsJunit(report);\n break;\n }\n if (text.length > 0 || !OMITTED_WHEN_CLEAN.has(format)) print(text);\n process.exitCode = report.summary.failed > 0 ? 1 : 0;\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"term\")\n .description(\"Check, lint and render a docset's terms and the references into them.\")\n .version(pkg.version, \"-V, --version\")\n // A pointer, not the whole help screen: the message that precedes it\n // already names the offending flag.\n .showHelpAfterError(\"(add --help for usage)\")\n // MUST come before the `.command()` calls below: commander copies the exit\n // callback into each subcommand by value when the subcommand is created.\n .exitOverride();\n\n withInputs(\n program\n .command(\"list\")\n .description(\"List the resolved entries\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `output: ${LIST_FORMATS.join(\" | \")}`, \"pretty\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni term list # every collection\",\n \" manni term list docs/terms/ # one directory\",\n \" manni term list -f csv | head -2 # for a script\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: FormatCliOptions) => {\n try {\n const format = formatChoice(options.format, LIST_FORMATS);\n const { terms } = await runList(await coreOptions(paths, options));\n print(format === \"json\" ? renderListJson(terms) : format === \"csv\" ? renderListCsv(terms) : renderListPretty(terms));\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n withInputs(\n program\n .command(\"get\")\n .description(\"Show one entry\")\n .argument(\"<term>\", \"the entry's id, or its label or an alt-label in any case\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `output: ${GET_FORMATS.join(\" | \")}`, \"pretty\")\n .addHelpText(\n \"after\",\n [\"\", \"Examples:\", \" manni term get progressive-lens\", ' manni term get \"progressive lens\" -f json'].join(\"\\n\"),\n )\n .action(async (term: string, paths: string[], options: FormatCliOptions) => {\n try {\n const format = formatChoice(options.format, GET_FORMATS);\n const found = await runGet({ ...(await coreOptions(paths, options)), term });\n print(\n format === \"json\"\n ? renderGetJson(found.term)\n : renderGetPretty(found.term, { color: colorFor(options), others: found.others }),\n );\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n withInputs(\n program\n .command(\"check\")\n .description(\"Check the set and every reference into it\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `output: ${FINDING_FORMATS.join(\" | \")}`, \"pretty\")\n .option(\"--baseline\", \"record the findings on the first run; after that, fail only on new ones\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni term check # every collection\",\n \" manni term check -f github # CI annotations\",\n \" manni term check --baseline # ramp in on an existing docset\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: CheckCliOptions) => {\n try {\n const format = formatChoice(options.format, FINDING_FORMATS);\n const report = await runCheck({\n ...(await coreOptions(paths, options)),\n ...(options.baseline === true ? { baseline: true } : {}),\n });\n renderFindings(report, format, options, true);\n } catch (err) {\n fail(err);\n }\n });\n\n withInputs(\n program\n .command(\"lint\")\n .description(\"Run Vale over the definitions\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `output: ${FINDING_FORMATS.join(\" | \")}`, \"pretty\")\n .addHelpText(\n \"after\",\n [\"\", \"Examples:\", \" manni term lint\", \" manni term lint -f github\"].join(\"\\n\"),\n )\n .action(async (paths: string[], options: FormatCliOptions) => {\n try {\n const format = formatChoice(options.format, FINDING_FORMATS);\n const report = await runLint(await coreOptions(paths, options));\n renderFindings(report, format, options, false);\n } catch (err) {\n fail(err);\n }\n });\n\n withInputs(\n program\n .command(\"write\")\n .description(\"Write the set back, or render it elsewhere\")\n .argument(\"[paths...]\", \"files, directories, or globs to read (use - for stdin)\"),\n )\n .option(\"-f, --format <format>\", `render as: ${writeFormats().join(\" | \")} (default: each entry's own, in place)`)\n .option(\"-o, --out <path>\", \"file or directory to render into; a trailing / means a directory\")\n .option(\"--check\", \"write nothing; exit 1 when the target differs from the render\")\n .option(\"--dry-run\", \"write nothing; print what would change\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni term write # each entry back to its source\",\n \" manni term write -f json -o build/terms.json\",\n \" manni term write -f vale # into Vale's styles directory\",\n \" manni term write -f vale --check # keep the style in step\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: WriteCliOptions) => {\n try {\n const report = await runWrite({\n ...(await coreOptions(paths, options)),\n ...(options.format === undefined ? {} : { format: options.format }),\n ...(options.out === undefined ? {} : { out: options.out }),\n ...(options.check === true ? { check: true } : {}),\n ...(options.dryRun === true ? { dryRun: true } : {}),\n });\n print(renderWritePretty(report));\n if (report.wiring !== undefined) process.stderr.write(`${renderValeWiring(report.wiring)}\\n`);\n process.exitCode = report.check && report.changes.length > 0 ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"formats\")\n .description(\"List the constructs read and written, per format\")\n .option(\"-f, --format <format>\", `output: ${FORMATS_FORMATS.join(\" | \")}`, \"pretty\")\n .action((options: { format: string }) => {\n try {\n const format = formatChoice(options.format, FORMATS_FORMATS);\n const rows = listFormats();\n print(format === \"json\" ? renderFormatsJson(rows) : renderFormatsPretty(rows));\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n return program;\n}\n","/**\n * Writers for the seven document formats. The target's shape decides the\n * construct: a directory gets one term page per term (a DITA glossentry topic\n * for DITA), a file gets every term in the format's list construct. DocBook\n * has no one-term construct, so it is written as a file only.\n *\n * A set in more than one language puts each page under a directory named for\n * its language. A list construct holds one language, so a file gets the first\n * term's, and the render reports the terms in any other.\n */\nimport { join } from \"node:path\";\nimport { TermError } from \"../../errors.js\";\nimport {\n TERM_FIELDS,\n type Term,\n type TermField,\n type TermRender,\n type TermShape,\n type TermTarget,\n type TermWriteFormat,\n type TermWriter,\n} from \"../../types.js\";\nimport {\n DITA_HOLDS,\n DOCBOOK_HOLDS,\n LIST_HOLDS,\n asciidocEntry,\n ditaEntry,\n docbookEntry,\n htmlDlEntry,\n markdownEntry,\n rstEntry,\n} from \"./entries.js\";\nimport { fileOf, reindent, sharedLanguage, xmlAttribute } from \"./markup.js\";\nimport { htmlPage, metadataPage, yamlFrontmatter } from \"./page.js\";\nimport { droppedFields, isMultilingual, languageKey, languageOf, requireShape } from \"./render-util.js\";\n\n/** Characters no file name may hold on any platform manni runs on. */\nconst UNSAFE_NAME = /[/\\\\:*?\"<>|]/;\n\ninterface DocumentSpec {\n format: TermWriteFormat;\n extension: string;\n file: {\n holds: readonly TermField[];\n render: (terms: readonly Term[]) => string;\n /**\n * Whether the file's construct reads an entry only when it has a\n * definition. A Markdown or AsciiDoc list and a `.. glossary::` skip one\n * with none, and a `<dl>` folds its `<dt>`s into the next entry's, so a\n * term with no definition is left out rather than written unreadable.\n */\n needsDefinition: boolean;\n };\n directory?: { holds: readonly TermField[]; render: (term: Term) => string };\n}\n\n/**\n * One path per term: `<id><ext>`, or `<lang>/<id><ext>` when the set holds\n * more than one language. A language's directory is spelled as its first term\n * spells it.\n */\nfunction pagePaths(terms: readonly Term[], target: TermTarget, extension: string): string[] {\n const multilingual = isMultilingual(terms);\n const spelling = new Map<string, string>();\n const seen = new Set<string>();\n return terms.map((term) => {\n if (UNSAFE_NAME.test(term.id) || term.id === \".\" || term.id === \"..\") {\n throw new TermError(`the id \"${term.id}\" cannot name a file. Give the term an id without path characters.`);\n }\n if (!multilingual) {\n if (seen.has(term.id)) {\n throw new TermError(`two terms have the id \"${term.id}\", and a directory holds one file per id.`);\n }\n seen.add(term.id);\n return join(target.path, `${term.id}${extension}`);\n }\n const key = languageKey(term);\n const language = spelling.get(key) ?? languageOf(term);\n spelling.set(key, language);\n if (UNSAFE_NAME.test(language) || language === \".\" || language === \"..\") {\n throw new TermError(\n `the language \"${language}\" cannot name a directory. Give the term a language without path characters.`,\n );\n }\n if (seen.has(`${key} ${term.id}`)) {\n throw new TermError(\n `two terms have the id \"${term.id}\" in ${language}, and a directory holds one file per id in each language.`,\n );\n }\n seen.add(`${key} ${term.id}`);\n return join(target.path, language, `${term.id}${extension}`);\n });\n}\n\n/** The terms a one-language construct writes: the first term's language. The rest are reported. */\nfunction firstLanguage(terms: readonly Term[]): { kept: Term[]; otherLanguages?: TermRender[\"otherLanguages\"] } {\n const [first] = terms;\n if (first === undefined || !isMultilingual(terms)) return { kept: [...terms] };\n const key = languageKey(first);\n return {\n kept: terms.filter((t) => languageKey(t) === key),\n otherLanguages: {\n written: languageOf(first),\n terms: terms.filter((t) => languageKey(t) !== key).map((t) => ({ id: t.id, language: languageOf(t) })),\n },\n };\n}\n\nfunction documentWriter(spec: DocumentSpec): TermWriter {\n const { directory } = spec;\n return {\n format: spec.format,\n shapes: directory === undefined ? [\"file\"] : [\"file\", \"directory\"],\n holds: (shape: TermShape) => (shape === \"directory\" && directory !== undefined ? directory.holds : spec.file.holds),\n render(terms, target): TermRender {\n if (target.shape === \"directory\" && directory !== undefined) {\n const paths = pagePaths(terms, target, spec.extension);\n return {\n files: terms.map((term, i) => ({ path: paths[i] ?? \"\", content: directory.render(term) })),\n removals: [],\n dropped: droppedFields(terms, directory.holds),\n skipped: [],\n };\n }\n requireShape(spec.format, target, \"file\");\n const { kept, otherLanguages } = firstLanguage(terms);\n const written = spec.file.needsDefinition ? kept.filter((t) => t.record.definition !== undefined) : kept;\n return {\n files: [{ path: target.path, content: spec.file.render(written) }],\n removals: [],\n dropped: droppedFields(written, spec.file.holds),\n skipped: kept.filter((t) => !written.includes(t)).map((t) => t.id),\n ...(otherLanguages === undefined ? {} : { otherLanguages }),\n };\n },\n };\n}\n\n/** Entries at indentation zero, a blank line between them, each indented to `indent`. */\nfunction entriesBlock(entries: readonly string[], indent = \"\"): string[] {\n return entries.flatMap((entry, i) => [\n ...(i === 0 ? [] : [\"\"]),\n `${indent}${reindent(entry, indent, \"\\n\")}`,\n ]);\n}\n\n/** Every line of each entry indented, no blank line between: markup keeps its entries adjacent. */\nfunction markupBlock(entries: readonly string[], indent: string): string[] {\n return entries.map((entry) => `${indent}${reindent(entry, indent, \"\\n\")}`);\n}\n\nfunction textPage(format: string): (term: Term) => string {\n return (term) => metadataPage(format, term);\n}\n\n/** The frontmatter a many-per-file text document opens with, or none when it would be empty. */\nfunction listFrontmatter(terms: readonly Term[], type: boolean): string[] {\n const metadata: Record<string, unknown> = {};\n if (type) metadata[\"type\"] = \"term-set\";\n const language = sharedLanguage(terms);\n if (language !== undefined) metadata[\"language\"] = language;\n if (Object.keys(metadata).length === 0) return [];\n return [yamlFrontmatter(metadata).replace(/\\n$/, \"\"), \"\"];\n}\n\nfunction markdownList(terms: readonly Term[]): string {\n return fileOf([...listFrontmatter(terms, true), ...entriesBlock(terms.map((t) => markdownEntry(t.record)))]);\n}\n\nconst XML_DECLARATION = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>';\n\nfunction langAttribute(language: string | undefined): string {\n return language === undefined ? \"\" : ` xml:lang=\"${xmlAttribute(language)}\"`;\n}\n\nexport const markdownWriter = documentWriter({\n format: \"markdown\",\n extension: \".md\",\n file: { holds: LIST_HOLDS, render: markdownList, needsDefinition: true },\n directory: { holds: TERM_FIELDS, render: textPage(\"markdown\") },\n});\n\nexport const mdxWriter = documentWriter({\n format: \"mdx\",\n extension: \".mdx\",\n file: { holds: LIST_HOLDS, render: markdownList, needsDefinition: true },\n directory: { holds: TERM_FIELDS, render: textPage(\"mdx\") },\n});\n\nexport const asciidocWriter = documentWriter({\n format: \"asciidoc\",\n extension: \".adoc\",\n file: {\n holds: LIST_HOLDS,\n needsDefinition: true,\n render: (terms) =>\n fileOf([...listFrontmatter(terms, false), \"[glossary]\", ...entriesBlock(terms.map((t) => asciidocEntry(t.record)))]),\n },\n directory: { holds: TERM_FIELDS, render: textPage(\"asciidoc\") },\n});\n\nexport const rstWriter = documentWriter({\n format: \"rst\",\n extension: \".rst\",\n file: {\n holds: LIST_HOLDS,\n needsDefinition: true,\n render: (terms) =>\n fileOf([\n ...listFrontmatter(terms, false),\n \".. glossary::\",\n \"\",\n ...entriesBlock(\n terms.map((t) => rstEntry(t.record)),\n \" \",\n ),\n ]),\n },\n directory: { holds: TERM_FIELDS, render: textPage(\"rst\") },\n});\n\nexport const htmlWriter = documentWriter({\n format: \"html\",\n extension: \".html\",\n file: {\n holds: LIST_HOLDS,\n needsDefinition: true,\n render: (terms) => {\n const language = sharedLanguage(terms);\n return fileOf([\n \"<!DOCTYPE html>\",\n \"<html>\",\n \" <head>\",\n \" <title>Glossary</title>\",\n ' <meta name=\"type\" content=\"term-set\">',\n ...(language === undefined ? [] : [` <meta name=\"language\" content=\"${xmlAttribute(language)}\">`]),\n \" </head>\",\n \" <body>\",\n \" <dl>\",\n ...markupBlock(terms.map(htmlDlEntry), \" \"),\n \" </dl>\",\n \" </body>\",\n \"</html>\",\n ]);\n },\n },\n directory: { holds: TERM_FIELDS, render: htmlPage },\n});\n\nexport const ditaWriter = documentWriter({\n format: \"dita\",\n extension: \".dita\",\n file: {\n holds: DITA_HOLDS,\n needsDefinition: false,\n render: (terms) =>\n fileOf([\n XML_DECLARATION,\n '<!DOCTYPE glossgroup PUBLIC \"-//OASIS//DTD DITA 2.0 Glossary Group//EN\" \"glossgroup.dtd\">',\n `<glossgroup id=\"glossary\"${langAttribute(sharedLanguage(terms))}>`,\n \" <title>Glossary</title>\",\n ...markupBlock(terms.map((t) => ditaEntry(t)), \" \"),\n \"</glossgroup>\",\n ]),\n },\n directory: {\n holds: DITA_HOLDS,\n render: (term) =>\n fileOf([\n XML_DECLARATION,\n '<!DOCTYPE glossentry PUBLIC \"-//OASIS//DTD DITA 2.0 Glossary Entry//EN\" \"glossentry.dtd\">',\n ditaEntry(term, term.language),\n ]),\n },\n});\n\nexport const docbookWriter = documentWriter({\n format: \"docbook\",\n extension: \".xml\",\n file: {\n holds: DOCBOOK_HOLDS,\n needsDefinition: false,\n render: (terms) =>\n fileOf([\n XML_DECLARATION,\n `<glossary xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\"${langAttribute(sharedLanguage(terms))}>`,\n \" <title>Glossary</title>\",\n ...markupBlock(terms.map(docbookEntry), \" \"),\n \"</glossary>\",\n ]),\n },\n});\n\nexport const DOCUMENT_WRITERS: readonly TermWriter[] = [\n markdownWriter,\n mdxWriter,\n asciidocWriter,\n rstWriter,\n htmlWriter,\n ditaWriter,\n docbookWriter,\n];\n","/**\n * A term page: one term per file, its record in the file's metadata channel\n * and an empty body. The metadata reads `title` (the label), `description`\n * (the abstract, when there is one), `type: term`, `id`, `language` (when the\n * term has one), then every terminology field in the vocabulary's order.\n */\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { extractorByName } from \"../../../meta/internal.js\";\nimport { TermError } from \"../../errors.js\";\nimport { TERM_FIELDS, type Term } from \"../../types.js\";\nimport { fileOf, xmlAttribute, xmlText } from \"./markup.js\";\n\nexport function pageMetadata(term: Term): Record<string, unknown> {\n const { record } = term;\n const metadata: Record<string, unknown> = { title: record.label };\n if (record.abstract !== undefined) metadata[\"description\"] = record.abstract;\n metadata[\"type\"] = \"term\";\n metadata[\"id\"] = term.id;\n if (term.language !== undefined) metadata[\"language\"] = term.language;\n for (const field of TERM_FIELDS) {\n const value = record[field];\n if (value !== undefined) metadata[field] = value;\n }\n return metadata;\n}\n\n/**\n * A Markdown, MDX, AsciiDoc or reStructuredText term page: a fenced YAML block\n * and no body. The block is written by the format's own extractor, the one an\n * in-place write goes through, so a render and a write-back agree on how a\n * value is spelled.\n */\nexport function metadataPage(format: string, term: Term): string {\n const apply = extractorByName(format)?.apply;\n if (apply === undefined) throw new TermError(`manni cannot write ${format} metadata.`);\n return apply(\"---\\n---\\n\", pageMetadata(term));\n}\n\n/** A fenced YAML block, which Markdown, MDX, AsciiDoc and reStructuredText all read. */\nexport function yamlFrontmatter(metadata: Record<string, unknown>): string {\n return `---\\n${stringifyYaml(metadata, { lineWidth: 0 })}---\\n`;\n}\n\n/**\n * A `<meta content>` value as the HTML extractor reads it back: the value is\n * parsed as a YAML scalar, so a string that would parse as anything else, and\n * every list, is written as JSON, which is YAML and stays on one line.\n */\nfunction metaContent(value: unknown): string {\n if (typeof value === \"string\" && !value.includes(\"\\n\")) {\n try {\n if (parseYaml(value) === value) return value;\n } catch {\n // Not plain YAML: JSON below.\n }\n }\n return JSON.stringify(value);\n}\n\nexport function htmlPage(term: Term): string {\n const metadata = pageMetadata(term);\n const metas = Object.entries(metadata)\n .filter(([key]) => key !== \"title\")\n .map(([key, value]) => ` <meta name=\"${xmlAttribute(key)}\" content=\"${xmlAttribute(metaContent(value))}\">`);\n return fileOf([\n \"<!DOCTYPE html>\",\n \"<html>\",\n \" <head>\",\n ` <title>${xmlText(term.record.label)}</title>`,\n ...metas,\n \" </head>\",\n \" <body></body>\",\n \"</html>\",\n ]);\n}\n","/**\n * `term write -f csv`: one row per id, for a translation or terminology\n * system to import. The headers describe themselves, so a system maps columns\n * by name: `ID`, then six columns per language the set holds, each filled\n * from that language's term, then the four language-neutral relation columns,\n * which take the first term's value.\n */\nimport type { MergeConflict, Term, TermField, TermRecord, TermShape, TermWriter } from \"../../types.js\";\nimport { conceptGroups, mergeFirst } from \"./merge.js\";\nimport { droppedFields, languageKey, languageOf, requireShape } from \"./render-util.js\";\n\n/** The fields the columns hold: the ten of terminology 1.0.0. Every other field is reported dropped. */\nconst HOLDS = [\n \"label\",\n \"definition\",\n \"abstract\",\n \"alt-labels\",\n \"hidden-labels\",\n \"broader\",\n \"narrower\",\n \"related-terms\",\n \"see\",\n \"scope-note\",\n] as const satisfies readonly TermField[];\ntype CsvField = (typeof HOLDS)[number];\n\n/** The per-language columns, in order, with their header names. */\nconst LANGUAGE_COLUMNS: readonly (readonly [CsvField, string])[] = [\n [\"label\", \"Term\"],\n [\"definition\", \"Definition\"],\n [\"abstract\", \"Abstract\"],\n [\"alt-labels\", \"Alt labels\"],\n [\"hidden-labels\", \"Hidden labels\"],\n [\"scope-note\", \"Scope note\"],\n];\n\n/** The columns every language shares: they name other terms, not words in a language. */\nconst NEUTRAL_COLUMNS: readonly (readonly [CsvField, string])[] = [\n [\"broader\", \"Broader\"],\n [\"narrower\", \"Narrower\"],\n [\"related-terms\", \"Related terms\"],\n [\"see\", \"See\"],\n];\n\n/**\n * The one separator a list field is joined with inside its cell. A value that\n * itself contains ` | ` cannot be split back apart; that is the price of one\n * cell per field, which is what a translation system imports.\n */\nconst LIST_SEPARATOR = \" | \";\n\n/** RFC 4180 quoting: a cell holding a quote, comma or line break is quoted, with quotes doubled. */\nfunction cell(value: string): string {\n return /[\",\\r\\n]/.test(value) ? `\"${value.replaceAll('\"', '\"\"')}\"` : value;\n}\n\nfunction fieldText(record: Partial<Pick<TermRecord, CsvField>>, field: CsvField): string {\n const value = record[field];\n if (value === undefined) return \"\";\n return typeof value === \"string\" ? value : value.join(LIST_SEPARATOR);\n}\n\n/**\n * The set joined on id: one row per id, holding at most one term per\n * language. A second term with an id and language a row already holds starts\n * a row of its own, so a repeated id in one language is written, not lost.\n */\nfunction rowsOf(terms: readonly Term[]): Term[][] {\n return conceptGroups(terms).flatMap((group) => {\n const rows: Term[][] = [];\n for (const term of group) {\n const row = rows.find((r) => !r.some((t) => languageKey(t) === languageKey(term)));\n if (row === undefined) rows.push([term]);\n else row.push(term);\n }\n return rows;\n });\n}\n\nexport const csvWriter: TermWriter = {\n format: \"csv\",\n shapes: [\"file\"],\n holds: (_shape: TermShape) => HOLDS,\n render(terms, target) {\n requireShape(\"csv\", target, \"file\");\n // Languages in order of first appearance, so the columns follow the set.\n const languages = new Map<string, string>();\n for (const term of terms) {\n if (!languages.has(languageKey(term))) languages.set(languageKey(term), languageOf(term));\n }\n\n const header = [\n \"ID\",\n ...[...languages.values()].flatMap((language) => LANGUAGE_COLUMNS.map(([, name]) => `${name} [${language}]`)),\n ...NEUTRAL_COLUMNS.map(([, name]) => name),\n ];\n const conflicts: MergeConflict[] = [];\n const rows = rowsOf(terms).map((row) => {\n const [first] = row;\n const id = first?.id ?? \"\";\n // The neutral columns name other terms, so the row holds them once.\n const neutral = mergeFirst(\n id,\n row.map((t) => Object.fromEntries(NEUTRAL_COLUMNS.map(([field]) => [field, t.record[field]]))),\n );\n conflicts.push(...neutral.conflicts);\n return [\n id,\n ...[...languages.keys()].flatMap((language) => {\n const own = row.find((t) => languageKey(t) === language);\n return LANGUAGE_COLUMNS.map(([field]) => (own === undefined ? \"\" : fieldText(own.record, field)));\n }),\n ...NEUTRAL_COLUMNS.map(([field]) => fieldText(neutral.merged, field)),\n ];\n });\n\n const content = [header, ...rows].map((row) => `${row.map(cell).join(\",\")}\\n`).join(\"\");\n return {\n files: [{ path: target.path, content }],\n removals: [],\n dropped: droppedFields(terms, HOLDS),\n skipped: [],\n ...(conflicts.length === 0 ? {} : { conflicts }),\n };\n },\n};\n","/**\n * `term write -f json`: the set as `{ \"terms\": [...] }`, one object per term\n * holding its id, its language when it has one, and every record field in the\n * vocabulary's order. It is the shape `term list -f json` prints, so it holds\n * every field.\n */\nimport { TERM_FIELDS, type TermShape, type TermWriter } from \"../../types.js\";\nimport { droppedFields, requireShape } from \"./render-util.js\";\n\nexport const jsonWriter: TermWriter = {\n format: \"json\",\n shapes: [\"file\"],\n holds: (_shape: TermShape) => TERM_FIELDS,\n render(terms, target) {\n requireShape(\"json\", target, \"file\");\n const entries = terms.map((term) => {\n const entry: Record<string, unknown> = { id: term.id };\n if (term.language !== undefined) entry[\"language\"] = term.language;\n for (const field of TERM_FIELDS) {\n const value = term.record[field];\n if (value !== undefined) entry[field] = value;\n }\n return entry;\n });\n const content = `${JSON.stringify({ terms: entries }, null, 2)}\\n`;\n return {\n files: [{ path: target.path, content }],\n removals: [],\n dropped: droppedFields(terms, TERM_FIELDS),\n skipped: [],\n };\n },\n};\n","/**\n * `term write -f skos`: the set as a SKOS concept scheme in JSON-LD. The\n * document is the scheme, and each term is a concept at `#<id>` within it.\n *\n * A relation (`broader`, `narrower`, `related-terms`) names another term by\n * label or id, and becomes a reference to that concept. A value naming no term\n * is left out: a dangling reference is `check`'s finding, not a field this\n * format cannot hold.\n */\nimport type { Term, TermField, TermShape, TermWriter } from \"../../types.js\";\nimport { droppedFields, requireShape } from \"./render-util.js\";\n\nconst HOLDS: readonly TermField[] = [\n \"label\",\n \"definition\",\n \"alt-labels\",\n \"hidden-labels\",\n \"broader\",\n \"narrower\",\n \"related-terms\",\n \"scope-note\",\n];\n\nconst CONTEXT = {\n skos: \"http://www.w3.org/2004/02/skos/core#\",\n dcterms: \"http://purl.org/dc/terms/\",\n};\n\n/** The scheme's `@id`: the document itself, which the concepts' `#<id>` fragments sit in. */\nconst SCHEME_ID = \"\";\n\ntype Literal = string | { \"@value\": string; \"@language\": string };\n\nfunction literal(term: Term, value: string): Literal {\n return term.language === undefined ? value : { \"@value\": value, \"@language\": term.language };\n}\n\n/** The term a relation value names: a label first, then an id, compared case-insensitively. Never `self`. */\nfunction resolve(terms: readonly Term[], self: Term, value: string): Term | undefined {\n const wanted = value.toLowerCase();\n const others = terms.filter((t) => t !== self);\n return (\n others.find((t) => t.record.label.toLowerCase() === wanted) ?? others.find((t) => t.id.toLowerCase() === wanted)\n );\n}\n\nfunction references(terms: readonly Term[], self: Term, values: readonly string[] | undefined): { \"@id\": string }[] {\n const ids: string[] = [];\n for (const value of values ?? []) {\n const target = resolve(terms, self, value);\n if (target !== undefined && !ids.includes(target.id)) ids.push(target.id);\n }\n return ids.map((id) => ({ \"@id\": `#${id}` }));\n}\n\nfunction concept(terms: readonly Term[], term: Term): Record<string, unknown> {\n const { record } = term;\n const node: Record<string, unknown> = {\n \"@id\": `#${term.id}`,\n \"@type\": \"skos:Concept\",\n \"skos:inScheme\": { \"@id\": SCHEME_ID },\n \"skos:prefLabel\": literal(term, record.label),\n };\n if (record[\"alt-labels\"] !== undefined) node[\"skos:altLabel\"] = record[\"alt-labels\"].map((v) => literal(term, v));\n if (record[\"hidden-labels\"] !== undefined) {\n node[\"skos:hiddenLabel\"] = record[\"hidden-labels\"].map((v) => literal(term, v));\n }\n if (record.definition !== undefined) node[\"skos:definition\"] = literal(term, record.definition);\n if (record[\"scope-note\"] !== undefined) node[\"skos:scopeNote\"] = literal(term, record[\"scope-note\"]);\n const relations = [\n [\"skos:broader\", record.broader],\n [\"skos:narrower\", record.narrower],\n [\"skos:related\", record[\"related-terms\"]],\n ] as const;\n for (const [key, values] of relations) {\n const refs = references(terms, term, values);\n if (refs.length > 0) node[key] = refs;\n }\n return node;\n}\n\nexport const skosWriter: TermWriter = {\n format: \"skos\",\n shapes: [\"file\"],\n holds: (_shape: TermShape) => HOLDS,\n render(terms, target) {\n requireShape(\"skos\", target, \"file\");\n const document = {\n \"@context\": CONTEXT,\n \"@graph\": [\n {\n \"@id\": SCHEME_ID,\n \"@type\": \"skos:ConceptScheme\",\n \"dcterms:description\": \"Generated by manni term write.\",\n },\n ...terms.map((term) => concept(terms, term)),\n ],\n };\n const content = `${JSON.stringify(document, null, 2)}\\n`;\n return {\n files: [{ path: target.path, content }],\n removals: [],\n dropped: droppedFields(terms, HOLDS),\n skipped: [],\n };\n },\n};\n","/**\n * `term write -f tbx` and `-f tbx3`: the set as a TBX v2 (`<martif>`) or v3\n * (`<tbx>`) termbase, the exchange format translation memory and terminology\n * systems import (proposal 0084).\n *\n * One entry per id, in first-appearance order, with a language section per\n * term in set order, written in `tbx-model.ts`'s canonical form. Where terms\n * sharing an id disagree on `concept-entry`, the first term's value is kept\n * and the render reports it.\n *\n * The header depends on where the terms came from:\n * - all from one TBX file, at the version `-f` names: that file, with\n * unchanged entries and everything outside them copied byte for byte;\n * - all from one TBX file at the other version: canonical entries, under a\n * header holding the source header's children, and the source's back\n * matter after them, `refObjectList` (v2) renamed `refObjectSec` (v3) or\n * back, since entries' `target`s point into it;\n * - anything else: manni's own header, and each TBX source is reported as a\n * header dropped.\n */\nimport { TERM_FIELDS, type MergeConflict, type Term, type TermField, type TermShape, type TermWriter } from \"../../types.js\";\nimport { exportTbxSource } from \"../readers/tbx.js\";\nimport {\n TBX_V3_NAMESPACE,\n escapeAttribute,\n lf,\n tbxEntryLines,\n tbxSourceOf,\n type TbxDocument,\n type TbxVersion,\n} from \"../readers/tbx-model.js\";\nimport { reindent } from \"./markup.js\";\nimport { conceptGroups, mergeFirst } from \"./merge.js\";\nimport { DEFAULT_LANGUAGE, droppedFields, requireShape } from \"./render-util.js\";\n\n/** TBX-Basic has no category for these. */\nconst NOT_HELD: readonly TermField[] = [\"abstract\", \"broader\", \"narrower\", \"related-terms\", \"see\", \"scope-note\"];\nconst HOLDS: readonly TermField[] = TERM_FIELDS.filter((field) => !NOT_HELD.includes(field));\n\n/** The designation fields only TBX-Linguist defines. A v3 file carrying one declares itself TBX-Linguist. */\nconst LINGUIST_FIELDS = [\"register\", \"reading\", \"reading-note\", \"grammatical-number\", \"transfer-comments\"] as const;\n\n/** Where the body's entries start: inside `<text><body>`. */\nconst ENTRY_INDENT = \" \";\n\n/** manni's own header content, at the header's children's indentation. */\nconst OWN_HEADER = [\" <fileDesc>\", \" <sourceDesc>\", \" <p>manni term write</p>\", \" </sourceDesc>\", \" </fileDesc>\"];\n\nfunction isLinguist(terms: readonly Term[]): boolean {\n return terms.some((t) => (t.record.designations ?? []).some((d) => LINGUIST_FIELDS.some((f) => d[f] !== undefined)));\n}\n\n/** The TBX document every term was read from, when there is one and only one. */\nfunction soleSource(terms: readonly Term[]): { document: TbxDocument; file: string } | undefined {\n let found: { document: TbxDocument; file: string } | undefined;\n for (const term of terms) {\n const source = tbxSourceOf(term);\n if (source === undefined || (found !== undefined && found.document !== source.document)) return undefined;\n found ??= { document: source.document, file: term.location.file };\n }\n return found?.document.body === undefined ? undefined : found;\n}\n\n/** The TBX files the terms came from, as their terms name them, in order of first appearance. */\nexport function tbxHeaderFiles(terms: readonly Term[]): string[] {\n const files = new Map<TbxDocument, string>();\n for (const term of terms) {\n const source = tbxSourceOf(term);\n if (source !== undefined && !files.has(source.document)) files.set(source.document, term.location.file);\n }\n return [...files.values()];\n}\n\n/**\n * An element's children from the source, at `indent` and LF, or `undefined`\n * when it has none. Blank lines around them are trimmed, and one between them\n * is kept, empty.\n */\nfunction carried(document: TbxDocument, span: { start: number; end: number } | undefined, indent: string): string[] | undefined {\n if (span === undefined) return undefined;\n const raw = lf(document.content.slice(span.start, span.end));\n if (raw.trim() === \"\") return undefined;\n const lines = raw.replace(/^(?:[ \\t]*\\n)+/, \"\").replace(/(?:\\n[ \\t]*)+$/, \"\").split(\"\\n\");\n const blank = (line: string): boolean => line.trim() === \"\";\n const strip = Math.min(...lines.filter((line) => !blank(line)).map((line) => /^[ \\t]*/.exec(line)?.[0].length ?? 0));\n return lines.map((line) => (blank(line) ? \"\" : `${indent}${line.slice(strip).trimEnd()}`));\n}\n\n/** The source's `<back>` at the other version: the one element v3 renamed is renamed, and the rest is carried as it is. */\nfunction carriedBack(document: TbxDocument, version: TbxVersion): string[] {\n if (document.back === undefined) return [];\n const [from, to] = version === 3 ? [\"refObjectList\", \"refObjectSec\"] : [\"refObjectSec\", \"refObjectList\"];\n const rename = new RegExp(`(</?)${from}(?=[\\\\s/>])`, \"g\");\n const lines = carried(document, document.back, \" \")?.map((line) => line.replace(rename, `$1${to}`));\n return lines === undefined ? [\" <back/>\"] : [\" <back>\", ...lines, \" </back>\"];\n}\n\n/** Every entry, canonical, at the body's indentation; and where terms sharing an id disagree on `concept-entry`. */\nfunction entries(terms: readonly Term[], version: TbxVersion): { lines: string[]; conflicts: MergeConflict[] } {\n const lines: string[] = [];\n const conflicts: MergeConflict[] = [];\n for (const group of conceptGroups(terms)) {\n const [head, ...rest] = group;\n if (head === undefined) continue;\n const merge = mergeFirst(\n head.id,\n group.map((t) => t.record[\"concept-entry\"]),\n \"concept-entry.\",\n );\n conflicts.push(...merge.conflicts);\n const { \"concept-entry\": _concept, ...record } = head.record;\n const joined: Term = {\n ...head,\n record: Object.keys(merge.merged).length === 0 ? record : { ...record, \"concept-entry\": merge.merged },\n };\n const text = tbxEntryLines([joined, ...rest], { version, style: \"dca\" }).join(\"\\n\");\n lines.push(`${ENTRY_INDENT}${reindent(text, ENTRY_INDENT, \"\\n\")}`);\n }\n return { lines, conflicts };\n}\n\nfunction rootOpen(version: TbxVersion, terms: readonly Term[]): string {\n // The file's default language is the first term's; each language section states its own anyway.\n const language = escapeAttribute(terms[0]?.language ?? DEFAULT_LANGUAGE);\n if (version === 2) return `<martif type=\"TBX\" xml:lang=\"${language}\">`;\n const type = isLinguist(terms) ? \"TBX-Linguist\" : \"TBX-Basic\";\n return `<tbx type=\"${type}\" style=\"dca\" xml:lang=\"${language}\" xmlns=\"${TBX_V3_NAMESPACE}\">`;\n}\n\nfunction tbxWriterFor(format: \"tbx\" | \"tbx3\", version: TbxVersion): TermWriter {\n return {\n format,\n shapes: [\"file\"],\n holds: (_shape: TermShape) => HOLDS,\n render(terms, target) {\n requireShape(format, target, \"file\");\n const dropped = droppedFields(terms, HOLDS);\n const source = soleSource(terms);\n if (source?.document.version === version) {\n const exported = exportTbxSource(source.document, source.file, terms);\n return {\n files: [{ path: target.path, content: exported.content }],\n removals: [],\n dropped,\n skipped: [],\n ...(exported.conflicts.length === 0 ? {} : { conflicts: exported.conflicts }),\n droppedHeaders: [],\n };\n }\n const header = (source === undefined ? undefined : carried(source.document, source.document.header, \" \")) ?? OWN_HEADER;\n const [root, headerTag] = version === 2 ? [\"martif\", \"martifHeader\"] : [\"tbx\", \"tbxHeader\"];\n const body = entries(terms, version);\n const lines = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n rootOpen(version, terms),\n ` <${headerTag}>`,\n ...header,\n ` </${headerTag}>`,\n \" <text>\",\n \" <body>\",\n ...body.lines,\n \" </body>\",\n ...(source === undefined ? [] : carriedBack(source.document, version)),\n \" </text>\",\n `</${root}>`,\n ];\n return {\n files: [{ path: target.path, content: lines.map((line) => `${line}\\n`).join(\"\") }],\n removals: [],\n dropped,\n skipped: [],\n ...(body.conflicts.length === 0 ? {} : { conflicts: body.conflicts }),\n droppedHeaders: source === undefined ? tbxHeaderFiles(terms) : [],\n };\n },\n };\n}\n\nexport const tbxWriter = tbxWriterFor(\"tbx\", 2);\nexport const tbx3Writer = tbxWriterFor(\"tbx3\", 3);\n","/**\n * `term write -f vale`: a Vale style named `Terms`, written into a styles\n * directory (proposal 0052 § 6). Every rule shape here was chosen against a\n * real Vale 3.20.0 run.\n *\n * - `Terms/Casing.yml` enforces the exact form of a designation that starts\n * with a capital or a non-letter: `Kubernetes`, `K8s`, `.Net`.\n * - `Terms/Lowercase.yml` enforces an all-lowercase designation, allowing a\n * capital first letter so a sentence can start with it.\n * - `Terms/SentenceStart.yml` enforces a designation that starts lowercase and\n * holds a capital later (`iPhone`, `meta-schema URI`), allowing a capital\n * first letter the same way.\n * - `Terms/Deprecated.yml` swaps each hidden-label for its term's label.\n * - `Terms/<ACRONYM>.yml` asks for an all-caps alt-label to be spelled out on\n * first use, as `<label> (<ACRONYM>)`.\n *\n * An all-caps designation gets no casing rule: enforcing the case of `IT` fires\n * on nearly every paragraph. manni owns `Terms/`: every file opens with the\n * marker line, a file without it is someone else's and stops the write, and a\n * marked file the set no longer produces is removed.\n */\nimport { isAbsolute, join, relative, sep } from \"node:path\";\nimport { stringify } from \"yaml\";\nimport { TermError } from \"../../errors.js\";\nimport type { RenderedFile, TermField, TermShape, TermWriter } from \"../../types.js\";\nimport { droppedFields, requireShape } from \"./render-util.js\";\n\nexport const VALE_MARKER = \"# Generated by manni term write. Edit the terms, not this file.\";\nconst STYLE = \"Terms\";\nconst HOLDS: readonly TermField[] = [\"label\", \"alt-labels\", \"hidden-labels\"];\n/** The style's own files, which an acronym file may not replace. */\nconst OWN_FILES = [\"Casing\", \"Lowercase\", \"SentenceStart\", \"Deprecated\"] as const;\n\nconst REGEX_METACHARACTERS = /[\\\\^$.|?*+()[\\]{}]/g;\n\nfunction escapeRegex(value: string): string {\n return value.replace(REGEX_METACHARACTERS, \"\\\\$&\");\n}\n\n/**\n * A swap value as Vale reads it. Vale matches the value as a pattern against\n * the text it found, so a value holding a metacharacter is escaped, and only\n * then: the `%s` in the message prints the value, so the escape shows in that\n * message (`Use 'C\\+\\+' instead of 'c++'`). An exact message is worth more for\n * the common case than for the rare one.\n */\nfunction swapValue(value: string): string {\n return value.search(REGEX_METACHARACTERS) === -1 ? value : escapeRegex(value);\n}\n\n/**\n * A YAML scalar Vale's parser reads back as the same string. YAML 1.1 rules\n * quote `yes`, `on` and friends, which a 1.1 parser would read as booleans.\n * A line break cannot sit in a one-line key, so such a string is written as a\n * JSON string, which is valid double-quoted YAML.\n */\nfunction scalar(value: string): string {\n if (/[\\r\\n]/.test(value)) return JSON.stringify(value);\n const out = stringify(value, { version: \"1.1\", lineWidth: 0 });\n return out.endsWith(\"\\n\") ? out.slice(0, -1) : out;\n}\n\n/** A YAML double-quoted scalar on one line: a raw line break would fold to a space. */\nfunction doubleQuoted(value: string): string {\n const escaped = value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll('\"', '\\\\\"')\n .replaceAll(\"\\n\", \"\\\\n\")\n .replaceAll(\"\\r\", \"\\\\r\");\n return `\"${escaped}\"`;\n}\n\n/** A YAML single-quoted scalar, which keeps backslashes literal for a regex. */\nfunction singleQuoted(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\").replaceAll(/[\\r\\n]+/g, \" \")}'`;\n}\n\n/** Vale formats a message with Go's `fmt`, so a literal `%` is doubled. */\nfunction messageText(value: string): string {\n return value.replaceAll(\"%\", \"%%\");\n}\n\ntype Casing = \"none\" | \"all-caps\" | \"lowercase\" | \"lowercase-initial\" | \"mixed\";\n\nfunction casingOf(value: string): Casing {\n if (!/[\\p{Lu}\\p{Ll}\\p{Lt}]/u.test(value)) return \"none\";\n const letters = value.match(/\\p{L}/gu)?.length ?? 0;\n if (letters >= 2 && !/[\\p{Ll}\\p{Lt}]/u.test(value)) return \"all-caps\";\n if (!/[\\p{Lu}\\p{Lt}]/u.test(value)) return \"lowercase\";\n // `iPhone`: a mixed designation whose first character is a lowercase letter.\n if (/^\\p{Ll}/u.test(value)) return \"lowercase-initial\";\n return \"mixed\";\n}\n\n/** `progressive lens` → `[Pp]rogressive lens`: the first letter may be a capital, to start a sentence. */\nfunction sentenceStartPattern(value: string): string {\n const [first = \"\", ...rest] = Array.from(value);\n const upper = first.toUpperCase();\n const head = upper !== first && Array.from(upper).length === 1 ? `[${upper}${first}]` : escapeRegex(first);\n return `${head}${escapeRegex(rest.join(\"\"))}`;\n}\n\n/** A swap list in insertion order. A key already present keeps its first value, as YAML allows one. */\nclass Swaps {\n private readonly entries = new Map<string, string>();\n add(key: string, value: string): void {\n if (!this.entries.has(key)) this.entries.set(key, value);\n }\n get size(): number {\n return this.entries.size;\n }\n lines(): string[] {\n return [...this.entries].map(([key, value]) => ` ${scalar(key)}: ${scalar(value)}`);\n }\n}\n\n/**\n * A swap key with its own word boundaries. Vale wraps every key in `\\b…\\b`\n * unless a rule sets `nonword`, and Go regular expressions give `\\b` ASCII\n * word semantics. So a term whose first or last character is not an ASCII word\n * character never matched: `c++` before a space, `Café` before a full stop. A\n * real Vale 3.20.0 run confirmed `c++` went unflagged. Each edge is `\\b` beside\n * an ASCII word character and `\\B` beside anything else, which is exactly\n * Vale's default for an ordinary word and the right boundary for the rest.\n */\nconst ASCII_WORD = /^[A-Za-z0-9_]$/;\n\nfunction bounded(pattern: string, text: string): string {\n const chars = Array.from(text);\n const edge = (char: string | undefined): string =>\n char !== undefined && ASCII_WORD.test(char) ? \"\\\\b\" : \"\\\\B\";\n return `${edge(chars[0])}${pattern}${edge(chars.at(-1))}`;\n}\n\nfunction substitution(message: string, level: string, options: string[], swaps: Swaps): string {\n return [\n VALE_MARKER,\n \"extends: substitution\",\n `message: ${doubleQuoted(message)}`,\n `level: ${level}`,\n \"ignorecase: true\",\n \"nonword: true\",\n ...options,\n \"swap:\",\n ...swaps.lines(),\n ]\n .map((line) => `${line}\\n`)\n .join(\"\");\n}\n\nfunction acronymRule(acronym: string, label: string): string {\n const expansion = escapeRegex(label).replaceAll(/[\\r\\n]+/g, \" \");\n return [\n VALE_MARKER,\n \"extends: conditional\",\n `message: ${doubleQuoted(messageText(`Spell out '${acronym}' on first use, as '${label} (${acronym})'.`))}`,\n \"level: warning\",\n \"ignorecase: false\",\n `first: ${singleQuoted(`\\\\b(${escapeRegex(acronym)})\\\\b`)}`,\n `second: ${singleQuoted(`(?i)${expansion} \\\\((${escapeRegex(acronym)})\\\\)`)}`,\n ]\n .map((line) => `${line}\\n`)\n .join(\"\");\n}\n\n/** An acronym as a file name: anything a path or a Vale rule name cannot carry becomes `-`. */\nfunction acronymFileName(acronym: string): string {\n return acronym.replaceAll(/[^\\p{L}\\p{N}_-]/gu, \"-\");\n}\n\nfunction firstLine(content: string): string {\n const end = content.search(/\\r?\\n/);\n return end === -1 ? content : content.slice(0, end);\n}\n\nexport const valeWriter: TermWriter = {\n format: \"vale\",\n shapes: [\"directory\"],\n holds: (_shape: TermShape) => HOLDS,\n render(terms, target, context) {\n requireShape(\"vale\", target, \"directory\");\n const termsDir = join(target.path, STYLE);\n\n // Someone else's file in Terms/ stops the write before anything is computed.\n const marked: string[] = [];\n for (const [path, content] of context.existing) {\n const rel = relative(termsDir, path);\n if (rel === \"\" || rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) continue;\n if (firstLine(content) !== VALE_MARKER) {\n throw new TermError(`${path} was not written by manni. Move it, or pass -o <styles directory>.`);\n }\n if (!rel.includes(sep) && !rel.includes(\"/\")) marked.push(path);\n }\n\n const casing = new Swaps();\n const lowercase = new Swaps();\n const sentenceStart = new Swaps();\n const deprecated = new Swaps();\n const acronyms: { acronym: string; name: string; content: string }[] = [];\n const labels = new Set(terms.map((t) => t.record.label));\n\n for (const term of terms) {\n const { label } = term.record;\n const labelIsAllCaps = casingOf(label) === \"all-caps\";\n for (const designation of [label, ...(term.record[\"alt-labels\"] ?? [])]) {\n const kind = casingOf(designation);\n if (kind === \"lowercase\") lowercase.add(bounded(escapeRegex(designation), designation), sentenceStartPattern(designation));\n if (kind === \"lowercase-initial\") {\n sentenceStart.add(bounded(escapeRegex(designation.toLowerCase()), designation), sentenceStartPattern(designation));\n }\n if (kind === \"mixed\") casing.add(bounded(escapeRegex(designation.toLowerCase()), designation), swapValue(designation));\n if (kind !== \"all-caps\" || designation === label || labelIsAllCaps || labels.has(designation)) continue;\n const name = acronymFileName(designation);\n const own = OWN_FILES.find((file) => file.toLowerCase() === name.toLowerCase());\n if (own !== undefined) {\n throw new TermError(`the acronym \"${designation}\" would replace Terms/${own}.yml. Rename the alt-label.`);\n }\n const taken = acronyms.find((a) => a.name.toLowerCase() === name.toLowerCase());\n // The same acronym on a second term keeps the first term's rule.\n if (taken?.acronym === designation) continue;\n if (taken !== undefined) {\n throw new TermError(\n `the acronyms \"${taken.acronym}\" and \"${designation}\" would both write Terms/${taken.name}.yml. Rename one.`,\n );\n }\n acronyms.push({ acronym: designation, name, content: acronymRule(designation, label) });\n }\n for (const hidden of term.record[\"hidden-labels\"] ?? []) {\n deprecated.add(bounded(escapeRegex(hidden), hidden), swapValue(label));\n }\n }\n\n const files: RenderedFile[] = [];\n const add = (name: string, content: string): void => {\n files.push({ path: join(termsDir, `${name}.yml`), content });\n };\n if (casing.size > 0) {\n add(\"Casing\", substitution(\"Use '%s' instead of '%s'.\", \"error\", [\"vocab: false\"], casing));\n }\n if (lowercase.size > 0) {\n add(\n \"Lowercase\",\n substitution(\"Write '%[2]s' in lowercase, except to start a sentence.\", \"error\", [\"vocab: false\"], lowercase),\n );\n }\n if (sentenceStart.size > 0) {\n // Not Casing.yml: its message prints the value, which here is a pattern.\n add(\n \"SentenceStart\",\n substitution(\n \"Write '%[2]s' as the term list spells it, with a capital only to start a sentence.\",\n \"error\",\n [\"vocab: false\"],\n sentenceStart,\n ),\n );\n }\n if (deprecated.size > 0) {\n add(\"Deprecated\", substitution(\"Use '%s' instead of '%s'.\", \"warning\", [\"matchcase: true\"], deprecated));\n }\n for (const acronym of acronyms) add(acronym.name, acronym.content);\n\n // Compared without case: on a case-insensitive disk `pal.yml` and `PAL.yml`\n // are one file, and removing the old name would delete the new one.\n const produced = new Set(files.map((f) => relative(termsDir, f.path).toLowerCase()));\n const removals = marked.filter((path) => !produced.has(relative(termsDir, path).toLowerCase())).sort();\n\n return { files, removals, dropped: droppedFields(terms, HOLDS), skipped: [] };\n },\n};\n","/**\n * Writers for the formats a termbase leaves the docs in: TBX v2 and v3, SKOS, CSV, JSON,\n * and a Vale style.\n */\nimport type { TermWriter } from \"../../types.js\";\nimport { csvWriter } from \"./csv.js\";\nimport { jsonWriter } from \"./json.js\";\nimport { skosWriter } from \"./skos.js\";\nimport { tbx3Writer, tbxWriter } from \"./tbx.js\";\nimport { valeWriter } from \"./vale.js\";\n\nexport const INTERCHANGE_WRITERS: readonly TermWriter[] = [tbxWriter, tbx3Writer, skosWriter, csvWriter, jsonWriter, valeWriter];\n","/** Every term writer, one per `term write -f` value. */\nimport type { TermWriteFormat, TermWriter } from \"../../types.js\";\nimport { DOCUMENT_WRITERS } from \"./documents.js\";\nimport { INTERCHANGE_WRITERS } from \"./interchange.js\";\n\nexport const TERM_WRITERS: readonly TermWriter[] = [...DOCUMENT_WRITERS, ...INTERCHANGE_WRITERS];\n\nexport function writerFor(\n format: TermWriteFormat,\n writers: readonly TermWriter[] = TERM_WRITERS,\n): TermWriter | undefined {\n return writers.find((writer) => writer.format === format);\n}\n","/**\n * `manni term formats`: what is read and written, from the registries alone. A\n * construct a reader does not exist for is not listed, and `write` appears\n * only where a reader has `apply` or a registered document writer renders the\n * construct, so the listing never promises more than the build does.\n */\nimport { TERM_READERS } from \"../core/readers/index.js\";\nimport { TERM_WRITERS } from \"../core/writers/index.js\";\nimport type { TermConstruct, TermReader, TermShape, TermWriteFormat, TermWriter } from \"../types.js\";\n\nexport const FORMATS_FORMATS = [\"pretty\", \"json\"] as const;\nexport type FormatsFormat = (typeof FORMATS_FORMATS)[number];\n\nexport interface FormatRow {\n /** The input format a reader reads (`markdown`, `xml`), or a `write -f` value. */\n format: string;\n /** The construct, for a reader's row. */\n construct?: TermConstruct;\n /** What the construct or the render is called: `definition list`, `TBX v2`; empty for none. */\n label: string;\n read: boolean;\n write: boolean;\n}\n\n/**\n * The construct each document `-f` value renders, per shape, and the input\n * format that construct is read back from. A directory holds one entry per\n * file, which is a page; a file holds them all, in the format's list construct.\n */\nexport const DOCUMENT_RENDERS: Partial<\n Record<TermWriteFormat, { input: string; shapes: Partial<Record<TermShape, TermConstruct>> }>\n> = {\n markdown: { input: \"markdown\", shapes: { directory: \"page\", file: \"markdown-deflist\" } },\n mdx: { input: \"mdx\", shapes: { directory: \"page\", file: \"markdown-deflist\" } },\n asciidoc: { input: \"asciidoc\", shapes: { directory: \"page\", file: \"asciidoc-glossary\" } },\n rst: { input: \"rst\", shapes: { directory: \"page\", file: \"rst-glossary\" } },\n html: { input: \"html\", shapes: { directory: \"page\", file: \"html-dl\" } },\n dita: { input: \"xml\", shapes: { directory: \"dita-glossentry\", file: \"dita-glossgroup\" } },\n docbook: { input: \"xml\", shapes: { file: \"docbook-glossary\" } },\n};\n\n/** What `formats` calls an interchange render. */\nconst INTERCHANGE_LABELS: Partial<Record<TermWriteFormat, string>> = {\n tbx: \"TBX v2\",\n tbx3: \"TBX v3\",\n skos: \"JSON-LD\",\n vale: \"style\",\n};\n\nfunction rendered(writers: readonly TermWriter[], format: string, construct: TermConstruct): boolean {\n return writers.some((writer) => {\n const render = DOCUMENT_RENDERS[writer.format];\n if (render?.input !== format) return false;\n return writer.shapes.some((shape) => render.shapes[shape] === construct);\n });\n}\n\nexport function listFormats(\n opts: { readers?: readonly TermReader[]; writers?: readonly TermWriter[] } = {},\n): FormatRow[] {\n const readers = opts.readers ?? TERM_READERS;\n const writers = opts.writers ?? TERM_WRITERS;\n\n // Input formats in order of first appearance, then each format's readers in registry order.\n const formats: string[] = [];\n for (const reader of readers) {\n for (const format of reader.formats) if (!formats.includes(format)) formats.push(format);\n }\n const rows: FormatRow[] = [];\n for (const format of formats) {\n for (const reader of readers.filter((r) => r.formats.includes(format))) {\n rows.push({\n format,\n construct: reader.construct,\n label: reader.label,\n read: true,\n write: reader.apply !== undefined || rendered(writers, format, reader.construct),\n });\n }\n }\n for (const writer of writers) {\n if (DOCUMENT_RENDERS[writer.format] !== undefined) continue;\n rows.push({ format: writer.format, label: INTERCHANGE_LABELS[writer.format] ?? \"\", read: false, write: true });\n }\n return rows;\n}\n","/**\n * `manni term get <term>`: one entry, matched by id, else by label without\n * case, else by alt-label without case. A miss is a usage error that says how\n * big the set is and, when some id or label is a few edits away, which one,\n * because a typo is the likely cause.\n */\nimport { TermError } from \"../errors.js\";\nimport type { Term } from \"../types.js\";\nimport { loadTerms, plural, type TermCommandOptions } from \"./run.js\";\n\nexport const GET_FORMATS = [\"pretty\", \"json\"] as const;\nexport type GetFormat = (typeof GET_FORMATS)[number];\n\nexport interface GetOptions extends TermCommandOptions {\n /** The `<term>` argument: an id, a label or an alt-label. */\n term: string;\n}\n\n/**\n * The entry `query` names: an exact id first, then a label compared without\n * case, then an alt-label compared without case. Each pass takes the first\n * entry in set order.\n */\nexport function findTerm(terms: readonly Term[], query: string): Term | undefined {\n const folded = query.toLowerCase();\n return (\n terms.find((t) => t.id === query) ??\n terms.find((t) => t.record.label.toLowerCase() === folded) ??\n terms.find((t) => (t.record[\"alt-labels\"] ?? []).some((alt) => alt.toLowerCase() === folded))\n );\n}\n\n/** Levenshtein distance. */\nfunction editDistance(a: string, b: string): number {\n let prev = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i++) {\n const row = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n row.push(Math.min((row[j - 1] ?? 0) + 1, (prev[j] ?? 0) + 1, (prev[j - 1] ?? 0) + cost));\n }\n prev = row;\n }\n return prev[b.length] ?? 0;\n}\n\n/**\n * The name nearest `query` by edit distance, the first on a tie, when it is\n * within `max(2, floor(query.length / 3))` edits; `undefined` otherwise. A\n * name further off than that is not a typo of `query`, and suggesting it\n * points at an unrelated entry.\n */\nexport function closestName(query: string, names: readonly string[]): string | undefined {\n const limit = Math.max(2, Math.floor(query.length / 3));\n let best: string | undefined;\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const name of names) {\n const distance = editDistance(query, name);\n if (distance < bestDistance) {\n best = name;\n bestDistance = distance;\n }\n }\n return bestDistance <= limit ? best : undefined;\n}\n\nexport interface GetReport {\n term: Term;\n /** The set's other terms with the same id: the entry in its other languages, in set order. */\n others: Term[];\n}\n\nexport async function runGet(opts: GetOptions): Promise<GetReport> {\n const { set } = await loadTerms(opts);\n const found = findTerm(set.terms, opts.term);\n if (found !== undefined) return { term: found, others: set.terms.filter((t) => t.id === found.id && t !== found) };\n const nearest = closestName(\n opts.term,\n set.terms.flatMap((t) => [t.id, t.record.label]),\n );\n const hint = nearest === undefined ? \".\" : `; did you mean \"${nearest}\"?`;\n throw new TermError(`no term \"${opts.term}\". ${plural(set.terms.length, \"term\")}${hint}`);\n}\n","/**\n * `term lint`: the definitions against the house voice (proposal 0052 § 6).\n *\n * Each entry's `definition`, `abstract` and `scope-note` is written to a\n * temporary `<id>.<field>.md`, and Vale runs once over the directory holding\n * them. The file name is the voice switch: a `[*.definition.md]` section in the\n * user's own `.vale.ini` applies to definitions alone. One file per field keeps\n * a document-wide rule from reaching across unrelated entries.\n *\n * Vale is given the directory rather than the file list so a large set does not\n * run into the platform's command-line length limit; the directory holds only\n * the files written here.\n */\nimport { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Term, TermField, TermFinding, TermSet } from \"../types.js\";\nimport { foldValeSeverity, proseRuleId } from \"./severity.js\";\nimport { runValeJson } from \"./vale.js\";\n\nexport interface LintTermSetOptions {\n /** Absolute; from `valeConfigPath(run.tools, run.configDir)`. */\n valeConfig?: string;\n /** Where Vale runs, and so where it looks for its own config. */\n cwd?: string;\n runVale?: typeof runValeJson;\n}\n\n/** The prose fields `lint` reads, in the order it writes them. */\nexport const PROSE_FIELDS = [\"definition\", \"abstract\", \"scope-note\"] as const satisfies readonly TermField[];\ntype ProseField = (typeof PROSE_FIELDS)[number];\n\ninterface Written {\n term: Term;\n field: ProseField;\n value: string;\n}\n\n/** A term id made safe as a file name component. */\nfunction fileStem(id: string): string {\n const safe = id.replace(/[^A-Za-z0-9._-]/g, \"_\");\n return safe === \"\" ? \"_\" : safe;\n}\n\n/** The last component of a path printed by Vale, whichever separator it used. */\nfunction baseName(path: string): string {\n const parts = path.split(/[\\\\/]/);\n return parts[parts.length - 1] ?? path;\n}\n\n/** The source line a line of a field's prose sits on. */\nfunction sourceLine(written: Written, proseLine: number): number {\n const { term, field, value } = written;\n const fieldLine = term.location.fieldLines[field] ?? term.location.line;\n if (!value.includes(\"\\n\")) return fieldLine;\n const { construct } = term.location;\n return construct === \"page\" || construct === \"manifest\" ? fieldLine + proseLine : fieldLine + proseLine - 1;\n}\n\nfunction compareFindings(a: TermFinding, b: TermFinding): number {\n if (a.file !== b.file) return a.file < b.file ? -1 : 1;\n const lineA = a.line ?? 0;\n const lineB = b.line ?? 0;\n if (lineA !== lineB) return lineA - lineB;\n if (a.ruleId !== b.ruleId) return a.ruleId < b.ruleId ? -1 : 1;\n if (a.message !== b.message) return a.message < b.message ? -1 : 1;\n return 0;\n}\n\nexport async function lintTermSet(set: TermSet, opts: LintTermSetOptions = {}): Promise<TermFinding[]> {\n // Keyed by lowercased file name: Vale may print the path in another case, and\n // a case-insensitive file system would fold `API` and `api` onto one file.\n const byName = new Map<string, Written>();\n const files: { name: string; content: string }[] = [];\n const stemCount = new Map<string, number>();\n\n for (const term of set.terms) {\n const fields = PROSE_FIELDS.filter((field) => term.record[field] !== undefined);\n if (fields.length === 0) continue;\n const stem = fileStem(term.id);\n const seen = (stemCount.get(stem.toLowerCase()) ?? 0) + 1;\n stemCount.set(stem.toLowerCase(), seen);\n // A repeated id is suffixed before the field, so `*.definition.md` still matches it.\n const prefix = seen === 1 ? stem : `${stem}.${String(seen)}`;\n for (const field of fields) {\n const value = term.record[field];\n if (value === undefined) continue;\n const name = `${prefix}.${field}.md`;\n byName.set(name.toLowerCase(), { term, field, value });\n files.push({ name, content: `${value}\\n` });\n }\n }\n\n if (files.length === 0) return [];\n\n const runVale = opts.runVale ?? runValeJson;\n const dir = await mkdtemp(join(tmpdir(), \"manni-term-lint-\"));\n try {\n for (const file of files) await writeFile(join(dir, file.name), file.content, \"utf8\");\n const alerts = await runVale([dir], { config: opts.valeConfig, cwd: opts.cwd });\n\n const findings: TermFinding[] = [];\n for (const [path, list] of Object.entries(alerts)) {\n const written = byName.get(baseName(path).toLowerCase());\n if (written === undefined) continue;\n for (const alert of list) {\n findings.push({\n ruleId: proseRuleId(alert.Check),\n severity: foldValeSeverity(alert.Severity),\n message: alert.Message,\n file: written.term.location.file,\n line: sourceLine(written, alert.Line),\n id: written.term.id,\n tool: \"vale\",\n check: alert.Check,\n toolSeverity: alert.Severity,\n field: written.field,\n });\n }\n }\n return findings.sort(compareFindings);\n } finally {\n await rm(dir, { recursive: true, force: true });\n }\n}\n","/**\n * The Vale process seam (proposal 0052 § 6). The only module that starts Vale.\n *\n * manni asks Vale rather than reading its files: `vale --output=JSON` for the\n * alerts, `vale ls-config` for the resolved configuration. Vale is started with\n * an argv, never a shell string, and what it prints is validated here, because\n * it crosses a process boundary.\n */\nimport { execFile } from \"node:child_process\";\nimport type { ValeSeverity } from \"../types.js\";\nimport { TermError } from \"../errors.js\";\n\n/** One alert, as `vale --output=JSON` prints it, trimmed to the fields manni reads. */\nexport interface ValeAlert {\n Check: string;\n Message: string;\n Line: number;\n Span: [number, number];\n Severity: ValeSeverity;\n}\n\n/** `vale --output=JSON`: the path Vale printed for each file, to its alerts. */\nexport type ValeAlerts = Record<string, ValeAlert[]>;\n\n/** What `vale ls-config` resolved. */\nexport interface ValeResolvedConfig {\n /** The project's styles directory: the last entry of Vale's `Paths`. */\n stylesPath: string;\n /** The config file Vale resolved. */\n rootIni: string;\n /** Each section glob to its `BasedOnStyles`. */\n baseStyles: Record<string, string[]>;\n}\n\nexport interface ValeProcessResult {\n /** Vale's exit code; `null` when a signal ended it. */\n code: number | null;\n /**\n * The signal that ended it, when one did, and `code` is then null. Optional\n * because absent means what it says: the run was not killed.\n */\n signal?: string | null;\n stdout: string;\n stderr: string;\n}\n\n/**\n * Start `vale` with `args` and wait for it. Resolves for any exit; rejects when\n * the process could not start, with an error whose `code` is `ENOENT` when\n * there is no `vale` on PATH. Tests inject a stub.\n */\nexport type ValeSpawn = (args: string[], opts: { cwd?: string }) => Promise<ValeProcessResult>;\n\nconst MAX_BUFFER = 64 * 1024 * 1024;\n\nconst SEVERITIES: readonly ValeSeverity[] = [\"error\", \"warning\", \"suggestion\"];\n\nexport const spawnVale: ValeSpawn = (args, opts) =>\n new Promise((settle, reject) => {\n execFile(\n \"vale\",\n args,\n { cwd: opts.cwd, windowsHide: true, maxBuffer: MAX_BUFFER, encoding: \"utf8\" },\n (error, stdout, stderr) => {\n if (!error) {\n settle({ code: 0, stdout, stderr });\n return;\n }\n if (typeof error.code === \"number\") {\n settle({ code: error.code, stdout, stderr });\n return;\n }\n // Killed by a signal. Node reports the exit code as **null** here,\n // not as undefined, so testing for undefined never matched: a killed\n // run fell through to `reject` and surfaced as though Vale could not\n // start. Settling instead keeps whatever Vale managed to write, which\n // is the part a reader can act on.\n if (error.code == null && typeof error.signal === \"string\") {\n settle({ code: null, signal: error.signal, stdout, stderr });\n return;\n }\n // A start failure (ENOENT) or an output over the buffer.\n const failure: Error = error;\n reject(failure);\n },\n );\n });\n\nfunction isEnoent(err: unknown): boolean {\n return typeof err === \"object\" && err !== null && \"code\" in err && err.code === \"ENOENT\";\n}\n\nasync function start(\n spawn: ValeSpawn,\n args: string[],\n cwd: string | undefined,\n missing: string,\n): Promise<ValeProcessResult> {\n try {\n return await spawn(args, { cwd });\n } catch (err) {\n if (isEnoent(err)) throw new TermError(missing);\n throw err;\n }\n}\n\nfunction isMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Vale's own account of a failure. Under `--output=JSON` it prints its error\n * as a JSON object whose `Text` is the message; otherwise the stderr is the\n * message.\n */\nfunction failureText(result: ValeProcessResult): string {\n const stderr = result.stderr.trim();\n try {\n const parsed: unknown = JSON.parse(stderr);\n if (isMapping(parsed) && typeof parsed[\"Text\"] === \"string\") return parsed[\"Text\"].trim();\n } catch {\n // Not JSON: the stderr is the message.\n }\n if (stderr !== \"\") return stderr;\n // Vale said nothing, so the ending is the only account there is. A signal\n // leaves no message behind, and \"exit code null\" names nothing a reader can\n // act on.\n if (result.signal != null) return `killed by ${result.signal}`;\n return `exit code ${String(result.code)}`;\n}\n\nfunction parseJson(stdout: string, what: string): unknown {\n try {\n return JSON.parse(stdout) as unknown;\n } catch {\n throw new TermError(`vale printed ${what} that is not JSON: ${stdout.trim().slice(0, 200)}`);\n }\n}\n\nfunction parseAlert(raw: unknown, path: string): ValeAlert {\n const unreadable = (): TermError =>\n new TermError(`vale printed an alert for ${path} that manni cannot read: ${JSON.stringify(raw)}`);\n if (!isMapping(raw)) throw unreadable();\n const { Check, Message, Line, Span, Severity } = raw;\n if (typeof Check !== \"string\" || typeof Message !== \"string\" || typeof Line !== \"number\") throw unreadable();\n if (!Array.isArray(Span) || Span.length !== 2) throw unreadable();\n const span: unknown[] = Span;\n const [from, to] = span;\n if (typeof from !== \"number\" || typeof to !== \"number\") throw unreadable();\n const severity = SEVERITIES.find((s) => s === Severity);\n if (severity === undefined) throw unreadable();\n return { Check, Message, Line, Span: [from, to], Severity: severity };\n}\n\nfunction parseAlerts(stdout: string): ValeAlerts {\n const parsed = parseJson(stdout, \"alerts\");\n if (!isMapping(parsed)) throw new TermError(\"vale printed alerts that are not a JSON object.\");\n const alerts: ValeAlerts = {};\n for (const [path, list] of Object.entries(parsed)) {\n if (!Array.isArray(list)) throw new TermError(`vale printed alerts for ${path} that are not a list.`);\n alerts[path] = list.map((raw: unknown) => parseAlert(raw, path));\n }\n return alerts;\n}\n\n/**\n * `vale --output=JSON [--config <config>] <files...>`. Exit 0 (no error-level\n * alert) and exit 1 (at least one) both carry alerts; any other exit means\n * Vale could not run.\n */\nexport async function runValeJson(\n files: string[],\n opts: { config?: string; cwd?: string },\n spawn: ValeSpawn = spawnVale,\n): Promise<ValeAlerts> {\n const args = [\"--output=JSON\", ...(opts.config === undefined ? [] : [\"--config\", opts.config]), ...files];\n const result = await start(spawn, args, opts.cwd, \"vale is not on PATH. Install Vale to lint definitions.\");\n if (result.code !== 0 && result.code !== 1) {\n throw new TermError(`vale could not lint definitions: ${failureText(result)}`);\n }\n return parseAlerts(result.stdout);\n}\n\nconst NO_CONFIG = /no config file found|\\.vale\\.ini not found/i;\n\nfunction stringList(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const list: string[] = [];\n for (const item of value as unknown[]) {\n if (typeof item !== \"string\") return undefined;\n list.push(item);\n }\n return list;\n}\n\n/**\n * `vale [--config <config>] ls-config`, run in `cwd`. `null` when Vale finds no\n * config file, which is a state the caller reports, not a failure to run.\n */\nexport async function valeLsConfig(\n opts: { config?: string; cwd: string },\n spawn: ValeSpawn = spawnVale,\n): Promise<ValeResolvedConfig | null> {\n const args = [...(opts.config === undefined ? [] : [\"--config\", opts.config]), \"ls-config\"];\n const result = await start(\n spawn,\n args,\n opts.cwd,\n \"vale is not on PATH. Install Vale, or pass -o <styles directory>.\",\n );\n if (result.code !== 0) {\n const text = failureText(result);\n if (NO_CONFIG.test(text)) return null;\n throw new TermError(`vale could not resolve its configuration: ${text}`);\n }\n\n const parsed = parseJson(result.stdout, \"a configuration\");\n if (!isMapping(parsed)) throw new TermError(\"vale printed a configuration that is not a JSON object.\");\n\n const paths = stringList(parsed[\"Paths\"]);\n const stylesPath = paths?.[paths.length - 1];\n if (stylesPath === undefined || stylesPath === \"\") {\n throw new TermError(\n \"vale's configuration names no styles directory. Set StylesPath in it, or pass -o <styles directory>.\",\n );\n }\n\n // Under --config, Vale 3.20.0 leaves RootINI empty and names the file in ConfigFiles.\n const root = parsed[\"RootINI\"];\n const configFiles = stringList(parsed[\"ConfigFiles\"]);\n const rootIni =\n typeof root === \"string\" && root !== \"\" ? root : (configFiles?.[configFiles.length - 1] ?? opts.config ?? \"\");\n\n const baseStyles: Record<string, string[]> = {};\n const sections = parsed[\"SBaseStyles\"];\n if (sections !== null && sections !== undefined) {\n if (!isMapping(sections)) throw new TermError(\"vale printed SBaseStyles that is not a JSON object.\");\n for (const [glob, styles] of Object.entries(sections)) {\n const list = stringList(styles);\n if (list === undefined) throw new TermError(`vale printed styles for ${glob} that are not a list of names.`);\n baseStyles[glob] = list;\n }\n }\n\n return { stylesPath, rootIni, baseStyles };\n}\n","/**\n * `manni term lint`: each entry's prose through Vale (proposal 0052 § 6). The\n * process seam is `lintTermSet`'s; this core resolves Vale's config from the\n * family `tools:` and shapes the report `check` shares.\n */\nimport { lintTermSet, type LintTermSetOptions } from \"../core/lint.js\";\nimport { summarize, toResults, reportedFindings, type TermReport } from \"./findings.js\";\nimport { loadTerms, valeConfigFor, type TermCommandOptions } from \"./run.js\";\n\nexport interface LintOptions extends TermCommandOptions {\n /** The Vale seam. Tests hand in a stub. */\n runVale?: LintTermSetOptions[\"runVale\"];\n}\n\nexport async function runLint(opts: LintOptions): Promise<TermReport> {\n const { cwd, run, set } = await loadTerms(opts);\n const valeConfig = valeConfigFor(run);\n const findings = await lintTermSet(set, {\n cwd,\n ...(valeConfig === undefined ? {} : { valeConfig }),\n ...(opts.runVale === undefined ? {} : { runVale: opts.runVale }),\n });\n const { results, origin } = toResults(set, findings);\n return {\n findings: reportedFindings(results, origin),\n results,\n summary: summarize(results),\n frame: { cwd, base: run.configDir ?? cwd, runBase: run.base },\n terms: set.terms.length,\n references: set.references.length,\n found: findings.length,\n cwd,\n };\n}\n","/**\n * `manni term write` (proposal 0052 § 5): the set written back to its sources,\n * or rendered somewhere new.\n *\n * With no `-f`, each file's entries go back through the reader that read them,\n * construct by construct. With `-f`, the registered writer renders the whole\n * set into `-o`, whose spelling decides the shape: a trailing separator, an\n * existing directory, or the Vale style make it a directory; anything else is\n * a file. `-f vale` without `-o` asks Vale where its styles live.\n *\n * Writers are pure, so `--check` and `--dry-run` run the same render a write\n * does and differ only in what happens to the result.\n */\nimport { existsSync, statSync } from \"node:fs\";\nimport { lstat, mkdir, readdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, extname, join, resolve } from \"node:path\";\nimport { extractorForExtension } from \"../../meta/internal.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { MANIFEST_FORMAT, extractInput, tbxInput } from \"../core/load-set.js\";\nimport { TERM_READERS, readerForConstruct } from \"../core/readers/index.js\";\nimport { valeLsConfig, type ValeResolvedConfig } from \"../core/vale.js\";\nimport { TERM_WRITERS } from \"../core/writers/index.js\";\nimport { tbxHeaderFiles } from \"../core/writers/tbx.js\";\nimport { TermError } from \"../errors.js\";\nimport {\n TERM_WRITE_FORMATS,\n type DroppedField,\n type MergeConflict,\n type RenderedFile,\n type Term,\n type TermConstruct,\n type TermInput,\n type TermReader,\n type TermRender,\n type TermShape,\n type TermTarget,\n type TermWriteFormat,\n type TermWriter,\n} from \"../types.js\";\nimport { DOCUMENT_RENDERS } from \"./formats.js\";\nimport { displayPath, formatChoice, loadTerms, valeConfigFor, type TermCommandOptions } from \"./run.js\";\n\nexport interface WriteOptions extends TermCommandOptions {\n /** `-f, --format`. Absent writes in place. */\n format?: string;\n /** `-o, --out <path>`. */\n out?: string;\n /** `--check`. */\n check?: boolean;\n /** `--dry-run`. */\n dryRun?: boolean;\n /** The writers to render with. Tests hand in their own. */\n writers?: readonly TermWriter[];\n /** `vale ls-config`. Tests hand in a stub. */\n lsConfig?: (opts: { config?: string; cwd: string }) => Promise<ValeResolvedConfig | null>;\n}\n\n/** One file the write would change, as a person in `cwd` would name it. */\nexport interface WriteChange {\n path: string;\n action: \"create\" | \"change\" | \"remove\";\n}\n\n/** The `BasedOnStyles` line the notice suggests, when no section uses `Terms`. */\nexport interface ValeWiring {\n /** The config file Vale resolved, relative to cwd. */\n rootIni: string;\n /** The section glob to add the style to: the first Vale reports, or `*.md` when it reports none. */\n section: string;\n /** The section's styles with `Terms` appended. `[\"Terms\"]` when Vale reports no section. */\n styles: string[];\n /** True when Vale reports no section with `BasedOnStyles`, so the notice says to add `section`. */\n addSection: boolean;\n}\n\n/** The section glob the notice suggests when Vale's config has none. */\nconst SUGGESTED_SECTION = \"*.md\";\n\nexport interface WriteReport {\n mode: \"in-place\" | \"render\";\n format?: TermWriteFormat;\n shape?: TermShape;\n /** `-o` as typed, or the Vale style directory; relative to cwd. */\n target?: string;\n terms: number;\n /** Files that differ from disk. Under `--check` and `--dry-run` nothing was written. */\n changes: WriteChange[];\n /** The rendered files, relative to cwd, with their content. */\n files: RenderedFile[];\n dropped: DroppedField[];\n /** What a dropped field was dropped from, and a skipped term left out of: `a definition list`, `tbx`. */\n droppedFrom?: string;\n /** Ids of the terms left out because the target construct cannot read them back, in set order. */\n skipped: string[];\n /** The terms left out because the target construct holds one language, and the language it holds. */\n otherLanguages?: TermRender[\"otherLanguages\"];\n /** The fields where terms sharing an id disagree, and the render kept the first term's value. */\n conflicts?: MergeConflict[];\n /** The TBX files whose header the render left behind, as their terms name them. */\n droppedHeaders?: string[];\n check: boolean;\n dryRun: boolean;\n wiring?: ValeWiring;\n}\n\nconst STYLE = \"Terms\";\n\n/** The registered `-f` values, in the order the reference lists them. */\nexport function writeFormats(writers: readonly TermWriter[] = TERM_WRITERS): TermWriteFormat[] {\n return TERM_WRITE_FORMATS.filter((format) => writers.some((writer) => writer.format === format));\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * The largest file under a render target a write reads into the render context.\n * A larger one is there as an empty string: a render never produces an empty\n * file, so it still differs, and the Vale writer refuses it as not its own.\n */\nexport const MAX_EXISTING_FILE_BYTES = 1024 * 1024;\n\n/** Every regular file under `dir`. A symlink is skipped, never followed. */\nasync function filesUnder(dir: string, into: Map<string, string>): Promise<void> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const path = join(dir, entry.name);\n // A Dirent describes the entry itself, so a symlink is neither of these.\n if (entry.isDirectory()) await filesUnder(path, into);\n else if (entry.isFile()) {\n const { size } = await lstat(path);\n into.set(path, size > MAX_EXISTING_FILE_BYTES ? \"\" : await readFile(path, \"utf8\"));\n }\n }\n}\n\nasync function existingFor(target: TermTarget): Promise<Map<string, string>> {\n const existing = new Map<string, string>();\n if (target.shape === \"directory\") {\n await filesUnder(target.path, existing);\n } else if (existsSync(target.path) && !isDirectory(target.path)) {\n existing.set(target.path, await readFile(target.path, \"utf8\"));\n }\n return existing;\n}\n\n/** A writer's refusal, with every absolute path it names spelled from cwd. */\nfunction relativized(error: TermError, paths: readonly string[], cwd: string): TermError {\n let message = error.message;\n for (const path of [...paths].sort((a, b) => b.length - a.length)) {\n if (message.includes(path)) message = message.replaceAll(path, displayPath(path, cwd));\n }\n return message === error.message ? error : new TermError(message);\n}\n\n/** The noun a dropped field was dropped from. */\nfunction droppedFrom(format: TermWriteFormat, shape: TermShape, readers: readonly TermReader[]): string {\n const construct = DOCUMENT_RENDERS[format]?.shapes[shape];\n const reader = construct === undefined ? undefined : readerForConstruct(construct, readers);\n return reader === undefined ? format : `a ${reader.label}`;\n}\n\nasync function applyChanges(\n files: readonly RenderedFile[],\n removals: readonly string[],\n existing: ReadonlyMap<string, string>,\n cwd: string,\n write: boolean,\n): Promise<WriteChange[]> {\n const changes: WriteChange[] = [];\n for (const file of files) {\n const before = existing.get(file.path) ?? (existsSync(file.path) ? await readFile(file.path, \"utf8\") : undefined);\n if (before === file.content) continue;\n changes.push({ path: displayPath(file.path, cwd), action: before === undefined ? \"create\" : \"change\" });\n if (write) {\n await mkdir(dirname(file.path), { recursive: true });\n await writeFile(file.path, file.content, \"utf8\");\n }\n }\n for (const path of removals) {\n if (!existsSync(path)) continue;\n changes.push({ path: displayPath(path, cwd), action: \"remove\" });\n if (write) await rm(path, { force: true });\n }\n return changes;\n}\n\nexport async function runWrite(opts: WriteOptions): Promise<WriteReport> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const writers = opts.writers ?? TERM_WRITERS;\n const readers = opts.readers ?? TERM_READERS;\n const check = opts.check === true;\n const dryRun = opts.dryRun === true;\n if (check && dryRun) throw new TermError(\"--check and --dry-run cannot be combined.\");\n\n if (opts.format === undefined) {\n if (opts.out !== undefined) throw new TermError(\"-o needs -f <format>.\");\n return writeInPlace({ ...opts, cwd, readers }, check, dryRun);\n }\n\n const format = formatChoice(opts.format, writeFormats(writers));\n const writer = writers.find((w) => w.format === format);\n if (writer === undefined) throw new TermError(`unknown format \"${format}\".`);\n if (opts.out === undefined && format !== \"vale\") {\n throw new TermError(`-f ${format} needs -o <path>.`);\n }\n\n const { run, set } = await loadTerms({ ...opts, cwd, readers });\n\n // Where the render goes, and in which shape.\n let targetPath: string;\n let wiring: ValeWiring | undefined;\n if (opts.out === undefined) {\n const lsConfig = opts.lsConfig ?? ((o) => valeLsConfig(o));\n const config = valeConfigFor(run);\n const resolved = await lsConfig({ cwd, ...(config === undefined ? {} : { config }) });\n if (resolved === null) {\n throw new TermError(\n \"Vale found no config file. Set tools.vale.config in manni.config.yaml, or pass -o <styles directory>.\",\n );\n }\n targetPath = resolve(cwd, resolved.stylesPath);\n if (!Object.values(resolved.baseStyles).some((styles) => styles.includes(STYLE))) {\n const first = Object.entries(resolved.baseStyles)[0];\n const [section, styles] = first ?? [SUGGESTED_SECTION, []];\n wiring = {\n rootIni: displayPath(resolve(cwd, resolved.rootIni), cwd),\n section,\n styles: [...styles, STYLE],\n addSection: first === undefined,\n };\n }\n } else {\n targetPath = resolve(cwd, opts.out);\n }\n const shape: TermShape =\n format === \"vale\" || /[\\\\/]$/.test(opts.out ?? \"\") || isDirectory(targetPath) ? \"directory\" : \"file\";\n const target: TermTarget = { path: targetPath, shape };\n const existing = await existingFor(target);\n\n let render;\n try {\n render = writer.render(set.terms, target, { existing });\n } catch (error) {\n if (error instanceof TermError) throw relativized(error, [...existing.keys(), targetPath], cwd);\n throw error;\n }\n\n const changes = await applyChanges(render.files, render.removals, existing, cwd, !check && !dryRun);\n const shown =\n format === \"vale\" ? displayPath(join(targetPath, STYLE), cwd) : (opts.out ?? displayPath(targetPath, cwd));\n return {\n mode: \"render\",\n format,\n shape,\n target: shown,\n terms: set.terms.length,\n changes,\n files: render.files.map((file) => ({ path: displayPath(file.path, cwd), content: file.content })),\n // A Vale style holds designations only, by design; its dropped definitions are not news.\n dropped: format === \"vale\" ? [] : render.dropped,\n droppedFrom: droppedFrom(format, shape, readers),\n skipped: render.skipped,\n ...(render.otherLanguages === undefined ? {} : { otherLanguages: render.otherLanguages }),\n ...(render.conflicts === undefined ? {} : { conflicts: render.conflicts }),\n // A Vale style is not a termbase, so a header it does not hold is not news either.\n ...(format === \"vale\" ? {} : { droppedHeaders: render.droppedHeaders ?? tbxHeaderFiles(set.terms) }),\n check,\n dryRun,\n ...(wiring === undefined ? {} : { wiring }),\n };\n}\n\n/** The `TermInput` a construct's reader reads from `content`, rebuilt as the loader built it. */\nfunction inputFor(content: string, path: string, construct: TermConstruct, file: string): TermInput {\n if (construct === \"manifest\") {\n return { content, file, path, format: MANIFEST_FORMAT, metadata: {}, lineFor: () => undefined };\n }\n if (construct === \"tbx-entry\") return tbxInput(content, file, path);\n const extractor = extractorForExtension(extname(path));\n if (extractor === undefined) throw new TermError(`${file}: no reader for its extension.`);\n return extractInput(content, file, path, extractor.name);\n}\n\n/**\n * The caller's records carried onto `current`, the entries a construct's reader\n * read from content an earlier construct rewrote. An entry is matched by `id`;\n * where the id repeats in either list, by its position within the construct.\n * An entry the caller left out keeps the record it was read with.\n */\nfunction carryRecords(current: readonly Term[], edited: readonly Term[]): Term[] {\n const count = (terms: readonly Term[], id: string): number => terms.filter((t) => t.id === id).length;\n return current.map((entry, index) => {\n const unique = count(current, entry.id) === 1 && count(edited, entry.id) === 1;\n const match = unique ? edited.find((t) => t.id === entry.id) : edited[index];\n return match?.id === entry.id ? { ...entry, record: match.record } : entry;\n });\n}\n\n/**\n * One file's content with each construct's entries written back through its\n * reader, in order. A field the terms of one entry disagree on goes onto `conflicts`.\n */\nexport function applyInPlace(\n original: string,\n path: string,\n file: string,\n constructs: ReadonlyMap<TermConstruct, readonly Term[]>,\n readers: readonly TermReader[],\n conflicts?: MergeConflict[],\n): string {\n let content = original;\n let first = true;\n for (const [construct, terms] of constructs) {\n const reader = readerForConstruct(construct, readers);\n if (reader?.apply === undefined) continue;\n const input = inputFor(content, path, construct, file);\n // The loaded terms carry offsets into the file as it was read. Once an\n // earlier construct has rewritten it, this one's entries are read again for\n // offsets that are the content's own, and the caller's records carried over.\n content = reader.apply(input, first ? terms : carryRecords(reader.read(input).terms, terms), conflicts);\n first = false;\n }\n return content;\n}\n\nasync function writeInPlace(\n opts: WriteOptions & { cwd: string; readers: readonly TermReader[] },\n check: boolean,\n dryRun: boolean,\n): Promise<WriteReport> {\n const { cwd, readers } = opts;\n const { set } = await loadTerms(opts);\n\n // Every file's terms, per construct, in load order.\n const byPath = new Map<string, { file: string; constructs: Map<TermConstruct, Term[]> }>();\n for (const term of set.terms) {\n const { path, construct } = term.location;\n if (path === undefined) {\n throw new TermError(`${term.location.file} has nowhere to write back to. Pass -f <format> -o <path>.`);\n }\n const reader = readerForConstruct(construct, readers);\n if (reader?.apply === undefined) {\n const name = reader?.label ?? construct;\n throw new TermError(\n `${displayPath(term.location.file, cwd)}: a ${name} cannot be written in place. Pass -f <format> -o <path>.`,\n );\n }\n const entry = byPath.get(path) ?? { file: term.location.file, constructs: new Map<TermConstruct, Term[]>() };\n entry.constructs.set(construct, [...(entry.constructs.get(construct) ?? []), term]);\n byPath.set(path, entry);\n }\n\n const files: RenderedFile[] = [];\n const existing = new Map<string, string>();\n const conflicts: MergeConflict[] = [];\n for (const [path, { file, constructs }] of byPath) {\n let original: string;\n try {\n original = await readFile(path, \"utf8\");\n } catch (error) {\n throw new TermError(`${file}: could not be read: ${errorMessage(error)}`);\n }\n existing.set(path, original);\n files.push({ path, content: applyInPlace(original, path, file, constructs, readers, conflicts) });\n }\n\n const changes = await applyChanges(files, [], existing, cwd, !check && !dryRun);\n return {\n mode: \"in-place\",\n terms: set.terms.length,\n changes,\n files: files.map((f) => ({ path: displayPath(f.path, cwd), content: f.content })),\n dropped: [],\n skipped: [],\n ...(conflicts.length === 0 ? {} : { conflicts }),\n check,\n dryRun,\n };\n}\n","/**\n * `term list -f csv`: one row per term for a script,\n * `id,label,alt-labels,abstract,language`. A term with no language has an empty\n * language cell.\n * A list is joined with `|`, and a cell is quoted as RFC 4180 says.\n */\nimport type { Term } from \"../types.js\";\n\nconst LIST_SEPARATOR = \"|\";\n\nfunction cell(value: string): string {\n return /[\",\\r\\n]/.test(value) ? `\"${value.replaceAll('\"', '\"\"')}\"` : value;\n}\n\nexport function renderListCsv(terms: readonly Term[]): string {\n const rows = [\n [\"id\", \"label\", \"alt-labels\", \"abstract\", \"language\"],\n ...terms.map((t) => [\n t.id,\n t.record.label,\n (t.record[\"alt-labels\"] ?? []).join(LIST_SEPARATOR),\n t.record.abstract ?? \"\",\n t.language ?? \"\",\n ]),\n ];\n return rows.map((row) => row.map(cell).join(\",\")).join(\"\\n\");\n}\n","/**\n * SARIF for `check` and `lint`. Meta's renderer builds the envelope, the\n * repository-relative uris and the fingerprints the baseline shares, from the\n * adapted results. What it cannot know is what a term rule is: it describes\n * every rule as a schema keyword, links meta's fix page, and prefixes each\n * message with the JSON Pointer of the field, `(root)` for a finding about a\n * whole entry. This renderer replaces those three with the term rule's own\n * description, a link to its section of the rules page, and the finding's own\n * message.\n */\nimport { renderSarif } from \"../../meta/index.js\";\nimport { RULE_ID_PREFIX, isTermRule } from \"../core/severity.js\";\nimport type { TermReport } from \"../commands/findings.js\";\nimport { TERM_FIELDS, type TermRule } from \"../types.js\";\n\nconst INFORMATION_URI = \"https://hawkeyexl.github.io/manni/term/\";\n\n/** The rules reference, whose sections are anchored by rule name. */\nconst RULES_URI = \"https://hawkeyexl.github.io/manni/term/reference/rules/\";\n\n/** What each `check` rule is, as the rules reference's table says it. */\nconst RULE_DESCRIPTIONS: Readonly<Record<TermRule, string>> = {\n \"undefined-term\": \"A page's concepts: names a label no entry claims as its preferred label.\",\n \"duplicate-id\": \"Two entries share an id.\",\n \"label-collision\": \"Two entries claim the same preferred label, ignoring case.\",\n \"alt-label-collision\": \"An entry's alt-label is another entry's preferred label, ignoring case.\",\n \"dangling-reference\": \"A value of broader, narrower, related-terms or see names no entry, by label or by id.\",\n \"broader-cycle\": \"A chain of broader returns to where it started.\",\n \"see-not-empty\": \"An entry with see also carries a definition.\",\n \"asymmetric-hierarchy\": \"A names B as broader, and B omits A from narrower, or the reverse.\",\n \"abstract-too-long\": \"An abstract is longer than term.abstractMaxLength.\",\n \"unused-term\": \"No page's concepts: names the entry's preferred label.\",\n};\n\nconst PROSE_PREFIX = `${RULE_ID_PREFIX}/prose/`;\n\n/**\n * The label meta's reporters put before a message: `(root) ` for a finding\n * about the whole entry, `/<field> ` for one about a field. Nothing else ever\n * opens a term finding's adapted message.\n */\nexport const FIELD_LABEL = new RegExp(`^(?:\\\\(root\\\\)|/(?:${TERM_FIELDS.join(\"|\")})) `);\n\ninterface SarifRule {\n id: string;\n shortDescription: { text: string };\n helpUri?: string;\n}\n\ninterface SarifLog {\n runs: {\n tool: { driver: { informationUri: string; rules: SarifRule[] } };\n results: { message: { text: string } }[];\n }[];\n}\n\n/** A rule as the term tool describes it: a check rule links its section, a Vale rule links nothing manni documents. */\nfunction describe(rule: SarifRule): SarifRule {\n if (rule.id.startsWith(PROSE_PREFIX)) {\n const check = rule.id.slice(PROSE_PREFIX.length);\n return { id: rule.id, shortDescription: { text: `Vale's ${check} rule flagged the prose of an entry's field.` } };\n }\n const name = rule.id.slice(RULE_ID_PREFIX.length + 1);\n if (!isTermRule(name)) return rule;\n return { id: rule.id, shortDescription: { text: RULE_DESCRIPTIONS[name] }, helpUri: `${RULES_URI}#${name}` };\n}\n\nexport function renderFindingsSarif(report: TermReport, opts: { onNotice?: (message: string) => void } = {}): string {\n const log = JSON.parse(\n renderSarif(report.results, {\n frame: report.frame,\n ...(opts.onNotice === undefined ? {} : { onNotice: opts.onNotice }),\n }),\n ) as SarifLog;\n for (const run of log.runs) {\n run.tool.driver.informationUri = INFORMATION_URI;\n run.tool.driver.rules = run.tool.driver.rules.map(describe);\n for (const result of run.results) result.message.text = result.message.text.replace(FIELD_LABEL, \"\");\n }\n return JSON.stringify(log, null, 2);\n}\n","/**\n * JUnit for `check` and `lint`: meta's renderer over the adapted results,\n * under the `manni.term` classname, with each failure's message the finding's\n * own. Meta's renderer opens every message with the field's JSON Pointer,\n * `(root)` for a finding about a whole entry, which says nothing about a term.\n * The failure's `type` is already the rule id.\n */\nimport { renderJunit } from \"../../meta/index.js\";\nimport { JUNIT_CLASSNAME, type TermReport } from \"../commands/findings.js\";\nimport { FIELD_LABEL } from \"./sarif.js\";\n\n/** A `message=\"` attribute's opening label. The value is escaped, so `message=\"` opens nothing else. */\nconst MESSAGE_LABEL = new RegExp(`message=\"${FIELD_LABEL.source.slice(1)}`, \"g\");\n\nexport function renderFindingsJunit(report: TermReport): string {\n return renderJunit(report.results, { frame: report.frame, classname: JUNIT_CLASSNAME }).replace(\n MESSAGE_LABEL,\n 'message=\"',\n );\n}\n","/**\n * The termbase as `meta fill` reads it: each term's label and id, from the\n * same config and the same files `manni term check` reads. Registered as the\n * family's term label source by this domain's CLI module (see\n * `src/shared/term-labels.ts`).\n */\nimport type { TermLabel, TermLabelRequest } from \"../../shared/term-labels.js\";\nimport { resolveTermRun } from \"../core/config.js\";\nimport { loadSet } from \"./run.js\";\n\nexport async function termLabels(request: TermLabelRequest): Promise<TermLabel[]> {\n const run = await resolveTermRun({\n cwd: request.cwd,\n inputs: [],\n ...(request.configPath === undefined ? {} : { configPath: request.configPath }),\n ...(request.noConfig === true ? { noConfig: true } : {}),\n });\n // No collection and no manifest names a file, so there is no termbase.\n if (run.inputs.length === 0 && run.manifests.length === 0) return [];\n const set = await loadSet(run, { inputs: [], allowEmpty: true });\n return set.terms.map((term) => ({ label: term.record.label, id: term.id }));\n}\n"],"mappings":"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","names":["entries","entries","HOLDS","HOLDS","join","HOLDS","join","join","join","rm","writeFile","join","resolve","STYLE","entries","join","writeFile","rm","resolve","LIST_SEPARATOR","cell","references"]}
|