Skip to content

Commit 1eb3b74

Browse files
feat: allow callouts to override quote icon
## Details Request: #194 This adds an optional `quote_icon` field for each callout. If provided this value will be used instead of the `quote.icon` value. This means callouts can specify a custom value for the right bar of the quote. Functions very similar to callout highlight except it is always optional. Most changes to make this happen are related to splitting the type for custom checkboxes and custom callouts, which before used the same class. Now there is a different class for callouts and checkboxes which impacted context and config normalization.
1 parent e91b042 commit 1eb3b74

File tree

12 files changed

+101
-60
lines changed

12 files changed

+101
-60
lines changed

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,10 @@ require('render-markdown').setup({
428428
-- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link'
429429
-- Can specify as many additional values as you like following the pattern from any below, such as 'note'
430430
-- The key in this case 'note' is for healthcheck and to allow users to change its values
431-
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
432-
-- 'rendered': Replaces the 'raw' value when rendering
433-
-- 'highlight': Highlight for the 'rendered' text and quote markers
431+
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
432+
-- 'rendered': Replaces the 'raw' value when rendering
433+
-- 'highlight': Highlight for the 'rendered' text and quote markers
434+
-- 'quote_icon': Optional override for quote.icon value for individual callout
434435
callout = {
435436
note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'RenderMarkdownInfo' },
436437
tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'RenderMarkdownSuccess' },
@@ -905,9 +906,10 @@ require('render-markdown').setup({
905906
-- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link'
906907
-- Can specify as many additional values as you like following the pattern from any below, such as 'note'
907908
-- The key in this case 'note' is for healthcheck and to allow users to change its values
908-
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
909-
-- 'rendered': Replaces the 'raw' value when rendering
910-
-- 'highlight': Highlight for the 'rendered' text and quote markers
909+
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
910+
-- 'rendered': Replaces the 'raw' value when rendering
911+
-- 'highlight': Highlight for the 'rendered' text and quote markers
912+
-- 'quote_icon': Optional override for quote.icon value for individual callout
911913
callout = {
912914
note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'RenderMarkdownInfo' },
913915
tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'RenderMarkdownSuccess' },

doc/render-markdown.txt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For 0.10.0 Last change: 2024 September 30
1+
*render-markdown.txt* For 0.10.0 Last change: 2024 October 03
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*
@@ -476,9 +476,10 @@ Default Configuration ~
476476
-- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link'
477477
-- Can specify as many additional values as you like following the pattern from any below, such as 'note'
478478
-- The key in this case 'note' is for healthcheck and to allow users to change its values
479-
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
480-
-- 'rendered': Replaces the 'raw' value when rendering
481-
-- 'highlight': Highlight for the 'rendered' text and quote markers
479+
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
480+
-- 'rendered': Replaces the 'raw' value when rendering
481+
-- 'highlight': Highlight for the 'rendered' text and quote markers
482+
-- 'quote_icon': Optional override for quote.icon value for individual callout
482483
callout = {
483484
note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'RenderMarkdownInfo' },
484485
tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'RenderMarkdownSuccess' },
@@ -937,9 +938,10 @@ Callout Configuration ~
937938
-- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link'
938939
-- Can specify as many additional values as you like following the pattern from any below, such as 'note'
939940
-- The key in this case 'note' is for healthcheck and to allow users to change its values
940-
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
941-
-- 'rendered': Replaces the 'raw' value when rendering
942-
-- 'highlight': Highlight for the 'rendered' text and quote markers
941+
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
942+
-- 'rendered': Replaces the 'raw' value when rendering
943+
-- 'highlight': Highlight for the 'rendered' text and quote markers
944+
-- 'quote_icon': Optional override for quote.icon value for individual callout
943945
callout = {
944946
note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'RenderMarkdownInfo' },
945947
tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'RenderMarkdownSuccess' },

lua/render-markdown/config.lua

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
local Range = require('render-markdown.core.range')
22

33
---@class render.md.component.Config
4-
---@field callout table<string, render.md.CustomComponent>
5-
---@field checkbox table<string, render.md.CustomComponent>
4+
---@field callout table<string, render.md.CustomCallout>
5+
---@field checkbox table<string, render.md.CustomCheckbox>
66

77
---@class render.md.buffer.Config: render.md.BufferConfig
88
---@field component render.md.component.Config
@@ -22,7 +22,9 @@ function Config.new(config)
2222
end
2323

2424
---@private
25-
---@param components table<string, render.md.CustomComponent>
25+
---@generic T: render.md.CustomCallout|render.md.CustomCheckbox
26+
---@param components table<string, T>
27+
---@return table<string, T>
2628
function Config.normalize(components)
2729
local result = {}
2830
for _, component in pairs(components) do

