Restore 0.1.5 version from stash
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# 向后兼容
|
||||
from pypinyin.style._tone_rule import right_mark_index # noqa
|
||||
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Text, Optional
|
||||
|
||||
|
||||
def right_mark_index(pinyin_no_number: Text) -> Optional[int]: ...
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""最大正向匹配分词"""
|
||||
|
||||
# 用于向后兼容,TODO: 废弃
|
||||
from pypinyin.seg.mmseg import Seg, PrefixSet, seg, retrain, p_set # noqa
|
||||
@@ -0,0 +1,29 @@
|
||||
from typing import Iterator
|
||||
from typing import Text
|
||||
|
||||
|
||||
class Seg(object):
|
||||
"""最大正向匹配分词
|
||||
|
||||
:type prefix_set: PrefixSet
|
||||
"""
|
||||
def __init__(self, prefix_set: PrefixSet) -> None: ...
|
||||
|
||||
def cut(self, text: Text) -> Iterator[Text]: ...
|
||||
|
||||
def train(self, words: Iterator[Text]) -> None: ...
|
||||
|
||||
|
||||
class PrefixSet(object):
|
||||
def __init__(self) -> None: ...
|
||||
|
||||
def train(self, word_s: Iterator[Text]) -> None: ...
|
||||
|
||||
def __contains__(self, key: Text) -> bool: ...
|
||||
|
||||
|
||||
p_set = ... # type: PrefixSet
|
||||
seg = ... # type: Seg
|
||||
|
||||
|
||||
def retrain(seg_instance: Seg) -> None: ...
|
||||
@@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from pypinyin import Style
|
||||
from pypinyin.contrib._tone_rule import right_mark_index
|
||||
|
||||
|
||||
_re_number = re.compile(r'\d')
|
||||
|
||||
|
||||
class NeutralToneWith5Mixin(object):
|
||||
"""声调使用数字表示的相关拼音风格下的结果使用 5 标识轻声。
|
||||
|
||||
使用方法::
|
||||
|
||||
from pypinyin import lazy_pinyin, Style
|
||||
from pypinyin.contrib.neutral_tone import NeutralToneWith5Mixin
|
||||
from pypinyin.converter import DefaultConverter
|
||||
from pypinyin.core import Pinyin
|
||||
|
||||
# 原来的结果中不会标识轻声
|
||||
print(lazy_pinyin('好了', style=Style.TONE2))
|
||||
# 输出: ['ha3o', 'le']
|
||||
|
||||
|
||||
class MyConverter(NeutralToneWith5Mixin, DefaultConverter):
|
||||
pass
|
||||
|
||||
my_pinyin = Pinyin(MyConverter())
|
||||
pinyin = my_pinyin.pinyin
|
||||
lazy_pinyin = my_pinyin.lazy_pinyin
|
||||
|
||||
# 新的结果中使用 ``5`` 标识轻声
|
||||
print(lazy_pinyin('好了', style=Style.TONE2))
|
||||
# 输出: ['ha3o', 'le5']
|
||||
|
||||
print(pinyin('好了', style=Style.TONE2))
|
||||
# 输出:[['ha3o'], ['le5']]
|
||||
|
||||
|
||||
"""
|
||||
|
||||
NUMBER_TONE = (Style.TONE2, Style.TONE3, Style.FINALS_TONE2,
|
||||
Style.FINALS_TONE3)
|
||||
NUMBER_AT_END = (Style.TONE3, Style.FINALS_TONE3)
|
||||
|
||||
def post_convert_style(self, han, orig_pinyin, converted_pinyin,
|
||||
style, strict, **kwargs):
|
||||
pre_data = super(NeutralToneWith5Mixin, self).post_convert_style(
|
||||
han, orig_pinyin, converted_pinyin, style, strict, **kwargs)
|
||||
|
||||
if style not in self.NUMBER_TONE:
|
||||
return pre_data
|
||||
|
||||
if pre_data is not None:
|
||||
converted_pinyin = pre_data
|
||||
if not converted_pinyin: # 空字符串
|
||||
return converted_pinyin
|
||||
# 有声调,跳过
|
||||
if _re_number.search(converted_pinyin):
|
||||
return converted_pinyin
|
||||
|
||||
if style in self.NUMBER_AT_END:
|
||||
return '{}5'.format(converted_pinyin)
|
||||
|
||||
# 找到应该在哪个字母上标声调
|
||||
mark_index = right_mark_index(converted_pinyin)
|
||||
before = converted_pinyin[:mark_index + 1]
|
||||
after = converted_pinyin[mark_index + 1:]
|
||||
|
||||
return '{}5{}'.format(before, after)
|
||||
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
from typing import Tuple
|
||||
|
||||
from pypinyin.constants import Style
|
||||
|
||||
TStyle = Style
|
||||
|
||||
|
||||
class NeutralToneWith5Mixin(object):
|
||||
NUMBER_TONE = ... # type: Tuple[TStyle]
|
||||
NUMBER_AT_END = ... # type: Tuple[TStyle]
|
||||
|
||||
def post_convert_style(self, han: Text, orig_pinyin: Text,
|
||||
converted_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Optional[Text]: ...
|
||||
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.style._tone_convert import ( # noqa
|
||||
to_normal,
|
||||
to_tone,
|
||||
to_tone2,
|
||||
to_tone3,
|
||||
to_initials,
|
||||
to_finals,
|
||||
to_finals_tone,
|
||||
to_finals_tone2,
|
||||
to_finals_tone3,
|
||||
tone_to_normal,
|
||||
tone_to_tone2,
|
||||
tone_to_tone3,
|
||||
tone2_to_normal,
|
||||
tone2_to_tone,
|
||||
tone2_to_tone3,
|
||||
tone3_to_normal,
|
||||
tone3_to_tone,
|
||||
tone3_to_tone2,
|
||||
# 向后兼容
|
||||
_improve_tone3,
|
||||
_get_number_from_pinyin,
|
||||
_v_to_u,
|
||||
_fix_v_u,
|
||||
_re_number,
|
||||
) # noqa
|
||||
@@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
from typing import Tuple
|
||||
|
||||
_re_number = ... # type: Any
|
||||
|
||||
def to_normal(pinyin: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def to_tone(pinyin: Text) -> Text: ...
|
||||
|
||||
def to_tone2(pinyin: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_tone3(pinyin: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_initials(pinyin: Text, strict: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals(pinyin: Text, strict: bool = ..., v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone(pinyin: Text, strict: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone2(pinyin: Text, strict: bool = ..., v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone3(pinyin: Text, strict: bool = ..., v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_normal(tone: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_tone2(tone: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_tone3(tone: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone2_to_normal(tone2: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone2_to_tone(tone2: Text,) -> Text: ...
|
||||
|
||||
def tone2_to_tone3(tone2: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone3_to_normal(tone3: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone3_to_tone(tone3: Text) -> Text: ...
|
||||
|
||||
def tone3_to_tone2(tone3: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def _improve_tone3(tone3: Text, neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def _get_number_from_pinyin(pinyin: Text) -> Optional[int]: ...
|
||||
|
||||
def _v_to_u(pinyin: Text, replace: bool = ...) -> Text: ...
|
||||
|
||||
def _fix_v_u(origin_py: Text, new_py: Text, v_to_u: bool) -> Text: ...
|
||||
@@ -0,0 +1,163 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from pypinyin.contrib.tone_convert import tone_to_tone2, tone2_to_tone
|
||||
|
||||
_re_num = re.compile(r'\d')
|
||||
|
||||
|
||||
class ToneSandhiMixin(object):
|
||||
"""
|
||||
|
||||
按普通话变调规则处理拼音:
|
||||
|
||||
* https://en.wikipedia.org/wiki/Standard_Chinese_phonology#Tone_sandhi
|
||||
* https://studycli.org/zh-CN/learn-chinese/tone-changes-in-mandarin/
|
||||
|
||||
""" # noqa
|
||||
|
||||
def post_pinyin(self, han, heteronym, pinyin_list, **kwargs):
|
||||
ret = super(ToneSandhiMixin, self).post_pinyin(
|
||||
han, heteronym, pinyin_list, **kwargs)
|
||||
if ret is not None:
|
||||
pinyin_list = ret
|
||||
|
||||
pinyin_list = self._third_tone(han, pinyin_list)
|
||||
pinyin_list = self._bu(han, pinyin_list)
|
||||
pinyin_list = self._yi(han, pinyin_list)
|
||||
|
||||
return pinyin_list
|
||||
|
||||
def _third_tone(self, han, pinyin_list):
|
||||
"""
|
||||
|
||||
Third tone sandhi:
|
||||
|
||||
The principal rule of third tone sandhi is:
|
||||
|
||||
When there are two consecutive third-tone syllables, the first of them is pronounced with second tone.
|
||||
|
||||
For example, lǎoshǔ 老鼠 ("mouse") comes to be pronounced láoshǔ [lau̯˧˥ʂu˨˩]. It has been investigated whether the rising contour (˧˥) on the prior syllable is in fact identical to a normal second tone; it has been concluded that it is, at least in terms of auditory perception.[1]: 237
|
||||
|
||||
When there are three or more third tones in a row, the situation becomes more complicated, since a third tone that precedes a second tone resulting from third tone sandhi may or may not be subject to sandhi itself. The results may depend on word boundaries, stress, and dialectal variations. General rules for three-syllable third-tone combinations can be formulated as follows:
|
||||
|
||||
If the first word is two syllables and the second word is one syllable, then the first two syllables become second tones. For example, bǎoguǎn hǎo 保管好 ("to take good care of") takes the pronunciation báoguán hǎo [pau̯˧˥kwan˧˥xau̯˨˩˦].
|
||||
If the first word is one syllable, and the second word is two syllables, the second syllable becomes second tone, but the first syllable remains third tone. For example: lǎo bǎoguǎn 老保管 ("to take care of all the time") takes the pronunciation lǎo báoguǎn [lau̯˨˩pau̯˧˥kwan˨˩˦].
|
||||
|
||||
Some linguists have put forward more comprehensive systems of sandhi rules for multiple third tone sequences. For example, it is proposed[1]: 248 that modifications are applied cyclically, initially within rhythmic feet (trochees; see below), and that sandhi "need not apply between two cyclic branches".
|
||||
|
||||
""" # noqa
|
||||
tone2_pinyin_list = [tone_to_tone2(x[0]) for x in pinyin_list]
|
||||
if '3' not in ''.join(tone2_pinyin_list):
|
||||
return pinyin_list
|
||||
|
||||
changed = False
|
||||
third_num = 0
|
||||
for pinyin in tone2_pinyin_list:
|
||||
if '3' in pinyin:
|
||||
third_num += 1
|
||||
else:
|
||||
third_num = 0
|
||||
|
||||
if third_num == 2:
|
||||
for i, v in enumerate(tone2_pinyin_list):
|
||||
if '3' in v:
|
||||
tone2_pinyin_list[i] = v.replace('3', '2')
|
||||
changed = True
|
||||
break
|
||||
|
||||
elif third_num > 2:
|
||||
n = 1
|
||||
for i, v in enumerate(tone2_pinyin_list):
|
||||
if '3' in v:
|
||||
if n == third_num:
|
||||
break
|
||||
tone2_pinyin_list[i] = v.replace('3', '2')
|
||||
changed = True
|
||||
n += 1
|
||||
|
||||
if changed:
|
||||
return [[tone2_to_tone(x)] for x in tone2_pinyin_list]
|
||||
|
||||
return pinyin_list
|
||||
|
||||
def _bu(self, han, pinyin_list):
|
||||
"""
|
||||
|
||||
For 不 bù:
|
||||
|
||||
不 is pronounced with second tone when followed by a fourth tone syllable.
|
||||
|
||||
Example: 不是 (bù+shì, "to not be") becomes búshì [pu˧˥ʂɻ̩˥˩]
|
||||
|
||||
In other cases, 不 is pronounced with fourth tone. However, when used between words in an A-not-A question, it may become neutral in tone (e.g., 是不是 shìbushì).
|
||||
|
||||
""" # noqa
|
||||
if '不' not in han:
|
||||
return pinyin_list
|
||||
|
||||
tone2_pinyin_list = [tone_to_tone2(x[0]) for x in pinyin_list]
|
||||
changed = False
|
||||
|
||||
for i, h in enumerate(han):
|
||||
current_pinyin = tone2_pinyin_list[i]
|
||||
if h == '不' and i < len(han) - 1:
|
||||
next_pinyin = tone2_pinyin_list[i+1]
|
||||
if '4' in next_pinyin:
|
||||
tone2_pinyin_list[i] = current_pinyin.replace('4', '2')
|
||||
changed = True
|
||||
else:
|
||||
tone2_pinyin_list[i] = _re_num.sub('4', current_pinyin)
|
||||
changed = True
|
||||
elif h == '不':
|
||||
tone2_pinyin_list[i] = _re_num.sub('4', current_pinyin)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
return [[tone2_to_tone(x)] for x in tone2_pinyin_list]
|
||||
|
||||
return pinyin_list
|
||||
|
||||
def _yi(self, han, pinyin_list):
|
||||
"""
|
||||
|
||||
For 一 yī:
|
||||
|
||||
一 is pronounced with second tone when followed by a fourth tone syllable.
|
||||
|
||||
Example: 一定 (yī+dìng, "must") becomes yídìng [i˧˥tiŋ˥˩]
|
||||
|
||||
Before a first, second or third tone syllable, 一 is pronounced with fourth tone.
|
||||
|
||||
Examples:一天 (yī+tiān, "one day") becomes yìtiān [i˥˩tʰjɛn˥], 一年 (yī+nián, "one year") becomes yìnián [i˥˩njɛn˧˥], 一起 (yī+qǐ, "together") becomes yìqǐ [i˥˩t͡ɕʰi˨˩˦].
|
||||
|
||||
When final, or when it comes at the end of a multi-syllable word (regardless of the first tone of the next word), 一 is pronounced with first tone. It also has first tone when used as an ordinal number (or part of one), and when it is immediately followed by any digit (including another 一; hence both syllables of the word 一一 yīyī and its compounds have first tone).
|
||||
When 一 is used between two reduplicated words, it may become neutral in tone (e.g. 看一看 kànyikàn ("to take a look of")).
|
||||
|
||||
""" # noqa
|
||||
if '一' not in han:
|
||||
return pinyin_list
|
||||
|
||||
tone2_pinyin_list = [tone_to_tone2(x[0]) for x in pinyin_list]
|
||||
changed = False
|
||||
|
||||
for i, h in enumerate(han):
|
||||
current_pinyin = tone2_pinyin_list[i]
|
||||
if h == '一' and i < len(han) - 1:
|
||||
next_pinyin = tone2_pinyin_list[i + 1]
|
||||
if '4' in next_pinyin:
|
||||
tone2_pinyin_list[i] = current_pinyin.replace('4', '2')
|
||||
changed = True
|
||||
else:
|
||||
tone2_pinyin_list[i] = _re_num.sub('4', current_pinyin)
|
||||
changed = True
|
||||
elif h == '一':
|
||||
tone2_pinyin_list[i] = _re_num.sub('1', current_pinyin)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
return [[tone2_to_tone(x)] for x in tone2_pinyin_list]
|
||||
|
||||
return pinyin_list
|
||||
@@ -0,0 +1,21 @@
|
||||
from typing import Any
|
||||
from typing import List
|
||||
from typing import Union
|
||||
from typing import Callable
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
|
||||
from pypinyin.constants import Style
|
||||
|
||||
|
||||
TStyle = Style
|
||||
TErrors = Union[Callable[[Text], Text], Text]
|
||||
TPinyinResult = List[List[Text]]
|
||||
TErrorResult = Union[Text, List[Text], None]
|
||||
TNoPinyinResult = Union[TPinyinResult, List[Text], Text, None]
|
||||
|
||||
class ToneSandhiMixin(object):
|
||||
|
||||
def post_pinyin(self, han: Text, heteronym: bool,
|
||||
pinyin: TPinyinResult,
|
||||
**kwargs: Any) -> Union[TPinyinResult, None]: ...
|
||||
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class V2UMixin(object):
|
||||
"""无声调相关拼音风格下的结果使用 ``ü`` 代替原来的 ``v``
|
||||
|
||||
使用方法::
|
||||
|
||||
from pypinyin import lazy_pinyin, Style
|
||||
from pypinyin.contrib.uv import V2UMixin
|
||||
from pypinyin.converter import DefaultConverter
|
||||
from pypinyin.core import Pinyin
|
||||
|
||||
# 原来的结果中会使用 ``v`` 表示 ``ü``
|
||||
print(lazy_pinyin('战略'))
|
||||
# 输出:['zhan', 'lve']
|
||||
|
||||
|
||||
class MyConverter(V2UMixin, DefaultConverter):
|
||||
pass
|
||||
|
||||
my_pinyin = Pinyin(MyConverter())
|
||||
pinyin = my_pinyin.pinyin
|
||||
lazy_pinyin = my_pinyin.lazy_pinyin
|
||||
|
||||
# 新的结果中使用 ``ü`` 代替原来的 ``v``
|
||||
print(lazy_pinyin('战略'))
|
||||
# 输出: ['zhan', 'lüe']
|
||||
|
||||
print(pinyin('战略', style=Style.NORMAL))
|
||||
# 输出:[['zhan'], ['lüe']]
|
||||
|
||||
|
||||
"""
|
||||
|
||||
def post_convert_style(self, han, orig_pinyin, converted_pinyin,
|
||||
style, strict, **kwargs):
|
||||
pre_data = super(V2UMixin, self).post_convert_style(
|
||||
han, orig_pinyin, converted_pinyin, style, strict, **kwargs)
|
||||
|
||||
if pre_data is not None:
|
||||
converted_pinyin = pre_data
|
||||
|
||||
return converted_pinyin.replace('v', 'ü')
|
||||
@@ -0,0 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
|
||||
from pypinyin.constants import Style
|
||||
|
||||
TStyle = Style
|
||||
|
||||
|
||||
class V2UMixin(object):
|
||||
|
||||
def post_convert_style(self, han: Text, orig_pinyin: Text,
|
||||
converted_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Optional[Text]: ...
|
||||
Reference in New Issue
Block a user