Ruby
asciichemasciichemasciichem-tsasciichem-pypip install asciichem-pyfrom asciichem import parse_text, ParseErrorfrom asciichem.text import renderfrom asciichem.wire import to_model_json, from_model_jsonfrom asciichem.smiles import parse_smiles, write_smilesfrom asciichem.mathml import render_mathml
formula = parse_text("2H_2 + O_2 ->[heat] 2H_2O")print(render(formula)) # canonical AsciiChem text (round-trip)print(render_mathml(formula)) # presentation MathML (L2 goldens)
aspirin = parse_smiles("CC(=O)OC1=CC=CC=C1C(=O)O")print(write_smiles(aspirin)) # deterministic — round-trips exactly
# Canonical wire form (asciichem-model v1) with lossless round-tripwire = to_model_json(formula)back = from_model_json(wire)assert render(back) == render(formula)Parse / reject · L0 emission · L1 text · L2 MathML · SMILES · molfile — 100% of the shared corpus. See the Implementations matrix for the full table.
The Python implementation is built for data and science workflows where dependencies are liabilities:
jsonschema and pytest are dev-only for the conformance suite. The shipped package is plain stdlib + the model dataclasses.@dataclass-shaped, introspectable with standard tools (dataclasses.asdict, pydantic if you must). No framework magic.to_model_json/from_model_json for pipelines that already speak JSON.asciichem[inchi] extra — RDKit-backed InChI engine when you need to derive identity locally; off by default.github.com/asciichem/asciichem-py — zero runtime deps.