runner.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from __future__ import unicode_literals
  4. from argparse import ArgumentParser
  5. import logging
  6. import sys
  7. import pypinyin
  8. from pypinyin.compat import PY2
  9. style_map = {
  10. 'NORMAL': pypinyin.Style.NORMAL,
  11. 'zhao': pypinyin.Style.NORMAL,
  12. 'TONE': pypinyin.Style.TONE,
  13. 'zh4ao': pypinyin.Style.TONE,
  14. 'TONE2': pypinyin.Style.TONE2,
  15. 'zha4o': pypinyin.Style.TONE2,
  16. 'TONE3': pypinyin.Style.TONE3,
  17. 'zhao4': pypinyin.Style.TONE3,
  18. 'INITIALS': pypinyin.Style.INITIALS,
  19. 'zh': pypinyin.Style.INITIALS,
  20. 'FIRST_LETTER': pypinyin.Style.FIRST_LETTER,
  21. 'z': pypinyin.Style.FIRST_LETTER,
  22. 'FINALS': pypinyin.Style.FINALS,
  23. 'ao': pypinyin.Style.FINALS,
  24. 'FINALS_TONE': pypinyin.Style.FINALS_TONE,
  25. '4ao': pypinyin.Style.FINALS_TONE,
  26. 'FINALS_TONE2': pypinyin.Style.FINALS_TONE2,
  27. 'a4o': pypinyin.Style.FINALS_TONE2,
  28. 'FINALS_TONE3': pypinyin.Style.FINALS_TONE3,
  29. 'ao4': pypinyin.Style.FINALS_TONE3,
  30. 'BOPOMOFO': pypinyin.Style.BOPOMOFO,
  31. 'BOPOMOFO_FIRST': pypinyin.Style.BOPOMOFO_FIRST,
  32. 'CYRILLIC': pypinyin.Style.CYRILLIC,
  33. 'CYRILLIC_FIRST': pypinyin.Style.CYRILLIC_FIRST,
  34. }
  35. func_map = {
  36. 'pinyin': pypinyin.pinyin,
  37. 'slug': pypinyin.slug,
  38. }
  39. default_style = 'zh4ao'
  40. class NullWriter(object):
  41. """数据流黑洞,类似 linux/unix 下 /dev/null 的效果。"""
  42. def write(self, string):
  43. pass
  44. def get_parser():
  45. parser = ArgumentParser(description='convert chinese to pinyin.')
  46. parser.add_argument('-V', '--version', action='version',
  47. version='{0} {1}'.format(
  48. pypinyin.__title__, pypinyin.__version__
  49. ))
  50. # 要执行的函数名称
  51. parser.add_argument('-f', '--func',
  52. help='function name (default: "pinyin")',
  53. choices=['pinyin', 'slug'],
  54. default='pinyin')
  55. # 拼音风格
  56. parser.add_argument(
  57. '-s', '--style',
  58. help='pinyin style (default: "{0}")'.format(default_style),
  59. choices=style_map.keys(), default=default_style
  60. )
  61. parser.add_argument('-p', '--separator',
  62. help='slug separator (default: "-")',
  63. default='-')
  64. parser.add_argument('-e', '--errors',
  65. help=('how to handle none-pinyin string'
  66. ' (default: "default")'),
  67. choices=['default', 'ignore', 'replace'],
  68. default='default')
  69. # 输出多音字
  70. parser.add_argument('-m', '--heteronym', help='enable heteronym',
  71. action='store_true')
  72. # 要查询的汉字
  73. parser.add_argument('hans', nargs='+', help='chinese string')
  74. return parser
  75. def main():
  76. # 禁用除 CRITICAL 外的日志消息
  77. logging.disable(logging.CRITICAL)
  78. # read hans from stdin
  79. if not sys.stdin.isatty():
  80. pipe_data = sys.stdin.read().strip()
  81. else:
  82. pipe_data = ''
  83. args = sys.argv[1:]
  84. if pipe_data:
  85. args.append(pipe_data)
  86. # 获取命令行选项和参数
  87. parser = get_parser()
  88. options = parser.parse_args(args)
  89. if PY2:
  90. hans = [
  91. han.decode(sys.stdin.encoding or 'utf-8') for han in options.hans
  92. ]
  93. else:
  94. hans = options.hans
  95. func = getattr(pypinyin, options.func)
  96. style = style_map[options.style]
  97. heteronym = options.heteronym
  98. separator = options.separator
  99. errors = options.errors
  100. func_kwargs = {
  101. 'pinyin': {'heteronym': heteronym, 'errors': errors},
  102. 'slug': {'heteronym': heteronym, 'separator': separator,
  103. 'errors': errors},
  104. }
  105. if PY2:
  106. kwargs = func_kwargs[func.func_name]
  107. else:
  108. kwargs = func_kwargs[func.__name__]
  109. # 重设标准输出流和标准错误流
  110. # 不输出任何字符,防止污染命令行命令的输出结果
  111. # 其实主要是为了干掉 jieba 内的 print 语句 ;)
  112. sys.stdout = sys.stderr = NullWriter()
  113. results = [func(han, style=style, **kwargs) for han in hans]
  114. # 恢复默认
  115. sys.stdout = sys.__stdout__
  116. sys.stderr = sys.__stderr__
  117. for result in results:
  118. if not result:
  119. print('')
  120. elif result and isinstance(result, (list, tuple)):
  121. if isinstance(result[0], (list, tuple)):
  122. print(' '.join([','.join(s) for s in result]))
  123. else:
  124. print(result)
  125. else:
  126. print(result)
  127. if __name__ == '__main__':
  128. main()