├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── composer.json
├── features
├── bootstrap
│ └── FeatureContext.php
└── romanize.feature
├── phpunit.xml
├── src
└── KoreanRomanizer
│ ├── Dictionary
│ ├── Dictionary.php
│ └── DictionaryEntry.php
│ ├── EndConsonant.php
│ ├── Exception.php
│ ├── IniConsonant.php
│ ├── InvalidArgumentException.php
│ ├── Jamo.php
│ ├── JamoList.php
│ ├── RomanizeInterface.php
│ ├── Romanizer.php
│ ├── SpecialRule.php
│ ├── SpecialRuleContainer.php
│ ├── SpecialRuleFactory.php
│ ├── Syllabe.php
│ ├── UnicodeChar.php
│ └── Vowel.php
└── tests
├── DictionaryTest.php
├── JamoListTest.php
├── RomanizerTest.php
├── RomanizerWithDictionaryTest.php
├── SpecialCasesTest.php
├── SyllabeTest.php
├── UnicodeTest.php
├── bootstrap.php
├── romanizationExamples.php
└── seoulSubwayExamples.php
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | vendor
3 | build
4 | *.swp
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 5.4
4 | - 5.5
5 | - 5.6
6 | - hhvm
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Julio Martinez
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/liopic/php-Korean-romanizer)
2 | [](https://insight.sensiolabs.com/projects/192c62a4-ec9a-4a86-a625-0fac48a0e770)
3 | [](https://codeclimate.com/github/liopic/php-Korean-romanizer)
4 | [](https://packagist.org/packages/liopic/korean-romanizer)
5 | [](https://packagist.org/packages/liopic/korean-romanizer)
6 | [](https://packagist.org/packages/liopic/korean-romanizer)
7 |
8 | korean-romanizer
9 | ================
10 |
11 | PHP 5.4+ library to romanize Korean in UTF-8 format.
12 |
13 | Description
14 | ===========
15 |
16 | Uses the "[Revised Romanization of Korean (국어의 로마자 표기법)](http://www.korean.go.kr/eng/roman/roman.jsp)" which is the official Korean language romanization system in South Korea proclaimed by Ministry of Culture, Sports and Tourism. [Wikipedia page](http://en.wikipedia.org/wiki/Revised_Romanization_of_Korean).
17 |
18 | Notice that this is different from transliteration, which comes implemented in PHP's [intl extension](http://php.net/manual/en/book.intl.php) ([Transliterator class](http://php.net/manual/en/class.transliterator.php)).
19 | For example, "왕십리" subway stop is transliterated as "wangsibli" but romanized as "wangsimni" (which is closer to the Korean pronuntiation).
20 |
21 | Usage
22 | =====
23 | First add this library as requirement in your composer.json file. If you are not familiar with Composer, please read [its documentation](https://getcomposer.org/doc/01-basic-usage.md) first.
24 |
25 | {
26 | "require": {
27 | "liopic/korean-romanizer": "~1.0"
28 | }
29 | }
30 |
31 | Then create a new KoreanRomanizer\Romanizer() instance with the Korean text in UTF-8 you want to romanize.
32 | For example:
33 |
34 | require "vendor/autoload.php";
35 |
36 | $example = new KoreanRomanizer\Romanizer("안녕 하세요");
37 | echo $example->romanize(); //Displays "annyeong haseyo"
38 |
39 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "liopic/korean-romanizer",
3 | "description": "Library to romanize Korean in UTF-8 format",
4 | "keywords": ["Korean", "romanization", "romanize", "hangul", "hangeul", "hangugeo"],
5 | "homepage": "https://github.com/liopic/php-Korean-romanizer",
6 | "type": "library",
7 | "license": "MIT",
8 | "authors": [{
9 | "name": "Julio Martinez",
10 | "email": "liopic@liopic.com",
11 | "homepage": "http://liopic.com"
12 | }],
13 | "require": {
14 | "php": ">=5.4.0"
15 | },
16 | "require-dev": {
17 | "phpunit/phpunit": ">=4.0.0",
18 | "behat/behat": "^3.0"
19 | },
20 | "autoload": {
21 | "psr-4": {"KoreanRomanizer\\": "src/KoreanRomanizer"}
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/features/bootstrap/FeatureContext.php:
--------------------------------------------------------------------------------
1 | romanizer = new Romanizer($word);
22 | }
23 |
24 | /**
25 | * @When I run the romanization
26 | */
27 | public function iRunTheRomanization()
28 | {
29 | $this->result = $this->romanizer->romanize();
30 | }
31 |
32 | /**
33 | * @Then I should get :latin
34 | */
35 | public function iShouldGet($latin)
36 | {
37 | if ((string) $latin !== $this->result) {
38 | throw new Exception("Actual result is:\n" . $this->result);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/features/romanize.feature:
--------------------------------------------------------------------------------
1 | Feature: Romanize
2 | In order to get the romanization form of a Korean text
3 | As an user that has no idea of Korean
4 | I need to be able to use the romanizer
5 |
6 | Scenario: Romanize a common Korean word
7 | Given I have the word "대학원생"
8 | When I run the romanization
9 | Then I should get "daehagwonsaeng"
10 |
11 | Scenario: Romanize a complex place-name
12 | Given I have the word "대학로"
13 | When I run the romanization
14 | Then I should get "daehangno"
15 |
16 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | tests
5 |
6 |
7 |
8 |
9 | src
10 |
11 | .composer
12 | tests
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/Dictionary/Dictionary.php:
--------------------------------------------------------------------------------
1 | rewind();
35 | while ($this->valid()) {
36 | $current = $this->current();
37 | $s = $current->translate($s);
38 | $this->next();
39 | }
40 | return $s;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/Dictionary/DictionaryEntry.php:
--------------------------------------------------------------------------------
1 | original = $original;
40 | $this->translation = $translation;
41 | $this->regex = $regex;
42 | }
43 |
44 | /**
45 | * Translate in the given string
46 | * @param $s
47 | * @return string
48 | */
49 | public function translate($s)
50 | {
51 | if ($this->regex === self::REGEX) {
52 | mb_internal_encoding("UTF-8");
53 | return mb_ereg_replace($this->original, $this->translation, $s);
54 | } else {
55 | return str_replace($this->original, $this->translation, $s);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/EndConsonant.php:
--------------------------------------------------------------------------------
1 | char, $origin)];
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/Exception.php:
--------------------------------------------------------------------------------
1 | char, $origin)];
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/InvalidArgumentException.php:
--------------------------------------------------------------------------------
1 | char = $letter;
20 | }
21 | /**
22 | * Check if a caracter is among allowed chars
23 | * @param char $char the caracter to test
24 | * @return bool
25 | */
26 | public static function isAllowedChar($char)
27 | {
28 | $allowed = static::getAllowedChars();
29 | return in_array($char, $allowed);
30 | }
31 |
32 | /**
33 | * Returns an array of UTF8 Korean letters that are allowed for instanciating the class
34 | * @return array
35 | */
36 | public static function getAllowedChars()
37 | {
38 | $consonants = EndConsonant::getAllowedChars();
39 | $vowels = Vowel::getAllowedChars();
40 | return array_merge($consonants, $vowels);
41 | }
42 |
43 | abstract public function romanize();
44 | }
45 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/JamoList.php:
--------------------------------------------------------------------------------
1 | s = $s;
27 | $this->dict = null;
28 | }
29 |
30 | public function setDictionary(\KoreanRomanizer\Dictionary\Dictionary $dict)
31 | {
32 | $this->dict = $dict;
33 | }
34 |
35 | /**
36 | * Returns the romanization
37 | * @return string
38 | */
39 | public function romanize()
40 | {
41 | $s = $this->s;
42 | //If a Dictionary is set, use it firstly
43 | if ($this->dict) {
44 | $s = $this->dict->translate($s);
45 | }
46 |
47 | //Extract utf8 chars one by one, creating a Syllabe object for each char
48 | $syllabes = [];
49 | mb_internal_encoding("UTF-8");
50 | $strlen = mb_strlen($s);
51 | while ($strlen) {
52 | $syllabes[] = new Syllabe(mb_substr($s, 0, 1));
53 | $s = mb_substr($s, 1);
54 | $strlen = mb_strlen($s);
55 | }
56 | $syllabes[] =new Syllabe(" "); //add a fake end, to mark last Korean word ending
57 |
58 | //Get the jamos of each syllabe, grouping by Korean words
59 | $specialRules = SpecialRuleFactory::build();
60 | $jamoList = new JamoList();
61 | $rom = [];
62 | foreach ($syllabes as $syllabe) {
63 | if ($syllabe->isKorean()) {
64 | $jamoList->addAll($syllabe->getJamos());
65 | } else {
66 | //first process stored Korean word
67 | $rom[] = $this->romanizeWord($jamoList, $specialRules);
68 | unset($jamoList);
69 | $jamoList = new JamoList();
70 | //and then process the non Korean char
71 | $rom[] = $syllabe->romanize();
72 | }
73 | }
74 | array_pop($rom); //remove the fake end
75 | return implode($rom);
76 | }
77 |
78 | /**
79 | * romanize a word, using its $jamos and applying $specialRules
80 | * @return string
81 | */
82 | private function romanizeWord(JamoList $jamoList, SpecialRuleContainer $specialRules)
83 | {
84 | // Apply romanization, first checking for special rules that start with an EndConsonant
85 | $rom = [];
86 | foreach ($jamoList as $k => $j) {
87 | if ($j instanceof EndConsonant) {
88 | $rule = $specialRules->findRuleAt($jamoList, $k);
89 | if ($rule) {
90 | $rom[] = $rule->applyAt($jamoList, $k);
91 | continue;
92 | }
93 | }
94 | $rom[] = $j->romanize();
95 | }
96 | return implode($rom);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/SpecialRule.php:
--------------------------------------------------------------------------------
1 | jamos = $jamos;
29 | $this->romanization = $romanization;
30 | }
31 |
32 | public function matchesAt(JamoList $jamoList, $key)
33 | {
34 | $copy = clone($jamoList);
35 | while ($copy->key() != $key) {
36 | $copy->next();
37 | }
38 | $this->jamos->rewind();
39 | $size = min($this->jamos->count(), $copy->count());
40 | while ($size--) {
41 | if ($copy->current() != $this->jamos->current()) {
42 | return false;
43 | }
44 | $copy->next();
45 | $this->jamos->next();
46 | }
47 | return true;
48 | }
49 |
50 | public function applyAt(JamoList $jamoList, $key)
51 | {
52 | if (!$this->matchesAt($jamoList, $key)) {
53 | return "";
54 | }
55 | $shift = $this->jamos->count()-1;
56 | while ($shift--) {
57 | $jamoList->next();
58 | }
59 | return $this->romanization;
60 | }
61 |
62 | public function __toString()
63 | {
64 | return $this->jamos.'->'.$this->romanization;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/SpecialRuleContainer.php:
--------------------------------------------------------------------------------
1 | rewind();
36 | while ($this->valid()) {
37 | $current = $this->current();
38 | if ($current->matchesAt($jamoList, $key)) {
39 | $rule = $current;
40 | break;
41 | }
42 | $this->next();
43 | }
44 | return $rule;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/SpecialRuleFactory.php:
--------------------------------------------------------------------------------
1 | Sinmunno (instead of Sinmullo)
63 | ['ㄱ', 'ㅇ', 'ㅕ', 'ngnyeo'], //학여울->Hangnyeoul
64 | ['ㄹ', 'ㅇ', 'ㅑ', 'llya'] //알약->Allyak
65 | ];
66 |
67 | public static function build()
68 | {
69 | $ruleContainer = new SpecialRuleContainer();
70 |
71 | //3-jamo rules: end + ini + vow
72 | foreach (self::$endIniVow as $rule) {
73 | $jamos = new JamoList();
74 | $jamos->attach(new EndConsonant($rule[0]));
75 | $jamos->attach(new IniConsonant($rule[1]));
76 | $jamos->attach(new Vowel($rule[2]));
77 | $rule = new SpecialRule($jamos, $rule[3]);
78 | $ruleContainer->attach($rule);
79 | }
80 | //2-jamo rules: end + ini
81 | foreach (self::$endIni as $rule) {
82 | $jamos = new JamoList();
83 | $jamos->attach(new EndConsonant($rule[0]));
84 | $jamos->attach(new IniConsonant($rule[1]));
85 | $rule = new SpecialRule($jamos, $rule[2]);
86 | $ruleContainer->attach($rule);
87 | }
88 |
89 | return $ruleContainer;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/Syllabe.php:
--------------------------------------------------------------------------------
1 | char = $s;
41 | $this->isKoreanFlag = $this->isKoreanSyllabe();
42 | if ($this->isKoreanFlag) {
43 | $this->splitJamo();
44 | }
45 | }
46 |
47 | /**
48 | * Tells if the object is a Korean syllabe
49 | * @return bool
50 | */
51 | public function isKorean()
52 | {
53 | return !!$this->isKoreanFlag;
54 | }
55 |
56 | /**
57 | * Tells if the char $s is a Korean Syllabe in UTF8
58 | * @param string $s
59 | * @return integer
60 | */
61 | private function isKoreanSyllabe()
62 | {
63 | $dec = $this->getUnicodeIndex();
64 | return $dec >= self::FIRST_KOREAN_SYLLABE
65 | && $dec <= self::LAST_KOREAN_SYLLABE;
66 | }
67 |
68 | /**
69 | * Extract the letters of the syllabe
70 | * @return string
71 | */
72 | public function splitJamo()
73 | {
74 | if (!$this->isKoreanFlag) {
75 | return false;
76 | }
77 |
78 | $base = $this->getUnicodeIndex() - self::FIRST_KOREAN_SYLLABE;
79 |
80 | //Extract ending consonant
81 | $finals = EndConsonant::getAllowedChars();
82 | $finalC = count($finals);
83 | $finalIndex = $base % $finalC;
84 | $this->endConsonant = new EndConsonant($finals[$finalIndex]);
85 | $base = ($base-$finalIndex) / $finalC;
86 |
87 | //Extract vowel
88 | $vowels = Vowel::getAllowedChars();
89 | $vowelC = count($vowels);
90 | $vowelIndex = $base % $vowelC;
91 | $this->vowel = new Vowel($vowels[$vowelIndex]);
92 | $base = ($base-$vowelIndex) / $vowelC;
93 |
94 | //Extract initial consonant
95 | $initials = IniConsonant::getAllowedChars();
96 | $initialC = count($initials);
97 | $initialIndex = $base % $initialC;
98 | $this->iniConsonant = new IniConsonant($initials[$initialIndex]);
99 |
100 | return true;
101 | }
102 |
103 | public function getJamos()
104 | {
105 | $jamos = new JamoList();
106 | if ($this->isKoreanFlag) {
107 | $jamos->attach($this->iniConsonant);
108 | $jamos->attach($this->vowel);
109 | $jamos->attach($this->endConsonant);
110 | }
111 | return $jamos;
112 | }
113 |
114 | public function romanize()
115 | {
116 | if (!$this->isKoreanFlag) {
117 | return $this->char;
118 | } else {
119 | return $this->iniConsonant->romanize()
120 | .$this->vowel->romanize()
121 | .$this->endConsonant->romanize();
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/UnicodeChar.php:
--------------------------------------------------------------------------------
1 | char = $letter;
25 | }
26 |
27 | /**
28 | * Check if it's an UTF-8 1-char-long string
29 | * @param string $s UTF-8 letter
30 | * @throws \KoreanRomanizer\InvalidArgumentException
31 | */
32 | private static function isOneUTF8Char($s)
33 | {
34 | return mb_strlen($s, "UTF-8") == 1;
35 | }
36 |
37 | /**
38 | * Returns the unicode index of the character $s
39 | * @param string $s
40 | * @return integer
41 | */
42 | final public function getUnicodeIndex()
43 | {
44 | $long = mb_convert_encoding($this->char, "UCS2", "UTF-8");
45 | return hexdec(bin2hex($long));
46 | }
47 |
48 | public function __toString()
49 | {
50 | return $this->char;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/KoreanRomanizer/Vowel.php:
--------------------------------------------------------------------------------
1 | char, $origin)];
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/DictionaryTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('oh[1] 아이우', $d->translate($s));
31 | }
32 |
33 | public function testNoRegexTranslation()
34 | {
35 | $s ="오(1) 오아이우";
36 | $pat = "오";
37 | $translation = "oh";
38 | $d = new DictionaryEntry($pat, $translation);
39 | $this->assertEquals('oh(1) oh아이우', $d->translate($s));
40 | }
41 |
42 | public function testDictionaryTranslation()
43 | {
44 | $dict = new Dictionary();
45 | $dict->attach(new DictionaryEntry("123", "321"));
46 | $dict->attach(new DictionaryEntry("ab", "=AB="));
47 | $result = $dict->translate('123456,abcd,321');
48 | $this->assertEquals('321456,=AB=cd,321', $result);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/tests/JamoListTest.php:
--------------------------------------------------------------------------------
1 | jl = new JamoList();
14 | }
15 |
16 |
17 | public function testAddAndRemoveAJamoToList()
18 | {
19 | $j = new Vowel('ㅏ');
20 | $this->assertEquals(false, $this->jl->contains($j));
21 | $this->jl->attach($j);
22 | $this->assertEquals(true, $this->jl->contains($j));
23 | $this->jl->detach($j);
24 | $this->assertEquals(false, $this->jl->contains($j));
25 | }
26 |
27 | public function testConvertToString()
28 | {
29 | $j1 = new Vowel('ㅏ');
30 | $j2 = new Vowel('ㅜ');
31 | $this->jl->attach($j1);
32 | $this->jl->attach($j2);
33 | $this->assertEquals('ㅏㅜ', $this->jl.'');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/RomanizerTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($sOut, $s->romanize());
14 | }
15 |
16 | public function examplesTestRomanize()
17 | {
18 | //Basic Korean words without special cases
19 | $basic = [
20 | ["나비", "nabi"],
21 | ["두부", "dubu"],
22 | ["사랑해", "saranghae"],
23 | ["안녕", "annyeong"],
24 | ["고마워요","gomawoyo"],
25 | ["커피", "keopi"]
26 | ];
27 |
28 | //Mixed with non-Korean chars
29 | $mix = [
30 | ["신촌역 4번출구", "sinchonyeok 4beonchulgu"],
31 | ["북한 1 - 한국 2", "bukhan 1 - han-guk 2"]
32 | ];
33 |
34 | return array_merge($basic, $mix);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/RomanizerWithDictionaryTest.php:
--------------------------------------------------------------------------------
1 | attach(new DictionaryEntry("시청", "City Hall"));
17 | //$dict->attach(new DictionaryEntry('(.)대통령', 'President \\1', DictionaryEntry::REGEX));
18 | $rom->setDictionary($dict);
19 | $this->assertEquals($sOut, $rom->romanize());
20 | }
21 |
22 | public function examplesTestRomanize()
23 | {
24 | $tests = [
25 | ["시청 4번출구", "City Hall 4beonchulgu"]
26 | // ["조대통령", "President jo"]
27 | ];
28 |
29 | return $tests;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/SpecialCasesTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($this->simplify($sOut), $this->simplify($s->romanize()));
14 | }
15 |
16 | public function examplesFromFiles()
17 | {
18 | include_once "romanizationExamples.php";
19 | $examples = array_reduce($romanizationExamples, 'array_merge', []);
20 | unset($romanizationExamples);
21 |
22 | include_once "seoulSubwayExamples.php";
23 | $examples = array_merge($examples, array_reduce($seoulLines, 'array_merge', []));
24 |
25 | foreach ($examples as $k => $v) {
26 | if (isset($v[2])) {
27 | unset($examples[$k]);
28 | }
29 | }
30 | return $examples;
31 | }
32 |
33 | /**
34 | * make $s lowercase and without '-' (as those are optionals)
35 | * @param string $s
36 | * @return $s
37 | */
38 | private function simplify($s)
39 | {
40 | return str_replace('-', '', strtolower($s));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/tests/SyllabeTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(false, $s->isKorean());
11 | $this->assertEquals(" ", $s->romanize());
12 | }
13 |
14 | /**
15 | * @dataProvider examplesTestRomanize
16 | */
17 | public function testRomanize($sIn, $sOut)
18 | {
19 | $s = new Syllabe($sIn);
20 | $this->assertEquals($sOut, $s->romanize());
21 | }
22 |
23 | public function examplesTestRomanize()
24 | {
25 | //Non Korean syllabes
26 | $non = [["a", "a"],
27 | ["午", "午"],
28 | ["д", "д"],
29 | ["😀","😀"]
30 | ];
31 |
32 | //Korean syllabes
33 | $kor = [["가", "ga"],
34 | ["힣", "hit"],
35 | ["한", "han"],
36 | ["글", "geul"],
37 | ["닭", "dak"]
38 | ];
39 |
40 | return array_merge($kor, $non);
41 | }
42 |
43 | /**
44 | * Test for splitting Jamos and returning them
45 | */
46 | public function testSplittingJamos()
47 | {
48 | $s = new Syllabe("강");
49 | $jamos = $s->getJamos();
50 | $this->assertEquals("ㄱㅏㅇ", $jamos->__toString());
51 | $s = new Syllabe("옮");
52 | $jamos = $s->getJamos();
53 | $this->assertEquals("ㅇㅗㄻ", $jamos->__toString());
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/tests/UnicodeTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('ñ', $c->__toString());
19 | }
20 |
21 | public function testGetUnicodeIndex()
22 | {
23 | $c = new UnicodeChar('ᄑ'); //Unicode 0x1111, 4369
24 | $this->assertEquals(0x1111, $c->getUnicodeIndex());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 |