Skip to content

Commit

Permalink
Create nasal assimilation rules
Browse files Browse the repository at this point in the history
  • Loading branch information
mooniker committed Oct 13, 2019
1 parent ed5307c commit f9300ab
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 35 deletions.
108 changes: 75 additions & 33 deletions jamo.js
@@ -1,17 +1,14 @@
// "...what have the Romans ever done for us?"

const isHangul = require("./hangul/isHangul");
const _ = require("lodash");

const [
initialConsonants,
medialVowels,
finalConsonants
] = require("./hangul/unicode/hangul-jamo");

const explain = jamo => {
const codePoint = jamo.codePointAt(0);
return `${jamo} (${codePoint}/${codePoint.toString(16)})`;
};

const jamoMapper = jamoSet => ({ jamo, roman }, idx) => {
const unicodeJamo = jamoSet[idx].jamo;
Expand All @@ -34,13 +31,21 @@ const jamoMapper = jamoSet => ({ jamo, roman }, idx) => {

// initial consonants
const choseong = [
{ jamo: "ㄱ", roman: "g" },
{ jamo: "ㄱ", roman: { default: "g", MR: "k" } },
{ jamo: "ㄲ", roman: "kk" },
{
jamo: "ㄴ",
roman: { default: "n", : "l", [String.fromCodePoint(4527)]: "l" }
},
{ jamo: "ㄷ", roman: "d" },
{
jamo: "ㄷ",
roman: {
default: "d",
: "dd",
// ㄶ: "",
: "dd"
}
},
{ jamo: "ㄸ", roman: "dd" },
{
jamo: "ㄹ", // initial
Expand Down Expand Up @@ -70,7 +75,15 @@ const choseong = [
{ jamo: "ㅃ", roman: "pp" },
{ jamo: "ㅅ", roman: "s" },
{ jamo: "ㅆ", roman: "ss" },
{ jamo: "ㅇ", roman: "" },
{
jamo: "ㅇ",
roman: {
default: "",
: "j",
// ㄶ: "",
: "b"
}
},
{ jamo: "ㅈ", roman: "j" },
{ jamo: "ㅉ", roman: "jj" },
{ jamo: "ㅊ", roman: "ch" },
Expand Down Expand Up @@ -105,6 +118,30 @@ const jungseong = [
{ jamo: "ㅣ", roman: "i" }
].map(jamoMapper(medialVowels));

const assimilate = (jamos, sound) =>
_.fromPairs(jamos.map(jamo => [jamo, sound]));

const nasalAssimilators = [
"ㄴ",
String.fromCodePoint(0x1102),
"n",
"ㅁ",
String.fromCodePoint(0x1106),
"m",
"ㅇ",
String.fromCodePoint(0x110b)
];

// nasal assimilation/nasalization when followed by ㅁ, ㄴ
const nasalAssimilation = {
// ㅂ ㅍ ㅄ ㄿ ㄼ => ㅁ
trailingBM: assimilate(nasalAssimilators, "m"),
// ㄷ ㅌ ㅈ ㅊ ㅅ ㅆ ㅎ => ㄴ
trailingDN: assimilate(nasalAssimilators, "n"),
// ㄱ ㅋ ㄲ ㄳ ㄺ => ㅇ
trailingGNg: assimilate(nasalAssimilators, "ng")
};

// final consonants
const jongseong = [
{ jamo: null, roman: "" },
Expand All @@ -113,18 +150,14 @@ const jongseong = [
roman: {
default: "k",
vowelNext: "g",
: "ng",
n: "ng",
: "ng",
// if followed by ㅁ
m: "ng",
: "ng",
[String.fromCodePoint(4358)]: "ng",
[String.fromCodePoint(0x1105)]: "ng",
...nasalAssimilation.trailingGNg,
RRT: "g"
}
},
{ jamo: "ㄲ", roman: "kk" },
{ jamo: "ㄳ", roman: "k" },
{ jamo: "ㄲ", roman: { default: "kk", ...nasalAssimilation.trailingGNg } },
{ jamo: "ㄳ", roman: { default: "k", ...nasalAssimilation.trailingGNg } },
{
jamo: "ㄴ", // final
roman: { default: "n", : "l", [String.fromCodePoint(4357)]: "l" }
Expand All @@ -136,58 +169,63 @@ const jongseong = [
roman: {
default: "t",
vowelNext: "d",
: "n",
: "n",
: "n",
...nasalAssimilation.trailingDN,
RRT: "d"
}
},
{
jamo: "ㄹ",
roman: { default: "l", vowelNext: "r", : "l", : "l" }
},
{ jamo: "ㄺ", roman: { default: "r", vowelNext: "lg" } },
{
jamo: "ㄺ",
roman: { default: "r", vowelNext: "lg", ...nasalAssimilation.trailingGNg }
},
{ jamo: "ㄻ", roman: "lm" },
{ jamo: "ㄼ", roman: "lb" },
{ jamo: "ㄼ", roman: { default: "lb", ...nasalAssimilation.trailingBM } },
{ jamo: "ㄽ", roman: "ls" },
{ jamo: "ㄾ", roman: "lt" },
{ jamo: "ㄿ", roman: "lp" },
{ jamo: "ㄿ", roman: { default: "lp", ...nasalAssimilation.trailingBM } },
{ jamo: "ㅀ", roman: "lh" },
{ jamo: "ㅁ", roman: "m" },
{
jamo: "ㅂ",
roman: {
default: "p",
vowelNext: "b",
: "m",
: "m",
[String.fromCodePoint(4357)]: "m",
: "m",
[String.fromCodePoint(0x1105)]: "m", // ㄹ
...nasalAssimilation.trailingBM,
RRT: "b"
}
},
{ jamo: "ㅄ", roman: "bs" },
{ jamo: "ㅄ", roman: { default: "bs", ...nasalAssimilation.trailingBM } },
{
jamo: "ㅅ",
roman: {
default: "t",
vowelNext: "s",
: "n",
: "n",
: "n",
...nasalAssimilation.trailingDN,
RRT: "s"
}
},
{ jamo: "ㅆ", roman: "ss" },
{
jamo: "ㅆ",
roman: {
default: "ss",
...nasalAssimilation.trailingDN
}
},
{ jamo: "ㅇ", roman: { default: "ng", vowelNext: "ng-" } },
{
jamo: "ㅈ",
roman: {
default: "t",
vowelNext: "j",
: "n",
: "n",
: "n"
...nasalAssimilation.trailingDN
}
},
{
Expand All @@ -197,16 +235,20 @@ const jongseong = [
vowelNext: "ch",
: "n",
: "n",
: "n",
...nasalAssimilation.trailingDN,
RRT: "ch"
}
},
{ jamo: "ㅋ", roman: "k" },
{ jamo: "ㅋ", roman: { default: "k", ...nasalAssimilation.trailingGNg } },
{
jamo: "ㅌ",
roman: { default: "t", : "n", : "n", : "n" }
roman: {
default: "t",
: "n",
...nasalAssimilation.trailingDN
}
},
{ jamo: "ㅍ", roman: "p" },
{ jamo: "ㅍ", roman: { default: "p", ...nasalAssimilation.trailingBM } },
{
jamo: "ㅎ",
roman: {
Expand Down
2 changes: 0 additions & 2 deletions romanize.js
Expand Up @@ -29,7 +29,6 @@ function searchJamo(node, params, prevNode) {
return next(node[method]);
}

// console.log(params, vowelNext, node.vowelNext, node);
if (vowelNext && (node.vowelNext || typeof node.vowelNext === "string")) {
return next(node.vowelNext);
}
Expand All @@ -47,7 +46,6 @@ function searchJamo(node, params, prevNode) {
return next(node.default);
}

console.warn(prevNode);
throw new Error("Unimplemented: " + JSON.stringify(node, null, 2));

function next(nextNode) {
Expand Down

0 comments on commit f9300ab

Please sign in to comment.