lua/render-markdown/core/context.lua

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ local util = require('render-markdown.core.util')
88
---@field private buf integer
99
---@field private win integer
1010
---@field private ranges render.md.Range[]
11-
---@field private components table<integer, render.md.CustomComponent>
11+
---@field private callouts table<integer, render.md.CustomCallout>
12+
---@field private checkboxes table<integer, render.md.CustomCheckbox>
1213
---@field private conceal? table<integer, [integer, integer][]>
1314
---@field private links table<integer, [integer, integer, integer][]>
1415
---@field private window_width? integer
@@ -33,7 +34,8 @@ function Context.new(buf, win, offset)
3334
end
3435
self.ranges = Range.coalesce(ranges)
3536

36-
self.components = {}
37+
self.callouts = {}
38+
self.checkboxes = {}
3739
self.conceal = nil
3840
self.links = {}
3941
self.window_width = nil
@@ -64,15 +66,27 @@ function Context.compute_range(buf, win, offset)
6466
end
6567

6668
---@param info render.md.NodeInfo
67-
---@return render.md.CustomComponent?
68-
function Context:get_component(info)
69-
return self.components[info.start_row]
69+
---@return render.md.CustomCallout?
70+
function Context:get_callout(info)
71+
return self.callouts[info.start_row]
7072
end
7173

7274
---@param info render.md.NodeInfo
73-
---@param component render.md.CustomComponent
74-
function Context:add_component(info, component)
75-
self.components[info.start_row] = component
75+
---@param callout render.md.CustomCallout
76+
function Context:add_callout(info, callout)
77+
self.callouts[info.start_row] = callout
78+
end
79+
80+
---@param info render.md.NodeInfo
81+
---@return render.md.CustomCheckbox?
82+
function Context:get_checkbox(info)
83+
return self.checkboxes[info.start_row]
84+
end
85+
86+
---@param info render.md.NodeInfo
87+
---@param checkbox render.md.CustomCheckbox
88+
function Context:add_checkbox(info, checkbox)
89+
self.checkboxes[info.start_row] = checkbox
7690
end
7791

7892
---@param info? render.md.NodeInfo

lua/render-markdown/handler/markdown_inline.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ end
9494

9595
---@private
9696
---@param info render.md.NodeInfo
97-
---@param callout render.md.CustomComponent
97+
---@param callout render.md.CustomCallout
9898
function Handler:callout(info, callout)
9999
if not self.config.quote.enabled then
100100
return
@@ -124,13 +124,13 @@ function Handler:callout(info, callout)
124124
conceal = conceal and '' or nil,
125125
})
126126
if added then
127-
self.context:add_component(info, callout)
127+
self.context:add_callout(info, callout)
128128
end
129129
end
130130

131131
---@private
132132
---@param info render.md.NodeInfo
133-
---@param checkbox render.md.CustomComponent
133+
---@param checkbox render.md.CustomCheckbox
134134
function Handler:checkbox(info, checkbox)
135135
if not self.config.checkbox.enabled then
136136
return
@@ -145,7 +145,7 @@ function Handler:checkbox(info, checkbox)
145145
conceal = '',
146146
})
147147
if added then
148-
self.context:add_component(info, checkbox)
148+
self.context:add_checkbox(info, checkbox)
149149
end
150150
end
151151

lua/render-markdown/health.lua

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

66
---@private
7-
M.version = '7.2.9'
7+
M.version = '7.2.10'
88

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

lua/render-markdown/init.lua

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ local M = {}
5151
---@field public highlight? string
5252
---@field public custom? table<string, render.md.UserLinkComponent>
5353

54+
---@class (exact) render.md.UserCustomCallout
55+
---@field public raw? string
56+
---@field public rendered? string
57+
---@field public highlight? string
58+
---@field public quote_icon? string
59+
5460
---@alias render.md.table.Preset 'none'|'round'|'double'|'heavy'
5561
---@alias render.md.table.Style 'full'|'normal'|'none'
5662
---@alias render.md.table.Cell 'trimmed'|'padded'|'raw'|'overlay'
@@ -73,7 +79,7 @@ local M = {}
7379
---@field public repeat_linebreak? boolean
7480
---@field public highlight? string
7581

76-
---@class (exact) render.md.UserCustomComponent
82+
---@class (exact) render.md.UserCustomCheckbox
7783
---@field public raw? string
7884
---@field public rendered? string
7985
---@field public highlight? string
@@ -90,7 +96,7 @@ local M = {}
9096
---@field public position? render.md.checkbox.Position
9197
---@field public unchecked? render.md.UserCheckboxComponent
9298
---@field public checked? render.md.UserCheckboxComponent
93-
---@field public custom? table<string, render.md.UserCustomComponent>
99+
---@field public custom? table<string, render.md.UserCustomCheckbox>
94100

