text_wrapper.py
Go to the documentation of this file.
1 import sys
2 
3 from itertools import groupby
4 import textwrap
5 import unicodedata
6 
7 
8 # these codes are copied and modified from sphinx
9 # https://github.com/sphinx-doc/sphinx/commit/00fa1b2505adbaec66496ec20fa5952da976496d
10 def column_width(text):
11  east_asian_widths = {
12  'W': 2, # Wide
13  'F': 2, # Full-width (wide)
14  'Na': 1, # Narrow
15  'H': 1, # Half-width (narrow)
16  'N': 1, # Neutral (not East Asian, treated as narrow)
17  'A': 1 # Ambiguous (s/b wide in East Asian context
18  }
19  if isinstance(text, str) and sys.version_info < (3, 0):
20  return len(text)
21  combining_correction = sum([-1 for c in text
22  if unicodedata.combining(c)])
23  try:
24  width = sum([east_asian_widths[unicodedata.east_asian_width(c)]
25  for c in text])
26  except AttributeError: # east_asian_width() New in version 2.4.
27  width = len(text)
28  return width + combining_correction
29 
30 
31 class TextWrapper(textwrap.TextWrapper):
32 
33  def _wrap_chunks(self, chunks):
34  """_wrap_chunks(chunks : [string]) -> [string]
35 
36  Original _wrap_chunks use len() to calculate width.
37  This method respect to wide/fullwidth characters for width adjustment.
38  """
39  lines = []
40  if self.width <= 0:
41  raise ValueError("invalid width %r (must be > 0)" % self.width)
42 
43  chunks.reverse()
44 
45  while chunks:
46  cur_line = []
47  cur_len = 0
48 
49  if lines:
50  indent = self.subsequent_indent
51  else:
52  indent = self.initial_indent
53 
54  width = self.width - column_width(indent)
55 
56  if self.drop_whitespace and chunks[-1].strip() == '' and lines:
57  del chunks[-1]
58 
59  while chunks:
60  c_l = column_width(chunks[-1])
61 
62  if cur_len + c_l <= width:
63  cur_line.append(chunks.pop())
64  cur_len += c_l
65 
66  else:
67  break
68 
69  if chunks and column_width(chunks[-1]) > width:
70  self._handle_long_word(chunks, cur_line, cur_len, width)
71 
72  if (self.drop_whitespace and cur_line
73  and cur_line[-1].strip() == ''):
74  del cur_line[-1]
75 
76  if cur_line:
77  lines.append(indent + ''.join(cur_line))
78 
79  return lines
80 
81  def _break_word(self, word, space_left):
82  """_break_word(word : string, space_left : int) -> (string, string)
83 
84  Break line by unicode width instead of len(word).
85  """
86  total = 0
87  for i, c in enumerate(word):
88  total += column_width(c)
89  if total > space_left:
90  return word[:i-1], word[i-1:]
91  return word, ''
92 
93  def _split(self, text):
94  """_split(text : string) -> [string]
95 
96  Override original method that only split by 'wordsep_re'.
97  This '_split' split wide-characters into chunk by one character.
98  """
99  split = lambda t: textwrap.TextWrapper._split(self, t)
100  chunks = []
101  for chunk in split(text):
102  for w, g in groupby(chunk, column_width):
103  if w == 1:
104  chunks.extend(split(''.join(g)))
105  else:
106  chunks.extend(list(g))
107  return chunks
108 
109  def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
110  """_handle_long_word(chunks : [string], cur_line : [string], cur_len : int, width : int)
111 
112  Override original method for using self._break_word() instead of slice.
113  """
114  space_left = max(width - cur_len, 1)
115  if self.break_long_words:
116  l, r = self._break_word(reversed_chunks[-1], space_left)
117  cur_line.append(l)
118  reversed_chunks[-1] = r
119 
120  elif not cur_line:
121  cur_line.append(reversed_chunks.pop())
smach_viewer.text_wrapper.TextWrapper._split
def _split(self, text)
Definition: text_wrapper.py:93
smach_viewer.text_wrapper.TextWrapper._handle_long_word
def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width)
Definition: text_wrapper.py:109
smach_viewer.text_wrapper.column_width
def column_width(text)
Definition: text_wrapper.py:10
smach_viewer.text_wrapper.TextWrapper._break_word
def _break_word(self, word, space_left)
Definition: text_wrapper.py:81
smach_viewer.text_wrapper.TextWrapper
Definition: text_wrapper.py:31
smach_viewer.text_wrapper.TextWrapper._wrap_chunks
def _wrap_chunks(self, chunks)
Definition: text_wrapper.py:33


smach_viewer
Author(s): Jonathan Bohren
autogenerated on Thu Feb 20 2025 03:09:09