Module: RubyRich::Markdown::TerminalConverter::MermaidRenderer
- Defined in:
- lib/ruby_rich/markdown.rb
Overview
—- Mermaid diagram renderer —- Renders pie charts inline; other diagram types show source with a hint to install ‘mmdc` for full rendering.
Constant Summary collapse
- BAR_MAX =
32
Class Method Summary collapse
- .AnsiCode ⇒ Object
- .detect_type(source) ⇒ Object
- .render(source, width = 80) ⇒ Object
-
.render_fallback(source, type, width) ⇒ Object
Fallback: show diagram source with a labelled header.
-
.render_pie(source, width) ⇒ Object
Pie chart → horizontal bar chart with percentage labels.
-
.tc(key) ⇒ Object
Proxy theme colour access (same instance as TerminalConverter).
Class Method Details
.AnsiCode ⇒ Object
926 927 928 |
# File 'lib/ruby_rich/markdown.rb', line 926 def self.AnsiCode ::RubyRich::AnsiCode end |
.detect_type(source) ⇒ Object
850 851 852 853 854 855 856 857 858 859 |
# File 'lib/ruby_rich/markdown.rb', line 850 def self.detect_type(source) first = source.lines.first&.strip&.downcase || "" return :pie if first.start_with?("pie") return :flowchart if first.start_with?("flowchart") || first.start_with?("graph") return :sequence if first.start_with?("sequencediagram") return :class if first.start_with?("classdiagram") return :gantt if first.start_with?("gantt") return :state if first.start_with?("statediagram") :generic end |
.render(source, width = 80) ⇒ Object
837 838 839 840 841 842 843 844 845 846 847 848 |
# File 'lib/ruby_rich/markdown.rb', line 837 def self.render(source, width = 80) trimmed = source.strip return "" if trimmed.empty? type = detect_type(trimmed) case type when :pie render_pie(trimmed, width) else render_fallback(trimmed, type, width) end end |
.render_fallback(source, type, width) ⇒ Object
Fallback: show diagram source with a labelled header.
908 909 910 911 912 913 914 915 916 917 918 |
# File 'lib/ruby_rich/markdown.rb', line 908 def self.render_fallback(source, type, width) label = type.to_s.capitalize pad = (width - label.length - 2).clamp(2, 60) lines = source.lines.map(&:chomp) [ "#{tc(:code_border)}┌─ #{label} #{'─' * pad}┐#{AnsiCode.reset}", *lines.map { |l| "#{tc(:code_border)}│#{AnsiCode.reset} #{l}" }, "#{tc(:code_border)}└#{'─' * (width - 2)}┘#{AnsiCode.reset}", "#{tc(:muted || :heading_4_6)}Install mmdc (npm i -g @mermaid-js/mermaid-cli) for full diagram rendering.#{AnsiCode.reset}", ].join("\n") end |
.render_pie(source, width) ⇒ Object
Pie chart → horizontal bar chart with percentage labels.
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 |
# File 'lib/ruby_rich/markdown.rb', line 862 def self.render_pie(source, width) title = "" entries = [] source.each_line do |line| line = line.strip next if line.empty? if line.downcase.start_with?("pie") rest = line[3..].strip if rest.downcase.start_with?("title") title = rest[5..].strip end next end if line.downcase.start_with?("title") title = line[5..].strip next end # Parse "label" : value label_part, value_part = line.split(":", 2).map(&:strip) next unless label_part && value_part label = label_part.delete_prefix('"').delete_suffix('"') value = value_part.to_f entries << [label, value] if value > 0 end return "[Mermaid pie: no data]" if entries.empty? total = entries.sum { |_l, v| v } return "[Mermaid pie: total is zero]" if total <= 0 max_label = entries.map { |l, _| l.length }.max out = +"" out << "#{tc(:heading_3)}#{title}#{AnsiCode.reset}\n" unless title.empty? entries.each do |label, value| pct = value / total * 100.0 filled = (pct / 100.0 * BAR_MAX).round half = (pct / 100.0 * BAR_MAX * 2).round % 2 == 1 = "█" * filled + (half ? "▌" : "") out << sprintf("%-#{BAR_MAX + 1}s %-#{max_label}s %5.1f%%\n", , label, pct) end out.strip end |
.tc(key) ⇒ Object
Proxy theme colour access (same instance as TerminalConverter).
921 922 923 924 |
# File 'lib/ruby_rich/markdown.rb', line 921 def self.tc(key) color, bright = MarkdownTheme[key] AnsiCode.color(color, bright) end |