diff --git a/.eslintrc.js b/.eslintrc.js index 6c60578..6f1b1dc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -11,9 +11,6 @@ module.exports = { plugins: [ '@typescript-eslint', ], - extends: [ - 'plugin:@next/next/recommended', - ], ignorePatterns: '*.js', overrides: [ { diff --git a/.github/workflows/publish-next.yaml b/.github/workflows/publish-next.yaml index 5d0c19c..9113337 100644 --- a/.github/workflows/publish-next.yaml +++ b/.github/workflows/publish-next.yaml @@ -64,7 +64,7 @@ jobs: always-auth: true cache: yarn - - run: yarn workspace $PACKAGE_NAME install --frozen-lockfile + - run: yarn workspace $PACKAGE_NAME install --immutable - name: publish abjad-convert @next to npm if: ${{ env.PACKAGE_NAME == 'abjad-convert' }} diff --git a/README.md b/README.md index 95497ab..912bfea 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,6 @@ This is a monorepo for the Abjad Convert project. ### Abjad Client example of a client for the abjad convert package + +### Abjad Web +[README](https://github.com/amerharb/abjad/blob/main/packages/abjad-web/README.md) diff --git a/packages/abjad-convert/CHANGELOG.md b/packages/abjad-convert/CHANGELOG.md index 3ee5e12..b03ffd1 100644 --- a/packages/abjad-convert/CHANGELOG.md +++ b/packages/abjad-convert/CHANGELOG.md @@ -2,6 +2,8 @@ ## [0.3.0] 2024-01-17 +### Added +- return array of letters of a script ## [0.2.1] 2024-01-13 ### Fixed diff --git a/packages/abjad-convert/CONTRIBUTING.md b/packages/abjad-convert/CONTRIBUTING.md new file mode 100644 index 0000000..fc73c54 --- /dev/null +++ b/packages/abjad-convert/CONTRIBUTING.md @@ -0,0 +1,118 @@ +# Abjad-convert Contributing + +## Adding new script +Pull requests are welcome. For adding new script. let's say that we want to add a new script "Foo" +- Step #1: create a feature branch from `main` named `abjad-convert/version/0.[x].0` where `x` is the next minor of current version number. +- Step #2: create a new branch that will the previous feature branch when creating the PR. +- Step #3: create a new folder named `foo` in `src`. +- Step #4: add pdf documentation for the script we want to add from www.unicode.org. for example for Ugaritic the file is `U10380.pdf`. this file will be used as a reference +- Step #5: add a new file named `letters.ts` in `foo` folder this file will export +- - `letters` an array of letters written using unicode values with jsdoc each line will contain + the value of the letter using UTF-16 BE using escape \u followed by 4 hex digits. + notice that UTF16BE value is not always the same as the unicode value. + for example for letter Alpa in Ugaritic the unicode value is `0x10380` but the UTF16BE encode value is `0xD800DF80` + follow the value with jsdoc that contain array index, letter itself, unicode value, and the name of the letter. + for example for ugaritic looks like this: + +```ts +const letters = [ + '\uD800\uDF80', /** #0 𐎀 U+10380 UGARITIC LETTER ALPA */ + '\uD800\uDF81', /** #1 𐎁 U+10381 UGARITIC LETTER BETA */ + //... +]; +``` + +- - 'Fo' an alias object called `Fo` short of Foo. this will give an alias for all letters mentioned in the letters array. + +for example for ugaritic looks like this: +```ts +const Ug = { + Alpa: letters[0], // 𐎀 + Beta: letters[1], // 𐎁 + //... +}; +``` + +- - `foo` an instance of `Script` class, which will be exported + +for example for ugaritic looks like this: +```ts +export const ugaritic = new Script( + Abjad.Ugaritic, // enum value of the script + false, // true if the script is right to left + letters, // array of letters + Ug, // alias object of letters +) +``` + +- Step #6: Add the script to the enum `Abjad` in `src/types.ts` file. + at this point we have finished adding the script, but it is an island script. Meaning that it can't be converted to or from any other script. + +- Step #7: To make it convertable we need at least to have one from and one to converter to another script. + the preferred way is to add a converter to and from Arabic script, as it is currently act as a de facto hub script for all abjad scripts. + The algorithm for converting will look first for 1-step converter (direct converter) the one that convert from the source to the target, in case there isn't any it will look for 2-steps approach where it can find a middle script, + after that it won't look for 3 or more steps, it will basically throw an error. + That is why Arabic is used as preferred hub, so if all script add converter to Arabic and Arabic add converter to all other scripts then all conversion is possible. + However, there is a plan in the future to add IPA to be a canonical hub script. + +- - Adding to Arabic: Add file to `foo` folder with name `toArabic.ts` that include a class called FooToArabicConverter that implements `IConverter` interface. + it should look like this: +```ts +import { IConverter } from '../../types'; +import { Fo } from './letters' +import { Ar } from '../arabic/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class FooToArabicConverter implements IConverter { + public readonly from = Abjad.Foo + public readonly to = Abjad.Arabic + public convert(fooText: string): string { + // convert logic here + // return (araic text) + } +} +``` +- - Add toArabic converter to `converterFactory.ts` +- - - import the new converter in alphabetical order +```ts +//... +import { FooToArabicConverter } from './foo/toArabic' +//... +``` +- - - add the converter to converters array in alphabetical order +```ts +const converters: IConverter[] = [ + //... + new TifinaghToArabicConverter(), + //... +]; +``` +- - Add toFoo converter to `arabic` folder with name `toFoo.ts` that include a class called ArabicToFooConverter that implements `IConverter` interface. + it should look like this: +```ts +import {Ar} from './letters' +import {Fo} from '../foo/letters' +import {IConverter} from '../../IConverter' +import {Abjad} from '../../types' + +export class ArabicToFooConverter implements IConverter { + public readonly from = Abjad.Arabic + public readonly to = Abjad.Foo + public convert(arabicText: string): string { + // convert logic here + // return (foo text) + } +} +``` +- - Add toFoo converter to `converterFactory.ts` + +- Step #8 add unit test to`test/index.test.ts`. + +- Step #9: update for new version +- - update `CHANGELOG.md` with the new version number and the changes. +- Step #10 update +- - `README.md` links and badges. +- - version in `package.json` file. +- - run yarn to update `yarn.lock` files +- - run test to update coverage badges diff --git a/packages/abjad-convert/README.md b/packages/abjad-convert/README.md index ba8f46b..cfaf473 100644 --- a/packages/abjad-convert/README.md +++ b/packages/abjad-convert/README.md @@ -1,8 +1,8 @@ # Abjad Convert -[![Version](https://img.shields.io/badge/version-0.2.1-blue.svg)](https://github.com/amerharb/abjad/tree/version/0.2.1) +[![Version](https://img.shields.io/badge/version-0.3.0-blue.svg)](https://github.com/amerharb/abjad/tree/version/0.3.0) [![License: GPLv3](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC) -![Coverage](https://raw.githubusercontent.com/amerharb/abjad/abjad-convert/version/0.2.1/packages/abjad-convert/badges/coverage.svg) -![Github workflow](https://github.com/amerharb/abjad/actions/workflows/lint-test.yaml/badge.svg?branch=abjad-convert/version/0.2.1) +![Coverage](https://raw.githubusercontent.com/amerharb/abjad/abjad-convert/version/0.3.0/packages/abjad-convert/badges/coverage.svg) +![Github workflow](https://github.com/amerharb/abjad/actions/workflows/lint-test.yaml/badge.svg?branch=abjad-convert/version/0.3.0) **abjad-convert** is a package for converting Abjad alphabets phonetically. @@ -24,7 +24,7 @@ yarn: yarn add abjad-convert ``` -Java Script: +Type Script: ```js import { convert, Abjad } from 'abjad-convert'; @@ -45,106 +45,3 @@ console.log(tifinaghWord); // ⵎⵔⵃⴱⴰ const ugariticWord = convert(arabicWord, Abjad.Arabic, Abjad.Ugaritic); console.log(ugariticWord); // 𐎎𐎗𐎈𐎁𐎀 ``` -## Contributing -### Adding new script -Pull requests are welcome. For adding new script. let's say that we want to add a new script "Foo" -- Step #1: create a feature branch from `main` named `abjad-convert/version/0.[x].0` where `x` is the next minor of current version number. -- Step #2: create a new branch that will the previous feature branch when creating the PR. -- Step #3: create a new folder named `foo` in `src`. -- Step #4: add pdf documentation for the script we want to add from www.unicode.org. for example for Ugaritic the file is `U10380.pdf`. this file will be used as a reference -- Step #5: add a new file named `letters.ts` in `foo` folder this file will export -- - `letters` an array of letters written using unicode values with jsdoc each line will contain -the value of the letter using UTF-16 BE using escape \u followed by 4 hex digits. -notice that UTF16BE value is not always the same as the unicode value. -for example for letter Alpa in Ugaritic the unicode value is `0x10380` but the UTF16BE encode value is `0xD800DF80` -follow the value with jsdoc that contain array index, letter itself, unicode value, and the name of the letter. -for example for ugaritic looks like this: - -```ts -export const letters = [ - '\uD800\uDF80', /** #0 𐎀 U+10380 UGARITIC LETTER ALPA */ - '\uD800\uDF81', /** #1 𐎁 U+10381 UGARITIC LETTER BETA */ - //... -]; -``` -- - 'Fo' an alias object called `Fo` short of Foo. this will give an alias for all letters mentioned in the letters array. - -for example for ugaritic looks like this: -```ts -export const Ug = { - Alpa: letters[0], // 𐎀 - Beta: letters[1], // 𐎁 - //... -}; -``` - -- Step #6: Add the script to the enum `Abjad` in `src/types.ts` file. -at this point we have finished adding the script, but it is an island script. Meaning that it can't be converted to or from any other script. - -- Step #7: To make it convertable we need at least to have one from and one to converter to another script. -the preferred way is to add a converter to and from Arabic script, as it is currently act as a de facto hub script for all abjad scripts. -The algorithm for converting will look first for 1-step converter (direct converter) the one that convert from the source to the target, in case there isn't any it will look for 2-steps approach where it can find a middle script, -after that it won't look for 3 or more steps, it will basically throw an error. -That is why Arabic is used as preferred hub, so if all script add converter to Arabic and Arabic add converter to all other scripts then all conversion is possible. -However, there is a plan in the future to add IPA to be a canonical hub script. - -- - Adding to Arabic: Add file to `foo` folder with name `toArabic.ts` that include a class called FooToArabicConverter that implements `IConverter` interface. -it should look like this: -```ts -import { IConverter } from '../types'; -import { Fo } from './letters' -import { Ar } from '../arabic/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class FooToArabicConverter implements IConverter { - public readonly from = Abjad.Foo - public readonly to = Abjad.Arabic - public convert(fooText: string): string { - // convert logic here - // return (araic text) - } -} -``` -- - Add toArabic converter to `converterFactory.ts` -- - - import the new converter in alphabetical order -```ts -//... -import { FooToArabicConverter } from './foo/toArabic' -//... -``` -- - - add the converter to converters array in alphabetical order -```ts -const converters: IConverter[] = [ - //... - new TifinaghToArabicConverter(), - //... -]; -``` -- - Add toFoo converter to `arabic` folder with name `toFoo.ts` that include a class called ArabicToFooConverter that implements `IConverter` interface. -it should look like this: -```ts -import {Ar} from './letters' -import {Fo} from '../foo/letters' -import {IConverter} from '../IConverter' -import {Abjad} from '../types' - -export class ArabicToFooConverter implements IConverter { - public readonly from = Abjad.Arabic - public readonly to = Abjad.Foo - public convert(arabicText: string): string { - // convert logic here - // return (foo text) - } -} -``` -- - Add toFoo converter to `converterFactory.ts` - -- Step #8 add unit test to`test/index.test.ts`. - -- Step #9: update for new version -- - update `CHANGELOG.md` with the new version number and the changes. -- - Step #10 update `README.md` links and badges. -- - Update version in `package.json` file. -- - run yarn to update yarn.lock files -- - run test to update coverage badges diff --git a/packages/abjad-convert/badges/coverage.svg b/packages/abjad-convert/badges/coverage.svg index 9ea328b..d05e638 100644 --- a/packages/abjad-convert/badges/coverage.svg +++ b/packages/abjad-convert/badges/coverage.svg @@ -1 +1 @@ -Coverage: 99.46%CoverageCoverage99.46%99.46% \ No newline at end of file +Coverage: 99.47%CoverageCoverage99.47%99.47% \ No newline at end of file diff --git a/packages/abjad-convert/package.json b/packages/abjad-convert/package.json index 891f5ef..d4cd7bd 100644 --- a/packages/abjad-convert/package.json +++ b/packages/abjad-convert/package.json @@ -1,6 +1,6 @@ { "name": "abjad-convert", - "version": "0.3.0", + "version": "0.3.0-next.1", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", "files": [ diff --git a/packages/abjad-convert/src/arabic/toImperialAramaic.ts b/packages/abjad-convert/src/arabic/toImperialAramaic.ts deleted file mode 100644 index 4ed618e..0000000 --- a/packages/abjad-convert/src/arabic/toImperialAramaic.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Ar } from './letters' -import { Ia } from '../imperialAramaic/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class ArabicToImperialAramaicConverter implements IConverter { - public readonly from = Abjad.Arabic - public readonly to = Abjad.ImperialAramaic - - private map = new Map( - [ - [' ', ' '], - [Ar.Hamza, ''], - [Ar.AlefMadda, Ia.Aleph], - [Ar.AlefHamza, Ia.Aleph], - [Ar.WawHamza, Ia.Waw], - [Ar.AlefHamzaMaksura, Ia.Yod], - [Ar.Alef, Ia.Aleph], - [Ar.Ba, Ia.Bet], - [Ar.TaMarbuta, Ia.Taw], - [Ar.Ta, Ia.Taw], - [Ar.Tha, Ia.Taw], - [Ar.Jeem, Ia.Gimel], - [Ar.H7aa, Ia.Heth], - [Ar.Khaa, Ia.Heth], - [Ar.Dal, Ia.Daleth], - [Ar.Thal, Ia.Daleth], - [Ar.Ra, Ia.Resh], - [Ar.Zay, Ia.Zayin], - [Ar.Seen, Ia.Samekh], - [Ar.Sheen, Ia.Shin], - [Ar.Sad, Ia.Sadhe], - [Ar.Dad, Ia.Daleth], - [Ar.TTa, Ia.Teth], - [Ar.THa, Ia.Taw], - [Ar.Ayn, Ia.Ayin], - [Ar.Ghayn, Ia.Ayin], - [Ar.Fa, Ia.Pe], - [Ar.Qaf, Ia.Qoph], - [Ar.Kaf, Ia.Kaph], - [Ar.Lam, Ia.Lamedh], - [Ar.Meem, Ia.Mem], - [Ar.Noon, Ia.Nun], - [Ar.Ha, Ia.He], - [Ar.Waw, Ia.Waw], - [Ar.Yaa, Ia.Yod], - [Ar.AlefMaksura, Ia.Aleph], - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - const u = this.map.get(letter) ?? '' - result += u - } - return result - } -} diff --git a/packages/abjad-convert/src/arabic/toPhoenician.ts b/packages/abjad-convert/src/arabic/toPhoenician.ts deleted file mode 100644 index 89b585d..0000000 --- a/packages/abjad-convert/src/arabic/toPhoenician.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Ar } from './letters' -import { Ph } from '../phoenician/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class ArabicToPhoenicianConverter implements IConverter { - public readonly from = Abjad.Arabic - public readonly to = Abjad.Phoenician - - private map = new Map( - [ - [' ', Ph.WordSeparator], - [Ar.Hamza, ''], - [Ar.AlefMadda, Ph.Alep], // 𐤀 <- آ - [Ar.AlefHamza, Ph.Alep], // 𐤀 <- ا - [Ar.WawHamza, Ph.Waw], // 𐤅 <- ؤ - [Ar.AlefHamzaMaksura, Ph.Alep], // 𐤀 <- ى - [Ar.Alef, Ph.Alep], // 𐤀 <- ا - [Ar.Ba, Ph.Bet], // 𐤁 <- ب - [Ar.TaMarbuta, Ph.Tau], // 𐤕 <- ة - [Ar.Ta, Ph.Tau], // 𐤕 <- ت - [Ar.Tha, Ph.Tau], // 𐤕 <- ث - [Ar.Jeem, Ph.Gimi], // 𐤂 <- ج - [Ar.H7aa, Ph.Het], // 𐤇 <- ح - [Ar.Khaa, Ph.Het], // 𐤇 <- خ - [Ar.Dal, Ph.Dalet], // 𐤃 <- د - [Ar.Thal, Ph.Dalet], // 𐤃 <- ذ - [Ar.Ra, Ph.Ros], // 𐤓 <- ر - [Ar.Zay, Ph.Zayin], // 𐤆 <- ز - [Ar.Seen, Ph.Semk], // 𐤎 <- س - [Ar.Sheen, Ph.Shin], // 𐤔 <- ش - [Ar.Sad, Ph.Sade], // 𐤑 <- ص - [Ar.Dad, Ph.Dalet], // 𐤃 <- ض - [Ar.TTa, Ph.Tet], // 𐤈 <- ط - [Ar.THa, Ph.Tau], // 𐤕 <- ظ - [Ar.Ayn, Ph.Ain], // 𐤏 <- ع - [Ar.Ghayn, Ph.Ain], // 𐤏 <- غ - [Ar.Fa, Ph.Pe], // 𐤐 <- ف - [Ar.Qaf, Ph.Qof], // 𐤒 <- ق - [Ar.Kaf, Ph.Kap], // 𐤊 <- ك - [Ar.Lam, Ph.Lam], // 𐤋 < - ل - [Ar.Meem, Ph.Mem], // 𐤌 <- م - [Ar.Noon, Ph.Nun], // 𐤍 <- ن - [Ar.Ha, Ph.He], // 𐤄 <- ه - [Ar.Waw, Ph.Waw], // 𐤅 <- و - [Ar.Yaa, Ph.Yod], // 𐤉 <- ي - [Ar.AlefMaksura, Ph.Alep], // 𐤀 <- ى - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - const u = this.map.get(letter) ?? '' - result += u - } - return result - } -} diff --git a/packages/abjad-convert/src/arabic/toSyriac.ts b/packages/abjad-convert/src/arabic/toSyriac.ts deleted file mode 100644 index 2fbaf7d..0000000 --- a/packages/abjad-convert/src/arabic/toSyriac.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Ar } from './letters' -import { Sy } from '../syriac/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class ArabicToSyriacConverter implements IConverter { - public readonly from = Abjad.Arabic - public readonly to = Abjad.Syriac - - private map = new Map( - [ - [' ', ' '], - [Ar.Hamza, Sy.SuperaAlaph], // ء -> ܐ TODO: check - [Ar.AlefMadda, Sy.Alaph], // آ -> ܐ - [Ar.AlefHamza, Sy.Alaph], // أ -> ܐ - [Ar.WawHamza, Sy.Waw], // ؤ -> ܘ - [Ar.AlefHamzaMaksura, Sy.YudhHe], // ى -> ܞ - [Ar.Alef, Sy.Alaph], // ا -> ܐ - [Ar.Ba, Sy.Beth], // ب -> ܒ - [Ar.TaMarbuta, Sy.Taw], // ة -> ܬ - [Ar.Ta, Sy.Taw], // ت -> ܬ - [Ar.Tha, Sy.Taw], // ث -> ܬ - [Ar.Jeem, Sy.Gamal], // ج -> ܓ - [Ar.H7aa, Sy.Heth], // ح -> ܚ - [Ar.Khaa, Sy.Heth], // خ -> ܚ - [Ar.Dal, Sy.Dalath], // د -> ܕ - [Ar.Thal, Sy.Dalath], // ذ -> ܕ - [Ar.Ra, Sy.Rish], // ر -> ܪ - [Ar.Zay, Sy.Zain], // ز -> ܙ - [Ar.Seen, Sy.Semkath], // س -> ܣ - [Ar.Sheen, Sy.Shin], // ش -> ܫ - [Ar.Sad, Sy.Sadhe], // ص -> ܨ - [Ar.Dad, Sy.Dalath], // ض -> ܕ - [Ar.TTa, Sy.Teth], // ط -> ܛ - [Ar.THa, Sy.Taw], // ظ -> ܬ - [Ar.Ayn, Sy.E], // ع -> ܥ - [Ar.Ghayn, Sy.E], // غ -> ܥ - [Ar.Fa, Sy.Pe], // ف -> ܦ - [Ar.Qaf, Sy.Qaph], // ق -> ܩ - [Ar.Kaf, Sy.Kaph], // ك -> ܟ - [Ar.Lam, Sy.Lamadh], // ل -> ܠ - [Ar.Meem, Sy.Mim], // م -> ܡ - [Ar.Noon, Sy.Nun], // ن -> ܢ - [Ar.Ha, Sy.He], // ه -> ܗ - [Ar.Waw, Sy.Waw], // و -> ܘ - [Ar.Yaa, Sy.Yudh], // ي -> ܝ - [Ar.AlefMaksura, Sy.Alaph], // ى -> ܐ - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - const u = this.map.get(letter) ?? '' - result += u - } - return result - } -} diff --git a/packages/abjad-convert/src/arabic/toTifinagh.ts b/packages/abjad-convert/src/arabic/toTifinagh.ts deleted file mode 100644 index 1edd934..0000000 --- a/packages/abjad-convert/src/arabic/toTifinagh.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Ar } from './letters' -import { Ti } from '../tifinagh/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class ArabicToTifinaghConverter implements IConverter { - public readonly from = Abjad.Arabic - public readonly to = Abjad.Tifinagh - - private map = new Map( - [ - [' ', ' '], - [Ar.Hamza, Ti.Ya], /** ء -> ⴰ */ - [Ar.AlefMadda, Ti.Ya], /** ا -> ⴰ */ - [Ar.AlefHamza, Ti.Ya], /** أ -> ⴰ*/ - [Ar.WawHamza, Ti.Yu], /** ؤ -> ⵓ */ - [Ar.AlefHamzaMaksura, Ti.Ya], /** ى -> ⴰ */ - [Ar.Alef, Ti.Ya], /** ا -> ⴰ */ - [Ar.Ba, Ti.Yab], /** ب -> ⴱ */ - [Ar.TaMarbuta, Ti.Ya], /** ة -> ⴰ */ - [Ar.Ta, Ti.Yat], /** ت -> ⵜ */ - [Ar.Tha, Ti.Yath], /** ث -> ⵝ */ - [Ar.Jeem, Ti.Yazh], /** ج -> ⵊ */ - [Ar.H7aa, Ti.Yahh], /** ح -> ⵃ */ - [Ar.Khaa, Ti.Yakh], /** خ -> ⵅ */ - [Ar.Dal, Ti.Yad], /** د -> ⴷ */ - [Ar.Thal, Ti.Yadh], /** ذ -> ⴸ */ - [Ar.Ra, Ti.Yar], /** ر -> ⵔ */ - [Ar.Zay, Ti.Ya], /** ز -> ⴰ */ - [Ar.Seen, Ti.Yas], /** س -> ⵙ */ - [Ar.Sheen, Ti.Yash], /** ش -> ⵛ */ - [Ar.Sad, Ti.Yat], /** ص -> ⵜ */ - [Ar.Dad, Ti.Yadd], /** ض -> ⴹ */ - [Ar.TTa, Ti.Yatt], /** ط -> ⵟ */ - [Ar.THa, Ti.Yaddh], /** ظ -> ⴺ */ - [Ar.Ayn, Ti.Yaa], /** ع -> ⵄ */ - [Ar.Ghayn, Ti.Yagh], /** غ -> ⵖ */ - [Ar.Fa, Ti.Yaf], /** ف -> ⴼ */ - [Ar.Qaf, Ti.Yaq], /** ق -> ⵇ */ - [Ar.Kaf, Ti.Yak], /** ك -> ⴽ */ - [Ar.Lam, Ti.Yal], /** ل -> ⵍ */ - [Ar.Meem, Ti.Yam], /** م -> ⵎ */ - [Ar.Noon, Ti.Yan], /** ن -> ⵏ */ - [Ar.Ha, Ti.Yey], /** ه -> ⴻ */ - [Ar.Waw, Ti.Yu], /** و -> ⵓ */ - [Ar.AlefMaksura, Ti.Ya], /** ى -> ⴰ */ - [Ar.Yaa, Ti.Yi], /** ي -> ⵉ */ - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - const u = this.map.get(letter) ?? '' - result += u - } - return result - } -} diff --git a/packages/abjad-convert/src/arabic/toUgaritic.ts b/packages/abjad-convert/src/arabic/toUgaritic.ts deleted file mode 100644 index 265fbbc..0000000 --- a/packages/abjad-convert/src/arabic/toUgaritic.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Ar } from './letters' -import { Ug } from '../ugaritic/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class ArabicToUgariticConverter implements IConverter { - public readonly from = Abjad.Arabic - public readonly to = Abjad.Ugaritic - private map = new Map( - [ - [' ', ' '], - [Ar.Hamza, ''], - [Ar.AlefMadda, Ug.Alpa], - [Ar.AlefHamza, Ug.Alpa], - [Ar.WawHamza, Ug.Alpa], - [Ar.AlefHamzaMaksura, Ug.Alpa], - [Ar.Alef, Ug.Alpa], - [Ar.Ba, Ug.Beta], - [Ar.TaMarbuta, Ug.To], - [Ar.Ta, Ug.To], - [Ar.Tha, Ug.Thanna], - [Ar.Jeem, Ug.Gamla], - [Ar.H7aa, Ug.Hota], - [Ar.Khaa, Ug.Kha], - [Ar.Dal, Ug.Delta], - [Ar.Thal, Ug.Delta], - [Ar.Ra, Ug.Rasha], - [Ar.Zay, Ug.Zu], - [Ar.Seen, Ug.Samka], - [Ar.Sheen, Ug.Shin], - [Ar.Sad, Ug.Sade], - [Ar.Dad, Ug.Dhal], - [Ar.TTa, Ug.Tet], - [Ar.THa, Ug.Thanna], - [Ar.Ayn, Ug.Ain], - [Ar.Ghayn, Ug.Ghain], - [Ar.Fa, Ug.Pu], - [Ar.Qaf, Ug.Qopa], - [Ar.Kaf, Ug.Kaf], - [Ar.Lam, Ug.Lamda], - [Ar.Meem, Ug.Mem], - [Ar.Noon, Ug.Nun], - [Ar.Ha, Ug.Ho], - [Ar.Waw, Ug.Wo], - [Ar.Yaa, Ug.Yod], - [Ar.AlefMaksura, Ug.Alpa], - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - const u = this.map.get(letter) ?? '' - result += u - } - return result - } -} diff --git a/packages/abjad-convert/src/converterFactory.ts b/packages/abjad-convert/src/converterFactory.ts index 0207dfe..facb8ae 100644 --- a/packages/abjad-convert/src/converterFactory.ts +++ b/packages/abjad-convert/src/converterFactory.ts @@ -1,15 +1,15 @@ import { Abjad } from './types' import { IConverter } from './IConverter' -import { ArabicToImperialAramaicConverter } from './arabic/toImperialAramaic' -import { ArabicToPhoenicianConverter } from './arabic/toPhoenician' -import { ArabicToSyriacConverter } from './arabic/toSyriac' -import { ArabicToTifinaghConverter } from './arabic/toTifinagh' -import { ArabicToUgariticConverter } from './arabic/toUgaritic' -import { ImperialAramaicToArabicConverter } from './imperialAramaic/toArabic' -import { PhoenicianToArabicConverter } from './phoenician/toArabic' -import { SyriacToArabicConverter } from './syriac/toArabic' -import { TifinaghToArabicConverter } from './tifinagh/toArabic' -import { UgariticToArabicConverter } from './ugaritic/toArabic' +import { ArabicToImperialAramaicConverter } from './scripts/arabic/toImperialAramaic' +import { ArabicToPhoenicianConverter } from './scripts/arabic/toPhoenician' +import { ArabicToSyriacConverter } from './scripts/arabic/toSyriac' +import { ArabicToTifinaghConverter } from './scripts/arabic/toTifinagh' +import { ArabicToUgariticConverter } from './scripts/arabic/toUgaritic' +import { ImperialAramaicToArabicConverter } from './scripts/imperialAramaic/toArabic' +import { PhoenicianToArabicConverter } from './scripts/phoenician/toArabic' +import { SyriacToArabicConverter } from './scripts/syriac/toArabic' +import { TifinaghToArabicConverter } from './scripts/tifinagh/toArabic' +import { UgariticToArabicConverter } from './scripts/ugaritic/toArabic' const converters: IConverter[] = [ new ArabicToImperialAramaicConverter(), diff --git a/packages/abjad-convert/src/imperialAramaic/toArabic.ts b/packages/abjad-convert/src/imperialAramaic/toArabic.ts deleted file mode 100644 index d82c24f..0000000 --- a/packages/abjad-convert/src/imperialAramaic/toArabic.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Ia } from './letters' -import { Ar } from '../arabic/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class ImperialAramaicToArabicConverter implements IConverter { - public readonly from = Abjad.ImperialAramaic - public readonly to = Abjad.Arabic - - private map = new Map( - [ - [' ', ' '], - [Ia.Aleph, Ar.Alef], // 𐡀 -> ا - [Ia.Bet, Ar.Ba], // 𐡁 -> ب - [Ia.Gimel, Ar.Jeem], // 𐡂 -> ج - [Ia.Daleth, Ar.Dal], // 𐡃 -> د - [Ia.He, Ar.Ha], // 𐡄 -> ه - [Ia.Waw, Ar.Waw], // 𐡅 -> و - [Ia.Zayin, Ar.Zay], // 𐡆 -> ز - [Ia.Heth, Ar.Ha], // 𐡇 -> ح - [Ia.Teth, Ar.Ta], // 𐡈 -> ط - [Ia.Yod, Ar.Yaa], // 𐡉 -> ي - [Ia.Kaph, Ar.Kaf], // 𐡊 -> ك - [Ia.Lamedh, Ar.Lam], // 𐡋 -> ل - [Ia.Mem, Ar.Meem], // 𐡌 -> م - [Ia.Nun, Ar.Noon], // 𐡍 -> ن - [Ia.Samekh, Ar.Seen], // 𐡎 -> س - [Ia.Ayin, Ar.Ayn], // 𐡏 -> ع - [Ia.Pe, Ar.Fa], // 𐡐 -> ف - [Ia.Sadhe, Ar.Sad], // 𐡑 -> ص - [Ia.Qoph, Ar.Qaf], // 𐡒 -> ق - [Ia.Resh, Ar.Ra], // 𐡓 -> ر - [Ia.Shin, Ar.Sheen], // 𐡔 -> ش - [Ia.Taw, Ar.Ta], // 𐡕 -> ت - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - result += this.map.get(letter) ?? '' - } - return result - } -} diff --git a/packages/abjad-convert/src/index.ts b/packages/abjad-convert/src/index.ts index 8e79319..e3ad6cb 100644 --- a/packages/abjad-convert/src/index.ts +++ b/packages/abjad-convert/src/index.ts @@ -1,5 +1,13 @@ import { getConverter } from './converterFactory' import { Abjad } from './types' +import { arabic } from './scripts/arabic/letters' +import { imperialAramaic } from './scripts/imperialAramaic/letters' +import { phoenician } from './scripts/phoenician/letters' +import { syriac } from './scripts/syriac/letters' +import { tifinagh } from './scripts/tifinagh/letters' +import { ugaritic } from './scripts/ugaritic/letters' + +export { Abjad } from './types' export function convert(source: string, from: Abjad, to: Abjad): string { if (from === to) { @@ -9,4 +17,21 @@ export function convert(source: string, from: Abjad, to: Abjad): string { return converter.convert(source) } -export { Abjad } from './types' +export function getLetters(script: Abjad): readonly string[] { + switch (script) { + case Abjad.Arabic: + return arabic.letters + case Abjad.ImperialAramaic: + return imperialAramaic.letters + case Abjad.Phoenician: + return phoenician.letters + case Abjad.Syriac: + return syriac.letters + case Abjad.Tifinagh: + return tifinagh.letters + case Abjad.Ugaritic: + return ugaritic.letters + default: + return [] + } +} diff --git a/packages/abjad-convert/src/phoenician/toArabic.ts b/packages/abjad-convert/src/phoenician/toArabic.ts deleted file mode 100644 index ac3d9d9..0000000 --- a/packages/abjad-convert/src/phoenician/toArabic.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Ph } from './letters' -import { Ar } from '../arabic/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class PhoenicianToArabicConverter implements IConverter { - public readonly from = Abjad.Phoenician - public readonly to = Abjad.Arabic - - private map = new Map( - [ - [' ', ' '], - [Ph.WordSeparator, ' '], - [Ph.Alep, Ar.Alef], // 𐤀 -> ا - [Ph.Bet, Ar.Ba], // 𐤁 -> ب - [Ph.Gimi, Ar.Jeem], // 𐤂 -> ج - [Ph.Dalet, Ar.Dal], // 𐤃 -> د - [Ph.He, Ar.Ha], // 𐤄 -> ه - [Ph.Waw, Ar.Waw], // 𐤅 -> و - [Ph.Zayin, Ar.Zay], // 𐤆 -> ز - [Ph.Het, Ar.H7aa], // 𐤇 -> ح - [Ph.Tet, Ar.TTa], // 𐤈 -> ط - [Ph.Yod, Ar.Yaa], // 𐤉 -> ي - [Ph.Kap, Ar.Kaf], // 𐤊 -> ك - [Ph.Lam, Ar.Lam], // 𐤋 -> ل - [Ph.Mem, Ar.Meem], // 𐤌 -> م - [Ph.Nun, Ar.Noon], // 𐤍 -> ن - [Ph.Semk, Ar.Seen], // 𐤎 -> س - [Ph.Ain, Ar.Ayn], // 𐤏 -> ع - [Ph.Pe, Ar.Fa], // 𐤐 -> ف - [Ph.Sade, Ar.Sad], // 𐤑 -> ض - [Ph.Qof, Ar.Qaf], // 𐤒 -> ق - [Ph.Ros, Ar.Ra], // 𐤓 -> ر - [Ph.Shin, Ar.Sheen], // 𐤔 -> ش - [Ph.Tau, Ar.Ta], // 𐤕 -> ث - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - result += this.map.get(letter) ?? '' - } - return result - } -} diff --git a/packages/abjad-convert/src/scripts/Script.ts b/packages/abjad-convert/src/scripts/Script.ts new file mode 100644 index 0000000..e15e874 --- /dev/null +++ b/packages/abjad-convert/src/scripts/Script.ts @@ -0,0 +1,10 @@ +import { Abjad } from '../types' + +export class Script { + constructor( + public readonly abjad: Abjad, + public readonly rtl: boolean, + public readonly letters: readonly string[], + public readonly L: Record + ) {} +} diff --git a/packages/abjad-convert/src/arabic/U0600.pdf b/packages/abjad-convert/src/scripts/arabic/U0600.pdf similarity index 100% rename from packages/abjad-convert/src/arabic/U0600.pdf rename to packages/abjad-convert/src/scripts/arabic/U0600.pdf diff --git a/packages/abjad-convert/src/arabic/letters.ts b/packages/abjad-convert/src/scripts/arabic/letters.ts similarity index 90% rename from packages/abjad-convert/src/arabic/letters.ts rename to packages/abjad-convert/src/scripts/arabic/letters.ts index b769e5c..d419e23 100644 --- a/packages/abjad-convert/src/arabic/letters.ts +++ b/packages/abjad-convert/src/scripts/arabic/letters.ts @@ -1,4 +1,7 @@ -export const letters = [ +import { Script } from '../Script' +import { Abjad } from '../../types' + +const letters = [ '\u0621', /** #0 ء */ '\u0622', /** #1 آ */ '\u0623', /** #2 أ */ @@ -34,9 +37,9 @@ export const letters = [ '\u0648', /** #32 و */ '\u0649', /** #33 ى */ '\u064A', /** #34 ي */ -] +] as const -export const Ar = { +const Ar = { Hamza: letters[0], // ء AlefMadda: letters[1], // آ AlefHamza: letters[2], // أ @@ -73,3 +76,10 @@ export const Ar = { AlefMaksura: letters[33], // ى Yaa: letters[34], // ي } + +export const arabic = new Script( + Abjad.Arabic, + true, + letters, + Ar, +) diff --git a/packages/abjad-convert/src/scripts/arabic/toImperialAramaic.ts b/packages/abjad-convert/src/scripts/arabic/toImperialAramaic.ts new file mode 100644 index 0000000..5b3a43c --- /dev/null +++ b/packages/abjad-convert/src/scripts/arabic/toImperialAramaic.ts @@ -0,0 +1,59 @@ +import { arabic } from './letters' +import { imperialAramaic } from '../imperialAramaic/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class ArabicToImperialAramaicConverter implements IConverter { + public readonly from = Abjad.Arabic + public readonly to = Abjad.ImperialAramaic + + private map = new Map( + [ + [' ', ' '], + [arabic.L.Hamza, ''], + [arabic.L.AlefMadda, imperialAramaic.L.Aleph], + [arabic.L.AlefHamza, imperialAramaic.L.Aleph], + [arabic.L.WawHamza, imperialAramaic.L.Waw], + [arabic.L.AlefHamzaMaksura, imperialAramaic.L.Yod], + [arabic.L.Alef, imperialAramaic.L.Aleph], + [arabic.L.Ba, imperialAramaic.L.Bet], + [arabic.L.TaMarbuta, imperialAramaic.L.Taw], + [arabic.L.Ta, imperialAramaic.L.Taw], + [arabic.L.Tha, imperialAramaic.L.Taw], + [arabic.L.Jeem, imperialAramaic.L.Gimel], + [arabic.L.H7aa, imperialAramaic.L.Heth], + [arabic.L.Khaa, imperialAramaic.L.Heth], + [arabic.L.Dal, imperialAramaic.L.Daleth], + [arabic.L.Thal, imperialAramaic.L.Daleth], + [arabic.L.Ra, imperialAramaic.L.Resh], + [arabic.L.Zay, imperialAramaic.L.Zayin], + [arabic.L.Seen, imperialAramaic.L.Samekh], + [arabic.L.Sheen, imperialAramaic.L.Shin], + [arabic.L.Sad, imperialAramaic.L.Sadhe], + [arabic.L.Dad, imperialAramaic.L.Daleth], + [arabic.L.TTa, imperialAramaic.L.Teth], + [arabic.L.THa, imperialAramaic.L.Taw], + [arabic.L.Ayn, imperialAramaic.L.Ayin], + [arabic.L.Ghayn, imperialAramaic.L.Ayin], + [arabic.L.Fa, imperialAramaic.L.Pe], + [arabic.L.Qaf, imperialAramaic.L.Qoph], + [arabic.L.Kaf, imperialAramaic.L.Kaph], + [arabic.L.Lam, imperialAramaic.L.Lamedh], + [arabic.L.Meem, imperialAramaic.L.Mem], + [arabic.L.Noon, imperialAramaic.L.Nun], + [arabic.L.Ha, imperialAramaic.L.He], + [arabic.L.Waw, imperialAramaic.L.Waw], + [arabic.L.Yaa, imperialAramaic.L.Yod], + [arabic.L.AlefMaksura, imperialAramaic.L.Aleph], + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + const u = this.map.get(letter) ?? '' + result += u + } + return result + } +} diff --git a/packages/abjad-convert/src/scripts/arabic/toPhoenician.ts b/packages/abjad-convert/src/scripts/arabic/toPhoenician.ts new file mode 100644 index 0000000..5a6c163 --- /dev/null +++ b/packages/abjad-convert/src/scripts/arabic/toPhoenician.ts @@ -0,0 +1,59 @@ +import { arabic } from './letters' +import { phoenician } from '../phoenician/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class ArabicToPhoenicianConverter implements IConverter { + public readonly from = Abjad.Arabic + public readonly to = Abjad.Phoenician + + private map = new Map( + [ + [' ', phoenician.L.WordSeparator], + [arabic.L.Hamza, ''], + [arabic.L.AlefMadda, phoenician.L.Alep], // 𐤀 <- آ + [arabic.L.AlefHamza, phoenician.L.Alep], // 𐤀 <- ا + [arabic.L.WawHamza, phoenician.L.Waw], // 𐤅 <- ؤ + [arabic.L.AlefHamzaMaksura, phoenician.L.Alep], // 𐤀 <- ى + [arabic.L.Alef, phoenician.L.Alep], // 𐤀 <- ا + [arabic.L.Ba, phoenician.L.Bet], // 𐤁 <- ب + [arabic.L.TaMarbuta, phoenician.L.Tau], // 𐤕 <- ة + [arabic.L.Ta, phoenician.L.Tau], // 𐤕 <- ت + [arabic.L.Tha, phoenician.L.Tau], // 𐤕 <- ث + [arabic.L.Jeem, phoenician.L.Gimi], // 𐤂 <- ج + [arabic.L.H7aa, phoenician.L.Het], // 𐤇 <- ح + [arabic.L.Khaa, phoenician.L.Het], // 𐤇 <- خ + [arabic.L.Dal, phoenician.L.Dalet], // 𐤃 <- د + [arabic.L.Thal, phoenician.L.Dalet], // 𐤃 <- ذ + [arabic.L.Ra, phoenician.L.Ros], // 𐤓 <- ر + [arabic.L.Zay, phoenician.L.Zayin], // 𐤆 <- ز + [arabic.L.Seen, phoenician.L.Semk], // 𐤎 <- س + [arabic.L.Sheen, phoenician.L.Shin], // 𐤔 <- ش + [arabic.L.Sad, phoenician.L.Sade], // 𐤑 <- ص + [arabic.L.Dad, phoenician.L.Dalet], // 𐤃 <- ض + [arabic.L.TTa, phoenician.L.Tet], // 𐤈 <- ط + [arabic.L.THa, phoenician.L.Tau], // 𐤕 <- ظ + [arabic.L.Ayn, phoenician.L.Ain], // 𐤏 <- ع + [arabic.L.Ghayn, phoenician.L.Ain], // 𐤏 <- غ + [arabic.L.Fa, phoenician.L.Pe], // 𐤐 <- ف + [arabic.L.Qaf, phoenician.L.Qof], // 𐤒 <- ق + [arabic.L.Kaf, phoenician.L.Kap], // 𐤊 <- ك + [arabic.L.Lam, phoenician.L.Lam], // 𐤋 < - ل + [arabic.L.Meem, phoenician.L.Mem], // 𐤌 <- م + [arabic.L.Noon, phoenician.L.Nun], // 𐤍 <- ن + [arabic.L.Ha, phoenician.L.He], // 𐤄 <- ه + [arabic.L.Waw, phoenician.L.Waw], // 𐤅 <- و + [arabic.L.Yaa, phoenician.L.Yod], // 𐤉 <- ي + [arabic.L.AlefMaksura, phoenician.L.Alep], // 𐤀 <- ى + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + const u = this.map.get(letter) ?? '' + result += u + } + return result + } +} diff --git a/packages/abjad-convert/src/scripts/arabic/toSyriac.ts b/packages/abjad-convert/src/scripts/arabic/toSyriac.ts new file mode 100644 index 0000000..30580e0 --- /dev/null +++ b/packages/abjad-convert/src/scripts/arabic/toSyriac.ts @@ -0,0 +1,59 @@ +import { arabic } from './letters' +import { syriac } from '../syriac/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class ArabicToSyriacConverter implements IConverter { + public readonly from = Abjad.Arabic + public readonly to = Abjad.Syriac + + private map = new Map( + [ + [' ', ' '], + [arabic.L.Hamza, syriac.L.SuperaAlaph], // ء -> ܐ TODO: check + [arabic.L.AlefMadda, syriac.L.Alaph], // آ -> ܐ + [arabic.L.AlefHamza, syriac.L.Alaph], // أ -> ܐ + [arabic.L.WawHamza, syriac.L.Waw], // ؤ -> ܘ + [arabic.L.AlefHamzaMaksura, syriac.L.YudhHe], // ى -> ܞ + [arabic.L.Alef, syriac.L.Alaph], // ا -> ܐ + [arabic.L.Ba, syriac.L.Beth], // ب -> ܒ + [arabic.L.TaMarbuta, syriac.L.Taw], // ة -> ܬ + [arabic.L.Ta, syriac.L.Taw], // ت -> ܬ + [arabic.L.Tha, syriac.L.Taw], // ث -> ܬ + [arabic.L.Jeem, syriac.L.Gamal], // ج -> ܓ + [arabic.L.H7aa, syriac.L.Heth], // ح -> ܚ + [arabic.L.Khaa, syriac.L.Heth], // خ -> ܚ + [arabic.L.Dal, syriac.L.Dalath], // د -> ܕ + [arabic.L.Thal, syriac.L.Dalath], // ذ -> ܕ + [arabic.L.Ra, syriac.L.Rish], // ر -> ܪ + [arabic.L.Zay, syriac.L.Zain], // ز -> ܙ + [arabic.L.Seen, syriac.L.Semkath], // س -> ܣ + [arabic.L.Sheen, syriac.L.Shin], // ش -> ܫ + [arabic.L.Sad, syriac.L.Sadhe], // ص -> ܨ + [arabic.L.Dad, syriac.L.Dalath], // ض -> ܕ + [arabic.L.TTa, syriac.L.Teth], // ط -> ܛ + [arabic.L.THa, syriac.L.Taw], // ظ -> ܬ + [arabic.L.Ayn, syriac.L.E], // ع -> ܥ + [arabic.L.Ghayn, syriac.L.E], // غ -> ܥ + [arabic.L.Fa, syriac.L.Pe], // ف -> ܦ + [arabic.L.Qaf, syriac.L.Qaph], // ق -> ܩ + [arabic.L.Kaf, syriac.L.Kaph], // ك -> ܟ + [arabic.L.Lam, syriac.L.Lamadh], // ل -> ܠ + [arabic.L.Meem, syriac.L.Mim], // م -> ܡ + [arabic.L.Noon, syriac.L.Nun], // ن -> ܢ + [arabic.L.Ha, syriac.L.He], // ه -> ܗ + [arabic.L.Waw, syriac.L.Waw], // و -> ܘ + [arabic.L.Yaa, syriac.L.Yudh], // ي -> ܝ + [arabic.L.AlefMaksura, syriac.L.Alaph], // ى -> ܐ + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + const u = this.map.get(letter) ?? '' + result += u + } + return result + } +} diff --git a/packages/abjad-convert/src/scripts/arabic/toTifinagh.ts b/packages/abjad-convert/src/scripts/arabic/toTifinagh.ts new file mode 100644 index 0000000..c7cdf3c --- /dev/null +++ b/packages/abjad-convert/src/scripts/arabic/toTifinagh.ts @@ -0,0 +1,59 @@ +import { arabic } from './letters' +import { tifinagh } from '../tifinagh/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class ArabicToTifinaghConverter implements IConverter { + public readonly from = Abjad.Arabic + public readonly to = Abjad.Tifinagh + + private map = new Map( + [ + [' ', ' '], + [arabic.L.Hamza, tifinagh.L.Ya], /** ء -> ⴰ */ + [arabic.L.AlefMadda, tifinagh.L.Ya], /** ا -> ⴰ */ + [arabic.L.AlefHamza, tifinagh.L.Ya], /** أ -> ⴰ*/ + [arabic.L.WawHamza, tifinagh.L.Yu], /** ؤ -> ⵓ */ + [arabic.L.AlefHamzaMaksura, tifinagh.L.Ya], /** ى -> ⴰ */ + [arabic.L.Alef, tifinagh.L.Ya], /** ا -> ⴰ */ + [arabic.L.Ba, tifinagh.L.Yab], /** ب -> ⴱ */ + [arabic.L.TaMarbuta, tifinagh.L.Ya], /** ة -> ⴰ */ + [arabic.L.Ta, tifinagh.L.Yat], /** ت -> ⵜ */ + [arabic.L.Tha, tifinagh.L.Yath], /** ث -> ⵝ */ + [arabic.L.Jeem, tifinagh.L.Yazh], /** ج -> ⵊ */ + [arabic.L.H7aa, tifinagh.L.Yahh], /** ح -> ⵃ */ + [arabic.L.Khaa, tifinagh.L.Yakh], /** خ -> ⵅ */ + [arabic.L.Dal, tifinagh.L.Yad], /** د -> ⴷ */ + [arabic.L.Thal, tifinagh.L.Yadh], /** ذ -> ⴸ */ + [arabic.L.Ra, tifinagh.L.Yar], /** ر -> ⵔ */ + [arabic.L.Zay, tifinagh.L.Ya], /** ز -> ⴰ */ + [arabic.L.Seen, tifinagh.L.Yas], /** س -> ⵙ */ + [arabic.L.Sheen, tifinagh.L.Yash], /** ش -> ⵛ */ + [arabic.L.Sad, tifinagh.L.Yat], /** ص -> ⵜ */ + [arabic.L.Dad, tifinagh.L.Yadd], /** ض -> ⴹ */ + [arabic.L.TTa, tifinagh.L.Yatt], /** ط -> ⵟ */ + [arabic.L.THa, tifinagh.L.Yaddh], /** ظ -> ⴺ */ + [arabic.L.Ayn, tifinagh.L.Yaa], /** ع -> ⵄ */ + [arabic.L.Ghayn, tifinagh.L.Yagh], /** غ -> ⵖ */ + [arabic.L.Fa, tifinagh.L.Yaf], /** ف -> ⴼ */ + [arabic.L.Qaf, tifinagh.L.Yaq], /** ق -> ⵇ */ + [arabic.L.Kaf, tifinagh.L.Yak], /** ك -> ⴽ */ + [arabic.L.Lam, tifinagh.L.Yal], /** ل -> ⵍ */ + [arabic.L.Meem, tifinagh.L.Yam], /** م -> ⵎ */ + [arabic.L.Noon, tifinagh.L.Yan], /** ن -> ⵏ */ + [arabic.L.Ha, tifinagh.L.Yey], /** ه -> ⴻ */ + [arabic.L.Waw, tifinagh.L.Yu], /** و -> ⵓ */ + [arabic.L.AlefMaksura, tifinagh.L.Ya], /** ى -> ⴰ */ + [arabic.L.Yaa, tifinagh.L.Yi], /** ي -> ⵉ */ + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + const u = this.map.get(letter) ?? '' + result += u + } + return result + } +} diff --git a/packages/abjad-convert/src/scripts/arabic/toUgaritic.ts b/packages/abjad-convert/src/scripts/arabic/toUgaritic.ts new file mode 100644 index 0000000..e857713 --- /dev/null +++ b/packages/abjad-convert/src/scripts/arabic/toUgaritic.ts @@ -0,0 +1,58 @@ +import { arabic } from './letters' +import { ugaritic } from '../ugaritic/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class ArabicToUgariticConverter implements IConverter { + public readonly from = Abjad.Arabic + public readonly to = Abjad.Ugaritic + private map = new Map( + [ + [' ', ' '], + [arabic.L.Hamza, ''], + [arabic.L.AlefMadda, ugaritic.L.Alpa], + [arabic.L.AlefHamza, ugaritic.L.Alpa], + [arabic.L.WawHamza, ugaritic.L.Alpa], + [arabic.L.AlefHamzaMaksura, ugaritic.L.Alpa], + [arabic.L.Alef, ugaritic.L.Alpa], + [arabic.L.Ba, ugaritic.L.Beta], + [arabic.L.TaMarbuta, ugaritic.L.To], + [arabic.L.Ta, ugaritic.L.To], + [arabic.L.Tha, ugaritic.L.Thanna], + [arabic.L.Jeem, ugaritic.L.Gamla], + [arabic.L.H7aa, ugaritic.L.Hota], + [arabic.L.Khaa, ugaritic.L.Kha], + [arabic.L.Dal, ugaritic.L.Delta], + [arabic.L.Thal, ugaritic.L.Delta], + [arabic.L.Ra, ugaritic.L.Rasha], + [arabic.L.Zay, ugaritic.L.Zu], + [arabic.L.Seen, ugaritic.L.Samka], + [arabic.L.Sheen, ugaritic.L.Shin], + [arabic.L.Sad, ugaritic.L.Sade], + [arabic.L.Dad, ugaritic.L.Dhal], + [arabic.L.TTa, ugaritic.L.Tet], + [arabic.L.THa, ugaritic.L.Thanna], + [arabic.L.Ayn, ugaritic.L.Ain], + [arabic.L.Ghayn, ugaritic.L.Ghain], + [arabic.L.Fa, ugaritic.L.Pu], + [arabic.L.Qaf, ugaritic.L.Qopa], + [arabic.L.Kaf, ugaritic.L.Kaf], + [arabic.L.Lam, ugaritic.L.Lamda], + [arabic.L.Meem, ugaritic.L.Mem], + [arabic.L.Noon, ugaritic.L.Nun], + [arabic.L.Ha, ugaritic.L.Ho], + [arabic.L.Waw, ugaritic.L.Wo], + [arabic.L.Yaa, ugaritic.L.Yod], + [arabic.L.AlefMaksura, ugaritic.L.Alpa], + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + const u = this.map.get(letter) ?? '' + result += u + } + return result + } +} diff --git a/packages/abjad-convert/src/imperialAramaic/U10840.pdf b/packages/abjad-convert/src/scripts/imperialAramaic/U10840.pdf similarity index 100% rename from packages/abjad-convert/src/imperialAramaic/U10840.pdf rename to packages/abjad-convert/src/scripts/imperialAramaic/U10840.pdf diff --git a/packages/abjad-convert/src/imperialAramaic/letters.ts b/packages/abjad-convert/src/scripts/imperialAramaic/letters.ts similarity index 94% rename from packages/abjad-convert/src/imperialAramaic/letters.ts rename to packages/abjad-convert/src/scripts/imperialAramaic/letters.ts index 9992396..aa7ae53 100644 --- a/packages/abjad-convert/src/imperialAramaic/letters.ts +++ b/packages/abjad-convert/src/scripts/imperialAramaic/letters.ts @@ -1,3 +1,6 @@ +import { Script } from '../Script' +import { Abjad } from '../../types' + /** * Imperial Aramaic letters */ @@ -33,9 +36,9 @@ const letters = [ '\uD802\uDC5D', /** #27 𐡝 U+1085D IMPERIAL ARAMAIC NUMBER ONE HUNDRED */ '\uD802\uDC5E', /** #28 𐡞 U+1085E IMPERIAL ARAMAIC NUMBER ONE THOUSAND */ '\uD802\uDC5F', /** #29 𐡟 U+1085F IMPERIAL ARAMAIC NUMBER TEN THOUSAND */ -] +] as const -export const Ia = { +const Ia = { Aleph: letters[0], // 𐡀 Bet: letters[1], // 𐡁 Gimel: letters[2], // 𐡂 @@ -68,3 +71,10 @@ export const Ia = { Thousand: letters[28], // 𐡞 TenThousand: letters[29], // 𐡟 } + +export const imperialAramaic = new Script( + Abjad.ImperialAramaic, + true, + letters, + Ia, +) diff --git a/packages/abjad-convert/src/scripts/imperialAramaic/toArabic.ts b/packages/abjad-convert/src/scripts/imperialAramaic/toArabic.ts new file mode 100644 index 0000000..8fb9602 --- /dev/null +++ b/packages/abjad-convert/src/scripts/imperialAramaic/toArabic.ts @@ -0,0 +1,45 @@ +import { imperialAramaic } from './letters' +import { arabic } from '../arabic/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class ImperialAramaicToArabicConverter implements IConverter { + public readonly from = Abjad.ImperialAramaic + public readonly to = Abjad.Arabic + + private map = new Map( + [ + [' ', ' '], + [imperialAramaic.L.Aleph, arabic.L.Alef], // 𐡀 -> ا + [imperialAramaic.L.Bet, arabic.L.Ba], // 𐡁 -> ب + [imperialAramaic.L.Gimel, arabic.L.Jeem], // 𐡂 -> ج + [imperialAramaic.L.Daleth, arabic.L.Dal], // 𐡃 -> د + [imperialAramaic.L.He, arabic.L.Ha], // 𐡄 -> ه + [imperialAramaic.L.Waw, arabic.L.Waw], // 𐡅 -> و + [imperialAramaic.L.Zayin, arabic.L.Zay], // 𐡆 -> ز + [imperialAramaic.L.Heth, arabic.L.Ha], // 𐡇 -> ح + [imperialAramaic.L.Teth, arabic.L.Ta], // 𐡈 -> ط + [imperialAramaic.L.Yod, arabic.L.Yaa], // 𐡉 -> ي + [imperialAramaic.L.Kaph, arabic.L.Kaf], // 𐡊 -> ك + [imperialAramaic.L.Lamedh, arabic.L.Lam], // 𐡋 -> ل + [imperialAramaic.L.Mem, arabic.L.Meem], // 𐡌 -> م + [imperialAramaic.L.Nun, arabic.L.Noon], // 𐡍 -> ن + [imperialAramaic.L.Samekh, arabic.L.Seen], // 𐡎 -> س + [imperialAramaic.L.Ayin, arabic.L.Ayn], // 𐡏 -> ع + [imperialAramaic.L.Pe, arabic.L.Fa], // 𐡐 -> ف + [imperialAramaic.L.Sadhe, arabic.L.Sad], // 𐡑 -> ص + [imperialAramaic.L.Qoph, arabic.L.Qaf], // 𐡒 -> ق + [imperialAramaic.L.Resh, arabic.L.Ra], // 𐡓 -> ر + [imperialAramaic.L.Shin, arabic.L.Sheen], // 𐡔 -> ش + [imperialAramaic.L.Taw, arabic.L.Ta], // 𐡕 -> ت + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + result += this.map.get(letter) ?? '' + } + return result + } +} diff --git a/packages/abjad-convert/src/phoenician/U10900.pdf b/packages/abjad-convert/src/scripts/phoenician/U10900.pdf similarity index 100% rename from packages/abjad-convert/src/phoenician/U10900.pdf rename to packages/abjad-convert/src/scripts/phoenician/U10900.pdf diff --git a/packages/abjad-convert/src/phoenician/letters.ts b/packages/abjad-convert/src/scripts/phoenician/letters.ts similarity index 93% rename from packages/abjad-convert/src/phoenician/letters.ts rename to packages/abjad-convert/src/scripts/phoenician/letters.ts index 97b8c33..e7ee610 100644 --- a/packages/abjad-convert/src/phoenician/letters.ts +++ b/packages/abjad-convert/src/scripts/phoenician/letters.ts @@ -1,3 +1,6 @@ +import { Abjad } from '../../types' +import { Script } from '../Script' + const letters = [ '\uD802\uDD00', /** #0 𐤀 U+10900 PHOENICIAN LETTER Alep */ '\uD802\uDD01', /** #1 𐤁 U+10901 PHOENICIAN LETTER Bet */ @@ -30,9 +33,9 @@ const letters = [ '\uD802\uDD1B', /** #27 𐤛 U+1091B PHOENICIAN NUMBER THREE */ '\uD802\uDD1F', /** #28 𐤟 U+1091F PHOENICIAN Word Separator */ -] +] as const -export const Ph = { +const Ph = { Alep: letters[0], // 𐤀 Bet: letters[1], // 𐤁 Gimi: letters[2], // 𐤂 @@ -63,3 +66,10 @@ export const Ph = { Three: letters[27], // 𐤛 WordSeparator: letters[28], // 𐤟 } + +export const phoenician = new Script( + Abjad.Phoenician, + true, + letters, + Ph, +) diff --git a/packages/abjad-convert/src/scripts/phoenician/toArabic.ts b/packages/abjad-convert/src/scripts/phoenician/toArabic.ts new file mode 100644 index 0000000..dee20f5 --- /dev/null +++ b/packages/abjad-convert/src/scripts/phoenician/toArabic.ts @@ -0,0 +1,46 @@ +import { phoenician } from './letters' +import { arabic } from '../arabic/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class PhoenicianToArabicConverter implements IConverter { + public readonly from = Abjad.Phoenician + public readonly to = Abjad.Arabic + + private map = new Map( + [ + [' ', ' '], + [phoenician.L.WordSeparator, ' '], + [phoenician.L.Alep, arabic.L.Alef], // 𐤀 -> ا + [phoenician.L.Bet, arabic.L.Ba], // 𐤁 -> ب + [phoenician.L.Gimi, arabic.L.Jeem], // 𐤂 -> ج + [phoenician.L.Dalet, arabic.L.Dal], // 𐤃 -> د + [phoenician.L.He, arabic.L.Ha], // 𐤄 -> ه + [phoenician.L.Waw, arabic.L.Waw], // 𐤅 -> و + [phoenician.L.Zayin, arabic.L.Zay], // 𐤆 -> ز + [phoenician.L.Het, arabic.L.H7aa], // 𐤇 -> ح + [phoenician.L.Tet, arabic.L.TTa], // 𐤈 -> ط + [phoenician.L.Yod, arabic.L.Yaa], // 𐤉 -> ي + [phoenician.L.Kap, arabic.L.Kaf], // 𐤊 -> ك + [phoenician.L.Lam, arabic.L.Lam], // 𐤋 -> ل + [phoenician.L.Mem, arabic.L.Meem], // 𐤌 -> م + [phoenician.L.Nun, arabic.L.Noon], // 𐤍 -> ن + [phoenician.L.Semk, arabic.L.Seen], // 𐤎 -> س + [phoenician.L.Ain, arabic.L.Ayn], // 𐤏 -> ع + [phoenician.L.Pe, arabic.L.Fa], // 𐤐 -> ف + [phoenician.L.Sade, arabic.L.Sad], // 𐤑 -> ض + [phoenician.L.Qof, arabic.L.Qaf], // 𐤒 -> ق + [phoenician.L.Ros, arabic.L.Ra], // 𐤓 -> ر + [phoenician.L.Shin, arabic.L.Sheen], // 𐤔 -> ش + [phoenician.L.Tau, arabic.L.Ta], // 𐤕 -> ث + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + result += this.map.get(letter) ?? '' + } + return result + } +} diff --git a/packages/abjad-convert/src/syriac/U0700.pdf b/packages/abjad-convert/src/scripts/syriac/U0700.pdf similarity index 100% rename from packages/abjad-convert/src/syriac/U0700.pdf rename to packages/abjad-convert/src/scripts/syriac/U0700.pdf diff --git a/packages/abjad-convert/src/syriac/letters.ts b/packages/abjad-convert/src/scripts/syriac/letters.ts similarity index 93% rename from packages/abjad-convert/src/syriac/letters.ts rename to packages/abjad-convert/src/scripts/syriac/letters.ts index a130224..e0c74d5 100644 --- a/packages/abjad-convert/src/syriac/letters.ts +++ b/packages/abjad-convert/src/scripts/syriac/letters.ts @@ -1,4 +1,7 @@ -export const letters = [ +import { Script } from '../Script' +import { Abjad } from '../../types' + +const letters = [ '\u0710', /** #0 ܐ U+0710 SYRIAC LETTER ALAPH */ '\u0711', /** #1 ܑ U+0711 SYRIAC LETTER SUPERSCRIPT ALAPH */ '\u0712', /** #2 ܒ U+0712 SYRIAC LETTER BETH */ @@ -31,9 +34,9 @@ export const letters = [ '\u072D', /** #29 ܭ U+072D SYRIAC LETTER PERSIAN BHETH */ '\u072E', /** #30 ܮ U+072E SYRIAC LETTER PERSIAN GHAMAL */ '\u072F', /** #31 ܯ U+072F SYRIAC LETTER PERSIAN DHALATH */ -] +] as const -export const Sy = { +const Sy = { Alaph: letters[0], // ܐ SuperaAlaph: letters[1], // ܑ Beth: letters[2], // ܒ @@ -67,3 +70,10 @@ export const Sy = { PersianGhamal: letters[30], // ܮ PersianDhalath: letters[31], // ܯ } + +export const syriac = new Script( + Abjad.Syriac, + true, + letters, + Sy, +) diff --git a/packages/abjad-convert/src/scripts/syriac/toArabic.ts b/packages/abjad-convert/src/scripts/syriac/toArabic.ts new file mode 100644 index 0000000..e1a2e35 --- /dev/null +++ b/packages/abjad-convert/src/scripts/syriac/toArabic.ts @@ -0,0 +1,55 @@ +import { syriac } from './letters' +import { arabic } from '../arabic/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class SyriacToArabicConverter implements IConverter { + public readonly from = Abjad.Syriac + public readonly to = Abjad.Arabic + + private map = new Map( + [ + [' ', ' '], + [syriac.L.Alaph, arabic.L.Alef], // ܐ -> ا + [syriac.L.SuperaAlaph, ''], // TODO: check if this logic is correct + [syriac.L.Beth, arabic.L.Ba], // ܒ -> ب + [syriac.L.Gamal, arabic.L.Jeem], // ܓ -> ج + [syriac.L.GamalGarshuni, arabic.L.Jeem], // ܔ -> ج + [syriac.L.Dalath, arabic.L.Dal], // ܕ -> د + [syriac.L.DalathRish, arabic.L.Dal], // ܖ -> د + [syriac.L.He, arabic.L.Ha], // ܗ -> ه + [syriac.L.Waw, arabic.L.Waw], // ܘ -> و + [syriac.L.Zain, arabic.L.Zay], // ܙ -> ز + [syriac.L.Heth, arabic.L.H7aa], // ܚ -> ح + [syriac.L.Teth, arabic.L.TTa], // ܛ -> ط + [syriac.L.TethGarshuni, arabic.L.TTa], // ܜ -> ط + [syriac.L.Yudh, arabic.L.Yaa], // ܝ -> ي + [syriac.L.YudhHe, arabic.L.Yaa], // ܞ -> ي + [syriac.L.Kaph, arabic.L.Kaf], // ܟ -> ك + [syriac.L.Lamadh, arabic.L.Lam], // ܠ -> ل + [syriac.L.Mim, arabic.L.Meem], // ܡ -> م + [syriac.L.Nun, arabic.L.Noon], // ܢ -> ن + [syriac.L.Semkath, arabic.L.Seen], // ܣ -> س + [syriac.L.FinalSemkath, arabic.L.Seen], // ܤ -> س + [syriac.L.E, arabic.L.Ayn], // ܥ -> ع + [syriac.L.Pe, arabic.L.Fa], // ܦ -> ف + [syriac.L.ReversedPe, arabic.L.Fa], // ܧ -> ف + [syriac.L.Sadhe, arabic.L.Sad], // ܨ -> ص + [syriac.L.Qaph, arabic.L.Qaf], // ܩ -> ق + [syriac.L.Rish, arabic.L.Ra], // ܪ -> ر + [syriac.L.Shin, arabic.L.Sheen], // ܫ -> ش + [syriac.L.Taw, arabic.L.Ta], // ܬ -> ت + [syriac.L.PersianBheth, arabic.L.Ba], // ܭ -> ب + [syriac.L.PersianGhamal, arabic.L.Jeem], // ܮ -> ج + [syriac.L.PersianDhalath, arabic.L.Dal], // ܯ -> د + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + result += this.map.get(letter) ?? '' + } + return result + } +} diff --git a/packages/abjad-convert/src/tifinagh/U2D30.pdf b/packages/abjad-convert/src/scripts/tifinagh/U2D30.pdf similarity index 100% rename from packages/abjad-convert/src/tifinagh/U2D30.pdf rename to packages/abjad-convert/src/scripts/tifinagh/U2D30.pdf diff --git a/packages/abjad-convert/src/tifinagh/letters.ts b/packages/abjad-convert/src/scripts/tifinagh/letters.ts similarity index 96% rename from packages/abjad-convert/src/tifinagh/letters.ts rename to packages/abjad-convert/src/scripts/tifinagh/letters.ts index 71e88ec..5bf8ae2 100644 --- a/packages/abjad-convert/src/tifinagh/letters.ts +++ b/packages/abjad-convert/src/scripts/tifinagh/letters.ts @@ -1,4 +1,7 @@ -export const letters = [ +import { Abjad } from '../../types' +import { Script } from '../Script' + +const letters = [ '\u2d30', /** #0 ⴰ U+2D30 TIFINAGH LETTER YA */ '\u2d31', /** #1 ⴱ U+2D31 TIFINAGH LETTER YAB */ '\u2d32', /** #2 ⴲ U+2D32 TIFINAGH LETTER YABH */ @@ -58,9 +61,9 @@ export const letters = [ '\u2d6f', /** #56 ⵯ U+2D6F TIFINAGH MODIFIER LETTER LABIALIZATION MARK */ '\u2d70', /** #54 ⵯ U+2D70 TIFINAGH SEPARATOR MARK */ '\u2d7f', /** #55 ⵯ U+2D7F TIFINAGH CONSONANT JOINER */ -] +] as const -export const Ti = { +const Ti = { Ya: letters[0], // ⴰ Yab: letters[1], // ⴱ Yabh: letters[2], // ⴲ @@ -121,3 +124,10 @@ export const Ti = { SeparatorMark: letters[57], // ⵯ ConsonantJoiner: letters[58], // ⵯ } + +export const tifinagh = new Script( + Abjad.Tifinagh, + false, + letters, + Ti, +) diff --git a/packages/abjad-convert/src/scripts/tifinagh/toArabic.ts b/packages/abjad-convert/src/scripts/tifinagh/toArabic.ts new file mode 100644 index 0000000..b15e1df --- /dev/null +++ b/packages/abjad-convert/src/scripts/tifinagh/toArabic.ts @@ -0,0 +1,80 @@ +import { tifinagh } from './letters' +import { arabic } from '../arabic/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class TifinaghToArabicConverter implements IConverter { + public readonly from = Abjad.Tifinagh + public readonly to = Abjad.Arabic + + private map = new Map( + [ + [' ', ' '], + [tifinagh.L.Ya, arabic.L.Alef], // ⴰ -> ا + [tifinagh.L.Yab, arabic.L.Ba], // ⴱ -> ب + [tifinagh.L.Yabh, arabic.L.Ba], // ⴲ -> ب P + [tifinagh.L.Yag, arabic.L.Jeem], // ⴳ -> ج G + [tifinagh.L.Yagh, arabic.L.Jeem], // ⴴ -> ج G + [tifinagh.L.Yad, arabic.L.Dal], // ⴷ -> د + [tifinagh.L.Yadh, arabic.L.Thal], // ⴸ -> ذ + [tifinagh.L.Yadd, arabic.L.Dad], // ⴹ -> ض + [tifinagh.L.Yaddh, arabic.L.THa], // ⴺ -> ظ + [tifinagh.L.Yey, arabic.L.Ha], // ⴻ -> ه + [tifinagh.L.Yaf, arabic.L.Fa], // ⴼ -> ف + [tifinagh.L.Yak, arabic.L.Kaf], // ⴽ -> ك + [tifinagh.L.TuaregYak, arabic.L.Kaf], // ⴾ -> ك + [tifinagh.L.Yakhh, arabic.L.Kaf], // ⴿ -> ك + [tifinagh.L.Yah, arabic.L.Ha], // ⵀ -> هـ , TODO: also it can be B ب + [tifinagh.L.BerberAcademyYah, arabic.L.Ha], // ⵁ -> هـ + [tifinagh.L.TuaregYah, arabic.L.Ha], // ⵂ -> هـ + [tifinagh.L.Yahh, arabic.L.H7aa], // ⵃ -> ح + [tifinagh.L.Yaa, arabic.L.Ayn], // ⵄ -> ع + [tifinagh.L.Yakh, arabic.L.Khaa], // ⵅ -> خ + [tifinagh.L.TuaregYakh, arabic.L.Khaa], // ⵆ -> خ + [tifinagh.L.Yaq, arabic.L.Qaf], // ⵇ -> ق + [tifinagh.L.TuaregYaq, arabic.L.Qaf], // ⵈ -> ق + [tifinagh.L.Yi, arabic.L.Yaa], // ⵉ -> ي + [tifinagh.L.Yazh, arabic.L.Jeem], // ⵊ -> ج + [tifinagh.L.AhaggarYazh, arabic.L.Jeem], // ⵋ -> ج + [tifinagh.L.TuaregYazh, arabic.L.Jeem], // ⵌ -> ج + [tifinagh.L.Yal, arabic.L.Lam], // ⵍ -> ل + [tifinagh.L.Yam, arabic.L.Meem], // ⵎ -> م + [tifinagh.L.Yan, arabic.L.Noon], // ⵏ -> ن + [tifinagh.L.TuaregYagn, arabic.L.Noon], // ⵐ -> ن IPA: ɲ TODO: this is 2 letters of ني + [tifinagh.L.TuaregYang, arabic.L.Noon], // ⵑ -> ن IPA: ŋ + [tifinagh.L.Yap, arabic.L.Ba], // ⵒ -> ب + [tifinagh.L.Yu, arabic.L.Waw], // ⵓ -> و + [tifinagh.L.Yar, arabic.L.Ra], // ⵔ -> ر + [tifinagh.L.Yarr, arabic.L.Ra], // ⵕ -> ر + [tifinagh.L.Yagh, arabic.L.Ghayn], // ⵖ -> غ + [tifinagh.L.TuaregYagh, arabic.L.Ghayn], // ⵗ -> غ + [tifinagh.L.AyerYagh, arabic.L.Ghayn], // ⵘ -> غ TODO: this can be ج + [tifinagh.L.Yas, arabic.L.Seen], // ⵙ -> س + [tifinagh.L.Yass, arabic.L.Seen], // ⵚ -> ص + [tifinagh.L.Yash, arabic.L.Sheen], // ⵛ -> ش + [tifinagh.L.Yat, arabic.L.Ta], // ⵜ -> ت + [tifinagh.L.Yath, arabic.L.Tha], // ⵝ -> ث + [tifinagh.L.Yach, arabic.L.Jeem], // ⵞ -> ج + [tifinagh.L.Yatt, arabic.L.Ta], // ⵟ -> ت + [tifinagh.L.Yav, arabic.L.Fa], // ⵠ -> ف + [tifinagh.L.Yaw, arabic.L.Waw], // ⵡ -> و + [tifinagh.L.Yay, arabic.L.Yaa], // ⵢ -> ي + [tifinagh.L.Yaz, arabic.L.Zay], // ⵣ -> ز + [tifinagh.L.TawellemetYaz, arabic.L.Zay], // ⵤ -> ز + [tifinagh.L.Yazz, arabic.L.Zay], // ⵥ -> ز + [tifinagh.L.Ye, arabic.L.Yaa], // ⵦ -> ي + [tifinagh.L.Yo, arabic.L.Waw], // ⵧ -> و + [tifinagh.L.ModifierLetterLabializationMark, ''], // ⵯ -> nothing + [tifinagh.L.SeparatorMark, ''], // ⵯ -> nothing + [tifinagh.L.ConsonantJoiner, ''], // ⵯ -> nothing + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + result += this.map.get(letter) ?? '' + } + return result + } +} diff --git a/packages/abjad-convert/src/ugaritic/U10380.pdf b/packages/abjad-convert/src/scripts/ugaritic/U10380.pdf similarity index 100% rename from packages/abjad-convert/src/ugaritic/U10380.pdf rename to packages/abjad-convert/src/scripts/ugaritic/U10380.pdf diff --git a/packages/abjad-convert/src/ugaritic/letters.ts b/packages/abjad-convert/src/scripts/ugaritic/letters.ts similarity index 93% rename from packages/abjad-convert/src/ugaritic/letters.ts rename to packages/abjad-convert/src/scripts/ugaritic/letters.ts index dd940cb..69e76ef 100644 --- a/packages/abjad-convert/src/ugaritic/letters.ts +++ b/packages/abjad-convert/src/scripts/ugaritic/letters.ts @@ -1,4 +1,7 @@ -export const letters = [ +import { Script } from '../Script' +import { Abjad } from '../../types' + +const letters = [ '\uD800\uDF80', /** #0 𐎀 U+10380 UGARITIC LETTER ALPA */ '\uD800\uDF81', /** #1 𐎁 U+10381 UGARITIC LETTER BETA */ '\uD800\uDF82', /** #2 𐎂 U+10382 UGARITIC LETTER GAMLA */ @@ -29,9 +32,9 @@ export const letters = [ '\uD800\uDF9B', /** #27 𐎛 U+1039B UGARITIC LETTER I */ '\uD800\uDF9C', /** #28 𐎜 U+1039C UGARITIC LETTER U */ '\uD800\uDF9D', /** #29 𐎝 U+1039D UGARITIC LETTER SSU */ -] +] as const -export const Ug = { +const Ug = { Alpa: letters[0], // 𐎀 Beta: letters[1], // 𐎁 Gamla: letters[2], // 𐎂 @@ -63,3 +66,10 @@ export const Ug = { U: letters[28], // 𐎜 Ssu: letters[29], // 𐎝 } + +export const ugaritic = new Script( + Abjad.Ugaritic, + false, + letters, + Ug, +) diff --git a/packages/abjad-convert/src/scripts/ugaritic/toArabic.ts b/packages/abjad-convert/src/scripts/ugaritic/toArabic.ts new file mode 100644 index 0000000..2c99f21 --- /dev/null +++ b/packages/abjad-convert/src/scripts/ugaritic/toArabic.ts @@ -0,0 +1,53 @@ +import { ugaritic } from './letters' +import { arabic } from '../arabic/letters' +import { IConverter } from '../../IConverter' +import { Abjad } from '../../types' + +export class UgariticToArabicConverter implements IConverter { + public readonly from = Abjad.Ugaritic + public readonly to = Abjad.Arabic + + private map = new Map( + [ + [' ', ' '], + [ugaritic.L.Alpa, arabic.L.Alef], + [ugaritic.L.Beta, arabic.L.Ba], + [ugaritic.L.Gamla, arabic.L.Jeem], + [ugaritic.L.Kha, arabic.L.Khaa], + [ugaritic.L.Delta, arabic.L.Dal], + [ugaritic.L.Ho, arabic.L.Ha], + [ugaritic.L.Wo, arabic.L.Waw], + [ugaritic.L.Zeta, arabic.L.Zay], + [ugaritic.L.Hota, arabic.L.H7aa], + [ugaritic.L.Tet, arabic.L.TTa], + [ugaritic.L.Yod, arabic.L.Yaa], + [ugaritic.L.Kaf, arabic.L.Kaf], + [ugaritic.L.Shin, arabic.L.Sheen], + [ugaritic.L.Lamda, arabic.L.Lam], + [ugaritic.L.Mem, arabic.L.Meem], + [ugaritic.L.Dhal, arabic.L.Dad], + [ugaritic.L.Nun, arabic.L.Noon], + [ugaritic.L.Zu, arabic.L.Zay], + [ugaritic.L.Samka, arabic.L.Seen], + [ugaritic.L.Ain, arabic.L.Ayn], + [ugaritic.L.Pu, arabic.L.Fa], + [ugaritic.L.Sade, arabic.L.Sad], + [ugaritic.L.Qopa, arabic.L.Qaf], + [ugaritic.L.Rasha, arabic.L.Ra], + [ugaritic.L.Thanna, arabic.L.THa], + [ugaritic.L.Ghain, arabic.L.Ghayn], + [ugaritic.L.To, arabic.L.Ta], + [ugaritic.L.I, arabic.L.AlefMaksura], + [ugaritic.L.U, arabic.L.Waw], + [ugaritic.L.Ssu, arabic.L.Sad], + ] + ) + + public convert(text: string): string { + let result = '' + for (const letter of text) { + result += this.map.get(letter) ?? '' + } + return result + } +} diff --git a/packages/abjad-convert/src/syriac/toArabic.ts b/packages/abjad-convert/src/syriac/toArabic.ts deleted file mode 100644 index 30dc969..0000000 --- a/packages/abjad-convert/src/syriac/toArabic.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Sy } from './letters' -import { Ar } from '../arabic/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class SyriacToArabicConverter implements IConverter { - public readonly from = Abjad.Syriac - public readonly to = Abjad.Arabic - - private map = new Map( - [ - [' ', ' '], - [Sy.Alaph, Ar.Alef], // ܐ -> ا - [Sy.SuperaAlaph, ''], // TODO: check if this logic is correct - [Sy.Beth, Ar.Ba], // ܒ -> ب - [Sy.Gamal, Ar.Jeem], // ܓ -> ج - [Sy.GamalGarshuni, Ar.Jeem], // ܔ -> ج - [Sy.Dalath, Ar.Dal], // ܕ -> د - [Sy.DalathRish, Ar.Dal], // ܖ -> د - [Sy.He, Ar.Ha], // ܗ -> ه - [Sy.Waw, Ar.Waw], // ܘ -> و - [Sy.Zain, Ar.Zay], // ܙ -> ز - [Sy.Heth, Ar.H7aa], // ܚ -> ح - [Sy.Teth, Ar.TTa], // ܛ -> ط - [Sy.TethGarshuni, Ar.TTa], // ܜ -> ط - [Sy.Yudh, Ar.Yaa], // ܝ -> ي - [Sy.YudhHe, Ar.Yaa], // ܞ -> ي - [Sy.Kaph, Ar.Kaf], // ܟ -> ك - [Sy.Lamadh, Ar.Lam], // ܠ -> ل - [Sy.Mim, Ar.Meem], // ܡ -> م - [Sy.Nun, Ar.Noon], // ܢ -> ن - [Sy.Semkath, Ar.Seen], // ܣ -> س - [Sy.FinalSemkath, Ar.Seen], // ܤ -> س - [Sy.E, Ar.Ayn], // ܥ -> ع - [Sy.Pe, Ar.Fa], // ܦ -> ف - [Sy.ReversedPe, Ar.Fa], // ܧ -> ف - [Sy.Sadhe, Ar.Sad], // ܨ -> ص - [Sy.Qaph, Ar.Qaf], // ܩ -> ق - [Sy.Rish, Ar.Ra], // ܪ -> ر - [Sy.Shin, Ar.Sheen], // ܫ -> ش - [Sy.Taw, Ar.Ta], // ܬ -> ت - [Sy.PersianBheth, Ar.Ba], // ܭ -> ب - [Sy.PersianGhamal, Ar.Jeem], // ܮ -> ج - [Sy.PersianDhalath, Ar.Dal], // ܯ -> د - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - result += this.map.get(letter) ?? '' - } - return result - } -} diff --git a/packages/abjad-convert/src/tifinagh/toArabic.ts b/packages/abjad-convert/src/tifinagh/toArabic.ts deleted file mode 100644 index 99190ce..0000000 --- a/packages/abjad-convert/src/tifinagh/toArabic.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Ti } from './letters' -import { Ar } from '../arabic/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class TifinaghToArabicConverter implements IConverter { - public readonly from = Abjad.Tifinagh - public readonly to = Abjad.Arabic - - private map = new Map( - [ - [' ', ' '], - [Ti.Ya, Ar.Alef], // ⴰ -> ا - [Ti.Yab, Ar.Ba], // ⴱ -> ب - [Ti.Yabh, Ar.Ba], // ⴲ -> ب P - [Ti.Yag, Ar.Jeem], // ⴳ -> ج G - [Ti.Yagh, Ar.Jeem], // ⴴ -> ج G - [Ti.Yad, Ar.Dal], // ⴷ -> د - [Ti.Yadh, Ar.Thal], // ⴸ -> ذ - [Ti.Yadd, Ar.Dad], // ⴹ -> ض - [Ti.Yaddh, Ar.THa], // ⴺ -> ظ - [Ti.Yey, Ar.Ha], // ⴻ -> ه - [Ti.Yaf, Ar.Fa], // ⴼ -> ف - [Ti.Yak, Ar.Kaf], // ⴽ -> ك - [Ti.TuaregYak, Ar.Kaf], // ⴾ -> ك - [Ti.Yakhh, Ar.Kaf], // ⴿ -> ك - [Ti.Yah, Ar.Ha], // ⵀ -> هـ , TODO: also it can be B ب - [Ti.BerberAcademyYah, Ar.Ha], // ⵁ -> هـ - [Ti.TuaregYah, Ar.Ha], // ⵂ -> هـ - [Ti.Yahh, Ar.H7aa], // ⵃ -> ح - [Ti.Yaa, Ar.Ayn], // ⵄ -> ع - [Ti.Yakh, Ar.Khaa], // ⵅ -> خ - [Ti.TuaregYakh, Ar.Khaa], // ⵆ -> خ - [Ti.Yaq, Ar.Qaf], // ⵇ -> ق - [Ti.TuaregYaq, Ar.Qaf], // ⵈ -> ق - [Ti.Yi, Ar.Yaa], // ⵉ -> ي - [Ti.Yazh, Ar.Jeem], // ⵊ -> ج - [Ti.AhaggarYazh, Ar.Jeem], // ⵋ -> ج - [Ti.TuaregYazh, Ar.Jeem], // ⵌ -> ج - [Ti.Yal, Ar.Lam], // ⵍ -> ل - [Ti.Yam, Ar.Meem], // ⵎ -> م - [Ti.Yan, Ar.Noon], // ⵏ -> ن - [Ti.TuaregYagn, Ar.Noon], // ⵐ -> ن IPA: ɲ TODO: this is 2 letters of ني - [Ti.TuaregYang, Ar.Noon], // ⵑ -> ن IPA: ŋ - [Ti.Yap, Ar.Ba], // ⵒ -> ب - [Ti.Yu, Ar.Waw], // ⵓ -> و - [Ti.Yar, Ar.Ra], // ⵔ -> ر - [Ti.Yarr, Ar.Ra], // ⵕ -> ر - [Ti.Yagh, Ar.Ghayn], // ⵖ -> غ - [Ti.TuaregYagh, Ar.Ghayn], // ⵗ -> غ - [Ti.AyerYagh, Ar.Ghayn], // ⵘ -> غ TODO: this can be ج - [Ti.Yas, Ar.Seen], // ⵙ -> س - [Ti.Yass, Ar.Seen], // ⵚ -> ص - [Ti.Yash, Ar.Sheen], // ⵛ -> ش - [Ti.Yat, Ar.Ta], // ⵜ -> ت - [Ti.Yath, Ar.Tha], // ⵝ -> ث - [Ti.Yach, Ar.Jeem], // ⵞ -> ج - [Ti.Yatt, Ar.Ta], // ⵟ -> ت - [Ti.Yav, Ar.Fa], // ⵠ -> ف - [Ti.Yaw, Ar.Waw], // ⵡ -> و - [Ti.Yay, Ar.Yaa], // ⵢ -> ي - [Ti.Yaz, Ar.Zay], // ⵣ -> ز - [Ti.TawellemetYaz, Ar.Zay], // ⵤ -> ز - [Ti.Yazz, Ar.Zay], // ⵥ -> ز - [Ti.Ye, Ar.Yaa], // ⵦ -> ي - [Ti.Yo, Ar.Waw], // ⵧ -> و - [Ti.ModifierLetterLabializationMark, ''], // ⵯ -> nothing - [Ti.SeparatorMark, ''], // ⵯ -> nothing - [Ti.ConsonantJoiner, ''], // ⵯ -> nothing - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - result += this.map.get(letter) ?? '' - } - return result - } -} diff --git a/packages/abjad-convert/src/ugaritic/toArabic.ts b/packages/abjad-convert/src/ugaritic/toArabic.ts deleted file mode 100644 index fbd10d9..0000000 --- a/packages/abjad-convert/src/ugaritic/toArabic.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Ug } from './letters' -import { Ar } from '../arabic/letters' -import { IConverter } from '../IConverter' -import { Abjad } from '../types' - -export class UgariticToArabicConverter implements IConverter { - public readonly from = Abjad.Ugaritic - public readonly to = Abjad.Arabic - - private map = new Map( - [ - [' ', ' '], - [Ug.Alpa, Ar.Alef], - [Ug.Beta, Ar.Ba], - [Ug.Gamla, Ar.Jeem], - [Ug.Kha, Ar.Khaa], - [Ug.Delta, Ar.Dal], - [Ug.Ho, Ar.Ha], - [Ug.Wo, Ar.Waw], - [Ug.Zeta, Ar.Zay], - - [Ug.Hota, Ar.H7aa], - [Ug.Tet, Ar.TTa], - [Ug.Yod, Ar.Yaa], - [Ug.Kaf, Ar.Kaf], - [Ug.Shin, Ar.Sheen], - [Ug.Lamda, Ar.Lam], - [Ug.Mem, Ar.Meem], - [Ug.Dhal, Ar.Dad], - - [Ug.Nun, Ar.Noon], - [Ug.Zu, Ar.Zay], - [Ug.Samka, Ar.Seen], - [Ug.Ain, Ar.Ayn], - [Ug.Pu, Ar.Fa], - [Ug.Sade, Ar.Sad], - [Ug.Qopa, Ar.Qaf], - [Ug.Rasha, Ar.Ra], - - [Ug.Thanna, Ar.THa], - [Ug.Ghain, Ar.Ghayn], - [Ug.To, Ar.Ta], - [Ug.I, Ar.AlefMaksura], - [Ug.U, Ar.Waw], - [Ug.Ssu, Ar.Sad], - ] - ) - - public convert(text: string): string { - let result = '' - for (const letter of text) { - result += this.map.get(letter) ?? '' - } - return result - } -} diff --git a/packages/abjad-convert/test/arabic/toPhoenician.test.ts b/packages/abjad-convert/test/arabic/toPhoenician.test.ts index 0eef85b..48d738b 100644 --- a/packages/abjad-convert/test/arabic/toPhoenician.test.ts +++ b/packages/abjad-convert/test/arabic/toPhoenician.test.ts @@ -1,4 +1,4 @@ -import { ArabicToPhoenicianConverter } from '../../src/arabic/toPhoenician' +import { ArabicToPhoenicianConverter } from '../../src/scripts/arabic/toPhoenician' import { describe, expect, it } from '@jest/globals' describe('ArabicToPhoenicianConverter', () => { diff --git a/packages/abjad-web/.eslintrc.js b/packages/abjad-web/.eslintrc.js new file mode 100644 index 0000000..edd24fe --- /dev/null +++ b/packages/abjad-web/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + ...require('../../.eslintrc.js'), + extends: [ + 'plugin:@next/next/recommended', + ], +} diff --git a/packages/abjad-web/CHANGELOG.md b/packages/abjad-web/CHANGELOG.md index 0d24dff..39b44f0 100644 --- a/packages/abjad-web/CHANGELOG.md +++ b/packages/abjad-web/CHANGELOG.md @@ -1,7 +1,13 @@ -# Changelog +# abjad-web Changelog +## [0.3.0] 2024-01-17 +### Added +- OnScreen Keyboard +## Changed +- use abjad-convert 0.3.0 + ## [0.2.0] 2024-01-16 ### Changed - style web page diff --git a/packages/abjad-web/README.md b/packages/abjad-web/README.md index 21c9f8c..66ae120 100644 --- a/packages/abjad-web/README.md +++ b/packages/abjad-web/README.md @@ -3,3 +3,5 @@ A simple web page for Abjad using Next.js. web: [abjad.amerharb.com]() + +![screen-shot.png](screen-shot.png) diff --git a/packages/abjad-web/package.json b/packages/abjad-web/package.json index c2da850..8e23e77 100644 --- a/packages/abjad-web/package.json +++ b/packages/abjad-web/package.json @@ -1,6 +1,6 @@ { "name": "abjad-web", - "version": "0.2.0", + "version": "0.3.0", "private": true, "scripts": { "dev": "next dev", diff --git a/packages/abjad-web/screen-shot.png b/packages/abjad-web/screen-shot.png new file mode 100644 index 0000000..923aebf Binary files /dev/null and b/packages/abjad-web/screen-shot.png differ diff --git a/packages/abjad-web/src/app/page.tsx b/packages/abjad-web/src/app/page.tsx index d6390e2..e68f0c1 100644 --- a/packages/abjad-web/src/app/page.tsx +++ b/packages/abjad-web/src/app/page.tsx @@ -2,7 +2,10 @@ import { useState } from 'react' import Select from 'react-select' +// temp +// import { Abjad, convert, getLetters } from 'abjad-convert' import { Abjad, convert } from 'abjad-convert' +import OnScreenKeyboard from '@/components/OnScreenKeyboard' export default function Home() { const [textBoxValue, setTextBoxValue] = useState('') @@ -56,18 +59,24 @@ export default function Home() { }} /> - const handleConvert = () => { - if (!fromValue || !toValue) { - return - } - const result = convert(textBoxValue, fromValue, toValue) - setResultText(result) - } return ( Abjad Converter {FromSelect()} + {/* // temp */} + {/* {*/} + {/* const newTextBoxValue = textBoxValue + letter*/} + {/* setTextBoxValue(newTextBoxValue)*/} + {/* if (!fromValue || !toValue) {*/} + {/* return*/} + {/* }*/} + {/* const result = convert(newTextBoxValue, fromValue, toValue)*/} + {/* setResultText(result)*/} + {/* }}*/} + {/*/>*/} {ToSelect()} Enter Text: diff --git a/packages/abjad-web/src/components/OnScreenKeyboard.tsx b/packages/abjad-web/src/components/OnScreenKeyboard.tsx new file mode 100644 index 0000000..7bc1a7d --- /dev/null +++ b/packages/abjad-web/src/components/OnScreenKeyboard.tsx @@ -0,0 +1,14 @@ +import { FC } from 'react' + +type Props = { + letters: readonly string[]; + onClick: (letter: string) => void; +}; + +const OnScreenKeyboard: FC = ({ letters, onClick }) => { + return + {letters.map((letter) => onClick(letter)}>{letter})} + +} + +export default OnScreenKeyboard