SMILES Structure Preview
Adds SMILES molecules and SMARTS patterns to VS Code's built-in Markdown preview,
drawn by smiles-renderer, the same
library that renders SMILES on reonarudo.github.io. Requires VS Code 1.101 or later;
older versions get 0.2.0.
Write a SMILES string in a fence tagged smiles:
```smiles
CC(=O)Oc1ccccc1C(=O)O
```
Only smiles and smarts fences are claimed — smi fences are left to other
renderers.

Several molecules
Each non-blank line is one molecule. Text after the first whitespace labels it,
as in .smi files; the molecules sit side by side with each label beneath:
```smiles
CCO ethanol
c1ccccc1 benzene
[Na+].[Cl-] table salt
```
SMARTS patterns
A fence tagged smarts parses each line as a SMARTS substructure query instead
of a molecule. Atom lists, negations, hydrogen counts, ring constraints, any-bonds
and recursive groups are drawn, with each constraint annotated on the atom it
applies to:
```smarts
[CX3](https://github.com/Reonarudo/smiles-markdown-preview/blob/HEAD/=O)[OX2H1] carboxylic acid
[C,N;!H0]~* C or N with a hydrogen
[NX3;H2,H1;!$(NC=O)] amine, not amide
```

Any-bonds (~) carry an orange dot. Atoms that a negated recursive group
requires to be absent, such as the carbonyl in !$(NC=O), are shaded. Patterns
are drawn half as large again as molecules so their annotations stay legible.
Labels, attributes and limits work exactly as for smiles fences, and each
pattern's <svg> carries an extra smarts class. The notation is never guessed:
a SMARTS query in a smiles fence is a parse error, so a mistyped molecule is
never quietly drawn as a pattern. SMARTS features OpenChemLib does not
support, such as x ring connectivity, @? chirality or two positive recursive
groups in one atom, are reported as parse errors like any other.
Fence attributes
An optional attribute block after the smiles or smarts tag adjusts how one
fence is presented:
```smiles {alt="Aspirin" caption="Figure 1: Acetylsalicylic acid" align="center"}
CC(=O)Oc1ccccc1C(=O)O
```
| Attribute |
Effect |
alt |
Description for readers who cannot see the structure |
caption |
Text shown beneath the structure |
align |
left, center or right |
class |
Extra CSS class on each structure's <svg> |
Values are quoted. A mistyped or malformed attribute never costs you the
structure: it is ignored, and a note is written to the SMILES Structure Preview
output channel.

Viewing the source
Every structure carries a small button in its top corner that flips the fence
between the structure and the fence's text, highlighted the way the preview shows
any other code block. A multi-line fence flips as a whole. A flipped fence stays
flipped while you edit the document, after Markdown: Refresh Preview, and when
the preview is reopened; flip it back to see the structure again. The button is a
reader's control: a fence cannot be written to open in source view.
Errors and limits
A SMILES or SMARTS parse error is shown in place of that one structure, naming
its line and column in the fence and quoting the string with a caret at the
offending position; the other molecules of the fence still render. Depiction is
limited to 4,000 characters per string and, by default, 3 seconds per molecule; a
molecule that takes longer shows a timeout message until its string changes. Raise
or lower the limit with the smiles.depictionTimeout setting (seconds, 0.5 to 60);
a change restarts the renderer with the new limit, and molecules that timed out
under the old limit are retried.
Structures are drawn on a white card with CPK element colours in every theme.
The extension reads no files, so it works fully in Restricted Mode and virtual
workspaces.
Development
Requires Node 22 or newer (see .nvmrc).
npm ci
npm run lint # tsc --noEmit
npm test # node --test, after building
npm run package # vsce package
npm run test:package # the VSIX inside a real VS Code
npm run test:preview # the view toggle in a live preview, through Playwright
npm run screenshots # regenerate media/screenshots from examples/demo.md
License
MIT for this extension; OpenChemLib, shipped with smiles-renderer, is BSD-3-Clause — see
THIRD_PARTY_NOTICES.md.