@@ -519,93 +519,91 @@ function Handler:pipe_table(info)
519
519
if not pipe_table .enabled or pipe_table .style == ' none' then
520
520
return
521
521
end
522
- local parsed_table = pipe_table_parser .parse (info )
522
+ local parsed_table = pipe_table_parser .parse (self . context , info )
523
523
if parsed_table == nil then
524
524
return
525
525
end
526
526
527
- self :table_row (parsed_table .head , pipe_table .head )
528
- self :table_delimiter (parsed_table .delim , parsed_table .columns )
527
+ self :table_delimiter (parsed_table .delim )
529
528
for _ , row in ipairs (parsed_table .rows ) do
530
- self :table_row (row , pipe_table . row )
529
+ self :table_row (parsed_table . delim , row )
531
530
end
532
531
if pipe_table .style == ' full' then
533
532
self :table_full (parsed_table )
534
533
end
535
534
end
536
535
537
536
--- @private
538
- --- @param row render.md.NodeInfo
539
- --- @param columns render.md.parsed.TableColumn[]
540
- function Handler :table_delimiter (row , columns )
537
+ --- @param delim render.md.parsed.table.DelimRow
538
+ function Handler :table_delimiter (delim )
541
539
local pipe_table = self .config .pipe_table
542
540
local indicator = pipe_table .alignment_indicator
543
541
local border = pipe_table .border
544
- local sections = vim .tbl_map (
545
- --- @param column render.md.parsed.TableColumn
546
- --- @return string
547
- function (column )
548
- -- If column is small there's no good place to put the alignment indicator
549
- -- Alignment indicator must be exactly one character wide
550
- -- We do not put an indicator for default alignment
551
- if column .width < 4 or str .width (indicator ) ~= 1 or column .alignment == ' default' then
552
- return border [11 ]:rep (column .width )
553
- end
554
- -- Handle the various alignmnet possibilities
555
- local left = border [11 ]:rep (math.floor (column .width / 2 ))
556
- local right = border [11 ]:rep (math.ceil (column .width / 2 ) - 1 )
557
- if column .alignment == ' left' then
558
- return indicator .. left .. right
559
- elseif column .alignment == ' right' then
560
- return left .. right .. indicator
561
- else
562
- return left .. indicator .. right
563
- end
564
- end ,
565
- columns
566
- )
542
+ local sections = vim .tbl_map (function (column )
543
+ -- If column is small there's no good place to put the alignment indicator
544
+ -- Alignment indicator must be exactly one character wide
545
+ -- Do not put an indicator for default alignment
546
+ if column .width < 4 or str .width (indicator ) ~= 1 or column .alignment == ' default' then
547
+ return border [11 ]:rep (column .width )
548
+ end
549
+ -- Handle the various alignmnet possibilities
550
+ local left = border [11 ]:rep (math.floor (column .width / 2 ))
551
+ local right = border [11 ]:rep (math.ceil (column .width / 2 ) - 1 )
552
+ if column .alignment == ' left' then
553
+ return indicator .. left .. right
554
+ elseif column .alignment == ' right' then
555
+ return left .. right .. indicator
556
+ else
557
+ return left .. indicator .. right
558
+ end
559
+ end , delim .columns )
567
560
local delimiter = border [4 ] .. table.concat (sections , border [5 ]) .. border [6 ]
568
- self :add (true , row . start_row , row .start_col , {
569
- end_row = row .end_row ,
570
- end_col = row .end_col ,
561
+ self :add (true , delim . info . start_row , delim . info .start_col , {
562
+ end_row = delim . info .end_row ,
563
+ end_col = delim . info .end_col ,
571
564
virt_text = { { delimiter , pipe_table .head } },
572
565
virt_text_pos = ' overlay' ,
573
566
})
574
567
end
575
568
576
569
--- @private
577
- --- @param row render.md.NodeInfo
578
- --- @param highlight string
579
- function Handler :table_row (row , highlight )
570
+ --- @param delim render.md.parsed.table.DelimRow
571
+ --- @param row render.md.parsed.table.Row
572
+ function Handler :table_row (delim , row )
580
573
local pipe_table = self .config .pipe_table
581
- if vim .tbl_contains ({ ' raw' , ' padded' }, pipe_table .cell ) then
582
- row :for_each_child (function (cell )
583
- if cell .type == ' |' then
584
- self :add (true , cell .start_row , cell .start_col , {
585
- end_row = cell .end_row ,
586
- end_col = cell .end_col ,
587
- virt_text = { { pipe_table .border [10 ], highlight } },
588
- virt_text_pos = ' overlay' ,
574
+ local highlight = row .info .type == ' pipe_table_header' and pipe_table .head or pipe_table .row
575
+ if pipe_table .cell == ' padded' then
576
+ for _ , pipe in ipairs (row .pipes ) do
577
+ self :add (true , pipe .start_row , pipe .start_col , {
578
+ end_row = pipe .end_row ,
579
+ end_col = pipe .end_col ,
580
+ virt_text = { { pipe_table .border [10 ], highlight } },
581
+ virt_text_pos = ' overlay' ,
582
+ })
583
+ end
584
+ for i , column in ipairs (row .columns ) do
585
+ local offset = delim .columns [i ].width - column .width
586
+ if offset > 0 then
587
+ self :add (true , column .info .start_row , column .info .end_col - 1 , {
588
+ virt_text = { { str .pad (offset ), pipe_table .filler } },
589
+ virt_text_pos = ' inline' ,
589
590
})
590
- elseif cell .type == ' pipe_table_cell' then
591
- if pipe_table .cell == ' padded' then
592
- local offset = self :table_visual_offset (cell )
593
- if offset > 0 then
594
- self :add (true , cell .start_row , cell .end_col - 1 , {
595
- virt_text = { { str .pad (offset ), pipe_table .filler } },
596
- virt_text_pos = ' inline' ,
597
- })
598
- end
599
- end
600
- else
601
- logger .unhandled_type (' markdown' , ' cell' , cell .type )
602
591
end
603
- end )
592
+ end
593
+ elseif pipe_table .cell == ' raw' then
594
+ for _ , pipe in ipairs (row .pipes ) do
595
+ self :add (true , pipe .start_row , pipe .start_col , {
596
+ end_row = pipe .end_row ,
597
+ end_col = pipe .end_col ,
598
+ virt_text = { { pipe_table .border [10 ], highlight } },
599
+ virt_text_pos = ' overlay' ,
600
+ })
601
+ end
604
602
elseif pipe_table .cell == ' overlay' then
605
- self :add (true , row .start_row , row .start_col , {
606
- end_row = row .end_row ,
607
- end_col = row .end_col ,
608
- virt_text = { { row .text :gsub (' |' , pipe_table .border [10 ]), highlight } },
603
+ self :add (true , row .info . start_row , row . info .start_col , {
604
+ end_row = row .info . end_row ,
605
+ end_col = row .info . end_col ,
606
+ virt_text = { { row .info . text :gsub (' |' , pipe_table .border [10 ]), highlight } },
609
607
virt_text_pos = ' overlay' ,
610
608
})
611
609
end
@@ -617,56 +615,53 @@ function Handler:table_full(parsed_table)
617
615
local pipe_table = self .config .pipe_table
618
616
local border = pipe_table .border
619
617
620
- --- @param info render.md.NodeInfo
621
- --- @return integer
622
- local function width (info )
623
- local result = str .width (info .text )
624
- if pipe_table .cell == ' raw' then
625
- -- For the raw cell style we want the lengths to match after
626
- -- concealing & inlined elements
627
- result = result - self :table_visual_offset (info )
618
+ --- @param row render.md.parsed.table.Row
619
+ --- @param delim render.md.parsed.table.DelimRow
620
+ --- @return boolean
621
+ local function width_equal (row , delim )
622
+ if pipe_table .cell == ' padded' then
623
+ -- Assume table was padded to match
624
+ return true
625
+ elseif pipe_table .cell == ' raw' then
626
+ -- Want the computed widths to match
627
+ for i , column in ipairs (row .columns ) do
628
+ if delim .columns [i ].width ~= column .width then
629
+ return false
630
+ end
631
+ end
632
+ return true
633
+ elseif pipe_table .cell == ' overlay' then
634
+ -- Want the underlying text widths to match
635
+ return str .width (delim .info .text ) == str .width (row .info .text )
636
+ else
637
+ return false
628
638
end
629
- return result
630
639
end
631
640
632
- local first = parsed_table .head
641
+ local delim = parsed_table .delim
642
+ local first = parsed_table .rows [1 ]
633
643
local last = parsed_table .rows [# parsed_table .rows ]
634
-
635
- -- Do not need to account for concealed / inlined text on delimiter row
636
- local delim_width = str .width (parsed_table .delim .text )
637
- if delim_width ~= width (first ) or delim_width ~= width (last ) then
638
- return {}
644
+ if not width_equal (first , delim ) or not width_equal (last , delim ) then
645
+ return
639
646
end
640
647
641
- local sections = vim .tbl_map (
642
- --- @param column render.md.parsed.TableColumn
643
- --- @return string
644
- function (column )
645
- return border [11 ]:rep (column .width )
646
- end ,
647
- parsed_table .columns
648
- )
648
+ local sections = vim .tbl_map (function (column )
649
+ return border [11 ]:rep (column .width )
650
+ end , delim .columns )
649
651
650
652
local line_above = border [1 ] .. table.concat (sections , border [2 ]) .. border [3 ]
651
- self :add (false , first .start_row , first .start_col , {
653
+ self :add (false , first .info . start_row , first . info .start_col , {
652
654
virt_lines_above = true ,
653
655
virt_lines = { { { line_above , pipe_table .head } } },
654
656
})
655
657
656
658
local line_below = border [7 ] .. table.concat (sections , border [8 ]) .. border [9 ]
657
- self :add (false , last .start_row , last .start_col , {
659
+ self :add (false , last .info . start_row , last . info .start_col , {
658
660
virt_lines_above = false ,
659
661
virt_lines = { { { line_below , pipe_table .row } } },
660
662
})
661
663
end
662
664
663
- --- @private
664
- --- @param info render.md.NodeInfo
665
- --- @return integer
666
- function Handler :table_visual_offset (info )
667
- return self .context :concealed (info ) - self .context :link_width (info )
668
- end
669
-
670
665
--- @class render.md.handler.Markdown : render.md.Handler
671
666
local M = {}
672
667
0 commit comments