95101
---@class (exact) render.md.UserBullet
96102
---@field public enabled? boolean
@@ -176,7 +182,7 @@ local M = {}
176182
---@field public checkbox? render.md.UserCheckbox
177183
---@field public quote? render.md.UserQuote
178184
---@field public pipe_table? render.md.UserPipeTable
179-
---@field public callout? table<string, render.md.UserCustomComponent>
185+
---@field public callout? table<string, render.md.UserCustomCallout>
180186
---@field public link? render.md.UserLink
181187
---@field public sign? render.md.UserSign
182188
---@field public indent? render.md.UserIndent
@@ -500,9 +506,10 @@ M.default_config = {
500506
-- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link'
501507
-- Can specify as many additional values as you like following the pattern from any below, such as 'note'
502508
-- The key in this case 'note' is for healthcheck and to allow users to change its values
503-
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
504-
-- 'rendered': Replaces the 'raw' value when rendering
505-
-- 'highlight': Highlight for the 'rendered' text and quote markers
509+
-- 'raw': Matched against the raw text of a 'shortcut_link', case insensitive
510+
-- 'rendered': Replaces the 'raw' value when rendering
511+
-- 'highlight': Highlight for the 'rendered' text and quote markers
512+
-- 'quote_icon': Optional override for quote.icon value for individual callout
506513
callout = {
507514
note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'RenderMarkdownInfo' },
508515
tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'RenderMarkdownSuccess' },

lua/render-markdown/render/list_marker.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function Render:sibling_checkbox()
4949
if not self.config.checkbox.enabled then
5050
return false
5151
end
52-
if self.context:get_component(self.info) ~= nil then
52+
if self.context:get_checkbox(self.info) ~= nil then
5353
return true
5454
end
5555
if self.info:sibling('task_list_marker_unchecked') ~= nil then

lua/render-markdown/render/quote.lua

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ local Base = require('render-markdown.render.base')
22
local log = require('render-markdown.core.log')
33
local treesitter = require('render-markdown.core.treesitter')
44

5+
---@class render.md.data.Quote
6+
---@field query vim.treesitter.Query
7+
---@field icon string
8+
---@field highlight string
9+
---@field repeat_linebreak? boolean
10+
511
---@class render.md.render.Quote: render.md.Renderer
6-
---@field private quote render.md.Quote
7-
---@field private query vim.treesitter.Query
8-
---@field private highlight string
12+
---@field private data render.md.data.Quote
913
local Render = setmetatable({}, Base)
1014
Render.__index = Render
1115

@@ -20,29 +24,33 @@ end
2024

2125
---@return boolean
2226
function Render:setup()
23-
self.quote = self.config.quote
24-
if not self.quote.enabled then
27+
local quote = self.config.quote
28+
if not quote.enabled then
2529
return false
2630
end
2731

28-
self.query = treesitter.parse(
29-
'markdown',
30-
[[
31-
[
32-
(block_quote_marker)
33-
(block_continuation)
34-
] @quote_marker
35-
]]
36-
)
32+
local callout = self.context:get_callout(self.info)
3733

38-
local callout = self.context:get_component(self.info)
39-
self.highlight = callout ~= nil and callout.highlight or self.quote.highlight
34+
self.data = {
35+
query = treesitter.parse(
36+
'markdown',
37+
[[
38+
[
39+
(block_quote_marker)
40+
(block_continuation)
41+
] @quote_marker
42+
]]
43+
),
44+
icon = callout ~= nil and callout.quote_icon or quote.icon,
45+
highlight = callout ~= nil and callout.highlight or quote.highlight,
46+
repeat_linebreak = quote.repeat_linebreak or nil,
47+
}
4048

4149
return true
4250
end
4351

4452
function Render:render()
45-
self.context:query(self.info:get_node(), self.query, function(capture, info)
53+
self.context:query(self.info:get_node(), self.data.query, function(capture, info)
4654
if capture == 'quote_marker' then
4755
self:quote_marker(info)
4856
else
@@ -57,9 +65,9 @@ function Render:quote_marker(info)
5765
self.marks:add(true, info.start_row, info.start_col, {
5866
end_row = info.end_row,
5967
end_col = info.end_col,
60-
virt_text = { { info.text:gsub('>', self.quote.icon), self.highlight } },
68+
virt_text = { { info.text:gsub('>', self.data.icon), self.data.highlight } },
6169
virt_text_pos = 'overlay',
62-
virt_text_repeat_linebreak = self.quote.repeat_linebreak or nil,
70+
virt_text_repeat_linebreak = self.data.repeat_linebreak,
6371
})
6472
end
6573

lua/render-markdown/state.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ function M.validate()
210210
:check()
211211

212212
validator:spec(path, config, 'callout', nilable):for_each(function(spec)
213-
spec:type({ 'raw', 'rendered', 'highlight' }, 'string'):check()
213+
spec:type({ 'raw', 'rendered', 'highlight' }, 'string'):type('quote_icon', { 'string', 'nil' }):check()
214214
end)
215215

216216
validator

0 commit comments

Comments
 (0)