Skip to content

Commit

Permalink
Add script to update state config type and README default config from…
Browse files Browse the repository at this point in the history
… init.lua

# Details

Currently any time an argument is added to the configuration, it
needs to replicated in 3 places:
- `init.lua` with the user config classes and default configuration
- `state.lua` with non optional main config
- `README.md` with the updated default config

This is mildly annoying and error prone.

Instead use `init.lua` as our source of truth and replicate this
information to `state.lua` and `README.md`. Logic is contained
in `scripts/update.py` and can be executed with `just update`.

To make this easier 2 other changes were made:
- Rather than storing the config classes like `render.md.Config`
  in `state.lua` move this to a new module `types.lua`. By doing
  this we avoid needing special handling for the other information
  contained in `state.lua` and instead can fully overwrite `types.lua`.
- Add comments on default config currently only in `README.md` to
  the config in `init.lua`, that way when the configuration is pulled
  the comments get included as well with no special logic.
  • Loading branch information
MeanderingProgrammer committed May 31, 2024
1 parent c1d9edc commit d1cd854
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 56 deletions.
3 changes: 3 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ demo zoom=default_zoom:
--last-frame-duration 1
rm demo.cast

update:
python -Wignore scripts/update.py

gen-doc:
# https://github.com/kdheepak/panvimdoc
# https://pandoc.org/
Expand Down
37 changes: 37 additions & 0 deletions lua/render-markdown/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,12 @@ local M = {}
function M.setup(opts)
---@type render.md.Config
local default_config = {
-- Configure whether Markdown should be rendered by default or not
start_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,
-- Capture groups that get pulled from markdown
markdown_query = [[
(atx_heading [
(atx_h1_marker)
Expand Down Expand Up @@ -97,37 +101,60 @@ function M.setup(opts)
(pipe_table_delimiter_row) @table_delim
(pipe_table_row) @table_row
]],
-- Capture groups that get pulled from inline markdown
inline_query = [[
(code_span) @code
(shortcut_link) @callout
]],
-- 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',
-- Filetypes this plugin will run on
file_types = { 'markdown' },
-- 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 = { '', '', '', '' },
checkbox = {
-- Character that will replace the [ ] in unchecked checkboxes
unchecked = '󰄱 ',
-- Character that will replace the [x] in checked checkboxes
checked = '',
},
-- Character that will replace the > at the start of block quotes
quote = '',
-- Symbol / text to use for different callouts
callout = {
note = ' Note',
tip = ' Tip',
important = '󰅾 Important',
warning = ' Warning',
caution = '󰳦 Caution',
},
-- See :h 'conceallevel' for more information about meaning of values
conceal = {
-- conceallevel used for buffer when not being rendered, get user setting
default = vim.opt.conceallevel:get(),
-- conceallevel used for buffer when being rendered
rendered = 3,
},
-- Determines how tables are rendered
-- full: adds a line above and below tables + normal behavior
-- normal: renders the rows of tables
-- none: disables rendering, use this if you prefer having cell highlights
table_style = 'full',
-- 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',
Expand All @@ -137,19 +164,29 @@ function M.setup(opts)
'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',
Expand Down
56 changes: 0 additions & 56 deletions lua/render-markdown/state.lua
Original file line number Diff line number Diff line change
@@ -1,59 +1,3 @@
---@class render.md.Callout
---@field public note string
---@field public tip string
---@field public important string
---@field public warning string
---@field public caution string

---@class render.md.TableHighlights
---@field public head string
---@field public row string

---@class render.md.CheckboxHighlights
---@field public unchecked string
---@field public checked string

---@class render.md.HeadingHighlights
---@field public backgrounds string[]
---@field public foregrounds string[]

---@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.Callout

---@class render.md.Conceal
---@field public default integer
---@field public rendered integer

---@class render.md.Checkbox
---@field public unchecked string
---@field public checked string

---@class render.md.Config
---@field public start_enabled boolean
---@field public max_file_size number
---@field public markdown_query string
---@field public inline_query 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 checkbox render.md.Checkbox
---@field public quote string
---@field public callout render.md.Callout
---@field public conceal render.md.Conceal
---@field public table_style 'full'|'normal'|'none'
---@field public highlights render.md.Highlights

---@class render.md.State
---@field config render.md.Config
---@field enabled boolean
Expand Down
55 changes: 55 additions & 0 deletions lua/render-markdown/types.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---@class render.md.Callout
---@field public note string
---@field public tip string
---@field public important string
---@field public warning string
---@field public caution string

---@class render.md.TableHighlights
---@field public head string
---@field public row string

---@class render.md.CheckboxHighlights
---@field public unchecked string
---@field public checked string

---@class render.md.HeadingHighlights
---@field public backgrounds string[]
---@field public foregrounds string[]

---@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.Callout

---@class render.md.Conceal
---@field public default integer
---@field public rendered integer

---@class render.md.Checkbox
---@field public unchecked string
---@field public checked string

---@class render.md.Config
---@field public start_enabled boolean
---@field public max_file_size number
---@field public markdown_query string
---@field public inline_query 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 checkbox render.md.Checkbox
---@field public quote string
---@field public callout render.md.Callout
---@field public conceal render.md.Conceal
---@field public table_style 'full'|'normal'|'none'
---@field public highlights render.md.Highlights
2 changes: 2 additions & 0 deletions scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tree_sitter==0.21.3
tree_sitter_languages==1.10.2
92 changes: 92 additions & 0 deletions scripts/update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from pathlib import Path
from textwrap import dedent

from tree_sitter_languages import get_language, get_parser


def main() -> None:
init_file: Path = Path("lua/render-markdown/init.lua")
update_types(init_file)
update_readme(init_file)


def update_types(init_file: Path) -> None:
lines: list[str] = []
for comment in get_comments(init_file):
comment_type: str = comment.split()[0].split("@")[-1]
if comment_type in ["class", "field"]:
comment = comment.replace("User", "")
if comment_type == "field":
assert "?" in comment, f"All fields must be optional: {comment}"
comment = comment.replace("?", "")
if comment_type == "class" and len(lines) > 0:
lines.append("")
lines.append(comment)
lines.append("")

types_file: Path = Path("lua/render-markdown/types.lua")
types_file.write_text("\n".join(lines))


def update_readme(init_file: Path) -> None:
default_config = get_default_config(init_file)
new_config = " require('render-markdown').setup(" + default_config + ")"
new_config = dedent(new_config)

readme_file = Path("README.md")
current_config = get_readme_config(readme_file)

text = readme_file.read_text()
text = text.replace(current_config, new_config)
readme_file.write_text(text)


def get_comments(file: Path) -> list[str]:
query = "(comment) @comment"
return ts_query(file, query, "comment")


def get_default_config(file: Path) -> str:
query = """
(local_variable_declaration(
(variable_list(
variable name: (identifier) @name
(#eq? @name "default_config")
))
(expression_list value: (table)) @value
))
"""
default_configs = ts_query(file, query, "value")
assert len(default_configs) == 1
return default_configs[0]


def get_readme_config(file: Path) -> str:
query = "(code_fence_content) @content"
code_blocks = ts_query(file, query, "content")
query_code_blocks = [code for code in code_blocks if "query" in code]
assert len(query_code_blocks) == 1
return query_code_blocks[0]


def ts_query(file: Path, query_string: str, target: str) -> list[str]:
ts_language: str = {
".lua": "lua",
".md": "markdown",
}[file.suffix]
parser = get_parser(ts_language)
tree = parser.parse(file.read_text().encode())

language = get_language(ts_language)
query = language.query(query_string)
captures = query.captures(tree.root_node)

values: list[str] = []
for node, capture in captures:
if capture == target:
values.append(node.text.decode())
return values


if __name__ == "__main__":
main()

0 comments on commit d1cd854

Please sign in to comment.