diff --git a/packages/abjad-client/package.json b/packages/abjad-client/package.json
index 43a0306..a9c2deb 100644
--- a/packages/abjad-client/package.json
+++ b/packages/abjad-client/package.json
@@ -1,7 +1,7 @@
{
"name": "abjad-client",
"private": true,
- "version": "0.0.2",
+ "version": "0.0.3",
"main": "dist/index.js",
"scripts": {
"prebuild": "rm -rf dist",
@@ -13,6 +13,6 @@
"lint:fix": "npx eslint . --fix"
},
"dependencies": {
- "abjad-convert": "^0.1.0-next.0"
+ "abjad-convert": "0.2.0-next.0"
}
}
diff --git a/packages/abjad-client/src/index.ts b/packages/abjad-client/src/index.ts
index bcd718b..118b34d 100644
--- a/packages/abjad-client/src/index.ts
+++ b/packages/abjad-client/src/index.ts
@@ -32,9 +32,10 @@ log(calmConvert(ugaritic, Abjad.Ugaritic, Abjad.Arabic))
log(`convert Ugaritic text ${ugaritic} to Phoenician`)
log(calmConvert(ugaritic, Abjad.Ugaritic, Abjad.Phoenician))
-log(calmConvert('مرحبا', Abjad.Arabic, Abjad.Phoenician))
log(calmConvert('مرحبا', Abjad.Arabic, Abjad.ImperialAramaic))
+log(calmConvert('مرحبا', Abjad.Arabic, Abjad.Phoenician))
log(calmConvert('مرحبا', Abjad.Arabic, Abjad.Syriac))
+log(calmConvert('مرحبا', Abjad.Arabic, Abjad.Tifinagh))
log(calmConvert('مرحبا', Abjad.Arabic, Abjad.Ugaritic))
log('Done')
diff --git a/packages/abjad-convert/CHANGELOG.md b/packages/abjad-convert/CHANGELOG.md
index 78b6669..768373c 100644
--- a/packages/abjad-convert/CHANGELOG.md
+++ b/packages/abjad-convert/CHANGELOG.md
@@ -1,6 +1,10 @@
# Changelog
+## [0.2.0] 2024-01-10
+### Added
+- Support Tifinagh
+
## [0.1.0] 2024-01-06
### Added
- Support Syriac
diff --git a/packages/abjad-convert/README.md b/packages/abjad-convert/README.md
index e533464..a41060c 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.1.0-blue.svg)](https://github.com/amerharb/abjad/tree/version/0.1.0)
+[![Version](https://img.shields.io/badge/version-0.2.0-blue.svg)](https://github.com/amerharb/abjad/tree/version/0.2.0)
[![License: GPLv3](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
-![Coverage](https://raw.githubusercontent.com/amerharb/abjad/version/0.1.0/packages/abjad-convert/badges/coverage.svg)
-![Github workflow](https://github.com/amerharb/abjad/actions/workflows/lint-test.yaml/badge.svg?branch=version/0.1.0)
+![Coverage](https://raw.githubusercontent.com/amerharb/abjad/version/0.2.0/packages/abjad-convert/badges/coverage.svg)
+![Github workflow](https://github.com/amerharb/abjad/actions/workflows/lint-test.yaml/badge.svg?branch=version/0.2.0)
**abjad-convert** is a package for converting Abjad alphabets phonetically.
@@ -11,6 +11,7 @@ current supported alphabets:
- Imperial Aramaic
- Phoenician
- Syriac
+- Tifinagh
- Uguritic
## How to use
@@ -29,15 +30,121 @@ import { convert, Abjad } from 'abjad-convert';
const arabicWord = 'مرحبا';
+const imperialAramaicWord = convert(arabicWord, Abjad.Arabic, Abjad.ImperialAramaic);
+console.log(imperialAramaicWord); // 𐡌𐡓𐡇𐡁𐡀
+
const phoenicianWord = convert(arabicWord, Abjad.Arabic, Abjad.Phoenician);
console.log(phoenicianWord); // 𐤌𐤓𐤇𐤁𐤀
+const syriacWord = convert(arabicWord, Abjad.Arabic, Abjad.Syriac);
+console.log(syriacWord); // ܡܪܚܒܐ
+
+const tifinaghWord = convert(arabicWord, Abjad.Arabic, Abjad.Tifinagh);
+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:
-const imperialAramaicWord = convert(arabicWord, Abjad.Arabic, Abjad.ImperialAramaic);
-console.log(imperialAramaicWord); // 𐡌𐡓𐡇𐡁𐡀
+```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.
-const syriacWord = convert(arabicWord, Abjad.Arabic, Abjad.Syriac);
-console.log(syriacWord); // ܡܪܚܒܐ
+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 8d58334..f2daea8 100644
--- a/packages/abjad-convert/badges/coverage.svg
+++ b/packages/abjad-convert/badges/coverage.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/packages/abjad-convert/package.json b/packages/abjad-convert/package.json
index 02a09c9..1131b06 100644
--- a/packages/abjad-convert/package.json
+++ b/packages/abjad-convert/package.json
@@ -1,6 +1,6 @@
{
"name": "abjad-convert",
- "version": "0.1.0",
+ "version": "0.2.0",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"files": [
@@ -10,8 +10,13 @@
"CHANGELOG.md",
"README.md"
],
- "repository": "git@github.com:amerharb/abjad.git",
"author": "Amer Harb",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/amerharb/abjad.git"
+ },
+ "homepage": "https://github.com/amerharb/abjad#readme",
+ "url": "https://github.com/amerharb/abjad/issues",
"email": "abjad@amerharb.com",
"keywords": [
"abjad",
diff --git a/packages/abjad-convert/src/arabic/toTifinagh.ts b/packages/abjad-convert/src/arabic/toTifinagh.ts
new file mode 100644
index 0000000..1edd934
--- /dev/null
+++ b/packages/abjad-convert/src/arabic/toTifinagh.ts
@@ -0,0 +1,59 @@
+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/ConverterFactory.ts b/packages/abjad-convert/src/converterFactory.ts
similarity index 92%
rename from packages/abjad-convert/src/ConverterFactory.ts
rename to packages/abjad-convert/src/converterFactory.ts
index fa9dc0b..6f32467 100644
--- a/packages/abjad-convert/src/ConverterFactory.ts
+++ b/packages/abjad-convert/src/converterFactory.ts
@@ -3,6 +3,7 @@ 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 { ImperialAramaicToPhoenicianConverter } from './imperialAramaic/toPhoenician'
@@ -11,6 +12,7 @@ import { PhoenicianToArabicConverter } from './phoenician/toArabic'
import { PhoenicianToImperialAramaicConverter } from './phoenician/toImperialAramaic'
import { PhoenicianToUgariticConverter } from './phoenician/toUgaritic'
import { SyriacToArabicConverter } from './syriac/toArabic'
+import { TifinaghToArabicConverter } from './tifinagh/toArabic'
import { UgariticToArabicConverter } from './ugaritic/toArabic'
import { UgariticToImperialAramaicConverter } from './ugaritic/toImperialAramaic'
import { UgariticToPhoenicianConverter } from './ugaritic/toPhoenician'
@@ -19,6 +21,7 @@ const converters: IConverter[] = [
new ArabicToImperialAramaicConverter(),
new ArabicToPhoenicianConverter(),
new ArabicToSyriacConverter(),
+ new ArabicToTifinaghConverter(),
new ArabicToUgariticConverter(),
new ImperialAramaicToArabicConverter(),
new ImperialAramaicToPhoenicianConverter(),
@@ -27,6 +30,7 @@ const converters: IConverter[] = [
new PhoenicianToImperialAramaicConverter(),
new PhoenicianToUgariticConverter(),
new SyriacToArabicConverter(),
+ new TifinaghToArabicConverter(),
new UgariticToArabicConverter(),
new UgariticToImperialAramaicConverter(),
new UgariticToPhoenicianConverter(),
diff --git a/packages/abjad-convert/src/index.ts b/packages/abjad-convert/src/index.ts
index 2552b11..8e79319 100644
--- a/packages/abjad-convert/src/index.ts
+++ b/packages/abjad-convert/src/index.ts
@@ -1,4 +1,4 @@
-import { getConverter } from './ConverterFactory'
+import { getConverter } from './converterFactory'
import { Abjad } from './types'
export function convert(source: string, from: Abjad, to: Abjad): string {
diff --git a/packages/abjad-convert/src/phoenician/letters.ts b/packages/abjad-convert/src/phoenician/letters.ts
index ff2ade6..97b8c33 100644
--- a/packages/abjad-convert/src/phoenician/letters.ts
+++ b/packages/abjad-convert/src/phoenician/letters.ts
@@ -41,7 +41,6 @@ export const Ph = {
Waw: letters[5], // 𐤅
Zayin: letters[6], // 𐤆
Het: letters[7], // 𐤇
-
Tet: letters[8], // 𐤈
Yod: letters[9], // 𐤉
Kap: letters[10], // 𐤊
@@ -50,20 +49,17 @@ export const Ph = {
Nun: letters[13], // 𐤍
Semk: letters[14], // 𐤎
Ain: letters[15], // 𐤏
-
Pe: letters[16], // 𐤐
Sade: letters[17], // 𐤑
Qof: letters[18], // 𐤒
Ros: letters[19], // 𐤓
Shin: letters[20], // 𐤔
Tau: letters[21], // 𐤕
-
One: letters[22], // 𐤖
Ten: letters[23], // 𐤗
Twenty: letters[24], // 𐤘
OneHundred: letters[25], // 𐤙
Two: letters[26], // 𐤚
Three: letters[27], // 𐤛
-
WordSeparator: letters[28], // 𐤟
}
diff --git a/packages/abjad-convert/src/tifinagh/U2D30.pdf b/packages/abjad-convert/src/tifinagh/U2D30.pdf
new file mode 100644
index 0000000..51f6afa
Binary files /dev/null and b/packages/abjad-convert/src/tifinagh/U2D30.pdf differ
diff --git a/packages/abjad-convert/src/tifinagh/letters.ts b/packages/abjad-convert/src/tifinagh/letters.ts
new file mode 100644
index 0000000..71e88ec
--- /dev/null
+++ b/packages/abjad-convert/src/tifinagh/letters.ts
@@ -0,0 +1,123 @@
+export const letters = [
+ '\u2d30', /** #0 ⴰ U+2D30 TIFINAGH LETTER YA */
+ '\u2d31', /** #1 ⴱ U+2D31 TIFINAGH LETTER YAB */
+ '\u2d32', /** #2 ⴲ U+2D32 TIFINAGH LETTER YABH */
+ '\u2d33', /** #3 ⴳ U+2D33 TIFINAGH LETTER YAG */
+ '\u2d34', /** #4 ⴴ U+2D34 TIFINAGH LETTER YAGHH */
+ '\u2d35', /** #5 ⴵ U+2D35 TIFINAGH LETTER BERBER ACADEMY YAJ */
+ '\u2d36', /** #6 ⴶ U+2D36 TIFINAGH LETTER YAJ */
+ '\u2d37', /** #7 ⴷ U+2D37 TIFINAGH LETTER YAD */
+ '\u2d38', /** #8 ⴸ U+2D38 TIFINAGH LETTER YADH */
+ '\u2d39', /** #9 ⴹ U+2D39 TIFINAGH LETTER YADD */
+ '\u2d3a', /** #10 ⴺ U+2D3A TIFINAGH LETTER YADDH */
+ '\u2d3b', /** #11 ⴻ U+2D3B TIFINAGH LETTER YEY */
+ '\u2d3c', /** #12 ⴼ U+2D3C TIFINAGH LETTER YAF */
+ '\u2d3d', /** #13 ⴽ U+2D3D TIFINAGH LETTER YAK */
+ '\u2d3e', /** #14 ⴾ U+2D3E TIFINAGH LETTER TUAREG YAK */
+ '\u2d3f', /** #15 ⴿ U+2D3F TIFINAGH LETTER YAKHH */
+ '\u2d40', /** #16 ⵀ U+2D40 TIFINAGH LETTER YAH */
+ '\u2d41', /** #17 ⵁ U+2D41 TIFINAGH LETTER BERBER ACADEMY YAH */
+ '\u2d42', /** #18 ⵂ U+2D42 TIFINAGH LETTER TUAREG YAH */
+ '\u2d43', /** #19 ⵃ U+2D43 TIFINAGH LETTER YAHH */
+ '\u2d44', /** #20 ⵄ U+2D44 TIFINAGH LETTER YAA */
+ '\u2d45', /** #21 ⵅ U+2D45 TIFINAGH LETTER YAKH */
+ '\u2d46', /** #22 ⵆ U+2D46 TIFINAGH LETTER TUAREG YAKH */
+ '\u2d47', /** #23 ⵇ U+2D47 TIFINAGH LETTER YAQ */
+ '\u2d48', /** #24 ⵈ U+2D48 TIFINAGH LETTER TUAREG YAQ */
+ '\u2d49', /** #25 ⵉ U+2D49 TIFINAGH LETTER YI */
+ '\u2d4a', /** #26 ⵊ U+2D4A TIFINAGH LETTER YAZH */
+ '\u2d4b', /** #27 ⵋ U+2D4B TIFINAGH LETTER AHAGGAR YAZH */
+ '\u2d4c', /** #28 ⵌ U+2D4C TIFINAGH LETTER TUAREG YAZH */
+ '\u2d4d', /** #29 ⵍ U+2D4D TIFINAGH LETTER YAL */
+ '\u2d4e', /** #30 ⵎ U+2D4E TIFINAGH LETTER YAM */
+ '\u2d4f', /** #31 ⵏ U+2D4F TIFINAGH LETTER YAN */
+ '\u2d50', /** #32 ⵐ U+2D50 TIFINAGH LETTER TUAREG YAGN */
+ '\u2d51', /** #33 ⵑ U+2D51 TIFINAGH LETTER TUAREG YANG */
+ '\u2d52', /** #34 ⵒ U+2D52 TIFINAGH LETTER YAP */
+ '\u2d53', /** #35 ⵓ U+2D53 TIFINAGH LETTER YU */
+ '\u2d54', /** #36 ⵔ U+2D54 TIFINAGH LETTER YAR */
+ '\u2d55', /** #37 ⵕ U+2D55 TIFINAGH LETTER YARR */
+ '\u2d56', /** #38 ⵖ U+2D56 TIFINAGH LETTER YAGH */
+ '\u2d57', /** #39 ⵗ U+2D57 TIFINAGH LETTER TUAREG YAGH */
+ '\u2d58', /** #40 ⵘ U+2D58 TIFINAGH LETTER AYER YAGH */
+ '\u2d59', /** #41 ⵙ U+2D59 TIFINAGH LETTER YAS */
+ '\u2d5a', /** #42 ⵚ U+2D5A TIFINAGH LETTER YASS */
+ '\u2d5b', /** #43 ⵛ U+2D5B TIFINAGH LETTER YASH */
+ '\u2d5c', /** #44 ⵜ U+2D5C TIFINAGH LETTER YAT */
+ '\u2d5d', /** #45 ⵝ U+2D5D TIFINAGH LETTER YATH */
+ '\u2d5e', /** #46 ⵞ U+2D5E TIFINAGH LETTER YACH */
+ '\u2d5f', /** #47 ⵟ U+2D5F TIFINAGH LETTER YATT */
+ '\u2d60', /** #48 ⵠ U+2D60 TIFINAGH LETTER YAV */
+ '\u2d61', /** #49 ⵡ U+2D61 TIFINAGH LETTER YAW */
+ '\u2d62', /** #50 ⵢ U+2D62 TIFINAGH LETTER YAY */
+ '\u2d63', /** #51 ⵣ U+2D63 TIFINAGH LETTER YAZ */
+ '\u2d64', /** #52 ⵤ U+2D64 TIFINAGH LETTER TAWELLEMET YAZ */
+ '\u2d65', /** #53 ⵥ U+2D65 TIFINAGH LETTER YAZZ */
+ '\u2d66', /** #54 ⵦ U+2D66 TIFINAGH LETTER YE */
+ '\u2d67', /** #55 ⵧ U+2D67 TIFINAGH LETTER YO */
+ '\u2d6f', /** #56 ⵯ U+2D6F TIFINAGH MODIFIER LETTER LABIALIZATION MARK */
+ '\u2d70', /** #54 ⵯ U+2D70 TIFINAGH SEPARATOR MARK */
+ '\u2d7f', /** #55 ⵯ U+2D7F TIFINAGH CONSONANT JOINER */
+]
+
+export const Ti = {
+ Ya: letters[0], // ⴰ
+ Yab: letters[1], // ⴱ
+ Yabh: letters[2], // ⴲ
+ Yag: letters[3], // ⴳ
+ Yaghh: letters[4], // ⴴ
+ BerberAcademyYaj: letters[5], // ⴵ
+ Yaj: letters[6], // ⴶ
+ Yad: letters[7], // ⴷ
+ Yadh: letters[8], // ⴸ
+ Yadd: letters[9], // ⴹ
+ Yaddh: letters[10], // ⴺ
+ Yey: letters[11], // ⴻ
+ Yaf: letters[12], // ⴼ
+ Yak: letters[13], // ⴽ
+ TuaregYak: letters[14], // ⴾ
+ Yakhh: letters[15], // ⴿ
+ Yah: letters[16], // ⵀ
+ BerberAcademyYah: letters[17], // ⵁ
+ TuaregYah: letters[18], // ⵂ
+ Yahh: letters[19], // ⵃ
+ Yaa: letters[20], // ⵄ
+ Yakh: letters[21], // ⵅ
+ TuaregYakh: letters[22], // ⵆ
+ Yaq: letters[23], // ⵇ
+ TuaregYaq: letters[24], // ⵈ
+ Yi: letters[25], // ⵉ
+ Yazh: letters[26], // ⵊ
+ AhaggarYazh: letters[27], // ⵋ
+ TuaregYazh: letters[28], // ⵌ
+ Yal: letters[29], // ⵍ
+ Yam: letters[30], // ⵎ
+ Yan: letters[31], // ⵏ
+ TuaregYagn: letters[32], // ⵐ
+ TuaregYang: letters[33], // ⵑ
+ Yap: letters[34], // ⵒ
+ Yu: letters[35], // ⵓ
+ Yar: letters[36], // ⵔ
+ Yarr: letters[37], // ⵕ
+ Yagh: letters[38], // ⵖ
+ TuaregYagh: letters[39], // ⵗ
+ AyerYagh: letters[40], // ⵘ
+ Yas: letters[41], // ⵙ
+ Yass: letters[42], // ⵚ
+ Yash: letters[43], // ⵛ
+ Yat: letters[44], // ⵜ
+ Yath: letters[45], // ⵝ
+ Yach: letters[46], // ⵞ
+ Yatt: letters[47], // ⵟ
+ Yav: letters[48], // ⵠ
+ Yaw: letters[49], // ⵡ
+ Yay: letters[50], // ⵢ
+ Yaz: letters[51], // ⵣ
+ TawellemetYaz: letters[52], // ⵤ
+ Yazz: letters[53], // ⵥ
+ Ye: letters[54], // ⵦ
+ Yo: letters[55], // ⵧ
+ ModifierLetterLabializationMark: letters[56], // ⵯ
+ SeparatorMark: letters[57], // ⵯ
+ ConsonantJoiner: letters[58], // ⵯ
+}
diff --git a/packages/abjad-convert/src/tifinagh/toArabic.ts b/packages/abjad-convert/src/tifinagh/toArabic.ts
new file mode 100644
index 0000000..99190ce
--- /dev/null
+++ b/packages/abjad-convert/src/tifinagh/toArabic.ts
@@ -0,0 +1,80 @@
+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/types.ts b/packages/abjad-convert/src/types.ts
index 8b24d15..dd083ba 100644
--- a/packages/abjad-convert/src/types.ts
+++ b/packages/abjad-convert/src/types.ts
@@ -3,5 +3,6 @@ export enum Abjad {
ImperialAramaic = 'imperial-aramaic',
Phoenician = 'phoenician',
Syriac = 'syriac',
+ Tifinagh = 'tifinagh',
Ugaritic = 'ugaritic',
}
diff --git a/packages/abjad-convert/src/ugaritic/letters.ts b/packages/abjad-convert/src/ugaritic/letters.ts
index d564d32..dd940cb 100644
--- a/packages/abjad-convert/src/ugaritic/letters.ts
+++ b/packages/abjad-convert/src/ugaritic/letters.ts
@@ -1,65 +1,65 @@
export const letters = [
- '\uD800\uDF80', // 𐎀 U+10380 UGARITIC LETTER ALPA
- '\uD800\uDF81', // 𐎁 U+10381 UGARITIC LETTER BETA
- '\uD800\uDF82', // 𐎂 U+10382 UGARITIC LETTER GAMLA
- '\uD800\uDF83', // 𐎃 U+10383 UGARITIC LETTER KHA
- '\uD800\uDF84', // 𐎄 U+10384 UGARITIC LETTER DELTA
- '\uD800\uDF85', // 𐎅 U+10385 UGARITIC LETTER HO
- '\uD800\uDF86', // 𐎆 U+10386 UGARITIC LETTER WO
- '\uD800\uDF87', // 𐎇 U+10387 UGARITIC LETTER ZETA
- '\uD800\uDF88', // 𐎈 U+10388 UGARITIC LETTER HOTA
- '\uD800\uDF89', // 𐎉 U+10389 UGARITIC LETTER TET
- '\uD800\uDF8A', // 𐎊 U+1038A UGARITIC LETTER YOD
- '\uD800\uDF8B', // 𐎋 U+1038B UGARITIC LETTER KAF
- '\uD800\uDF8C', // 𐎌 U+1038C UGARITIC LETTER SHIN
- '\uD800\uDF8D', // 𐎍 U+1038D UGARITIC LETTER LAMDA
- '\uD800\uDF8E', // 𐎎 U+1038E UGARITIC LETTER MEM
- '\uD800\uDF8F', // 𐎏 U+1038F UGARITIC LETTER DHAL
- '\uD800\uDF90', // 𐎐 U+10390 UGARITIC LETTER NUN
- '\uD800\uDF91', // 𐎑 U+10391 UGARITIC LETTER ZU
- '\uD800\uDF92', // 𐎒 U+10392 UGARITIC LETTER SAMKA
- '\uD800\uDF93', // 𐎓 U+10393 UGARITIC LETTER AIN
- '\uD800\uDF94', // 𐎔 U+10394 UGARITIC LETTER PU
- '\uD800\uDF95', // 𐎕 U+10395 UGARITIC LETTER SADE
- '\uD800\uDF96', // 𐎖 U+10396 UGARITIC LETTER QOPA
- '\uD800\uDF97', // 𐎗 U+10397 UGARITIC LETTER RASHA
- '\uD800\uDF98', // 𐎘 U+10398 UGARITIC LETTER THANNA
- '\uD800\uDF99', // 𐎙 U+10399 UGARITIC LETTER GHAIN
- '\uD800\uDF9A', // 𐎚 U+1039A UGARITIC LETTER TO
- '\uD800\uDF9B', // 𐎛 U+1039B UGARITIC LETTER I
- '\uD800\uDF9C', // 𐎜 U+1039C UGARITIC LETTER U
- '\uD800\uDF9D', // 𐎝 U+1039D UGARITIC LETTER SSU
+ '\uD800\uDF80', /** #0 𐎀 U+10380 UGARITIC LETTER ALPA */
+ '\uD800\uDF81', /** #1 𐎁 U+10381 UGARITIC LETTER BETA */
+ '\uD800\uDF82', /** #2 𐎂 U+10382 UGARITIC LETTER GAMLA */
+ '\uD800\uDF83', /** #3 𐎃 U+10383 UGARITIC LETTER KHA */
+ '\uD800\uDF84', /** #4 𐎄 U+10384 UGARITIC LETTER DELTA */
+ '\uD800\uDF85', /** #5 𐎅 U+10385 UGARITIC LETTER HO */
+ '\uD800\uDF86', /** #6 𐎆 U+10386 UGARITIC LETTER WO */
+ '\uD800\uDF87', /** #7 𐎇 U+10387 UGARITIC LETTER ZETA */
+ '\uD800\uDF88', /** #8 𐎈 U+10388 UGARITIC LETTER HOTA */
+ '\uD800\uDF89', /** #9 𐎉 U+10389 UGARITIC LETTER TET */
+ '\uD800\uDF8A', /** #10 𐎊 U+1038A UGARITIC LETTER YOD */
+ '\uD800\uDF8B', /** #11 𐎋 U+1038B UGARITIC LETTER KAF */
+ '\uD800\uDF8C', /** #12 𐎌 U+1038C UGARITIC LETTER SHIN */
+ '\uD800\uDF8D', /** #13 𐎍 U+1038D UGARITIC LETTER LAMDA */
+ '\uD800\uDF8E', /** #14 𐎎 U+1038E UGARITIC LETTER MEM */
+ '\uD800\uDF8F', /** #15 𐎏 U+1038F UGARITIC LETTER DHAL */
+ '\uD800\uDF90', /** #16 𐎐 U+10390 UGARITIC LETTER NUN */
+ '\uD800\uDF91', /** #17 𐎑 U+10391 UGARITIC LETTER ZU */
+ '\uD800\uDF92', /** #18 𐎒 U+10392 UGARITIC LETTER SAMKA */
+ '\uD800\uDF93', /** #19 𐎓 U+10393 UGARITIC LETTER AIN */
+ '\uD800\uDF94', /** #20 𐎔 U+10394 UGARITIC LETTER PU */
+ '\uD800\uDF95', /** #21 𐎕 U+10395 UGARITIC LETTER SADE */
+ '\uD800\uDF96', /** #22 𐎖 U+10396 UGARITIC LETTER QOPA */
+ '\uD800\uDF97', /** #23 𐎗 U+10397 UGARITIC LETTER RASHA */
+ '\uD800\uDF98', /** #24 𐎘 U+10398 UGARITIC LETTER THANNA */
+ '\uD800\uDF99', /** #25 𐎙 U+10399 UGARITIC LETTER GHAIN */
+ '\uD800\uDF9A', /** #26 𐎚 U+1039A UGARITIC LETTER TO */
+ '\uD800\uDF9B', /** #27 𐎛 U+1039B UGARITIC LETTER I */
+ '\uD800\uDF9C', /** #28 𐎜 U+1039C UGARITIC LETTER U */
+ '\uD800\uDF9D', /** #29 𐎝 U+1039D UGARITIC LETTER SSU */
]
export const Ug = {
- Alpa: '\uD800\uDF80',
- Beta: '\uD800\uDF81',
- Gamla: '\uD800\uDF82',
- Kha: '\uD800\uDF83',
- Delta: '\uD800\uDF84',
- Ho: '\uD800\uDF85',
- Wo: '\uD800\uDF86',
- Zeta: '\uD800\uDF87',
- Hota: '\uD800\uDF88',
- Tet: '\uD800\uDF89',
- Yod: '\uD800\uDF8A',
- Kaf: '\uD800\uDF8B',
- Shin: '\uD800\uDF8C',
- Lamda: '\uD800\uDF8D',
- Mem: '\uD800\uDF8E',
- Dhal: '\uD800\uDF8F',
- Nun: '\uD800\uDF90',
- Zu: '\uD800\uDF91',
- Samka: '\uD800\uDF92',
- Ain: '\uD800\uDF93',
- Pu: '\uD800\uDF94',
- Sade: '\uD800\uDF95',
- Qopa: '\uD800\uDF96',
- Rasha: '\uD800\uDF97',
- Thanna: '\uD800\uDF98',
- Ghain: '\uD800\uDF99',
- To: '\uD800\uDF9A',
- I: '\uD800\uDF9B',
- U: '\uD800\uDF9C',
- Ssu: '\uD800\uDF9D',
+ Alpa: letters[0], // 𐎀
+ Beta: letters[1], // 𐎁
+ Gamla: letters[2], // 𐎂
+ Kha: letters[3], // 𐎃
+ Delta: letters[4], // 𐎄
+ Ho: letters[5], // 𐎅
+ Wo: letters[6], // 𐎆
+ Zeta: letters[7], // 𐎇
+ Hota: letters[8], // 𐎈
+ Tet: letters[9], // 𐎉
+ Yod: letters[10], // 𐎊
+ Kaf: letters[11], // 𐎋
+ Shin: letters[12], // 𐎌
+ Lamda: letters[13], // 𐎍
+ Mem: letters[14], // 𐎎
+ Dhal: letters[15], // 𐎏
+ Nun: letters[16], // 𐎐
+ Zu: letters[17], // 𐎑
+ Samka: letters[18], // 𐎒
+ Ain: letters[19], // 𐎓
+ Pu: letters[20], // 𐎔
+ Sade: letters[21], // 𐎕
+ Qopa: letters[22], // 𐎖
+ Rasha: letters[23], // 𐎗
+ Thanna: letters[24], // 𐎘
+ Ghain: letters[25], // 𐎙
+ To: letters[26], // 𐎚
+ I: letters[27], // 𐎛
+ U: letters[28], // 𐎜
+ Ssu: letters[29], // 𐎝
}
diff --git a/packages/abjad-convert/test/index.test.ts b/packages/abjad-convert/test/index.test.ts
index 022abf0..9ba2886 100644
--- a/packages/abjad-convert/test/index.test.ts
+++ b/packages/abjad-convert/test/index.test.ts
@@ -21,6 +21,12 @@ describe('convert()', () => {
expect(actual).toEqual('ܐ ܒ ܓ')
})
})
+ describe('to Tifinagh', () => {
+ it('convert ا ب ج into ⴰ ⴱ ⵊ', () => {
+ const actual = convert('ا ب ج', Abjad.Arabic, Abjad.Tifinagh)
+ expect(actual).toEqual('ⴰ ⴱ ⵊ')
+ })
+ })
describe('to Ugaritic', () => {
it('convert ا ب ج into 𐎀 𐎁 𐎂', () => {
const actual = convert('ا ب ج', Abjad.Arabic, Abjad.Ugaritic)
@@ -47,6 +53,12 @@ describe('convert()', () => {
expect(actual).toEqual('ܐ ܒ ܓ')
})
})
+ describe('to Tifinagh', () => {
+ it('convert 𐡀 𐡁 𐡂 into ⴰ ⴱ ⵊ', () => {
+ const actual = convert('𐡀 𐡁 𐡂', Abjad.ImperialAramaic, Abjad.Tifinagh)
+ expect(actual).toEqual('ⴰ ⴱ ⵊ')
+ })
+ })
describe('to Ugaritic', () => {
it('convert 𐡀 𐡁 𐡂 into 𐎀 𐎁 𐎂', () => {
const actual = convert('𐡀 𐡁 𐡂', Abjad.ImperialAramaic, Abjad.Ugaritic)
@@ -73,6 +85,12 @@ describe('convert()', () => {
expect(actual).toEqual('ܐ ܒ ܓ')
})
})
+ describe('to Tifinagh', () => {
+ it('convert 𐤀𐤟𐤁𐤟𐤂 into ⴰ ⴱ ⵊ', () => {
+ const actual = convert('𐤀𐤟𐤁𐤟𐤂', Abjad.Phoenician, Abjad.Tifinagh)
+ expect(actual).toEqual('ⴰ ⴱ ⵊ')
+ })
+ })
describe('to Ugaritic', () => {
it('convert 𐤀𐤟𐤁𐤟𐤂 into 𐎀𐎁𐎂', () => {
const actual = convert('𐤀𐤟𐤁𐤟𐤂', Abjad.Phoenician, Abjad.Ugaritic)
@@ -99,6 +117,12 @@ describe('convert()', () => {
expect(actual).toEqual('𐤀𐤟𐤁𐤟𐤂')
})
})
+ describe('to Tifinagh', () => {
+ it('convert ܐ ܒ ܓ into ⴰ ⴱ ⵊ', () => {
+ const actual = convert('ܐ ܒ ܓ', Abjad.Syriac, Abjad.Tifinagh)
+ expect(actual).toEqual('ⴰ ⴱ ⵊ')
+ })
+ })
describe('to Ugaritic', () => {
it('convert ܐ ܒ ܓ into 𐎀 𐎁 𐎂', () => {
const actual = convert('ܐ ܒ ܓ', Abjad.Syriac, Abjad.Ugaritic)
@@ -106,6 +130,38 @@ describe('convert()', () => {
})
})
})
+ describe('from Tifinagh', () => {
+ describe('to Arabic', () => {
+ it('convert ⴰ ⴱ ⵊ into ا ب ج', () => {
+ const actual = convert('ⴰ ⴱ ⵊ', Abjad.Tifinagh, Abjad.Arabic)
+ expect(actual).toEqual('ا ب ج')
+ })
+ })
+ describe('to ImperialAramaic', () => {
+ it('convert ⴰ ⴱ ⵊ into 𐡀 𐡁 𐡂', () => {
+ const actual = convert('ⴰ ⴱ ⵊ', Abjad.Tifinagh, Abjad.ImperialAramaic)
+ expect(actual).toEqual('𐡀 𐡁 𐡂')
+ })
+ })
+ describe('to Phoenician', () => {
+ it('convert ⴰ ⴱ ⵊ into 𐤀𐤟𐤁𐤟𐤂', () => {
+ const actual = convert('ⴰ ⴱ ⵊ', Abjad.Tifinagh, Abjad.Phoenician)
+ expect(actual).toEqual('𐤀𐤟𐤁𐤟𐤂')
+ })
+ })
+ describe('to Syriac', () => {
+ it('convert ⴰ ⴱ ⵊ into ܐ ܒ ܓ', () => {
+ const actual = convert('ⴰ ⴱ ⵊ', Abjad.Tifinagh, Abjad.Syriac)
+ expect(actual).toEqual('ܐ ܒ ܓ')
+ })
+ })
+ describe('to Ugaritic', () => {
+ it('convert ⴰ ⴱ ⵊ into 𐎀 𐎁 𐎂', () => {
+ const actual = convert('ⴰ ⴱ ⵊ', Abjad.Tifinagh, Abjad.Ugaritic)
+ expect(actual).toEqual('𐎀 𐎁 𐎂')
+ })
+ })
+ })
describe('from Ugaritic', () => {
describe('to Arabic', () => {
it('convert 𐎀 𐎁 𐎂 into ا ب ج', () => {
@@ -131,5 +187,11 @@ describe('convert()', () => {
expect(actual).toEqual('ܐ ܒ ܓ')
})
})
+ describe('to Tifinagh', () => {
+ it('convert 𐎀 𐎁 𐎂 into ⴰ ⴱ ⵊ', () => {
+ const actual = convert('𐎀 𐎁 𐎂', Abjad.Ugaritic, Abjad.Tifinagh)
+ expect(actual).toEqual('ⴰ ⴱ ⵊ')
+ })
+ })
})
})