TypeScript API
npm install asciichemZero runtime dependencies. Runs in the browser, Node, and workers.
Parsing
Section titled “Parsing”import { parse, parseText, parseSmiles, parseMolfile } from "asciichem";
const formula = parse("2H_2 + O_2 -> 2H_2O"); // => Formulaparse === parseText; // alias
// All input grammars land in the same modelparseSmiles("CC(=O)OC1=CC=CC=C1C(=O)O"); // aspirinparseMolfile(v2000Text); // coordinates preservedInvalid input throws ParseError (extends AsciiChemError) — nothing
is ever parsed “partially”.
Model shortcuts
Section titled “Model shortcuts”Every model node carries output methods:
formula.toText(); // canonical AsciiChem text (round trip)formula.toModelJSON(); // asciichem-model v1 wire JSONformula.toSvg(); // typographic SVGformula.toStructuralSvg(); // 2D structural SVG (bonds you author)formula.toSmiles(); // deterministic SMILES writermol.toMolfile(); // V2000 molfile (molecules only)Renderers
Section titled “Renderers”Formatters are registered, not switch-cased — import the ones you need:
import { TextFormatter, SvgFormatter, StructuralSvgFormatter, MathmlFormatter, renderMathml,} from "asciichem";
renderMathml(formula); // presentation MathML, L2 goldensnew TextFormatter().render(formula);The MathML output is byte-identical with the Ruby reference —
pinned by the shared corpus goldens (format/mathml/*), enforced in
CI.
Wire form
Section titled “Wire form”The canonical JSON interchange (asciichem-model v1):
import { fromModelJSON } from "asciichem";
const wire = formula.toModelJSON(); // plain JSON objectconst back = fromModelJSON(wire); // => FormulafromModelJSON(JSON.stringify(wire)); // strings work tooback.toText(); // round-tripsError handling
Section titled “Error handling”import { ParseError, AsciiChemError } from "asciichem";
try { parse("H_2O @cas(\"not-a-cas\")");} catch (e) { if (e instanceof AsciiChemError) { // all library errors extend AsciiChemError }}InChI engine seam (optional)
Section titled “InChI engine seam (optional)”import { setInchiEngine, inchiIdentityFor, InchiEngineMissingError } from "asciichem";
setInchiEngine(myEngine); // register onceinchiIdentityFor(molecule) // { inchi, inchikey? }// no engine registered => throws InchiEngineMissingError with guidanceThe InChI algorithm is never reimplemented — engines wrap an InChI implementation (a WASM build of the IUPAC library in this environment).
What runs where
Section titled “What runs where”- Browser — everything above. This site’s playground uses exactly this package, client-side.
- Node — same API; the peggy grammar ships prebuilt.
- Build tools — parse at build time, emit SVG/MathML into static output; the corpus guarantees your web previews match the Ruby gem’s build-time renders.
Claimed levels
Section titled “Claimed levels”Parse/reject · L0 emission · L1 text · L2 MathML · SMILES · molfile — 100% of the shared corpus. See Implementations for the full matrix.