lib/syntax_tree/mermaid_visitor.rb
# frozen_string_literal: true module SyntaxTree # This visitor transforms the AST into a mermaid flow chart. class MermaidVisitor < FieldVisitor attr_reader :flowchart, :target def initialize @flowchart = Mermaid.flowchart @target = nil end def visit_program(node) super flowchart.render end private def comments(node) # Ignore end def field(name, value) case value when nil # skip when Node flowchart.link(target, visit(value), name) else to = flowchart.node("#{target.id}_#{name}", value.inspect, shape: :stadium) flowchart.link(target, to, name) end end def list(name, values) values.each_with_index do |value, index| field("#{name}[#{index}]", value) end end def node(node, type) previous_target = target begin @target = flowchart.node("node_#{node.object_id}", type) yield @target ensure @target = previous_target end end def pairs(name, values) values.each_with_index do |(key, value), index| to = flowchart.node("#{target.id}_#{name}_#{index}", shape: :circle) flowchart.link(target, to, "#{name}[#{index}]") flowchart.link(to, visit(key), "[0]") flowchart.link(to, visit(value), "[1]") if value end end def text(name, value) field(name, value) end end end