Maybe off to the races to start fleshing out the vocab list

This commit is contained in:
ryan 2025-09-23 12:23:57 -07:00
parent 24ad55bb57
commit fc3bcd064a
10 changed files with 178 additions and 22 deletions

View File

@ -9,6 +9,7 @@ const vocabListJson = YAML.parse(vocabListFile);
const categories = vocabListJson.map( const categories = vocabListJson.map(
(/** @type {{ slug: string }} */ category) => category.slug, (/** @type {{ slug: string }} */ category) => category.slug,
); );
const vocabList = [ const vocabList = [
{ {
label: "Index", label: "Index",

90
package-lock.json generated
View File

@ -9,7 +9,10 @@
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"@astrojs/starlight": "^0.36.0", "@astrojs/starlight": "^0.36.0",
"@types/markdown-it": "^14.1.2",
"astro": "^5.6.1", "astro": "^5.6.1",
"markdown-it": "^14.1.0",
"markdown-it-mark": "^4.0.0",
"sharp": "^0.34.2", "sharp": "^0.34.2",
"yaml": "^2.8.1" "yaml": "^2.8.1"
}, },
@ -1709,6 +1712,22 @@
"integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/linkify-it": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
"license": "MIT"
},
"node_modules/@types/markdown-it": {
"version": "14.1.2",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
"license": "MIT",
"dependencies": {
"@types/linkify-it": "^5",
"@types/mdurl": "^2"
}
},
"node_modules/@types/mdast": { "node_modules/@types/mdast": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@ -1718,6 +1737,12 @@
"@types/unist": "*" "@types/unist": "*"
} }
}, },
"node_modules/@types/mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
"license": "MIT"
},
"node_modules/@types/mdx": { "node_modules/@types/mdx": {
"version": "2.0.13", "version": "2.0.13",
"resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz",
@ -3451,6 +3476,15 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/linkify-it": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
"license": "MIT",
"dependencies": {
"uc.micro": "^2.0.0"
}
},
"node_modules/longest-streak": { "node_modules/longest-streak": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
@ -3499,6 +3533,41 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/markdown-it": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
"linkify-it": "^5.0.0",
"mdurl": "^2.0.0",
"punycode.js": "^2.3.1",
"uc.micro": "^2.1.0"
},
"bin": {
"markdown-it": "bin/markdown-it.mjs"
}
},
"node_modules/markdown-it-mark": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-4.0.0.tgz",
"integrity": "sha512-YLhzaOsU9THO/cal0lUjfMjrqSMPjjyjChYM7oyj4DnyaXEzA8gnW6cVJeyCrCVeyesrY2PlEdUYJSPFYL4Nkg==",
"license": "MIT"
},
"node_modules/markdown-it/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/markdown-table": { "node_modules/markdown-table": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
@ -3838,6 +3907,12 @@
"integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
"license": "CC0-1.0" "license": "CC0-1.0"
}, },
"node_modules/mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
"license": "MIT"
},
"node_modules/micromark": { "node_modules/micromark": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
@ -4999,6 +5074,15 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/punycode.js": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/radix3": { "node_modules/radix3": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz",
@ -5777,6 +5861,12 @@
"node": ">=14.17" "node": ">=14.17"
} }
}, },
"node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
"license": "MIT"
},
"node_modules/ufo": { "node_modules/ufo": {
"version": "1.6.1", "version": "1.6.1",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",

View File

@ -11,7 +11,10 @@
}, },
"dependencies": { "dependencies": {
"@astrojs/starlight": "^0.36.0", "@astrojs/starlight": "^0.36.0",
"@types/markdown-it": "^14.1.2",
"astro": "^5.6.1", "astro": "^5.6.1",
"markdown-it": "^14.1.0",
"markdown-it-mark": "^4.0.0",
"sharp": "^0.34.2", "sharp": "^0.34.2",
"yaml": "^2.8.1" "yaml": "^2.8.1"
}, },

View File

