Wire form
The canonical JSON every implementation emits — /models.
AsciiChem’s model has two more front doors besides the ASCII syntax: structure interchange (SMILES, molfile) and resolution (identifiers → substance records). Both land in the same semantic model, so every formatter and the wire form work unchanged.
A molecular formula is not a structure — C_2H_6O is ethanol or
dimethyl ether. The chemistry world carries connectivity as SMILES or
connection tables (molfile/SDF), and so does AsciiChem:
AsciiChem.parse_smiles("CC(=O)OC1=CC=CC=C1C(=O)O") # aspirinAsciiChem.parse_molfile(molfile_text) # V2000, coordinates preservedBoth produce ordinary Model::Molecules: bonds, ring closures,
charges, isotopes, aromaticity. Render them (to_structural_svg),
re-emit them (to_smiles — a deterministic writer; aspirin
round-trips exactly), or serialise to the wire form.
From the CLI:
asciichem convert -i "CCO" --from smiles -t structural-svgasciichem convert -f ethanol.mol --from molfile -t model-jsonThe supported subset is honest about its edges: chirality (@) and
E/Z bond directions (/ \) raise actionable errors rather than
silently dropping stereo.
Resolution turns identifiers into substance records with provenance (TODO.v2 07). The default source is PubChem (keyless, permissive); more sources are opt-in because sources carry license obligations.
substance = AsciiChem::Resolver.resolve(value: "50-78-2", convention: "cas")substance.identifier_value("inchikey") # => "BSYNRYMUTXBXSQ-UHFFFAOYSA-N"substance.structure.to_structural_svg # parsed from the source SMILESsubstance.to_model_json # canonical substance recordEvery result carries provenance — source, retrieved-at, attribution —
because the citation track emits one bibitem per (substance, source).
Results are cached in your user cache directory; --refresh
bypasses it.
asciichem resolve --name aspirin --source pubchemasciichem validate -i 'H_2O @cas("7732-18-5")' # offlineIdentity can also be computed from the structure you drew — offline, through the IUPAC reference software (never a reimplementation). The engine is opt-in and external:
AsciiChem::Inchi.engine = AsciiChem::Inchi::BinaryEngine.newAsciiChem::Inchi.identity_for(molecule).inchikeyWith an engine configured, asciichem lint structurally cross-checks
@inchi and @inchikey annotations against the drawn structure —
catching transcription errors that format validation cannot. Python
wraps the same library via RDKit (pip install 'asciichem[inchi]').
Wire form
The canonical JSON every implementation emits — /models.
Live renderer
Parse and draw structures in the browser — /playground.