Skip to content

Commit 770f7a1

Browse files
Add support for code blocks in callouts / quotes
# Details The current logic for finding quote markers in a block quote relies on several tree-sitter queries that do not handle different element types well, an example of this is code blocks. To fix this rather than having a top level query which pulls quote marker nodes use 2 separate queries. This first gets the block_quote, the second runs on the block_quote node and gets all continuations, regardless of how they are nested. This does to a certain extent allow arbitrary nesting, however the highlights chosen for nested callouts do not look great, but it does work, so that's cool. Other minor changes: - README order - Add checkhealth field to bug report template - Store callouts as a list so order is consistent
1 parent 069768d commit 770f7a1

File tree

14 files changed

+166
-105
lines changed

14 files changed

+166
-105
lines changed

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ labels: [bug]
55
body:
66
- type: input
77
attributes:
8-
label: "Neovim version (nvim -v)"
9-
placeholder: "0.9.5"
8+
label: Neovim version (nvim -v)
9+
placeholder: 0.9.5
1010
validations:
1111
required: true
1212
- type: input
1313
attributes:
14-
label: "Operating system"
15-
placeholder: "MacOS"
14+
label: Operating system
15+
placeholder: MacOS
1616
validations:
1717
required: true
1818
- type: input
1919
attributes:
20-
label: "Terminal emulator / GUI"
21-
placeholder: "WezTerm"
20+
label: Terminal emulator / GUI
21+
placeholder: WezTerm
2222
validations:
2323
required: true
2424
- type: textarea
@@ -32,7 +32,12 @@ body:
3232
label: Expected behavior
3333
description: A description of what you expected to happen.
3434
validations:
35-
required: true
35+
required: true
36+
- type: textarea
37+
attributes:
38+
label: Healthcheck output (:checkhealth render-markdown)
39+
validations:
40+
required: true
3641
- type: textarea
3742
attributes:
3843
label: Additional information

README.md

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ use({
7575
})
7676
```
7777

78+
# Commands
79+
80+
`:RenderMarkdownToggle` - Switch between enabling & disabling this plugin
81+
82+
- Function can also be accessed directly through `require('render-markdown').toggle()`
83+
7884
# Setup
7985

8086
Below is the configuration that gets used by default, any part of it can be modified
@@ -114,16 +120,20 @@ require('render-markdown').setup({
114120
(task_list_marker_unchecked) @checkbox_unchecked
115121
(task_list_marker_checked) @checkbox_checked
116122
117-
(block_quote (block_quote_marker) @quote_marker)
118-
(block_quote (block_continuation) @quote_marker)
119-
(block_quote (paragraph (block_continuation) @quote_marker))
120-
(block_quote (paragraph (inline (block_continuation) @quote_marker)))
123+
(block_quote) @quote
121124
122125
(pipe_table) @table
123126
(pipe_table_header) @table_head
124127
(pipe_table_delimiter_row) @table_delim
125128
(pipe_table_row) @table_row
126129
]],
130+
-- Capture groups that get pulled from quote nodes
131+
markdown_quote_query = [[
132+
[
133+
(block_quote_marker)
134+
(block_continuation)
135+
] @quote_marker
136+
]],
127137
-- Capture groups that get pulled from inline markdown
128138
inline_query = [[
129139
(code_span) @code
@@ -245,31 +255,6 @@ require('render-markdown').setup({
245255
})
246256
```
247257

