app/lib/dictionary-entries.mjs
98 lines and 11 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| labelPrefix | 36 to 38 | 2 | 100% | OkCRAP 2 | Critical0% |
| listenLabel | 41 to 43 | 1 | 100% | OkCRAP 1 | Ok100% |
| etymologyText | 46 to 48 | 1 | 100% | OkCRAP 1 | No data: changed since the last mutation run |
| <anonymous:47> | 47 to 47 | 2 | 100% | OkCRAP 2 | Critical0% |
| dictionaryEntryText | 55 to 62 | 2 | 100% | OkCRAP 2 | Critical50% |
| <anonymous:59> | 59 to 59 | 1 | 100% | OkCRAP 1 | Critical0% |
| dictionaryEntryMarkdown | 70 to 84 | 2 | 100% | OkCRAP 2 | Watch66.7% |
| <anonymous:71> | 71 to 71 | 1 | 100% | OkCRAP 1 | Critical20% |
| <anonymous:72> | 72 to 72 | 2 | 100% | OkCRAP 2 | Ok100% |
| <anonymous:76> | 76 to 79 | 2 | 100% | OkCRAP 2 | Ok100% |
| definedTermJsonLd | 93 to 106 | 1 | 100% | OkCRAP 1 | Critical55.6% |
Imports
It imports no other module of this repo. Imported by app/components/dictionary-entry.tsx, app/db/dictionary.ts, app/lib/content-pages.mjs, app/lib/dictionary/compile.mjs, app/lib/dictionary/save.server.ts, app/lib/pages/page-json-ld.ts, app/lib/pages/save.server.ts.
Source
/**
* How a dictionary entry reads on each surface. The entries themselves are files, content/dictionary/<key>.md
* (docs/DICTIONARY.md), compiled by app/lib/dictionary/compile.mjs and drawn from D1 (the dictionary_entries
* table) at request time; this module only turns one entry into the page's lead, the markdown twin's lead, the
* search record's sentences and the DefinedTerm JSON-LD, so people and machines read the same entry.
*
* Each name is a real English word most readers rarely meet, so the page first says what the word means, then
* what the software is. Sense 1 follows the dictionaries; sense 2 is the software, plain and factual, and
* carries the subject label "software." in italics, as a dictionary marks a specialised sense.
*/
/**
* An etymology is text with foreign words marked, so the page can set them in italics with their
* language and the twin can emphasise them: a string is plain text, a pair is [lang, word].
*
* @typedef {string | [string, string]} EtymologyPart
* @typedef {{
* path: string,
* term: string,
* syllables: string,
* ipa: string,
* respelling: string,
* partOfSpeech: string,
* plural: string[] | null,
* etymology: EtymologyPart[],
* senses: [string, string],
* senseLabels: [string | null, string | null],
* audio: string,
* }} DictionaryEntry
*/
/** The subject label on each software sense (Dustin, 2026-09-28), set in italics before it. */
export const SOFTWARE_LABEL = "software";
/** @param {string | null | undefined} label */
function labelPrefix(label) {
return label ? `${label}. ` : "";
}
/** @param {string} term */
export function listenLabel(term) {
return `Listen to the pronunciation of ${term}`;
}
/** @param {DictionaryEntry} entry */
function etymologyText(entry) {
return entry.etymology.map((part) => (typeof part === "string" ? part : part[1])).join("");
}
/**
* The entry as plain sentences, for the search record, where markup would be noise.
*
* @param {DictionaryEntry} entry
*/
export function dictionaryEntryText(entry) {
const plural = entry.plural ? `; plural ${entry.plural.join(" or ")}` : "";
return [
`${entry.term} (${entry.syllables}), ${entry.ipa}, ${entry.respelling}, ${entry.partOfSpeech}${plural}.`,
...entry.senses.map((sense, i) => `${i + 1}. ${labelPrefix(entry.senseLabels[i])}${sense}`),
`Etymology: ${etymologyText(entry)}`,
].join(" ");
}
/**
* The entry in the markdown twin, directly under the title, the same place the page shows it.
*
* @param {DictionaryEntry} entry
* @param {string} origin absolute origin for the audio link, so the twin read alone still resolves
*/
export function dictionaryEntryMarkdown(entry, origin = "") {
const plural = entry.plural ? `; plural ${entry.plural.map((form) => `*${form}*`).join(" or ")}` : "";
const etymology = entry.etymology.map((part) => (typeof part === "string" ? part : `*${part[1]}*`)).join("");
return [
`**${entry.syllables}** ${entry.ipa} (${entry.respelling}), *${entry.partOfSpeech}*${plural}. [Pronunciation audio](${origin}${entry.audio})`,
"",
...entry.senses.map((sense, i) => {
const label = entry.senseLabels[i];
return `${i + 1}. ${label ? `*${label}.* ` : ""}${sense}`;
}),
"",
`Etymology: ${etymology}`,
"",
].join("\n");
}
/**
* schema.org DefinedTerm: the name, sense 2 as the description (what the word means on this page),
* and the set every entry belongs to, which is the Software hub.
*
* @param {DictionaryEntry} entry
* @param {string} origin
*/
export function definedTermJsonLd(entry, origin) {
return {
"@context": "https://schema.org",
"@type": "DefinedTerm",
name: entry.term,
description: entry.senses[1],
url: `${origin}${entry.path}`,
inDefinedTermSet: {
"@type": "DefinedTermSet",
name: "Software names on dustinedwards.info",
url: `${origin}/software`,
},
};
}