Skip to content

Commit

Permalink
feat: 使用 heteronym 代替 polyphonic 多音字 #184
Browse files Browse the repository at this point in the history
  • Loading branch information
overtrue committed Mar 30, 2024
1 parent 8255ee3 commit 20f75b7
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 19 deletions.
25 changes: 17 additions & 8 deletions src/Converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class Converter

public const TONE_STYLE_NONE = 'none';

protected bool $polyphonic = false;
protected bool $heteronym = false;

protected bool $polyphonicAsList = false;
protected bool $heteronymAsList = false;

protected bool $asSurname = false;

Expand Down Expand Up @@ -57,14 +57,23 @@ public static function make(): static
return new static();
}

public function polyphonic(bool $asList = false): static
public function heteronym(bool $asList = false): static
{
$this->polyphonic = true;
$this->polyphonicAsList = $asList;
$this->heteronym = true;
$this->heteronymAsList = $asList;

return $this;
}

/**
* @deprecated Use `heteronym` instead.
* This method will be removed in the next major version.
*/
public function polyphonic(bool $asList = false): static
{
return $this->heteronym($asList);
}

public function surname(): static
{
$this->asSurname = true;
Expand Down Expand Up @@ -166,7 +175,7 @@ public function when(bool $condition, callable $callback): static
return $this;
}

