diff --git a/astro.config.mjs b/astro.config.mjs index 161ef7b..80a46cc 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,34 +1,50 @@ // @ts-check import { defineConfig } from "astro/config"; import starlight from "@astrojs/starlight"; +import YAML from "yaml"; +import fs from "fs"; + +const vocabListFile = fs.readFileSync("src/vocab_list.yaml", "utf8"); +const vocabListJson = YAML.parse(vocabListFile); +const categories = vocabListJson.map( + (/** @type {{ slug: string }} */ category) => category.slug, +); +const vocabList = [ + { + label: "Index", + link: `/vocab/index`, + }, +].concat( + categories.map((/** @type {string} */ category) => ({ + label: category.charAt(0).toUpperCase() + category.slice(1), + link: `/vocab/${category}`, + })), +); // https://astro.build/config export default defineConfig({ + vite: { + resolve: { + alias: { + "@": "/src", + }, + }, + }, integrations: [ starlight({ title: "हिंदकी", - social: [ - { - icon: "github", - label: "GitHub", - href: "https://github.com/withastro/starlight", - }, - ], customCss: [ // Path to your custom CSS file "./src/styles/custom.css", ], sidebar: [ { - label: "Guides", - items: [ - // Each item here is one entry in the navigation menu. - { label: "Example Guide", slug: "guides/example" }, - ], + label: "Vocabulary", + items: vocabList, }, { - label: "Reference", - autogenerate: { directory: "reference" }, + label: "Grammar", + autogenerate: { directory: "grammar" }, }, ], }), diff --git a/package-lock.json b/package-lock.json index af185c7..747096c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "dependencies": { "@astrojs/starlight": "^0.36.0", "astro": "^5.6.1", - "sharp": "^0.34.2" + "sharp": "^0.34.2", + "yaml": "^2.8.1" }, "devDependencies": { "prettier": "^3.6.2", @@ -6296,6 +6297,18 @@ "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", "license": "MIT" }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", diff --git a/package.json b/package.json index 8e1fc20..6200683 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "dependencies": { "@astrojs/starlight": "^0.36.0", "astro": "^5.6.1", - "sharp": "^0.34.2" + "sharp": "^0.34.2", + "yaml": "^2.8.1" }, "devDependencies": { "prettier": "^3.6.2", diff --git a/src/components/VocabWord.astro b/src/components/VocabWord.astro new file mode 100644 index 0000000..20c401f --- /dev/null +++ b/src/components/VocabWord.astro @@ -0,0 +1,50 @@ +--- + import {Badge} from '@astrojs/starlight/components'; +interface Props { + word: { + english: string; + hindi: string; + gender?: "m" | "f"; + note?: string; + examples: Array<{ + hindi: string; + english: string; + }> +} +} + +const {word}: Props = Astro.props; + +const gender_lookup: Record<"m" | "f", ["note" | "tip", string]> = { + "m": ["note", "male"], + "f": ["tip", "female"], +}; + +function highlight(text: string, term: string) { + const regex = new RegExp(`(${term})`, 'gi'); + const parts = text.split(regex); + return 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) => +

    + - +

    + )} +
    + +
  • \ No newline at end of file diff --git a/src/content.config.ts b/src/content.config.ts index d9ee8c9..ae8e3e0 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -1,7 +1,32 @@ -import { defineCollection } from 'astro:content'; -import { docsLoader } from '@astrojs/starlight/loaders'; -import { docsSchema } from '@astrojs/starlight/schema'; +import { defineCollection } from "astro:content"; +import { docsLoader } from "@astrojs/starlight/loaders"; +import { docsSchema } from "@astrojs/starlight/schema"; +import { file } from "astro/loaders"; +import { z } from "zod"; export const collections = { - docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), + vocabList: defineCollection({ + loader: file("src/vocab_list.yaml"), + schema: z.object({ + about: z.string().optional(), + words: z.array( + z.object({ + type: z.string(), + english: z.string(), + hindi: z.string(), + gender: z.enum(["m", "f"]).optional(), + note: z.string().optional(), + examples: z + .array( + z.object({ + english: z.string(), + hindi: z.string(), + }), + ) + .optional(), + }), + ), + }), + }), }; diff --git a/src/content/docs/grammar/intro.mdx b/src/content/docs/grammar/intro.mdx new file mode 100644 index 0000000..b420ce9 --- /dev/null +++ b/src/content/docs/grammar/intro.mdx @@ -0,0 +1,13 @@ +--- +title: Grammar Introduction +--- + +Yo yo. + +## Here's an h2. + +Stuff. + +### Here's an h3. + +More shit. diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx index 99c927d..39352f5 100644 --- a/src/content/docs/index.mdx +++ b/src/content/docs/index.mdx @@ -8,8 +8,8 @@ head: hero: tagline: Welcome to Hindki! actions: - - text: Dictionary - link: /dictionary/index/ + - text: Jump In + link: /vocabulary icon: right-arrow - text: Hindi Textbook (260 MB) link: https://files.pandu.ski/share/2BfsIfEb diff --git a/src/content/docs/vocabulary/datetime.mdx b/src/content/docs/vocabulary/datetime.mdx new file mode 100644 index 0000000..fedf3c0 --- /dev/null +++ b/src/content/docs/vocabulary/datetime.mdx @@ -0,0 +1,14 @@ +--- +title: Dates and Times +--- + +When specifying a point in time, generally, को is used, e.g. रात को, सोमवार को. However, for some reason, सुबह में is used instead. + +## General words + +Words for the various units of date and time. + +Starting off strong with: + +- तारिख / _Date_ +- **Time** / समय diff --git a/src/content/docs/vocabulary/education.mdx b/src/content/docs/vocabulary/education.mdx new file mode 100644 index 0000000..bbff641 --- /dev/null +++ b/src/content/docs/vocabulary/education.mdx @@ -0,0 +1,10 @@ +--- +title: Education +--- + +Learning about learning. + +## Roles + +- शिक्षक / _teacher_ +- चात्र / _student_ diff --git a/src/content/docs/vocabulary/food_drink.mdx b/src/content/docs/vocabulary/food_drink.mdx new file mode 100644 index 0000000..563d90d --- /dev/null +++ b/src/content/docs/vocabulary/food_drink.mdx @@ -0,0 +1,11 @@ +--- +title: Food and Drink +--- + +जो खाएं और पिये जाते हैं. + +## Nouns + +- + +## Verbs diff --git a/src/content/docs/vocabulary/index.mdx b/src/content/docs/vocabulary/index.mdx new file mode 100644 index 0000000..94b0679 --- /dev/null +++ b/src/content/docs/vocabulary/index.mdx @@ -0,0 +1,7 @@ +--- +title: Index +--- + +## Welcome to the Hindki Docs! + +Test test test. diff --git a/src/content/docs/vocabulary/media.mdx b/src/content/docs/vocabulary/media.mdx new file mode 100644 index 0000000..7ccbe3e --- /dev/null +++ b/src/content/docs/vocabulary/media.mdx @@ -0,0 +1,13 @@ +--- +title: Media +--- + +import VocabWord from "@/components/VocabWord.astro"; + +जो पढ़ीं और देखीं जाते हैं. + +## Reading words + +- + +## Viewing words diff --git a/src/content/docs/vocabulary/substances.mdx b/src/content/docs/vocabulary/substances.mdx new file mode 100644 index 0000000..7cc6069 --- /dev/null +++ b/src/content/docs/vocabulary/substances.mdx @@ -0,0 +1,9 @@ +--- +title: Elements and Substances +--- + +Stuff in the world. + +## Elements + +- आग / _fire_ diff --git a/src/pages/vocab/[category].astro b/src/pages/vocab/[category].astro new file mode 100644 index 0000000..0ce9a1a --- /dev/null +++ b/src/pages/vocab/[category].astro @@ -0,0 +1,63 @@ +--- + import { getCollection, getEntry } from 'astro:content'; + import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; +import VocabWord from '@/components/VocabWord.astro'; + +function titlecase(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1); +} + + export async function getStaticPaths() { + const vocabList = await getCollection("vocabList"); + return vocabList.map((category) => ({ + params: { category: category.id }, + })); + } + +const { category } = Astro.params; +const entry = await getEntry("vocabList", category); +entry!.id = titlecase(entry!.id); + + +const wordtypes = [...new Set(entry!.data.words.map((word) => word.type))]; +const wordsByType = wordtypes.map((type) => ({ + type: titlecase(type) + "s", + words: entry!.data.words.filter((word) => word.type === type), +})); + +const headings = wordsByType.map(({type, words}) => { + return [{ + text: type, + depth: 2, + slug: type.toLowerCase().replace(/\s+/g, '-'), + }].concat(words.map((word) => ({ + text: word.english, + depth: 3, + slug: word.english.toLowerCase().replace(/\s+/g, '-'), + }))); +})[0]; +--- + + +
    + { entry?.data.about} +
    + { + wordsByType.map(({type, words}) => ( +
    +

    {type}

    +
      + { + words.map((word) => ( + + )) + } +
    +
    + )) + } + +
    \ No newline at end of file diff --git a/src/styles/custom.css b/src/styles/custom.css index faf4b49..43f9ae9 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -1,4 +1,8 @@ -/* MinionPro (Default serif font) */ +/* ================================================================= + FONT DECLARATIONS + ================================================================= */ + +/* MinionPro (Serif font) */ @font-face { font-family: "MinionPro"; src: url("/fonts/MinionPro_Regular.otf") format("opentype"); @@ -31,7 +35,7 @@ font-display: swap; } -/* MyriadPro (Default sans-serif font) */ +/* MyriadPro (Sans-serif font) */ @font-face { font-family: "MyriadPro"; src: url("/fonts/MyriadPro_Regular.otf") format("opentype"); @@ -64,99 +68,11 @@ font-display: swap; } -/* Custom font for Devanagari script - Multiple weights */ -@font-face { - font-family: "hindi"; - src: url("/fonts/Martel-Light.ttf") format("truetype"); - font-weight: 300; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "hindi"; - src: url("/fonts/Martel-Regular.ttf") format("truetype"); - font-weight: 400; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "hindi"; - src: url("/fonts/Martel-SemiBold.ttf") format("truetype"); - font-weight: 600; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "hindi"; - src: url("/fonts/Martel-Bold.ttf") format("truetype"); - font-weight: 700; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: "hindi"; - src: url("/fonts/Martel-Black.ttf") format("truetype"); - font-weight: 900; - font-style: normal; - font-display: swap; -} - -/* Apply default fonts and Devanagari font to content */ -:root { - --sl-font-system: "MyriadPro", system-ui, sans-serif; - --sl-font: "MyriadPro", system-ui, sans-serif; -} - -/* Set global font default to sans-serif */ -body { - font-family: "MyriadPro", system-ui, sans-serif; -} - -/* Apply serif font to content/reading areas */ -p, -.sl-markdown-content p, -blockquote, -.sl-markdown-content blockquote, -li, -.sl-markdown-content li, -.content, -.prose, -.sl-markdown-content { - font-family: "MinionPro", Georgia, serif; - font-size: 1.5rem; /* 18px, up from default 16px */ -} - -/* Keep UI elements as sans-serif with Devanagari support */ -.sl-nav, -.sl-sidebar, -.sl-page-title, -.card, -.starlight-card, -button, -.sl-search-box, -nav, -header, -footer { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; -} - -/* Specific targeting for Devanagari text */ -[lang="hi"], -[lang="sa"], -.devanagari { - font-family: "hindi", "Noto Sans Devanagari", sans-serif !important; -} - -/* Auto-detect Devanagari characters using CSS unicode-range approach */ -/* This creates a fallback system that will use the hindi font for Devanagari characters */ +/* Devanagari fonts with auto-detection via unicode-range */ @font-face { font-family: "DevanagariAuto"; - src: url("/fonts/Martel-Regular.ttf") format("truetype"); - font-weight: 400; + src: url("/fonts/Martel-Light.ttf") format("truetype"); + font-weight: 300; font-style: normal; font-display: swap; unicode-range: @@ -165,8 +81,8 @@ footer { @font-face { font-family: "DevanagariAuto"; - src: url("/fonts/Martel-Light.ttf") format("truetype"); - font-weight: 300; + src: url("/fonts/Martel-Regular.ttf") format("truetype"); + font-weight: 400; font-style: normal; font-display: swap; unicode-range: U+0900-097F, U+200C-200D; @@ -199,146 +115,38 @@ footer { unicode-range: U+0900-097F, U+200C-200D; } -/* Update font stacks to include automatic Devanagari detection */ -body { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; -} +/* ================================================================= + CSS CUSTOM PROPERTIES (VARIABLES) + ================================================================= */ -/* Apply serif font to content/reading areas with Devanagari support */ -p, -.sl-markdown-content p, -blockquote, -.sl-markdown-content blockquote, -li, -.sl-markdown-content li, -.content, -.prose, -.sl-markdown-content { - font-family: "DevanagariAuto", "MinionPro", Georgia, serif; - font-size: 1.5rem; /* 18px, up from default 16px */ -} - -/* Alternative approach: Apply to all text content */ -/* Uncomment if you want the Devanagari font to be the primary font */ -/* -body { - font-family: 'DevanagariFont', 'Noto Sans Devanagari', system-ui, sans-serif; -} -*/ - -/* Ensure proper rendering for complex scripts */ -.devanagari, -[lang="hi"], -[lang="sa"] { - font-feature-settings: - "kern" 1, - "liga" 1; - text-rendering: optimizeLegibility; -} - -/* Font weight utility classes */ -.hindi-light { - font-family: "hindi", "Noto Sans Devanagari", sans-serif; - font-weight: 300; -} - -.hindi-regular { - font-family: "hindi", "Noto Sans Devanagari", sans-serif; - font-weight: 400; -} - -.hindi-semibold { - font-family: "hindi", "Noto Sans Devanagari", sans-serif; - font-weight: 600; -} - -.hindi-bold { - font-family: "hindi", "Noto Sans Devanagari", sans-serif; - font-weight: 700; -} - -.hindi-black { - font-family: "hindi", "Noto Sans Devanagari", sans-serif; - font-weight: 900; -} - -/* Override Starlight's heading fonts */ -h1, -.sl-markdown-content h1 { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; - font-weight: 700; /* Bold */ -} - -h2, -.sl-markdown-content h2 { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; - font-weight: 700; /* Bold */ -} - -h3, -.sl-markdown-content h3, -h4, -.sl-markdown-content h4 { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; - font-weight: 700; /* Bold */ -} - -h5, -.sl-markdown-content h5, -h6, -.sl-markdown-content h6 { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; - font-weight: 400; /* Regular */ -} - -/* Font family utility classes */ -.minion, -.serif { - font-family: "DevanagariAuto", "MinionPro", Georgia, serif; -} - -.myriad, -.sans { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; -} - -/* Font weight utilities for main fonts */ -.minion-regular, -.serif-regular { - font-family: "DevanagariAuto", "MinionPro", Georgia, serif; - font-weight: 400; -} - -.minion-bold, -.serif-bold { - font-family: "DevanagariAuto", "MinionPro", Georgia, serif; - font-weight: 700; -} - -.myriad-regular, -.sans-regular { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; - font-weight: 400; -} - -.myriad-bold, -.sans-bold { - font-family: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; - font-weight: 700; -} - -/* Custom background colors for a more paper-like feel */ :root { + /* Font stacks */ + --font-sans: "DevanagariAuto", "MyriadPro", system-ui, sans-serif; + --font-serif: "DevanagariAuto", "MinionPro", Georgia, serif; + --font-devanagari: "DevanagariAuto", "Noto Sans Devanagari", sans-serif; + + /* Starlight overrides */ + --sl-font-system: var(--font-sans); + --sl-font: var(--font-sans); + /* Light theme - warm paper-like background */ --sl-color-bg: #fefcf8; /* Warm off-white, like aged paper */ --sl-color-bg-nav: #faf8f4; /* Slightly darker for navigation */ --sl-color-bg-sidebar: #f8f6f2; /* Even softer for sidebar */ --sl-color-bg-inline-code: #f4f2ee; /* Subtle for inline code */ - /* Custom accent color for links and buttons */ + /* Custom accent color */ --sl-color-accent: #336699; --sl-color-accent-low: #336699; --sl-color-accent-high: #336699; + + /* Gender badge colors */ + /* Cyan for masculine */ + --sl-badge-note-bg: #3399cc; + --sl-badge-note-border: #3388bb; + /* Magenta for feminine */ + --sl-badge-tip-bg: #cc3366; + --sl-badge-tip-border: #bb3355; } /* Dark theme overrides */ @@ -348,18 +156,185 @@ h6, --sl-color-bg-sidebar: #16140f; --sl-color-bg-inline-code: #2a2620; - /* Keep the same accent color in dark theme */ --sl-color-accent: #336699; --sl-color-accent-low: #336699; --sl-color-accent-high: #336699; } -/* Additional paper-like styling */ +/* ================================================================= + BASE STYLES + ================================================================= */ + body { + font-family: var(--font-sans); background-color: var(--sl-color-bg); } -/* Subtle texture effect (optional) */ +/* Content areas use serif font */ +p, +.sl-markdown-content p, +blockquote, +.content, +.prose, +.sl-markdown-content { + font-family: var(--font-serif); + font-size: 1.5rem; /* 18px, up from default 16px */ +} + +/* UI elements remain sans-serif */ +.sl-nav, +.sidebar-content, +.sl-page-title, +.card, +.starlight-card, +button, +.sl-search-box, +nav, +header, +footer { + font-family: var(--font-sans); +} + +/* Headings */ +h1, +.sl-markdown-content h1, +h2, +.sl-markdown-content h2, +h3, +.sl-markdown-content h3, +h4, +.sl-markdown-content h4 { + font-family: var(--font-sans); + font-weight: 700; +} + +h5, +.sl-markdown-content h5, +h6, +.sl-markdown-content h6 { + font-family: var(--font-sans); + font-weight: 400; +} + +.gender-badge { + margin-left: 0.5rem; + vertical-align: middle; + font-family: var(--font-sans); +} + +.word-entry { + margin-bottom: 2em; +} + +/* ================================================================= + LANGUAGE-SPECIFIC STYLES + ================================================================= */ + +/* Devanagari text optimization */ +[lang="hi"], +[lang="sa"], +.devanagari { + font-family: var(--font-devanagari) !important; + font-feature-settings: + "kern" 1, + "liga" 1; + text-rendering: optimizeLegibility; +} + +/* ================================================================= + UTILITY CLASSES + ================================================================= */ + +/* Font family utilities */ +.serif { + font-family: var(--font-serif); +} +.sans { + font-family: var(--font-sans); +} +.devanagari-font { + font-family: var(--font-devanagari); +} + +/* Font weight utilities */ +.font-light { + font-weight: 300; +} +.font-regular { + font-weight: 400; +} +.font-semibold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.font-black { + font-weight: 900; +} + +/* Combined font family + weight utilities */ +.serif-regular { + font-family: var(--font-serif); + font-weight: 400; +} +.serif-bold { + font-family: var(--font-serif); + font-weight: 700; +} +.sans-regular { + font-family: var(--font-sans); + font-weight: 400; +} +.sans-bold { + font-family: var(--font-sans); + font-weight: 700; +} + +/* Devanagari-specific weight utilities */ +.hindi-light { + font-family: var(--font-devanagari); + font-weight: 300; +} +.hindi-regular { + font-family: var(--font-devanagari); + font-weight: 400; +} +.hindi-semibold { + font-family: var(--font-devanagari); + font-weight: 600; +} +.hindi-bold { + font-family: var(--font-devanagari); + font-weight: 700; +} +.hindi-black { + font-family: var(--font-devanagari); + font-weight: 900; +} + +/* Legacy aliases */ +.minion-regular { + font-family: var(--font-serif); + font-weight: 400; +} +.minion-bold { + font-family: var(--font-serif); + font-weight: 700; +} +.myriad-regular { + font-family: var(--font-sans); + font-weight: 400; +} +.myriad-bold { + font-family: var(--font-sans); + font-weight: 700; +} + +/* ================================================================= + THEME ENHANCEMENTS + ================================================================= */ + .sl-markdown-content, main { background-color: var(--sl-color-bg); diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..7efb0f8 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,10 @@ +export interface VocabWord { + type: "noun" | "verb" | "adjective" | "adverb" | "phrase" | "other"; + english: string; + hindi: string; + gender?: "m" | "f"; +} +export interface VocabCategory { + slug: string; + words: VocabWord[]; +} diff --git a/src/vocab_list.yaml b/src/vocab_list.yaml new file mode 100644 index 0000000..242bc8e --- /dev/null +++ b/src/vocab_list.yaml @@ -0,0 +1,17 @@ +- slug: general + about: Common everyday vocabulary words. + words: + - type: noun + english: thing + hindi: बात + gender: f + note: More abstract than "चीज़", often used for matters, topics, or affairs. + see_also: + - hindi: चीज़ + examples: + - english: "No problem. (Literally: (there is) nothing.)" + hindi: कोई बात नहीं. + - type: noun + english: help + hindi: मदद + gender: f diff --git a/tsconfig.json b/tsconfig.json index 8bf91d3..990abae 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,11 @@ { "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], - "exclude": ["dist"] + "exclude": ["dist"], + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + } }