Skip to content

Commit

Permalink
Refactor! Likely to break all configs, group properties by component
Browse files Browse the repository at this point in the history
## Details

This is a massive breaking change that modifies nearly every
configuration parameter.

Give the amount of changes if you would rather punt dealing with this
for now feel free to use the 'v3.3.1' git tag which will keep you at
the previous commit.

For example with lazy.nvim:

```lua
{
    'MeanderingProgrammer/markdown.nvim',
    tag = 'v3.3.1',
    ...
}
```

Most configs will likely still work, in that the plugin will not
break, but it will essentially ignore all user settings. There are
known settings that if set previously will break the plugin:

- `dash`
- `checkbox.unchecked`
- `checkbox.checked`
- `quote`

The idea of this change is rather than scattering properties for
say 'headings' through the top level 'headings' parameter and a
separate 'highlights.headings' parameter, we instead create a top
level 'heading' parameter that stores icons and highlights. This
should make the problem of what to modify easier as well as allow
individual components to evolve more easily.

List of all changes and how to fix them split by section below.

### Base

- `start_enabled` -> `enabled`

### Latex

- `latex_enabled` -> `latex.enabled`
- `latex_converter` -> `latex.converter`
- `highlights.latex` -> `latex.highlight`

### Headings

- `headings` -> `heading.icons`
- `highlights.heading.backgrounds` -> `heading.backgrounds`
- `highlights.heading.foregrounds` -> `heading.foregrounds`

### Code

- `code_style` -> `code.style`
- `highlights.code` -> `code.highlight`

### Dash

- `dash` -> `dash.icon`
- `highlights.dash` -> `dash.highlight`

### Bullets

- `bullets` -> `bullet.icons`
- `highlights.bullet` -> `bullet.highlight`

### Checkbox

- `checkbox.unchecked` -> `checkbox.unchecked.icon`
- `highlights.checkbox.unchecked` -> `checkbox.unchecked.highlight`
- `checkbox.checked` -> `checkbox.checked.icon`
- `highlights.checkbox.checked` -> `checkbox.checked.highlight`

### Quote

- `quote` -> `quote.icon`
- `highlights.quote` -> `quote.highlight`

### Table

- `table_style` -> `pipe_table.style`
- `cell_style` -> `pipe_table.cell`
- `highlight.table.head` -> `pipe_table.head`
- `highlight.table.row` -> `pipe_table.row`

### Callouts

- `callout.note` -> `callout.note.rendered`
- `callout.tip` -> `callout.tip.rendered`
- `callout.important` -> `callout.important.rendered`
- `callout.warning` -> `callout.warning.rendered`
- `callout.caution` -> `callout.caution.rendered`
- `highlights.callout.note` -> `callout.note.highlight`
- `highlights.callout.tip` -> `callout.tip.highlight`
- `highlights.callout.important` -> `callout.important.highlight`
- `highlights.callout.warning` -> `callout.warning.highlight`
- `highlights.callout.caution` -> `callout.caution.highlight`
- `callout.custom.*` -> `callout.*` (i.e. unnest from custom block)

### Others

Any remaing changes are covered within that component.

I.e. `code_style` is covered in Code, `highlights.table` is covered in
Table, `highlights.callout.note` is covered in Callouts, etc.
  • Loading branch information
MeanderingProgrammer committed Jul 8, 2024
1 parent 33c8571 commit a021d5b
Show file tree
Hide file tree
Showing 12 changed files with 766 additions and 743 deletions.
398 changes: 195 additions & 203 deletions README.md

Large diffs are not rendered by default.

404 changes: 198 additions & 206 deletions doc/render-markdown.txt

Large diffs are not rendered by default.

23 changes: 1 addition & 22 deletions lua/render-markdown/component.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,6 @@ local state = require('render-markdown.state')
---@field text string
---@field highlight string

---@class render.md.CalloutInfo
---@field text string
---@field key string

---@type render.md.CalloutInfo[]
local callouts = {
{ text = '[!NOTE]', key = 'note' },
{ text = '[!TIP]', key = 'tip' },
{ text = '[!IMPORTANT]', key = 'important' },
{ text = '[!WARNING]', key = 'warning' },
{ text = '[!CAUTION]', key = 'caution' },
}

local M = {}

