Skip to content

Commit 8c33733

Browse files
chore(refactor): add line builder module
## Details Moves logic out of base renderer into top level config: - `append` -> new line builder module created from top level config - `line_icon` -> top level config in `link_icon` method
1 parent bffe418 commit 8c33733

File tree

15 files changed

+177
-132
lines changed

15 files changed

+177
-132
lines changed

lua/render-markdown/config.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
local Env = require('render-markdown.lib.env')
2+
local Iter = require('render-markdown.lib.iter')
3+
local Line = require('render-markdown.lib.line')
24
local Range = require('render-markdown.core.range')
35

46
---@class render.md.main.Full
@@ -132,6 +134,11 @@ function Config.validate(spec)
132134
spec:nested('win_options', require('render-markdown.config.win_options').validate)
133135
end
134136

137+
---@return render.md.Line
138+
function Config:line()
139+
return Line.new(self)
140+
end
141+
135142
---@param mode string
136143
---@return boolean
137144
function Config:render(mode)
@@ -150,6 +157,26 @@ function Config:get_checkbox(node)
150157
return self.full.checkbox[node.text:lower()]
151158
end
152159

160+
---@param destination string
161+
---@param icon render.md.mark.Text
162+
function Config:link_text(destination, icon)
163+
local options = Iter.table.filter(self.link.custom, function(custom)
164+
if custom.kind == 'suffix' then
165+
return vim.endswith(destination, custom.pattern)
166+
else
167+
return destination:find(custom.pattern) ~= nil
168+
end
169+
end)
170+
Iter.list.sort(options, function(custom)
171+
return custom.priority or #custom.pattern
172+
end)
173+
local result = options[#options]
174+
if result then
175+
icon[1] = result.icon
176+
icon[2] = result.highlight or icon[2]
177+
end
178+
end
179+
153180
---@param mode string
154181
---@param row? integer
155182
---@return render.md.Range?

lua/render-markdown/health.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local state = require('render-markdown.state')
55
local M = {}
66

77
---@private
8-
M.version = '8.3.21'
8+
M.version = '8.3.22'
99

1010
function M.check()
1111
M.start('version')

lua/render-markdown/lib/line.lua

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---@class render.md.Line
2+
---@field private highlight string
3+
---@field private line render.md.mark.Line
4+
local Line = {}
5+
Line.__index = Line
6+
7+
---@param config render.md.main.Config
8+
---@return render.md.Line
9+
function Line.new(config)
10+
local self = setmetatable({}, Line)
11+
self.highlight = config.padding.highlight
12+
self.line = {}
13+
return self
14+
end
15+
16+
---@return render.md.mark.Line
17+
function Line:get()
18+
return self.line
19+
end
20+
21+
---@return boolean
22+
function Line:empty()
23+
return #self.line == 0
24+
end
25+
26+
---@param other render.md.Line
27+
---@return render.md.Line
28+
function Line:extend(other)
29+
vim.list_extend(self.line, other.line)
30+
return self
31+
end
32+
33+
---@param s string
34+
---@param highlight? string|string[]
35+
---@return render.md.Line
36+
function Line:text(s, highlight)
37+
if #s > 0 then
38+
self:add(s, highlight)
39+
end
40+
return self
41+
end
42+
43+
---@param n integer
44+
---@param highlight? string|string[]
45+
---@return render.md.Line
46+
function Line:pad(n, highlight)
47+
if n > 0 then
48+
self:add((' '):rep(n), highlight)
49+
end
50+
return self
51+
end
52+
53+
---@private
54+
---@param text string
55+
---@param highlight? string|string[]
56+
function Line:add(text, highlight)
57+
self.line[#self.line + 1] = { text, highlight or self.highlight }
58+
end
59+
60+
return Line

lua/render-markdown/lib/marks.lua

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,19 @@ local log = require('render-markdown.core.log')
2626
---@class render.md.Marks
2727
---@field private context render.md.Context
2828
---@field private ignore render.md.conceal.Ignore
29-
---@field private inline boolean
29+
---@field private update boolean
3030
---@field private marks render.md.Mark[]
3131
local Marks = {}
3232
Marks.__index = Marks
3333

3434
---@param context render.md.Context
35-
---@param inline boolean
35+
---@param update boolean
3636
---@return render.md.Marks
37-
function Marks.new(context, inline)
37+
function Marks.new(context, update)
3838
local self = setmetatable({}, Marks)
3939
self.context = context
4040
self.ignore = context.config.anti_conceal.ignore
41-
self.inline = inline
41+
self.update = update
4242
self.marks = {}
4343
return self
4444
end
@@ -93,7 +93,9 @@ function Marks:add(element, start_row, start_col, opts)
9393
return false
9494
end
9595
log.add('debug', 'mark', mark)
96-
self:update(mark)
96+
if self.update then
97+
self:run_update(mark)
98+
end
9799
self.marks[#self.marks + 1] = mark
98100
return true
99101
end
@@ -131,10 +133,7 @@ end
131133

132134
---@private
133135
---@param mark render.md.Mark
134-
function Marks:update(mark)
135-
if not self.inline then
136-
return
137-
end
136+
function Marks:run_update(mark)
138137
local row, start_col = mark.start_row, mark.start_col
139138
if mark.opts.conceal then
140139
local end_col = assert(mark.opts.end_col, 'conceal requires end_col')

lua/render-markdown/render/base.lua

Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
local Iter = require('render-markdown.lib.iter')
21
local Str = require('render-markdown.lib.str')
32
local colors = require('render-markdown.colors')
43

@@ -31,7 +30,7 @@ end
3130
---@param highlight? string
3231
function Base:sign(enabled, text, highlight)
3332
local sign = self.config.sign
34-
if not enabled or not sign.enabled or not text then
33+
if not sign.enabled or not enabled or not text then
3534
return
3635
end
3736
local sign_highlight = sign.highlight
@@ -49,27 +48,26 @@ end
4948
---@param highlight string
5049
---@return boolean
5150
function Base:check_icon(icon, highlight)
52-
local line = self:append({}, icon, highlight)
51+
local line = self.config:line():text(icon, highlight)
5352
local space = self.context:width(self.node) + 1 - Str.width(icon)
5453
local right_pad = self.config.checkbox.right_pad
5554
if space < 0 then
5655
-- not enough space to fit the icon in-place
5756
return self.marks:over('check_icon', self.node, {
58-
virt_text = self:append(line, right_pad),
57+
virt_text = line:pad(right_pad):get(),
5958
virt_text_pos = 'inline',
6059
conceal = '',
6160
}, { 0, 0, 0, 1 })
6261
else
6362
local fits = math.min(space, right_pad)
64-
self:append(line, fits)
6563
space = space - fits
6664
right_pad = right_pad - fits
6765
local row = self.node.start_row
6866
local start_col = self.node.start_col
6967
local end_col = self.node.end_col + 1
7068
self.marks:add('check_icon', row, start_col, {
7169
end_col = end_col - space,
72-
virt_text = line,
70+
virt_text = line:pad(fits):get(),
7371
virt_text_pos = 'overlay',
7472
})
7573
if space > 0 then
@@ -82,7 +80,7 @@ function Base:check_icon(icon, highlight)
8280
if right_pad > 0 then
8381
-- add padding
8482
self.marks:add('check_icon', row, end_col, {
85-
virt_text = self:append({}, right_pad),
83+
virt_text = self.config:line():pad(right_pad):get(),
8684
virt_text_pos = 'inline',
8785
})
8886
end
@@ -101,47 +99,26 @@ function Base:scope(element, node, highlight)
10199
self.marks:over(element, node:child('inline'), { hl_group = highlight })
102100
end
103101

104-
---@protected
105-
---@param destination string
106-
---@param icon render.md.mark.Text
107-
function Base:link_icon(destination, icon)
108-
local options = Iter.table.filter(self.config.link.custom, function(custom)
109-
if custom.kind == 'suffix' then
110-
return vim.endswith(destination, custom.pattern)
111-
else
112-
return destination:find(custom.pattern) ~= nil
113-
end
114-
end)
115-
Iter.list.sort(options, function(custom)
116-
return custom.priority or Str.width(custom.pattern)
117-
end)
118-
local result = options[#options]
119-
if result then
120-
icon[1] = result.icon
121-
icon[2] = result.highlight or icon[2]
122-
end
123-
end
124-
125102
---@protected
126103
---@param virtual boolean
127104
---@param level? integer
128-
---@return render.md.mark.Line
105+
---@return render.md.Line
129106
function Base:indent_line(virtual, level)
130107
if virtual then
131108
level = self:indent_level(level)
132109
else
133110
assert(level, 'level must be known for real lines')
134111
end
135-
local line = {}
112+
local line = self.config:line()
136113
if level > 0 then
137114
local indent = self.config.indent
138115
local icon_width = Str.width(indent.icon)
139116
if icon_width == 0 then
140-
self:append(line, indent.per_level * level)
117+
line:pad(indent.per_level * level)
141118
else
142119
for _ = 1, level do
143-
self:append(line, indent.icon, indent.highlight)
144-
self:append(line, indent.per_level - icon_width)
120+
line:text(indent.icon, indent.highlight)
121+
line:pad(indent.per_level - icon_width)
145122
end
146123
end
147124
end
@@ -177,23 +154,4 @@ function Base:indent_level(level)
177154
return math.max(level - indent.skip_level, 0)
178155
end
179156

180-
---@protected
181-
---@param line render.md.mark.Line
182-
---@param value string|integer
183-
---@param highlight? string|string[]
184-
---@return render.md.mark.Line
185-
function Base:append(line, value, highlight)
186-
highlight = highlight or self.config.padding.highlight
187-
if type(value) == 'string' then
188-
if #value > 0 then
189-
line[#line + 1] = { value, highlight }
190-
end
191-
else
192-
if value > 0 then
193-
line[#line + 1] = { Str.pad(value), highlight }
194-
end
195-
end
196-
return line
197-
end
198-
199157
return Base

lua/render-markdown/render/bullet.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ function Render:padding(root, left_pad, right_pad)
146146
return
147147
end
148148
local start_row, end_row = self.node.start_row, self:end_row(root)
149-
local left_line = self:append({}, left_pad)
150-
local right_line = self:append({}, right_pad)
149+
local left_line = self.config:line():pad(left_pad):get()
150+
local right_line = self.config:line():pad(right_pad):get()
151151
for row = start_row, end_row - 1 do
152152
local left = root and root.start_col or self.node.start_col
153153
local right = row == start_row and self.data.marker.end_col - 1 or left

lua/render-markdown/render/code.lua

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -207,22 +207,23 @@ end
207207
---@param end_row integer
208208
---@param highlight string
209209
function Render:background(start_row, end_row, highlight)
210-
local col, win_col, padding = self.node.start_col, 0, {}
210+
local padding = self.config:line()
211+
local win_col = 0
211212
if self.info.width == 'block' then
213+
padding:pad(vim.o.columns * 2)
212214
win_col = self.data.margin + self.data.width + self.data.indent
213-
self:append(padding, vim.o.columns * 2)
214215
end
215216
for row = start_row, end_row do
216-
self.marks:add('code_background', row, col, {
217+
self.marks:add('code_background', row, self.node.start_col, {
217218
end_row = row + 1,
218219
hl_group = highlight,
219220
hl_eol = true,
220221
})
221-
if win_col > 0 and #padding > 0 then
222-
-- Overwrite anything beyond width with padding highlight
223-
self.marks:add('code_background', row, col, {
222+
if not padding:empty() and win_col > 0 then
223+
-- overwrite anything beyond width with padding
224+
self.marks:add('code_background', row, self.node.start_col, {
224225
priority = 0,
225-
virt_text = padding,
226+
virt_text = padding:get(),
226227
virt_text_win_col = win_col,
227228
})
228229
end
@@ -250,18 +251,18 @@ function Render:padding(background)
250251
local highlight = background and self.info.highlight or nil
251252

252253
for row = start_row, end_row do
253-
local line = {}
254+
local line = self.config:line()
254255
if vim.tbl_contains(empty, row) then
255-
self:append(line, col)
256+
line:pad(col)
256257
end
257-
self:append(line, self.data.margin)
258+
line:pad(self.data.margin)
258259
if row > start_row and row < end_row then
259-
self:append(line, self.data.padding, highlight)
260+
line:pad(self.data.padding, highlight)
260261
end
261-
if #line > 0 then
262+
if not line:empty() then
262263
self.marks:add(false, row, col, {
263264
priority = priority,
264-
virt_text = line,
265+
virt_text = line:get(),
265266
virt_text_pos = 'inline',
266267
})
267268
end

lua/render-markdown/render/code_inline.lua

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,21 @@ end
2929
---@param highlight string
3030
---@param left boolean
3131
function Render:padding(highlight, left)
32-
local line, icon_highlight = {}, colors.bg_as_fg(highlight)
32+
local line = self.config:line()
33+
local icon_highlight = colors.bg_as_fg(highlight)
3334
if left then
34-
self:append(line, self.info.inline_left, icon_highlight)
35-
self:append(line, self.info.inline_pad, highlight)
35+
line:text(self.info.inline_left, icon_highlight)
36+
line:pad(self.info.inline_pad, highlight)
3637
else
37-
self:append(line, self.info.inline_pad, highlight)
38-
self:append(line, self.info.inline_right, icon_highlight)
38+
line:pad(self.info.inline_pad, highlight)
39+
line:text(self.info.inline_right, icon_highlight)
3940
end
40-
if #line > 0 then
41+
if not line:empty() then
4142
local row = left and self.node.start_row or self.node.end_row
4243
local col = left and self.node.start_col or self.node.end_col
4344
self.marks:add(true, row, col, {
4445
priority = 0,
45-
virt_text = line,
46+
virt_text = line:get(),
4647
virt_text_pos = 'inline',
4748
})
4849
end

0 commit comments

Comments
 (0)