├── .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 | [![Build Status](https://travis-ci.org/liopic/php-Korean-romanizer.svg?branch=master)](https://travis-ci.org/liopic/php-Korean-romanizer) 2 | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/192c62a4-ec9a-4a86-a625-0fac48a0e770/mini.png)](https://insight.sensiolabs.com/projects/192c62a4-ec9a-4a86-a625-0fac48a0e770) 3 | [![Code Climate](https://codeclimate.com/github/liopic/php-Korean-romanizer/badges/gpa.svg)](https://codeclimate.com/github/liopic/php-Korean-romanizer) 4 | [![Latest Stable Version](https://poser.pugx.org/liopic/korean-romanizer/v/stable.svg)](https://packagist.org/packages/liopic/korean-romanizer) 5 | [![Monthly Downloads](https://poser.pugx.org/liopic/korean-romanizer/d/monthly.png)](https://packagist.org/packages/liopic/korean-romanizer) 6 | [![License](https://poser.pugx.org/liopic/korean-romanizer/license.svg)](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 |