From a941034ac4891f6f3543380a58ebfa6da116a879 Mon Sep 17 00:00:00 2001 From: AcidF0x Date: Fri, 21 Jan 2022 00:01:58 +0900 Subject: [PATCH] =?UTF-8?q?v2=20=EC=83=88=EB=A1=9C=EC=9A=B4=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +- composer.json | 2 +- composer.lock | 27 +++--- src/Character.php | 75 +++++++++++++++ src/Constants.php | 17 ++++ src/SeparateResult.php | 96 +++++++++++++++++++ src/Separator.php | 210 ++++++++--------------------------------- tests/HangulTest.php | 80 ---------------- 8 files changed, 248 insertions(+), 268 deletions(-) create mode 100644 src/Character.php create mode 100644 src/Constants.php create mode 100644 src/SeparateResult.php delete mode 100644 tests/HangulTest.php diff --git a/README.md b/README.md index 45be263..6c85600 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,11 @@ Usage The return value is the *Hangul Compatibility Jamo* between `U+3130` and `U+318F` 반환 값은 `U+3130`와 `U+318F` 사이의 *Hangul Compatibility Jamo*가 반환 됩니다. - See [Hangul Compatibility Jamo](https://unicode.org/charts/PDF/U3130.pdf) + ```php -use AcidF0x\KoreanHandler\Separator; +use AcidF0x\KoreanHandler\aaaaaaa; -$separator = new Separator(); +$separator = new aaaaaaa(); $separator->separate("가"); $separator->getChoseong(); // "ㄱ" @@ -36,9 +37,9 @@ The return value is the *Hangul Jamo* between `U+1100` and `U+11FF` - See [Hangul Jamo](https://unicode.org/charts/PDF/U1100.pdf) ```php -use AcidF0x\KoreanHandler\Separator; +use AcidF0x\KoreanHandler\aaaaaaa; -$separator = new Separator(); +$separator = new aaaaaaa(); $separator->strictMode(); $separator->separate("가"); diff --git a/composer.json b/composer.json index d17aeae..08b7b33 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ }, "require": { "php": ">=7.4", - "ext-mbstring": "*" + "ext-mbstring": "*" }, "require-dev": { "phpunit/phpunit": "^9.0" diff --git a/composer.lock b/composer.lock index 35b029c..510fb93 100644 --- a/composer.lock +++ b/composer.lock @@ -410,16 +410,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.1", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", "shasum": "" }, "require": { @@ -454,9 +454,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" }, - "time": "2021-10-02T14:08:47+00:00" + "time": "2022-01-04T19:58:01+00:00" }, { "name": "phpspec/prophecy", @@ -1912,21 +1912,24 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.23.0", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + "reference": "30885182c981ab175d4d034db0f6f469898070ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-ctype": "*" + }, "suggest": { "ext-ctype": "For best performance" }, @@ -1971,7 +1974,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" }, "funding": [ { @@ -1987,7 +1990,7 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2021-10-20T20:35:02+00:00" }, { "name": "theseer/tokenizer", diff --git a/src/Character.php b/src/Character.php new file mode 100644 index 0000000..c60dec1 --- /dev/null +++ b/src/Character.php @@ -0,0 +1,75 @@ +choseong = $choseong; + $this->jungseong = $jungseong; + $this->jongseong = $jongseong; + } + + public function getChoseong(): ?string + { + return $this->choseong; + } + + public function setChoseong(?string $choseong): Character + { + $this->choseong = $choseong; + return $this; + } + + public function getJungseong(): ?string + { + return $this->jungseong; + } + + public function setJungseong(?string $jungseong): Character + { + $this->jungseong = $jungseong; + return $this; + } + + public function getJongseong(): ?string + { + return $this->jongseong; + } + + public function setJongseong(?string $jongseong): Character + { + $this->jongseong = $jongseong; + return $this; + } + + /** + * @return array|string[] + */ + public function getSplit(): array + { + return $this->split; + } + + public function setSplit(): Character + { + $split = [ + $this->choseong, + $this->jungseong + ]; + + if ($this->jongseong) { + $split[] = $this->jongseong; + } + + $this->split = $split; + return $this; + } +} diff --git a/src/Constants.php b/src/Constants.php new file mode 100644 index 0000000..0c87689 --- /dev/null +++ b/src/Constants.php @@ -0,0 +1,17 @@ +position = 0; + $this->characters = $characters; + } + + public function offsetSet($offset, $value) { + if (is_null($offset)) { + $this->characters[] = $value; + } else { + $this->characters[$offset] = $value; + } + } + + public function offsetExists($offset): bool + { + return isset($this->characters[$offset]); + } + + public function offsetUnset($offset) + { + unset($this->characters[$offset]); + } + + public function offsetGet($offset): ?Character + { + return $this->characters[$offset] ?? null; + } + + public function rewind() + { + $this->position = 0; + } + + public function current(): Character + { + return $this->characters[$this->position]; + } + + public function key(): int + { + return $this->position; + } + + public function next() + { + ++$this->position; + } + + public function valid(): bool + { + return isset($this->characters[$this->position]); + } + + public function getChoseongList(): array + { + return array_map(fn(Character $char) => $char->getChoseong(), $this->characters); + } + + public function getJungseongList(): array + { + return array_map(fn(Character $char) => $char->getJungseong(), $this->characters); + } + + public function getJongseongList(): array + { + return array_filter( + array_map(fn(Character $char) => $char->getJongseong(), $this->characters), + fn($i) => $i !== null + ); + } + + public function getSplitList(): array + { + $result = []; + /** @var Character $character */ + foreach ($this->characters as $character) { + array_push($result, ...$character->getSplit()); + } + + return $result; + } +} diff --git a/src/Separator.php b/src/Separator.php index a350618..6a7f44b 100644 --- a/src/Separator.php +++ b/src/Separator.php @@ -1,171 +1,39 @@ -choseseong; - } - - /** - * Get jungseong - * @return null|String - */ - public function getJungseong() - { - return $this->jungseong; - } - - /** - * Get jongseong - * @return null|String - */ - public function getJongseong() - { - return $this->jongseong; - } - - public function getSplit() - { - return $this->split; - } - /** - * Separate Hangul - * - * @param string $string - * @return $this - */ - public function separate($string) - { - $this->clear(); - $code = mb_ord(mb_strlen($string) === 1 ? $string : substr($string, 0, 1)); - - if ($code < self::HANGUL_SYLLABLE_START || $code > self::HANGUL_SYLLABLE_END) { - return $this; - } - - $base = $code - self::HANGUL_SYLLABLE_START; - $choseongBase = ($base / 28) / 21; - $jungseongBase = ($base / 28) % 21; - $jongseongBase = $base % 28 - 1; - - $this->toChar($choseongBase, $jungseongBase, $jongseongBase); - - return $this; - } - - /** - * set strict Mode; - * @return $this - */ - public function strictMode() - { - $this->strictMode = true; - return $this; - } - - /** - * set simple Mode; - * @return $this - */ - public function simpleMode() - { - $this->strictMode = false; - return $this; - } - - /** - * - * @param float $choseongBase - * @param float $jungseongBase - * @param float $jongseongBase - * @return boolean - */ - protected function toChar($choseongBase, $jungseongBase, $jongseongBase) - { - if ($this->strictMode) { - $this->choseseong= mb_chr($choseongBase + self::HANGUL_CHOSEONG_START); - $this->jungseong= mb_chr($jungseongBase + self::HANGUL_JOONGSEONG_START); - $this->split = [ $this->choseseong, $this->jungseong ]; - if ($jongseongBase > 0) { - $this->jongseong = mb_chr($jongseongBase + self::HANGUL_JONGSEONG_START); - $this->split[] = $this->jongseong; - } - return true; - } - - $this->choseseong = self::SIMPLE_CHOSEONG_LIST[intval($choseongBase)]; - $this->jungseong = self::SIMPLE_JOONGSEONG_LIST[intval($jungseongBase)]; - $this->split = [ $this->choseseong, $this->jungseong ]; - if ($jongseongBase > 0) { - $this->jongseong = self::SIMPLE_JONGSEONG_LIST[intval($jongseongBase)]; - $this->split[] = $this->jongseong; - } - } - - protected function clear() - { - $this->choseseong = null; - $this->jungseong = null; - $this->jongseong = null; - $this->split = []; - } -} \ No newline at end of file + $this->doSeparator($string), mb_str_split($string)), + fn($i) => $i !== null + ); + + return new SeparateResult($array); + } + + private function doSeparator(string $char): ?Character + { + $code = mb_ord($char); + if ($code < Constants::UNICODE_HANGUL_SYLLABLE_START || $code > Constants::UNICODE_HANGUL_SYLLABLE_END) + { + return null; + } + + $base = $code - Constants::UNICODE_HANGUL_SYLLABLE_START; + $choseongBase = ($base / 28) / 21; + $jungseongBase = ($base / 28) % 21; + $jongseongBase = $base % 28 - 1; + + $choseong = Constants::CHOSEONG_LIST[(int) $choseongBase]; + $jungseong = Constants::JUNGSEONG_LIST[$jungseongBase]; + $jongseong = $jongseongBase > 0 + ? Constants::JONGSEONG_LIST[$jongseongBase] + : null; + + $character = new Character($choseong, $jungseong, $jongseong); + return $character->setSplit(); + } +} diff --git a/tests/HangulTest.php b/tests/HangulTest.php deleted file mode 100644 index a61ce64..0000000 --- a/tests/HangulTest.php +++ /dev/null @@ -1,80 +0,0 @@ -separate('1'); - $this->assertNull($separator->getChoseong()); - $separator->separate('100'); - $this->assertNull($separator->getChoseong()); - $separator->separate('A'); - $this->assertNull($separator->getChoseong()); - $separator->separate('æ'); - $this->assertNull($separator->getChoseong()); - $separator->separate('語'); - $this->assertNull($separator->getChoseong()); - } - public function testSimpleMode() { - $separator = new Separator(); - $separator->separate("가"); - $this->assertTrue($separator->getChoseong() === "ㄱ"); - $this->assertTrue($separator->getJungseong() === "ㅏ"); - $this->assertNull($separator->getJongseong()); - - - $separator->separate("곰"); - $this->assertTrue($separator->getChoseong() === "ㄱ"); - $this->assertTrue($separator->getJungseong() === "ㅗ"); - $this->assertTrue($separator->getJongseong() === "ㅁ"); - - $separator->separate("쉐"); - $this->assertTrue($separator->getChoseong() === "ㅅ"); - $this->assertTrue($separator->getJungseong() === "ㅞ"); - $this->assertNull($separator->getJongseong()); - - - $separator->separate("벼"); - $this->assertTrue($separator->getChoseong() === "ㅂ"); - $this->assertTrue($separator->getJungseong() === "ㅕ"); - $this->assertNull($separator->getJongseong()); - - - $separator->separate("뷁"); - $this->assertTrue($separator->getChoseong() === "ㅂ"); - $this->assertTrue($separator->getJungseong() === "ㅞ"); - $this->assertTrue($separator->getJongseong() === "ㄺ"); - } - - public function testStrictMode() { - $separator = new Separator(); - $separator->strictMode(); - $separator->separate("가"); - $this->assertTrue($separator->getChoseong() === mb_chr(0x1100)); - $this->assertTrue($separator->getJungseong() === mb_chr(0x1161)); - $this->assertNull($separator->getJongseong()); - - - $separator->separate("곰"); - $this->assertTrue($separator->getChoseong() === mb_chr(0x1100)); - $this->assertTrue($separator->getJungseong() === mb_chr(0x1169)); - $this->assertTrue($separator->getJongseong() === mb_chr(0x11B7)); - - $separator->separate("쉐"); - $this->assertTrue($separator->getChoseong() === mb_chr(0x1109)); - $this->assertTrue($separator->getJungseong() === mb_chr(0x1170)); - $this->assertNull($separator->getJongseong()); - - - $separator->separate("뷁"); - $this->assertTrue($separator->getChoseong() === mb_chr(0x1107)); - $this->assertTrue($separator->getJungseong() === mb_chr(0x1170)); - $this->assertTrue($separator->getJongseong() === mb_chr(0x11b0)); - } - -} \ No newline at end of file