summaryrefslogtreecommitdiff
path: root/logic
diff options
context:
space:
mode:
Diffstat (limited to 'logic')
-rw-r--r--logic/cartridge/parser.rb84
-rw-r--r--logic/helpers/hash.rb13
2 files changed, 90 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
diff --git a/logic/helpers/hash.rb b/logic/helpers/hash.rb
index 90432b5..4cb44ac 100644
--- a/logic/helpers/hash.rb
+++ b/logic/helpers/hash.rb
@@ -17,6 +17,19 @@ module NanoBot
end
end
+ def self.stringify_keys(object)
+ case object
+ when ::Hash
+ object.each_with_object({}) do |(key, value), result|
+ result[key.to_s] = stringify_keys(value)
+ end
+ when Array
+ object.map { |e| stringify_keys(e) }
+ else
+ object
+ end
+ end
+
def self.fetch(object, path)
node = object