add minimal pairs page

This commit is contained in:
adueck 2024-12-17 21:06:50 -05:00
parent 82d3e4fee5
commit b3fff82766
4 changed files with 14126 additions and 0 deletions

View File

@ -119,6 +119,8 @@ import * as diacritics from "./writing/diacritics.mdx";
import * as theFiveYeys from "./writing/the-five-yeys.mdx"; import * as theFiveYeys from "./writing/the-five-yeys.mdx";
// @ts-ignore // @ts-ignore
import * as typingIssues from "./writing/typing-issues.mdx"; import * as typingIssues from "./writing/typing-issues.mdx";
// @ts-ignore
import * as minimalPairs from "./writing/minimal-pairs.mdx";
// @ts-ignore // @ts-ignore
import * as unrealConditionals from "./recipes/unreal-conditionals.mdx"; import * as unrealConditionals from "./recipes/unreal-conditionals.mdx";
@ -419,6 +421,10 @@ export const contentTree: (ChapterSection | ChaptersSection)[] =
{ {
"import": typingIssues, "import": typingIssues,
"slug": "typing-issues" "slug": "typing-issues"
},
{
"import": minimalPairs,
"slug": "minimal-pairs"
} }
] ]
}, },

View File

@ -0,0 +1,65 @@
import { InlinePs, Types as T } from "@lingdocs/ps-react";
import { useState } from "react";
// @ts-ignore
import SmoothCollapse from "react-smooth-collapse";
export default function MinimalPairs({
opts,
section,
}: {
opts: T.TextOptions;
section: {
title: string;
pairs: { f: string; entry: T.DictionaryEntry }[][];
};
}) {
const [opened, setOpened] = useState<boolean>(false);
return (
<div>
<h5 className="my-3" onClick={() => setOpened((x) => !x)}>
{opened ? "▼" : "▶"} View Pairs
</h5>
<SmoothCollapse expanded={opened}>
{section.pairs.map((pairs) => (
<div className="d-flex flex-row" style={{ gap: "1rem" }}>
{pairs.map((e) => (
<PairItem entry={e} opts={opts} />
))}
</div>
))}
</SmoothCollapse>
</div>
);
}
function PairItem({
entry,
opts,
}: {
entry: { f: string; entry: T.DictionaryEntry };
opts: T.TextOptions;
}) {
return (
<div>
<div className="mb-1">
<InlinePs
opts={opts}
ps={{ ...entry.entry, f: entry.f, e: undefined }}
/>
</div>
<audio
controls
src={getAudio(entry.entry.ts, entry.entry.a)}
preload="none"
/>
</div>
);
}
function getAudio(ts: number, a: number | undefined) {
if (!a) {
return undefined;
}
const tag = a === 1 ? "" : "f";
return `https://storage.lingdocs.com/audio/${ts}${tag}.mp3`;
}

View File

@ -0,0 +1,75 @@
---
title: Minimal Pairs 👂
---
import {
defaultTextOptions as opts,
Examples,
InlinePs,
} from "@lingdocs/ps-react";
import psmd from "../../lib/psmd";
import Link from "../../components/Link";
import MinimalPairs from "./MinimalPairs.tsx";
import minimalPairs from "./minimal-pairs.ts";
There are certain sounds in Pashto that are quite difficult for some learners to distinguish.
For example, English speakers have a very hard time hearing the difference between the dental <InlinePs opts={opts} ps={{ p: "ت", f: "t" }}/> and retroflex <InlinePs opts={opts} ps={{ p: "ټ", f: "T" }}/>. Some of the vowels like <InlinePs opts={opts} ps={{ p: "ي", f: "ee" }}/> and <InlinePs opts={opts} ps={{ p: "ې", f: "e" }}/> can also be very tricky to distinguish.
Here are some examples of words that vary by these different sounds. Listen to them to train your ear to the difference, and then use the games to see if you can hear the difference yourself. (Games coming soon! 🚧)
## ت - t and ټ - T
<MinimalPairs
opts={opts}
section={minimalPairs.find((x) => x.title === "t and T")}
/>
## د - d and ډ - D
<MinimalPairs
opts={opts}
section={minimalPairs.find((x) => x.title === "d and D")}
/>
## ر - r and ړ - R
<MinimalPairs
opts={opts}
section={minimalPairs.find((x) => x.title === "r and R")}
/>
## ن - n and ڼ - N
<MinimalPairs
opts={opts}
section={minimalPairs.find((x) => x.title === "n and N")}
/>
## ه - a and ا - aa
<MinimalPairs
opts={opts}
section={minimalPairs.find((x) => x.title === "a and aa")}
/>
## ی - ay and ۍ - uy
<MinimalPairs
opts={opts}
section={minimalPairs.find((x) => x.title === "ay and uy")}
/>
## ی - ay and ې - e
<MinimalPairs
opts={opts}
section={minimalPairs.find((x) => x.title === "ay and e")}
/>
## ي - ee and ې - e
<MinimalPairs
opts={opts}
section={minimalPairs.find((x) => x.title === "ee and e")}
/>

File diff suppressed because it is too large Load Diff