allow for JSX in Pashto text!! 💪
This commit is contained in:
parent
aae06148ad
commit
cdea37e024
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@lingdocs/pashto-inflector",
|
"name": "@lingdocs/pashto-inflector",
|
||||||
"version": "0.4.4",
|
"version": "0.4.5",
|
||||||
"author": "lingdocs.com",
|
"author": "lingdocs.com",
|
||||||
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
|
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
|
||||||
"homepage": "https://verbs.lingdocs.com",
|
"homepage": "https://verbs.lingdocs.com",
|
||||||
|
|
16
src/App.tsx
16
src/App.tsx
|
@ -11,6 +11,7 @@ import ConjugationViewer from "./components/ConjugationViewer";
|
||||||
import verbs from "./verbs";
|
import verbs from "./verbs";
|
||||||
import Pashto from "./components/Pashto";
|
import Pashto from "./components/Pashto";
|
||||||
import Phonetics from "./components/Phonetics";
|
import Phonetics from "./components/Phonetics";
|
||||||
|
import InlinePs from "./components/InlinePs";
|
||||||
import { conjugateVerb } from "./lib/verb-conjugation";
|
import { conjugateVerb } from "./lib/verb-conjugation";
|
||||||
import { getVerbInfo } from "./lib/verb-info";
|
import { getVerbInfo } from "./lib/verb-info";
|
||||||
import ButtonSelect from "./components/ButtonSelect";
|
import ButtonSelect from "./components/ButtonSelect";
|
||||||
|
@ -25,7 +26,6 @@ import {
|
||||||
} from "react-bootstrap";
|
} from "react-bootstrap";
|
||||||
import * as T from "./types";
|
import * as T from "./types";
|
||||||
import defualtTextOptions from "./lib/default-text-options";
|
import defualtTextOptions from "./lib/default-text-options";
|
||||||
import InlinePs from "./components/InlinePs";
|
|
||||||
|
|
||||||
type VerbType = "simple" | "stative compound" | "dynamic compound";
|
type VerbType = "simple" | "stative compound" | "dynamic compound";
|
||||||
const verbTypes: VerbType[] = [
|
const verbTypes: VerbType[] = [
|
||||||
|
@ -181,14 +181,12 @@ function App() {
|
||||||
const conjugation = v
|
const conjugation = v
|
||||||
? conjugateVerb(v.verb.entry, aayTailType, v.verb.complement)
|
? conjugateVerb(v.verb.entry, aayTailType, v.verb.complement)
|
||||||
: undefined;
|
: undefined;
|
||||||
if (v) {
|
// if (v) {
|
||||||
console.log("Verb chosen:");
|
// console.log("Verb chosen:");
|
||||||
console.log(v.verb);
|
// console.log(v.verb);
|
||||||
console.log("Conjugation of verb:")
|
// console.log("Conjugation of verb:")
|
||||||
console.log(conjugation);
|
// console.log(conjugation);
|
||||||
}
|
// }
|
||||||
console.log(verbTypeShowing);
|
|
||||||
console.log(textOptions);
|
|
||||||
return <>
|
return <>
|
||||||
<main className="flex-shrink-0 mb-4">
|
<main className="flex-shrink-0 mb-4">
|
||||||
<div className="container" style={{ maxWidth: "800px" }}>
|
<div className="container" style={{ maxWidth: "800px" }}>
|
||||||
|
|
|
@ -15,8 +15,8 @@ function InlinePs ({
|
||||||
ps,
|
ps,
|
||||||
opts,
|
opts,
|
||||||
}: {
|
}: {
|
||||||
ps?: T.PsString,
|
ps?: T.PsString | (T.PsJSX & { e?: string }),
|
||||||
children: T.PsString,
|
children: T.PsString | (T.PsJSX & { e?: string }),
|
||||||
opts: T.TextOptions,
|
opts: T.TextOptions,
|
||||||
}) {
|
}) {
|
||||||
const text = children || ps;
|
const text = children || ps;
|
||||||
|
|
|
@ -12,21 +12,34 @@ import {
|
||||||
import {
|
import {
|
||||||
phoneticsToDiacritics
|
phoneticsToDiacritics
|
||||||
} from "../lib/phonetics-to-diacritics";
|
} from "../lib/phonetics-to-diacritics";
|
||||||
|
import { psJSXMap } from "../lib/jsx-map";
|
||||||
import * as T from "../types";
|
import * as T from "../types";
|
||||||
|
|
||||||
const Pashto = ({ opts, children: text }: {
|
const Pashto = ({ opts, children: text }: {
|
||||||
opts: T.TextOptions,
|
opts: T.TextOptions,
|
||||||
children: T.PsString,
|
children: T.PsString | T.PsJSX,
|
||||||
}) => {
|
}) => {
|
||||||
const p = opts.diacritics
|
function convertText(ps: T.PsString, opts: T.TextOptions): string {
|
||||||
? (phoneticsToDiacritics(text.p, text.f) || text.p)
|
const p = opts.diacritics
|
||||||
: text.p;
|
? (phoneticsToDiacritics(ps.p, ps.f) || ps.p)
|
||||||
|
: ps.p;
|
||||||
|
return opts.spelling === "Afghan"
|
||||||
|
? p
|
||||||
|
: convertAfToPkSpelling(p);
|
||||||
|
}
|
||||||
|
if (typeof text.p !== "string" && typeof text.f !== "string") {
|
||||||
|
return psJSXMap(
|
||||||
|
text as T.PsJSX,
|
||||||
|
"p",
|
||||||
|
(ps: T.PsString) => convertText(ps, opts),
|
||||||
|
);
|
||||||
|
}
|
||||||
const style = opts.pTextSize === "normal"
|
const style = opts.pTextSize === "normal"
|
||||||
? undefined
|
? undefined
|
||||||
: { fontSize: opts.pTextSize === "larger" ? "large" : "larger" };
|
: { fontSize: opts.pTextSize === "larger" ? "large" : "larger" };
|
||||||
return (
|
return (
|
||||||
<span className="p-text" dir="rtl" style={style}>
|
<span className="p-text" dir="rtl" style={style}>
|
||||||
{opts.spelling === "Afghan" ? p : convertAfToPkSpelling(p)}
|
{convertText(text as T.PsString, opts)}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,22 +9,31 @@
|
||||||
import {
|
import {
|
||||||
translatePhonetics,
|
translatePhonetics,
|
||||||
} from "../lib/translate-phonetics";
|
} from "../lib/translate-phonetics";
|
||||||
|
import { psJSXMap } from "../lib/jsx-map";
|
||||||
import * as T from "../types";
|
import * as T from "../types";
|
||||||
|
|
||||||
const Phonetics = ({ opts, children: text }: {
|
const Phonetics = ({ opts, children: text }: {
|
||||||
opts: T.TextOptions,
|
opts: T.TextOptions,
|
||||||
children: T.PsString,
|
children: T.PsJSX | T.PsString | string,
|
||||||
}) => {
|
}) => {
|
||||||
if (opts.phonetics === "none") {
|
if (opts.phonetics === "none") {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return <span className="f-text">
|
const handleText = (f: string) => (
|
||||||
{opts.phonetics === "lingdocs"
|
opts.phonetics === "lingdocs"
|
||||||
? text.f
|
? f
|
||||||
: translatePhonetics(text.f, {
|
: translatePhonetics(f, {
|
||||||
dialect: opts.dialect,
|
dialect: opts.dialect,
|
||||||
|
// @ts-ignore - weird TS not picking up the elimination of "none herre"
|
||||||
system: opts.phonetics,
|
system: opts.phonetics,
|
||||||
})}
|
})
|
||||||
|
);
|
||||||
|
if (typeof text !== "string" && typeof text.f !== "string") {
|
||||||
|
return psJSXMap(text as T.PsJSX, "f", ({f}) => handleText(f));
|
||||||
|
}
|
||||||
|
const f = typeof text === "string" ? text : text.f as string;
|
||||||
|
return <span className="f-text">
|
||||||
|
{handleText(f)}
|
||||||
</span>
|
</span>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { psJSXMap, JSXMap } from "./jsx-map";
|
||||||
|
|
||||||
|
test("psJSXMap should work with f as a target", () => {
|
||||||
|
const input = { p: <>زه کور ته <strong>ځم</strong></>, f: <>zu kor ta <strong>dzum</strong></> };
|
||||||
|
const output = psJSXMap(input, "p", (ps) => ps.p.replace(/ځ/g, "ز"));
|
||||||
|
expect(output).toEqual(<>زه کور ته <strong>زم</strong></>);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("psJSXMap should work with f as a target", () => {
|
||||||
|
const input = { p: <>زه کور ته <strong>ځم</strong></>, f: <>zu kor ta <strong>dzum</strong></> };
|
||||||
|
const output = psJSXMap(input, "f", (ps) => ps.f.replace(/dz/g, "z"));
|
||||||
|
expect(output).toEqual(<>zu kor ta <strong>zum</strong></>);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("psJSXMap will error if given an uneven/unbalanced pair of JSX Elements", () => {
|
||||||
|
expect(() => {
|
||||||
|
const input = { p: <>زه کور ته <strong>ځم</strong></>, f: <>zu kor ta dzum</> };
|
||||||
|
psJSXMap(input, "p", (ps) => ps.p.replace(/ځ/g, "ز"));
|
||||||
|
}).toThrow("error mapping out PsJSX - unbalanced trees");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("plain JSX map util", () => {
|
||||||
|
const input = <>this <em>will be <strong>transformed</strong></em> <span>nicely</span></>;
|
||||||
|
const output = JSXMap(input, (s) => s.toUpperCase());
|
||||||
|
expect(output).toEqual(<>THIS <em>WILL BE <strong>TRANSFORMED</strong></em> <span>NICELY</span></>);
|
||||||
|
});
|
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2021 lingdocs.com
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as T from "../types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows PsString transforming methods to be applied to a Pashto/Phonetics set of JSX elements
|
||||||
|
* outputs a single part of the pair (p or f) with the transform function applied to all the text
|
||||||
|
* within
|
||||||
|
* eg: { p: <>زه <strong>ځم</strong></>, f : <>zu <strong>dzum</strong></> }
|
||||||
|
*
|
||||||
|
* @param ps
|
||||||
|
* @param target
|
||||||
|
* @param dealWithString
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function psJSXMap(ps: T.PsJSX, target: "p" | "f", dealWithString: (ps: T.PsString) => string): JSX.Element {
|
||||||
|
const base = ps[target];
|
||||||
|
const sec = ps[target === "p" ? "f" : "p"];
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
props: {
|
||||||
|
...base.props,
|
||||||
|
children: typeof base.props.children === "string"
|
||||||
|
? dealWithString({
|
||||||
|
p: (target === "p" ? base : sec).props.children,
|
||||||
|
f: (target === "p" ? sec : base).props.children,
|
||||||
|
})
|
||||||
|
: base.props.children.map((x: string | JSX.Element, i: number) => {
|
||||||
|
if (typeof x === "string") {
|
||||||
|
return dealWithString({
|
||||||
|
p: (target === "p" ? x : sec.props.children[i]),
|
||||||
|
f: (target === "p" ? sec.props.children[i] : x),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return psJSXMap({
|
||||||
|
p: (target === "p" ? x : sec.props.children[i]),
|
||||||
|
f: (target === "p" ? sec.props.children[i] : x),
|
||||||
|
}, target, dealWithString);
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
throw new Error("error mapping out PsJSX - unbalanced trees");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UNUSED POC OF THE BASIC JSXMAP - COULD BE PUBLISHED SEPERATELY
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows a text transform function to be run over all the text in a JSX element
|
||||||
|
*
|
||||||
|
* @param e a JSX Element
|
||||||
|
* @param f a function to transform the text
|
||||||
|
* @returns the JSX Element with all the text transformed
|
||||||
|
*/
|
||||||
|
export function JSXMap(e: JSX.Element, f: (s: string) => string): JSX.Element {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
props: {
|
||||||
|
...e.props,
|
||||||
|
children: typeof e.props.children === "string"
|
||||||
|
? f(e.props.children)
|
||||||
|
: e.props.children.map((x: string | JSX.Element, i: number) => {
|
||||||
|
if (typeof x === "string") {
|
||||||
|
return f(x);
|
||||||
|
}
|
||||||
|
return JSXMap(x, f);
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ export type PsString = {
|
||||||
} & {
|
} & {
|
||||||
e?: string;
|
e?: string;
|
||||||
};
|
};
|
||||||
|
export type PsJSX = { p: JSX.Element, f: JSX.Element };
|
||||||
|
|
||||||
export type DictionaryInfo = {
|
export type DictionaryInfo = {
|
||||||
title: string;
|
title: string;
|
||||||
|
|
Loading…
Reference in New Issue