1
0
Fork 0
dot/.config/vis/lexers/markdown.lua

109 lines
3.5 KiB
Lua
Raw Normal View History

-- Adapted from Markdown LPeg lexer by Mitchell to simplify and lex some pandoc
-- specifics.
2024-07-31 12:05:39 +02:00
local lexer = lexer
local P, S, B = lpeg.P, lpeg.S, lpeg.B
local lex = lexer.new(..., {no_user_word_lists = true})
-- Heading.
lex:add_rule('heading',
lex:tag(lexer.COMMENT, lexer.starts_line(P('#')^-6)) *
P(' ') *
2024-10-23 18:57:09 +02:00
lex:tag(lexer.HEADING, lexer.to_eol(lexer.any) * #P('\n\n')))
-- List.
lex:add_rule('list',
lex:tag(lexer.COMMENT, lexer.starts_line(P(S('-*') * ' ') + P('(@' * P(lexer.alnum + S('-_'))^0 * ')' + S(' \n')), true)))
2024-07-31 12:05:39 +02:00
-- Blockquote.
2024-10-23 18:57:09 +02:00
lex:add_rule('block_quote',
lex:tag(lexer.COMMENT,
2024-10-23 18:57:09 +02:00
lexer.starts_line(P('>' + P(' '))^1, true)))
2024-07-31 12:05:39 +02:00
-- Horizontal rule.
lex:add_rule('hr',
2024-10-23 18:57:09 +02:00
lex:tag(lexer.COMMENT, B('\n\n') * S('*-_')^3 * #P('\n\n')))
2024-07-31 12:05:39 +02:00
-- Native div.
lex:add_rule("native_div",
lex:tag(lexer.COMMENT, lexer.starts_line(lexer.to_eol(P(':')^3))))
2024-07-31 12:05:39 +02:00
-- Code block.
2024-10-23 18:57:09 +02:00
lex:add_rule("block_code",
lex:tag(lexer.COMMENT,
lexer.starts_line('~~~' + P('```'))))
2024-07-31 12:05:39 +02:00
-- Escape.
lex:add_rule('escape', lex:tag(lexer.DEFAULT, P('\\') * 1))
-- Bracket.
lex:add_rule('brackets',
lex:tag(lexer.COMMENT, S('[]')))
-- Native span.
lex:add_rule('native_span',
B(']') * lex:tag(lexer.COMMENT, lexer.range('{', '}')))
2024-07-31 12:05:39 +02:00
-- Footnote.
lex:add_rule('footnote_key',
lex:tag(lexer.REFERENCE, P('^')) * #P('[') +
B('[') * lex:tag(lexer.REFERENCE, P('^') * (lexer.any - lexer.space - S('^[]'))^1) * #P(']'))
-- @todo footnote reference
-- Cite.
2024-07-31 12:05:39 +02:00
lex:add_rule('cite_key',
B(lexer.space + P('[')) * lex:tag(lexer.REFERENCE,
P('-')^-1 *
(P('@') * (lexer.alnum + P('_')) * (lexer.alnum + S(':.#$%&-+?<>~/'))^0 +
P('@') * lexer.range('{', '}'))))
2024-07-31 12:05:39 +02:00
-- Link.
lex:add_rule('link_text',
B('[') * lex:tag(lexer.LINK, (lexer.any - P(']'))^1) * #P(']' * lexer.range('(', ')')))
2024-07-31 12:05:39 +02:00
lex:add_rule('link_target',
B(']') * lex:tag(lexer.COMMENT, lexer.range('(', ')')))
-- @todo link reference
2024-07-31 12:05:39 +02:00
-- Image
lex:add_rule('image_bang', lex:tag(lexer.REFERENCE, P('!')) * #P('['))
2024-07-31 12:05:39 +02:00
local punct_space = lexer.punct + lexer.space
-- Handles flanking delimiters as described in
-- https://github.github.com/gfm/#emphasis-and-strong-emphasis in the cases
-- where simple delimited ranges are not sufficient.
local function flanked_range(s, not_inword)
local fl_char = lexer.any - s - lexer.space
local left_fl = B(punct_space - s) * s * #fl_char + s * #(fl_char - lexer.punct)
local right_fl = B(lexer.punct) * s * #(punct_space - s) + B(fl_char) * s
2024-10-23 18:57:09 +02:00
return left_fl * (lexer.any - P('\n\n') - (not_inword and s * #punct_space or s))^0 * right_fl
2024-07-31 12:05:39 +02:00
end
local asterisk_strong = flanked_range('**')
local underscore_strong = (B(punct_space) + #lexer.starts_line('_')) * flanked_range('__', true) * #(punct_space + -1)
lex:add_rule('strong', lex:tag(lexer.BOLD, asterisk_strong + underscore_strong))
local asterisk_em = flanked_range('*')
local underscore_em = (B(punct_space) + #lexer.starts_line('_')) * flanked_range('_', true) * #(punct_space + -1)
lex:add_rule('em', lex:tag(lexer.ITALIC, asterisk_em + underscore_em))
-- Embedded HTML.
local html = lexer.load('html')
local html_start_rule = lexer.starts_line(P(' ')^-3) *
#P('<') *
html:get_rule('tag') +
html:get_rule('comment')
2024-10-23 18:57:09 +02:00
local html_end_rule = #P('\n\n') * lexer.space
2024-07-31 12:05:39 +02:00
lex:embed(html, html_start_rule, html_end_rule)
-- Embedded YAML.
local yaml = lexer.load('yaml')
local doc_bounds_rule = yaml:get_rule('doc_bounds')
local hr_rule = lex:get_rule('hr')
2024-10-23 18:57:09 +02:00
local yaml_start_rule = doc_bounds_rule * P('\n') - hr_rule
local yaml_end_rule = doc_bounds_rule * P('\n') - hr_rule
2024-07-31 12:05:39 +02:00
lex:embed(yaml, yaml_start_rule, yaml_end_rule)
return lex