248-
# Commands
249-
250-
`:RenderMarkdownToggle` - Switch between enabling & disabling this plugin
251-
252-
- Function can also be accessed directly through `require('render-markdown').toggle()`
253-
254-
# Note to `vimwiki` Users
255-
256-
If you use [vimwiki](https://github.com/vimwiki/vimwiki), because it overrides the
257-
`filetype` of `markdown` files there are additional setup steps.
258-
259-
- Add `vimwiki` to the `file_types` configuration of this plugin
260-
261-
```lua
262-
require('render-markdown').setup({
263-
file_types = { 'markdown', 'vimwiki' },
264-
})
265-
```
266-
267-
- Register `markdown` as the parser for `vimwiki` files
268-
269-
```lua
270-
vim.treesitter.language.register('markdown', 'vimwiki')
271-
```
272-
273258
# Additional Info
274259

275260
- [Limitations](doc/limitations.md): Known limitations of this plugin
@@ -279,3 +264,22 @@ vim.treesitter.language.register('markdown', 'vimwiki')
279264
- [Purpose](doc/purpose.md): Why this plugin exists
280265
- [Markdown Ecosystem](doc/markdown-ecosystem.md): Information about other `markdown`
281266
related plugins and how they co-exist
267+
268+
> [!NOTE]
269+
>
270+
> If you use [vimwiki](https://github.com/vimwiki/vimwiki), because it overrides
271+
> the `filetype` of `markdown` files there are additional setup steps.
272+
>
273+
> - Add `vimwiki` to the `file_types` configuration of this plugin
274+
>
275+
> ```lua
276+
> require('render-markdown').setup({
277+
> file_types = { 'markdown', 'vimwiki' },
278+
> })
279+
> ```
280+
>
281+
> - Register `markdown` as the parser for `vimwiki` files
282+
>
283+
> ```lua
284+
> vim.treesitter.language.register('markdown', 'vimwiki')
285+
> ```

demo/callout.gif

14.7 KB
Loading

demo/callout.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
# Tip
1010

1111
> [!TIP]
12-
> Standard tip
12+
>
13+
> ```lua
14+
> print('Standard tip')
15+
> ```
1316
1417
# Important
1518

doc/render-markdown.txt

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For 0.10.0 Last change: 2024 July 01
1+
*render-markdown.txt* For 0.10.0 Last change: 2024 July 05
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*
@@ -9,10 +9,9 @@ Table of Contents *render-markdown-table-of-contents*
99
4. Install |render-markdown-install|
1010
- lazy.nvim |render-markdown-install-lazy.nvim|
1111
- packer.nvim |render-markdown-install-packer.nvim|
12-
5. Setup |render-markdown-setup|
13-
6. Commands |render-markdown-commands|
14-
7. Note to vimwiki Users |render-markdown-note-to-vimwiki-users|
15-
8. Additional Info |render-markdown-additional-info|
12+
5. Commands |render-markdown-commands|
13+
6. Setup |render-markdown-setup|
14+
7. Additional Info |render-markdown-additional-info|
1615

1716
==============================================================================
1817
1. markdown.nvim *render-markdown-markdown.nvim*
@@ -103,7 +102,15 @@ PACKER.NVIM *render-markdown-install-packer.nvim*
103102

104103

105104
==============================================================================
106-
5. Setup *render-markdown-setup*
105+
5. Commands *render-markdown-commands*
106+
107+
`:RenderMarkdownToggle` - Switch between enabling & disabling this plugin
108+
109+
- Function can also be accessed directly through `require('render-markdown').toggle()`
110+
111+
112+
==============================================================================
113+
6. Setup *render-markdown-setup*
107114

108115
Below is the configuration that gets used by default, any part of it can be
109116
modified by the user.
@@ -142,16 +149,20 @@ modified by the user.
142149
(task_list_marker_unchecked) @checkbox_unchecked
143150
(task_list_marker_checked) @checkbox_checked
144151

145-
(block_quote (block_quote_marker) @quote_marker)
146-
(block_quote (block_continuation) @quote_marker)
147-
(block_quote (paragraph (block_continuation) @quote_marker))
148-
(block_quote (paragraph (inline (block_continuation) @quote_marker)))
152+
(block_quote) @quote
149153

150154
(pipe_table) @table
151155
(pipe_table_header) @table_head
152156
(pipe_table_delimiter_row) @table_delim
153157
(pipe_table_row) @table_row
154158
]],
159+
-- Capture groups that get pulled from quote nodes
160+
markdown_quote_query = [[
161+
[
162+
(block_quote_marker)
163+
(block_continuation)
164+
] @quote_marker
165+
]],
155166
-- Capture groups that get pulled from inline markdown
156167
inline_query = [[
157168
(code_span) @code
@@ -275,36 +286,7 @@ modified by the user.
275286

276287

277288
==============================================================================
278-
6. Commands *render-markdown-commands*
279-
280-
`:RenderMarkdownToggle` - Switch between enabling & disabling this plugin
281-
282-
- Function can also be accessed directly through `require('render-markdown').toggle()`
283-
284-
285-
==============================================================================
286-
7. Note to vimwiki Users *render-markdown-note-to-vimwiki-users*
287-
288-
If you use vimwiki <https://github.com/vimwiki/vimwiki>, because it overrides
289-
the `filetype` of `markdown` files there are additional setup steps.
290-
291-
- Add `vimwiki` to the `file_types` configuration of this plugin
292-
293-
>lua
294-
require('render-markdown').setup({
295-
file_types = { 'markdown', 'vimwiki' },
296-
})
297-
<
298-
299-
- Register `markdown` as the parser for `vimwiki` files
300-
301-
>lua
302-
vim.treesitter.language.register('markdown', 'vimwiki')
303-
<
304-
305-
306-
==============================================================================
307-
8. Additional Info *render-markdown-additional-info*
289+
7. Additional Info *render-markdown-additional-info*
308290

309291
- Limitations <doc/limitations.md>: Known limitations of this plugin
310292
- Custom Handlers <doc/custom-handlers.md>: Allow users to integrate custom rendering
@@ -314,6 +296,21 @@ the `filetype` of `markdown` files there are additional setup steps.
314296
- Markdown Ecosystem <doc/markdown-ecosystem.md>: Information about other `markdown`
315297
related plugins and how they co-exist
316298

299+
300+
[!NOTE]
301+
If you use vimwiki <https://github.com/vimwiki/vimwiki>, because it overrides
302+
the `filetype` of `markdown` files there are additional setup steps.
303+
- Add `vimwiki` to the `file_types` configuration of this plugin
304+
>lua
305+
require('render-markdown').setup({
306+
file_types = { 'markdown', 'vimwiki' },
307+
})
308+
<
309+
- Register `markdown` as the parser for `vimwiki` files
310+
>lua
311+
vim.treesitter.language.register('markdown', 'vimwiki')
312+
<
313+
317314
Generated by panvimdoc <https://github.com/kdheepak/panvimdoc>
318315

319316
vim:tw=78:ts=8:noet:ft=help:norl:

justfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ demo-latex:
2222
just demo "latex" "15" ""
2323

2424
demo-callout:
25-
just demo "callout" "30" ""
25+
just demo "callout" "35" ""
2626

2727
demo file rows content:
2828
rm -f demo/{{file}}.gif

lua/render-markdown/callout.lua

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,35 @@
1-
local callout_to_key = {
2-
['[!NOTE]'] = 'note',
3-
['[!TIP]'] = 'tip',
4-
['[!IMPORTANT]'] = 'important',
5-
['[!WARNING]'] = 'warning',
6-
['[!CAUTION]'] = 'caution',
1+
---@class render.md.CalloutInfo
2+
---@field text string
3+
---@field key string
4+
5+
---@type render.md.CalloutInfo[]
6+
local callouts = {
7+
{ text = '[!NOTE]', key = 'note' },
8+
{ text = '[!TIP]', key = 'tip' },
9+
{ text = '[!IMPORTANT]', key = 'important' },
10+
{ text = '[!WARNING]', key = 'warning' },
11+
{ text = '[!CAUTION]', key = 'caution' },
712
}
813

914
local M = {}
1015

1116
---@param value string
1217
---@return string?
1318
M.get_key_exact = function(value)
14-
return callout_to_key[value]
19+
for _, callout in ipairs(callouts) do
20+
if value == callout.text then
21+
return callout.key
22+
end
23+
end
24+
return nil
1525
end
1626

1727
---@param value string
1828
---@return string?
1929
M.get_key_contains = function(value)
20-
for callout, key in pairs(callout_to_key) do
21-
if value:find(callout, 1, true) then
22-
return key
30+
for _, callout in ipairs(callouts) do
31+
if value:find(callout.text, 1, true) then
32+
return callout.key
2333
end
2434
end
2535
return nil

lua/render-markdown/handler/latex.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ M.render = function(namespace, root, buf)
2222
if vim.fn.executable(converter) ~= 1 then
2323
logger.debug('Executable not found: ' .. converter)
2424
else
25-
logger.debug_node('latex', root, buf)
2625
M.render_node(namespace, buf, root, converter)
2726
end
2827
end
@@ -35,6 +34,7 @@ M.render_node = function(namespace, buf, node, converter)
3534
local highlights = state.config.highlights
3635
local value = vim.treesitter.get_node_text(node, buf)
3736
local start_row, start_col, end_row, end_col = node:range()
37+
logger.debug_node('latex', node, buf)
3838

3939
local expressions = cache.expressions[value]
4040
if expressions == nil then

lua/render-markdown/handler/markdown.lua

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ local M = {}
1212
---@param root TSNode
1313
---@param buf integer
1414
M.render = function(namespace, root, buf)
15-
for id, node in state.markdown_query:iter_captures(root, buf) do
16-
local capture = state.markdown_query.captures[id]
17-
logger.debug_node(capture, node, buf)
18-
M.render_node(namespace, buf, capture, node)
15+
local query = state.markdown_query
16+
for id, node in query:iter_captures(root, buf) do
17+
M.render_node(namespace, buf, query.captures[id], node)
1918
end
2019
end
2120

@@ -27,6 +26,7 @@ M.render_node = function(namespace, buf, capture, node)
2726
local highlights = state.config.highlights
2827
local value = vim.treesitter.get_node_text(node, buf)
2928
local start_row, start_col, end_row, end_col = node:range()
29+
logger.debug_node(capture, node, buf)
3030

3131
if capture == 'heading' then
3232
local level = vim.fn.strdisplaywidth(value)
@@ -109,6 +109,11 @@ M.render_node = function(namespace, buf, capture, node)
109109
virt_text_pos = 'overlay',
110110
})
111111
end
112+
elseif capture == 'quote' then
113+
local query = state.markdown_quote_query
114+
for id, nested_node in query:iter_captures(node, buf) do
115+
M.render_node(namespace, buf, query.captures[id], nested_node)
116+
end
112117
elseif capture == 'quote_marker' then
113118
local highlight = highlights.quote
114119
local quote = ts.parent_in_section(node, 'block_quote')

lua/render-markdown/handler/markdown_inline.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ local M = {}
88
---@param root TSNode
99
---@param buf integer
1010
M.render = function(namespace, root, buf)
11-
for id, node in state.inline_query:iter_captures(root, buf) do
12-
local capture = state.inline_query.captures[id]
13-
logger.debug_node(capture, node, buf)
14-
M.render_node(namespace, buf, capture, node)
11+
local query = state.inline_query
12+
for id, node in query:iter_captures(root, buf) do
13+
M.render_node(namespace, buf, query.captures[id], node)
1514
end
1615
end
1716

@@ -23,6 +22,7 @@ M.render_node = function(namespace, buf, capture, node)
2322
local highlights = state.config.highlights
2423
local value = vim.treesitter.get_node_text(node, buf)
2524
local start_row, start_col, end_row, end_col = node:range()
25+
logger.debug_node(capture, node, buf)
2626

2727
if capture == 'code' then
2828
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {

0 commit comments

Comments
 (0)