@@ -18,6 +18,39 @@ def __init__(self, text, base=0, padding=0, height=1, width=0):
18
18
assert height == 1
19
19
assert width == 0
20
20
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
+
21
54
def root (self , n = None ):
22
55
"""Produce a nice root symbol.
23
56
Produces ugly results for big n inserts.
@@ -93,7 +126,7 @@ def __init__(self, text, base=0, padding=0, height=1, width=0):
93
126
else :
94
127
lines = [line .replace ("\t " , " " ) for line in lines ]
95
128
96
- self .lines , self .width , self .height , self .base = self ._build_attributes (
129
+ self .lines , self .width , self .height , self .baseline = self ._build_attributes (
97
130
lines , width , height , base
98
131
)
99
132
@@ -257,7 +290,6 @@ def fraction(a: Union[TextBlock, str], b: Union[TextBlock, str]) -> TextBlock:
257
290
if isinstance (b , str ):
258
291
b = TextBlock (b )
259
292
return a / b
260
- return result
261
293
262
294
263
295
def grid (items : list , ** options ) -> TextBlock :
@@ -290,10 +322,10 @@ def grid(items: list, **options) -> TextBlock:
290
322
full_width : int = 0
291
323
for row in items :
292
324
if isinstance (row , TextBlock ):
293
- full_width = max (full_width , row .width )
325
+ full_width = max (full_width , row .width () )
294
326
else :
295
327
for index , item in enumerate (row ):
296
- widths [index ] = max (widths [index ], item .width )
328
+ widths [index ] = max (widths [index ], item .width () )
297
329
298
330
total_width : int = sum (widths ) + max (0 , len (widths ) - 1 ) * 3
299
331
@@ -308,18 +340,18 @@ def grid(items: list, **options) -> TextBlock:
308
340
interline = TextBlock ("+" + "+" .join ((w + 2 ) * "-" for w in widths ) + "+" )
309
341
else :
310
342
interline = TextBlock ((sum (w + 3 for w in widths ) - 2 ) * "-" )
311
- full_width = interline .width - 4
343
+ full_width = interline .width () - 4
312
344
else :
313
345
if col_border :
314
346
interline = (
315
347
TextBlock ("|" )
316
348
+ TextBlock ("|" .join ((w + 2 ) * " " for w in widths ))
317
349
+ TextBlock ("|" )
318
350
)
319
- full_width = max (0 , interline .width - 4 )
351
+ full_width = max (0 , interline .width () - 4 )
320
352
else :
321
353
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 )
323
355
324
356
def normalize_widths (row ):
325
357
if isinstance (row , TextBlock ):
@@ -336,11 +368,20 @@ def normalize_widths(row):
336
368
"|" , height = row_height , base = row_base , left_padding = 1 , right_padding = 1
337
369
)
338
370
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 )
344
385
)
345
386
if i == 0 :
346
387
if row_border :
@@ -351,7 +392,16 @@ def normalize_widths(row):
351
392
result = new_row_txt .stack (result , align = "l" )
352
393
else :
353
394
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 ("" )
355
405
if i == 0 :
356
406
if row_border :
357
407
new_row_txt = new_row_txt .stack (interline , align = "l" )
@@ -363,7 +413,7 @@ def normalize_widths(row):
363
413
if row_border :
364
414
result = interline .stack (result , align = "l" )
365
415
366
- result .base = int (result .height / 2 )
416
+ result .baseline = int (result .height () / 2 )
367
417
return result
368
418
369
419
@@ -507,3 +557,20 @@ def superscript(base: Union[TextBlock, str], a: Union[TextBlock, str]) -> TextBl
507
557
base = TextBlock (* TextBlock .next (base , TextBlock (a_width * " " )))
508
558
result = TextBlock (* TextBlock .above (base , a ))
509
559
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