Merge branch 'l10n-tw' of github.com:l10n-tw/rich into l10n-tw

This commit is contained in:
toto6038 2022-01-23 23:56:14 +08:00
commit 61f1b56192
No known key found for this signature in database
GPG Key ID: CCFEFBB432ECB880
8 changed files with 63 additions and 540 deletions

View File

@ -9,10 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Fix width measurement of 353 emoji variation sequences https://github.com/Textualize/rich/pull/1832
- Workaround for edge case of object from Faiss with no `__class__` https://github.com/Textualize/rich/issues/1838 - Workaround for edge case of object from Faiss with no `__class__` https://github.com/Textualize/rich/issues/1838
## [11.0.0] - 2022-01-09
### Added ### Added

32
poetry.lock generated
View File

@ -3,7 +3,7 @@ name = "appnope"
version = "0.1.2" version = "0.1.2"
description = "Disable App Nap on macOS >= 10.9" description = "Disable App Nap on macOS >= 10.9"
category = "main" category = "main"
optional = true optional = false
python-versions = "*" python-versions = "*"
[[package]] [[package]]
@ -74,7 +74,7 @@ name = "backcall"
version = "0.2.0" version = "0.2.0"
description = "Specifications for callback functions passed in to an API" description = "Specifications for callback functions passed in to an API"
category = "main" category = "main"
optional = true optional = false
python-versions = "*" python-versions = "*"
[[package]] [[package]]
@ -195,7 +195,7 @@ name = "decorator"
version = "5.1.0" version = "5.1.0"
description = "Decorators for Humans" description = "Decorators for Humans"
category = "main" category = "main"
optional = true optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
[[package]] [[package]]
@ -306,10 +306,10 @@ test = ["pytest (!=5.3.4)", "pytest-cov", "flaky", "nose", "jedi (<=0.17.2)"]
[[package]] [[package]]
name = "ipython" name = "ipython"
version = "7.16.2" version = "7.16.3"
description = "IPython: Productive Interactive Computing" description = "IPython: Productive Interactive Computing"
category = "main" category = "main"
optional = true optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
[package.dependencies] [package.dependencies]
@ -340,7 +340,7 @@ name = "ipython-genutils"
version = "0.2.0" version = "0.2.0"
description = "Vestigial utilities from IPython" description = "Vestigial utilities from IPython"
category = "main" category = "main"
optional = true optional = false
python-versions = "*" python-versions = "*"
[[package]] [[package]]
@ -368,7 +368,7 @@ name = "jedi"
version = "0.17.2" version = "0.17.2"
description = "An autocompletion tool for Python that can be used for text editors." description = "An autocompletion tool for Python that can be used for text editors."
category = "main" category = "main"
optional = true optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.dependencies] [package.dependencies]
@ -641,7 +641,7 @@ name = "parso"
version = "0.7.1" version = "0.7.1"
description = "A Python Parser" description = "A Python Parser"
category = "main" category = "main"
optional = true optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[package.extras] [package.extras]
@ -660,7 +660,7 @@ name = "pexpect"
version = "4.8.0" version = "4.8.0"
description = "Pexpect allows easy control of interactive console applications." description = "Pexpect allows easy control of interactive console applications."
category = "main" category = "main"
optional = true optional = false
python-versions = "*" python-versions = "*"
[package.dependencies] [package.dependencies]
@ -671,7 +671,7 @@ name = "pickleshare"
version = "0.7.5" version = "0.7.5"
description = "Tiny 'shelve'-like database with concurrency support" description = "Tiny 'shelve'-like database with concurrency support"
category = "main" category = "main"
optional = true optional = false
python-versions = "*" python-versions = "*"
[[package]] [[package]]
@ -735,7 +735,7 @@ name = "prompt-toolkit"
version = "3.0.24" version = "3.0.24"
description = "Library for building powerful interactive command lines in Python" description = "Library for building powerful interactive command lines in Python"
category = "main" category = "main"
optional = true optional = false
python-versions = ">=3.6.2" python-versions = ">=3.6.2"
[package.dependencies] [package.dependencies]
@ -746,7 +746,7 @@ name = "ptyprocess"
version = "0.7.0" version = "0.7.0"
description = "Run a subprocess in a pseudo terminal" description = "Run a subprocess in a pseudo terminal"
category = "main" category = "main"
optional = true optional = false
python-versions = "*" python-versions = "*"
[[package]] [[package]]
@ -953,7 +953,7 @@ name = "traitlets"
version = "4.3.3" version = "4.3.3"
description = "Traitlets Python config system" description = "Traitlets Python config system"
category = "main" category = "main"
optional = true optional = false
python-versions = "*" python-versions = "*"
[package.dependencies] [package.dependencies]
@ -1013,7 +1013,7 @@ name = "wcwidth"
version = "0.2.5" version = "0.2.5"
description = "Measures the displayed width of unicode strings in a terminal" description = "Measures the displayed width of unicode strings in a terminal"
category = "main" category = "main"
optional = true optional = false
python-versions = "*" python-versions = "*"
[[package]] [[package]]
@ -1273,8 +1273,8 @@ ipykernel = [
{file = "ipykernel-5.5.6.tar.gz", hash = "sha256:4ea44b90ae1f7c38987ad58ea0809562a17c2695a0499644326f334aecd369ec"}, {file = "ipykernel-5.5.6.tar.gz", hash = "sha256:4ea44b90ae1f7c38987ad58ea0809562a17c2695a0499644326f334aecd369ec"},
] ]
ipython = [ ipython = [
{file = "ipython-7.16.2-py3-none-any.whl", hash = "sha256:2f644313be4fdc5c8c2a17467f2949c29423c9e283a159d1fc9bf450a1a300af"}, {file = "ipython-7.16.3-py3-none-any.whl", hash = "sha256:c0427ed8bc33ac481faf9d3acf7e84e0010cdaada945e0badd1e2e74cc075833"},
{file = "ipython-7.16.2.tar.gz", hash = "sha256:613085f8acb0f35f759e32bea35fba62c651a4a2e409a0da11414618f5eec0c4"}, {file = "ipython-7.16.3.tar.gz", hash = "sha256:5ac47dc9af66fc2f5530c12069390877ae372ac905edca75a92a6e363b5d7caa"},
] ]
ipython-genutils = [ ipython-genutils = [
{file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"},

View File

@ -3,11 +3,7 @@
CELL_WIDTHS = [ CELL_WIDTHS = [
(0, 0, 0), (0, 0, 0),
(1, 31, -1), (1, 31, -1),
(35, 35, 2),
(42, 42, 2),
(127, 159, -1), (127, 159, -1),
(169, 169, 2),
(174, 174, 2),
(768, 879, 0), (768, 879, 0),
(1155, 1161, 0), (1155, 1161, 0),
(1425, 1469, 0), (1425, 1469, 0),
@ -174,85 +170,39 @@ CELL_WIDTHS = [
(7675, 7679, 0), (7675, 7679, 0),
(8203, 8207, 0), (8203, 8207, 0),
(8232, 8238, 0), (8232, 8238, 0),
(8252, 8252, 2),
(8265, 8265, 2),
(8288, 8291, 0), (8288, 8291, 0),
(8400, 8432, 0), (8400, 8432, 0),
(8482, 8482, 2),
(8505, 8505, 2),
(8596, 8601, 2),
(8617, 8618, 2),
(8986, 8987, 2), (8986, 8987, 2),
(9000, 9002, 2), (9001, 9002, 2),
(9167, 9167, 2), (9193, 9196, 2),
(9193, 9203, 2), (9200, 9200, 2),
(9208, 9210, 2), (9203, 9203, 2),
(9410, 9410, 2), (9725, 9726, 2),
(9642, 9643, 2),
(9654, 9654, 2),
(9664, 9664, 2),
(9723, 9726, 2),
(9728, 9732, 2),
(9742, 9742, 2),
(9745, 9745, 2),
(9748, 9749, 2), (9748, 9749, 2),
(9752, 9752, 2),
(9757, 9757, 2),
(9760, 9760, 2),
(9762, 9763, 2),
(9766, 9766, 2),
(9770, 9770, 2),
(9774, 9775, 2),
(9784, 9786, 2),
(9792, 9792, 2),
(9794, 9794, 2),
(9800, 9811, 2), (9800, 9811, 2),
(9823, 9824, 2), (9855, 9855, 2),
(9827, 9827, 2), (9875, 9875, 2),
(9829, 9830, 2), (9889, 9889, 2),
(9832, 9832, 2),
(9851, 9851, 2),
(9854, 9855, 2),
(9874, 9879, 2),
(9881, 9881, 2),
(9883, 9884, 2),
(9888, 9889, 2),
(9898, 9899, 2), (9898, 9899, 2),
(9904, 9905, 2),
(9917, 9918, 2), (9917, 9918, 2),
(9924, 9925, 2), (9924, 9925, 2),
(9928, 9928, 2), (9934, 9934, 2),
(9934, 9935, 2), (9940, 9940, 2),
(9937, 9937, 2), (9962, 9962, 2),
(9939, 9940, 2), (9970, 9971, 2),
(9961, 9962, 2), (9973, 9973, 2),
(9968, 9973, 2), (9978, 9978, 2),
(9975, 9978, 2),
(9981, 9981, 2), (9981, 9981, 2),
(9986, 9986, 2),
(9989, 9989, 2), (9989, 9989, 2),
(9992, 9997, 2), (9994, 9995, 2),
(9999, 9999, 2),
(10002, 10002, 2),
(10004, 10004, 2),
(10006, 10006, 2),
(10013, 10013, 2),
(10017, 10017, 2),
(10024, 10024, 2), (10024, 10024, 2),
(10035, 10036, 2),
(10052, 10052, 2),
(10055, 10055, 2),
(10060, 10060, 2), (10060, 10060, 2),
(10062, 10062, 2), (10062, 10062, 2),
(10067, 10069, 2), (10067, 10069, 2),
(10071, 10071, 2), (10071, 10071, 2),
(10083, 10084, 2),
(10133, 10135, 2), (10133, 10135, 2),
(10145, 10145, 2),
(10160, 10160, 2), (10160, 10160, 2),
(10175, 10175, 2), (10175, 10175, 2),
(10548, 10549, 2),
(11013, 11015, 2),
(11035, 11036, 2), (11035, 11036, 2),
(11088, 11088, 2), (11088, 11088, 2),
(11093, 11093, 2), (11093, 11093, 2),
@ -451,8 +401,6 @@ CELL_WIDTHS = [
(125252, 125258, 0), (125252, 125258, 0),
(126980, 126980, 2), (126980, 126980, 2),
(127183, 127183, 2), (127183, 127183, 2),
(127344, 127345, 2),
(127358, 127359, 2),
(127374, 127374, 2), (127374, 127374, 2),
(127377, 127386, 2), (127377, 127386, 2),
(127488, 127490, 2), (127488, 127490, 2),
@ -460,43 +408,30 @@ CELL_WIDTHS = [
(127552, 127560, 2), (127552, 127560, 2),
(127568, 127569, 2), (127568, 127569, 2),
(127584, 127589, 2), (127584, 127589, 2),
(127744, 127777, 2), (127744, 127776, 2),
(127780, 127891, 2), (127789, 127797, 2),
(127894, 127895, 2), (127799, 127868, 2),
(127897, 127899, 2), (127870, 127891, 2),
(127902, 127984, 2), (127904, 127946, 2),
(127987, 127989, 2), (127951, 127955, 2),
(127991, 128253, 2), (127968, 127984, 2),
(127988, 127988, 2),
(127992, 128062, 2),
(128064, 128064, 2),
(128066, 128252, 2),
(128255, 128317, 2), (128255, 128317, 2),
(128329, 128334, 2), (128331, 128334, 2),
(128336, 128359, 2), (128336, 128359, 2),
(128367, 128368, 2), (128378, 128378, 2),
(128371, 128378, 2),
(128391, 128391, 2),
(128394, 128397, 2),
(128400, 128400, 2),
(128405, 128406, 2), (128405, 128406, 2),
(128420, 128421, 2), (128420, 128420, 2),
(128424, 128424, 2), (128507, 128591, 2),
(128433, 128434, 2),
(128444, 128444, 2),
(128450, 128452, 2),
(128465, 128467, 2),
(128476, 128478, 2),
(128481, 128481, 2),
(128483, 128483, 2),
(128488, 128488, 2),
(128495, 128495, 2),
(128499, 128499, 2),
(128506, 128591, 2),
(128640, 128709, 2), (128640, 128709, 2),
(128715, 128722, 2), (128716, 128716, 2),
(128720, 128722, 2),
(128725, 128727, 2), (128725, 128727, 2),
(128736, 128741, 2),
(128745, 128745, 2),
(128747, 128748, 2), (128747, 128748, 2),
(128752, 128752, 2), (128756, 128764, 2),
(128755, 128764, 2),
(128992, 129003, 2), (128992, 129003, 2),
(129292, 129338, 2), (129292, 129338, 2),
(129340, 129349, 2), (129340, 129349, 2),

View File

@ -1,5 +1,5 @@
import re
from functools import lru_cache from functools import lru_cache
import re
from typing import Dict, List from typing import Dict, List
from ._cell_widths import CELL_WIDTHS from ._cell_widths import CELL_WIDTHS
@ -138,7 +138,6 @@ def chop_cells(text: str, max_size: int, position: int = 0) -> List[str]:
if __name__ == "__main__": # pragma: no cover if __name__ == "__main__": # pragma: no cover
print(get_character_cell_size("🛥"))
print(get_character_cell_size("😽")) print(get_character_cell_size("😽"))
for line in chop_cells("""这是对亚洲语言支持的测试。面对模棱两可的想法,拒绝猜测的诱惑。""", 8): for line in chop_cells("""这是对亚洲语言支持的测试。面对模棱两可的想法,拒绝猜测的诱惑。""", 8):

View File

@ -1,11 +1,11 @@
import sys import sys
from typing import TYPE_CHECKING, Optional, Union from typing import TYPE_CHECKING, Optional, Union
from ._emoji_codes import EMOJI
from ._emoji_replace import _emoji_replace
from .jupyter import JupyterMixin from .jupyter import JupyterMixin
from .segment import Segment from .segment import Segment
from .style import Style from .style import Style
from ._emoji_codes import EMOJI
from ._emoji_replace import _emoji_replace
if sys.version_info >= (3, 8): if sys.version_info >= (3, 8):
from typing import Literal from typing import Literal
@ -86,15 +86,11 @@ if __name__ == "__main__": # pragma: no cover
console = Console(record=True) console = Console(record=True)
data = list(
f":{name}: {name}" for name, value in sorted(EMOJI.items()) if len(value) == 1
)
columns = Columns( columns = Columns(
data, (f":{name}: {name}" for name in sorted(EMOJI.keys()) if "\u200D" not in name),
column_first=True, column_first=True,
) )
console.print(columns) console.print(columns)
console.print(len(data))
if len(sys.argv) > 1: if len(sys.argv) > 1:
console.save_html(sys.argv[1]) console.save_html(sys.argv[1])

View File

@ -1,43 +1,6 @@
from rich import cells from rich import cells
def test_cell_len_empty_string():
assert cells.cell_len("") == 0
def test_cell_len_single_ascii_char():
assert cells.cell_len("a") == 1
def test_cell_len_single_ascii_num():
assert cells.cell_len("5") == 1
def test_cell_len_ascii_string():
assert cells.cell_len("hello") == len("hello")
def test_cell_len_zero_width_character():
assert cells.cell_len("\u0483") == 0
def test_cell_len_single_width_non_ascii_character():
assert cells.cell_len("\u0370") == 1
def test_cell_len_japanese_hiragana():
assert cells.cell_len("こんにちは") == 10
def test_cell_len_poop_emoji_has_width_2():
assert cells.cell_len("💩") == 2
def test_cell_len_emoji_presentation_sequence():
# Handled different from standard emoji - we vary from wcwidth here, which reports width 1.
assert cells.cell_len("🏵️") == 2
def test_set_cell_size(): def test_set_cell_size():
assert cells.set_cell_size("foo", 0) == "" assert cells.set_cell_size("foo", 0) == ""
assert cells.set_cell_size("f", 0) == "" assert cells.set_cell_size("f", 0) == ""

View File

@ -1,355 +0,0 @@
EMOJI_VARIATION_SEQUENCES = {
"",
"🕖",
"",
"🔒",
"",
"",
"🔍",
"",
"",
"🕳",
"🐿",
"",
"🗡",
"🚘",
"🌪",
"",
"",
"🛳",
"📺",
"",
"",
"👆",
"",
"🎧",
"🌡",
"",
"8",
"",
"",
"🗂",
"🏆",
"",
"📥",
"🅰",
"🗓",
"",
"📟",
"🚍",
"🌤",
"",
"7",
"🏊",
"",
"🛥",
"",
"🗞",
"📋",
"🕡",
"",
"",
"🛤",
"",
"",
"1",
"🚼",
"💣",
"🌨",
"",
"🕷",
"",
"",
"©",
"",
"",
"🏞",
"🎛",
"🌦",
"",
"🎓",
"🕣",
"📭",
"",
"👎",
"",
"",
"💳",
"",
"",
"",
"💻",
"",
"",
"6",
"",
"",
"",
"🏄",
"🚺",
"🛰",
"🖍",
"",
"🚭",
"",
"🌏",
"🏘",
"👍",
"🕰",
"📚",
"",
"🕘",
"📽",
"🕵",
"🕓",
"",
"",
"",
"",
"🕙",
"🗺",
"🕔",
"",
"📻",
"",
"",
"",
"",
"🕸",
"🍸",
"🈚",
"🕞",
"🕦",
"",
"🗑",
"",
"📤",
"🛍",
"🎬",
"🕕",
"🌥",
"🎚",
"",
"🛡",
"👪",
"",
"👽",
"",
"",
"",
"",
"🖱",
"🏳",
"👈",
"",
"🏚",
"🎟",
"",
"2",
"",
"",
"",
"🕹",
"🏕",
"👁",
"",
"",
"",
"🈯",
"🎮",
"",
"*",
"🛠",
"🅾",
"",
"🕜",
"🛎",
"",
"",
"",
"🗣",
"",
"",
"",
"4",
"🖊",
"",
"🀄",
"9",
"🖐",
"",
"",
"🖋",
"",
"🚔",
"🅱",
"👉",
"",
"",
"🛩",
"",
"",
"",
"🔈",
"🏷",
"",
"",
"🗝",
"🖥",
"",
"📬",
"🖲",
"🗳",
"🕛",
"🕧",
"",
"🖼",
"",
"🚹",
"#",
"🛋",
"🌧",
"🐦",
"🕊",
"🗄",
"🐟",
"🐕",
"",
"",
"3",
"🌬",
"🏂",
"",
"🏗",
"💿",
"🛏",
"🏵",
"🎙",
"😐",
"",
"",
"",
"🏝",
"🏜",
"📷",
"🗨",
"🖌",
"🚲",
"",
"🕯",
"🎭",
"🚑",
"®",
"",
"",
"🗃",
"",
"🎖",
"🛣",
"🕗",
"👂",
"",
"",
"",
"🚇",
"",
"📦",
"",
"",
"",
"🏠",
"",
"🏭",
"",
"",
"",
"🛢",
"",
"",
"🏛",
"🕒",
"",
"🏖",
"🌜",
"🕶",
"",
"🕟",
"🖇",
"🐈",
"",
"🌩",
"",
"",
"🏟",
"",
"💰",
"",
"🌍",
"",
"",
"",
"",
"👓",
"",
"📹",
"🕴",
"🎞",
"",
"",
"🍽",
"",
"🗜",
"",
"📫",
"🏋",
"",
"🏍",
"",
"",
"🕐",
"🗯",
"🏔",
"🕑",
"🏙",
"",
"📪",
"🅿",
"🌶",
"",
"🔓",
"",
"",
"🕠",
"🕝",
"🈂",
"🕚",
"🗒",
"🈷",
"",
"",
"",
"🕉",
"5",
"",
"",
"🏎",
"🌫",
"🏌",
"",
"",
"🕤",
"",
"🌎",
"🕥",
"🌕",
"",
"0",
"",
"🎗",
"🖨",
"👇",
"",
"🕢",
"",
"",
}

View File

@ -1,12 +1,11 @@
import string
import subprocess import subprocess
import sys
from typing import List, Tuple from typing import List, Tuple
import sys
from rich.progress import Progress
from wcwidth import wcwidth from wcwidth import wcwidth
from rich.progress import Progress
from tools.emoji_variation_sequences import EMOJI_VARIATION_SEQUENCES
progress = Progress() progress = Progress()
@ -17,21 +16,10 @@ def make_widths_table() -> List[Tuple[int, int, int]]:
make_table_task = progress.add_task("Calculating table...") make_table_task = progress.add_task("Calculating table...")
widths = [] widths = (
for codepoint in range(0, sys.maxunicode + 1): (codepoint, wcwidth(chr(codepoint)))
# Emoji presentation sequences behave as though they were East Asian Wide, for codepoint in range(0, sys.maxunicode + 1)
# regardless of their assigned East_Asian_Width property value: )
# http://www.unicode.org/reports/tr41/tr41-26.html#UTS51
# Codepoints representing digits can appear at the start of EPSQs, but they
# are captured by a regex inside Rich which targets the most common codepoint ranges,
# so we don't need them in our lookup table.
if (
chr(codepoint) in EMOJI_VARIATION_SEQUENCES
and chr(codepoint) not in string.digits
):
widths.append((codepoint, 2))
else:
widths.append((codepoint, wcwidth(chr(codepoint))))
_widths = [(codepoint, width) for codepoint, width in widths if width != 1] _widths = [(codepoint, width) for codepoint, width in widths if width != 1]
iter_widths = iter(_widths) iter_widths = iter(_widths)
@ -52,6 +40,7 @@ def make_widths_table() -> List[Tuple[int, int, int]]:
def get_cell_size(table: List[Tuple[int, int, int]], character: str) -> int: def get_cell_size(table: List[Tuple[int, int, int]], character: str) -> int:
codepoint = ord(character) codepoint = ord(character)
lower_bound = 0 lower_bound = 0
upper_bound = len(table) - 1 upper_bound = len(table) - 1
@ -77,11 +66,9 @@ def test(widths_table):
character = chr(codepoint) character = chr(codepoint)
width1 = get_cell_size(widths_table, character) width1 = get_cell_size(widths_table, character)
width2 = wcwidth(character) width2 = wcwidth(character)
if width1 != width2 and character not in EMOJI_VARIATION_SEQUENCES: if width1 != width2:
print(f"{width1} != {width2}") print(f"{width1} != {width2}")
raise Exception( break
f"Width mismatch between Rich and wcwidth for character '{character}'"
)
def run(): def run():