diff --git a/README.md b/README.md index de463ee..81fd40a 100644 --- a/README.md +++ b/README.md @@ -101,9 +101,7 @@ Some of the more useful fields are discussed further down. ```lua require('render-markdown').setup({ -- Whether Markdown should be rendered by default or not - start_enabled = true, - -- Whether LaTeX should be rendered, mainly used for health check - latex_enabled = true, + enabled = true, -- Maximum file size (in MB) that this plugin will attempt to render -- Any file larger than this will effectively be ignored max_file_size = 1.5, @@ -152,8 +150,6 @@ require('render-markdown').setup({ (shortcut_link) @callout ]], - -- Executable used to convert latex formula to rendered unicode - latex_converter = 'latex2text', -- The level of logs to write to file: vim.fn.stdpath('state') .. '/render-markdown.log' -- Only intended to be used for plugin development / debugging log_level = 'error', @@ -162,34 +158,112 @@ require('render-markdown').setup({ -- Vim modes that will show a rendered view of the markdown file -- All other modes will be uneffected by this plugin render_modes = { 'n', 'c' }, - -- Characters that will replace the # at the start of headings - headings = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, - -- Character to use for the horizontal break - dash = '─', - -- Character to use for the bullet points in lists - bullets = { '●', '○', '◆', '◇' }, + latex = { + -- Whether LaTeX should be rendered, mainly used for health check + enabled = true, + -- Executable used to convert latex formula to rendered unicode + converter = 'latex2text', + -- Highlight for LaTeX blocks + highlight = '@markup.math', + }, + heading = { + -- Replaces '#+' of 'atx_h._marker' + -- The number of '#' in the heading determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- The result is left padded with spaces to hide any additional '#' + icons = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon and extends through the entire line + backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon only + foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, + }, + code = { + -- Determines how code blocks are rendered: + -- none: disables all rendering + -- normal: adds highlight group to the code block + -- full: normal + language icon & name above the code block + style = 'full', + -- Highlight for code blocks + highlight = 'ColorColumn', + }, + dash = { + -- Replaces '---'|'***'|'___'|'* * *' of 'thematic_break' + -- The icon gets repeated across the window's width + icon = '─', + -- Highlight for the whole line generated from the icon + highlight = 'LineNr', + }, + bullet = { + -- Replaces '-'|'+'|'*' of 'list_item' + -- How deeply nested the list is determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- If the item is a 'checkbox' a conceal is used to hide the bullet instead + icons = { '●', '○', '◆', '◇' }, + -- Highlight for the bullet icon + highlight = 'Normal', + }, + -- Checkboxes are a special instance of a 'list_item' that start with a 'shortcut_link' + -- There are two special states for unchecked & checked defined in the markdown grammar checkbox = { - -- Character that will replace the [ ] in unchecked checkboxes - unchecked = '󰄱 ', - -- Character that will replace the [x] in checked checkboxes - checked = '󰱒 ', - -- Specify custom checkboxes, must be surrounded in square brackets + unchecked = { + -- Replaces '[ ]' of 'task_list_marker_unchecked' + icon = '󰄱 ', + -- Highlight for the unchecked icon + highlight = '@markup.list.unchecked', + }, + checked = { + -- Replaces '[x]' of 'task_list_marker_checked' + icon = '󰱒 ', + -- Highligh for the checked icon + highlight = '@markup.heading', + }, + -- Define custom checkbox states, more involved as they are not part of the markdown grammar + -- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks + -- Can specify as many additional states as you like following the 'todo' pattern below + -- The key in this case 'todo' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' icon custom = { todo = { raw = '[-]', rendered = '󰥔 ', highlight = '@markup.raw' }, }, }, - -- Character that will replace the > at the start of block quotes - quote = '▋', - -- Symbol / text to use for different callouts + quote = { + -- Replaces '>' of 'block_quote' + icon = '▋', + -- Highlight for the quote icon + highlight = '@markup.quote', + }, + pipe_table = { + -- Determines how the table as a whole is rendered: + -- none: disables all rendering + -- normal: applies the 'cell' style rendering to each row of the table + -- full: normal + a top & bottom line that fill out the table when lengths match + style = 'full', + -- Determines how individual cells of a table are rendered: + -- overlay: writes completely over the table, removing conceal behavior and highlights + -- raw: replaces only the '|' characters in each row, leaving the cells completely unmodified + cell = 'overlay', + -- Highlight for table heading, delimitter, and the line above + head = '@markup.heading', + -- Highlight for everything else, main table rows and the line below + row = 'Normal', + }, + -- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link' + -- Can specify as many additional values as you like following the pattern from any below, such as 'note' + -- The key in this case 'note' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' text and quote markers callout = { - note = '󰋽 Note', - tip = '󰌶 Tip', - important = '󰅾 Important', - warning = '󰀪 Warning', - caution = '󰳦 Caution', - custom = { - bug = { raw = '[!BUG]', rendered = '󰨰 Bug', highlight = 'DiagnosticError' }, - }, + note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'DiagnosticInfo' }, + tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'DiagnosticOk' }, + important = { raw = '[!IMPORTANT]', rendered = '󰅾 Important', highlight = 'DiagnosticHint' }, + warning = { raw = '[!WARNING]', rendered = '󰀪 Warning', highlight = 'DiagnosticWarn' }, + caution = { raw = '[!CAUTION]', rendered = '󰳦 Caution', highlight = 'DiagnosticError' }, + bug = { raw = '[!BUG]', rendered = '󰨰 Bug', highlight = 'DiagnosticError' }, }, -- Window options to use that change between rendered and raw view win_options = { @@ -208,62 +282,9 @@ require('render-markdown').setup({ rendered = 'nvic', }, }, - -- Determines how code blocks are rendered - -- full: adds language icon above code block if possible + normal behavior - -- normal: renders a background - -- none: disables rendering - code_style = 'full', - -- Determines how tables are rendered - -- full: adds a line above and below tables + normal behavior - -- normal: renders the rows of tables - -- none: disables rendering - table_style = 'full', - -- Determines how table cells are rendered - -- overlay: writes over the top of cells removing conealing and highlighting - -- raw: will leave the cells as they and only replace table related symbols - cell_style = 'overlay', -- Mapping from treesitter language to user defined handlers - -- See 'Custom Handlers' section for more info + -- See 'Custom Handlers' document for more info custom_handlers = {}, - -- Define the highlight groups to use when rendering various components - highlights = { - heading = { - -- Background of heading line - backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, - -- Foreground of heading character only - foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, - }, - -- Horizontal break - dash = 'LineNr', - -- Code blocks - code = 'ColorColumn', - -- Bullet points in list - bullet = 'Normal', - checkbox = { - -- Unchecked checkboxes - unchecked = '@markup.list.unchecked', - -- Checked checkboxes - checked = '@markup.heading', - }, - table = { - -- Header of a markdown table - head = '@markup.heading', - -- Non header rows in a markdown table - row = 'Normal', - }, - -- LaTeX blocks - latex = '@markup.math', - -- Quote character in a block quote - quote = '@markup.quote', - -- Highlights to use for different callouts - callout = { - note = 'DiagnosticInfo', - tip = 'DiagnosticOk', - important = 'DiagnosticHint', - warning = 'DiagnosticWarn', - caution = 'DiagnosticError', - }, - }, }) ``` @@ -280,20 +301,34 @@ We use the following definitions when discussing indexing into arrays: ```lua require('render-markdown').setup({ - -- Replaces '#+' of 'atx_h._marker' - -- The number of '#' in the heading determines the 'level' - -- The 'level' is used to index into the array using a cycle - -- The result is left padded with spaces to hide any additional '#' - headings = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, - highlights = { - heading = { - -- The 'level' is used to index into the array using a clamp - -- Applies to the heading icon and extends through the entire line - backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, - -- The 'level' is used to index into the array using a clamp - -- Applies to the heading icon only - foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, - }, + heading = { + -- Replaces '#+' of 'atx_h._marker' + -- The number of '#' in the heading determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- The result is left padded with spaces to hide any additional '#' + icons = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon and extends through the entire line + backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon only + foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, + }, +}) +``` + +## Code Blocks + +```lua +require('render-markdown').setup({ + code = { + -- Determines how code blocks are rendered: + -- none: disables all rendering + -- normal: adds highlight group to the code block + -- full: normal + language icon & name above the code block + style = 'full', + -- Highlight for code blocks + highlight = 'ColorColumn', }, }) ``` @@ -302,12 +337,12 @@ require('render-markdown').setup({ ```lua require('render-markdown').setup({ - -- Replaces '---'|'***'|'___'|'* * *' of 'thematic_break' - -- The icon gets repeated across the window's width - dash = '─', - highlights = { - -- Applies to the whole line generated from the icon - dash = 'LineNr', + dash = { + -- Replaces '---'|'***'|'___'|'* * *' of 'thematic_break' + -- The icon gets repeated across the window's width + icon = '─', + -- Highlight for the whole line generated from the icon + highlight = 'LineNr', }, }) ``` @@ -316,14 +351,14 @@ require('render-markdown').setup({ ```lua require('render-markdown').setup({ - -- Replaces '-'|'+'|'*' of 'list_item' - -- How deeply nested the list is determines the 'level' - -- The 'level' is used to index into the array using a cycle - -- If the item is a 'checkbox' a conceal is used to hide the bullet instead - bullets = { '●', '○', '◆', '◇' }, - highlights = { - -- Applies the bullet icon - bullet = 'Normal', + bullet = { + -- Replaces '-'|'+'|'*' of 'list_item' + -- How deeply nested the list is determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- If the item is a 'checkbox' a conceal is used to hide the bullet instead + icons = { '●', '○', '◆', '◇' }, + -- Highlight for the bullet icon + highlight = 'Normal', }, }) ``` @@ -335,31 +370,27 @@ require('render-markdown').setup({ -- Checkboxes are a special instance of a 'list_item' that start with a 'shortcut_link' -- There are two special states for unchecked & checked defined in the markdown grammar checkbox = { - -- Replaces '[ ]' of 'task_list_marker_unchecked' - unchecked = '󰄱 ', - -- Replaces '[x]' of 'task_list_marker_checked' - checked = '󰱒 ', + unchecked = { + -- Replaces '[ ]' of 'task_list_marker_unchecked' + icon = '󰄱 ', + -- Highlight for the unchecked icon + highlight = '@markup.list.unchecked', + }, + checked = { + -- Replaces '[x]' of 'task_list_marker_checked' + icon = '󰱒 ', + -- Highligh for the checked icon + highlight = '@markup.heading', + }, -- Define custom checkbox states, more involved as they are not part of the markdown grammar -- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks -- Can specify as many additional states as you like following the 'todo' pattern below + -- The key in this case 'todo' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' icon custom = { - -- The key in this case `todo` is unused - todo = { - -- Matched against the raw text of a 'shortcut_link' - raw = '[-]', - -- Replaces the 'raw' value when rendering - rendered = '󰥔 ', - -- Applies to the 'rendered' icon - highlight = '@markup.raw' - }, - }, - }, - highlights = { - checkbox = { - -- Applies to the unchecked icon - unchecked = '@markup.list.unchecked', - -- Applies to the checked icon - checked = '@markup.heading', + todo = { raw = '[-]', rendered = '󰥔 ', highlight = '@markup.raw' }, }, }, }) @@ -369,93 +400,54 @@ require('render-markdown').setup({ ```lua require('render-markdown').setup({ - -- Replaces '>' of 'block_quote' - quote = '▋', - highlights = { - -- Applies to the quote icon - quote = '@markup.quote', - }, -}) -``` - -## Callouts - -```lua -require('render-markdown').setup({ - -- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link' - callout = { - -- Replaces '[!NOTE]' - note = '󰋽 Note', - -- Replaces '[!TIP]' - tip = '󰌶 Tip', - -- Replaces '[!IMPORTANT]' - important = '󰅾 Important', - -- Replaces '[!WARNING]' - warning = '󰀪 Warning', - -- Replaces '[!CAUTION]' - caution = '󰳦 Caution', - -- Define custom callouts, can specify as many as you like following the 'bug' pattern below - custom = { - -- The key in this case `bug` is unused - bug = { - -- Matched against the raw text of a 'shortcut_link' - raw = '[!BUG]', - -- Replaces the 'raw' value when rendering - rendered = '󰨰 Bug', - -- Applies to the 'rendered' text and quote markers - highlight = 'DiagnosticError', - }, - }, - }, - highlights = { - -- Used for standard callouts, applies to both text and quote markers - callout = { - note = 'DiagnosticInfo', - tip = 'DiagnosticOk', - important = 'DiagnosticHint', - warning = 'DiagnosticWarn', - caution = 'DiagnosticError', - }, + quote = { + -- Replaces '>' of 'block_quote' + icon = '▋', + -- Highlight for the quote icon + highlight = '@markup.quote', }, }) ``` -## Code Blocks +## Tables ```lua require('render-markdown').setup({ - -- Determines how code blocks are rendered: - -- none: disables all rendering - -- normal: adds highlight group to the code block - -- full: normal + language icon & name above the code block - code_style = 'full', - highlights = { - -- Applies to code blocks - code = 'ColorColumn', + pipe_table = { + -- Determines how the table as a whole is rendered: + -- none: disables all rendering + -- normal: applies the 'cell' style rendering to each row of the table + -- full: normal + a top & bottom line that fill out the table when lengths match + style = 'full', + -- Determines how individual cells of a table are rendered: + -- overlay: writes completely over the table, removing conceal behavior and highlights + -- raw: replaces only the '|' characters in each row, leaving the cells completely unmodified + cell = 'overlay', + -- Highlight for table heading, delimitter, and the line above + head = '@markup.heading', + -- Highlight for everything else, main table rows and the line below + row = 'Normal', }, }) ``` -## Tables +## Callouts ```lua require('render-markdown').setup({ - -- Determines how the table as a whole is rendered: - -- none: disables all rendering - -- normal: applies the 'cell_style' rendering to each row of the table - -- full: normal + a top & bottom line that fill out the table when lengths match - table_style = 'full', - -- Determines how individual cells of a table are rendered: - -- overlay: writes completely over the table, removing conceal behavior and highlights - -- raw: replaces only the '|' characters in each row, leaving the cells completely unmodified - cell_style = 'overlay', - highlights = { - table = { - -- Applies to table heading, delimitter, and the line above - head = '@markup.heading', - -- Applies to everything else, main table rows and the line below - row = 'Normal', - }, + -- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link' + -- Can specify as many additional values as you like following the pattern from any below, such as 'note' + -- The key in this case 'note' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' text and quote markers + callout = { + note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'DiagnosticInfo' }, + tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'DiagnosticOk' }, + important = { raw = '[!IMPORTANT]', rendered = '󰅾 Important', highlight = 'DiagnosticHint' }, + warning = { raw = '[!WARNING]', rendered = '󰀪 Warning', highlight = 'DiagnosticWarn' }, + caution = { raw = '[!CAUTION]', rendered = '󰳦 Caution', highlight = 'DiagnosticError' }, + bug = { raw = '[!BUG]', rendered = '󰨰 Bug', highlight = 'DiagnosticError' }, }, }) ``` diff --git a/doc/render-markdown.txt b/doc/render-markdown.txt index 2b59b6d..3cc97b2 100644 --- a/doc/render-markdown.txt +++ b/doc/render-markdown.txt @@ -12,13 +12,13 @@ Table of Contents *render-markdown-table-of-contents* 5. Commands |render-markdown-commands| 6. Setup |render-markdown-setup| - Headings |render-markdown-setup-headings| + - Code Blocks |render-markdown-setup-code-blocks| - Dashed Line |render-markdown-setup-dashed-line| - List Bullets |render-markdown-setup-list-bullets| - Checkboxes |render-markdown-setup-checkboxes| - Standard Quotes |render-markdown-setup-standard-quotes| - - Callouts |render-markdown-setup-callouts| - - Code Blocks |render-markdown-setup-code-blocks| - Tables |render-markdown-setup-tables| + - Callouts |render-markdown-setup-callouts| 7. Additional Info |render-markdown-additional-info| ============================================================================== @@ -137,9 +137,7 @@ Full Default Configuration ~ >lua require('render-markdown').setup({ -- Whether Markdown should be rendered by default or not - start_enabled = true, - -- Whether LaTeX should be rendered, mainly used for health check - latex_enabled = true, + enabled = true, -- Maximum file size (in MB) that this plugin will attempt to render -- Any file larger than this will effectively be ignored max_file_size = 1.5, @@ -188,8 +186,6 @@ Full Default Configuration ~ (shortcut_link) @callout ]], - -- Executable used to convert latex formula to rendered unicode - latex_converter = 'latex2text', -- The level of logs to write to file: vim.fn.stdpath('state') .. '/render-markdown.log' -- Only intended to be used for plugin development / debugging log_level = 'error', @@ -198,34 +194,112 @@ Full Default Configuration ~ -- Vim modes that will show a rendered view of the markdown file -- All other modes will be uneffected by this plugin render_modes = { 'n', 'c' }, - -- Characters that will replace the # at the start of headings - headings = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, - -- Character to use for the horizontal break - dash = '─', - -- Character to use for the bullet points in lists - bullets = { '●', '○', '◆', '◇' }, + latex = { + -- Whether LaTeX should be rendered, mainly used for health check + enabled = true, + -- Executable used to convert latex formula to rendered unicode + converter = 'latex2text', + -- Highlight for LaTeX blocks + highlight = '@markup.math', + }, + heading = { + -- Replaces '#+' of 'atx_h._marker' + -- The number of '#' in the heading determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- The result is left padded with spaces to hide any additional '#' + icons = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon and extends through the entire line + backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon only + foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, + }, + code = { + -- Determines how code blocks are rendered: + -- none: disables all rendering + -- normal: adds highlight group to the code block + -- full: normal + language icon & name above the code block + style = 'full', + -- Highlight for code blocks + highlight = 'ColorColumn', + }, + dash = { + -- Replaces '---'|'***'|'___'|'* * *' of 'thematic_break' + -- The icon gets repeated across the window's width + icon = '─', + -- Highlight for the whole line generated from the icon + highlight = 'LineNr', + }, + bullet = { + -- Replaces '-'|'+'|'*' of 'list_item' + -- How deeply nested the list is determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- If the item is a 'checkbox' a conceal is used to hide the bullet instead + icons = { '●', '○', '◆', '◇' }, + -- Highlight for the bullet icon + highlight = 'Normal', + }, + -- Checkboxes are a special instance of a 'list_item' that start with a 'shortcut_link' + -- There are two special states for unchecked & checked defined in the markdown grammar checkbox = { - -- Character that will replace the [ ] in unchecked checkboxes - unchecked = '󰄱 ', - -- Character that will replace the [x] in checked checkboxes - checked = '󰱒 ', - -- Specify custom checkboxes, must be surrounded in square brackets + unchecked = { + -- Replaces '[ ]' of 'task_list_marker_unchecked' + icon = '󰄱 ', + -- Highlight for the unchecked icon + highlight = '@markup.list.unchecked', + }, + checked = { + -- Replaces '[x]' of 'task_list_marker_checked' + icon = '󰱒 ', + -- Highligh for the checked icon + highlight = '@markup.heading', + }, + -- Define custom checkbox states, more involved as they are not part of the markdown grammar + -- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks + -- Can specify as many additional states as you like following the 'todo' pattern below + -- The key in this case 'todo' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' icon custom = { todo = { raw = '[-]', rendered = '󰥔 ', highlight = '@markup.raw' }, }, }, - -- Character that will replace the > at the start of block quotes - quote = '▋', - -- Symbol / text to use for different callouts + quote = { + -- Replaces '>' of 'block_quote' + icon = '▋', + -- Highlight for the quote icon + highlight = '@markup.quote', + }, + pipe_table = { + -- Determines how the table as a whole is rendered: + -- none: disables all rendering + -- normal: applies the 'cell' style rendering to each row of the table + -- full: normal + a top & bottom line that fill out the table when lengths match + style = 'full', + -- Determines how individual cells of a table are rendered: + -- overlay: writes completely over the table, removing conceal behavior and highlights + -- raw: replaces only the '|' characters in each row, leaving the cells completely unmodified + cell = 'overlay', + -- Highlight for table heading, delimitter, and the line above + head = '@markup.heading', + -- Highlight for everything else, main table rows and the line below + row = 'Normal', + }, + -- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link' + -- Can specify as many additional values as you like following the pattern from any below, such as 'note' + -- The key in this case 'note' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' text and quote markers callout = { - note = '󰋽 Note', - tip = '󰌶 Tip', - important = '󰅾 Important', - warning = '󰀪 Warning', - caution = '󰳦 Caution', - custom = { - bug = { raw = '[!BUG]', rendered = '󰨰 Bug', highlight = 'DiagnosticError' }, - }, + note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'DiagnosticInfo' }, + tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'DiagnosticOk' }, + important = { raw = '[!IMPORTANT]', rendered = '󰅾 Important', highlight = 'DiagnosticHint' }, + warning = { raw = '[!WARNING]', rendered = '󰀪 Warning', highlight = 'DiagnosticWarn' }, + caution = { raw = '[!CAUTION]', rendered = '󰳦 Caution', highlight = 'DiagnosticError' }, + bug = { raw = '[!BUG]', rendered = '󰨰 Bug', highlight = 'DiagnosticError' }, }, -- Window options to use that change between rendered and raw view win_options = { @@ -244,62 +318,9 @@ Full Default Configuration ~ rendered = 'nvic', }, }, - -- Determines how code blocks are rendered - -- full: adds language icon above code block if possible + normal behavior - -- normal: renders a background - -- none: disables rendering - code_style = 'full', - -- Determines how tables are rendered - -- full: adds a line above and below tables + normal behavior - -- normal: renders the rows of tables - -- none: disables rendering - table_style = 'full', - -- Determines how table cells are rendered - -- overlay: writes over the top of cells removing conealing and highlighting - -- raw: will leave the cells as they and only replace table related symbols - cell_style = 'overlay', -- Mapping from treesitter language to user defined handlers - -- See 'Custom Handlers' section for more info + -- See 'Custom Handlers' document for more info custom_handlers = {}, - -- Define the highlight groups to use when rendering various components - highlights = { - heading = { - -- Background of heading line - backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, - -- Foreground of heading character only - foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, - }, - -- Horizontal break - dash = 'LineNr', - -- Code blocks - code = 'ColorColumn', - -- Bullet points in list - bullet = 'Normal', - checkbox = { - -- Unchecked checkboxes - unchecked = '@markup.list.unchecked', - -- Checked checkboxes - checked = '@markup.heading', - }, - table = { - -- Header of a markdown table - head = '@markup.heading', - -- Non header rows in a markdown table - row = 'Normal', - }, - -- LaTeX blocks - latex = '@markup.math', - -- Quote character in a block quote - quote = '@markup.quote', - -- Highlights to use for different callouts - callout = { - note = 'DiagnosticInfo', - tip = 'DiagnosticOk', - important = 'DiagnosticHint', - warning = 'DiagnosticWarn', - caution = 'DiagnosticError', - }, - }, }) < @@ -315,20 +336,35 @@ HEADINGS *render-markdown-setup-headings* >lua require('render-markdown').setup({ - -- Replaces '#+' of 'atx_h._marker' - -- The number of '#' in the heading determines the 'level' - -- The 'level' is used to index into the array using a cycle - -- The result is left padded with spaces to hide any additional '#' - headings = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, - highlights = { - heading = { - -- The 'level' is used to index into the array using a clamp - -- Applies to the heading icon and extends through the entire line - backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, - -- The 'level' is used to index into the array using a clamp - -- Applies to the heading icon only - foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, - }, + heading = { + -- Replaces '#+' of 'atx_h._marker' + -- The number of '#' in the heading determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- The result is left padded with spaces to hide any additional '#' + icons = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon and extends through the entire line + backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon only + foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, + }, + }) +< + + +CODE BLOCKS *render-markdown-setup-code-blocks* + +>lua + require('render-markdown').setup({ + code = { + -- Determines how code blocks are rendered: + -- none: disables all rendering + -- normal: adds highlight group to the code block + -- full: normal + language icon & name above the code block + style = 'full', + -- Highlight for code blocks + highlight = 'ColorColumn', }, }) < @@ -338,12 +374,12 @@ DASHED LINE *render-markdown-setup-dashed-line* >lua require('render-markdown').setup({ - -- Replaces '---'|'***'|'___'|'* * *' of 'thematic_break' - -- The icon gets repeated across the window's width - dash = '─', - highlights = { - -- Applies to the whole line generated from the icon - dash = 'LineNr', + dash = { + -- Replaces '---'|'***'|'___'|'* * *' of 'thematic_break' + -- The icon gets repeated across the window's width + icon = '─', + -- Highlight for the whole line generated from the icon + highlight = 'LineNr', }, }) < @@ -353,14 +389,14 @@ LIST BULLETS *render-markdown-setup-list-bullets* >lua require('render-markdown').setup({ - -- Replaces '-'|'+'|'*' of 'list_item' - -- How deeply nested the list is determines the 'level' - -- The 'level' is used to index into the array using a cycle - -- If the item is a 'checkbox' a conceal is used to hide the bullet instead - bullets = { '●', '○', '◆', '◇' }, - highlights = { - -- Applies the bullet icon - bullet = 'Normal', + bullet = { + -- Replaces '-'|'+'|'*' of 'list_item' + -- How deeply nested the list is determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- If the item is a 'checkbox' a conceal is used to hide the bullet instead + icons = { '●', '○', '◆', '◇' }, + -- Highlight for the bullet icon + highlight = 'Normal', }, }) < @@ -373,31 +409,27 @@ CHECKBOXES *render-markdown-setup-checkboxes* -- Checkboxes are a special instance of a 'list_item' that start with a 'shortcut_link' -- There are two special states for unchecked & checked defined in the markdown grammar checkbox = { - -- Replaces '[ ]' of 'task_list_marker_unchecked' - unchecked = '󰄱 ', - -- Replaces '[x]' of 'task_list_marker_checked' - checked = '󰱒 ', + unchecked = { + -- Replaces '[ ]' of 'task_list_marker_unchecked' + icon = '󰄱 ', + -- Highlight for the unchecked icon + highlight = '@markup.list.unchecked', + }, + checked = { + -- Replaces '[x]' of 'task_list_marker_checked' + icon = '󰱒 ', + -- Highligh for the checked icon + highlight = '@markup.heading', + }, -- Define custom checkbox states, more involved as they are not part of the markdown grammar -- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks -- Can specify as many additional states as you like following the 'todo' pattern below + -- The key in this case 'todo' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' icon custom = { - -- The key in this case `todo` is unused - todo = { - -- Matched against the raw text of a 'shortcut_link' - raw = '[-]', - -- Replaces the 'raw' value when rendering - rendered = '󰥔 ', - -- Applies to the 'rendered' icon - highlight = '@markup.raw' - }, - }, - }, - highlights = { - checkbox = { - -- Applies to the unchecked icon - unchecked = '@markup.list.unchecked', - -- Applies to the checked icon - checked = '@markup.heading', + todo = { raw = '[-]', rendered = '󰥔 ', highlight = '@markup.raw' }, }, }, }) @@ -408,96 +440,56 @@ STANDARD QUOTES *render-markdown-setup-standard-quotes* >lua require('render-markdown').setup({ - -- Replaces '>' of 'block_quote' - quote = '▋', - highlights = { - -- Applies to the quote icon - quote = '@markup.quote', + quote = { + -- Replaces '>' of 'block_quote' + icon = '▋', + -- Highlight for the quote icon + highlight = '@markup.quote', }, }) < -CALLOUTS *render-markdown-setup-callouts* - ->lua - require('render-markdown').setup({ - -- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link' - callout = { - -- Replaces '[!NOTE]' - note = '󰋽 Note', - -- Replaces '[!TIP]' - tip = '󰌶 Tip', - -- Replaces '[!IMPORTANT]' - important = '󰅾 Important', - -- Replaces '[!WARNING]' - warning = '󰀪 Warning', - -- Replaces '[!CAUTION]' - caution = '󰳦 Caution', - -- Define custom callouts, can specify as many as you like following the 'bug' pattern below - custom = { - -- The key in this case `bug` is unused - bug = { - -- Matched against the raw text of a 'shortcut_link' - raw = '[!BUG]', - -- Replaces the 'raw' value when rendering - rendered = '󰨰 Bug', - -- Applies to the 'rendered' text and quote markers - highlight = 'DiagnosticError', - }, - }, - }, - highlights = { - -- Used for standard callouts, applies to both text and quote markers - callout = { - note = 'DiagnosticInfo', - tip = 'DiagnosticOk', - important = 'DiagnosticHint', - warning = 'DiagnosticWarn', - caution = 'DiagnosticError', - }, - }, - }) -< - - -CODE BLOCKS *render-markdown-setup-code-blocks* +TABLES *render-markdown-setup-tables* >lua require('render-markdown').setup({ - -- Determines how code blocks are rendered: - -- none: disables all rendering - -- normal: adds highlight group to the code block - -- full: normal + language icon & name above the code block - code_style = 'full', - highlights = { - -- Applies to code blocks - code = 'ColorColumn', + pipe_table = { + -- Determines how the table as a whole is rendered: + -- none: disables all rendering + -- normal: applies the 'cell' style rendering to each row of the table + -- full: normal + a top & bottom line that fill out the table when lengths match + style = 'full', + -- Determines how individual cells of a table are rendered: + -- overlay: writes completely over the table, removing conceal behavior and highlights + -- raw: replaces only the '|' characters in each row, leaving the cells completely unmodified + cell = 'overlay', + -- Highlight for table heading, delimitter, and the line above + head = '@markup.heading', + -- Highlight for everything else, main table rows and the line below + row = 'Normal', }, }) < -TABLES *render-markdown-setup-tables* +CALLOUTS *render-markdown-setup-callouts* >lua require('render-markdown').setup({ - -- Determines how the table as a whole is rendered: - -- none: disables all rendering - -- normal: applies the 'cell_style' rendering to each row of the table - -- full: normal + a top & bottom line that fill out the table when lengths match - table_style = 'full', - -- Determines how individual cells of a table are rendered: - -- overlay: writes completely over the table, removing conceal behavior and highlights - -- raw: replaces only the '|' characters in each row, leaving the cells completely unmodified - cell_style = 'overlay', - highlights = { - table = { - -- Applies to table heading, delimitter, and the line above - head = '@markup.heading', - -- Applies to everything else, main table rows and the line below - row = 'Normal', - }, + -- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link' + -- Can specify as many additional values as you like following the pattern from any below, such as 'note' + -- The key in this case 'note' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' text and quote markers + callout = { + note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'DiagnosticInfo' }, + tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'DiagnosticOk' }, + important = { raw = '[!IMPORTANT]', rendered = '󰅾 Important', highlight = 'DiagnosticHint' }, + warning = { raw = '[!WARNING]', rendered = '󰀪 Warning', highlight = 'DiagnosticWarn' }, + caution = { raw = '[!CAUTION]', rendered = '󰳦 Caution', highlight = 'DiagnosticError' }, + bug = { raw = '[!BUG]', rendered = '󰨰 Bug', highlight = 'DiagnosticError' }, }, }) < diff --git a/lua/render-markdown/component.lua b/lua/render-markdown/component.lua index 0eb2003..ff99728 100644 --- a/lua/render-markdown/component.lua +++ b/lua/render-markdown/component.lua @@ -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 @@ -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 diff --git a/lua/render-markdown/handler/latex.lua b/lua/render-markdown/handler/latex.lua index fbb7c79..417db0a 100644 --- a/lua/render-markdown/handler/latex.lua +++ b/lua/render-markdown/handler/latex.lua @@ -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 @@ -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) @@ -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, diff --git a/lua/render-markdown/handler/markdown.lua b/lua/render-markdown/handler/markdown.lua index 7dc6685..c654bde 100644 --- a/lua/render-markdown/handler/markdown.lua +++ b/lua/render-markdown/handler/markdown.lua @@ -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, @@ -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 @@ -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', @@ -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, @@ -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, @@ -134,13 +140,11 @@ 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, @@ -148,7 +152,8 @@ M.render_node = function(namespace, buf, capture, node) 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 @@ -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 @@ -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 @@ -220,7 +226,7 @@ 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, @@ -228,7 +234,7 @@ M.render_node = function(namespace, buf, capture, node) 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 diff --git a/lua/render-markdown/handler/markdown_inline.lua b/lua/render-markdown/handler/markdown_inline.lua index 60f56a4..3cee549 100644 --- a/lua/render-markdown/handler/markdown_inline.lua +++ b/lua/render-markdown/handler/markdown_inline.lua @@ -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') diff --git a/lua/render-markdown/health.lua b/lua/render-markdown/health.lua index 796b49d..8b11aed 100644 --- a/lua/render-markdown/health.lua +++ b/lua/render-markdown/health.lua @@ -1,10 +1,9 @@ -local md = require('render-markdown') local state = require('render-markdown.state') local M = {} function M.check() - local latex_advice = 'If you do not want LaTeX support avoid this warning by setting { latex_enabled = false }' + local latex_advice = 'Disable LaTeX support to avoid this warning by setting { latex = { enabled = false } }' vim.health.start('markdown.nvim [nvim-treesitter]') local ok = pcall(require, 'nvim-treesitter') @@ -13,7 +12,7 @@ function M.check() M.check_parser('markdown') M.check_parser('markdown_inline') - if state.config.latex_enabled then + if state.config.latex.enabled then M.check_parser('latex', latex_advice) end @@ -28,8 +27,8 @@ function M.check() end vim.health.start('markdown.nvim [executables]') - if state.config.latex_enabled then - M.check_executable(state.config.latex_converter, latex_advice) + if state.config.latex.enabled then + M.check_executable(state.config.latex.converter, latex_advice) else vim.health.ok('none to check') end @@ -111,41 +110,83 @@ function M.check_config(config) end append_errors(nil, { - start_enabled = { config.start_enabled, 'boolean' }, - latex_enabled = { config.latex_enabled, 'boolean' }, + enabled = { config.enabled, 'boolean' }, max_file_size = { config.max_file_size, 'number' }, markdown_query = { config.markdown_query, 'string' }, markdown_quote_query = { config.markdown_quote_query, 'string' }, inline_query = { config.inline_query, 'string' }, - latex_converter = { config.latex_converter, 'string' }, log_level = one_of(config.log_level, { 'debug', 'error' }), file_types = { config.file_types, 'table' }, render_modes = { config.render_modes, 'table' }, - headings = { config.headings, 'table' }, - dash = { config.dash, 'string' }, - bullets = { config.bullets, 'table' }, + latex = { config.latex, 'table' }, + heading = { config.heading, 'table' }, + code = { config.code, 'table' }, + dash = { config.dash, 'table' }, + bullet = { config.bullet, 'table' }, + pipe_table = { config.pipe_table, 'table' }, checkbox = { config.checkbox, 'table' }, - quote = { config.quote, 'string' }, + quote = { config.quote, 'table' }, callout = { config.callout, 'table' }, win_options = { config.win_options, 'table' }, - code_style = one_of(config.code_style, { 'full', 'normal', 'none' }), - table_style = one_of(config.table_style, { 'full', 'normal', 'none' }), - cell_style = one_of(config.cell_style, { 'overlay', 'raw' }), custom_handlers = { config.custom_handlers, 'table' }, - highlights = { config.highlights, 'table' }, }) all_strings('file_types', config.file_types) all_strings('render_modes', config.render_modes) - all_strings('headings', config.headings) - all_strings('bullets', config.bullets) + local latex = config.latex + append_errors('latex', { + enabled = { latex.enabled, 'boolean' }, + converter = { latex.converter, 'string' }, + highlight = { latex.highlight, 'string' }, + }) + + local heading = config.heading + append_errors('heading', { + icons = { heading.icons, 'table' }, + backgrounds = { heading.backgrounds, 'table' }, + foregrounds = { heading.foregrounds, 'table' }, + }) + all_strings('heading.icons', heading.icons) + all_strings('heading.backgrounds', heading.backgrounds) + all_strings('heading.foregrounds', heading.foregrounds) + + local code = config.code + append_errors('code', { + style = one_of(code.style, { 'full', 'normal', 'none' }), + highlight = { code.highlight, 'string' }, + }) + + local dash = config.dash + append_errors('dash', { + icon = { dash.icon, 'string' }, + highlight = { dash.highlight, 'string' }, + }) + + local bullet = config.bullet + append_errors('bullet', { + icons = { bullet.icons, 'table' }, + highlight = { bullet.highlight, 'string' }, + }) + all_strings('bullet.icons', bullet.icons) + + local checkbox = config.checkbox append_errors('checkbox', { - unchecked = { config.checkbox.unchecked, 'string' }, - checked = { config.checkbox.checked, 'string' }, - custom = { config.checkbox.custom, 'table' }, + unchecked = { checkbox.unchecked, 'table' }, + checked = { checkbox.checked, 'table' }, + custom = { checkbox.custom, 'table' }, }) - for name, component in pairs(config.checkbox.custom) do + local unchecked = checkbox.unchecked + append_errors('checkbox.unchecked', { + icon = { unchecked.icon, 'string' }, + highlight = { unchecked.highlight, 'string' }, + }) + local checked = checkbox.checked + append_errors('checkbox.checked', { + icon = { checked.icon, 'string' }, + highlight = { checked.highlight, 'string' }, + }) + for name, component in pairs(checkbox.custom) do append_errors('checkbox.custom.' .. name, { raw = { component.raw, 'string' }, rendered = { component.rendered, 'string' }, @@ -153,16 +194,22 @@ function M.check_config(config) }) end - append_errors('callout', { - note = { config.callout.note, 'string' }, - tip = { config.callout.tip, 'string' }, - important = { config.callout.important, 'string' }, - warning = { config.callout.warning, 'string' }, - caution = { config.callout.caution, 'string' }, - custom = { config.callout.custom, 'table' }, + local quote = config.quote + append_errors('quote', { + icon = { quote.icon, 'string' }, + highlight = { quote.highlight, 'string' }, + }) + + local pipe_table = config.pipe_table + append_errors('pipe_table', { + style = one_of(pipe_table.style, { 'full', 'normal', 'none' }), + cell = one_of(pipe_table.cell, { 'overlay', 'raw' }), + head = { pipe_table.head, 'string' }, + row = { pipe_table.row, 'string' }, }) - for name, component in pairs(config.callout.custom) do - append_errors('callout.custom.' .. name, { + + for name, component in pairs(config.callout) do + append_errors('callout.' .. name, { raw = { component.raw, 'string' }, rendered = { component.rendered, 'string' }, highlight = { component.highlight, 'string' }, @@ -183,43 +230,6 @@ function M.check_config(config) }) end - append_errors('highlights', { - heading = { config.highlights.heading, 'table' }, - dash = { config.highlights.dash, 'string' }, - code = { config.highlights.code, 'string' }, - bullet = { config.highlights.bullet, 'string' }, - checkbox = { config.highlights.checkbox, 'table' }, - table = { config.highlights.table, 'table' }, - latex = { config.highlights.latex, 'string' }, - quote = { config.highlights.quote, 'string' }, - callout = { config.highlights.callout, 'table' }, - }) - - append_errors('highlights.heading', { - backgrounds = { config.highlights.heading.backgrounds, 'table' }, - foregrounds = { config.highlights.heading.foregrounds, 'table' }, - }) - all_strings('highlights.heading.backgrounds', config.highlights.heading.backgrounds) - all_strings('highlights.heading.foregrounds', config.highlights.heading.foregrounds) - - append_errors('highlights.checkbox', { - unchecked = { config.highlights.checkbox.unchecked, 'string' }, - checked = { config.highlights.checkbox.checked, 'string' }, - }) - - append_errors('highlights.table', { - head = { config.highlights.table.head, 'string' }, - row = { config.highlights.table.row, 'string' }, - }) - - append_errors('highlights.callout', { - note = { config.highlights.callout.note, 'string' }, - tip = { config.highlights.callout.tip, 'string' }, - important = { config.highlights.callout.important, 'string' }, - warning = { config.highlights.callout.warning, 'string' }, - caution = { config.highlights.callout.caution, 'string' }, - }) - return errors end diff --git a/lua/render-markdown/init.lua b/lua/render-markdown/init.lua index e4b76d4..274bb78 100644 --- a/lua/render-markdown/init.lua +++ b/lua/render-markdown/init.lua @@ -3,36 +3,6 @@ local state = require('render-markdown.state') local M = {} ----@class render.md.UserCalloutHighlights ----@field public note? string ----@field public tip? string ----@field public important? string ----@field public warning? string ----@field public caution? string - ----@class render.md.UserTableHighlights ----@field public head? string ----@field public row? string - ----@class render.md.UserCheckboxHighlights ----@field public unchecked? string ----@field public checked? string - ----@class render.md.UserHeadingHighlights ----@field public backgrounds? string[] ----@field public foregrounds? string[] - ----@class render.md.UserHighlights ----@field public heading? render.md.UserHeadingHighlights ----@field public dash? string ----@field public code? string ----@field public bullet? string ----@field public checkbox? render.md.UserCheckboxHighlights ----@field public table? render.md.UserTableHighlights ----@field public latex? string ----@field public quote? string ----@field public callout? render.md.UserCalloutHighlights - ---@class render.md.Handler ---@field public render fun(namespace: integer, root: TSNode, buf: integer) ---@field public extends? boolean @@ -41,54 +11,69 @@ local M = {} ---@field public default any ---@field public rendered any ----@class render.md.CustomComponent ----@field public raw string ----@field public rendered string ----@field public highlight string +---@class render.md.UserPipeTable +---@field public style? 'full'|'normal'|'none' +---@field public cell? 'overlay'|'raw' +---@field public head? string +---@field public row? string ----@class render.md.UserCallout ----@field public note? string ----@field public tip? string ----@field public important? string ----@field public warning? string ----@field public caution? string ----@field public custom? table +---@class render.md.UserCustomComponent +---@field public raw? string +---@field public rendered? string +---@field public highlight? string ---@class render.md.UserCheckbox ----@field public unchecked? string ----@field public checked? string +---@field public unchecked? render.md.UserBasicComponent +---@field public checked? render.md.UserBasicComponent ---@field public custom? table +---@class render.md.UserBullet +---@field public icons? string[] +---@field public highlight? string + +---@class render.md.UserBasicComponent +---@field public icon? string +---@field public highlight? string + +---@class render.md.UserCode +---@field public style? 'full'|'normal'|'none' +---@field public highlight? string + +---@class render.md.UserHeading +---@field public icons? string[] +---@field public backgrounds? string[] +---@field public foregrounds? string[] + +---@class render.md.UserLatex +---@field public enabled? boolean +---@field public converter? string +---@field public highlight? string + ---@class render.md.UserConfig ----@field public start_enabled? boolean ----@field public latex_enabled? boolean +---@field public enabled? boolean ---@field public max_file_size? number ---@field public markdown_query? string ---@field public markdown_quote_query? string ---@field public inline_query? string ----@field public latex_converter? string ---@field public log_level? 'debug'|'error' ---@field public file_types? string[] ---@field public render_modes? string[] ----@field public headings? string[] ----@field public dash? string ----@field public bullets? string[] +---@field public latex? render.md.UserLatex +---@field public heading? render.md.UserHeading +---@field public code? render.md.UserCode +---@field public dash? render.md.UserBasicComponent +---@field public bullet? render.md.UserBullet ---@field public checkbox? render.md.UserCheckbox ----@field public quote? string ----@field public callout? render.md.UserCallout +---@field public quote? render.md.UserBasicComponent +---@field public pipe_table? render.md.UserPipeTable +---@field public callout? table ---@field public win_options? table ----@field public code_style? 'full'|'normal'|'none' ----@field public table_style? 'full'|'normal'|'none' ----@field public cell_style? 'overlay'|'raw' ---@field public custom_handlers? table ----@field public highlights? render.md.UserHighlights ---@type render.md.Config M.default_config = { -- Whether Markdown should be rendered by default or not - start_enabled = true, - -- Whether LaTeX should be rendered, mainly used for health check - latex_enabled = true, + enabled = true, -- Maximum file size (in MB) that this plugin will attempt to render -- Any file larger than this will effectively be ignored max_file_size = 1.5, @@ -137,8 +122,6 @@ M.default_config = { (shortcut_link) @callout ]], - -- Executable used to convert latex formula to rendered unicode - latex_converter = 'latex2text', -- The level of logs to write to file: vim.fn.stdpath('state') .. '/render-markdown.log' -- Only intended to be used for plugin development / debugging log_level = 'error', @@ -147,34 +130,112 @@ M.default_config = { -- Vim modes that will show a rendered view of the markdown file -- All other modes will be uneffected by this plugin render_modes = { 'n', 'c' }, - -- Characters that will replace the # at the start of headings - headings = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, - -- Character to use for the horizontal break - dash = '─', - -- Character to use for the bullet points in lists - bullets = { '●', '○', '◆', '◇' }, + latex = { + -- Whether LaTeX should be rendered, mainly used for health check + enabled = true, + -- Executable used to convert latex formula to rendered unicode + converter = 'latex2text', + -- Highlight for LaTeX blocks + highlight = '@markup.math', + }, + heading = { + -- Replaces '#+' of 'atx_h._marker' + -- The number of '#' in the heading determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- The result is left padded with spaces to hide any additional '#' + icons = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon and extends through the entire line + backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, + -- The 'level' is used to index into the array using a clamp + -- Highlight for the heading icon only + foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, + }, + code = { + -- Determines how code blocks are rendered: + -- none: disables all rendering + -- normal: adds highlight group to the code block + -- full: normal + language icon & name above the code block + style = 'full', + -- Highlight for code blocks + highlight = 'ColorColumn', + }, + dash = { + -- Replaces '---'|'***'|'___'|'* * *' of 'thematic_break' + -- The icon gets repeated across the window's width + icon = '─', + -- Highlight for the whole line generated from the icon + highlight = 'LineNr', + }, + bullet = { + -- Replaces '-'|'+'|'*' of 'list_item' + -- How deeply nested the list is determines the 'level' + -- The 'level' is used to index into the array using a cycle + -- If the item is a 'checkbox' a conceal is used to hide the bullet instead + icons = { '●', '○', '◆', '◇' }, + -- Highlight for the bullet icon + highlight = 'Normal', + }, + -- Checkboxes are a special instance of a 'list_item' that start with a 'shortcut_link' + -- There are two special states for unchecked & checked defined in the markdown grammar checkbox = { - -- Character that will replace the [ ] in unchecked checkboxes - unchecked = '󰄱 ', - -- Character that will replace the [x] in checked checkboxes - checked = '󰱒 ', - -- Specify custom checkboxes, must be surrounded in square brackets + unchecked = { + -- Replaces '[ ]' of 'task_list_marker_unchecked' + icon = '󰄱 ', + -- Highlight for the unchecked icon + highlight = '@markup.list.unchecked', + }, + checked = { + -- Replaces '[x]' of 'task_list_marker_checked' + icon = '󰱒 ', + -- Highligh for the checked icon + highlight = '@markup.heading', + }, + -- Define custom checkbox states, more involved as they are not part of the markdown grammar + -- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks + -- Can specify as many additional states as you like following the 'todo' pattern below + -- The key in this case 'todo' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' icon custom = { todo = { raw = '[-]', rendered = '󰥔 ', highlight = '@markup.raw' }, }, }, - -- Character that will replace the > at the start of block quotes - quote = '▋', - -- Symbol / text to use for different callouts + quote = { + -- Replaces '>' of 'block_quote' + icon = '▋', + -- Highlight for the quote icon + highlight = '@markup.quote', + }, + pipe_table = { + -- Determines how the table as a whole is rendered: + -- none: disables all rendering + -- normal: applies the 'cell' style rendering to each row of the table + -- full: normal + a top & bottom line that fill out the table when lengths match + style = 'full', + -- Determines how individual cells of a table are rendered: + -- overlay: writes completely over the table, removing conceal behavior and highlights + -- raw: replaces only the '|' characters in each row, leaving the cells completely unmodified + cell = 'overlay', + -- Highlight for table heading, delimitter, and the line above + head = '@markup.heading', + -- Highlight for everything else, main table rows and the line below + row = 'Normal', + }, + -- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link' + -- Can specify as many additional values as you like following the pattern from any below, such as 'note' + -- The key in this case 'note' is for healthcheck and to allow users to change its values + -- 'raw': Matched against the raw text of a 'shortcut_link' + -- 'rendered': Replaces the 'raw' value when rendering + -- 'highlight': Highlight for the 'rendered' text and quote markers callout = { - note = '󰋽 Note', - tip = '󰌶 Tip', - important = '󰅾 Important', - warning = '󰀪 Warning', - caution = '󰳦 Caution', - custom = { - bug = { raw = '[!BUG]', rendered = '󰨰 Bug', highlight = 'DiagnosticError' }, - }, + note = { raw = '[!NOTE]', rendered = '󰋽 Note', highlight = 'DiagnosticInfo' }, + tip = { raw = '[!TIP]', rendered = '󰌶 Tip', highlight = 'DiagnosticOk' }, + important = { raw = '[!IMPORTANT]', rendered = '󰅾 Important', highlight = 'DiagnosticHint' }, + warning = { raw = '[!WARNING]', rendered = '󰀪 Warning', highlight = 'DiagnosticWarn' }, + caution = { raw = '[!CAUTION]', rendered = '󰳦 Caution', highlight = 'DiagnosticError' }, + bug = { raw = '[!BUG]', rendered = '󰨰 Bug', highlight = 'DiagnosticError' }, }, -- Window options to use that change between rendered and raw view win_options = { @@ -193,68 +254,15 @@ M.default_config = { rendered = 'nvic', }, }, - -- Determines how code blocks are rendered - -- full: adds language icon above code block if possible + normal behavior - -- normal: renders a background - -- none: disables rendering - code_style = 'full', - -- Determines how tables are rendered - -- full: adds a line above and below tables + normal behavior - -- normal: renders the rows of tables - -- none: disables rendering - table_style = 'full', - -- Determines how table cells are rendered - -- overlay: writes over the top of cells removing conealing and highlighting - -- raw: will leave the cells as they and only replace table related symbols - cell_style = 'overlay', -- Mapping from treesitter language to user defined handlers - -- See 'Custom Handlers' section for more info + -- See 'Custom Handlers' document for more info custom_handlers = {}, - -- Define the highlight groups to use when rendering various components - highlights = { - heading = { - -- Background of heading line - backgrounds = { 'DiffAdd', 'DiffChange', 'DiffDelete' }, - -- Foreground of heading character only - foregrounds = { 'markdownH1', 'markdownH2', 'markdownH3', 'markdownH4', 'markdownH5', 'markdownH6' }, - }, - -- Horizontal break - dash = 'LineNr', - -- Code blocks - code = 'ColorColumn', - -- Bullet points in list - bullet = 'Normal', - checkbox = { - -- Unchecked checkboxes - unchecked = '@markup.list.unchecked', - -- Checked checkboxes - checked = '@markup.heading', - }, - table = { - -- Header of a markdown table - head = '@markup.heading', - -- Non header rows in a markdown table - row = 'Normal', - }, - -- LaTeX blocks - latex = '@markup.math', - -- Quote character in a block quote - quote = '@markup.quote', - -- Highlights to use for different callouts - callout = { - note = 'DiagnosticInfo', - tip = 'DiagnosticOk', - important = 'DiagnosticHint', - warning = 'DiagnosticWarn', - caution = 'DiagnosticError', - }, - }, } ---@param opts? render.md.UserConfig function M.setup(opts) state.config = vim.tbl_deep_extend('force', M.default_config, opts or {}) - state.enabled = state.config.start_enabled + state.enabled = state.config.enabled vim.schedule(function() state.markdown_query = vim.treesitter.query.parse('markdown', state.config.markdown_query) state.markdown_quote_query = vim.treesitter.query.parse('markdown', state.config.markdown_quote_query) diff --git a/lua/render-markdown/list.lua b/lua/render-markdown/list.lua index 193c64a..de9494d 100644 --- a/lua/render-markdown/list.lua +++ b/lua/render-markdown/list.lua @@ -10,7 +10,7 @@ end ---@param values string[] ---@param index integer ---@return string -function M.clamp_last(values, index) +function M.clamp(values, index) return values[math.min(index, #values)] end diff --git a/lua/render-markdown/types.lua b/lua/render-markdown/types.lua index 172899d..5cd9653 100644 --- a/lua/render-markdown/types.lua +++ b/lua/render-markdown/types.lua @@ -1,66 +1,58 @@ ----@class render.md.CalloutHighlights ----@field public note string ----@field public tip string ----@field public important string ----@field public warning string ----@field public caution string - ----@class render.md.TableHighlights +---@class render.md.PipeTable +---@field public style 'full'|'normal'|'none' +---@field public cell 'overlay'|'raw' ---@field public head string ---@field public row string ----@class render.md.CheckboxHighlights ----@field public unchecked string ----@field public checked string +---@class render.md.CustomComponent +---@field public raw string +---@field public rendered string +---@field public highlight string ----@class render.md.HeadingHighlights ----@field public backgrounds string[] ----@field public foregrounds string[] +---@class render.md.Checkbox +---@field public unchecked render.md.BasicComponent +---@field public checked render.md.BasicComponent +---@field public custom table ----@class render.md.Highlights ----@field public heading render.md.HeadingHighlights ----@field public dash string ----@field public code string ----@field public bullet string ----@field public checkbox render.md.CheckboxHighlights ----@field public table render.md.TableHighlights ----@field public latex string ----@field public quote string ----@field public callout render.md.CalloutHighlights +---@class render.md.Bullet +---@field public icons string[] +---@field public highlight string ----@class render.md.Callout ----@field public note string ----@field public tip string ----@field public important string ----@field public warning string ----@field public caution string ----@field public custom table +---@class render.md.BasicComponent +---@field public icon string +---@field public highlight string ----@class render.md.Checkbox ----@field public unchecked string ----@field public checked string ----@field public custom table +---@class render.md.Code +---@field public style 'full'|'normal'|'none' +---@field public highlight string + +---@class render.md.Heading +---@field public icons string[] +---@field public backgrounds string[] +---@field public foregrounds string[] + +---@class render.md.Latex +---@field public enabled boolean +---@field public converter string +---@field public highlight string ---@class render.md.Config ----@field public start_enabled boolean ----@field public latex_enabled boolean +---@field public enabled boolean ---@field public max_file_size number ---@field public markdown_query string ---@field public markdown_quote_query string ---@field public inline_query string ----@field public latex_converter string ---@field public log_level 'debug'|'error' ---@field public file_types string[] ---@field public render_modes string[] ----@field public headings string[] ----@field public dash string ----@field public bullets string[] +---@field public latex render.md.Latex +---@field public heading render.md.Heading +---@field public code render.md.Code +---@field public dash render.md.BasicComponent +---@field public bullet render.md.Bullet ---@field public checkbox render.md.Checkbox ----@field public quote string ----@field public callout render.md.Callout +---@field public quote render.md.BasicComponent +---@field public pipe_table render.md.PipeTable +---@field public callout table ---@field public win_options table ----@field public code_style 'full'|'normal'|'none' ----@field public table_style 'full'|'normal'|'none' ----@field public cell_style 'overlay'|'raw' ---@field public custom_handlers table ----@field public highlights render.md.Highlights diff --git a/scripts/update.py b/scripts/update.py index fbf8929..ef335f8 100644 --- a/scripts/update.py +++ b/scripts/update.py @@ -10,20 +10,25 @@ class LuaClass: fields: list[str] def validate(self) -> None: + for field in self.fields: + if "User" in self.name: + self.validate_user_field(field) + else: + self.validate_non_user_field(field) + + def validate_user_field(self, field: str) -> None: + # User classes are expected to have optional fields + assert "?" in field, f"Field must be optional: {field}" + + def validate_non_user_field(self, field: str) -> None: + # Non user classes are expected to have mandatory fields with some exceptions + optional: bool = False optional_fields: list[str] = ["extends"] if "Handler" in self.name else [] - if "User" in self.name: - # User classes are expected to have optional fields - for field in self.fields: - assert "?" in field, f"Field must be optional: {field}" - else: - # Non user classes are expected to have mandatory fields with some exceptions - for field in self.fields: - optional: bool = False - for optional_field in optional_fields: - if optional_field in field: - optional = True - if not optional: - assert "?" not in field, f"Field must be mandatory: {field}" + for optional_field in optional_fields: + if optional_field in field: + optional = True + if not optional: + assert "?" not in field, f"Field must be mandatory: {field}" def to_public_lines(self) -> list[str]: if "User" not in self.name: @@ -60,17 +65,27 @@ def update_types(init_file: Path, types_file: Path) -> None: def update_readme(init_file: Path, readme_file: Path) -> None: - old = get_code_block(readme_file, "enabled") - default_config = get_default_config(init_file) - new = "require('render-markdown').setup(" + default_config + ")" - readme_file.write_text(readme_file.read_text().replace(old, new)) + old_config = get_code_block(readme_file, "enabled", 1) + new_config = wrap_setup(get_default_config(init_file)) + text = readme_file.read_text().replace(old_config, new_config) + + parameters: list[str] = ["heading", "code", "dash", "bullet"] + parameters.extend(["checkbox", "quote", "pipe_table", "callout"]) + for parameter in parameters: + parameter = f"{parameter} = " + old_param = get_code_block(readme_file, parameter, 2) + new_param = wrap_setup(get_config_for(new_config, parameter)) + text = text.replace(old_param, new_param) + + readme_file.write_text(text) def update_custom_handlers(init_file: Path, handler_file: Path) -> None: class_name: str = "render.md.Handler" - old = get_code_block(handler_file, class_name) + old = get_code_block(handler_file, class_name, 1) new = get_class(init_file, class_name).to_str() - handler_file.write_text(handler_file.read_text().replace(old, new)) + text = handler_file.read_text().replace(old, new) + handler_file.write_text(text) def get_class(init_file: Path, name: str) -> LuaClass: @@ -96,6 +111,36 @@ def get_classes(init_file: Path) -> list[LuaClass]: return lua_classes +def wrap_setup(value: str) -> str: + return f"require('render-markdown').setup({value})" + + +def get_config_for(config: str, parameter: str) -> str: + lines: list[str] = config.splitlines() + param_start: int | None = None + for i, line in enumerate(lines): + if parameter in line: + param_start = i + break + assert param_start is not None + + start_line: int = param_start + for i in range(param_start - 1, 0, -1): + if "--" not in lines[i]: + start_line = i + 1 + break + + end_line: int = param_start + level: int = 0 + for i in range(param_start, len(lines)): + level += lines[i].count("{") - lines[i].count("}") + if level == 0: + end_line = i + break + + return "\n".join(["{"] + lines[start_line : end_line + 1] + ["}"]) + + def get_comments(file: Path) -> list[str]: query = "(comment) @comment" return ts_query(file, query, "comment") @@ -116,12 +161,12 @@ def get_default_config(file: Path) -> str: return default_configs[0] -def get_code_block(file: Path, content: str) -> str: +def get_code_block(file: Path, content: str, n: int) -> str: query = "(code_fence_content) @content" code_blocks = ts_query(file, query, "content") code_blocks = [code for code in code_blocks if content in code] - assert len(code_blocks) == 1 - return code_blocks[0] + assert len(code_blocks) == n + return code_blocks[n - 1] def ts_query(file: Path, query: str, target: str) -> list[str]: diff --git a/tests/table_spec.lua b/tests/table_spec.lua index c939c52..668fa80 100644 --- a/tests/table_spec.lua +++ b/tests/table_spec.lua @@ -124,7 +124,7 @@ async_tests.describe('table.md', function() end) async_tests.it('raw', function() - util.setup('tests/data/table.md', { cell_style = 'raw' }) + util.setup('tests/data/table.md', { pipe_table = { cell = 'raw' } }) local expected = {}