Last active
February 21, 2021 12:11
-
-
Save jca02266/9237bde2a154d4357f5fd1847cfc77d1 to your computer and use it in GitHub Desktop.
Detect string width on screen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import unicodedata | |
# https://www.unicode.org/reports/tr11/tr11-14.html | |
EAW_WIDTH = { | |
'F': 2, # Full-width | |
'H': 1, # Half-width | |
'W': 2, # Wide | |
'Na': 1, # Narrow | |
'A': 2, # Ambiguous | |
'N': 1 # Not East Asian (Neutral) | |
} | |
def _letter_width(c): | |
eaw = unicodedata.east_asian_width(c) | |
return EAW_WIDTH[eaw] | |
def string_width(s): | |
width = 0 | |
for c in s: | |
width += _letter_width(c) | |
return width | |
def _padding_width(s, width): | |
w = string_width(s) | |
ret = width - w | |
if ret > 0: | |
return ret | |
else: | |
return 0 | |
def rpad(s, width): | |
w = _padding_width(s, width) | |
return s + " " * w | |
def lpad(s, width): | |
w = _padding_width(s, width) | |
return " " * w + s | |
ljust=rpad | |
rjust=lpad | |
if __name__ == "__main__": | |
import unittest | |
class Test(unittest.TestCase): | |
def test_letter_width(self): | |
self.assertEqual(_letter_width("c"), 1) | |
self.assertEqual(_letter_width("あ"), 2) | |
self.assertEqual(_letter_width("ア"), 1) | |
self.assertEqual(string_width("cあア"), 4) | |
self.assertEqual(_padding_width("cあア", 10), 6) | |
self.assertEqual(_padding_width("cあア", 2), 0) | |
self.assertEqual(rpad("cあア", 10), "cあア ") | |
self.assertEqual(rpad("cあア", 2), "cあア") | |
self.assertEqual(lpad("cあア", 10), " cあア") | |
self.assertEqual(lpad("cあア", 2), "cあア") | |
self.assertEqual(ljust("cあア", 10), "cあア ") | |
self.assertEqual(ljust("cあア", 2), "cあア") | |
self.assertEqual(rjust("cあア", 10), " cあア") | |
self.assertEqual(rjust("cあア", 2), "cあア") | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment