Skip to content

Commit 51da7d1

Browse files
feat: ability to conceal text based on lua patterns
## Details Request: #397 Adds new top level `document` configuration. The main part of this new configuration is a nested `conceal` configuration which contains two fields, `char_patterns` & `line_patterns`. These 2 fields will have their values iterated over the top level `markdown` document node text and any ranges that match the text will be concealed. The difference in behavior is the kind of mark that gets added over the range. - char_patterns: `conceal = ''` characters in the range are hidden but lines rest of line if any is still visible. - line_patterns: `conceal_lines = ''` entire lines are hidden even if match is partial, will unfold when user cursor enters the range, requires neovim `0.11.0` as that is when horizontal conceal was added. This plugin does not do anything clever for the ranges and will at no time support doing anything outside of the bounds of lua patterns. It is entirely up to the user to make good patterns, i.e. using `-` instead of `+/*` for non-greedy matches, capturing the start of line or start of document patterns, and any other specific behavior they want. Any issues opened about how to make a pattern do something or why does some pattern match like this will be auto-closed, lua patterns are well defined and easy to iterate and test with. Providing some examples below: - Hiding words surrounded by `:`, i.e. `:conceal-me:`: ```lua require('render-markdown').setup({ document = { conceal = { char_patterns = { ':%S-:%s' }, }, }, }) ``` - Hiding minus metadata ```lua require('render-markdown').setup({ document = { conceal = { line_patterns = { '^%-%-%-\n.-\n%-%-%-\n', -- start '\n%-%-%-\n.-\n%-%-%-\n', -- middle }, }, }, }) ``` - Hiding plus metadata ```lua require('render-markdown').setup({ document = { conceal = { line_patterns = { '^%+%+%+\n.-\n%+%+%+\n', -- start '\n%+%+%+\n.-\n%+%+%+\n', -- middle }, }, }, }) ```
1 parent 8355c85 commit 51da7d1

File tree

14 files changed

+149
-33
lines changed

14 files changed

+149
-33
lines changed