---@param value string
Expand All @@ -34,15 +21,7 @@ M.callout = function(value, comparison)
error(string.format('Unhandled comparison: %s', comparison))
end
end
for _, callout in ipairs(callouts) do
if matches(callout.text) then
return {
text = state.config.callout[callout.key],
highlight = state.config.highlights.callout[callout.key],
}
end
end
for _, callout in pairs(state.config.callout.custom) do
for _, callout in pairs(state.config.callout) do
if matches(callout.raw) then
return { text = callout.rendered, highlight = callout.highlight }
end
Expand Down
7 changes: 3 additions & 4 deletions lua/render-markdown/handler/latex.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ local M = {}
---@param root TSNode
---@param buf integer
M.render = function(namespace, root, buf)
if not state.config.latex_enabled then
if not state.config.latex.enabled then
return
end
local converter = state.config.latex_converter
local converter = state.config.latex.converter
if vim.fn.executable(converter) ~= 1 then
logger.debug('Executable not found: ' .. converter)
else
Expand All @@ -31,7 +31,6 @@ end
---@param node TSNode
---@param converter string
M.render_node = function(namespace, buf, node, converter)
local highlights = state.config.highlights
local value = vim.treesitter.get_node_text(node, buf)
local start_row, start_col, end_row, end_col = node:range()
logger.debug_node('latex', node, buf)
Expand All @@ -45,7 +44,7 @@ M.render_node = function(namespace, buf, node, converter)
end

local latex_lines = vim.tbl_map(function(expression)
return { { expression, highlights.latex } }
return { { expression, state.config.latex.highlight } }
end, expressions)
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
end_row = end_row,
Expand Down
66 changes: 36 additions & 30 deletions lua/render-markdown/handler/markdown.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@ end
---@param capture string
---@param node TSNode
M.render_node = function(namespace, buf, capture, node)
local highlights = state.config.highlights
local value = vim.treesitter.get_node_text(node, buf)
local start_row, start_col, end_row, end_col = node:range()
logger.debug_node(capture, node, buf)

if capture == 'heading' then
local heading = state.config.heading
local level = vim.fn.strdisplaywidth(value)

local heading = list.cycle(state.config.headings, level)
local icon = list.cycle(heading.icons, level)
-- Available width is level + 1, where level = number of `#` characters and one is added
-- to account for the space after the last `#` but before the heading title
local padding = level + 1 - vim.fn.strdisplaywidth(heading)
local padding = level + 1 - vim.fn.strdisplaywidth(icon)

local background = list.clamp_last(highlights.heading.backgrounds, level)
local foreground = list.clamp_last(highlights.heading.foregrounds, level)
local background = list.clamp(heading.backgrounds, level)
local foreground = list.clamp(heading.foregrounds, level)

local heading_text = { str.pad(heading, padding), { foreground, background } }
local heading_text = { str.pad(icon, padding), { foreground, background } }
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, 0, {
end_row = end_row + 1,
end_col = 0,
Expand All @@ -50,25 +50,29 @@ M.render_node = function(namespace, buf, capture, node)
hl_eol = true,
})
elseif capture == 'dash' then
local dash = state.config.dash
local width = vim.api.nvim_win_get_width(util.buf_to_win(buf))
local dash_text = { state.config.dash:rep(width), highlights.dash }

local dash_text = { dash.icon:rep(width), dash.highlight }
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, 0, {
virt_text = { dash_text },
virt_text_pos = 'overlay',
})
elseif capture == 'code' then
if state.config.code_style == 'none' then
local code = state.config.code
if code.style == 'none' then
return
end

vim.api.nvim_buf_set_extmark(buf, namespace, start_row, 0, {
end_row = end_row,
end_col = 0,
hl_group = highlights.code,
hl_group = code.highlight,
hl_eol = true,
})
elseif capture == 'language' then
if state.config.code_style ~= 'full' then
local code = state.config.code
if code.style ~= 'full' then
return
end
-- Requires inline extmarks
Expand All @@ -81,7 +85,7 @@ M.render_node = function(namespace, buf, capture, node)
return
end

local icon_text = { icon .. ' ' .. value, { icon_highlight, highlights.code } }
local icon_text = { icon .. ' ' .. value, { icon_highlight, code.highlight } }
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
virt_text = { icon_text },
virt_text_pos = 'inline',
Expand All @@ -95,14 +99,15 @@ M.render_node = function(namespace, buf, capture, node)
conceal = '',
})
else
local bullet = state.config.bullet
-- List markers from tree-sitter should have leading spaces removed, however there are known
-- edge cases in the parser: https://github.com/tree-sitter-grammars/tree-sitter-markdown/issues/127
-- As a result we handle leading spaces here, can remove if this gets fixed upstream
local _, leading_spaces = value:find('^%s*')
local level = ts.level_in_section(node, 'list')
local bullet = list.cycle(state.config.bullets, level)
local icon = list.cycle(bullet.icons, level)

