hangul-romanize
Version:
Romanize Hangul
387 lines (386 loc) • 20.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Romanize = void 0;
var hangulx_1 = require("hangulx");
var CombinationUtil_1 = require("./utils/CombinationUtil");
var FormatUtil_1 = require("./utils/FormatUtil");
var jamoDictionary_1 = require("./constants/jamoDictionary");
var Romanize = exports.Romanize = /** @class */ (function () {
function Romanize() {
}
Romanize.extractJamoMeta = function (char, position) {
if (char === null || char === undefined) {
return null;
}
var charCode = char.charCodeAt(0);
if (!hangulx_1.Hangul.isHangulCharCode(charCode)) {
// Not Hangul
return null;
}
// Hangul
var meta = {};
if (!hangulx_1.Hangul.isCompleteCharCode(charCode)) {
// Not Complete Hangul
meta.charCode = charCode;
return { jamo: char, meta: meta };
}
// Complete Hangul
var syllable = hangulx_1.Syllable.disassembleFromCharCode(charCode);
if (syllable) {
switch (position) {
case hangulx_1.Syllable.Position.INITIAL: {
if (syllable.cho) {
meta.charCode = syllable.cho.charCodeAt(0);
meta.syllablePosition = hangulx_1.Syllable.Position.INITIAL;
return { jamo: syllable.cho, meta: meta };
}
break;
}
case hangulx_1.Syllable.Position.FINAL: {
if (syllable.jong) {
meta.charCode = syllable.jong.charCodeAt(0);
meta.syllablePosition = hangulx_1.Syllable.Position.FINAL;
return { jamo: syllable.jong, meta: meta };
}
break;
}
}
}
else {
// Logical error, Disassemble to Syllable from Complete Hangul failed.
}
// Not handled
return { jamo: char, meta: meta };
};
Romanize.getJamoRomanizationCandidates = function (jamo, jamoMeta, pJamo, pJamoMeta, nJamo, nJamoMeta, option) {
var results = [];
var charCode = (jamoMeta === null || jamoMeta === void 0 ? void 0 : jamoMeta.charCode) || jamo.charCodeAt(0);
if (hangulx_1.Hangul.isHangulCharCode(charCode)) {
if ((option === null || option === void 0 ? void 0 : option.jamoDictionary) !== null) {
var romanizationDictionary = (option === null || option === void 0 ? void 0 : option.jamoDictionary) || this.DEFAULT_JAMO_ROMANIZATION_DICTIONARY;
if (romanizationDictionary.has(jamo)) {
var romanizationMapping = romanizationDictionary.get(jamo);
if (romanizationMapping) {
var pCharCode = (pJamoMeta === null || pJamoMeta === void 0 ? void 0 : pJamoMeta.charCode) || (pJamo === null || pJamo === void 0 ? void 0 : pJamo.charCodeAt(0));
var nCharCode = (nJamoMeta === null || nJamoMeta === void 0 ? void 0 : nJamoMeta.charCode) || (nJamo === null || nJamo === void 0 ? void 0 : nJamo.charCodeAt(0));
// Sequence
var isSequence = (pCharCode !== undefined && pCharCode === charCode) || (nCharCode !== undefined && nCharCode === charCode);
if (isSequence) {
if (romanizationMapping.sequence_ !== undefined) {
return romanizationMapping.sequence_;
}
}
if ((jamoMeta === null || jamoMeta === void 0 ? void 0 : jamoMeta.syllablePosition) !== undefined) {
// Syllable
switch (jamoMeta.syllablePosition) {
case hangulx_1.Syllable.Position.INITIAL: {
if (romanizationMapping.initial_) {
return romanizationMapping.initial_;
}
break;
}
case hangulx_1.Syllable.Position.MIDDLE: {
if (romanizationMapping.middle_) {
return romanizationMapping.middle_;
}
break;
}
case hangulx_1.Syllable.Position.FINAL: {
if (romanizationMapping.final_) {
return romanizationMapping.final_;
}
break;
}
default: {
throw new Error('unknown syllable position');
}
}
}
var isAlone = (jamoMeta === null || jamoMeta === void 0 ? void 0 : jamoMeta.syllablePosition) === undefined;
if (isAlone) {
// Alone
if (romanizationMapping.alone_ !== undefined) {
return romanizationMapping.alone_;
}
return results;
}
// Fallback
if (romanizationMapping.alone_ !== undefined) {
return romanizationMapping.alone_;
}
}
}
}
}
return results;
};
Romanize.candidatesFromChar = function (char, pChar, nChar, option) {
var charCode = char.charCodeAt(0);
if (hangulx_1.Hangul.isHangulCharCode(charCode)) {
// Hangul
var results = [];
var cascadeOption = {
jamoDictionary: option === null || option === void 0 ? void 0 : option.jamoDictionary
};
var pJamoWithMeta = this.extractJamoMeta(pChar, hangulx_1.Syllable.Position.FINAL);
var nJamoWithMeta = this.extractJamoMeta(nChar, hangulx_1.Syllable.Position.INITIAL);
if (hangulx_1.Hangul.isCompleteCharCode(charCode)) {
var format_1 = option === null || option === void 0 ? void 0 : option.format;
// Complete map
if (option === null || option === void 0 ? void 0 : option.completeMap) {
if (option.completeMap.has(char)) {
var mapValue = option.completeMap.get(char);
if (mapValue) {
if (format_1) {
results.push.apply(results, mapValue.map(function (v) { return FormatUtil_1.FormatUtil.fromString(v, format_1); }));
}
else {
results.push.apply(results, mapValue);
}
}
}
}
// Syllable-Jamo-Dictionary
var syllable = hangulx_1.Syllable.disassembleFromCharCode(charCode);
if (!syllable) {
throw new Error('failed to disassemble complete hangul to syllable');
}
var candidates = [];
if (syllable.cho) {
var meta = { syllablePosition: hangulx_1.Syllable.Position.INITIAL };
var result = this.getJamoRomanizationCandidates(syllable.cho, meta, pJamoWithMeta === null || pJamoWithMeta === void 0 ? void 0 : pJamoWithMeta.jamo, pJamoWithMeta === null || pJamoWithMeta === void 0 ? void 0 : pJamoWithMeta.meta, nJamoWithMeta === null || nJamoWithMeta === void 0 ? void 0 : nJamoWithMeta.jamo, nJamoWithMeta === null || nJamoWithMeta === void 0 ? void 0 : nJamoWithMeta.meta, cascadeOption);
if (result.length > 0) {
candidates.push(result);
}
}
if (syllable.jung) {
var meta = { syllablePosition: hangulx_1.Syllable.Position.MIDDLE };
var result = this.getJamoRomanizationCandidates(syllable.jung, meta, pJamoWithMeta === null || pJamoWithMeta === void 0 ? void 0 : pJamoWithMeta.jamo, pJamoWithMeta === null || pJamoWithMeta === void 0 ? void 0 : pJamoWithMeta.meta, nJamoWithMeta === null || nJamoWithMeta === void 0 ? void 0 : nJamoWithMeta.jamo, nJamoWithMeta === null || nJamoWithMeta === void 0 ? void 0 : nJamoWithMeta.meta, cascadeOption);
if (result.length > 0) {
candidates.push(result);
}
}
if (syllable.jong) {
var meta = { syllablePosition: hangulx_1.Syllable.Position.FINAL };
var result = this.getJamoRomanizationCandidates(syllable.jong, meta, pJamoWithMeta === null || pJamoWithMeta === void 0 ? void 0 : pJamoWithMeta.jamo, pJamoWithMeta === null || pJamoWithMeta === void 0 ? void 0 : pJamoWithMeta.meta, nJamoWithMeta === null || nJamoWithMeta === void 0 ? void 0 : nJamoWithMeta.jamo, nJamoWithMeta === null || nJamoWithMeta === void 0 ? void 0 : nJamoWithMeta.meta, cascadeOption);
if (result.length > 0) {
candidates.push(result);
}
}
var candidatesLength = candidates.length;
if (candidatesLength > 0) {
var combinations = CombinationUtil_1.CombinationUtil.getCombinations(candidates);
if (format_1) {
results.push.apply(results, combinations.map(function (e) { return FormatUtil_1.FormatUtil.fromString(e.join(''), format_1); }));
}
else {
results.push.apply(results, combinations.map(function (e) { return e.join(''); }));
}
}
}
else {
// Not Complete Hangul
var meta = { charCode: charCode, syllablePosition: undefined };
return this.getJamoRomanizationCandidates(char, meta, pJamoWithMeta === null || pJamoWithMeta === void 0 ? void 0 : pJamoWithMeta.jamo, pJamoWithMeta === null || pJamoWithMeta === void 0 ? void 0 : pJamoWithMeta.meta, nJamoWithMeta === null || nJamoWithMeta === void 0 ? void 0 : nJamoWithMeta.jamo, nJamoWithMeta === null || nJamoWithMeta === void 0 ? void 0 : nJamoWithMeta.meta, cascadeOption);
}
return Array.from(new Set(results));
}
else {
return [char];
}
};
Romanize.candidatesFrom = function (str, option) {
var cascadeOption = {
jamoDictionary: option === null || option === void 0 ? void 0 : option.jamoDictionary,
completeMap: option === null || option === void 0 ? void 0 : option.completeMap,
format: option === null || option === void 0 ? void 0 : option.format,
};
var candidates = [];
var strLength = str.length;
for (var i = 0; i < strLength; ++i) {
var char = str[i];
var pChar = str === null || str === void 0 ? void 0 : str[i - 1];
var nChar = str === null || str === void 0 ? void 0 : str[i + 1];
candidates.push(this.candidatesFromChar(char, pChar, nChar, cascadeOption));
}
var combinations = CombinationUtil_1.CombinationUtil.getCombinations(candidates.filter(function (e) { return e.length > 0; }));
var separator = (option === null || option === void 0 ? void 0 : option.separator) || '';
return combinations.map(function (e) { return e.join(separator); });
};
Romanize.from = function (str, option) {
var _a;
return ((_a = this.candidatesFrom(str, option)) === null || _a === void 0 ? void 0 : _a[0]) || '';
};
Romanize.fromName = function (input1, input2, option) {
var _a, _b, _c;
switch (arguments.length) {
case 1: return ((_a = Romanize.candidatesFromName(input1)) === null || _a === void 0 ? void 0 : _a[0]) || null;
case 2: return ((_b = Romanize.candidatesFromName(input1, input2)) === null || _b === void 0 ? void 0 : _b[0]) || null;
case 3: return ((_c = Romanize.candidatesFromName(input1, input2, option)) === null || _c === void 0 ? void 0 : _c[0]) || null;
}
return null;
};
Romanize.toGroup = function (str, option) {
var _a;
var results = [];
var strLength = str.length;
for (var i = 0; i < strLength; ++i) {
var char = str[i];
var pChar = str === null || str === void 0 ? void 0 : str[i - 1];
var nChar = str === null || str === void 0 ? void 0 : str[i + 1];
var result = ((_a = this.candidatesFromChar(char, pChar, nChar, option)) === null || _a === void 0 ? void 0 : _a[0]) || '';
if (result) {
results.push(result);
}
}
return results;
};
Romanize.candidatesFromName = function (input1, input2, option) {
var _this = this;
var argsLength = arguments.length;
var name;
// Option
var surnameCascadeOption = {};
var givenNameCascadeOption = {};
if (argsLength === 1) {
if (typeof input1 === 'string') {
var splitCandidates = hangulx_1.KoreanName.splitCandidates(input1);
if (splitCandidates === null) {
throw new Error('failed to split full name');
}
var results_1 = [];
var candidatesResults = splitCandidates.map(function (candidate) { return _this.candidatesFromName(candidate); });
var candidatesResultsLength = candidatesResults.length;
for (var i = 0; i < candidatesResultsLength; ++i) {
var candidates = candidatesResults[i];
results_1.push.apply(results_1, candidates);
}
return results_1;
}
else if (typeof input1 === 'object') {
// Assign
name = input1;
}
else {
throw new Error('args[0] should be object or string');
}
}
else if (argsLength === 2) {
var surname = void 0, givenName = void 0;
// input1 can be string(surname) or string(full name) or object(IName)
switch (typeof input1) {
case 'string': {
// input1 : fullName or surname, input2 : undefined or string(Given name) or object(Option)
if (typeof input2 === 'string') {
// input1 : surname, input2: givenName
return this.candidatesFromName({ surname: input1, givenName: input2 });
}
else if (input2 === undefined || typeof input2 === 'object') {
// input1 : Full name, input2 : undefined or object(Option)
var splitCandidates = hangulx_1.KoreanName.splitCandidates(input1);
if (splitCandidates === null) {
throw new Error('failed to split full name');
}
var results_2 = [];
var candidatesResults = splitCandidates.map(function (candidate) { return _this.candidatesFromName(candidate, input2); });
var candidatesResultsLength = candidatesResults.length;
for (var i = 0; i < candidatesResultsLength; ++i) {
var candidates = candidatesResults[i];
results_2.push.apply(results_2, candidates);
}
return results_2;
}
else {
throw new Error('typeof args[1] should be string or object or undefined');
}
break;
}
case 'object': {
// input1 : IName(Surname + Given name)
surname = input1.surname;
givenName = input1.givenName;
break;
}
default: {
throw new Error('args[0] should be string or object');
}
}
if (input2 !== undefined) {
// input2 can be undefined or string(givenName) or object(IName)
switch (typeof input2) {
case 'string': {
// input2 is givenName
if (typeof input1 !== 'string') {
throw new Error('typeof args[0] should be string if typeof args[1] is string');
}
givenName = input2;
break;
}
case 'object': {
// input2 is option
surnameCascadeOption.jamoDictionary = input2 === null || input2 === void 0 ? void 0 : input2.jamoDictionary;
givenNameCascadeOption.jamoDictionary = input2 === null || input2 === void 0 ? void 0 : input2.jamoDictionary;
surnameCascadeOption.format = input2.format;
givenNameCascadeOption.format = input2.format;
// Separator between given name
givenNameCascadeOption.separator = input2 === null || input2 === void 0 ? void 0 : input2.givenNameSeparator;
// Complete map
if (input2 === null || input2 === void 0 ? void 0 : input2.completeMap) {
surnameCascadeOption.completeMap = input2.completeMap;
givenNameCascadeOption.completeMap = input2.completeMap;
}
if (input2 === null || input2 === void 0 ? void 0 : input2.surnameCompleteMap) {
surnameCascadeOption.completeMap = input2.surnameCompleteMap;
}
if (input2 === null || input2 === void 0 ? void 0 : input2.givenNameCompleteMap) {
givenNameCascadeOption.completeMap = input2.givenNameCompleteMap;
}
break;
}
default: {
throw new Error('args[1] should be string or object');
}
}
}
if (surname === undefined) {
throw new Error('surname is undefined');
}
if (givenName === undefined) {
throw new Error('given name is undefined');
}
name = { surname: surname, givenName: givenName };
}
else if (argsLength === 3) {
if (typeof input1 !== 'string') {
throw new Error('typeof args[0] should be a string');
}
if (typeof input2 !== 'string') {
throw new Error('typeof args[1] should be a string');
}
return this.candidatesFromName({ surname: input1, givenName: input2 }, option);
}
else {
throw new Error('args length should be between one to three');
}
// Validate name
if (typeof (name === null || name === void 0 ? void 0 : name.surname) !== 'string') {
throw new Error('name.surname should be a string');
}
if (typeof (name === null || name === void 0 ? void 0 : name.givenName) !== 'string') {
throw new Error('name.surname should be a string');
}
var surnameCandidates = this.candidatesFrom(name.surname, surnameCascadeOption);
var surnameCandidatesLength = surnameCandidates.length;
var givenNameCandidates = this.candidatesFrom(name.givenName, givenNameCascadeOption);
var givenNameCandidatesLength = givenNameCandidates.length;
var results = [];
for (var i = 0; i < surnameCandidatesLength; ++i) {
for (var j = 0; j < givenNameCandidatesLength; ++j) {
results.push({ surname: surnameCandidates[i], givenName: givenNameCandidates[j] });
}
}
return results;
};
Romanize.DEFAULT_JAMO_ROMANIZATION_DICTIONARY = jamoDictionary_1.jamoDictionary;
return Romanize;
}());