diff options
author | icebaker <icebaker@proton.me> | 2024-01-10 20:05:48 -0300 |
---|---|---|
committer | icebaker <icebaker@proton.me> | 2024-01-10 20:05:48 -0300 |
commit | 3dc22548895718ffc7396227267ecbb4902b62f9 (patch) | |
tree | d19984eef953a2cd1e57c6fd51a73f2bcbb77541 /logic/cartridge | |
parent | a36604d266cb019311cdf67110596a16986a0fff (diff) |
improving markdown parser
Diffstat (limited to 'logic/cartridge')
-rw-r--r-- | logic/cartridge/parser.rb | 84 |
1 files changed, 77 insertions, 7 deletions
diff --git a/logic/cartridge/parser.rb b/logic/cartridge/parser.rb index 308ca36..f82b968 100644 --- a/logic/cartridge/parser.rb +++ b/logic/cartridge/parser.rb @@ -22,7 +22,50 @@ module NanoBot end def self.markdown(raw) - yaml(Markdown.instance.render(raw)) + yaml_source = [] + + tools = [] + + blocks = Markdown.new.render(raw).blocks + + previous_block_is_tool = false + + blocks.each do |block| + if block[:language] == 'yaml' + parsed = Logic::Helpers::Hash.symbolize_keys( + YAML.safe_load(block[:source], permitted_classes: [Symbol]) + ) + + if parsed.key?(:tools) && parsed[:tools].is_a?(Array) && !parsed[:tools].empty? + previous_block_is_tool = true + + tools.concat(parsed[:tools]) + + parsed.delete(:tools) + + unless parsed.empty? + yaml_source << YAML.dump(Logic::Helpers::Hash.stringify_keys( + parsed + )).gsub(/^---/, '') # TODO: Is this safe enough? + end + else + yaml_source << block[:source] + previous_block_is_tool = false + nil + end + elsif previous_block_is_tool + tools.last[block[:language].to_sym] = block[:source] + previous_block_is_tool = false + end + end + + unless tools.empty? + yaml_source << YAML.dump(Logic::Helpers::Hash.stringify_keys( + { tools: } + )).gsub(/^---/, '') # TODO: Is this safe enough? + end + + yaml(yaml_source.join("\n")) end def self.yaml(raw) @@ -32,24 +75,51 @@ module NanoBot end class Renderer < Redcarpet::Render::Base + LANGUAGES_MAP = { + 'yml' => 'yaml', + 'yaml' => 'yaml', + 'lua' => 'lua', + 'fnl' => 'fennel', + 'fennel' => 'fennel', + 'clj' => 'clojure', + 'clojure' => 'clojure' + }.freeze + + LANGUAGES = LANGUAGES_MAP.keys.freeze + + def initialize(...) + super(...) + @_nano_bots_blocks = [] + end + + attr_reader :_nano_bots_blocks + def block_code(code, language) - return nil unless %w[yml yaml].include?(language.to_s.downcase.strip) + key = language.to_s.downcase.strip - "\n#{code}\n" + return nil unless LANGUAGES.include?(key) + + @_nano_bots_blocks << { language: LANGUAGES_MAP[key], source: code } + + nil end end class Markdown - include Singleton - attr_reader :markdown def initialize - @markdown = Redcarpet::Markdown.new(Renderer, fenced_code_blocks: true) + @renderer = Renderer.new + @markdown = Redcarpet::Markdown.new(@renderer, fenced_code_blocks: true) + end + + def blocks + @renderer._nano_bots_blocks end def render(raw) - @markdown.render(raw) + @markdown.render(raw.gsub(/```\w/, "\n\n\\0")) + self end end end |