diff --git a/.terserrc b/.terserrc
new file mode 100644
index 0000000..9cbf56d
--- /dev/null
+++ b/.terserrc
@@ -0,0 +1,7 @@
+{
+ "mangle": {
+ "properties": {
+ "regex": "^CAPITAL|^SMALL|^PUNCT|^DIA"
+ }
+ }
+}
diff --git a/README.md b/README.md
index 153f24f..032e3f4 100644
--- a/README.md
+++ b/README.md
@@ -82,9 +82,9 @@ fromType: KeyType,
settings: Preset | MixedPreset | IConversionOptions = {}
```
-The **`fromType`** parameter can be set to `BETA_CODE | GREEK | TRANSLITERATION` (e.g. `KeyType.GREEK`).
+**`fromType`** can be set to `BETA_CODE | TLG_BETA_CODE | GREEK | TRANSLITERATION` (e.g. `KeyType.GREEK`).
-The **`settings`** parameter can be filled with:
+**`settings`** can be filled with:
1. a `Preset`;
2. a user-defined `IConversionOptions` object;
3. a preset mixed with user-defined conversion options (`[Preset, IConversionOptions]`).
@@ -98,6 +98,7 @@ The available presets are:
| Preset | Description |
| ------ | ----------- |
| [**`MODERN_BC`**](https://github.com/antoineboquet/greek-conversion/wiki#Modern-beta-code) | `greek-conversion`'s own modernized style |
+| [**`TLG`**](https://github.com/antoineboquet/greek-conversion/wiki#TLG) | Thesaurus Linguae Graecae |
2. **For transliteration:**
@@ -105,35 +106,48 @@ The available presets are:
| ------ | ----------- |
| [**`ALA_LC`**](https://github.com/antoineboquet/greek-conversion/wiki#ALA-LC) | American Library Association – Library of Congress |
| [**`BNF`**](https://github.com/antoineboquet/greek-conversion/wiki#BNF) | Bibliothèque nationale de France |
+| [**`ISO`**](https://github.com/antoineboquet/greek-conversion/wiki#iso-843-1997) | ISO 843 (1997) — type 1 (transliteration) |
| [**`SBL`**](https://github.com/antoineboquet/greek-conversion/wiki#SBL) | Society of Biblical Literature |
### Conversion options
The **`IConversionOptions`** interface provides the following controls over the conversion process:
+
```ts
-removeDiacritics?: boolean, // remove diacritics, except those that represent letters
+removeDiacritics?: boolean, // remove diacritics, except those that represent letters
+
+removeExtraWhitespace?: boolean, // remove potential extra whitespace
-removeExtraWhitespace?: boolean, // remove potential extra whitespace
+betaCodeStyle?: {
+ useTLGStyle?: boolean // use the Thesaurus Linguae Graecae style. e.g. 'Ἄϊδι' → '*)/AI+DI'
+},
-setGreekStyle?: {
- disableBetaVariant?: boolean, // disable the typographic variant 'ϐ' [U+03D0]
- useLunateSigma?: boolean // use the lunate sigma rather than the regular form
+greekStyle?: {
+ disableBetaVariant?: boolean, // disable the typographic variant 'ϐ' [U+03D0]
+ useGreekQuestionMark?: boolean, // use greek question marks ';' [U+037E] rather than regular semicolons
+ useLunateSigma?: boolean // use lunate sigmas 'ϲ, Ϲ' rather than regular sigmas
},
-setTransliterationStyle?: {
- useCxOverMacron?: boolean, // use a circumflex rather than a macron for 'η', 'ω', etc
- xi_ks?: boolean, // transliterate 'ξ' as 'ks' (defaults to: 'x')
- rho_rh?: boolean, // transliterate 'ρ' as 'rh' even if it doesn't have a rough breathing
- chi_kh?: boolean, // transliterate 'χ' as 'kh' (defaults to: 'ch')
- upsilon_y?: boolean, // transliterate 'υ' as 'y' (defaults to: 'u')
- lunatesigma_s?: boolean // transliterate 'ϲ' [U+03F2] as 's' (defaults to: 'c')
+transliterationStyle?: {
+ setCoronisStyle?: Coronis, // set Coronis enum to PSILI | APOSTOPHE | NO (defaults to: PSILI)
+ useCxOverMacron?: boolean, // use a circumflex rather than a macron for 'η', 'ω', etc
+ beta_v?: boolean, // transliterate 'β' as 'v' (defaults to: 'b')
+ eta_i?: boolean, // transliterate 'η' as 'ī' (defaults to: 'ē')
+ xi_ks?: boolean, // transliterate 'ξ' as 'ks' (defaults to: 'x')
+ rho_rh?: boolean, // transliterate 'ρ' as 'rh' even if it doesn't have a rough breathing
+ phi_f?: boolean, // transliterate 'φ' as 'f' (defaults to: 'ph')
+ chi_kh?: boolean, // transliterate 'χ' as 'kh' (defaults to: 'ch')
+ upsilon_y?: boolean, // transliterate 'υ' as 'y' (defaults to: 'u')
+ lunatesigma_s?: boolean // transliterate 'ϲ' [U+03F2] as 's' (defaults to: 'c')
},
-useAdditionalChars?: // extend the default mapping with additional chars
- AdditionalChar[] | // (use AdditionalChar.ALL to enable the whole set)
+additionalChars?: // extend the default mapping with additional chars
+ AdditionalChar[] | // (use AdditionalChar.ALL to enable the whole set)
AdditionalChar
```
+A more detailed description of these conversion options is available on this [page](https://github.com/antoineboquet/greek-conversion/wiki#conversion-options).
+
### Examples
#### Basic examples
@@ -141,6 +155,7 @@ useAdditionalChars?: // extend the default mapping with additional c
```ts
toBetaCode('ανθρωπος', KeyType.GREEK) // anqrwpos
toGreek('A)/i+da', KeyType.BETA_CODE) // Ἄϊδα
+toGreek('*)/AI+DA', KeyType.TLG_BETA_CODE) // Ἄϊδα
toTransliteration('ἄϋλος', KeyType.GREEK, { removeDiacritics: true }) // aulos
```
@@ -164,7 +179,7 @@ toTransliteration('ἀΰπνους νύκτας ἴαυον', KeyType.GREEK, [
```ts
const style = {
- setGreekStyle: {
+ greekStyle: {
useLunateSigma: true
}
}
@@ -177,7 +192,7 @@ toGreek('ICHTHUS ZŌNTŌN', KeyType.TRANSLITERATION, style) // ἸΧΘΥϹ ΖΩ
```ts
const style = {
- setTransliterationStyle: {
+ transliterationStyle: {
useCxOverMacron: true,
chi_kh: true
}
@@ -187,6 +202,19 @@ toTransliteration('τέχνη', KeyType.GREEK) // téchnē
toTransliteration('τέχνη', KeyType.GREEK, style) // tékhnê
```
+#### Self conversion (reflect settings)
+
+```ts
+toBetaCode('O(pli/ths', KeyType.BETA_CODE, Preset.TLG) // *(OPLI/THS
+toBetaCode('*(OPLI/THS', KeyType.TLG_BETA_CODE) // O(pli/ths
+
+const grStyle = { greekStyle: { useLunateSigma: true } }
+toGreek('ἅγιος', KeyType.GREEK, grStyle) // ἅγιοϲ
+
+const trStyle = { transliterationStyle: { lunatesigma_s: true } }
+toTransliteration('Cōkrátēc', KeyType.TRANSLITERATION, trStyle) // Sōkrátēs
+```
+
## OOP style
### Summary
diff --git a/examples/playground.html b/examples/playground.html
index f4b84cb..107ab45 100644
--- a/examples/playground.html
+++ b/examples/playground.html
@@ -11,7 +11,7 @@
main {
display: grid;
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
column-gap: 1.5rem;
margin-bottom: 1.5rem;
}
@@ -24,7 +24,7 @@
#options-area {
margin-top: 1.5rem;
- padding: 0.75rem;
+ padding: .75rem;
background: var(--accent-bg);
border-radius: var(--standard-border-radius);
}
@@ -33,10 +33,10 @@
z-index: 999;
position: absolute;
margin-left: 5em;
- padding: 0.75em;
- font-size: 0.75em;
+ padding: .75em;
+ font-size: .75em;
box-shadow: rgba(50, 50, 93, 0.25) 0px 30px 60px -12px,
- rgba(0, 0, 0, 0.3) 0px 18px 36px -18px;
+ rgba(0, 0, 0, .3) 0px 18px 36px -18px;
}
label:has(input[type='checkbox']:disabled) {
@@ -52,12 +52,26 @@
}
fieldset {
- padding: 0.5rem;
+ padding: .125em .5em;
+ }
+
+ fieldset:last-child {
+ margin-bottom: 0;
+ }
+
+ legend {
+ font-variant: small-caps;
+ font-size: .75em;
+ font-weight: bold;
}
fieldset label {
display: inline-block;
- margin: 0.25rem 0.75rem;
+ margin: .25rem .75rem;
+ }
+
+ fieldset select {
+ margin: auto;
}
@@ -70,7 +84,7 @@
Playground example
-
- Conversion results will be displayed here...
+
diff --git a/examples/searchBar.html b/examples/searchBar.html
index 6f1422f..e6aa8ec 100644
--- a/examples/searchBar.html
+++ b/examples/searchBar.html
@@ -241,7 +241,7 @@ Search bar example
const conversionOptions = {
removeDiacritics: true,
- setTransliterationStyle: {
+ transliterationStyle: {
useCxOverMacron: true
}
};
diff --git a/examples/textTransliteration.html b/examples/textTransliteration.html
index 6fa4cc7..fb21c64 100644
--- a/examples/textTransliteration.html
+++ b/examples/textTransliteration.html
@@ -65,6 +65,7 @@ Text transliteration example
+
diff --git a/package-lock.json b/package-lock.json
index 739ee0e..ab6d0c4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "greek-conversion",
- "version": "0.12.3",
+ "version": "0.13.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "greek-conversion",
- "version": "0.12.3",
+ "version": "0.13.0",
"license": "agpl-3.0",
"devDependencies": {
"@parcel/packager-ts": "^2.11.0",
@@ -15,6 +15,9 @@
"jest": "^29.7.0",
"parcel": "^2.11.0",
"ts-jest": "^29.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
}
},
"node_modules/@ampproject/remapping": {
@@ -2813,9 +2816,9 @@
}
},
"node_modules/@swc/core": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.4.tgz",
- "integrity": "sha512-P88AHGWM8xPY3Tjj5360V6vqKCS5UfsyffPJVnr7BKSr45rlG4/pjEGGmFYQjg6ztgPyrGLYz1jSyzajTqTVIA==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.6.tgz",
+ "integrity": "sha512-A7iK9+1qzTCIuc3IYcS8gPHCm9bZVKUJrfNnwveZYyo6OFp3jLno4WOM2yBy5uqedgYATEiWgBYHKq37KrU6IA==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -2830,16 +2833,16 @@
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
- "@swc/core-darwin-arm64": "1.4.4",
- "@swc/core-darwin-x64": "1.4.4",
- "@swc/core-linux-arm-gnueabihf": "1.4.4",
- "@swc/core-linux-arm64-gnu": "1.4.4",
- "@swc/core-linux-arm64-musl": "1.4.4",
- "@swc/core-linux-x64-gnu": "1.4.4",
- "@swc/core-linux-x64-musl": "1.4.4",
- "@swc/core-win32-arm64-msvc": "1.4.4",
- "@swc/core-win32-ia32-msvc": "1.4.4",
- "@swc/core-win32-x64-msvc": "1.4.4"
+ "@swc/core-darwin-arm64": "1.4.6",
+ "@swc/core-darwin-x64": "1.4.6",
+ "@swc/core-linux-arm-gnueabihf": "1.4.6",
+ "@swc/core-linux-arm64-gnu": "1.4.6",
+ "@swc/core-linux-arm64-musl": "1.4.6",
+ "@swc/core-linux-x64-gnu": "1.4.6",
+ "@swc/core-linux-x64-musl": "1.4.6",
+ "@swc/core-win32-arm64-msvc": "1.4.6",
+ "@swc/core-win32-ia32-msvc": "1.4.6",
+ "@swc/core-win32-x64-msvc": "1.4.6"
},
"peerDependencies": {
"@swc/helpers": "^0.5.0"
@@ -2851,9 +2854,9 @@
}
},
"node_modules/@swc/core-darwin-arm64": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.4.tgz",
- "integrity": "sha512-goSHS8yvDgha93RHIV2Vn50neYasqbc4K1g/nKOV6T8kiKVv4w/rmqNJu9Aa0mPGVJtjcr0NvX6bBwE0T4HIzg==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.6.tgz",
+ "integrity": "sha512-bpggpx/BfLFyy48aUKq1PsNUxb7J6CINlpAUk0V4yXfmGnpZH80Gp1pM3GkFDQyCfq7L7IpjPrIjWQwCrL4hYw==",
"cpu": [
"arm64"
],
@@ -2867,9 +2870,9 @@
}
},
"node_modules/@swc/core-darwin-x64": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.4.tgz",
- "integrity": "sha512-PLfgL355qsl5c5kUPsFGITgVXoaqjp9sCd0Y5Z5uN7RtSOvwIX28e23eCxj02dOr7OBr8sq6qBlEMDV03T24Iw==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.6.tgz",
+ "integrity": "sha512-vJn+/ZuBTg+vtNkcmgZdH6FQpa0hFVdnB9bAeqYwKkyqP15zaPe6jfC+qL2y/cIeC7ASvHXEKrnCZgBLxfVQ9w==",
"cpu": [
"x64"
],
@@ -2883,9 +2886,9 @@
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.4.tgz",
- "integrity": "sha512-BVEZVOGnaZvEcHm//KyYzhte46vdF67wLVtmQEXPAlrkRgZ3b/JSySeLXqeocAcOANWb1/SPHlEmPK5azP+JvQ==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.6.tgz",
+ "integrity": "sha512-hEmYcB/9XBAl02MtuVHszhNjQpjBzhk/NFulnU33tBMbNZpy2TN5yTsitezMq090QXdDz8sKIALApDyg07ZR8g==",
"cpu": [
"arm"
],
@@ -2899,9 +2902,9 @@
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.4.tgz",
- "integrity": "sha512-ZbOJfVbCjVMKdfvvJDOTpa3tGqU6tfxng1CDjA62RUcqa7sRbovrjSiw6mq5/4EoOF4zK8CtPIG+TlxKPapnuw==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.6.tgz",
+ "integrity": "sha512-/UCYIVoGpm2YVvGHZM2QOA3dexa28BjcpLAIYnoCbgH5f7ulDhE8FAIO/9pasj+kixDBsdqewHfsNXFYlgGJjQ==",
"cpu": [
"arm64"
],
@@ -2915,9 +2918,9 @@
}
},
"node_modules/@swc/core-linux-arm64-musl": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.4.tgz",
- "integrity": "sha512-+Gjo1W4tY/4kgEe5h22iuCWkpKcPMccXwYaSLNvgBCBQADB0zKFfF0lNf7y6U+81NFEjhRsdwXMsRGZtgTpUrg==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.6.tgz",
+ "integrity": "sha512-LGQsKJ8MA9zZ8xHCkbGkcPSmpkZL2O7drvwsGKynyCttHhpwVjj9lguhD4DWU3+FWIsjvho5Vu0Ggei8OYi/Lw==",
"cpu": [
"arm64"
],
@@ -2931,9 +2934,9 @@
}
},
"node_modules/@swc/core-linux-x64-gnu": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.4.tgz",
- "integrity": "sha512-PR/VbGm0LEkhpm5qClovZWhE/jYoQSyIeyPh8XY39uUI1u2yEfuz5UCW2sJJIWOvNiAfu7+TjW+9H/I7zBBDJA==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.6.tgz",
+ "integrity": "sha512-10JL2nLIreMQDKvq2TECnQe5fCuoqBHu1yW8aChqgHUyg9d7gfZX/kppUsuimqcgRBnS0AjTDAA+JF6UsG/2Yg==",
"cpu": [
"x64"
],
@@ -2947,9 +2950,9 @@
}
},
"node_modules/@swc/core-linux-x64-musl": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.4.tgz",
- "integrity": "sha512-poT9zub4CyVcH1cxwGdrGiZD3urfOaYs/Kd52ve3ymPPeQZq7qQwKqAB/9NxoSiJDaSzJv5OwTEfgaBYCyw0iw==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.6.tgz",
+ "integrity": "sha512-EGyjFVzVY6Do89x8sfah7I3cuP4MwtwzmA6OlfD/KASqfCFf5eIaEBMbajgR41bVfMV7lK72lwAIea5xEyq1AQ==",
"cpu": [
"x64"
],
@@ -2963,9 +2966,9 @@
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.4.tgz",
- "integrity": "sha512-29V5/fBd6XXFb7J/ri9ZeSS/GTqXfSWa3BiE0zTNbASpQbEXf+YPYiAtO6c1HqNyQobKB9ni+w7sa8KkAGhHXw==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.6.tgz",
+ "integrity": "sha512-gfW9AuXvwSyK07Vb8Y8E9m2oJZk21WqcD+X4BZhkbKB0TCZK0zk1j/HpS2UFlr1JB2zPKPpSWLU3ll0GEHRG2A==",
"cpu": [
"arm64"
],
@@ -2979,9 +2982,9 @@
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.4.tgz",
- "integrity": "sha512-2lKEGEjpBOq0z4Nk0tFP9wxVwxgz7FonmjCkzJ95GBb5KNvMrgQQrGNGX6L0hoBo/a1kE752I6V5pOaMyIq5xQ==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.6.tgz",
+ "integrity": "sha512-ZuQm81FhhvNVYtVb9GfZ+Du6e7fZlkisWvuCeBeRiyseNt1tcrQ8J3V67jD2nxje8CVXrwG3oUIbPcybv2rxfQ==",
"cpu": [
"ia32"
],
@@ -2995,9 +2998,9 @@
}
},
"node_modules/@swc/core-win32-x64-msvc": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.4.tgz",
- "integrity": "sha512-xuN0oJhAewga8jNJkT5Wx25RPVnIEMZCYf4irqA5jiK6GckOdcXB8jvEJhggOxnJSW8RDsAtY5q+zw5kNkU+eA==",
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.6.tgz",
+ "integrity": "sha512-UagPb7w5V0uzWSjrXwOavGa7s9iv3wrVdEgWy+/inm0OwY4lj3zpK9qDnMWAwYLuFwkI3UG4Q3dH8wD+CUUcjw==",
"cpu": [
"x64"
],
@@ -3125,9 +3128,9 @@
}
},
"node_modules/@types/node": {
- "version": "20.11.24",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz",
- "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==",
+ "version": "20.11.25",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz",
+ "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
@@ -3458,9 +3461,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001594",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz",
- "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==",
+ "version": "1.0.30001596",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz",
+ "integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==",
"dev": true,
"funding": [
{
@@ -3986,9 +3989,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
- "version": "1.4.692",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.692.tgz",
- "integrity": "sha512-d5rZRka9n2Y3MkWRN74IoAsxR0HK3yaAt7T50e3iT9VZmCCQDT3geXUO5ZRMhDToa1pkCeQXuNo+0g+NfDOVPA==",
+ "version": "1.4.699",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.699.tgz",
+ "integrity": "sha512-I7q3BbQi6e4tJJN5CRcyvxhK0iJb34TV8eJQcgh+fR2fQ8miMgZcEInckCo1U9exDHbfz7DLDnFn8oqH/VcRKw==",
"dev": true
},
"node_modules/emittery": {
@@ -6526,9 +6529,9 @@
}
},
"node_modules/typescript": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
- "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "version": "5.4.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz",
+ "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==",
"dev": true,
"peer": true,
"bin": {
diff --git a/package.json b/package.json
index 68b0f2b..2c3a9cc 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "greek-conversion",
"author": "Antoine Boquet",
"license": "agpl-3.0",
- "version": "0.12.3",
+ "version": "0.13.0",
"description": "A small library to convert a polytonic greek string from/into various representations.",
"keywords": [
"greek",
@@ -24,19 +24,35 @@
"type": "git",
"url": "git+https://github.com/antoineboquet/greek-conversion.git"
},
+ "type": "module",
+ "exports": {
+ ".": {
+ "import": "./dist/greekConversion.min.js",
+ "require": "./dist/greekConversion.min.cjs"
+ }
+ },
"source": "./src/index.ts",
"types": "./dist/greekConversion.d.ts",
- "main": "./dist/greekConversion.cjs.js",
- "module": "./dist/greekConversion.esm.js",
- "unpkg": "./dist/greekConversion.min.js",
+ "main": "./dist/greekConversion.min.js",
+ "commonjs": "./dist/greekConversion.min.cjs",
"targets": {
- "unpkg": {
+ "main": {
+ "context": "browser",
"isLibrary": true,
"optimize": true,
"outputFormat": "esmodule"
+ },
+ "commonjs": {
+ "context": "node",
+ "isLibrary": true,
+ "optimize": true,
+ "outputFormat": "commonjs"
}
},
"browserslist": "defaults",
+ "engines": {
+ "node": ">= 18"
+ },
"files": [
"/dist"
],
diff --git a/src/Mapping.ts b/src/Mapping.ts
index 2045d37..40a937b 100644
--- a/src/Mapping.ts
+++ b/src/Mapping.ts
@@ -4,7 +4,7 @@ import {
IMappingProperty,
ITransliterationStyle
} from './interfaces';
-import { sanitizeRegExpString } from './utils';
+import { normalizeGreek, sanitizeRegExpString } from './utils';
export const GRAVE_ACCENT = '\u0300';
export const ACUTE_ACCENT = '\u0301';
@@ -21,6 +21,7 @@ export const CEDILLA = '\u0327';
export const IOTA_SUBSCRIPT = '\u0345';
export const ANO_TELEIA = '\u0387';
export const MIDDLE_DOT = '\u00B7';
+export const RIGHT_SINGLE_QUOTATION_MARK = '\u2019';
export const GREEK_QUESTION_MARK = '\u037E';
export const GREEK_BETA_SYMBOL = '\u03D0';
export const CAPITAL_LUNATE_SIGMA = '\u03F9';
@@ -130,409 +131,459 @@ const ADDITIONAL_CHARS_VALUES = (): {
}*/
});
-export class Mapping {
- private CAPITAL_ALPHA: IMappingProperty = {
+const CAPITAL_LETTERS = (): {
+ [k in string]: IMappingProperty;
+} => ({
+ CAPITAL_ALPHA: {
gr: 'Α',
bc: 'A',
tr: 'A'
- };
- private CAPITAL_BETA: IMappingProperty = {
+ },
+ CAPITAL_BETA: {
gr: 'Β',
bc: 'B',
tr: 'B'
- };
- private CAPITAL_GAMMA: IMappingProperty = {
+ },
+ CAPITAL_GAMMA: {
gr: 'Γ',
bc: 'G',
tr: 'G'
- };
- private CAPITAL_DELTA: IMappingProperty = {
+ },
+ CAPITAL_DELTA: {
gr: 'Δ',
bc: 'D',
tr: 'D'
- };
- private CAPITAL_EPSILON: IMappingProperty = {
+ },
+ CAPITAL_EPSILON: {
gr: 'Ε',
bc: 'E',
tr: 'E'
- };
- private CAPITAL_ZETA: IMappingProperty = {
+ },
+ CAPITAL_ZETA: {
gr: 'Ζ',
bc: 'Z',
tr: 'Z'
- };
- private CAPITAL_ETA: IMappingProperty = {
+ },
+ CAPITAL_ETA: {
gr: 'Η',
bc: 'H',
tr: 'Ē'
- };
- private CAPITAL_THETA: IMappingProperty = {
+ },
+ CAPITAL_THETA: {
gr: 'Θ',
bc: 'Q',
tr: 'Th'
- };
- private CAPITAL_IOTA: IMappingProperty = {
+ },
+ CAPITAL_IOTA: {
gr: 'Ι',
bc: 'I',
tr: 'I'
- };
- private CAPITAL_KAPPA: IMappingProperty = {
+ },
+ CAPITAL_KAPPA: {
gr: 'Κ',
bc: 'K',
tr: 'K'
- };
- private CAPITAL_LAMBDA: IMappingProperty = {
+ },
+ CAPITAL_LAMBDA: {
gr: 'Λ',
bc: 'L',
tr: 'L'
- };
- private CAPITAL_MU: IMappingProperty = {
+ },
+ CAPITAL_MU: {
gr: 'Μ',
bc: 'M',
tr: 'M'
- };
- private CAPITAL_NU: IMappingProperty = {
+ },
+ CAPITAL_NU: {
gr: 'Ν',
bc: 'N',
tr: 'N'
- };
- private CAPITAL_XI: IMappingProperty = {
+ },
+ CAPITAL_XI: {
gr: 'Ξ',
bc: 'C',
tr: 'X'
- };
- private CAPITAL_OMICRON: IMappingProperty = {
+ },
+ CAPITAL_OMICRON: {
gr: 'Ο',
bc: 'O',
tr: 'O'
- };
- private CAPITAL_PI: IMappingProperty = {
+ },
+ CAPITAL_PI: {
gr: 'Π',
bc: 'P',
tr: 'P'
- };
- private CAPITAL_RHO: IMappingProperty = {
+ },
+ CAPITAL_RHO: {
gr: 'Ρ',
bc: 'R',
tr: 'R'
- };
- private CAPITAL_SIGMA: IMappingProperty = {
+ },
+ CAPITAL_SIGMA: {
gr: 'Σ',
bc: 'S',
tr: 'S'
- };
- private CAPITAL_TAU: IMappingProperty = {
+ },
+ CAPITAL_TAU: {
gr: 'Τ',
bc: 'T',
tr: 'T'
- };
- private CAPITAL_UPSILON: IMappingProperty = {
+ },
+ CAPITAL_UPSILON: {
gr: 'Υ',
bc: 'U',
tr: 'U'
- };
- private CAPITAL_ALT_UPSILON: IMappingProperty;
- private CAPITAL_PHI: IMappingProperty = {
+ },
+ CAPITAL_PHI: {
gr: 'Φ',
bc: 'F',
tr: 'Ph'
- };
- private CAPITAL_CHI: IMappingProperty = {
+ },
+ CAPITAL_CHI: {
gr: 'Χ',
bc: 'X',
tr: 'Ch'
- };
- private CAPITAL_PSI: IMappingProperty = {
+ },
+ CAPITAL_PSI: {
gr: 'Ψ',
bc: 'Y',
tr: 'Ps'
- };
- private CAPITAL_OMEGA: IMappingProperty = {
+ },
+ CAPITAL_OMEGA: {
gr: 'Ω',
bc: 'W',
tr: 'Ō'
- };
- private CAPITAL_DIGAMMA: IMappingProperty;
- private CAPITAL_YOT: IMappingProperty;
- private CAPITAL_LUNATE_SIGMA: IMappingProperty;
- private CAPITAL_STIGMA: IMappingProperty;
- private CAPITAL_KOPPA: IMappingProperty;
- private CAPITAL_ARCHAIC_KOPPA: IMappingProperty;
- private CAPITAL_SAMPI: IMappingProperty;
- private CAPITAL_SAN: IMappingProperty;
- private SMALL_ALPHA: IMappingProperty = {
+ },
+ CAPITAL_ALT_UPSILON: {} as IMappingProperty,
+ CAPITAL_DIGAMMA: {} as IMappingProperty,
+ CAPITAL_YOT: {} as IMappingProperty,
+ CAPITAL_LUNATE_SIGMA: {} as IMappingProperty,
+ CAPITAL_STIGMA: {} as IMappingProperty,
+ CAPITAL_KOPPA: {} as IMappingProperty,
+ CAPITAL_ARCHAIC_KOPPA: {} as IMappingProperty,
+ CAPITAL_SAMPI: {} as IMappingProperty,
+ CAPITAL_SAN: {} as IMappingProperty
+});
+
+const SMALL_LETTERS = (): {
+ [k in string]: IMappingProperty;
+} => ({
+ SMALL_ALPHA: {
gr: 'α',
bc: 'a',
tr: 'a'
- };
- private SMALL_BETA: IMappingProperty = {
+ },
+ SMALL_BETA: {
gr: 'β',
bc: 'b',
tr: 'b'
- };
- private SMALL_GAMMA: IMappingProperty = {
+ },
+ SMALL_GAMMA: {
gr: 'γ',
bc: 'g',
tr: 'g'
- };
- private SMALL_DELTA: IMappingProperty = {
+ },
+ SMALL_DELTA: {
gr: 'δ',
bc: 'd',
tr: 'd'
- };
- private SMALL_EPSILON: IMappingProperty = {
+ },
+ SMALL_EPSILON: {
gr: 'ε',
bc: 'e',
tr: 'e'
- };
- private SMALL_ZETA: IMappingProperty = {
+ },
+ SMALL_ZETA: {
gr: 'ζ',
bc: 'z',
tr: 'z'
- };
- private SMALL_ETA: IMappingProperty = {
+ },
+ SMALL_ETA: {
gr: 'η',
bc: 'h',
tr: 'ē'
- };
- private SMALL_THETA: IMappingProperty = {
+ },
+ SMALL_THETA: {
gr: 'θ',
bc: 'q',
tr: 'th'
- };
- private SMALL_IOTA: IMappingProperty = {
+ },
+ SMALL_IOTA: {
gr: 'ι',
bc: 'i',
tr: 'i'
- };
- private SMALL_KAPPA: IMappingProperty = {
+ },
+ SMALL_KAPPA: {
gr: 'κ',
bc: 'k',
tr: 'k'
- };
- private SMALL_LAMBDA: IMappingProperty = {
+ },
+ SMALL_LAMBDA: {
gr: 'λ',
bc: 'l',
tr: 'l'
- };
- private SMALL_MU: IMappingProperty = {
+ },
+ SMALL_MU: {
gr: 'μ',
bc: 'm',
tr: 'm'
- };
- private SMALL_NU: IMappingProperty = {
+ },
+ SMALL_NU: {
gr: 'ν',
bc: 'n',
tr: 'n'
- };
- private SMALL_XI: IMappingProperty = {
+ },
+ SMALL_XI: {
gr: 'ξ',
bc: 'c',
tr: 'x'
- };
- private SMALL_OMICRON: IMappingProperty = {
+ },
+ SMALL_OMICRON: {
gr: 'ο',
bc: 'o',
tr: 'o'
- };
- private SMALL_PI: IMappingProperty = {
+ },
+ SMALL_PI: {
gr: 'π',
bc: 'p',
tr: 'p'
- };
- private SMALL_RHO: IMappingProperty = {
+ },
+ SMALL_RHO: {
gr: 'ρ',
bc: 'r',
tr: 'r'
- };
- private SMALL_SIGMA: IMappingProperty = {
+ },
+ SMALL_SIGMA: {
gr: 'σ',
bc: 's',
tr: 's'
- };
- private SMALL_TAU: IMappingProperty = {
+ },
+ SMALL_TAU: {
gr: 'τ',
bc: 't',
tr: 't'
- };
- private SMALL_UPSILON: IMappingProperty = {
+ },
+ SMALL_UPSILON: {
gr: 'υ',
bc: 'u',
tr: 'u'
- };
- private SMALL_ALT_UPSILON: IMappingProperty;
- private SMALL_PHI: IMappingProperty = {
+ },
+ SMALL_PHI: {
gr: 'φ',
bc: 'f',
tr: 'ph'
- };
- private SMALL_CHI: IMappingProperty = {
+ },
+ SMALL_CHI: {
gr: 'χ',
bc: 'x',
tr: 'ch'
- };
- private SMALL_PSI: IMappingProperty = {
+ },
+ SMALL_PSI: {
gr: 'ψ',
bc: 'y',
tr: 'ps'
- };
- private SMALL_OMEGA: IMappingProperty = {
+ },
+ SMALL_OMEGA: {
gr: 'ω',
bc: 'w',
tr: 'ō'
- };
- private SMALL_DIGAMMA: IMappingProperty;
- private SMALL_YOT: IMappingProperty;
- private SMALL_LUNATE_SIGMA: IMappingProperty;
- private SMALL_STIGMA: IMappingProperty;
- private SMALL_KOPPA: IMappingProperty;
- private SMALL_ARCHAIC_KOPPA: IMappingProperty;
- private SMALL_SAMPI: IMappingProperty;
- private SMALL_SAN: IMappingProperty;
- private QUESTION_MARK: IMappingProperty = {
+ },
+ SMALL_ALT_UPSILON: {} as IMappingProperty,
+ SMALL_DIGAMMA: {} as IMappingProperty,
+ SMALL_YOT: {} as IMappingProperty,
+ SMALL_LUNATE_SIGMA: {} as IMappingProperty,
+ SMALL_STIGMA: {} as IMappingProperty,
+ SMALL_KOPPA: {} as IMappingProperty,
+ SMALL_ARCHAIC_KOPPA: {} as IMappingProperty,
+ SMALL_SAMPI: {} as IMappingProperty,
+ SMALL_SAN: {} as IMappingProperty
+});
+
+const PUNCTUATION = (): {
+ [k in string]: IMappingProperty;
+} => ({
+ PUNCT_QUESTION_MARK: {
gr: GREEK_QUESTION_MARK,
bc: ';',
tr: '?'
- };
- private ANO_TELEIA: IMappingProperty = {
+ },
+ PUNCT_ANO_TELEIA: {
gr: ANO_TELEIA,
bc: ':',
tr: ';'
- };
- private DIACRITICS = {
- SMOOTH_BREATHING: {
- gr: SMOOTH_BREATHING,
- bc: ')',
- tr: SMOOTH_BREATHING
- } as IMappingProperty,
- ROUGH_BREATHING: {
- gr: ROUGH_BREATHING,
- bc: '(',
- tr: undefined
- } as IMappingProperty,
- ACCUTE_ACCENT: {
- gr: ACUTE_ACCENT,
- bc: '/',
- tr: ACUTE_ACCENT
- } as IMappingProperty,
- GRAVE_ACCENT: {
- gr: GRAVE_ACCENT,
- bc: '\\',
- tr: GRAVE_ACCENT
- } as IMappingProperty,
- MACRON: {
- gr: MACRON,
- bc: '%26',
- tr: MACRON
- } as IMappingProperty,
- BREVE: {
- gr: BREVE,
- bc: '%27',
- tr: BREVE
- } as IMappingProperty,
- TILDE: {
- gr: GREEK_TILDE,
- bc: '=',
- tr: LATIN_TILDE
- } as IMappingProperty,
- DIAERESIS: {
- gr: DIAERESIS,
- bc: '+',
- tr: DIAERESIS
- } as IMappingProperty,
- IOTA_SUBSCRIPT: {
- gr: IOTA_SUBSCRIPT,
- bc: '|',
- tr: CEDILLA
- } as IMappingProperty,
- DOT_BELOW: {
- gr: DOT_BELOW,
- bc: '?',
- tr: DOT_BELOW
- } as IMappingProperty
- };
+ }
+});
- #isUpperCase: boolean;
- //#betaCodeStyle: IBetaCodeStyle;
- #removeDiacritics: boolean;
- #transliterationStyle: ITransliterationStyle;
- #useAdditionalChars: AdditionalChar[] | AdditionalChar;
+const DIACRITICS = (): {
+ [k in string]: IMappingProperty;
+} => ({
+ DIA_SMOOTH_BREATHING: {
+ gr: SMOOTH_BREATHING,
+ bc: ')',
+ tr: SMOOTH_BREATHING
+ },
+ DIA_ROUGH_BREATHING: {
+ gr: ROUGH_BREATHING,
+ bc: '(',
+ tr: undefined
+ },
+ DIA_ACCUTE_ACCENT: {
+ gr: ACUTE_ACCENT,
+ bc: '/',
+ tr: ACUTE_ACCENT
+ },
+ DIA_GRAVE_ACCENT: {
+ gr: GRAVE_ACCENT,
+ bc: '\\',
+ tr: GRAVE_ACCENT
+ },
+ DIA_MACRON: {
+ gr: MACRON,
+ bc: '%26',
+ tr: MACRON
+ },
+ DIA_BREVE: {
+ gr: BREVE,
+ bc: '%27',
+ tr: BREVE
+ },
+ DIA_TILDE: {
+ gr: GREEK_TILDE,
+ bc: '=',
+ tr: LATIN_TILDE
+ },
+ DIA_DIAERESIS: {
+ gr: DIAERESIS,
+ bc: '+',
+ tr: DIAERESIS
+ },
+ DIA_IOTA_SUBSCRIPT: {
+ gr: IOTA_SUBSCRIPT,
+ bc: '|',
+ tr: CEDILLA
+ },
+ DIA_DOT_BELOW: {
+ gr: DOT_BELOW,
+ bc: '?',
+ tr: DOT_BELOW
+ }
+});
+
+export class Mapping {
+ #capitalLetters = CAPITAL_LETTERS();
+ #smallLetters = SMALL_LETTERS();
+ #punctuation = PUNCTUATION();
+ #diacritics = DIACRITICS();
+
+ #isUpperCase: boolean = false;
+ #removeDiacritics: boolean = false;
+ #transliterationStyle: ITransliterationStyle = {};
+ #additionalChars: AdditionalChar[] | AdditionalChar = [];
constructor(options?: IInternalConversionOptions) {
if (!options) return;
- this.#isUpperCase = options?.isUpperCase;
- //this.#betaCodeStyle = options?.setBetaCodeStyle;
- this.#removeDiacritics = options?.removeDiacritics;
- this.#transliterationStyle = options?.setTransliterationStyle;
- this.#useAdditionalChars = options?.useAdditionalChars;
+ this.#isUpperCase = Boolean(options?.isUpperCase);
+ this.#removeDiacritics = Boolean(options?.removeDiacritics);
+ this.#transliterationStyle = options?.transliterationStyle ?? {};
+ this.#additionalChars = options?.additionalChars ?? [];
- if (this.#useAdditionalChars) {
+ if (this.#additionalChars) {
for (const [k, v] of Object.entries(ADDITIONAL_CHARS_VALUES())) {
if (
- this.#useAdditionalChars === (AdditionalChar.ALL as number) ||
- this.#useAdditionalChars === (Number(k) as AdditionalChar) ||
- (Array.isArray(this.#useAdditionalChars) &&
- this.#useAdditionalChars.includes(Number(k) as AdditionalChar))
+ this.#additionalChars === (AdditionalChar.ALL as number) ||
+ this.#additionalChars === (Number(k) as AdditionalChar) ||
+ (Array.isArray(this.#additionalChars) &&
+ this.#additionalChars.includes(Number(k) as AdditionalChar))
) {
- for (const [char, props] of Object.entries(v)) {
- this[char] = props;
- }
+ const keys = Object.keys(v);
+ if (keys[0]) this.#capitalLetters[keys[0]] = v[keys[0]];
+ if (keys[1]) this.#smallLetters[keys[1]] = v[keys[1]];
}
}
}
- const { useCxOverMacron, xi_ks, chi_kh, upsilon_y, lunatesigma_s } =
- this.#transliterationStyle ?? {};
-
- if (useCxOverMacron) {
- this.CAPITAL_ETA.tr = 'Ê';
- this.SMALL_ETA.tr = 'ê';
-
- this.CAPITAL_OMEGA.tr = 'Ô';
- this.SMALL_OMEGA.tr = 'ô';
-
- if (this.CAPITAL_STIGMA?.tr) {
- this.CAPITAL_STIGMA.tr = 'Ĉ';
- this.SMALL_STIGMA.tr = 'ĉ';
- }
+ const {
+ useCxOverMacron,
+ beta_v,
+ eta_i,
+ xi_ks,
+ phi_f,
+ chi_kh,
+ upsilon_y,
+ lunatesigma_s
+ } = this.#transliterationStyle ?? {};
+
+ if (beta_v) {
+ this.#capitalLetters.CAPITAL_BETA.tr = 'V';
+ this.#smallLetters.SMALL_BETA.tr = 'v';
+ }
- if (this.CAPITAL_SAMPI?.tr) {
- this.CAPITAL_SAMPI.tr = 'Ŝ';
- this.SMALL_SAMPI.tr = 'ŝ';
- }
+ if (eta_i) {
+ this.#capitalLetters.CAPITAL_ETA.tr = 'Ī';
+ this.#smallLetters.SMALL_ETA.tr = 'ī';
}
if (xi_ks) {
- this.CAPITAL_XI.tr = 'Ks';
- this.SMALL_XI.tr = 'ks';
+ this.#capitalLetters.CAPITAL_XI.tr = 'Ks';
+ this.#smallLetters.SMALL_XI.tr = 'ks';
+ }
+
+ if (phi_f) {
+ this.#capitalLetters.CAPITAL_PHI.tr = 'F';
+ this.#smallLetters.SMALL_PHI.tr = 'f';
}
if (chi_kh) {
- this.CAPITAL_CHI.tr = 'Kh';
- this.SMALL_CHI.tr = 'kh';
+ this.#capitalLetters.CAPITAL_CHI.tr = 'Kh';
+ this.#smallLetters.SMALL_CHI.tr = 'kh';
}
if (upsilon_y) {
- this.CAPITAL_UPSILON.tr = 'Y';
- this.SMALL_UPSILON.tr = 'y';
+ this.#capitalLetters.CAPITAL_UPSILON.tr = 'Y';
+ this.#smallLetters.SMALL_UPSILON.tr = 'y';
}
if (lunatesigma_s) {
// The lunate sigma might not have been activated using the
- // `useAdditionalChars` option. So, we need to check if its property exists.
- if (this.CAPITAL_LUNATE_SIGMA?.tr) this.CAPITAL_LUNATE_SIGMA.tr = 'S';
- if (this.SMALL_LUNATE_SIGMA?.tr) this.SMALL_LUNATE_SIGMA.tr = 's';
+ // `additionalChars` option. So, we need to check if its property exists.
+ if (this.#capitalLetters.CAPITAL_LUNATE_SIGMA?.tr)
+ this.#capitalLetters.CAPITAL_LUNATE_SIGMA.tr = 'S';
+ if (this.#smallLetters.SMALL_LUNATE_SIGMA?.tr)
+ this.#smallLetters.SMALL_LUNATE_SIGMA.tr = 's';
+
+ if (!this.#capitalLetters.CAPITAL_LUNATE_SIGMA?.tr) {
+ console.warn('You must enable `AdditionalChar.LUNATE_SIGMA` for the option `transliterationStyle.lunatesigma_s` to take effect.'); // prettier-ignore
+ }
+ }
+
+ if (useCxOverMacron) {
+ if (eta_i) {
+ this.#capitalLetters.CAPITAL_ETA.tr = 'Î';
+ this.#smallLetters.SMALL_ETA.tr = 'î';
+ } else {
+ this.#capitalLetters.CAPITAL_ETA.tr = 'Ê';
+ this.#smallLetters.SMALL_ETA.tr = 'ê';
+ }
+
+ this.#capitalLetters.CAPITAL_OMEGA.tr = 'Ô';
+ this.#smallLetters.SMALL_OMEGA.tr = 'ô';
+
+ if (this.#capitalLetters.CAPITAL_STIGMA?.tr) {
+ this.#capitalLetters.CAPITAL_STIGMA.tr = 'Ĉ';
+ this.#smallLetters.SMALL_STIGMA.tr = 'ĉ';
+ }
- if (!this.CAPITAL_LUNATE_SIGMA?.tr) {
- console.warn('You must enable `AdditionalChar.LUNATE_SIGMA` for the option `setTransliterationStyle.lunatesigma_s` to take effect.'); // prettier-ignore
+ if (this.#capitalLetters.CAPITAL_SAMPI?.tr) {
+ this.#capitalLetters.CAPITAL_SAMPI.tr = 'Ŝ';
+ this.#smallLetters.SMALL_SAMPI.tr = 'ŝ';
}
}
if (this.#isUpperCase) {
- for (const [k, v] of Object.entries(this)) {
- if (k.startsWith('CAPITAL') && v.tr?.length > 1 /* Th, Ph, etc */) {
- this[k].tr = v.tr.toUpperCase();
+ for (const [k, v] of Object.entries(this.#capitalLetters)) {
+ if (v.tr?.length > 1 /* Th, Ph, etc */) {
+ this.#capitalLetters[k].tr = v.tr.toUpperCase();
}
}
}
@@ -544,35 +595,32 @@ export class Mapping {
apply(fromStr: string, fromType: KeyType, toType: KeyType): string {
fromStr = fromStr.normalize('NFD');
- if (
- fromType === KeyType.TRANSLITERATION &&
- toType !== KeyType.TRANSLITERATION
- ) {
+ if (fromType === KeyType.TRANSLITERATION && toType !== fromType) {
fromStr = this.#trJoinSpecialChars(fromStr);
// Add the alternate upsilon form (y/u) to the mapping.
if (this.#transliterationStyle?.upsilon_y) {
- this.CAPITAL_ALT_UPSILON = {
- bc: this.CAPITAL_UPSILON.bc,
- gr: this.CAPITAL_UPSILON.gr,
+ this.#capitalLetters.CAPITAL_ALT_UPSILON = {
+ bc: this.#capitalLetters.CAPITAL_UPSILON.bc,
+ gr: this.#capitalLetters.CAPITAL_UPSILON.gr,
tr: 'U'
};
- this.SMALL_ALT_UPSILON = {
- bc: this.SMALL_UPSILON.bc,
- gr: this.SMALL_UPSILON.gr,
+ this.#smallLetters.SMALL_ALT_UPSILON = {
+ bc: this.#smallLetters.SMALL_UPSILON.bc,
+ gr: this.#smallLetters.SMALL_UPSILON.gr,
tr: 'u'
};
}
// `lunatesigma_s` is destructive: convert back all sigmas using the regular form.
if (this.#transliterationStyle?.lunatesigma_s) {
- this.CAPITAL_LUNATE_SIGMA.tr = undefined;
- this.SMALL_LUNATE_SIGMA.tr = undefined;
+ this.#capitalLetters.CAPITAL_LUNATE_SIGMA.tr = undefined;
+ this.#smallLetters.SMALL_LUNATE_SIGMA.tr = undefined;
}
}
if (fromType === KeyType.GREEK) {
- fromStr = Mapping.#grBypassUnicodeEquivalences(fromStr);
+ fromStr = normalizeGreek(fromStr, true, true);
}
const mappingProps = this.#getPropsMapOrderByLengthDesc(fromType, toType);
@@ -604,7 +652,7 @@ export class Mapping {
// Nullish subsequent array indices if necessary.
if (lval.length > 1) {
for (let i = 1; i < lval.length; i++) {
- conversionArr[matches.index + i] = null;
+ conversionArr[matches.index + i] = '';
}
}
}
@@ -661,47 +709,32 @@ export class Mapping {
*
* @param fromType - The left value of the resulting `Map`
* @param toType - The right value of the resulting `Map`
- * @param removeDiacritics - If `true`, exclude the `DIACRITICS` property
+ * @param removeDiacritics - If `true`, exclude `this.#diacritics`
*/
#getPropsMapOrderByLengthDesc(
fromType: KeyType,
toType: KeyType
): Map {
- let fromProp: string;
- let toProp: string;
+ let fromProp, toProp: string;
- switch (fromType) {
- case KeyType.BETA_CODE:
- fromProp = 'bc';
- break;
- case KeyType.GREEK:
- fromProp = 'gr';
- break;
- case KeyType.TRANSLITERATION:
- fromProp = 'tr';
- break;
- }
+ if (fromType === KeyType.BETA_CODE) fromProp = 'bc';
+ else if (fromType === KeyType.GREEK) fromProp = 'gr';
+ else fromProp = 'tr';
- switch (toType) {
- case KeyType.BETA_CODE:
- toProp = 'bc';
- break;
- case KeyType.GREEK:
- toProp = 'gr';
- break;
- case KeyType.TRANSLITERATION:
- toProp = 'tr';
- break;
- }
+ if (toType === KeyType.BETA_CODE) toProp = 'bc';
+ else if (toType === KeyType.GREEK) toProp = 'gr';
+ else toProp = 'tr';
let chars = [];
- for (const [k, v] of Object.entries(this)) {
- if (this.#isUpperCase && k.startsWith('SMALL')) continue;
+ const props = Object.assign(
+ this.#capitalLetters,
+ !this.#isUpperCase ? this.#smallLetters : {},
+ this.#punctuation
+ );
- if (v[fromProp] !== undefined && v[toProp] !== undefined) {
- chars.push([v[fromProp], v[toProp]]);
- }
+ for (const [k, v] of Object.entries(props)) {
+ if (v[fromProp] && v[toProp]) chars.push([v[fromProp], v[toProp]]);
}
const sortedChars = chars.sort((a, b) => {
@@ -711,10 +744,8 @@ export class Mapping {
if (!this.#removeDiacritics) {
let diacritics = [];
- for (const [k, v] of Object.entries(this.DIACRITICS)) {
- if (v[fromProp] !== undefined && v[toProp] !== undefined) {
- diacritics.push([v[fromProp], v[toProp]]);
- }
+ for (const [k, v] of Object.entries(this.#diacritics)) {
+ if (v[fromProp] && v[toProp]) diacritics.push([v[fromProp], v[toProp]]);
}
return new Map([...sortedChars, ...diacritics]);
@@ -723,18 +754,6 @@ export class Mapping {
return new Map(sortedChars);
}
- /**
- * Returns a string for which the wrong Unicode canonical equivalences
- * have been replaced by the right Unicode points.
- *
- * @param NFDGreekStr - Expects an `NFD` normalized greek string.
- */
- static #grBypassUnicodeEquivalences(NFDGreekStr: string): string {
- return NFDGreekStr.replace(new RegExp(LATIN_TILDE, 'g'), GREEK_TILDE)
- .replace(new RegExp(MIDDLE_DOT, 'g'), ANO_TELEIA)
- .replace(new RegExp(';', 'g'), GREEK_QUESTION_MARK);
- }
-
/**
* Returns a string for which some diacritical marks have been joined back
* to their letter as they should not be treated separately (e. g. when
@@ -744,10 +763,9 @@ export class Mapping {
*/
#trJoinSpecialChars(NFDTransliteratedStr: string): string {
// Join back below dots to archaic koppas.
- // @fixme: this does not work with adjacent small & capital archaic koppa.
- if (this.CAPITAL_ARCHAIC_KOPPA?.tr) {
+ if (this.#capitalLetters.CAPITAL_ARCHAIC_KOPPA?.tr) {
NFDTransliteratedStr = NFDTransliteratedStr.replace(
- new RegExp(`${this.CAPITAL_ARCHAIC_KOPPA.tr.normalize('NFD')}`, 'gi'),
+ new RegExp(`${this.#capitalLetters.CAPITAL_ARCHAIC_KOPPA.tr.normalize('NFD')}`, 'gi'), // prettier-ignore
(match) => match.normalize()
);
}
@@ -762,32 +780,23 @@ export class Mapping {
}
/**
- * Returns an array containing the transliterated mapped chars tied
- * to a circumflex or a macron, depnding on the context.
+ * Returns an array containing the transliterated chars that carry
+ * a circumflex or a macron (depnding on the context).
*
* @remarks
- * (1) Letters are returned without their diacritical sign.
- * (2) The current implementation is semi-static as it doesn't check
- * the actual mapped chars.
+ * Letters are returned without their diacritical sign.
*/
trLettersWithCxOrMacron(): string[] {
- let letters = [
- this.CAPITAL_ETA,
- this.SMALL_ETA,
- this.CAPITAL_OMEGA,
- this.SMALL_OMEGA
- ];
-
- if (this.CAPITAL_STIGMA?.tr) {
- letters.push(this.CAPITAL_STIGMA, this.SMALL_STIGMA);
- }
+ const letters = Object.assign(this.#capitalLetters, this.#smallLetters);
- if (this.CAPITAL_SAMPI?.tr) {
- letters.push(this.CAPITAL_SAMPI, this.SMALL_SAMPI);
+ const found = [];
+ for (const [k, v] of Object.entries(letters)) {
+ const el = v?.tr ? v.tr.normalize('NFD') : '';
+ if (/\u0302|\u0304/.test(el)) {
+ found.push(el);
+ }
}
- return letters.map((letter) =>
- letter.tr.normalize('NFD').charAt(0).normalize()
- );
+ return found.map((el) => el.charAt(0).normalize());
}
}
diff --git a/src/enums.ts b/src/enums.ts
index 7810fb1..63fa8e8 100644
--- a/src/enums.ts
+++ b/src/enums.ts
@@ -1,3 +1,5 @@
+import { RIGHT_SINGLE_QUOTATION_MARK, SMOOTH_BREATHING } from './Mapping';
+
export enum AdditionalChar {
ALL = 1,
DIGAMMA,
@@ -10,16 +12,24 @@ export enum AdditionalChar {
//SAN
}
+export enum Coronis {
+ PSILI = SMOOTH_BREATHING,
+ APOSTROPHE = RIGHT_SINGLE_QUOTATION_MARK,
+ NO = ''
+}
+
export enum KeyType {
GREEK,
BETA_CODE,
+ TLG_BETA_CODE,
TRANSLITERATION
}
export enum Preset {
ALA_LC,
BNF,
+ ISO,
MODERN_BC,
- SBL
- //TLG
+ SBL,
+ TLG
}
diff --git a/src/index.ts b/src/index.ts
index 88da48d..eb52a25 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,7 +4,7 @@
* @license AGPL-3.0
*/
-import { AdditionalChar, KeyType, Preset } from './enums';
+import { AdditionalChar, Coronis, KeyType, Preset } from './enums';
import { GreekString } from './GreekString';
import { toBetaCode } from './toBetaCode';
import { toGreek } from './toGreek';
@@ -15,7 +15,7 @@ import {
removeGreekVariants
} from './utils';
-export { AdditionalChar, KeyType, Preset } from './enums';
+export { AdditionalChar, Coronis, KeyType, Preset } from './enums';
export { GreekString } from './GreekString';
export { toBetaCode } from './toBetaCode';
export { toGreek } from './toGreek';
@@ -28,6 +28,7 @@ export {
export default {
AdditionalChar,
+ Coronis,
KeyType,
Preset,
GreekString,
diff --git a/src/interfaces.ts b/src/interfaces.ts
index a2ae3d2..bea6bfa 100644
--- a/src/interfaces.ts
+++ b/src/interfaces.ts
@@ -1,12 +1,12 @@
-import { AdditionalChar, Preset } from './enums';
+import { AdditionalChar, Coronis, Preset } from './enums';
export interface IConversionOptions {
removeDiacritics?: boolean;
removeExtraWhitespace?: boolean;
- //setBetaCodeStyle?: IBetaCodeStyle;
- setGreekStyle?: IGreekStyle;
- setTransliterationStyle?: ITransliterationStyle;
- useAdditionalChars?: AdditionalChar[] | AdditionalChar;
+ betaCodeStyle?: IBetaCodeStyle;
+ greekStyle?: IGreekStyle;
+ transliterationStyle?: ITransliterationStyle;
+ additionalChars?: AdditionalChar[] | AdditionalChar;
}
export interface IInternalConversionOptions extends IConversionOptions {
@@ -15,13 +15,13 @@ export interface IInternalConversionOptions extends IConversionOptions {
export type MixedPreset = [Preset, IConversionOptions];
-// v0.13
-/*export interface IBetaCodeStyle {
+export interface IBetaCodeStyle {
useTLGStyle?: boolean;
-}*/
+}
export interface IGreekStyle {
disableBetaVariant?: boolean;
+ useGreekQuestionMark?: boolean;
useLunateSigma?: boolean;
}
@@ -32,10 +32,17 @@ export interface IMappingProperty {
}
export interface ITransliterationStyle {
+ setCoronisStyle?: Coronis;
useCxOverMacron?: boolean;
+ beta_v?: boolean;
+ eta_i?: boolean;
xi_ks?: boolean;
rho_rh?: boolean;
+ phi_f?: boolean;
chi_kh?: boolean;
- upsilon_y?: boolean;
+ upsilon_y?: boolean | Preset.ISO; // (¹)
lunatesigma_s?: boolean;
}
+
+// ¹ Preset.ISO: only preserve 'au', 'eu', 'ou'.
+// Note that this is undoubtedly poorly designed.
diff --git a/src/presets.ts b/src/presets.ts
index be6a969..fc4e681 100644
--- a/src/presets.ts
+++ b/src/presets.ts
@@ -1,23 +1,28 @@
-import { AdditionalChar, Preset } from './enums';
+import { AdditionalChar, Coronis, Preset } from './enums';
import { IConversionOptions, MixedPreset } from './interfaces';
const ALA_LC_OPTIONS = (): IConversionOptions => ({
removeDiacritics: true,
- useAdditionalChars: [
- AdditionalChar.DIGAMMA,
- AdditionalChar.ARCHAIC_KOPPA,
- AdditionalChar.LUNATE_SIGMA
- ],
- setTransliterationStyle: {
+ transliterationStyle: {
rho_rh: true,
upsilon_y: true,
lunatesigma_s: true
- }
+ },
+ additionalChars: [
+ AdditionalChar.DIGAMMA,
+ AdditionalChar.ARCHAIC_KOPPA,
+ AdditionalChar.LUNATE_SIGMA
+ ]
});
const BNF_OPTIONS = (): IConversionOptions => ({
- removeDiacritics: false,
- useAdditionalChars: [
+ greekStyle: {
+ useGreekQuestionMark: true
+ },
+ transliterationStyle: {
+ upsilon_y: Preset.ISO
+ },
+ additionalChars: [
AdditionalChar.DIGAMMA,
AdditionalChar.YOT,
AdditionalChar.LUNATE_SIGMA,
@@ -27,25 +32,39 @@ const BNF_OPTIONS = (): IConversionOptions => ({
]
});
+const ISO_OPTIONS = (): IConversionOptions => ({
+ transliterationStyle: {
+ setCoronisStyle: Coronis.APOSTROPHE,
+ beta_v: true,
+ eta_i: true,
+ phi_f: true,
+ upsilon_y: Preset.ISO,
+ lunatesigma_s: true
+ },
+ additionalChars: [
+ AdditionalChar.DIGAMMA,
+ AdditionalChar.YOT,
+ AdditionalChar.LUNATE_SIGMA
+ ]
+});
+
const MODERN_BC_OPTIONS = (): IConversionOptions => ({
- removeDiacritics: false,
- useAdditionalChars: AdditionalChar.ALL
+ additionalChars: AdditionalChar.ALL
});
const SBL_OPTIONS = (): IConversionOptions => ({
removeDiacritics: true,
- setTransliterationStyle: {
+ transliterationStyle: {
rho_rh: true,
upsilon_y: true
}
});
const TLG_OPTIONS = (): IConversionOptions => ({
- removeDiacritics: false,
- useAdditionalChars: AdditionalChar.ALL
- /*setBetaCodeStyle: {
+ betaCodeStyle: {
useTLGStyle: true
- }*/
+ },
+ additionalChars: AdditionalChar.ALL
});
export function applyPreset(preset: Preset | MixedPreset): IConversionOptions {
@@ -65,6 +84,10 @@ export function applyPreset(preset: Preset | MixedPreset): IConversionOptions {
options = BNF_OPTIONS();
break;
+ case Preset.ISO:
+ options = ISO_OPTIONS();
+ break;
+
case Preset.MODERN_BC:
options = MODERN_BC_OPTIONS();
break;
@@ -73,10 +96,9 @@ export function applyPreset(preset: Preset | MixedPreset): IConversionOptions {
options = SBL_OPTIONS();
break;
- // v0.13
- /*case Preset.TLG:
+ case Preset.TLG:
options = TLG_OPTIONS();
- break;*/
+ break;
default:
throw new RangeError(`Preset '${preset}' is not implemented.`);
@@ -90,7 +112,7 @@ export function applyPreset(preset: Preset | MixedPreset): IConversionOptions {
}
function mergeOptions(target: IConversionOptions, source: IConversionOptions) {
- const isObject = (obj) => obj && typeof obj === 'object';
+ const isObject = (obj: object) => obj && typeof obj === 'object';
for (const key in source) {
if (Array.isArray(target[key]) && Array.isArray(source[key])) {
diff --git a/src/toBetaCode.ts b/src/toBetaCode.ts
index 2483951..54e6b67 100644
--- a/src/toBetaCode.ts
+++ b/src/toBetaCode.ts
@@ -1,9 +1,12 @@
-import { KeyType, Preset } from './enums';
+import { Coronis, KeyType, Preset } from './enums';
import { IConversionOptions, MixedPreset } from './interfaces';
-import { Mapping } from './Mapping';
+import { Mapping, SMOOTH_BREATHING } from './Mapping';
import {
applyUppercaseChars,
+ bcReorderDiacritics,
+ fromTLG,
handleOptions,
+ toTLG,
removeDiacritics as utilRmDiacritics,
removeExtraWhitespace as utilRmExtraWhitespace,
removeGreekVariants as utilRmGreekVariants
@@ -16,42 +19,59 @@ export function toBetaCode(
declaredMapping?: Mapping
): string {
const options = handleOptions(str, fromType, settings);
- const { removeDiacritics, removeExtraWhitespace } = options;
+ const {
+ removeDiacritics,
+ removeExtraWhitespace,
+ betaCodeStyle,
+ transliterationStyle
+ } = options;
const mapping = declaredMapping ?? new Mapping(options);
switch (fromType) {
case KeyType.BETA_CODE:
+ case KeyType.TLG_BETA_CODE:
if (removeDiacritics) str = utilRmDiacritics(str, KeyType.BETA_CODE);
str = mapping.apply(str, KeyType.BETA_CODE, KeyType.BETA_CODE);
- str = reorderDiacritics(str);
break;
case KeyType.GREEK:
- if (removeDiacritics) str = utilRmDiacritics(str, KeyType.GREEK);
+ if (removeDiacritics) str = utilRmDiacritics(str, fromType);
str = utilRmGreekVariants(str);
- str = mapping.apply(str, KeyType.GREEK, KeyType.BETA_CODE);
- str = reorderDiacritics(str);
+ str = mapping.apply(str, fromType, KeyType.BETA_CODE);
break;
case KeyType.TRANSLITERATION:
str = applyUppercaseChars(str);
+ if (transliterationStyle?.setCoronisStyle === Coronis.APOSTROPHE) {
+ str = str.replace(
+ new RegExp(`(?<=\\S)${Coronis.APOSTROPHE}(?=\\S)`, 'gu'),
+ SMOOTH_BREATHING
+ );
+ }
+
// Flag transliterated rough breathings.
str = str.replace(/(?<=\p{P}|\s|^|r{1,2})h/gimu, '$');
- str = mapping.apply(str, KeyType.TRANSLITERATION, KeyType.BETA_CODE);
+ str = mapping.apply(str, fromType, KeyType.BETA_CODE);
if (removeDiacritics) {
- str = utilRmDiacritics(str, KeyType.TRANSLITERATION);
+ str = utilRmDiacritics(str, fromType);
str = str.replace(/\$/gi, '');
} else {
str = trConvertFlaggedBreathings(str);
}
-
- str = reorderDiacritics(str);
break;
}
+ str = bcReorderDiacritics(str);
+
+ if (fromType === KeyType.TLG_BETA_CODE) {
+ if (!betaCodeStyle?.useTLGStyle) str = fromTLG(str);
+ } else {
+ if (betaCodeStyle?.useTLGStyle) str = toTLG(str);
+ }
+
if (removeExtraWhitespace) str = utilRmExtraWhitespace(str);
return str.normalize();
@@ -101,15 +121,3 @@ function trConvertFlaggedBreathings(str: string): string {
.replace(/\$/g, '')
.normalize();
}
-
-/**
- * Returns a beta code string with a correct diacritics order.
- *
- * @privateRemarks
- * This function should reorder all the diacritics defined for the beta code
- * representation. Currently, it only reorders breathings/accents in relation
- * to the iota subscript.
- */
-function reorderDiacritics(betaCodeStr: string): string {
- return betaCodeStr.replace(/(\|)([()\\/+=]+)/g, '$2$1');
-}
diff --git a/src/toGreek.ts b/src/toGreek.ts
index 7ffdfcf..e3552f7 100644
--- a/src/toGreek.ts
+++ b/src/toGreek.ts
@@ -1,4 +1,4 @@
-import { KeyType, Preset } from './enums';
+import { Coronis, KeyType, Preset } from './enums';
import {
IConversionOptions,
IInternalConversionOptions,
@@ -8,6 +8,8 @@ import { Mapping, ROUGH_BREATHING, SMOOTH_BREATHING } from './Mapping';
import {
applyGreekVariants,
applyUppercaseChars,
+ bcReorderDiacritics,
+ fromTLG,
handleOptions,
normalizeGreek,
removeDiacritics as utilRmDiacritics,
@@ -22,27 +24,50 @@ export function toGreek(
declaredMapping?: Mapping
): string {
const options = handleOptions(str, fromType, settings);
- const { removeDiacritics, removeExtraWhitespace, setGreekStyle } = options;
+ const {
+ removeDiacritics,
+ removeExtraWhitespace,
+ greekStyle,
+ transliterationStyle
+ } = options;
const mapping = declaredMapping ?? new Mapping(options);
+ if (fromType === KeyType.TLG_BETA_CODE) {
+ str = fromTLG(str);
+ fromType = KeyType.BETA_CODE;
+ }
+
switch (fromType) {
case KeyType.BETA_CODE:
- if (removeDiacritics) str = utilRmDiacritics(str, KeyType.BETA_CODE);
- str = mapping.apply(str, KeyType.BETA_CODE, KeyType.GREEK);
+ if (removeDiacritics) str = utilRmDiacritics(str, fromType);
+ else str = bcReorderDiacritics(str);
+
+ str = mapping.apply(str, fromType, KeyType.GREEK);
+
break;
case KeyType.GREEK:
- if (removeDiacritics) str = utilRmDiacritics(str, KeyType.GREEK);
+ if (removeDiacritics) str = utilRmDiacritics(str, fromType);
str = utilRmGreekVariants(str);
- str = mapping.apply(str, KeyType.GREEK, KeyType.GREEK);
+ str = mapping.apply(str, fromType, fromType);
break;
case KeyType.TRANSLITERATION:
str = applyUppercaseChars(str);
- str = mapping.apply(str, KeyType.TRANSLITERATION, KeyType.GREEK);
+ str = mapping.apply(str, fromType, KeyType.GREEK);
+
+ if (transliterationStyle?.setCoronisStyle === Coronis.APOSTROPHE) {
+ str = str
+ .normalize('NFD')
+ .replace(
+ new RegExp(`(?<=\\S)${Coronis.APOSTROPHE}(?=\\S)`, 'gu'),
+ SMOOTH_BREATHING
+ )
+ .normalize();
+ }
if (removeDiacritics) {
- str = utilRmDiacritics(str, KeyType.TRANSLITERATION);
+ str = utilRmDiacritics(str, fromType);
str = str.replace(/h/gi, '');
} else {
str = trConvertBreathings(str, options);
@@ -50,10 +75,10 @@ export function toGreek(
break;
}
- str = applyGreekVariants(str, setGreekStyle);
+ str = applyGreekVariants(str, greekStyle);
if (removeExtraWhitespace) str = utilRmExtraWhitespace(str);
- return normalizeGreek(str);
+ return normalizeGreek(str, greekStyle?.useGreekQuestionMark);
}
/**
diff --git a/src/toTransliteration.ts b/src/toTransliteration.ts
index 46d41db..14e9713 100644
--- a/src/toTransliteration.ts
+++ b/src/toTransliteration.ts
@@ -1,4 +1,4 @@
-import { KeyType, Preset } from './enums';
+import { Coronis, KeyType, Preset } from './enums';
import {
IConversionOptions,
IInternalConversionOptions,
@@ -13,8 +13,9 @@ import {
SMOOTH_BREATHING
} from './Mapping';
import {
+ bcReorderDiacritics,
+ fromTLG,
handleOptions,
- normalizeGreek,
removeDiacritics as utilRmDiacritics,
removeExtraWhitespace as utilRmExtraWhitespace,
removeGreekVariants as utilRmGreekVariants
@@ -27,64 +28,94 @@ export function toTransliteration(
declaredMapping?: Mapping
): string {
const options = handleOptions(str, fromType, settings);
- const { removeDiacritics, removeExtraWhitespace, setTransliterationStyle } =
+ const { removeDiacritics, removeExtraWhitespace, transliterationStyle } =
options;
+ const {
+ setCoronisStyle,
+ useCxOverMacron,
+ beta_v,
+ eta_i,
+ xi_ks,
+ phi_f,
+ chi_kh,
+ rho_rh,
+ upsilon_y,
+ lunatesigma_s
+ } = transliterationStyle ?? {};
const mapping = declaredMapping ?? new Mapping(options);
- if (setTransliterationStyle?.upsilon_y) str = flagDiaereses(str, fromType);
+ if (upsilon_y) str = flagDiaereses(str, fromType);
+
+ if (fromType === KeyType.TLG_BETA_CODE) {
+ str = fromTLG(str);
+ fromType = KeyType.BETA_CODE;
+ }
switch (fromType) {
case KeyType.BETA_CODE:
+ str = bcReorderDiacritics(str);
str = bcFlagRoughBreathings(str, options);
- if (removeDiacritics) str = utilRmDiacritics(str, KeyType.BETA_CODE);
- str = mapping.apply(str, KeyType.BETA_CODE, KeyType.TRANSLITERATION);
+ if (removeDiacritics) str = utilRmDiacritics(str, fromType);
+ str = mapping.apply(str, fromType, KeyType.TRANSLITERATION);
str = bcConvertBreathings(str, options);
break;
case KeyType.GREEK:
str = grConvertBreathings(str, options);
- if (removeDiacritics) str = utilRmDiacritics(str, KeyType.GREEK);
+ if (removeDiacritics) str = utilRmDiacritics(str, fromType);
str = utilRmGreekVariants(str);
- str = normalizeGreek(str);
- str = mapping.apply(str, KeyType.GREEK, KeyType.TRANSLITERATION);
+ str = mapping.apply(str, fromType, KeyType.TRANSLITERATION);
break;
case KeyType.TRANSLITERATION:
- const {
- useCxOverMacron,
- xi_ks,
- chi_kh,
- rho_rh,
- upsilon_y,
- lunatesigma_s
- } = setTransliterationStyle ?? {};
-
if (useCxOverMacron) {
const re = new RegExp(`([${mapping.trLettersWithCxOrMacron()}])(${MACRON})`, 'g'); // prettier-ignore
str = str.normalize('NFD').replace(re, `$1${CIRCUMFLEX}`).normalize();
}
+ if (beta_v) {
+ str = str.replace(/b/gi, (m) => (m.toUpperCase() === m ? 'V' : 'v'));
+ }
+
+ if (eta_i) {
+ str = str
+ .normalize('NFD')
+ .replace(/(e)(\p{M}+)/giu, (m, $1, $2) => {
+ if ((useCxOverMacron && /\u0302/.test(m)) || /\u0304/.test(m)) {
+ return $1.toUpperCase() === $1 ? 'I' + $2 : 'i' + $2;
+ }
+ return m;
+ })
+ .normalize();
+ }
+
if (xi_ks) {
- str = str.replace(/x/gi, (match) => {
+ str = str.replace(/x/gi, (m) => {
if (options.isUpperCase) return 'KS';
- else return match.charAt(0).toUpperCase() === match ? 'Ks' : 'ks';
+ else return m.charAt(0).toUpperCase() === m.charAt(0) ? 'Ks' : 'ks';
});
}
+ if (phi_f) {
+ str = str.replace(/ph/gi, (m) =>
+ m.charAt(0).toUpperCase() === m.charAt(0) ? 'F' : 'f'
+ );
+ }
+
if (chi_kh) {
- str = str.replace(/ch/gi, (match) => {
+ str = str.replace(/ch/gi, (m) => {
if (options.isUpperCase) return 'KH';
- else return match.charAt(0).toUpperCase() === match ? 'Kh' : 'kh';
+ else return m.charAt(0).toUpperCase() === m.charAt(0) ? 'Kh' : 'kh';
});
}
if (rho_rh) {
str = str
- .replace(/(?
- match.toUpperCase() === match ? match + 'H' : match + 'h'
+ .replace(/(?
+ m.toUpperCase() === m ? m + 'H' : m + 'h'
)
- .replace(/(?<=\p{P}|\s|^)r/gimu, (match) =>
- options.isUpperCase ? match + 'H' : match + 'h'
+ .replace(/(?<=\p{P}|\s|^)r/gimu, (m) =>
+ options.isUpperCase ? m + 'H' : m + 'h'
);
}
@@ -97,35 +128,32 @@ export function toTransliteration(
}
if (lunatesigma_s) {
- str = str.replace(/c(?!h)/gi, (match) =>
- match.toUpperCase() === match ? 'S' : 's'
+ str = str.replace(/c(?!h)/gi, (m) =>
+ m.toUpperCase() === m ? 'S' : 's'
);
}
if (removeDiacritics) {
str = utilRmDiacritics(
str,
- KeyType.TRANSLITERATION,
+ fromType,
mapping.trLettersWithCxOrMacron(),
useCxOverMacron
);
}
- str = mapping.apply(
- str,
- KeyType.TRANSLITERATION,
- KeyType.TRANSLITERATION
- );
+ str = mapping.apply(str, fromType, fromType);
break;
}
- if (setTransliterationStyle?.upsilon_y) {
- str = applyUpsilonDiphthongs(str);
- str = str.replace(/@/gm, '');
+ if (upsilon_y) {
+ str = applyUpsilonDiphthongs(str, options, mapping).replace(/@/gm, '');
}
if (removeExtraWhitespace) str = utilRmExtraWhitespace(str);
+ str = trApplyCoronis(str, setCoronisStyle);
+
return str.normalize();
}
@@ -133,25 +161,41 @@ export function toTransliteration(
* Returns a transliterated string with correct upsilon forms.
*
* @remarks
- * This applies to the `transliterationStyle.upsilon_y` option.
+ * This applies to the `transliterationStyle.upsilon_y` option. If its
+ * value has been set to `Preset.ISO`, diphthongs 'au', 'eu', 'ou' only
+ * will be preserved.
*
* @privateRemarks
- * (1) Upsilon diphthongs are: 'au', 'eu', 'ēu', 'ou', 'ui', 'ōu'.
+ * (1) The expected input form of the upsilon is 'y'.
+ * (2) Upsilon diphthongs to preserve are: 'au', 'eu', 'ēu', 'ou', 'ui', 'ōu'.
* (2) The given string's diaereses should have been flagged as '@' using
* the `flagDiaereses()` function.
*/
-function applyUpsilonDiphthongs(transliteratedStr: string): string {
- const vowels = 'aeēioyō';
- // `vowelsGroup` includes the upsilon ('y'), the diaeresis flag '@'.
- const reUpsilonDiphthongs = new RegExp(`([${vowels}\\p{M}@]{2,})`, 'gimu'); // prettier-ignore
+function applyUpsilonDiphthongs(
+ transliteratedStr: string,
+ options: IInternalConversionOptions,
+ mapping: Mapping
+): string {
+ const { transliterationStyle } = options;
+ const reUpsilonDiphthongs = new RegExp(`([aeēioyō\\p{M}@]{2,})`, 'gimu');
return transliteratedStr
.normalize('NFD')
- .replace(reUpsilonDiphthongs, (match, vowelsGroup) => {
+ .replace(reUpsilonDiphthongs, (m, vowelsGroup) => {
if (!/y/i.test(vowelsGroup)) return vowelsGroup;
if (/* flagged diaeresis */ /@/.test(vowelsGroup)) return vowelsGroup;
if (vowelsGroup.normalize().length === 1) return vowelsGroup;
+ if (transliterationStyle?.upsilon_y === Preset.ISO) {
+ const unaccentedGroup = utilRmDiacritics(
+ vowelsGroup,
+ KeyType.TRANSLITERATION,
+ mapping.trLettersWithCxOrMacron(),
+ transliterationStyle?.useCxOverMacron
+ );
+ if (!/ay|ey|oy/i.test(unaccentedGroup)) return vowelsGroup;
+ }
+
return vowelsGroup.replace(/Y/, 'U').replace(/y/, 'u');
})
.normalize();
@@ -163,7 +207,7 @@ function applyUpsilonDiphthongs(transliteratedStr: string): string {
* @remarks
* This function does:
* 1. convert flagged rough breathings;
- * 2. enforce rough breathings on rhos if `setTransliterationStyle.rho_rh` is enabled;
+ * 2. enforce rough breathings on rhos if `transliterationStyle.rho_rh` is enabled;
* 3. remove initial smooth breathings (while keeping coronides);
* 4. remove potential smooth breathings on rhos.
* 5. transliterate the remaining smooth breathings.
@@ -176,21 +220,20 @@ function bcConvertBreathings(
transliteratedStr: string,
options: IInternalConversionOptions
): string {
- const { isUpperCase, setTransliterationStyle } = options;
- const rho_rh = setTransliterationStyle?.rho_rh;
+ const { isUpperCase, transliterationStyle } = options;
transliteratedStr = transliteratedStr
.replace(/\$\$/g, 'H')
.replace(/\$/g, 'h');
- if (rho_rh) {
+ if (transliterationStyle?.rho_rh) {
transliteratedStr = transliteratedStr
- .replace(new RegExp(`(r${SMOOTH_BREATHING}?r)(?!h)`, 'gi'), (match) =>
- match.toUpperCase() === match ? 'RRH' : 'rrh'
+ .replace(new RegExp(`(r${SMOOTH_BREATHING}?r)(?!h)`, 'gi'), (m) =>
+ m.toUpperCase() === m ? 'RRH' : 'rrh'
)
- .replace(/(?<=\p{P}|\\s|^)(r)(?!h)/gimu, (match) =>
- // @fixme(v0.13): case should be checked against the current word.
- isUpperCase ? match + 'H' : match + 'h'
+ .replace(/(?<=\p{P}|\\s|^)(r)(?!h)/gimu, (m) =>
+ // @fixme(v0.14): case should be checked against the current word.
+ isUpperCase ? m + 'H' : m + 'h'
);
}
@@ -219,8 +262,8 @@ function bcFlagRoughBreathings(
const { isUpperCase } = options;
return betaCodeStr
- .replace(/([aehiouw]{1,2})\(/gi, (match, vowelsGroup) => {
- // @fixme(v0.13): case should be checked against the current word too.
+ .replace(/([aehiouw]{1,2})\(/gi, (m, vowelsGroup) => {
+ // @fixme(v0.14): case should be checked against the current word too.
if (isUpperCase) return '$$' + vowelsGroup;
else {
return vowelsGroup.charAt(0).toUpperCase() === vowelsGroup.charAt(0)
@@ -228,7 +271,7 @@ function bcFlagRoughBreathings(
: '$' + vowelsGroup;
}
})
- .replace(/(r{1,2})\(/gi, (match, rho) =>
+ .replace(/(r{1,2})\(/gi, (m, rho) =>
isUpperCase ? rho + '$$' : rho + '$'
);
}
@@ -266,8 +309,8 @@ function grConvertBreathings(
greekStr: string,
options: IInternalConversionOptions
): string {
- const { isUpperCase, setTransliterationStyle } = options;
- const rho_rh = setTransliterationStyle?.rho_rh;
+ const { isUpperCase, transliterationStyle } = options;
+ const { rho_rh } = transliterationStyle ?? {};
const reInitialSmooth = new RegExp(`(?<=\\p{P}|\\s|^)([αεηιουω]{1,2})(${SMOOTH_BREATHING})`, 'gimu'); // prettier-ignore
const reInitialRough = new RegExp(`([αεηιοωυ]{1,2})(${ROUGH_BREATHING})`, 'gi'); // prettier-ignore
@@ -275,14 +318,11 @@ function grConvertBreathings(
const reInitialRho = new RegExp(`(ρ)${ROUGH_BREATHING}`, 'gi');
const reInitialRhoLazy = new RegExp(`(?<=\\p{P}|\\s|^)(ρ)${ROUGH_BREATHING}?`, 'gimu'); // prettier-ignore
- // Change the coronis form after `reInitialSmooth`,
- // by replacing the remaining smooth breathings (e. g.
- // `.replace(new RegExp(SMOOTH_BREATHING, 'g'), CORONIS)`).
return greekStr
.normalize('NFD')
.replace(reInitialSmooth, '$1')
- .replace(reInitialRough, (match, vowelsGroup) => {
- // @fixme(v0.13): case should be checked against the current word too.
+ .replace(reInitialRough, (m, vowelsGroup) => {
+ // @fixme(v0.14): case should be checked against the current word too.
if (isUpperCase) return 'H' + vowelsGroup;
else {
return vowelsGroup.charAt(0).toUpperCase() === vowelsGroup.charAt(0)
@@ -290,11 +330,53 @@ function grConvertBreathings(
: 'h' + vowelsGroup;
}
})
- .replace(reDoubleRhoLazy, (match, doubleRho) =>
+ .replace(reDoubleRhoLazy, (m, doubleRho) =>
doubleRho.toUpperCase() === doubleRho ? 'RRH' : 'rrh'
)
- .replace(rho_rh ? reInitialRhoLazy : reInitialRho, (match, initialRho) =>
+ .replace(rho_rh ? reInitialRhoLazy : reInitialRho, (m, initialRho) =>
isUpperCase ? initialRho + 'H' : initialRho + 'h'
)
.normalize();
}
+
+/**
+ * Returns a transliterated string with converted coronides,
+ * following the given `coronisStyle`.
+ */
+function trApplyCoronis(
+ transliteratedStr: string,
+ coronisStyle?: Coronis
+): string {
+ transliteratedStr = transliteratedStr
+ .normalize('NFD')
+ .replace(
+ new RegExp(`(?<=\\S)${Coronis.APOSTROPHE}(?=\\S)`, 'gu'),
+ SMOOTH_BREATHING
+ );
+
+ switch (coronisStyle) {
+ case Coronis.APOSTROPHE:
+ transliteratedStr = transliteratedStr.replace(
+ new RegExp(`(${SMOOTH_BREATHING})(\\p{M}*)`, 'gu'),
+ (m, $1, $2) => $2 + Coronis.APOSTROPHE
+ );
+ break;
+
+ case Coronis.NO:
+ transliteratedStr = transliteratedStr.replace(
+ new RegExp(SMOOTH_BREATHING, 'g'),
+ ''
+ );
+ break;
+
+ case Coronis.PSILI:
+ default:
+ transliteratedStr = transliteratedStr.replace(
+ new RegExp(`(\\p{M}*)(${SMOOTH_BREATHING})`, 'gu'),
+ (m, $1, $2) => $2 + $1
+ );
+ break;
+ }
+
+ return transliteratedStr.normalize();
+}
diff --git a/src/utils.ts b/src/utils.ts
index 9b59ee3..d3c8cd4 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -65,6 +65,55 @@ export function applyUppercaseChars(transliteratedStr: string): string {
});
}
+/**
+ * Takes a TLG beta code string and returns a beta code string following
+ * the `greek-conversion` convention.
+ */
+export function fromTLG(betaCodeStr: string): string {
+ return betaCodeStr
+ .toLowerCase()
+ .replace(
+ /(\*)([\(\)\\\/\+=\|\?]*)([a-z])/g,
+ (m, $1, $2, $3) => $3.toUpperCase() + $2
+ );
+}
+
+/**
+ * Takes a beta code string following the `greek-conversion` convention
+ * and returns a TLG beta code string.
+ *
+ * @remarks
+ * The iota subscript must remain after its base letter.
+ */
+export function toTLG(betaCodeStr: string): string {
+ return betaCodeStr
+ .replace(/([a-z])([\(\)\\\/\+=\?]*)/gi, (m, $1, $2) => {
+ if ($1.toUpperCase() === $1) return '*' + $2 + $1;
+ else return m;
+ })
+ .toUpperCase();
+}
+
+/**
+ * Returns a beta code string with a correct diacritics order.
+ *
+ * @remarks
+ * The correct order seems to be: (1) breathings; (2) diaereses; (3) accents;
+ * (4) iota subscript; (5) dot below.
+ */
+export function bcReorderDiacritics(betaCodeStr: string): string {
+ return betaCodeStr.replace(
+ /([\(\)\\\/\+=\|\?]{2,})/gi,
+ (match, diacritics) => {
+ const order: string[] = [')', '(', '+', '/', '\\', '=', '|', '?'];
+ return diacritics
+ .split('')
+ .sort((a: string, b: string) => order.indexOf(a) - order.indexOf(b))
+ .join('');
+ }
+ );
+}
+
/**
* Returns an `IInternalConversionOptions` from a (mixed) preset or
* a plain `IConversionOptions` object submitted by an end user.
@@ -79,6 +128,9 @@ export function handleOptions(
settings = applyPreset(settings);
}
+ // Determining the case of a TLG string involves converting it.
+ if (fromType === KeyType.TLG_BETA_CODE) str = fromTLG(str);
+
return {
isUpperCase: isUpperCase(str, fromType),
...settings
@@ -114,13 +166,24 @@ export function isUpperCase(str: string, type: KeyType): boolean {
* (2) Due to the poor Unicode canonical equivalences, any subsequent
* normalization may break the replacements made by this function.
*/
-export function normalizeGreek(greekStr: string): string {
- return greekStr
- .normalize('NFD')
- .replace(new RegExp(LATIN_TILDE, 'g'), GREEK_TILDE)
- .normalize()
- .replace(new RegExp(MIDDLE_DOT, 'g'), ANO_TELEIA)
- .replace(new RegExp(';', 'g'), GREEK_QUESTION_MARK);
+export function normalizeGreek(
+ greekStr: string,
+ useGreekQuestionMark: boolean = false,
+ skipUnicodeNormalization: boolean = false
+): string {
+ if (!skipUnicodeNormalization) greekStr = greekStr.normalize('NFD');
+
+ greekStr = greekStr.replace(new RegExp(LATIN_TILDE, 'g'), GREEK_TILDE);
+
+ if (!skipUnicodeNormalization) greekStr = greekStr.normalize();
+
+ greekStr = greekStr.replace(new RegExp(MIDDLE_DOT, 'g'), ANO_TELEIA);
+
+ if (useGreekQuestionMark) {
+ greekStr = greekStr.replace(new RegExp(';', 'g'), GREEK_QUESTION_MARK);
+ }
+
+ return greekStr;
}
/**
@@ -195,6 +258,6 @@ export function removeExtraWhitespace(str: string): string {
return str.replace(/(\s)+/g, '$1').trim();
}
-export function sanitizeRegExpString(str): string {
+export function sanitizeRegExpString(str: string): string {
return str.replace(/[#-.]|[[-^]|[?|{}]/g, '\\$&');
}
diff --git a/tests/GreekString.test.ts b/tests/GreekString.test.ts
index 2632879..215511d 100644
--- a/tests/GreekString.test.ts
+++ b/tests/GreekString.test.ts
@@ -75,7 +75,7 @@ describe('GreekString', () => {
test('From gr: Enabling/Disabling beta variant', () => {
const gs1 = new GreekString('βάρβαρος', KeyType.GREEK)
const gs2 = new GreekString('βάρβαρος', KeyType.GREEK, {
- setGreekStyle: {
+ greekStyle: {
disableBetaVariant: true
}
})
@@ -107,7 +107,7 @@ describe('GreekString', () => {
expect(gs2.transliteration).toBe('sphínx, tunchánō')
const gs3 = new GreekString('σφίγξ, τυγχάνω', KeyType.GREEK, {
- setTransliterationStyle: {
+ transliterationStyle: {
xi_ks: true,
chi_kh: true
}
@@ -135,7 +135,7 @@ describe('GreekString', () => {
expect(gs2.transliteration).toBe('sphínx, tunchánō')
const gs3 = new GreekString('sphínks, tunkhánō', KeyType.TRANSLITERATION, {
- setTransliterationStyle: {
+ transliterationStyle: {
xi_ks: true,
chi_kh: true
}
@@ -149,7 +149,7 @@ describe('GreekString', () => {
test('From tr: using circumflex on long vowels', () => {
const gs = new GreekString('ánthrôpos', KeyType.TRANSLITERATION, {
- setTransliterationStyle: {
+ transliterationStyle: {
useCxOverMacron: true
}
})
@@ -182,7 +182,7 @@ describe('GreekString', () => {
expect(gs1.transliteration).toBe('ánthrōpos')
const trStyleGs2: IConversionOptions = {
- setTransliterationStyle: {
+ transliterationStyle: {
lunatesigma_s: false
}
}
@@ -194,7 +194,7 @@ describe('GreekString', () => {
expect(gs2.transliteration).toBe('anthrōpos')
const trStyleGs3: IConversionOptions = {
- useAdditionalChars: undefined
+ additionalChars: undefined
}
const gs3 = new GreekString('a)/nqrwpos3', KeyType.BETA_CODE, [Preset.ALA_LC, trStyleGs3])
@@ -204,7 +204,7 @@ describe('GreekString', () => {
expect(gs3.transliteration).toBe('anthrōpos3')
const trStyleGs4: IConversionOptions = {
- useAdditionalChars: AdditionalChar.DIGAMMA
+ additionalChars: AdditionalChar.DIGAMMA
}
const gs4 = new GreekString('a)/nqrwpos3', KeyType.BETA_CODE, [Preset.ALA_LC, trStyleGs4])
@@ -214,7 +214,7 @@ describe('GreekString', () => {
expect(gs4.transliteration).toBe('anthrōpos3')
const trStyleGs5: IConversionOptions = {
- useAdditionalChars: AdditionalChar.LUNATE_SIGMA,
+ additionalChars: AdditionalChar.LUNATE_SIGMA,
removeExtraWhitespace: true
}
const gs5 = new GreekString('a)/nqrwpos3', KeyType.BETA_CODE, [Preset.ALA_LC, trStyleGs5])
@@ -227,7 +227,7 @@ describe('GreekString', () => {
test('Testing upsilon_y', () => {
const options = {
- setTransliterationStyle: {
+ transliterationStyle: {
upsilon_y: true
}
}
@@ -238,10 +238,10 @@ describe('GreekString', () => {
test('Testing lunatesigma_s w/ additional chars enabled', () => {
const options = {
- setTransliterationStyle: {
+ transliterationStyle: {
lunatesigma_s: true
},
- useAdditionalChars: AdditionalChar.ALL
+ additionalChars: AdditionalChar.ALL
}
const gs = new GreekString('purós, ouranós, aülos', KeyType.TRANSLITERATION, options)
diff --git a/tests/toBetaCode.test.ts b/tests/toBetaCode.test.ts
index e353451..60319ad 100644
--- a/tests/toBetaCode.test.ts
+++ b/tests/toBetaCode.test.ts
@@ -1,4 +1,4 @@
-import { AdditionalChar, KeyType, toBetaCode } from '../src/index'
+import { AdditionalChar, Coronis, KeyType, Preset, toBetaCode } from '../src/index'
/*
* Special characters:
@@ -14,6 +14,9 @@ const aristotle = {
}
describe('From greek to beta code', () => {
+
+ // Basic conversion
+
test.each`
str | expected
${'ἄνθρωπος'} | ${'a)/nqrwpos'}
@@ -31,6 +34,8 @@ describe('From greek to beta code', () => {
${aristotle.gr} | ${aristotle.bc}
`('Basic conversion', ({ str, expected }) => { expect(toBetaCode(str, KeyType.GREEK)).toBe(expected) })
+ // Removing diacritics
+
test.each`
str | expected
${'ανθρωπος'} | ${'anqrwpos'}
@@ -48,10 +53,28 @@ describe('From greek to beta code', () => {
${aristotle.gr} | ${aristotle.bcNoAcc}
`('Removing diacritics', ({ str, expected }) => { expect(toBetaCode(str, KeyType.GREEK, { removeDiacritics: true })).toBe(expected) })
+ // Testing useTLGStyle / TLG preset
+
+ test.each`
+ str | expected
+ ${'ἄνθρωπος'} | ${'A)/NQRWPOS'}
+ ${'Ὁπλίτης'} | ${'*(OPLI/THS'}
+ ${'Ἄϊδα'} | ${'*)/AI+DA'}
+ ${'ΠΟΙῌ͂'} | ${'*P*O*I*=H|'}
+ ${'ῬΌΔΟΣ'} | ${'*(R*/O*D*O*S'}
+ `('Testing useTLGStyle / TLG preset', ({ str, expected }) => {
+ expect(toBetaCode(str, KeyType.GREEK, { betaCodeStyle: { useTLGStyle: true } })).toBe(expected)
+ expect(toBetaCode(str, KeyType.GREEK, Preset.TLG)).toBe(expected)
+ })
+
+ // Disabling beta variant
+
test('Disabling beta variant', () => {
- expect(toBetaCode('βάρβαρος', KeyType.GREEK, { setGreekStyle: { disableBetaVariant: true } })).toBe('ba/rbaros')
+ expect(toBetaCode('βάρβαρος', KeyType.GREEK, { greekStyle: { disableBetaVariant: true } })).toBe('ba/rbaros')
})
+ // Testing rho rules
+
test.each`
str | expected
${'Ρόδος'} | ${'Ro/dos'}
@@ -61,18 +84,24 @@ describe('From greek to beta code', () => {
${'μάρμαρος'} | ${'ma/rmaros'}
`('Testing rho rules', ({ str, expected }) => { expect(toBetaCode(str, KeyType.GREEK)).toBe(expected) })
+ // Applying xi_ks / chi_kh
+
test.each`
str | expected
${'Ξενοφῶν'} | ${'Cenofw=n'}
${'χορηγέω'} | ${'xorhge/w'}
- `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toBetaCode(str, KeyType.GREEK, { setTransliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+ `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toBetaCode(str, KeyType.GREEK, { transliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+
+ // Using additional letters
test('Using additional letters', () => {
- expect(toBetaCode('ϝϜ\u03F3\u037F\u03F2\u03F9\u03DB\u03DAϟϞϙϘϡϠ', KeyType.GREEK, { useAdditionalChars: AdditionalChar.ALL })).toBe('vVjJs3S3#2*#2#1*#1#3*#3#5*#5')
- expect(toBetaCode('ϝϜ\u03F2\u03F9', KeyType.GREEK, { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('vVs3S3')
- expect(toBetaCode('\u03F3\u037F\u03DB\u03DAϟϞϡϠ', KeyType.GREEK, { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('\u03F3\u037F\u03DB\u03DAϟϞϡϠ')
+ expect(toBetaCode('ϝϜ\u03F3\u037F\u03F2\u03F9\u03DB\u03DAϟϞϙϘϡϠ', KeyType.GREEK, { additionalChars: AdditionalChar.ALL })).toBe('vVjJs3S3#2*#2#1*#1#3*#3#5*#5')
+ expect(toBetaCode('ϝϜ\u03F2\u03F9', KeyType.GREEK, { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('vVs3S3')
+ expect(toBetaCode('\u03F3\u037F\u03DB\u03DAϟϞϡϠ', KeyType.GREEK, { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('\u03F3\u037F\u03DB\u03DAϟϞϡϠ')
})
+ // Testing uppercase writing
+
test.each`
str | expected
${'ΒΆΡΒΑΡΟΣ'} | ${'BA/RBAROS'}
@@ -83,18 +112,35 @@ describe('From greek to beta code', () => {
${'ὙΙΌΣ'} | ${'U(IO/S'}
`('Testing uppercase writing', ({ str, expected }) => { expect(toBetaCode(str, KeyType.GREEK)).toBe(expected) })
+ // Testing whitespace behavior
+
test('Testing whitespace behavior', () => {
expect(toBetaCode('αἴξ κριός', KeyType.GREEK)).toBe('ai)/c krio/s')
expect(toBetaCode('αἴξ κριός', KeyType.GREEK, { removeExtraWhitespace: true })).toBe('ai)/c krio/s')
})
+ // Testing correctness with various word separators
+
test('Testing correctness with various word separators', () => {
expect(toBetaCode('Ρόδος\nΡόδος\tΡόδος Ρόδος', KeyType.GREEK)).toBe('Ro/dos\nRo/dos\tRo/dos Ro/dos')
expect(toBetaCode('Ῥόδος\nῬόδος\tῬόδος Ῥόδος', KeyType.GREEK)).toBe('R(o/dos\nR(o/dos\tR(o/dos R(o/dos')
})
+
+ // Testing diacritics order
+
+ test.each`
+ str | expected
+ ${'ἀΰλως'} | ${'a)u+/lws'}
+ ${'ᾖ'} | ${'h)=|'}
+ ${'ᾧ'} | ${'w(=|'}
+ `('Testing diacritics order', ({ str, expected }) => { expect(toBetaCode(str, KeyType.GREEK)).toBe(expected) })
+
})
describe('From transliteration to beta code', () => {
+
+ // Basic conversion
+
test.each`
str | expected
${'ánthrōpos'} | ${'a)/nqrwpos'}
@@ -116,6 +162,8 @@ describe('From transliteration to beta code', () => {
${aristotle.tr} | ${aristotle.bc}
`('Basic conversion', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Removing diacritics
+
test.each`
str | expected
${'ánthrōpos'} | ${'anqrwpos'}
@@ -137,12 +185,29 @@ describe('From transliteration to beta code', () => {
${aristotle.tr} | ${aristotle.bcNoAcc}
`('Removing diacritics', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION, { removeDiacritics: true })).toBe(expected) })
- // @fixme(v0.13)
+ // Testing useTLGStyle / TLG preset
+
+ test.each`
+ str | expected
+ ${'ánthrōpos'} | ${'A)/NQRWPOS'}
+ ${'Hoplítēs'} | ${'*(OPLI/THS'}
+ ${'Áïda'} | ${'*)/AI+DA'}
+ ${'POIȨ̄̃'} | ${'*P*O*I*=H|'}
+ ${'RHÓDOS'} | ${'*(R*/O*D*O*S'}
+ `('Testing useTLGStyle / TLG preset', ({ str, expected }) => {
+ expect(toBetaCode(str, KeyType.TRANSLITERATION, { betaCodeStyle: { useTLGStyle: true } })).toBe(expected)
+ expect(toBetaCode(str, KeyType.TRANSLITERATION, Preset.TLG)).toBe(expected)
+ })
+
+ // Testing the combining dot below
+
test('Testing the combining dot below', () => {
- expect(toBetaCode('Pátroḳlos', KeyType.TRANSLITERATION, { useAdditionalChars: AdditionalChar.ALL })).toBe('Pa/tro#3los')
- expect(toBetaCode('Pátroḳlos', KeyType.TRANSLITERATION, { removeDiacritics: true, useAdditionalChars: AdditionalChar.ALL })).toBe('Patro#3los')
+ expect(toBetaCode('Pátroḳlos', KeyType.TRANSLITERATION, { additionalChars: AdditionalChar.ALL })).toBe('Pa/tro#3los')
+ expect(toBetaCode('Pátroḳlos', KeyType.TRANSLITERATION, { removeDiacritics: true, additionalChars: AdditionalChar.ALL })).toBe('Patro#3los')
})
+ // Testing breathings placement rules
+
test.each`
str | expected
${'Ēṓs'} | ${'H)w/s'}
@@ -152,11 +217,41 @@ describe('From transliteration to beta code', () => {
${'huḯdion'} | ${'u(i+/dion'}
`('Testing breathings placement rules', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Testing coronides
+
test.each`
- str | expected
- ${'ka̓́n'} | ${'ka)/n'}
- ${'tau̓tó'} | ${'tau)to/'}
- `('Testing coronides', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ str | expected
+ ${'ka̓gṓ'} | ${'ka)gw/'}
+ ${'ka̓́n'} | ${'ka)/n'}
+ ${'ka’gṓ'} | ${'ka’gw/'}
+ ${'ká’n'} | ${'ka/’n'}
+ `('Testing coronides', ({ str, expected }) => expect(toBetaCode(str, KeyType.TRANSLITERATION)).toBe(expected))
+
+ // Testing coronides, using coronis style
+
+ test.each`
+ str | expected
+ ${'ka̓gṓ'} | ${'ka)gw/'}
+ ${'ka̓́n'} | ${'ka)/n'}
+ ${'ká’n'} | ${'ka/’n'}
+ `('Testing coronides, using coronis style (PSILI)', ({ str, expected }) => expect(toBetaCode(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.PSILI } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'ka’gṓ'} | ${'ka)gw/'}
+ ${'ká’n'} | ${'ka)/n'}
+ ${'ka̓́n'} | ${'ka)/n'}
+ `('Testing coronides, using coronis style (APOSTROPHE)', ({ str, expected }) => expect(toBetaCode(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.APOSTROPHE } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'ka̓gṓ'} | ${'ka)gw/'}
+ ${'ka’gṓ'} | ${'ka’gw/'}
+ ${'ka̓́n'} | ${'ka)/n'}
+ ${'ká’n'} | ${'ka/’n'}
+ `('Testing coronides, using coronis style (NO)', ({ str, expected }) => expect(toBetaCode(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.NO } })).toBe(expected))
+
+ // Testing rho rules
test.each`
str | expected
@@ -167,18 +262,54 @@ describe('From transliteration to beta code', () => {
${'mármaros'} | ${'ma/rmaros'}
`('Testing rho rules', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Using circumflex on long vowels
+
test.each`
str | expected
${'ánthrôpos'} | ${'a)/nqrwpos'}
${'Hoplítês'} | ${'O(pli/ths'}
${'Xenophỗn'} | ${'Cenofw=n'}
- `('Using circumflex on long vowels', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { useCxOverMacron: true } })).toBe(expected) })
+ `('Using circumflex on long vowels', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION, { transliterationStyle: { useCxOverMacron: true } })).toBe(expected) })
+
+ // Applying beta_v
+
+ test('Applying beta_v', () => {
+ expect(toBetaCode('várvaros', KeyType.TRANSLITERATION, { transliterationStyle: { beta_v: true } }))
+ .toBe('ba/rbaros')
+ })
+
+ // Applying eta_i
+
+ test('Applying eta_i', () => {
+ expect(toBetaCode('hīdonī́', KeyType.TRANSLITERATION, { transliterationStyle: { eta_i: true } }))
+ .toBe('h(donh/')
+ })
+
+ // Applying eta_i, using circumflex
+
+ test('Applying eta_i, using circumflex', () => {
+ expect(toBetaCode('hîdonî́', KeyType.TRANSLITERATION, { transliterationStyle: { useCxOverMacron: true, eta_i: true } }))
+ .toBe('h(donh/')
+ })
+
+ // Applying phi_f
+
+ test.each`
+ str | expected
+ ${'fantasía'} | ${'fantasi/a'}
+ ${'Fainṓ'} | ${'Fainw/'}
+ ${'FILOSOFIA'} | ${'FILOSOFIA'}
+ `('Applying phi_f', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION, { transliterationStyle: { phi_f: true } })).toBe(expected) })
+
+ // Applying xi_ks / chi_kh
test.each`
str | expected
${'Ksenophȭn'} | ${'Cenofw=n'}
${'khorēgéō'} | ${'xorhge/w'}
- `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+ `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION, { transliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+
+ // Applying upsilon_y
test.each`
str | expected
@@ -189,15 +320,19 @@ describe('From transliteration to beta code', () => {
${'hýdōr'} | ${'u(/dwr'}
${'Hýbla'} | ${'U(/bla'}
${'ý hỹ'} | ${'u)/ u(='}
- `('Applying upsilon_y', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { upsilon_y: true } })).toBe(expected) })
+ `('Applying upsilon_y', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION, { transliterationStyle: { upsilon_y: true } })).toBe(expected) })
+
+ // Using additional letters
test('Using additional letters', () => {
- expect(toBetaCode('wWjJcCc̄C̄qQḳḲs̄S̄', KeyType.TRANSLITERATION, { useAdditionalChars: AdditionalChar.ALL })).toBe('vVjJs3S3#2*#2#1*#1#3*#3#5*#5')
- expect(toBetaCode('wWcC', KeyType.TRANSLITERATION, { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('vVs3S3')
- expect(toBetaCode('qQḳḲs̄S̄', KeyType.TRANSLITERATION, { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('qQk?K?s%26S%26')
+ expect(toBetaCode('wWjJcCc̄C̄qQḳḲs̄S̄', KeyType.TRANSLITERATION, { additionalChars: AdditionalChar.ALL })).toBe('vVjJs3S3#2*#2#1*#1#3*#3#5*#5')
+ expect(toBetaCode('wWcC', KeyType.TRANSLITERATION, { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('vVs3S3')
+ expect(toBetaCode('qQḳḲs̄S̄', KeyType.TRANSLITERATION, { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('qQk?K?s%26S%26')
})
- // @fixme(v0.13): check if rough breathings diphthongs rules must be overridden when converting from
+ // Testing uppercase writing
+
+ // @fixme(v0.13.1): check if rough breathings diphthongs rules must be overridden when converting from
// transliteration to beta code, as 'HUIÓS' -> 'UI(O/S' but 'ὙΙΌΣ' produces 'U(IO/S' (greek to beta code).
test.each`
str | expected
@@ -209,8 +344,54 @@ describe('From transliteration to beta code', () => {
${'HUIÓS'} | ${'UI(O/S'}
`('Testing uppercase writing', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Testing whitespace behavior
+
test('Testing whitespace behavior', () => {
expect(toBetaCode('aíx kriós', KeyType.TRANSLITERATION)).toBe('ai)/c krio/s')
expect(toBetaCode('aíx kriós', KeyType.TRANSLITERATION, { removeExtraWhitespace: true })).toBe('ai)/c krio/s')
})
+
+ // Testing diacritics order
+
+ test.each`
+ str | expected
+ ${'aǘlōs'} | ${'a)u+/lws'}
+ ${'ȩ̄̃'} | ${'h)=|'}
+ ${'hō̧̃'} | ${'w(=|'}
+ `('Testing diacritics order', ({ str, expected }) => { expect(toBetaCode(str, KeyType.TRANSLITERATION)).toBe(expected) })
+
+})
+
+describe('Self conversion', () => {
+
+ // Testing useTLGStyle / TLG preset
+
+ test.each`
+ str | expected
+ ${'a)/nqrwpos'} | ${'A)/NQRWPOS'}
+ ${'O(pli/ths'} | ${'*(OPLI/THS'}
+ ${'A)/i+da'} | ${'*)/AI+DA'}
+ ${'POIH=|'} | ${'*P*O*I*=H|'}
+ ${'R(O/DOS'} | ${'*(R*/O*D*O*S'}
+ `('Testing useTLGStyle / TLG preset', ({ str, expected }) => {
+ expect(toBetaCode(str, KeyType.BETA_CODE, { betaCodeStyle: { useTLGStyle: true } })).toBe(expected)
+ expect(toBetaCode(str, KeyType.BETA_CODE, Preset.TLG)).toBe(expected)
+ })
+
+ // Testing TLG beta code input
+
+ test('Testing TLG beta code input', () => {
+ expect(toBetaCode('*(OPLI/THS', KeyType.TLG_BETA_CODE)).toBe('O(pli/ths')
+ expect(toBetaCode('*(OPLI/THS', KeyType.TLG_BETA_CODE, Preset.TLG)).toBe('*(OPLI/THS')
+ })
+
+ // Testing diacritics order
+
+ test.each`
+ str | expected
+ ${'a)u/+lws'} | ${'a)u+/lws'}
+ ${'h|)='} | ${'h)=|'}
+ ${'w|(='} | ${'w(=|'}
+ `('Testing diacritics order', ({ str, expected }) => { expect(toBetaCode(str, KeyType.BETA_CODE)).toBe(expected) })
+
})
diff --git a/tests/toGreek.test.ts b/tests/toGreek.test.ts
index 4570e3a..6e9abda 100644
--- a/tests/toGreek.test.ts
+++ b/tests/toGreek.test.ts
@@ -1,9 +1,10 @@
-import { AdditionalChar, KeyType, toGreek } from '../src/index'
+import { AdditionalChar, Coronis, KeyType, Preset, toGreek } from '../src/index'
/*
* Special characters:
* - \u03D0 = Greek Beta Symbol
* - \u03F2 = Greek Lunate Sigma Symbol
+ * - \u037E = Greek Question Mark
*/
const aristotle = {
@@ -20,10 +21,13 @@ const thucydides = {
const plato = {
tr: 'Chalepón gé se elénxai, ō̃ Sṓkrates; all\' ouchì ka̓̀n paĩs se elénxeien hóti ouk alēthē̃ légeis?',
trCx: 'Chalepón gé se elénxai, ỗ Sốkrates; all\' ouchì ka̓̀n paĩs se elénxeien hóti ouk alêthễ légeis?',
- gr: 'Χαλεπόν γέ σε ἐλέγξαι, ὦ Σώκρατες· ἀλλ\' οὐχὶ κἂν παῖς σε ἐλέγξειεν ὅτι οὐκ ἀληθῆ λέγεις\u037E'
+ gr: 'Χαλεπόν γέ σε ἐλέγξαι, ὦ Σώκρατες· ἀλλ\' οὐχὶ κἂν παῖς σε ἐλέγξειεν ὅτι οὐκ ἀληθῆ λέγεις;'
}
describe('From beta code to greek', () => {
+
+ // Basic conversion
+
test.each`
str | expected
${'a)/nqrwpos'} | ${'ἄνθρωπος'}
@@ -39,6 +43,8 @@ describe('From beta code to greek', () => {
${aristotle.bc} | ${aristotle.gr}
`('Basic conversion', ({ str, expected }) => { expect(toGreek(str, KeyType.BETA_CODE)).toBe(expected) })
+ // Removing diacritics
+
test.each`
str | expected
${'a)/nqrwpos'} | ${'ανθρωπος'}
@@ -54,28 +60,42 @@ describe('From beta code to greek', () => {
${aristotle.bc} | ${aristotle.grNoAcc}
`('Removing diacritics', ({ str, expected }) => { expect(toGreek(str, KeyType.BETA_CODE, { removeDiacritics: true })).toBe(expected) })
- // v0.13
- /*test.each`
- str | expected
- ${')/ANQRWPOS'} | ${'ἄνθρωπος'}
- ${'POIH|='} | ${'ποιῇ'}
- ${')/*AI+DA'} | ${'Ἄϊδα'}
- ${'BA/RBAROS'} | ${'βάρ\u03D0αρος'}
- ${'(*OPLI/THS'} | ${'Ὁπλίτης'}
- ${'(*Opli/ths'} | ${'Ὁπλίτης'}
- ${'NOI='} | ${'vοῖ'}
- ${'(/AGIOS3'} | ${'ἅγιοσ3'}
- `('Testing TLG preset', ({ str, expected }) => { expect(toGreek(str, KeyType.BETA_CODE, Preset.TLG)).toBe(expected) })*/
+ // Testing useTLGStyle / TLG preset
+
+ test.each`
+ str | expected
+ ${'A)/NQRWPOS'} | ${'ἄνθρωπος'}
+ ${'A)/nqrwpos'} | ${'ἄνθρωπος'}
+ ${'a)/nqrwpos'} | ${'ἄνθρωπος'}
+ ${'*(OPLI/THS'} | ${'Ὁπλίτης'}
+ ${'*(Opli/ths'} | ${'Ὁπλίτης'}
+ ${'*(opli/ths'} | ${'Ὁπλίτης'}
+ ${'*)/AI+DA'} | ${'Ἄϊδα'}
+ ${'*)/ai+da'} | ${'Ἄϊδα'}
+ ${'*P*O*I*=H|'} | ${'ΠΟΙῌ͂'}
+ ${'*p*o*i*=|h'} | ${'ΠΟΙῌ͂'}
+ ${'*(R*/O*D*O*S'} | ${'ῬΌΔΟΣ'}
+ ${'*(r*/o*d*o*s'} | ${'ῬΌΔΟΣ'}
+ `('Testing useTLGStyle / TLG preset', ({ str, expected }) => {
+ expect(toGreek(str, KeyType.TLG_BETA_CODE)).toBe(expected)
+ expect(toGreek(str, KeyType.TLG_BETA_CODE)).toBe(expected)
+ })
+
+ // Disabling beta variant
test('Disabling beta variant', () => {
- expect(toGreek('ba/rbaros', KeyType.BETA_CODE, { setGreekStyle: { disableBetaVariant: true } })).toBe('βάρβαρος')
+ expect(toGreek('ba/rbaros', KeyType.BETA_CODE, { greekStyle: { disableBetaVariant: true } })).toBe('βάρβαρος')
})
+ // Using lunate sigma
+
test('Using lunate sigma', () => {
expect(toGreek('I)hsou=s Xristo\\s Qeou= Ui(o\\s Swth/r', KeyType.BETA_CODE)).toBe('Ἰησοῦς Χριστὸς Θεοῦ Υἱὸς Σωτήρ')
- expect(toGreek('I)hsou=s Xristo\\s Qeou= Ui(o\\s Swth/r', KeyType.BETA_CODE, { setGreekStyle: { useLunateSigma: true } })).toBe('Ἰη\u03F2οῦ\u03F2 Χρι\u03F2τὸ\u03F2 Θεοῦ Υἱὸ\u03F2 \u03F9ωτήρ')
+ expect(toGreek('I)hsou=s Xristo\\s Qeou= Ui(o\\s Swth/r', KeyType.BETA_CODE, { greekStyle: { useLunateSigma: true } })).toBe('Ἰη\u03F2οῦ\u03F2 Χρι\u03F2τὸ\u03F2 Θεοῦ Υἱὸ\u03F2 \u03F9ωτήρ')
})
+ // Testing rho rules
+
test.each`
str | expected
${'Ro/dos'} | ${'Ρόδος'}
@@ -85,13 +105,16 @@ describe('From beta code to greek', () => {
${'ma/rmaros'} | ${'μάρμαρος'}
`('Testing rho rules', ({ str, expected }) => { expect(toGreek(str, KeyType.BETA_CODE)).toBe(expected) })
+ // Using additional letters
+
test('Using additional letters', () => {
- expect(toGreek('vVjJs3S3#2*#2#1*#1#3*#3#5*#5', KeyType.BETA_CODE, { useAdditionalChars: AdditionalChar.ALL })).toBe('ϝϜ\u03F3\u037F\u03F2\u03F9\u03DB\u03DAϟϞϙϘϡϠ')
- expect(toGreek('vVs3S3', KeyType.BETA_CODE, { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('ϝϜ\u03F2\u03F9')
- expect(toGreek('#1*#1#3*#3#5*#5', KeyType.BETA_CODE, { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('#1*#1#3*#3#5*#5')
+ expect(toGreek('vVjJs3S3#2*#2#1*#1#3*#3#5*#5', KeyType.BETA_CODE, { additionalChars: AdditionalChar.ALL })).toBe('ϝϜ\u03F3\u037F\u03F2\u03F9\u03DB\u03DAϟϞϙϘϡϠ')
+ expect(toGreek('vVs3S3', KeyType.BETA_CODE, { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('ϝϜ\u03F2\u03F9')
+ expect(toGreek('#1*#1#3*#3#5*#5', KeyType.BETA_CODE, { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('#1*#1#3*#3#5*#5')
})
- // @fixme(v0.13):
+ // Testing uppercase writing
+
test.each`
str | expected
${'BA/RBAROS'} | ${'ΒΆΡΒΑΡΟΣ'}
@@ -103,14 +126,16 @@ describe('From beta code to greek', () => {
${'UI(O/S'} | ${'ὙΙΌΣ'}
`('Testing uppercase writing', ({ str, expected }) => { expect(toGreek(str, KeyType.BETA_CODE)).toBe(expected) })
+ // Testing whitespace behavior
+
test('Testing whitespace behavior', () => {
expect(toGreek('ai)/c krio/s', KeyType.BETA_CODE)).toBe('αἴξ κριός')
expect(toGreek('ai)/c krio/s', KeyType.BETA_CODE, { removeExtraWhitespace: true })).toBe('αἴξ κριός')
})
- // v0.13
- // Broken orders: `w|=(`, `w=(|`, `w=|(`.
- /*test.each`
+ // Testing various diacritics order
+
+ test.each`
str | expected
${'w(|='} | ${'ᾧ'}
${'w(=|'} | ${'ᾧ'}
@@ -118,10 +143,14 @@ describe('From beta code to greek', () => {
${'w|=('} | ${'ᾧ'}
${'w=(|'} | ${'ᾧ'}
${'w=|('} | ${'ᾧ'}
- `('Applying various diacritics order', ({ str, expected }) => { expect(toGreek(str, KeyType.BETA_CODE)).toBe(expected) })*/
+ `('Testing various diacritics order', ({ str, expected }) => { expect(toGreek(str, KeyType.BETA_CODE)).toBe(expected) })
+
})
describe('From transliteration to greek', () => {
+
+ // Basic conversion
+
test.each`
str | expected
${'ánthrōpos'} | ${'ἄνθρωπος'}
@@ -143,6 +172,8 @@ describe('From transliteration to greek', () => {
${plato.tr} | ${plato.gr}
`('Basic conversion', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Removing diacritics
+
test.each`
str | expected
${'ánthrōpos'} | ${'ανθρωπος'}
@@ -164,6 +195,8 @@ describe('From transliteration to greek', () => {
${thucydides.trNoAcc} | ${thucydides.grNoAcc}
`('Removing diacritics', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { removeDiacritics: true })).toBe(expected) })
+ // Testing breathings placement rules
+
test.each`
str | expected
${'Ēṓs'} | ${'Ἠώς'}
@@ -173,11 +206,41 @@ describe('From transliteration to greek', () => {
${'huḯdion'} | ${'ὑΐδιον'}
`('Testing breathings placement rules', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Testing coronides
+
test.each`
- str | expected
- ${'ka̓́n'} | ${'κἄν'}
- ${'tau̓tó'} | ${'ταὐτό'}
- `('Testing coronides', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ str | expected
+ ${'ka̓gṓ'} | ${'κἀγώ'}
+ ${'ka̓́n'} | ${'κἄν'}
+ ${'ka’gṓ'} | ${'κα’γώ'}
+ ${'ká’n'} | ${'κά’ν'}
+ `('Testing coronides', ({ str, expected }) => expect(toGreek(str, KeyType.TRANSLITERATION)).toBe(expected))
+
+ // Testing coronides, using coronis style
+
+ test.each`
+ str | expected
+ ${'ka̓gṓ'} | ${'κἀγώ'}
+ ${'ka̓́n'} | ${'κἄν'}
+ ${'ká’n'} | ${'κά’ν'}
+ `('Testing coronides, using coronis style (PSILI)', ({ str, expected }) => expect(toGreek(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.PSILI } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'ka’gṓ'} | ${'κἀγώ'}
+ ${'ká’n'} | ${'κἄν'}
+ ${'ka̓́n'} | ${'κἄν'}
+ `('Testing coronides, using coronis style (APOSTROPHE)', ({ str, expected }) => expect(toGreek(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.APOSTROPHE } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'ka̓gṓ'} | ${'κἀγώ'}
+ ${'ka’gṓ'} | ${'κα’γώ'}
+ ${'ka̓́n'} | ${'κἄν'}
+ ${'ká’n'} | ${'κά’ν'}
+ `('Testing coronides, using coronis style (NO)', ({ str, expected }) => expect(toGreek(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.NO } })).toBe(expected))
+
+ // Testing gamma nasals
test.each`
str | expected
@@ -188,28 +251,38 @@ describe('From transliteration to greek', () => {
${'tunchánō'} | ${'τυγχάνω'}
`('Testing gamma nasals', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Testing gamma nasals with xi_ks / chi_kh enabled
+
test.each`
str | expected
${'sphínks'} | ${'σφίγξ'}
${'tunkhánō'} | ${'τυγχάνω'}
- `('Testing gamma nasals with xi_ks / chi_kh enabled', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+ `('Testing gamma nasals with xi_ks / chi_kh enabled', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { transliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+
+ // Disabling beta variant
test('Disabling beta variant', () => {
- expect(toGreek('bárbaros', KeyType.TRANSLITERATION, { setGreekStyle: { disableBetaVariant: true } })).toBe('βάρβαρος')
+ expect(toGreek('bárbaros', KeyType.TRANSLITERATION, { greekStyle: { disableBetaVariant: true } })).toBe('βάρβαρος')
})
+ // Using lunate sigma
+
test('Using lunate sigma', () => {
expect(toGreek('Iēsoũs Christòs Theoũ Huiòs Sōtḗr', KeyType.TRANSLITERATION)).toBe('Ἰησοῦς Χριστὸς Θεοῦ Υἱὸς Σωτήρ')
- expect(toGreek('Iēsoũs Christòs Theoũ Huiòs Sōtḗr', KeyType.TRANSLITERATION, { setGreekStyle: { useLunateSigma: true } })).toBe('Ἰη\u03F2οῦ\u03F2 Χρι\u03F2τὸ\u03F2 Θεοῦ Υἱὸ\u03F2 \u03F9ωτήρ')
+ expect(toGreek('Iēsoũs Christòs Theoũ Huiòs Sōtḗr', KeyType.TRANSLITERATION, { greekStyle: { useLunateSigma: true } })).toBe('Ἰη\u03F2οῦ\u03F2 Χρι\u03F2τὸ\u03F2 Θεοῦ Υἱὸ\u03F2 \u03F9ωτήρ')
})
+ // Using circumflex on long vowels
+
test.each`
str | expected
${'ánthrôpos'} | ${'ἄνθρωπος'}
${'Hoplítês'} | ${'Ὁπλίτης'}
${'Xenophỗn'} | ${'Ξενοφῶν'}
${plato.trCx} | ${plato.gr}
- `('Using circumflex on long vowels', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { useCxOverMacron: true } })).toBe(expected) })
+ `('Using circumflex on long vowels', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { transliterationStyle: { useCxOverMacron: true } })).toBe(expected) })
+
+ // Testing rho rules
test.each`
str | expected
@@ -220,11 +293,44 @@ describe('From transliteration to greek', () => {
${'mármaros'} | ${'μάρμαρος'}
`('Testing rho rules', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Applying beta_v
+ test('Applying beta_v', () => {
+ expect(toGreek('várvaros', KeyType.TRANSLITERATION, { transliterationStyle: { beta_v: true } }))
+ .toBe('βάρ\u03D0αρος')
+ })
+
+ // Applying eta_i
+
+ test('Applying eta_i', () => {
+ expect(toGreek('hīdonī́', KeyType.TRANSLITERATION, { transliterationStyle: { eta_i: true } }))
+ .toBe('ἡδονή')
+ })
+
+ // Applying eta_i, using circumflex
+
+ test('Applying eta_i', () => {
+ expect(toGreek('hîdonî́', KeyType.TRANSLITERATION, { transliterationStyle: { useCxOverMacron: true, eta_i: true } }))
+ .toBe('ἡδονή')
+ })
+
+ // Applying phi_f
+
+ test.each`
+ str | expected
+ ${'fantasía'} | ${'φαντασία'}
+ ${'Fainṓ'} | ${'Φαινώ'}
+ ${'FILOSOFIA'} | ${'ΦΙΛΟΣΟΦΙΑ'}
+ `('Applying phi_f', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { transliterationStyle: { phi_f: true } })).toBe(expected) })
+
+ // Applying xi_ks / chi_kh
+
test.each`
str | expected
${'Ksenophȭn'} | ${'Ξενοφῶν'}
${'khorēgéō'} | ${'χορηγέω'}
- `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+ `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { transliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+
+ // Applying upsilon_y
test.each`
str | expected
@@ -235,14 +341,18 @@ describe('From transliteration to greek', () => {
${'hýdōr'} | ${'ὕδωρ'}
${'Hýbla'} | ${'Ὕϐλα'}
${'ý hỹ'} | ${'ὔ ὗ'}
- `('Applying upsilon_y', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { upsilon_y: true } })).toBe(expected) })
+ `('Applying upsilon_y', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION, { transliterationStyle: { upsilon_y: true } })).toBe(expected) })
+
+ // Using additional letters
test('Using additional letters', () => {
- expect(toGreek('wWjJcCc̄C̄qQḳḲs̄S̄', KeyType.TRANSLITERATION, { useAdditionalChars: AdditionalChar.ALL })).toBe('ϝϜ\u03F3\u037F\u03F2\u03F9\u03DB\u03DAϟϞϙϘϡϠ')
- expect(toGreek('wWcC', KeyType.TRANSLITERATION, { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('ϝϜ\u03F2\u03F9')
- expect(toGreek('qQḳḲs̄S̄', KeyType.TRANSLITERATION, { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('qQκ̣Κ̣σ̄Σ̄')
+ expect(toGreek('wWjJcCc̄C̄qQḳḲs̄S̄', KeyType.TRANSLITERATION, { additionalChars: AdditionalChar.ALL })).toBe('ϝϜ\u03F3\u037F\u03F2\u03F9\u03DB\u03DAϟϞϙϘϡϠ')
+ expect(toGreek('wWcC', KeyType.TRANSLITERATION, { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('ϝϜ\u03F2\u03F9')
+ expect(toGreek('qQḳḲs̄S̄', KeyType.TRANSLITERATION, { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA] })).toBe('qQκ̣Κ̣σ̄Σ̄')
})
+ // Testing uppercase writing
+
test.each`
str | expected
${'BÁRBAROS'} | ${'ΒΆΡΒΑΡΟΣ'}
@@ -253,25 +363,59 @@ describe('From transliteration to greek', () => {
${'HUIÓS'} | ${'ὙΙΌΣ'}
`('Testing uppercase writing', ({ str, expected }) => { expect(toGreek(str, KeyType.TRANSLITERATION)).toBe(expected) })
+ // Testing whitespace behavior
+
test('Testing whitespace behavior', () => {
expect(toGreek('aíx kriós', KeyType.TRANSLITERATION)).toBe('αἴξ κριός')
expect(toGreek('aíx kriós', KeyType.TRANSLITERATION, { removeExtraWhitespace: true })).toBe('αἴξ κριός')
})
+ // Testing correctness with various word separators
+
test('Testing correctness with various word separators', () => {
expect(toGreek('Ródos\nRódos\tRódos Ródos Ródos.', KeyType.TRANSLITERATION)).toBe('Ρόδος\nΡόδος\tΡόδος Ρόδος Ρόδος.')
expect(toGreek('Rhódos\nRhódos\tRhódos Rhódos Rhódos.', KeyType.TRANSLITERATION)).toBe('Ῥόδος\nῬόδος\tῬόδος Ῥόδος Ῥόδος.')
})
+
})
describe('Self conversion', () => {
+
+ // Disabling beta variant
+
test('Disabling beta variant', () => {
const options = {
- setGreekStyle: {
+ greekStyle: {
disableBetaVariant: true
}
}
expect(toGreek('βάρ\u03D0αρος', KeyType.GREEK)).toBe('βάρ\u03D0αρος')
expect(toGreek('βάρ\u03D0αρος', KeyType.GREEK, options)).toBe('βάρβαρος')
})
+
+ // Using greek question mark
+
+ test('Using greek question mark', () => {
+ const options = {
+ greekStyle: {
+ useGreekQuestionMark: true
+ }
+ }
+ expect(toGreek('πῶς;', KeyType.GREEK)).toBe('πῶς;')
+ expect(toGreek('πῶς\u037E', KeyType.GREEK)).toBe('πῶς;')
+ expect(toGreek('πῶς;', KeyType.GREEK, options)).toBe('πῶς\u037E')
+ expect(toGreek('πῶς\u037E', KeyType.GREEK, options)).toBe('πῶς\u037E')
+ })
+
+ // Using lunate sigma
+
+ test('Using lunate sigma', () => {
+ const options = {
+ greekStyle: {
+ useLunateSigma: true
+ }
+ }
+ expect(toGreek('ἅγιος', KeyType.GREEK, options)).toBe('ἅγιο\u03F2')
+ })
+
})
diff --git a/tests/toTransliteration.test.ts b/tests/toTransliteration.test.ts
index f445458..eddd923 100644
--- a/tests/toTransliteration.test.ts
+++ b/tests/toTransliteration.test.ts
@@ -1,4 +1,4 @@
-import { AdditionalChar, KeyType, Preset, toTransliteration } from '../src/index'
+import { AdditionalChar, Coronis, KeyType, Preset, toTransliteration } from '../src/index'
/*
* Special characters:
@@ -60,6 +60,56 @@ describe('From beta code to transliteration', () => {
${aristotle.bc} | ${aristotle.trNoAcc}
`('Removing diacritics', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { removeDiacritics: true })).toBe(expected))
+ // Testing useTLGStyle / TLG preset
+
+ test.each`
+ str | expected
+ ${'A)/NQRWPOS'} | ${'ánthrōpos'}
+ ${'A)/nqrwpos'} | ${'ánthrōpos'}
+ ${'a)/nqrwpos'} | ${'ánthrōpos'}
+ ${'*(OPLI/THS'} | ${'Hoplítēs'}
+ ${'*(Opli/ths'} | ${'Hoplítēs'}
+ ${'*(opli/ths'} | ${'Hoplítēs'}
+ ${'*)/AI+DA'} | ${'Áïda'}
+ ${'*)/ai+da'} | ${'Áïda'}
+ ${'*P*O*I*=H|'} | ${'POIȨ̄̃'}
+ ${'*p*o*i*=|h'} | ${'POIȨ̄̃'}
+ ${'*(R*/O*D*O*S'} | ${'RHÓDOS'}
+ ${'*(r*/o*d*o*s'} | ${'RHÓDOS'}
+ `('Testing useTLGStyle / TLG preset', ({ str, expected }) => {
+ expect(toTransliteration(str, KeyType.TLG_BETA_CODE)).toBe(expected)
+ expect(toTransliteration(str, KeyType.TLG_BETA_CODE)).toBe(expected)
+ })
+
+ // Testing coronides
+
+ test.each`
+ str | expected
+ ${'ka)gw/'} | ${'ka̓gṓ'}
+ ${'ka)/n'} | ${'ka̓́n'}
+ ${'tau)to/'} | ${'tau̓tó'}
+ `('Testing coronides', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE)).toBe(expected))
+
+ // Testing coronides, using coronis style
+
+ test.each`
+ str | expected
+ ${'ka)gw/'} | ${'ka̓gṓ'}
+ ${'ka)/n'} | ${'ka̓́n'}
+ `('Testing coronides, using coronis style (PSILI)', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { transliterationStyle: { setCoronisStyle: Coronis.PSILI } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'ka)gw/'} | ${'ka’gṓ'}
+ ${'ka)/n'} | ${'ká’n'}
+ `('Testing coronides, using coronis style (APOSTROPHE)', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { transliterationStyle: { setCoronisStyle: Coronis.APOSTROPHE } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'ka)gw/'} | ${'kagṓ'}
+ ${'ka)/n'} | ${'kán'}
+ `('Testing coronides, using coronis style (NO)', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { transliterationStyle: { setCoronisStyle: Coronis.NO } })).toBe(expected))
+
// Testing rho rules
test.each`
@@ -84,7 +134,37 @@ describe('From beta code to transliteration', () => {
${'POLU/RRIZOS'} | ${'POLÚRRHIZOS'}
${'polu/r)r(izos'} | ${'polúrrhizos'}
${'ma/rmaros'} | ${'mármaros'}
- `('Testing rho rules, applying rho_rh', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { setTransliterationStyle: { rho_rh: true } })).toBe(expected))
+ `('Testing rho rules, applying rho_rh', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { transliterationStyle: { rho_rh: true } })).toBe(expected))
+
+ // Applying beta_v
+
+ test('Applying beta_v', () => {
+ expect(toTransliteration('ba/rbaros', KeyType.BETA_CODE, { transliterationStyle: { beta_v: true } }))
+ .toBe('várvaros')
+ })
+
+ // Applying eta_i
+
+ test('Applying eta_i', () => {
+ expect(toTransliteration('h(donh/', KeyType.BETA_CODE, { transliterationStyle: { eta_i: true } }))
+ .toBe('hīdonī́')
+ })
+
+ // Applying eta_i, using circumflex
+
+ test('Applying eta_i', () => {
+ expect(toTransliteration('h(donh/', KeyType.BETA_CODE, { transliterationStyle: { useCxOverMacron: true, eta_i: true } }))
+ .toBe('hîdonî́')
+ })
+
+ // Applying phi_f
+
+ test.each`
+ str | expected
+ ${'fantasi/a'} | ${'fantasía'}
+ ${'Fainw/'} | ${'Fainṓ'}
+ ${'FILOSOFIA'} | ${'FILOSOFIA'}
+ `('Applying phi_f', ({ str, expected }) => { expect(toTransliteration(str, KeyType.BETA_CODE, { transliterationStyle: { phi_f: true } })).toBe(expected) })
// Applying upsilon_y
@@ -97,13 +177,28 @@ describe('From beta code to transliteration', () => {
${'u(/dwr'} | ${'hýdōr'}
${'U(/bla'} | ${'Hýbla'}
${'u)/ u(='} | ${'ý hỹ'}
- `('Applying upsilon_y', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { setTransliterationStyle: { upsilon_y: true } })).toBe(expected))
+ `('Applying upsilon_y', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { transliterationStyle: { upsilon_y: true } })).toBe(expected))
+
+ // Applying upsilon_y, preserving diphthongs au/eu/ou only
+
+ test.each`
+ str | expected
+ ${'SOUIDAS'} | ${'SOUIDAS'}
+ ${'mauli/s'} | ${'maulís'}
+ ${'pneu=ma'} | ${'pneũma'}
+ ${'hu)/dwn'} | ${'ēýdōn'}
+ ${'pou='} | ${'poũ'}
+ ${'mui/agros'} | ${'myíagros'}
+ ${'wuto/s'} | ${'ōytós'}
+ `('Applying upsilon_y, preserving diphthongs au/eu/ou only', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE, { transliterationStyle: { upsilon_y: Preset.ISO } })).toBe(expected))
+
+ // Using additional letters
test('Using additional letters', () => {
- const enableAll = { useAdditionalChars: AdditionalChar.ALL }
+ const enableAll = { additionalChars: AdditionalChar.ALL }
expect(toTransliteration('vVjJs3S3#2*#2#1*#1#3*#3#5*#5', KeyType.BETA_CODE, enableAll)).toBe('wWjJcCc̄C̄qQḳḲs̄S̄')
- const enableDigammaAndLunateSigma = { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA]}
+ const enableDigammaAndLunateSigma = { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA]}
expect(toTransliteration('vVs3S3', KeyType.BETA_CODE, enableDigammaAndLunateSigma)).toBe('wWcC')
expect(toTransliteration('#1*#1#3*#3#5*#5', KeyType.GREEK, enableDigammaAndLunateSigma)).toBe('#1*#1#3*#3#5*#5')
})
@@ -127,18 +222,17 @@ describe('From beta code to transliteration', () => {
expect(toTransliteration('ai)/c krio/s', KeyType.BETA_CODE, { removeExtraWhitespace: true })).toBe('aíx kriós')
})
- // Applying various diacritics order
+ // Testing various diacritics order
- // v0.13 - broken orders: `w|=(`, `w=(|`, `w=|(`.
- /*test.each`
+ test.each`
str | expected
- ${'w(|='} | ${'ᾧ'}
- ${'w(=|'} | ${'ᾧ'}
- ${'w|(='} | ${'ᾧ'}
- ${'w|=('} | ${'ᾧ'}
- ${'w=(|'} | ${'ᾧ'}
- ${'w=|('} | ${'ᾧ'}
- `('Applying various diacritics order', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE)).toBe(expected))*/
+ ${'w(|='} | ${'hō̧̃'}
+ ${'w(=|'} | ${'hō̧̃'}
+ ${'w|(='} | ${'hō̧̃'}
+ ${'w|=('} | ${'hō̧̃'}
+ ${'w=(|'} | ${'hō̧̃'}
+ ${'w=|('} | ${'hō̧̃'}
+ `('Testing various diacritics order', ({ str, expected }) => expect(toTransliteration(str, KeyType.BETA_CODE)).toBe(expected))
})
@@ -202,11 +296,32 @@ describe('From greek to transliteration', () => {
// Testing coronides
test.each`
- str | expected
- ${'κἄν'} | ${'ka̓́n'}
- ${'ταὐτό'} | ${'tau̓tó'}
+ str | expected
+ ${'κἀγώ'} | ${'ka̓gṓ'}
+ ${'κἄν'} | ${'ka̓́n'}
+ ${'κηὖ'} | ${'kēu̓̃'}
`('Testing coronides', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK)).toBe(expected))
+ // Testing coronides, using coronis style
+
+ test.each`
+ str | expected
+ ${'κἀγώ'} | ${'ka̓gṓ'}
+ ${'κἄν'} | ${'ka̓́n'}
+ `('Testing coronides, using coronis style (PSILI)', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { setCoronisStyle: Coronis.PSILI } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'κἀγώ'} | ${'ka’gṓ'}
+ ${'κἄν'} | ${'ká’n'}
+ `('Testing coronides, using coronis style (APOSTROPHE)', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { setCoronisStyle: Coronis.APOSTROPHE } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'κἀγώ'} | ${'kagṓ'}
+ ${'κἄν'} | ${'kán'}
+ `('Testing coronides, using coronis style (NO)', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { setCoronisStyle: Coronis.NO } })).toBe(expected))
+
// Testing gamma nasals
test.each`
@@ -224,12 +339,12 @@ describe('From greek to transliteration', () => {
str | expected
${'σφίγξ'} | ${'sphínks'}
${'τυγχάνω'} | ${'tunkhánō'}
- `('Testing gamma nasals with xi_ks / chi_kh enabled', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { setTransliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected))
+ `('Testing gamma nasals with xi_ks / chi_kh enabled', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected))
// Disabling beta variant
test('Disabling beta variant', () => {
- expect(toTransliteration('βάρβαρος', KeyType.GREEK, { setGreekStyle: { disableBetaVariant: true } })).toBe('bárbaros')
+ expect(toTransliteration('βάρβαρος', KeyType.GREEK, { greekStyle: { disableBetaVariant: true } })).toBe('bárbaros')
})
// Testing rho rules
@@ -256,7 +371,7 @@ describe('From greek to transliteration', () => {
${'ΠΟΛΎΡΡΙΖΟΣ'} | ${'POLÚRRHIZOS'}
${'πολύῤῥιζος'} | ${'polúrrhizos'}
${'μάρμαρος'} | ${'mármaros'}
- `('Testing rho rules, applying rho_rh', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { setTransliterationStyle: { rho_rh: true } })).toBe(expected))
+ `('Testing rho rules, applying rho_rh', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { rho_rh: true } })).toBe(expected))
// Using circumflex on long vowels
@@ -266,19 +381,51 @@ describe('From greek to transliteration', () => {
${'Ὁπλίτης'} | ${'Hoplítês'}
${'Ξενοφῶν'} | ${'Xenophỗn'}
${plato.gr} | ${plato.trCrx}
- `('Using circumflex on long vowels', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { setTransliterationStyle: { useCxOverMacron: true } })).toBe(expected))
+ `('Using circumflex on long vowels', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { useCxOverMacron: true } })).toBe(expected))
+
+ // Applying beta_v
+
+ test('Applying beta_v', () => {
+ expect(toTransliteration('βάρ\u03D0αρος', KeyType.GREEK, { transliterationStyle: { beta_v: true } }))
+ .toBe('várvaros')
+ })
+
+ // Applying eta_i
+
+ test('Applying eta_i', () => {
+ expect(toTransliteration('ἡδονή', KeyType.GREEK, { transliterationStyle: { eta_i: true } }))
+ .toBe('hīdonī́')
+ })
+
+ // Applying eta_i, using circumflex
+
+ test('Applying eta_i', () => {
+ expect(toTransliteration('ἡδονή', KeyType.GREEK, { transliterationStyle: { useCxOverMacron: true, eta_i: true } }))
+ .toBe('hîdonî́')
+ })
+
+ // Applying phi_f
+
+ test.each`
+ str | expected
+ ${'φαντασία'} | ${'fantasía'}
+ ${'Φαινώ'} | ${'Fainṓ'}
+ ${'ΦΙΛΟΣΟΦΙΑ'} | ${'FILOSOFIA'}
+ `('Applying phi_f', ({ str, expected }) => { expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { phi_f: true } })).toBe(expected) })
// Applying xi_ks / chi_kh
test.each`
str | expected
+ ${'ΞΕΝΟΦΩΝ'} | ${'KSENOPHŌN'}
${'Ξενοφῶν'} | ${'Ksenophō̃n'}
+ ${'ΧΟΡΗΓΕΩ'} | ${'KHORĒGEŌ'}
${'χορηγέω'} | ${'khorēgéō'}
${'σφίγξ'} | ${'sphínks'}
${'μελαγχολία'} | ${'melankholía'}
${'σφίνξ'} | ${'sphínks'}
${'μελανχολία'} | ${'melankholía'}
- `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toTransliteration(str, KeyType.GREEK, { setTransliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+ `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
// Applying upsilon_y
@@ -292,15 +439,28 @@ describe('From greek to transliteration', () => {
${'ὕδωρ'} | ${'hýdōr'}
${'Ὕϐλα'} | ${'Hýbla'}
${'ὔ ὗ'} | ${'ý hỹ'}
- `('Applying upsilon_y', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { setTransliterationStyle: { upsilon_y: true } })).toBe(expected))
+ `('Applying upsilon_y', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { upsilon_y: true } })).toBe(expected))
+
+ // Applying upsilon_y, preserving diphthongs au/eu/ou only
+
+ test.each`
+ str | expected
+ ${'ΣΟΥΙΔΑΣ'} | ${'SOUIDAS'}
+ ${'μαυλίς'} | ${'maulís'}
+ ${'πνεῦμα'} | ${'pneũma'}
+ ${'ηὔδων'} | ${'ēýdōn'}
+ ${'ποῦ'} | ${'poũ'}
+ ${'μυίαγρος'} | ${'myíagros'}
+ ${'ωὐτός'} | ${'ōytós'}
+ `('Applying upsilon_y, preserving diphthongs au/eu/ou only', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, { transliterationStyle: { upsilon_y: Preset.ISO } })).toBe(expected))
// Using additional letters
test('Using additional letters', () => {
- const enableAll = { useAdditionalChars: AdditionalChar.ALL }
+ const enableAll = { additionalChars: AdditionalChar.ALL }
expect(toTransliteration('ϝϜ\u03F3\u037F\u03F2\u03F9\u03DB\u03DAϟϞϙϘϡϠ', KeyType.GREEK, enableAll)).toBe('wWjJcCc̄C̄qQḳḲs̄S̄')
- const enableDigammaAndLunateSigma = { useAdditionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA]}
+ const enableDigammaAndLunateSigma = { additionalChars: [AdditionalChar.DIGAMMA, AdditionalChar.LUNATE_SIGMA]}
expect(toTransliteration('ϝϜ\u03F2\u03F9', KeyType.GREEK, enableDigammaAndLunateSigma)).toBe('wWcC')
expect(toTransliteration('\u03F3\u037F\u03DB\u03DAϟϞϡϠ', KeyType.GREEK, enableDigammaAndLunateSigma)).toBe('\u03F3\u037F\u03DB\u03DAϟϞϡϠ')
})
@@ -331,7 +491,7 @@ describe('From greek to transliteration', () => {
expect(toTransliteration('Ῥόδος\nῬόδος\tῬόδος Ῥόδος', KeyType.GREEK)).toBe('Rhódos\nRhódos\tRhódos Rhódos')
})
- // Applying preset ALA_LC (the following sentences are given by the ALA-LC romanization table).
+ // Applying preset ALA_LC (the following sentences are given by the ALA-LC romanization table)
test.each`
str | expected
@@ -348,7 +508,7 @@ describe('From greek to transliteration', () => {
${'ὑϊκὸν πάσχειν'} | ${'hyikon paschein'}
${'εἶπε πρὸς τὸν ἄνδρα τὸν ἑωυτῆς'} | ${'eipe pros ton andra ton heōutēs'}
${'τί τοῦδ’ ἂν εὕρημ’ ηὗρον εὐτυχέστερον;'} | ${'ti toud’ an heurēm’ hēuron eutychesteron?'}
- ${'Τοῦ Κατὰ πασῶν αἱρέσεων ἐλέγχου βιβλίον αʹ'} | ${'Tou Kata pasōn haireseōn elenchou biblion 1'}
+ ${'Τοῦ Κατὰ πασῶν αἱρέσεων ἐλέγχου βιβλίον αʹ'} | ${'Tou Kata pasōn haireseōn elenchou biblion 1'}
${'καλὸν κἀγαθόν'} | ${'kalon kagathon'}
${'ᾤχοντο θοἰμάτιον λαβόντες μου'} | ${'ōchonto thoimation labontes mou'}
${'Περὶ ἰλίγγων'} | ${'Peri ilingōn'}
@@ -360,10 +520,55 @@ describe('From greek to transliteration', () => {
${'Πάτροϙλος'} | ${'Patroḳlos'}
`('Applying preset ALA_LC', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, Preset.ALA_LC)).toBe(expected))
+
+ // Applying preset ISO (-> ISO 843 [1997])
+
+ test.each`
+ str | expected
+ ${'Ἡσιόδου τοῦ Ἀσκραίου Ἔργα καὶ ἡμέραι'} | ${'Hīsiódou toũ Askraíou Érga kaì hīmérai'}
+ ${'Ἡ τοῦ Ὁμήρου Ἰλιάς'} | ${'Hī toũ Homī́rou Iliás'}
+ ${'Φίληβος ἢ Περὶ ἡδονῆς'} | ${'Fílīvos ī̀ Perì hīdonī̃s'}
+ ${'Ἀγνώστῳ θεῷ'} | ${'Agnṓstō̧ theō̧̃'}
+ ${'κεῖται παρ’ Ἅιδῃ'} | ${'keĩtai par’ Háidī̧'}
+ `('Applying preset ISO (-> ISO 843 [1997])', ({ str, expected }) => expect(toTransliteration(str, KeyType.GREEK, Preset.ISO)).toBe(expected))
+
})
describe('Self conversion', () => {
+ // Testing coronides
+
+ test.each`
+ str | expected
+ ${'ka̓gṓ'} | ${'ka̓gṓ'}
+ ${'ka̓́n'} | ${'ka̓́n'}
+ ${'ka’gṓ'} | ${'ka̓gṓ'}
+ ${'ká’n'} | ${'ka̓́n'}
+ `('Testing coronides', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION)).toBe(expected))
+
+ // Testing coronides, using coronis style
+
+ test.each`
+ str | expected
+ ${'ka̓gṓ'} | ${'ka̓gṓ'}
+ ${'ka’gṓ'} | ${'ka̓gṓ'}
+ ${'ká’n'} | ${'ka̓́n'}
+ `('Testing coronides, using coronis style (PSILI)', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.PSILI } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'ka̓gṓ'} | ${'ka’gṓ'}
+ ${'ka’gṓ'} | ${'ka’gṓ'}
+ ${'ka̓́n'} | ${'ká’n'}
+ `('Testing coronides, using coronis style (APOSTROPHE)', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.APOSTROPHE } })).toBe(expected))
+
+ test.each`
+ str | expected
+ ${'ka̓gṓ'} | ${'kagṓ'}
+ ${'ka’gṓ'} | ${'kagṓ'}
+ ${'ká’n'} | ${'kán'}
+ `('Testing coronides, using coronis style (NO)', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { setCoronisStyle: Coronis.NO } })).toBe(expected))
+
// Testing rho rules, applying rho_rh
test.each`
@@ -372,7 +577,7 @@ describe('Self conversion', () => {
${'RÓDOS'} | ${'RHÓDOS'}
${'polúrrizos'} | ${'polúrrhizos'}
${'POLÚRRIZOS'} | ${'POLÚRRHIZOS'}
- `('Testing rho rules, applying rho_rh', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { rho_rh: true } })).toBe(expected))
+ `('Testing rho rules, applying rho_rh', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { rho_rh: true } })).toBe(expected))
// Using circumflex on long vowels
@@ -381,17 +586,51 @@ describe('Self conversion', () => {
${'ánthrōpos'} | ${'ánthrôpos'}
${'chorēgéō'} | ${'chorêgéô'}
${'Xenophō̃n'} | ${'Xenophỗn'}
- `('Using circumflex on long vowels', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { useCxOverMacron: true } })).toBe(expected))
+ `('Using circumflex on long vowels', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { useCxOverMacron: true } })).toBe(expected))
+
+ // Applying beta_v
+
+ test('Applying beta_v', () => {
+ expect(toTransliteration('bárbaros', KeyType.TRANSLITERATION, { transliterationStyle: { beta_v: true } }))
+ .toBe('várvaros')
+ })
+
+ // Applying eta_i
+
+ test('Applying eta_i', () => {
+ expect(toTransliteration('hēdonḗ', KeyType.TRANSLITERATION, { transliterationStyle: { eta_i: true } }))
+ .toBe('hīdonī́')
+ })
+
+ // Applying eta_i, using circumflex
+
+ test('Applying eta_i', () => {
+ expect(toTransliteration('hêdonế', KeyType.TRANSLITERATION, { transliterationStyle: { useCxOverMacron: true, eta_i: true } }))
+ .toBe('hîdonî́')
+ })
+
+ // Applying phi_f
+
+ test.each`
+ str | expected
+ ${'phantasía'} | ${'fantasía'}
+ ${'Phainṓ'} | ${'Fainṓ'}
+ ${'PHILOSOFIA'} | ${'FILOSOFIA'}
+ `('Applying phi_f', ({ str, expected }) => { expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { phi_f: true } })).toBe(expected) })
// Applying xi_ks / chi_kh
test.each`
str | expected
+ ${'XENOPHŌN'} | ${'KSENOPHŌN'}
${'Xenophō̃n'} | ${'Ksenophō̃n'}
- ${'Chorēgéō'} | ${'khorēgéō'}
+ ${'xenophō̃n'} | ${'ksenophō̃n'}
+ ${'CHORĒGEŌ'} | ${'KHORĒGEŌ'}
+ ${'Chorēgéō'} | ${'Khorēgéō'}
+ ${'chorēgéō'} | ${'khorēgéō'}
${'sphínx'} | ${'sphínks'}
${'melancholía'} | ${'melankholía'}
- `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toTransliteration(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
+ `('Applying xi_ks / chi_kh', ({ str, expected }) => { expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { xi_ks: true, chi_kh: true } })).toBe(expected) })
// Applying upsilon_y
@@ -413,7 +652,20 @@ describe('Self conversion', () => {
${'Hýbla'} | ${'Hýbla'}
${'ú hũ'} | ${'ý hỹ'}
${'ý hỹ'} | ${'ý hỹ'}
- `('Applying upsilon_y', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { upsilon_y: true } })).toBe(expected))
+ `('Applying upsilon_y', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { upsilon_y: true } })).toBe(expected))
+
+ // Applying upsilon_y, preserving diphthongs au/eu/ou only
+
+ test.each`
+ str | expected
+ ${'SOYIDAS'} | ${'SOUIDAS'}
+ ${'maylís'} | ${'maulís'}
+ ${'pneỹma'} | ${'pneũma'}
+ ${'ēúdōn'} | ${'ēýdōn'}
+ ${'poỹ'} | ${'poũ'}
+ ${'muíagros'} | ${'myíagros'}
+ ${'ōutós'} | ${'ōytós'}
+ `('Applying upsilon_y, preserving diphthongs au/eu/ou only', ({ str, expected }) => expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { upsilon_y: Preset.ISO } })).toBe(expected))
// Applying lunatesigma_s
@@ -422,6 +674,6 @@ describe('Self conversion', () => {
${'hagioc'} | ${'hagios'}
${'Cōkrátēc'} | ${'Sōkrátēs'}
${'ICHTUC'} | ${'ICHTUS'}
- `('Applying lunatesigma_s', ({ str, expected }) => { expect(toTransliteration(str, KeyType.TRANSLITERATION, { setTransliterationStyle: { lunatesigma_s: true } })).toBe(expected) })
+ `('Applying lunatesigma_s', ({ str, expected }) => { expect(toTransliteration(str, KeyType.TRANSLITERATION, { transliterationStyle: { lunatesigma_s: true } })).toBe(expected) })
})
diff --git a/tsconfig.json b/tsconfig.json
index 2fe8638..f51a4e3 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,5 +1,7 @@
{
"compilerOptions": {
+ "useDefineForClassFields": true,
+ "esModuleInterop": true,
"isolatedModules": true,
"target": "ES2018"
}