public function convert(string $string, callable $beforeSplit = null): Collection
public function convert(string $string, ?callable $beforeSplit = null): Collection
{
// 把原有的数字和汉字分离,避免拼音转换时被误作声调
$string = preg_replace_callback('~[a-z0-9_-]+~i', function ($matches) {
Expand All @@ -179,7 +188,7 @@ public function convert(string $string, callable $beforeSplit = null): Collectio
}

// 多音字
if ($this->polyphonic) {
if ($this->heteronym) {
return $this->convertAsChars($string, true);
}

Expand Down Expand Up @@ -211,7 +220,7 @@ public function convertAsChars(string $string, bool $polyphonic = false): Collec
if (isset($map[$char])) {
if ($polyphonic) {
$pinyin = \array_map(fn ($pinyin) => $this->formatTone($pinyin, $this->toneStyle), $map[$char]);
if ($this->polyphonicAsList) {
if ($this->heteronymAsList) {
$items[] = [$char => $pinyin];
} else {
$items[$char] = $pinyin;
Expand Down
45 changes: 34 additions & 11 deletions src/Pinyin.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,60 @@ class Pinyin
{
public static function name(string $name, string $toneStyle = Converter::TONE_STYLE_SYMBOL): Collection
{
return self::surname()->withToneStyle($toneStyle)->convert($name);
return self::converter()->surname()->withToneStyle($toneStyle)->convert($name);
}

public static function passportName(string $name, string $toneStyle = Converter::TONE_STYLE_NONE): Collection
{
return self::surname()->yuToYu()->withToneStyle($toneStyle)->convert($name);
return self::converter()->surname()->yuToYu()->withToneStyle($toneStyle)->convert($name);
}

public static function phrase(string $string, string $toneStyle = Converter::TONE_STYLE_SYMBOL): Collection
{
return self::noPunctuation()->withToneStyle($toneStyle)->convert($string);
return self::converter()->noPunctuation()->withToneStyle($toneStyle)->convert($string);
}

public static function sentence(string $string, string $toneStyle = Converter::TONE_STYLE_SYMBOL): Collection
{
return self::withToneStyle($toneStyle)->convert($string);
return self::converter()->withToneStyle($toneStyle)->convert($string);
}

public static function fullSentence(string $string, string $toneStyle = Converter::TONE_STYLE_SYMBOL): Collection
{
return self::noCleanup()->withToneStyle($toneStyle)->convert($string);
return self::converter()->noCleanup()->withToneStyle($toneStyle)->convert($string);
}

public static function heteronym(string $string, string $toneStyle = Converter::TONE_STYLE_SYMBOL, bool $asList = false): Collection
{
return self::converter()->heteronym($asList)->withToneStyle($toneStyle)->convert($string);
}

public static function heteronymAsList(string $string, string $toneStyle = Converter::TONE_STYLE_SYMBOL): Collection
{
return self::heteronym($string, $toneStyle, true);
}

/**
* @deprecated Use `heteronym` instead.
* This method will be removed in the next major version.
*/
public static function polyphones(string $string, string $toneStyle = Converter::TONE_STYLE_SYMBOL, bool $asList = false): Collection
{
return self::polyphonic($asList)->withToneStyle($toneStyle)->convert($string);
return self::heteronym($string, $toneStyle, $asList);
}

/**
* @deprecated Use `heteronymAsList` instead.
* This method will be removed in the next major version.
*/
public static function polyphonesAsArray(string $string, string $toneStyle = Converter::TONE_STYLE_SYMBOL): Collection
{
return self::polyphones($string, $toneStyle, true);
return self::heteronym($string, $toneStyle, true);
}

public static function chars(string $string, string $toneStyle = Converter::TONE_STYLE_SYMBOL): Collection
{
return self::onlyHans()->noWords()->withToneStyle($toneStyle)->convert($string);
return self::converter()->onlyHans()->noWords()->withToneStyle($toneStyle)->convert($string);
}

public static function permalink(string $string, string $delimiter = '-'): string
Expand All @@ -68,7 +86,7 @@ public static function permalink(string $string, string $delimiter = '-'): strin
throw new InvalidArgumentException("Delimiter must be one of: '_', '-', '', '.'.");
}

return self::noPunctuation()->noTone()->convert($string)->join($delimiter);
return self::converter()->noPunctuation()->noTone()->convert($string)->join($delimiter);
}

public static function nameAbbr(string $string): Collection
Expand All @@ -78,7 +96,7 @@ public static function nameAbbr(string $string): Collection

public static function abbr(string $string, bool $asName = false, bool $preserveEnglishWords = false): Collection
{
return self::noTone()
return self::converter()->noTone()
->noPunctuation()
->when($asName, fn ($c) => $c->surname())
->convert($string)
Expand All @@ -93,9 +111,14 @@ public static function abbr(string $string, bool $asName = false, bool $preserve
});
}

public static function converter(): Converter
{
return Converter::make();
}

public static function __callStatic(string $name, array $arguments)
{
$converter = Converter::make();
$converter = self::converter();

if (\method_exists($converter, $name)) {
return $converter->$name(...$arguments);
Expand Down
16 changes: 16 additions & 0 deletions tests/ConverterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ public function assertPinyin(array|string $expected, Collection $collection)
$this->assertEquals($expected, \is_array($expected) ? $collection->toArray() : $collection->join());
}

public function test_heteronym()
{
$this->assertPinyin(['chóng', 'qìng'], Converter::make()->convert('重庆'));

$this->assertPinyin([
'' => ['zhòng', 'chóng', 'tóng'],
'' => ['qìng'],
], Converter::make()->heteronym()->convert('重庆'));

$this->assertPinyin([
['' => ['zhòng', 'chóng', 'tóng']],
['' => ['qìng']],
['' => ['qìng']],
], Converter::make()->heteronym(true)->convert('重庆庆'));
}

public function test_polyphonic()
{
$this->assertPinyin(['chóng', 'qìng'], Converter::make()->convert('重庆'));
Expand Down
27 changes: 27 additions & 0 deletions tests/PinyinTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,33 @@ public function test_name_abbr()
$this->assertPinyin(['s', 'c', 'y', 'd'], Pinyin::nameAbbr('单单于单'));
}

public function test_heteronym()
{
$this->assertPinyin([
'' => ['zhòng', 'chóng', 'tóng'],
'' => ['qìng'],
], Pinyin::heteronym('重庆'));

$this->assertPinyin([
'' => ['zhong', 'chong', 'tong'],
'' => ['qing'],
], Pinyin::heteronym('重庆', Converter::TONE_STYLE_NONE));

$this->assertPinyin([
['' => ['zhong4', 'chong2', 'tong2']],
['' => ['qing4']],
['' => ['zhong4', 'chong2', 'tong2']],
['' => ['qing4']],
], Pinyin::heteronym('重庆重庆', Converter::TONE_STYLE_NUMBER, true));

$this->assertPinyin([
['' => ['zhong4', 'chong2', 'tong2']],
['' => ['qing4']],
['' => ['zhong4', 'chong2', 'tong2']],
['' => ['qing4']],
], Pinyin::heteronymAsList('重庆重庆', Converter::TONE_STYLE_NUMBER));
}

public function test_polyphones()
{
$this->assertPinyin([
Expand Down

0 comments on commit 20f75b7

Please sign in to comment.