@@ -18,6 +18,39 @@ def __init__(self, text, base=0, padding=0, height=1, width=0):
1818 assert height == 1
1919 assert width == 0
2020
21+ @staticmethod
22+ def stack (self , * args , align = "c" ):
23+ if align == "c" :
24+ return super .stack (* args )
25+ max_width = max ((block .width () for block in args ))
26+ if align == "l" :
27+ new_args = []
28+ for block in args :
29+ block_width = block .width ()
30+ if block_width == max_width :
31+ new_args .append (block )
32+ else :
33+ fill_block = TextBlock ((max_width - block_width ) * " " )
34+ new_block = TextBlock (* TextBlock .next (block , fill_block ))
35+ new_args .append (new_block )
36+ return super .stack (* args )
37+ else : # align=="r"
38+ new_args = []
39+ for block in args :
40+ block_width = block .width ()
41+ if block_width == max_width :
42+ new_args .append (block )
43+ else :
44+ fill_block = TextBlock ((max_width - block_width ) * " " )
45+ new_block = TextBlock (
46+ * TextBlock .next (
47+ fill_block ,
48+ block ,
49+ )
50+ )
51+ new_args .append (new_block )
52+ return super .stack (* args )
53+
2154 def root (self , n = None ):
2255 """Produce a nice root symbol.
2356 Produces ugly results for big n inserts.
@@ -93,7 +126,7 @@ def __init__(self, text, base=0, padding=0, height=1, width=0):
93126 else :
94127 lines = [line .replace ("\t " , " " ) for line in lines ]
95128
96- self .lines , self .width , self .height , self .base = self ._build_attributes (
129+ self .lines , self .width , self .height , self .baseline = self ._build_attributes (
97130 lines , width , height , base
98131 )
99132
@@ -257,7 +290,6 @@ def fraction(a: Union[TextBlock, str], b: Union[TextBlock, str]) -> TextBlock:
257290 if isinstance (b , str ):
258291 b = TextBlock (b )
259292 return a / b
260- return result
261293
262294
263295def grid (items : list , ** options ) -> TextBlock :
@@ -290,10 +322,10 @@ def grid(items: list, **options) -> TextBlock:
290322 full_width : int = 0
291323 for row in items :
292324 if isinstance (row , TextBlock ):
293- full_width = max (full_width , row .width )
325+ full_width = max (full_width , row .width () )
294326 else :
295327 for index , item in enumerate (row ):
296- widths [index ] = max (widths [index ], item .width )
328+ widths [index ] = max (widths [index ], item .width () )
297329
298330 total_width : int = sum (widths ) + max (0 , len (widths ) - 1 ) * 3
299331
@@ -308,18 +340,18 @@ def grid(items: list, **options) -> TextBlock:
308340 interline = TextBlock ("+" + "+" .join ((w + 2 ) * "-" for w in widths ) + "+" )
309341 else :
310342 interline = TextBlock ((sum (w + 3 for w in widths ) - 2 ) * "-" )
311- full_width = interline .width - 4
343+ full_width = interline .width () - 4
312344 else :
313345 if col_border :
314346 interline = (
315347 TextBlock ("|" )
316348 + TextBlock ("|" .join ((w + 2 ) * " " for w in widths ))
317349 + TextBlock ("|" )
318350 )
319- full_width = max (0 , interline .width - 4 )
351+ full_width = max (0 , interline .width () - 4 )
320352 else :
321353 interline = TextBlock ((sum (w + 3 for w in widths ) - 3 ) * " " )
322- full_width = max (0 , interline .width - 4 )
354+ full_width = max (0 , interline .width () - 4 )
323355
324356 def normalize_widths (row ):
325357 if isinstance (row , TextBlock ):
@@ -336,11 +368,20 @@ def normalize_widths(row):
336368 "|" , height = row_height , base = row_base , left_padding = 1 , right_padding = 1
337369 )
338370
339- new_row_txt = col_sep .join (row )
340- new_row_txt = (
341- draw_vertical ("|" , row_height , base = row_base , right_padding = 1 )
342- + new_row_txt
343- + draw_vertical ("|" , row_height , base = row_base , left_padding = 1 )
371+ if row :
372+ field , * rest_row_txt = row
373+ new_row_txt = field
374+ for field in rest_row_txt :
375+ new_row_txt = TextBlock (
376+ * TextBlock .next (new_row_txt , col_sep , field )
377+ )
378+ else :
379+ new_row_txt = TextBlock ("" )
380+ vertical_line = draw_vertical (
381+ "|" , row_height , base = row_base , left_padding = 1
382+ )
383+ new_row_txt = TextBlock (
384+ * TextBlock .next (vertical_line , new_row_txt , vertical_line )
344385 )
345386 if i == 0 :
346387 if row_border :
@@ -351,7 +392,16 @@ def normalize_widths(row):
351392 result = new_row_txt .stack (result , align = "l" )
352393 else :
353394 for i , row in enumerate (items ):
354- new_row_txt = TextBlock (" " ).join (row )
395+ separator = TextBlock (" " )
396+ if row :
397+ field , * rest = row
398+ new_row_txt = field
399+ for field in rest :
400+ new_row_txt = TextBlock (
401+ * TextBlock .next (new_row_txt , separator , field )
402+ )
403+ else :
404+ new_row_txt = TextBlock ("" )
355405 if i == 0 :
356406 if row_border :
357407 new_row_txt = new_row_txt .stack (interline , align = "l" )
@@ -363,7 +413,7 @@ def normalize_widths(row):
363413 if row_border :
364414 result = interline .stack (result , align = "l" )
365415
366- result .base = int (result .height / 2 )
416+ result .baseline = int (result .height () / 2 )
367417 return result
368418
369419
@@ -507,3 +557,20 @@ def superscript(base: Union[TextBlock, str], a: Union[TextBlock, str]) -> TextBl
507557 base = TextBlock (* TextBlock .next (base , TextBlock (a_width * " " )))
508558 result = TextBlock (* TextBlock .above (base , a ))
509559 return result
560+
561+
562+ def join_blocks (* blocks ) -> TextBlock :
563+ """
564+ Concatenate blocks.
565+ The same that the idiom
566+ TextBlock(*TextBlock.next(*blocks))
567+ """
568+ return TextBlock (* TextBlock .next (* blocks ))
569+
570+
571+ TEXTBLOCK_COMMA = TextBlock ("," )
572+ TEXTBLOCK_MINUS = TextBlock ("-" )
573+ TEXTBLOCK_NULL = TextBlock ("" )
574+ TEXTBLOCK_PLUS = TextBlock ("+" )
575+ TEXTBLOCK_QUOTE = TextBlock ("'" )
576+ TEXTBLOCK_SPACE = TextBlock (" " )
0 commit comments