Molecule
A molecule is an ordered list of atoms, groups, and bonds, with an optional leading stoichiometric coefficient and an optional stereochemistry marker.
Fields
Section titled “Fields”| Field | Type | Source position | Example |
|---|---|---|---|
nodes | Array of Atom, Group, or Bond | the body | H, (OH), = |
coefficient | String | leading digits | 2H_2O |
stereo | Symbol | prefix | (R)- |
The stereo field is nil or one of: :R, :S, :E, :Z,
:alpha, :beta.
Diagram
Section titled “Diagram” ┌────────────────────────────────────────┐ stereo ───►│ Molecule │ │ │ │ nodes[0] ──┐ │ │ nodes[1] ──┤── ordered list │ │ nodes[2] ──┤ (Atom | Group | │ │ ... │ Bond) │ │ │ │ │ coefficient ─── leading digits │ └────────────────┘───────────────────────┘Grammar production
Section titled “Grammar production”molecule := stereo_prefix? coefficient? unitsunits := (unit | bond)+unit := prefixed_atom | group | plain_atomThe stereo_prefix is optional; if present it must be a closed-letter
set (R/S/E/Z/a/b/alpha/beta/α/β). The grammar
tries prefixed_atom (with isotope) before plain_atom and before
group; this ordering disambiguates (OH)-C (group + bond) from
(R)-C (stereo prefix).
Formatter behaviour
Section titled “Formatter behaviour”| Formatter | Coefficient | Stereo |
|---|---|---|
| MathML | <mn>2</mn> prefix | <mtext>(R)-</mtext> prefix |
| Text | literal digits prefix | (R)- prefix |
| HTML | plain text prefix | (R)- prefix |
| LaTeX | mhchem bare digits | \ce{(R)-...} |
| SVG | literal digits prefix | (R)- prefix |
Round-trip
Section titled “Round-trip”AsciiChem.parse("H_2O").to_text # => "H_2O"AsciiChem.parse("2H_2O").to_text # => "2H_2O"AsciiChem.parse("(R)-CH_3").to_text # => "(R)-CH_3"AsciiChem.parse("(alpha)-CH_3").to_text # => "(α)-CH_3" (canonical)Why stereo is on the molecule, not the atom
Section titled “Why stereo is on the molecule, not the atom”The chemist reads (R)-CH(OH)COOH and knows which carbon is chiral
from chemistry knowledge. The parser only sees the prefix — it can’t
know which atom is the stereocentre without structural context.
So stereo is metadata on the molecule. A future 2D structural renderer (via elk-rb integration) will be able to attach the marker to the specific atom via graph analysis; for now, the molecule-level marker preserves the source intent.
Children contract
Section titled “Children contract”class Molecule def children nodes endendThe linter walks into a molecule’s nodes via children. Adding a new
node type (e.g. an Anomer class for sugar-specific stereochemistry)
means defining children on the new class; the linter picks it up.