support expressions and use them for links

This commit is contained in:
kp2pml30 2025-03-21 13:40:31 +04:00
parent b90362a6e8
commit 59b1d6c116
3 changed files with 75 additions and 26 deletions

View file

@ -106,9 +106,13 @@ class HTMLRenderer < YAMD::Renderer
@buf << "</#{name}>"
end
def code(**attrs, &blk)
tag('pre') {
tag('code', **attrs) {
def link(to, &blk)
tag('a', href: to, &blk)
end
def code(&blk)
tag('pre', class: "language-any") {
tag('code', class: "language-any") {
@buf << YAMD::Code::highlight(blk.())
}
}
@ -151,7 +155,7 @@ File.open(options[:in]) { |f|
renderer = HTMLRenderer.new
eval(code).(renderer)
renderer.instance_eval(code)
Pathname.new(options[:out]).write(renderer.finalize)
}

View file

@ -30,19 +30,20 @@ module YAMD
class Output
def initialize()
@buf = String.new
@buf << "Proc.new { |__renderer|\n"
@ind = 1
#@buf << "Proc.new {\n"
@ind = 0
end
def add_static(s)
return if s.empty?
@buf << ("\t" * @ind) << "__renderer.str " << s.dump << "\n"
@buf << ("\t" * @ind) << "str " << s.dump << "\n"
end
def add_expr(e)
@buf << ("\t" * @ind) << "__renderer.str((#{e}).to_s)"
@buf << ("\t" * @ind) << "str((#{e}).to_s)"
end
def add_code_nl(c)
@ -60,7 +61,8 @@ module YAMD
end
def finalize()
@buf << "}"
#@buf << "}"
@buf.freeze
@buf
@ -218,7 +220,7 @@ module YAMD
prevParagraph = true
flushStrBuf.()
state.output.add_code_nl("__renderer.new_line")
state.output.add_code_nl("new_line")
end
state.nextLine
next
@ -246,7 +248,7 @@ module YAMD
flushStrBuf.()
state.consume(2)
state.output.add_code_nl("__renderer." + state.line.strip + " {")
state.output.add_code_nl("" + state.line.strip + " {")
state.nextLine
parseContent(state, ctx.indented)
state.output.add_code_nl("}")
@ -258,7 +260,7 @@ module YAMD
line = state.line.strip
state.nextLine
state.output.add_code_nl("__renderer." + line.strip + " {")
state.output.add_code_nl("" + line.strip + " {")
state.output.add_code_nl("next " + parseRaw(state, ctx.indented).dump)
state.output.add_code_nl("}")
@ -276,7 +278,7 @@ module YAMD
flushStrBuf.()
state.consume(2)
state.output.add_code_nl("__renderer.list_item {")
state.output.add_code_nl("list_item {")
parseContent state, ctx.indented
state.output.add_code_nl("}")
@ -292,6 +294,10 @@ module YAMD
elsif state.line.start_with?('##')
strBuf << '#'
state.consume 2
elsif state.line.start_with?('}#')
flushStrBuf.()
return
elsif state.line[0] == '#'
state.output.add_static(strBuf)
strBuf = String.new
@ -318,7 +324,7 @@ module YAMD
raise "unterminated \#` at #{state.errCtx}"
end
state.consume 1
state.output.add_code_nl("__renderer.inline_code(#{code.dump})")
state.output.add_code_nl("inline_code(#{code.dump})")
elsif state.line.start_with?('#{')
state.consume 2
expr = read_balanced(state, ctx)
@ -336,7 +342,42 @@ module YAMD
end
state.consume 1
state.output.add_code_nl "__renderer.inline_math #{expr.dump}"
state.output.add_code_nl "inline_math #{expr.dump}"
elsif state.line.start_with?(/^\#[a-zA-Z_]/)
exprBuf = String.new
state.consume 1
while not state.line.empty?
if state.line[0] == '('
exprBuf << '('
state.consume 1
exprBuf << read_balanced(state, ctx)
raise "unbalanced () at #{state.errCtx}" if state.line[0] != ')'
state.consume 1
exprBuf << ')'
elsif state.line.start_with?('#{')
state.consume 2
exprBuf << " {"
state.output.add_code_nl(exprBuf)
while state.line[0] == ' '
state.consume 1
end
self.parseContent(state, ctx.indented)
raise "unmatched \#{ }\# at #{state.errCtx}" if not state.line.start_with?('}#')
state.consume 2
state.output.add_code_nl("}")
return
else
exprBuf << state.line[0]
state.consume 1
end
end
state.output.add_code_nl exprBuf
# expression
else
raise "unexpected hash at #{state.errCtx}"
end

View file

@ -17,18 +17,22 @@
require 'erb'
module YAMD::Code
HIGHLIGHTS = {
/\b(?:[A-Z][a-zA-Z\-_0-9]*)\b*/ => 'type',
/#(\s|$)[^\n]*/ => 'comment',
/\b(?:open|final|class|fn|let|var|if|else|while|loop|return|namespace|new)\b/ => 'kw',
/\b(?:null|undefined|true|false|this|self)\b/i => 'const',
/[:,;()\[\]{}<>]/ => 'punct',
/0|(0x[0-9a-fA-F]+)|([1-9][0-9]*(\.[0-9]+)?)/ => 'number',
/"(?:\\.|[^\\"])*"/ => 'str',
/'(?:\\.|[^\\'])*'/ => 'str',
}
module Lang
DEFAULT = {
/\b(?:[A-Z][a-zA-Z\-_0-9]*)\b*/ => 'type',
/#(\s|$)[^\n]*/ => 'comment',
/\b(?:open|final|class|fn|let|var|if|else|while|loop|return|namespace|new)\b/ => 'kw',
/\b(?:def|import|from)\b/ => 'kw',
/\b(?:null|undefined|true|false|this|self)\b/i => 'const',
/\b(?:__[a-zA-Z0-9_]+__)\b/i => 'const',
/[:,;()\[\]{}<>]/ => 'punct',
/0|(0x[0-9a-fA-F]+)|([1-9][0-9]*(\.[0-9]+)?)/ => 'number',
/"(?:\\.|[^\\"])*"/ => 'str',
/'(?:\\.|[^\\'])*'/ => 'str',
}
end
def self.highlight(txt, highlights=HIGHLIGHTS)
def self.highlight(txt, highlights=Lang::DEFAULT)
idx = 0
res = String.new
old_idx = 0