From fc3bcd064a590d39f2ce50c55319c81a6a4180a1 Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 23 Sep 2025 12:23:57 -0700 Subject: [PATCH] Maybe off to the races to start fleshing out the vocab list --- astro.config.mjs | 1 + package-lock.json | 90 ++++++++++++++++++++++++++++++++ package.json | 3 ++ src/components/VocabWord.astro | 54 +++++++++++++------ src/content.config.ts | 2 + src/pages/vocab/[category].astro | 4 +- src/styles/custom.css | 20 +++++++ src/types/markdown-it-mark.d.ts | 5 ++ src/{ => types}/types.ts | 0 src/vocab_list.yaml | 21 ++++++-- 10 files changed, 178 insertions(+), 22 deletions(-) create mode 100644 src/types/markdown-it-mark.d.ts rename src/{ => types}/types.ts (100%) diff --git a/astro.config.mjs b/astro.config.mjs index 80a46cc..4b57326 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -9,6 +9,7 @@ const vocabListJson = YAML.parse(vocabListFile); const categories = vocabListJson.map( (/** @type {{ slug: string }} */ category) => category.slug, ); + const vocabList = [ { label: "Index", diff --git a/package-lock.json b/package-lock.json index 747096c..c9ce8cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,10 @@ "version": "0.0.1", "dependencies": { "@astrojs/starlight": "^0.36.0", + "@types/markdown-it": "^14.1.2", "astro": "^5.6.1", + "markdown-it": "^14.1.0", + "markdown-it-mark": "^4.0.0", "sharp": "^0.34.2", "yaml": "^2.8.1" }, @@ -1709,6 +1712,22 @@ "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", "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": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -1718,6 +1737,12 @@ "@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": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", @@ -3451,6 +3476,15 @@ "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": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -3499,6 +3533,41 @@ "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": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -3838,6 +3907,12 @@ "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "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": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -4999,6 +5074,15 @@ "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": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", @@ -5777,6 +5861,12 @@ "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": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", diff --git a/package.json b/package.json index 6200683..8814013 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,10 @@ }, "dependencies": { "@astrojs/starlight": "^0.36.0", + "@types/markdown-it": "^14.1.2", "astro": "^5.6.1", + "markdown-it": "^14.1.0", + "markdown-it-mark": "^4.0.0", "sharp": "^0.34.2", "yaml": "^2.8.1" }, diff --git a/src/components/VocabWord.astro b/src/components/VocabWord.astro index 20c401f..8c1e5a0 100644 --- a/src/components/VocabWord.astro +++ b/src/components/VocabWord.astro @@ -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 { word: { english: string; hindi: string; gender?: "m" | "f"; note?: string; - examples: Array<{ + examples?: Array<{ hindi: string; english: string; + note?: string; }> + see_also?: string[]; } } const {word}: Props = Astro.props; const gender_lookup: Record<"m" | "f", ["note" | "tip", string]> = { - "m": ["note", "male"], - "f": ["tip", "female"], + "m": ["note", "masculine"], + "f": ["tip", "feminine"], }; 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); - return parts.map((part) => regex.test(part) ? `${part}` : part).join(''); + return md.renderInline(parts.map((part) => regex.test(part) ? `**${part}**` : part).join('')); } --- -
  • +
  • {word.hindi} ({word.english}) {word.gender && }

    {word.note && -
    - {word.note} -
    +
    } { word.examples && -
    - For example, - {word.examples.map((e) => -

    - - + <> +

    For example,

    +
      + {word.examples.map((e) => ( +
    1. +

      + +

      + {e.note && ( + + )} +
    2. + ))} +
    + { word.see_also && ( +

    See also: + { word.see_also.map((ref) => ( + + )) }

    )} -
    - +
  • \ No newline at end of file diff --git a/src/content.config.ts b/src/content.config.ts index ae8e3e0..013e64f 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -22,9 +22,11 @@ export const collections = { z.object({ english: z.string(), hindi: z.string(), + note: z.string().optional(), }), ) .optional(), + see_also: z.array(z.string()).optional(), }), ), }), diff --git a/src/pages/vocab/[category].astro b/src/pages/vocab/[category].astro index 0ce9a1a..5fd05e8 100644 --- a/src/pages/vocab/[category].astro +++ b/src/pages/vocab/[category].astro @@ -31,9 +31,9 @@ const headings = wordsByType.map(({type, words}) => { depth: 2, slug: type.toLowerCase().replace(/\s+/g, '-'), }].concat(words.map((word) => ({ - text: word.english, + text: word.hindi, depth: 3, - slug: word.english.toLowerCase().replace(/\s+/g, '-'), + slug: word.hindi.toLowerCase().replace(/\s+/g, '-'), }))); })[0]; --- diff --git a/src/styles/custom.css b/src/styles/custom.css index 43f9ae9..85c8910 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -226,6 +226,26 @@ h6, 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 ================================================================= */ diff --git a/src/types/markdown-it-mark.d.ts b/src/types/markdown-it-mark.d.ts new file mode 100644 index 0000000..5df9453 --- /dev/null +++ b/src/types/markdown-it-mark.d.ts @@ -0,0 +1,5 @@ +declare module "markdown-it-mark" { + import { PluginSimple } from "markdown-it"; + const markdownItMark: PluginSimple; + export default markdownItMark; +} diff --git a/src/types.ts b/src/types/types.ts similarity index 100% rename from src/types.ts rename to src/types/types.ts diff --git a/src/vocab_list.yaml b/src/vocab_list.yaml index 242bc8e..7ad866b 100644 --- a/src/vocab_list.yaml +++ b/src/vocab_list.yaml @@ -5,13 +5,28 @@ english: thing hindi: बात 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: - - hindi: चीज़ + - "[चीज़](#चीज़)" examples: - - english: "No problem. (Literally: (there is) nothing.)" + - english: "No problem. *(Literally: [there is] nothing.)*" 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 english: help hindi: मदद 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?"