Class: AsciiChem::Formatter::Svg
- Defined in:
- lib/asciichem/formatter/svg.rb
Overview
Renders a Model tree as a linear SVG. The SVG draws the formula along a horizontal baseline with elements at fixed spacing.
This is the v1 fallback for environments that want a self-contained
vector output without MathML. True 2D structural diagrams (skeletal
formulae, rings, stereo wedges) require mn/elk-rb integration
(TODO 13); this formatter does not attempt that.
Constant Summary collapse
- LINE_HEIGHT =
40- CHAR_WIDTH =
14- BASELINE =
30
Instance Method Summary collapse
- #visit_atom(atom) ⇒ Object
- #visit_bond(bond) ⇒ Object
- #visit_electron_configuration(ec) ⇒ Object
- #visit_embedded_math(em) ⇒ Object
- #visit_formula(formula) ⇒ Object
- #visit_group(group) ⇒ Object
- #visit_molecule(molecule) ⇒ Object
- #visit_reaction(reaction) ⇒ Object
- #visit_reaction_cascade(cascade) ⇒ Object
- #visit_text(text) ⇒ Object
Methods inherited from Base
Instance Method Details
#visit_atom(atom) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/asciichem/formatter/svg.rb', line 32 def visit_atom(atom) parts = [] parts << "^#{atom.isotope}" if atom.isotope parts << atom.element parts << "_#{atom.subscript}" if atom.subscript if atom.charge parts << "^#{atom.charge}" elsif atom.oxidation_state parts << "^(#{atom.oxidation_state})" elsif atom.superscript parts << "^#{atom.superscript}" end parts << atom.ring_closures.to_s if atom.ring_closures parts.join end |
#visit_bond(bond) ⇒ Object
54 55 56 |
# File 'lib/asciichem/formatter/svg.rb', line 54 def visit_bond(bond) bond.ascii end |
#visit_electron_configuration(ec) ⇒ Object
90 91 92 |
# File 'lib/asciichem/formatter/svg.rb', line 90 def visit_electron_configuration(ec) ec.orbitals.map { |orb, occ| "#{orb}^#{occ}" }.join(" ") end |
#visit_embedded_math(em) ⇒ Object
94 95 96 |
# File 'lib/asciichem/formatter/svg.rb', line 94 def (em) em.source.to_s end |
#visit_formula(formula) ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/asciichem/formatter/svg.rb', line 17 def visit_formula(formula) nodes = formula.nodes rows = layout_rows(nodes) width = rows.map { |r| layout_width(r) }.max height = rows.size * LINE_HEIGHT + 10 render_svg(width, height, rows) end |
#visit_group(group) ⇒ Object
48 49 50 51 52 |
# File 'lib/asciichem/formatter/svg.rb', line 48 def visit_group(group) body = group.nodes.map { |n| render_node(n) }.join suffix = group.multiplicity ? "_#{group.multiplicity}" : "" "#{group.open_char}#{body}#{group.close_char}#{suffix}" end |
#visit_molecule(molecule) ⇒ Object
25 26 27 28 29 30 |
# File 'lib/asciichem/formatter/svg.rb', line 25 def visit_molecule(molecule) prefix = molecule.coefficient.nil? || molecule.coefficient.to_s.empty? ? "" : molecule.coefficient.to_s stereo = molecule.stereo ? "(#{molecule.stereo_letter})-" : "" body = molecule.nodes.map { |n| render_node(n) }.join "#{stereo}#{prefix}#{body}" end |
#visit_reaction(reaction) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/asciichem/formatter/svg.rb', line 58 def visit_reaction(reaction) left = reaction.reactants.map { |n| render_node(n) }.join(" + ") right = reaction.products.map { |n| render_node(n) }.join(" + ") arrow = reaction.arrow_ascii conds = reaction.conditions return "#{left} #{arrow} #{right}" unless conds above = conds.above ? "[#{conds.above}]" : "" below = conds.below ? "[#{conds.below}]" : "" "#{left} #{arrow}#{above}#{below} #{right}" end |
#visit_reaction_cascade(cascade) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/asciichem/formatter/svg.rb', line 70 def visit_reaction_cascade(cascade) return "" if cascade.steps.empty? head = cascade.steps.first out = head.reactants.map { |n| render_node(n) }.join(" + ") cascade.steps.each do |step| arrow = step.arrow_ascii conds = step.conditions if conds above = conds.above ? "[#{conds.above}]" : "" below = conds.below ? "[#{conds.below}]" : "" out += " #{arrow}#{above}#{below}" else out += " #{arrow}" end out += " " + step.products.map { |n| render_node(n) }.join(" + ") end out end |
#visit_text(text) ⇒ Object
98 99 100 |
# File 'lib/asciichem/formatter/svg.rb', line 98 def visit_text(text) text.content end |