@ -1,50 +1,70 @@
--- ---
import {Badge} from '@astrojs/starlight/components'; import {Aside, Badge, Icon} from '@astrojs/starlight/components';
import markdownit from 'markdown-it'
import markdownItMark from 'markdown-it-mark'
const md = markdownit().use(markdownItMark);
interface Props { interface Props {
word: { word: {
english: string; english: string;
hindi: string; hindi: string;
gender?: "m" | "f"; gender?: "m" | "f";
note?: string; note?: string;
examples: Array<{ examples?: Array<{
hindi: string; hindi: string;
english: string; english: string;
note?: string;
}> }>
see_also?: string[];
} }
} }
const {word}: Props = Astro.props; const {word}: Props = Astro.props;
const gender_lookup: Record<"m" | "f", ["note" | "tip", string]> = { const gender_lookup: Record<"m" | "f", ["note" | "tip", string]> = {
"m": ["note", "male"], "m": ["note", "masculine"],
"f": ["tip", "female"], "f": ["tip", "feminine"],
}; };
function highlight(text: string, term: string) { function highlight(text: string, term: string) {
const regex = new RegExp(`(${term})`, 'gi'); const terms = term.split(',').map(t => t.trim()).filter(Boolean);
const regex = new RegExp(`(${terms.map(t => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')})`, 'gi');
const parts = text.split(regex); const parts = text.split(regex);
return parts.map((part) => regex.test(part) ? `<mark>${part}</mark>` : part).join(''); return md.renderInline(parts.map((part) => regex.test(part) ? `**${part}**` : part).join(''));
} }
--- ---
<li class="word-entry"> <li id={word.hindi} class="word-entry">
<h4> <h4>
{word.hindi} ({word.english}) {word.hindi} ({word.english})
{word.gender && <Badge variant={gender_lookup[word.gender][0]} text={gender_lookup[word.gender][1]} class="gender-badge"/>} {word.gender && <Badge variant={gender_lookup[word.gender][0]} text={gender_lookup[word.gender][1]} class="gender-badge"/>}
</h4> </h4>
{word.note && {word.note &&
<div> <div set:html={md.renderInline(word.note)}></div>
{word.note}
</div>
} }
{ {
word.examples && word.examples &&
<div> <>
For example, <p>For example,</p>
{word.examples.map((e) => <ol>
<p> {word.examples.map((e) => (
<span set:html={highlight(e.hindi, word.hindi)}></span> - <span set:html={highlight(e.english, word.english)}></span> <li class="word-examples">
<p>
<span set:html={highlight(e.hindi, word.hindi)}></span> <Icon name="right-arrow" class="icon-inline" /> <span set:html={highlight(e.english, word.english)}></span>
</p>
{e.note && (
<Aside type="note" title="Note">
<p set:html={highlight(e.note, word.hindi)}></p>
</Aside>
)}
</li>
))}
</ol>
{ word.see_also && (
<p>See also:
{ word.see_also.map((ref) => (
<span set:html={md.renderInline(ref)}></span>
)) }
</p> </p>
)} )}
</div> </>
</li> </li>

View File

@ -22,9 +22,11 @@ export const collections = {
z.object({ z.object({
english: z.string(), english: z.string(),
hindi: z.string(), hindi: z.string(),
note: z.string().optional(),
}), }),
) )
.optional(), .optional(),
see_also: z.array(z.string()).optional(),
}), }),
), ),
}), }),

View File

@ -31,9 +31,9 @@ const headings = wordsByType.map(({type, words}) => {
depth: 2, depth: 2,
slug: type.toLowerCase().replace(/\s+/g, '-'), slug: type.toLowerCase().replace(/\s+/g, '-'),
}].concat(words.map((word) => ({ }].concat(words.map((word) => ({
text: word.english, text: word.hindi,
depth: 3, depth: 3,
slug: word.english.toLowerCase().replace(/\s+/g, '-'), slug: word.hindi.toLowerCase().replace(/\s+/g, '-'),
}))); })));
})[0]; })[0];
--- ---

View File

@ -226,6 +226,26 @@ h6,
margin-bottom: 2em; margin-bottom: 2em;
} }
.icon-inline {
display: inline-block;
vertical-align: text-top;
position: relative;
top: -0.1em;
}
.word-examples > p {
font-size: 0.9em;
}
.word-entry a {
text-decoration: none;
color: var(--sl-color-accent);
}
mark {
background-color: rgba(255, 255, 0, 0.2);
}
/* ================================================================= /* =================================================================
LANGUAGE-SPECIFIC STYLES LANGUAGE-SPECIFIC STYLES
================================================================= */ ================================================================= */

5
src/types/markdown-it-mark.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
declare module "markdown-it-mark" {
import { PluginSimple } from "markdown-it";
const markdownItMark: PluginSimple;
export default markdownItMark;
}

View File

@ -5,13 +5,28 @@
english: thing english: thing
hindi: बात hindi: बात
gender: f gender: f
note: More abstract than "चीज़", often used for matters, topics, or affairs. note: More abstract than "[चीज़](#चीज़)", often used for matters, topics, or affairs.
see_also: see_also:
- hindi: चीज़ - "[चीज़](#चीज़)"
examples: examples:
- english: "No problem. (Literally: (there is) nothing.)" - english: "No problem. *(Literally: [there is] nothing.)*"
hindi: कोई बात नहीं. hindi: कोई बात नहीं.
- hindi: मुझे यह बात [समझ](#understand) नहीं आई.
english: "I did not understand this thing (matter)."
note: >
आई, feminine, matches बात because the postposition in मुझे blocks the gender matching on मैं (Recall [मुझे = मैं + की](/grammar/pronouns)).
- hindi: बात करना
english: "to talk (seems to be more like: *to chat*)."
- type: noun - type: noun
english: help english: help
hindi: मदद hindi: मदद
gender: f gender: f
- slug: repetition
about: Hindi often uses repetition of words for emphasis or to indicate a variety of related meanings.
words:
- type: noun
hindi: क्या-क्या
english: what all, which all
examples:
- hindi: पिछले हफ्ते तुमने क्या-क्या किया?
english: "What all did you do last week?"