diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5340443..fb621c6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ repos: - - repo: https://github.com/pre-commit/pre-commit-hooks.git + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v3.4.0 hooks: - id: check-merge-conflict @@ -11,7 +11,7 @@ repos: exclude: '.bumpversion.cfg' - id: requirements-txt-fixer - id: trailing-whitespace - - repo: https://gitlab.com/pycqa/flake8 + - repo: https://github.com/pycqa/flake8 rev: 3.8.4 hooks: - id: flake8 diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..dd2aa46 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,35 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + # You can also specify other tool versions: + # nodejs: "20" + # rust: "1.70" + # golang: "1.20" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + # fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: +# - pdf +# - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +# python: +# install: +# - requirements: docs/requirements.txt diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9283dfc..96accd0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,38 @@ Changelog --------- +`0.51.0`_ (2024-03-10) ++++++++++++++++++++++++++ + +* **[New]** 新增一个用于转换拼音风格的命令行辅助工具:: + + $ python -m pypinyin.tools.toneconvert to-tone 'zhong4 xin1' + zhòng xīn + + $ python -m pypinyin.tools.toneconvert to-tone2 'zhòng xīn' + zho4ng xi1n + + $ python -m pypinyin.tools.toneconvert to-tone3 'zhòng xīn' + zhong4 xin1 + + $ python -m pypinyin.tools.toneconvert to-normal 'zhòng xīn' + zhong xin + +* **[New]** ``pypinyin`` 命令行工具支持接受空格间隔的多个汉字词语作为输入(无需引号包裹)(via `#318`_ Thanks `@Freed-Wu`_) :: + + # 老版本 + $ pypinyin 我 是 小明 + pypinyin: error: unrecognized arguments: 是 小明 + + # 新版本 + $ pypinyin 我 是 小明 + wǒ + shì + xiǎo míng + +* **[Improved]** 使用 `phrase-pinyin-data`_ v0.17.0 的词语拼音数据。 + + `0.50.0`_ (2023-12-11) +++++++++++++++++++++++++ @@ -980,8 +1012,10 @@ __ https://github.com/mozillazg/python-pinyin/issues/8 .. _#164: https://github.com/mozillazg/python-pinyin/pull/164 .. _#176: https://github.com/mozillazg/python-pinyin/pull/176 .. _#279: https://github.com/mozillazg/python-pinyin/pull/279 +.. _#318: https://github.com/mozillazg/python-pinyin/pull/318 .. _@hanabi1224: https://github.com/hanabi1224 .. _@yangwe1: https://github.com/yangwe1 +.. _@Freed-Wu: https://github.com/Freed-Wu .. _变调规则: https://en.wikipedia.org/wiki/Standard_Chinese_phonology#Tone_sandhi .. _0.2.0: https://github.com/mozillazg/python-pinyin/compare/v0.1.0...v0.2.0 @@ -1074,3 +1108,4 @@ __ https://github.com/mozillazg/python-pinyin/issues/8 .. _0.48.0: https://github.com/mozillazg/python-pinyin/compare/v0.47.1...v0.48.0 .. _0.49.0: https://github.com/mozillazg/python-pinyin/compare/v0.48.0...v0.49.0 .. _0.50.0: https://github.com/mozillazg/python-pinyin/compare/v0.49.0...v0.50.0 +.. _0.51.0: https://github.com/mozillazg/python-pinyin/compare/v0.50.0...v0.51.0 diff --git a/README.rst b/README.rst index a85d544..c51c525 100644 --- a/README.rst +++ b/README.rst @@ -37,8 +37,6 @@ 使用示例 -------- -Python 3(Python 2 下把 ``'中心'`` 替换为 ``u'中心'`` 即可): - .. code-block:: python >>> from pypinyin import pinyin, lazy_pinyin, Style @@ -80,7 +78,9 @@ Python 3(Python 2 下把 ``'中心'`` 替换为 ``u'中心'`` 即可): $ pypinyin 音乐 yīn yuè - $ pypinyin -h + + $ python -m pypinyin.tools.toneconvert to-tone 'zhong4 xin1' + zhòng xīn 文档 diff --git a/docs/usage.rst b/docs/usage.rst index 6893122..1185be6 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -213,6 +213,10 @@ 命令行工具 ------------ + +pypinyin +~~~~~~~~~~~ + 程序内置了一个命令行工具 ``pypinyin`` : .. code-block:: console @@ -283,4 +287,32 @@ CYRILLIC_FIRST :py:attr:`~pypinyin.Style.CYRILLIC_FIRST` ================== ========================================= +toneconvert +~~~~~~~~~~~~~ + +通过 ``python -m pypinyin.tools.toneconvert`` 命令可以运行一个辅助转换拼音风格的工具:: + + + $ python -m pypinyin.tools.toneconvert to-tone 'zhong4 xin1' + zhòng xīn + +**注意**: 当输入包含多个拼音时,必须使用空格或英文逗号分隔,该工具不支持多个拼音连在一起的输入。 + +该工具支持的命令如下:: + + $ python -m pypinyin.tools.toneconvert -h + + usage: toneconvert.py [-h] {to-normal,to-tone,to-tone2,to-tone3} ... + + options: + -h, --help show this help message and exit + + subcommands: + {to-normal,to-tone,to-tone2,to-tone3} + to-normal call pypinyin.contrib.tone_convert.to_normal() with inputs + to-tone call pypinyin.contrib.tone_convert.to_tone() with inputs + to-tone2 call pypinyin.contrib.tone_convert.to_tone2() with inputs + to-tone3 call pypinyin.contrib.tone_convert.to_tone3() with inputs + + .. _《汉语拼音方案》: http://www.moe.gov.cn/s78/A19/yxs_left/moe_810/s230/195802/t19580201_186000.html diff --git a/phrase-pinyin-data b/phrase-pinyin-data index dbf645d..1114cb9 160000 --- a/phrase-pinyin-data +++ b/phrase-pinyin-data @@ -1 +1 @@ -Subproject commit dbf645df063e2771c7247252e292b313cc66c4b8 +Subproject commit 1114cb9372804062e79d8b78affd333df41bf599 diff --git a/pypinyin/phrases_dict.py b/pypinyin/phrases_dict.py index fb666ea..13cdbd1 100644 --- a/pypinyin/phrases_dict.py +++ b/pypinyin/phrases_dict.py @@ -75,6 +75,7 @@ '一分一毫': [['yī'], ['fēn'], ['yī'], ['háo']], '一分为二': [['yī'], ['fēn'], ['wéi'], ['èr']], '一分子': [['yī'], ['fèn'], ['zi']], + '一分子甲烷': [['yī'], ['fēn'], ['zǐ'], ['jiǎ'], ['wán']], '一分钟': [['yì'], ['fēn'], ['zhōng']], '一切': [['yī'], ['qiè']], '一切万物': [['yī'], ['qiē'], ['wàn'], ['wù']], @@ -3103,7 +3104,7 @@ '九品中正': [['jiǔ'], ['pǐn'], ['zhōng'], ['zhèng']], '九回肠': [['jiǔ'], ['huí'], ['cháng']], '九垓八埏': [['jiǔ'], ['gāi'], ['bā'], ['yán']], - '九大行星': [['jiǔ'], ['dà'], ['háng'], ['xīng']], + '九大行星': [['jiǔ'], ['dà'], ['xíng'], ['xīng']], '九天九地': [['jiǔ'], ['tiān'], ['jiǔ'], ['dì']], '九天仙女': [['jiǔ'], ['tiān'], ['xiān'], ['nǚ']], '九头鸟': [['jiǔ'], ['tóu'], ['niǎo']], @@ -5932,7 +5933,7 @@ '克丁克卯': [['kè'], ['dīng'], ['kè'], ['mǎo']], '克什米尔': [['kè'], ['shí'], ['mǐ'], ['ěr']], '克传弓冶': [['kè'], ['chuán'], ['gōng'], ['yě']], - '克分子': [['kè'], ['fèn'], ['zǐ']], + '克分子': [['kè'], ['fēn'], ['zǐ']], '克尽厥职': [['kè'], ['jìn'], ['jué'], ['zhí']], '克尽职守': [['kè'], ['jìn'], ['zhí'], ['shǒu']], '克己慎行': [['kè'], ['jǐ'], ['shèn'], ['xíng']], @@ -6063,6 +6064,7 @@ '八卦教': [['bā'], ['guà'], ['jiào']], '八大山人': [['bā'], ['dà'], ['shān'], ['rén']], '八大胡同': [['bā'], ['dà'], ['hú'], ['tòng']], + '八大行星': [['bā'], ['dà'], ['xíng'], ['xīng']], '八字打开': [['bā'], ['zì'], ['dǎ'], ['kāi']], '八字没一撇': [['bā'], ['zì'], ['méi'], ['yī'], ['piě']], '八字没见一撇': [['bā'], ['zì'], ['méi'], ['jiàn'], ['yī'], ['piě']], @@ -6111,6 +6113,7 @@ '公共积累': [['gōng'], ['gòng'], ['jī'], ['lěi']], '公共课': [['gōng'], ['gòng'], ['kè']], '公分': [['gōng'], ['fēn']], + '公分子': [['gōng'], ['fēn'], ['zǐ']], '公切线': [['gōng'], ['qiē'], ['xiàn']], '公务员': [['gōng'], ['wù'], ['yuán']], '公助': [['gōng'], ['zhù']], @@ -7318,13 +7321,20 @@ '分头': [['fēn'], ['tóu']], '分娩': [['fēn'], ['miǎn']], '分子': [['fèn'], ['zǐ']], - '分子力': [['fèn'], ['zǐ'], ['lì']], - '分子式': [['fèn'], ['zǐ'], ['shì']], - '分子物理学': [['fèn'], ['zǐ'], ['wù'], ['lǐ'], ['xué']], - '分子生物学': [['fèn'], ['zǐ'], ['shēng'], ['wù'], ['xué']], - '分子筛': [['fèn'], ['zǐ'], ['shāi']], - '分子运动论': [['fèn'], ['zǐ'], ['yùn'], ['dòng'], ['lùn']], - '分子量': [['fèn'], ['zǐ'], ['liàng']], + '分子力': [['fēn'], ['zǐ'], ['lì']], + '分子和分母': [['fēn'], ['zǐ'], ['hé'], ['fēn'], ['mǔ']], + '分子式': [['fēn'], ['zǐ'], ['shì']], + '分子晶体': [['fēn'], ['zǐ'], ['jīng'], ['tǐ']], + '分子晶體': [['fēn'], ['zǐ'], ['jīng'], ['tǐ']], + '分子物理学': [['fēn'], ['zǐ'], ['wù'], ['lǐ'], ['xué']], + '分子生物学': [['fēn'], ['zǐ'], ['shēng'], ['wù'], ['xué']], + '分子生物學': [['fēn'], ['zǐ'], ['shēng'], ['wù'], ['xué']], + '分子筛': [['fēn'], ['zǐ'], ['shāi']], + '分子結構': [['fēn'], ['zǐ'], ['jié'], ['gòu']], + '分子结构': [['fēn'], ['zǐ'], ['jié'], ['gòu']], + '分子运动论': [['fēn'], ['zǐ'], ['yùn'], ['dòng'], ['lùn']], + '分子量': [['fēn'], ['zǐ'], ['liàng']], + '分子钟': [['fēn'], ['zǐ'], ['zhōng']], '分守要津': [['fēn'], ['shǒu'], ['yào'], ['jīn']], '分宜': [['fēn'], ['yí']], '分宵达曙': [['fēn'], ['xiāo'], ['dá'], ['shǔ']], @@ -13820,7 +13830,7 @@ '大藏经': [['dà'], ['zàng'], ['jīng']], '大虫': [['dà'], ['chóng']], '大行大市': [['dà'], ['háng'], ['dà'], ['shì']], - '大行星': [['dà'], ['háng'], ['xīng']], + '大行星': [['dà'], ['xíng'], ['xīng']], '大街': [['dà'], ['jiē']], '大街小巷': [['dà'], ['jiē'], ['xiǎo'], ['xiàng']], '大衣': [['dà'], ['yī']], @@ -21217,6 +21227,7 @@ '换约': [['huàn'], ['yuē']], '换脑筋': [['huàn'], ['nǎo'], ['jīn']], '换血': [['huàn'], ['xuè']], + '换行': [['huàn'], ['háng']], '换衣服': [['huàn'], ['yī'], ['fú']], '换骨夺胎': [['huàn'], ['gǔ'], ['duó'], ['tāi']], '换骨脱胎': [['huàn'], ['gǔ'], ['tuō'], ['tāi']], @@ -21556,6 +21567,7 @@ '揭露': [['jiē'], ['lù']], '援古刺今': [['yuán'], ['gǔ'], ['cì'], ['jīn']], '援款': [['yuán'], ['kuǎn']], + '援藏': [['yuán'], ['zàng']], '援鳖失龟': [['yuán'], ['biē'], ['shī'], ['guī']], '揽辔中原': [['lǎn'], ['pèi'], ['zhōng'], ['yuán']], '揽辔澄清': [['lǎn'], ['pèi'], ['chéng'], ['qīng']], @@ -24783,6 +24795,7 @@ '极少数': [['jí'], ['shǎo'], ['shù']], '极度': [['jí'], ['dù']], '极往知来': [['jí'], ['wǎng'], ['zhī'], ['lái']], + '极性分子': [['jí'], ['xìng'], ['fēn'], ['zǐ']], '极恶': [['jí'], ['è']], '极恶不赦': [['jí'], ['è'], ['bù'], ['shè']], '极恶穷凶': [['jí'], ['è'], ['qióng'], ['xiōng']], @@ -25485,6 +25498,7 @@ '楞头磕脑': [['léng'], ['tóu'], ['kē'], ['nǎo']], '楞眉横眼': [['lèng'], ['méi'], ['héng'], ['yǎn']], '楦头': [['xuàn'], ['tóu']], + '極性分子': [['jí'], ['xìng'], ['fēn'], ['zǐ']], '楷书': [['kǎi'], ['shū']], '楷体': [['kǎi'], ['tǐ']], '楷模': [['kǎi'], ['mó']], @@ -28232,6 +28246,7 @@ '漠不相关': [['mò'], ['bù'], ['xiāng'], ['guān']], '漠北': [['mò'], ['běi']], '漠南': [['mò'], ['nán']], + '漢藏': [['hàn'], ['zàng']], '漩涡': [['xuán'], ['wō']], '漫不加意': [['màn'], ['bù'], ['jiā'], ['yì']], '漫不经心': [['màn'], ['bù'], ['jīng'], ['xīn']], @@ -39081,6 +39096,7 @@ '超假': [['chāo'], ['jiǎ']], '超凡人圣': [['chāo'], ['fán'], ['rén'], ['shèng']], '超凡脱俗': [['chāo'], ['fán'], ['tuō'], ['sú']], + '超分子': [['chāo'], ['fēn'], ['zǐ']], '超员': [['chāo'], ['yuán']], '超导体': [['chāo'], ['dǎo'], ['tǐ']], '超市': [['chāo'], ['shì']], @@ -44628,8 +44644,10 @@ '高八度': [['gāo'], ['bā'], ['dù']], '高兴': [['gāo'], ['xìng']], '高冠博带': [['gāo'], ['guān'], ['bó'], ['dài']], - '高分子': [['gāo'], ['fèn'], ['zǐ']], - '高分子化合物': [['gāo'], ['fèn'], ['zǐ'], ['huà'], ['hé'], ['wù']], + '高分子': [['gāo'], ['fēn'], ['zǐ']], + '高分子功能材料': [['gāo'], ['fēn'], ['zǐ'], ['gōng'], ['néng'], ['cái'], ['liào']], + '高分子化合物': [['gāo'], ['fēn'], ['zǐ'], ['huà'], ['hé'], ['wù']], + '高分子化工': [['gāo'], ['fēn'], ['zǐ'], ['huà'], ['gōng']], '高压': [['gāo'], ['yā']], '高压电': [['gāo'], ['yā'], ['diàn']], '高压线': [['gāo'], ['yā'], ['xiàn']], diff --git a/pypinyin/runner.py b/pypinyin/runner.py index 17d4cef..208903f 100644 --- a/pypinyin/runner.py +++ b/pypinyin/runner.py @@ -77,7 +77,7 @@ def get_parser(): parser.add_argument('-m', '--heteronym', help='enable heteronym', action='store_true') # 要查询的汉字 - parser.add_argument('hans', help='chinese string') + parser.add_argument('hans', nargs='+', help='chinese string') return parser @@ -98,7 +98,9 @@ def main(): parser = get_parser() options = parser.parse_args(args) if PY2: - hans = options.hans.decode(sys.stdin.encoding or 'utf-8') + hans = [ + han.decode(sys.stdin.encoding or 'utf-8') for han in options.hans + ] else: hans = options.hans func = getattr(pypinyin, options.func) @@ -121,20 +123,21 @@ def main(): # 不输出任何字符,防止污染命令行命令的输出结果 # 其实主要是为了干掉 jieba 内的 print 语句 ;) sys.stdout = sys.stderr = NullWriter() - result = func(hans, style=style, **kwargs) + results = [func(han, style=style, **kwargs) for han in hans] # 恢复默认 sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ - if not result: - print('') - elif result and isinstance(result, (list, tuple)): - if isinstance(result[0], (list, tuple)): - print(' '.join([','.join(s) for s in result])) + for result in results: + if not result: + print('') + elif result and isinstance(result, (list, tuple)): + if isinstance(result[0], (list, tuple)): + print(' '.join([','.join(s) for s in result])) + else: + print(result) else: print(result) - else: - print(result) if __name__ == '__main__': diff --git a/pypinyin/tools/__init__.py b/pypinyin/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pypinyin/tools/toneconvert.py b/pypinyin/tools/toneconvert.py new file mode 100644 index 0000000..66bb1d8 --- /dev/null +++ b/pypinyin/tools/toneconvert.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals +from argparse import ArgumentParser +from functools import partial +import re +import sys + +from pypinyin.compat import PY2 +from pypinyin.style._constants import ( + PHONETIC_SYMBOL_DICT, PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE +) +from pypinyin.contrib.tone_convert import ( + to_normal, + to_tone, + to_tone2, + to_tone3, + # to_initials, + # to_finals, + # to_finals_tone, + # to_finals_tone2, + # to_finals_tone3, +) + +re_pinyin = re.compile( + r'(?m)(^|\s|,)([1-5a-zêü{0}]+)'.format( + re.escape( + ''.join(x for x in PHONETIC_SYMBOL_DICT if len(x) == 1) + ) + ) +) +ACTIONS = { + 'to_normal': to_normal, + 'to_tone': to_tone, + 'to_tone2': to_tone2, + 'to_tone3': to_tone3, + # 'to_initials': to_initials, + # 'to_finals': to_finals, + # 'to_finals_tone': to_finals_tone, + # 'to_finals_tone2': to_finals_tone2, + # 'to_finals_tone3': to_finals_tone3, +} + + +def re_sub(action, match_obj): + func = ACTIONS[action] + converted = func(match_obj.group(2)) + return '{0}{1}'.format(match_obj.group(1), converted) + + +def prepare(input): + for k, v in PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE.items(): + if k in input: + input = input.replace(k, v) + return input + + +def convert(action, args): + inputs = args.inputs + for item in inputs: + item = prepare(item) + result = re_pinyin.sub(lambda m: re_sub(action, m), item) + print(result) + + +def get_parser(): + parser = ArgumentParser() + + if PY2 or sys.version_info < (3, 7): + subparser = parser.add_subparsers() + else: + subparser = parser.add_subparsers(required=True, title='subcommands') + + for key in ACTIONS.keys(): + name = key.replace('_', '-') + func = partial(convert, key) + p = subparser.add_parser( + name, + help='call pypinyin.contrib.tone_convert.{}() with inputs'.format(key)) + p.set_defaults(func=func) + p.add_argument('inputs', nargs='+') + + return parser + + +def main(argv): + argv = argv[:] + + if not sys.stdin.isatty(): + pipe_data = sys.stdin.read().strip() + else: + pipe_data = '' + if pipe_data: + argv.append(pipe_data) + + parser = get_parser() + args = parser.parse_args(argv) + args.func(args) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/pypinyin/tools/toneconvert.pyi b/pypinyin/tools/toneconvert.pyi new file mode 100644 index 0000000..8c80f30 --- /dev/null +++ b/pypinyin/tools/toneconvert.pyi @@ -0,0 +1,16 @@ +from argparse import ArgumentParser, Namespace +import re +from typing import Union, Text, ByteString, Dict, Any, List + +re_pinyin = ... # type: Any +ACTIONS = ... # type: Dict[Text, Any] + +def re_sub(action: Text, match_obj: re.Match[Text]) -> Text: ... + +def prepare(input: Text) -> Text: ... + +def convert(action: Text, args: Namespace) -> None: ... + +def get_parser() -> ArgumentParser: ... + +def main(argv: List[Text]) -> None: ... diff --git a/tests/test_cmd.py b/tests/test_cmd.py index fedc3ff..4ed4677 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -3,31 +3,76 @@ from __future__ import unicode_literals -from pypinyin.runner import get_parser +import sys +from pypinyin.compat import SUPPORT_UCS4 +from pypinyin import runner +from pypinyin.tools import toneconvert +from pytest import mark -def test_default(): - options = get_parser().parse_args(['你好']) +class Buffer(object): + def __init__(self): + self._data = [] + + def write(self, data): + self._data.append(data) + + +def test_runner_default(): + options = runner.get_parser().parse_args(['你好']) assert options.func == 'pinyin' assert options.style == 'zh4ao' assert options.separator == '-' assert not options.heteronym - assert options.hans == '你好' + assert options.hans == ['你好'] assert options.errors == 'default' -def test_custom(): - options = get_parser().parse_args(['--func', 'slug', - '--style', 'zhao', - '--separator', ' ', - '--errors', 'ignore', - '--heteronym', '你好啊']) +def test_runner_custom(): + options = runner.get_parser().parse_args([ + '--func', 'slug', '--style', 'zhao', '--separator', ' ', + '--errors', 'ignore', '--heteronym', '你好啊']) assert options.func == 'slug' assert options.style == 'zhao' assert options.separator == ' ' assert options.errors == 'ignore' assert options.heteronym - assert options.hans == '你好啊' + assert options.hans == ['你好啊'] + + +@mark.parametrize('args,output', [ + [['to-normal', 'yí,yì'], ['yi,yi', '\n']], + [['to-tone', 'yi2,yi4'], ['yí,yì', '\n']], + [['to-tone', 'hao3'], ['hǎo', '\n']], + [['to-tone', 'zhong4 xin1'], ['zhòng xīn', '\n']], + [['to-tone2', 'hǎo'], ['ha3o', '\n']], + [['to-tone3', 'hǎo'], ['hao3', '\n']], +]) +def test_toneconvert_default(args, output): + buf = Buffer() + sys.stdout = sys.stderr = buf + toneconvert.main(args) + sys.stdout = sys.__stdout__ + sys.stderr = sys.__stderr__ + + assert buf._data == output + + +@mark.skipif(not SUPPORT_UCS4, reason='dont support ucs4') +@mark.parametrize('args,output', [ + [['to-normal', 'm̄, ḿ, m̀, ê̄, ế, ê̌'], ['m, m, m, ê, ê, ê', '\n']], + [['to-tone', 'm1, m2, m4, ê1, ê2, ê3'], ['m̄, ḿ, m̀, ê̄, ế, ê̌', '\n']], + [['to-tone2', 'm̄, ḿ, m̀, ê̄, ế, ê̌'], ['m1, m2, m4, ê1, ê2, ê3', '\n']], + [['to-tone3', 'm̄, ḿ, m̀, ê̄, ế, ê̌'], ['m1, m2, m4, ê1, ê2, ê3', '\n']], +]) +def test_toneconvert_nme(args, output): + buf = Buffer() + sys.stdout = sys.stderr = buf + toneconvert.main(args) + sys.stdout = sys.__stdout__ + sys.stderr = sys.__stderr__ + + assert buf._data == output if __name__ == '__main__':