local list_marker_text = { str.pad(bullet, leading_spaces), highlights.bullet }
local list_marker_text = { str.pad(icon, leading_spaces), bullet.highlight }
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
end_row = end_row,
end_col = end_col,
Expand All @@ -116,16 +121,17 @@ M.render_node = function(namespace, buf, capture, node)
M.render_node(namespace, buf, query.captures[id], nested_node)
end
elseif capture == 'quote_marker' then
local highlight = highlights.quote
local quote = ts.parent_in_section(node, 'block_quote')
if quote ~= nil then
local callout = component.callout(vim.treesitter.get_node_text(quote, buf), 'contains')
local quote = state.config.quote
local highlight = quote.highlight
local quote_node = ts.parent_in_section(node, 'block_quote')
if quote_node ~= nil then
local callout = component.callout(vim.treesitter.get_node_text(quote_node, buf), 'contains')
if callout ~= nil then
highlight = callout.highlight
end
end

local quote_marker_text = { value:gsub('>', state.config.quote), highlight }
local quote_marker_text = { value:gsub('>', quote.icon), highlight }
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
end_row = end_row,
end_col = end_col,
Expand All @@ -134,21 +140,20 @@ M.render_node = function(namespace, buf, capture, node)
})
elseif vim.tbl_contains({ 'checkbox_unchecked', 'checkbox_checked' }, capture) then
local checkbox = state.config.checkbox.unchecked
local highlight = highlights.checkbox.unchecked
if capture == 'checkbox_checked' then
checkbox = state.config.checkbox.checked
highlight = highlights.checkbox.checked
end

local checkbox_text = { str.pad_to(value, checkbox), highlight }
local checkbox_text = { str.pad_to(value, checkbox.icon), checkbox.highlight }
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
end_row = end_row,
end_col = end_col,
virt_text = { checkbox_text },
virt_text_pos = 'overlay',
})
elseif capture == 'table' then
if state.config.table_style ~= 'full' then
local pipe_table = state.config.pipe_table
if pipe_table.style ~= 'full' then
return
end

Expand All @@ -157,7 +162,7 @@ M.render_node = function(namespace, buf, capture, node)
---@return integer
local function get_table_row_width(row, s)
local result = vim.fn.strdisplaywidth(s)
if state.config.cell_style == 'raw' then
if pipe_table.cell == 'raw' then
result = result - ts.concealed(buf, row, s)
end
return result
Expand All @@ -181,26 +186,27 @@ M.render_node = function(namespace, buf, capture, node)
return string.rep('', vim.fn.strdisplaywidth(part))
end, headings)

local line_above = { { '' .. table.concat(lengths, '') .. '', highlights.table.head } }
local line_above = { { '' .. table.concat(lengths, '') .. '', pipe_table.head } }
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
virt_lines_above = true,
virt_lines = { line_above },
})

local line_below = { { '' .. table.concat(lengths, '') .. '', highlights.table.row } }
local line_below = { { '' .. table.concat(lengths, '') .. '', pipe_table.row } }
vim.api.nvim_buf_set_extmark(buf, namespace, end_row, start_col, {
virt_lines_above = true,
virt_lines = { line_below },
})
end
elseif vim.tbl_contains({ 'table_head', 'table_delim', 'table_row' }, capture) then
if state.config.table_style == 'none' then
local pipe_table = state.config.pipe_table
if pipe_table.style == 'none' then
return
end

local highlight = highlights.table.head
local highlight = pipe_table.head
if capture == 'table_row' then
highlight = highlights.table.row
highlight = pipe_table.row
end

if capture == 'table_delim' then
Expand All @@ -220,15 +226,15 @@ M.render_node = function(namespace, buf, capture, node)
virt_text = { table_delim_text },
virt_text_pos = 'overlay',
})
elseif state.config.cell_style == 'overlay' then
elseif pipe_table.cell == 'overlay' then
local table_row_text = { value:gsub('|', ''), highlight }
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
end_row = end_row,
end_col = end_col,
virt_text = { table_row_text },
virt_text_pos = 'overlay',
})
elseif state.config.cell_style == 'raw' then
elseif pipe_table.cell == 'raw' then
for i = 1, #value do
local ch = value:sub(i, i)
if ch == '|' then
Expand Down
4 changes: 2 additions & 2 deletions lua/render-markdown/handler/markdown_inline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ end
---@param capture string
---@param node TSNode
M.render_node = function(namespace, buf, capture, node)
local highlights = state.config.highlights
local value = vim.treesitter.get_node_text(node, buf)
local start_row, start_col, end_row, end_col = node:range()
logger.debug_node(capture, node, buf)

if capture == 'code' then
local code = state.config.code
vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
end_row = end_row,
end_col = end_col,
hl_group = highlights.code,
hl_group = code.highlight,
})
elseif capture == 'callout' then
local callout = component.callout(value, 'exact')
Expand Down
Loading

0 comments on commit a021d5b

Please sign in to comment.