README.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,10 @@ require('render-markdown').setup({
381381
-- Define custom heading patterns which allow you to override various properties based on
382382
-- the contents of a heading.
383383
-- The key is for healthcheck and to allow users to change its values, value type below.
384-
-- | pattern | matched against the heading text @see :h lua-pattern |
385-
-- | icon | optional override for the icon |
386-
-- | background | optional override for the background |
387-
-- | foreground | optional override for the foreground |
384+
-- | pattern | matched against the heading text @see :h lua-patterns |
385+
-- | icon | optional override for the icon |
386+
-- | background | optional override for the background |
387+
-- | foreground | optional override for the foreground |
388388
custom = {},
389389
},
390390
paragraph = {
@@ -489,6 +489,20 @@ require('render-markdown').setup({
489489
-- Highlight for the whole line generated from the icon.
490490
highlight = 'RenderMarkdownDash',
491491
},
492+
document = {
493+
-- Turn on / off document rendering.
494+
enabled = true,
495+
-- Additional modes to render document.
496+
render_modes = false,
497+
-- Ability to conceal arbitrary ranges of text based on lua patterns, @see :h lua-patterns.
498+
-- Relies entirely on user to set patterns that handle their edge cases.
499+
conceal = {
500+
-- Matched ranges will be concealed using character level conceal.
501+
char_patterns = {},
502+
-- Matched ranges will be concealed using line level conceal.
503+
line_patterns = {},
504+
},
505+
},
492506
-- Useful context to have when evaluating values.
493507
-- | level | how deeply nested the list is, 1-indexed |
494508
-- | index | how far down the item is at that level, 1-indexed |
@@ -702,7 +716,7 @@ require('render-markdown').setup({
702716
-- contains. Applies to 'inline_link', 'uri_autolink', and wikilink nodes. When multiple
703717
-- patterns match a link the one with the longer pattern is used.
704718
-- The key is for healthcheck and to allow users to change its values, value type below.
705-
-- | pattern | matched against the destination text, @see :h lua-pattern |
719+
-- | pattern | matched against the destination text, @see :h lua-patterns |
706720
-- | icon | gets inlined before the link text |
707721
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
708722
custom = {
@@ -914,10 +928,10 @@ require('render-markdown').setup({
914928
-- Define custom heading patterns which allow you to override various properties based on
915929
-- the contents of a heading.
916930
-- The key is for healthcheck and to allow users to change its values, value type below.
917-
-- | pattern | matched against the heading text @see :h lua-pattern |
918-
-- | icon | optional override for the icon |
919-
-- | background | optional override for the background |
920-
-- | foreground | optional override for the foreground |
931+
-- | pattern | matched against the heading text @see :h lua-patterns |
932+
-- | icon | optional override for the icon |
933+
-- | background | optional override for the background |
934+
-- | foreground | optional override for the foreground |
921935
custom = {},
922936
},
923937
})
@@ -1370,7 +1384,7 @@ require('render-markdown').setup({
13701384
-- contains. Applies to 'inline_link', 'uri_autolink', and wikilink nodes. When multiple
13711385
-- patterns match a link the one with the longer pattern is used.
13721386
-- The key is for healthcheck and to allow users to change its values, value type below.
1373-
-- | pattern | matched against the destination text, @see :h lua-pattern |
1387+
-- | pattern | matched against the destination text, @see :h lua-patterns |
13741388
-- | icon | gets inlined before the link text |
13751389
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
13761390
custom = {

doc/render-markdown.txt

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -446,10 +446,10 @@ Default Configuration ~
446446
-- Define custom heading patterns which allow you to override various properties based on
447447
-- the contents of a heading.
448448
-- The key is for healthcheck and to allow users to change its values, value type below.
449-
-- | pattern | matched against the heading text @see :h lua-pattern |
450-
-- | icon | optional override for the icon |
451-
-- | background | optional override for the background |
452-
-- | foreground | optional override for the foreground |
449+
-- | pattern | matched against the heading text @see :h lua-patterns |
450+
-- | icon | optional override for the icon |
451+
-- | background | optional override for the background |
452+
-- | foreground | optional override for the foreground |
453453
custom = {},
454454
},
455455
paragraph = {
@@ -554,6 +554,20 @@ Default Configuration ~
554554
-- Highlight for the whole line generated from the icon.
555555
highlight = 'RenderMarkdownDash',
556556
},
557+
document = {
558+
-- Turn on / off document rendering.
559+
enabled = true,
560+
-- Additional modes to render document.
561+
render_modes = false,
562+
-- Ability to conceal arbitrary ranges of text based on lua patterns, @see :h lua-patterns.
563+
-- Relies entirely on user to set patterns that handle their edge cases.
564+
conceal = {
565+
-- Matched ranges will be concealed using character level conceal.
566+
char_patterns = {},
567+
-- Matched ranges will be concealed using line level conceal.
568+
line_patterns = {},
569+
},
570+
},
557571
-- Useful context to have when evaluating values.
558572
-- | level | how deeply nested the list is, 1-indexed |
559573
-- | index | how far down the item is at that level, 1-indexed |
@@ -767,7 +781,7 @@ Default Configuration ~
767781
-- contains. Applies to 'inline_link', 'uri_autolink', and wikilink nodes. When multiple
768782
-- patterns match a link the one with the longer pattern is used.
769783
-- The key is for healthcheck and to allow users to change its values, value type below.
770-
-- | pattern | matched against the destination text, @see :h lua-pattern |
784+
-- | pattern | matched against the destination text, @see :h lua-patterns |
771785
-- | icon | gets inlined before the link text |
772786
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
773787
custom = {
@@ -977,10 +991,10 @@ Heading Configuration ~
977991
-- Define custom heading patterns which allow you to override various properties based on
978992
-- the contents of a heading.
979993
-- The key is for healthcheck and to allow users to change its values, value type below.
980-
-- | pattern | matched against the heading text @see :h lua-pattern |
981-
-- | icon | optional override for the icon |
982-
-- | background | optional override for the background |
983-
-- | foreground | optional override for the foreground |
994+
-- | pattern | matched against the heading text @see :h lua-patterns |
995+
-- | icon | optional override for the icon |
996+
-- | background | optional override for the background |
997+
-- | foreground | optional override for the foreground |
984998
custom = {},
985999
},
9861000
})
@@ -1415,7 +1429,7 @@ Link Configuration ~
14151429
-- contains. Applies to 'inline_link', 'uri_autolink', and wikilink nodes. When multiple
14161430
-- patterns match a link the one with the longer pattern is used.
14171431
-- The key is for healthcheck and to allow users to change its values, value type below.
1418-
-- | pattern | matched against the destination text, @see :h lua-pattern |
1432+
-- | pattern | matched against the destination text, @see :h lua-patterns |
14191433
-- | icon | gets inlined before the link text |
14201434
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
14211435
custom = {

lua/render-markdown/config.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function Config.validate(spec)
4747
spec:config('checkbox')
4848
spec:config('code')
4949
spec:config('dash')
50+
spec:config('document')
5051
spec:config('heading')
5152
spec:config('html')
5253
spec:config('indent')
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---@class (exact) render.md.document.Config: render.md.base.Config
2+
---@field conceal render.md.document.conceal.Config
3+
4+
---@class (exact) render.md.document.conceal.Config
5+
---@field char_patterns string[]
6+
---@field line_patterns string[]
7+
8+
local M = {}
9+
10+
---@param spec render.md.debug.ValidatorSpec
11+
function M.validate(spec)
12+
require('render-markdown.config.base').validate(spec)
13+
spec:nested('conceal', function(conceal)
14+
conceal:list('char_patterns', 'string')
15+
conceal:list('line_patterns', 'string')
16+
conceal:check()
17+
end)
18+
spec:check()
19+
end
20+
21+
return M

lua/render-markdown/handler/latex.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function M.parse(ctx)
4141
for _ = 1, latex.top_pad do
4242
expressions[#expressions + 1] = ''
4343
end
44-
for _, expression in ipairs(Str.split(raw_expression, '\n')) do
44+
for _, expression in ipairs(Str.split(raw_expression, '\n', true)) do
4545
expressions[#expressions + 1] = Str.pad(node.start_col) .. expression
4646
end
4747
for _ = 1, latex.bottom_pad do

lua/render-markdown/handler/markdown.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ function Handler.new(buf)
2222
self.query = ts.parse(
2323
'markdown',
2424
[[
25+
(document) @document
26+
2527
(section) @section
2628
2729
[
@@ -56,6 +58,7 @@ function Handler.new(buf)
5658
checkbox = require('render-markdown.render.checkbox'),
5759
code = require('render-markdown.render.code'),
5860
dash = require('render-markdown.render.dash'),
61+
document = require('render-markdown.render.document'),
5962
heading = require('render-markdown.render.heading'),
6063
paragraph = require('render-markdown.render.paragraph'),
6164
quote = require('render-markdown.render.quote'),

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.2.11'
8+
M.version = '8.2.12'
99

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

lua/render-markdown/init.lua

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ local M = {}
2828
---@field checkbox render.md.checkbox.Config
2929
---@field code render.md.code.Config
3030
---@field dash render.md.dash.Config
31+
---@field document render.md.document.Config
3132
---@field heading render.md.heading.Config
3233
---@field html render.md.html.Config
3334
---@field indent render.md.indent.Config
@@ -249,10 +250,10 @@ M.default = {
249250
-- Define custom heading patterns which allow you to override various properties based on
250251
-- the contents of a heading.
251252
-- The key is for healthcheck and to allow users to change its values, value type below.
252-
-- | pattern | matched against the heading text @see :h lua-pattern |
253-
-- | icon | optional override for the icon |
254-
-- | background | optional override for the background |
255-
-- | foreground | optional override for the foreground |
253+
-- | pattern | matched against the heading text @see :h lua-patterns |
254+
-- | icon | optional override for the icon |
255+
-- | background | optional override for the background |
256+
-- | foreground | optional override for the foreground |
256257
custom = {},
257258
},
258259
paragraph = {
@@ -357,6 +358,20 @@ M.default = {
357358
-- Highlight for the whole line generated from the icon.
358359
highlight = 'RenderMarkdownDash',
359360
},
361+
document = {
362+
-- Turn on / off document rendering.
363+
enabled = true,
364+
-- Additional modes to render document.
365+
render_modes = false,
366+
-- Ability to conceal arbitrary ranges of text based on lua patterns, @see :h lua-patterns.
367+
-- Relies entirely on user to set patterns that handle their edge cases.
368+
conceal = {
369+
-- Matched ranges will be concealed using character level conceal.
370+
char_patterns = {},
371+
-- Matched ranges will be concealed using line level conceal.
372+
line_patterns = {},
373+
},
374+
},
360375
-- Useful context to have when evaluating values.
361376
-- | level | how deeply nested the list is, 1-indexed |
362377
-- | index | how far down the item is at that level, 1-indexed |
@@ -570,7 +585,7 @@ M.default = {
570585
-- contains. Applies to 'inline_link', 'uri_autolink', and wikilink nodes. When multiple
571586
-- patterns match a link the one with the longer pattern is used.
572587
-- The key is for healthcheck and to allow users to change its values, value type below.
573-
-- | pattern | matched against the destination text, @see :h lua-pattern |
588+
-- | pattern | matched against the destination text, @see :h lua-patterns |
574589
-- | icon | gets inlined before the link text |
575590
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
576591
custom = {

lua/render-markdown/lib/node.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ end
230230
---@param offset integer
231231
---@return integer, integer
232232
function Node:position(index, offset)
233-
local lines = Str.split(self.text:sub(1, index), '\n')
233+
local lines = Str.split(self.text:sub(1, index), '\n', false)
234234
-- start row includes first line
235235
local row = self.start_row + #lines - 1
236236
local col = #lines[#lines] + offset

lua/render-markdown/lib/str.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ local M = {}
33

44
---@param s string
55
---@param sep string
6+
---@param trimempty boolean
67
---@return string[]
7-
function M.split(s, sep)
8-
return vim.split(s, sep, { plain = true, trimempty = true })
8+
function M.split(s, sep, trimempty)
9+
return vim.split(s, sep, { plain = true, trimempty = trimempty })
910
end
1011

1112
---@param s? string
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
local Base = require('render-markdown.render.base')
2+
3+
---@class render.md.render.Document: render.md.Render
4+
---@field private info render.md.document.Config
5+
local Render = setmetatable({}, Base)
6+
Render.__index = Render
7+
8+
---@return boolean
9+
function Render:setup()
10+
self.info = self.config.document
11+
if self.context:skip(self.info) then
12+
return false
13+
end
14+
return true
15+
end
16+
17+
function Render:render()
18+
for _, pattern in ipairs(self.info.conceal.char_patterns) do
19+
for _, range in ipairs(self.node:find(pattern)) do
20+
self.marks:add(true, range[1], range[2], {
21+
end_row = range[3],
22+
end_col = range[4],
23+
conceal = '',
24+
})
25+
end
26+
end
27+
for _, pattern in ipairs(self.info.conceal.line_patterns) do
28+
for _, range in ipairs(self.node:find(pattern)) do
29+
self.marks:add(true, range[1], 0, {
30+
end_row = range[3],
31+
end_col = 0,
32+
conceal_lines = '',
33+
})
34+
end
35+
end
36+
end
37+
38+
return Render

lua/render-markdown/render/shortcut.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ function Render:callout_title(callout)
6363
---Support for overriding title: https://help.obsidian.md/Editing+and+formatting/Callouts#Change+the+title
6464
local content = self.node:parent('inline')
6565
if content ~= nil then
66-
local line = Str.split(content.text, '\n')[1]
66+
local line = Str.split(content.text, '\n', true)[1]
6767
if
6868
#line > #callout.raw
6969
and vim.startswith(line:lower(), callout.raw:lower())
7070
then
71-
local icon = Str.split(callout.rendered, ' ')[1]
71+
local icon = Str.split(callout.rendered, ' ', true)[1]
7272
local title = vim.trim(line:sub(#callout.raw + 1))
7373
return icon .. ' ' .. title, true
7474
end
@@ -96,7 +96,7 @@ function Render:wiki_link()
9696
return
9797
end
9898

99-
local sections = Str.split(self.node.text:sub(2, -2), '|')
99+
local sections = Str.split(self.node.text:sub(2, -2), '|', true)
100100
---@type render.md.link.Context
101101
local ctx = {
102102
buf = self.context.buf,

lua/render-markdown/state.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ function M.default_buffer_config()
116116
checkbox = config.checkbox,
117117
code = config.code,
118118
dash = config.dash,
119+
document = config.document,
119120
heading = config.heading,
120121
html = config.html,
121122
indent = config.indent,

lua/render-markdown/types.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
---@field checkbox? render.md.checkbox.UserConfig
2424
---@field code? render.md.code.UserConfig
2525
---@field dash? render.md.dash.UserConfig
26+
---@field document? render.md.document.UserConfig
2627
---@field heading? render.md.heading.UserConfig
2728
---@field html? render.md.html.UserConfig
2829
---@field indent? render.md.indent.UserConfig
@@ -122,6 +123,13 @@
122123
---@field left_margin? number
123124
---@field highlight? string
124125

126+
---@class (exact) render.md.document.UserConfig: render.md.base.UserConfig
127+
---@field conceal? render.md.document.conceal.UserConfig
128+
129+
---@class (exact) render.md.document.conceal.UserConfig
130+
---@field char_patterns? string[]
131+
---@field line_patterns? string[]
132+
125133
---@class (exact) render.md.heading.UserConfig: render.md.base.UserConfig
126134
---@field atx? boolean
127135
---@field setext? boolean

0 commit comments

Comments
 (0)