From 59b1d6c11679b198b082b7a79960ad300c3a7274 Mon Sep 17 00:00:00 2001 From: kp2pml30 Date: Fri, 21 Mar 2025 13:40:31 +0400 Subject: [PATCH] support expressions and use them for links --- exe/yamd | 12 ++++++--- lib/yamd.rb | 63 +++++++++++++++++++++++++++++++++++++++--------- lib/yamd/code.rb | 26 +++++++++++--------- 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/exe/yamd b/exe/yamd index f46d622..f43a35a 100755 --- a/exe/yamd +++ b/exe/yamd @@ -106,9 +106,13 @@ class HTMLRenderer < YAMD::Renderer @buf << "" 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) } diff --git a/lib/yamd.rb b/lib/yamd.rb index 0db38b0..82930df 100644 --- a/lib/yamd.rb +++ b/lib/yamd.rb @@ -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 diff --git a/lib/yamd/code.rb b/lib/yamd/code.rb index f4c3ab1..73e666e 100644 --- a/lib/yamd/code.rb +++ b/lib/yamd/code.rb @@ -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