From cdea37e02478cc79d52676f40fff0d6337e6b489 Mon Sep 17 00:00:00 2001 From: lingdocs <71590811+lingdocs@users.noreply.github.com> Date: Thu, 24 Jun 2021 12:22:19 +0400 Subject: [PATCH] =?UTF-8?q?allow=20for=20JSX=20in=20Pashto=20text!!=20?= =?UTF-8?q?=F0=9F=92=AA=C2=9F=C2=99=C2=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/App.tsx | 16 ++++---- src/components/InlinePs.tsx | 4 +- src/components/Pashto.tsx | 23 ++++++++--- src/components/Phonetics.tsx | 21 +++++++--- src/lib/jsx-map.test.tsx | 26 ++++++++++++ src/lib/jsx-map.tsx | 79 ++++++++++++++++++++++++++++++++++++ src/types.ts | 1 + 8 files changed, 149 insertions(+), 23 deletions(-) create mode 100644 src/lib/jsx-map.test.tsx create mode 100644 src/lib/jsx-map.tsx diff --git a/package.json b/package.json index cda432b..28f6769 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lingdocs/pashto-inflector", - "version": "0.4.4", + "version": "0.4.5", "author": "lingdocs.com", "description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations", "homepage": "https://verbs.lingdocs.com", diff --git a/src/App.tsx b/src/App.tsx index bbe7969..f74a536 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,7 @@ import ConjugationViewer from "./components/ConjugationViewer"; import verbs from "./verbs"; import Pashto from "./components/Pashto"; import Phonetics from "./components/Phonetics"; +import InlinePs from "./components/InlinePs"; import { conjugateVerb } from "./lib/verb-conjugation"; import { getVerbInfo } from "./lib/verb-info"; import ButtonSelect from "./components/ButtonSelect"; @@ -25,7 +26,6 @@ import { } from "react-bootstrap"; import * as T from "./types"; import defualtTextOptions from "./lib/default-text-options"; -import InlinePs from "./components/InlinePs"; type VerbType = "simple" | "stative compound" | "dynamic compound"; const verbTypes: VerbType[] = [ @@ -181,14 +181,12 @@ function App() { const conjugation = v ? conjugateVerb(v.verb.entry, aayTailType, v.verb.complement) : undefined; - if (v) { - console.log("Verb chosen:"); - console.log(v.verb); - console.log("Conjugation of verb:") - console.log(conjugation); - } - console.log(verbTypeShowing); - console.log(textOptions); + // if (v) { + // console.log("Verb chosen:"); + // console.log(v.verb); + // console.log("Conjugation of verb:") + // console.log(conjugation); + // } return <>
diff --git a/src/components/InlinePs.tsx b/src/components/InlinePs.tsx index 154fa0a..3b647cd 100644 --- a/src/components/InlinePs.tsx +++ b/src/components/InlinePs.tsx @@ -15,8 +15,8 @@ function InlinePs ({ ps, opts, }: { - ps?: T.PsString, - children: T.PsString, + ps?: T.PsString | (T.PsJSX & { e?: string }), + children: T.PsString | (T.PsJSX & { e?: string }), opts: T.TextOptions, }) { const text = children || ps; diff --git a/src/components/Pashto.tsx b/src/components/Pashto.tsx index 7776393..7bad88a 100644 --- a/src/components/Pashto.tsx +++ b/src/components/Pashto.tsx @@ -12,21 +12,34 @@ import { import { phoneticsToDiacritics } from "../lib/phonetics-to-diacritics"; +import { psJSXMap } from "../lib/jsx-map"; import * as T from "../types"; const Pashto = ({ opts, children: text }: { opts: T.TextOptions, - children: T.PsString, + children: T.PsString | T.PsJSX, }) => { - const p = opts.diacritics - ? (phoneticsToDiacritics(text.p, text.f) || text.p) - : text.p; + function convertText(ps: T.PsString, opts: T.TextOptions): string { + const p = opts.diacritics + ? (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" ? undefined : { fontSize: opts.pTextSize === "larger" ? "large" : "larger" }; return ( - {opts.spelling === "Afghan" ? p : convertAfToPkSpelling(p)} + {convertText(text as T.PsString, opts)} ); }; diff --git a/src/components/Phonetics.tsx b/src/components/Phonetics.tsx index 4bc3c3e..b6577d2 100644 --- a/src/components/Phonetics.tsx +++ b/src/components/Phonetics.tsx @@ -9,22 +9,31 @@ import { translatePhonetics, } from "../lib/translate-phonetics"; +import { psJSXMap } from "../lib/jsx-map"; import * as T from "../types"; const Phonetics = ({ opts, children: text }: { opts: T.TextOptions, - children: T.PsString, + children: T.PsJSX | T.PsString | string, }) => { if (opts.phonetics === "none") { return null; } - return - {opts.phonetics === "lingdocs" - ? text.f - : translatePhonetics(text.f, { + const handleText = (f: string) => ( + opts.phonetics === "lingdocs" + ? f + : translatePhonetics(f, { dialect: opts.dialect, + // @ts-ignore - weird TS not picking up the elimination of "none herre" 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 + {handleText(f)} }; diff --git a/src/lib/jsx-map.test.tsx b/src/lib/jsx-map.test.tsx new file mode 100644 index 0000000..72d5d77 --- /dev/null +++ b/src/lib/jsx-map.test.tsx @@ -0,0 +1,26 @@ +import { psJSXMap, JSXMap } from "./jsx-map"; + +test("psJSXMap should work with f as a target", () => { + const input = { p: <>زه کور ته ځم, f: <>zu kor ta dzum }; + const output = psJSXMap(input, "p", (ps) => ps.p.replace(/ځ/g, "ز")); + expect(output).toEqual(<>زه کور ته زم); +}); + +test("psJSXMap should work with f as a target", () => { + const input = { p: <>زه کور ته ځم, f: <>zu kor ta dzum }; + const output = psJSXMap(input, "f", (ps) => ps.f.replace(/dz/g, "z")); + expect(output).toEqual(<>zu kor ta zum); +}); + +test("psJSXMap will error if given an uneven/unbalanced pair of JSX Elements", () => { + expect(() => { + const input = { p: <>زه کور ته ځم, 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 will be transformed nicely; + const output = JSXMap(input, (s) => s.toUpperCase()); + expect(output).toEqual(<>THIS WILL BE TRANSFORMED NICELY); +}); \ No newline at end of file diff --git a/src/lib/jsx-map.tsx b/src/lib/jsx-map.tsx new file mode 100644 index 0000000..f05e406 --- /dev/null +++ b/src/lib/jsx-map.tsx @@ -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: <>زه ځم, f : <>zu dzum } + * + * @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); + }), + }, + }; +} \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index 3f97b2e..d4e7232 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,6 +12,7 @@ export type PsString = { } & { e?: string; }; +export type PsJSX = { p: JSX.Element, f: JSX.Element }; export type DictionaryInfo = { title: string;