Skip to content

Instantly share code, notes, and snippets.

@jca02266
Last active February 21, 2021 12:11
Show Gist options
  • Save jca02266/9237bde2a154d4357f5fd1847cfc77d1 to your computer and use it in GitHub Desktop.
Save jca02266/9237bde2a154d4357f5fd1847cfc77d1 to your computer and use it in GitHub Desktop.
Detect string width on screen
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