# chemidentifier *[Version française](README.fr.md)* LaTeX package to number the compounds of a synthesis-chemistry paper in **the logical order of the synthesis** — the order in which you declare them — rather than the order in which they appear in the text. Every printed number is clickable and jumps to the scheme showing the compound. Written in LaTeX3 (expl3). Like `\ref`/`\label`, everything settles over **two compilations**. Version 2 is the one loaded by default; version 1 is frozen and stays available for the documents written against it: ```latex \usepackage{chemidentifier} % version 2 \usepackage[version=1]{chemidentifier} % version 1, frozen ``` ## Installation ```sh make install # into ~/texmf make install TEXMF=/path/to/texmf ``` Or, more simply, copy `chemidentifier.sty` next to your document. ## Three commands | Command | Role | Output | |---|---|---| | `\chemid*{key}` | declaration | none | | `\chemid{key}` | use | the number, clickable | | `\chemidhere{key}` | anchor | none | | `\chemidfamily{key}{options}` | templated family | none | ```latex \usepackage{hyperref} % preferably before \usepackage{chemidentifier} \chemid*{benz} % 1 \chemid*{benz.cl,benz.br} % 1a, 1b -- multiple declaration \chemid*{amine} % 2 \chemid*{target}{target\textsubscript{final}}[final target] \begin{document} Compound \chemid{benz} gives \chemid{benz.cl,benz.br}, then \chemid{target}. \begin{figure} \includegraphics{schema} \chemidhere{benz} % the parent and its children at once \caption{Halogenation of \chemid{benz}} \end{figure} \end{document} ``` ## Display rules | Call | Result | |---|---| | `\chemid{benz}` | `1` | | `\chemid{benz.cl}` | `1a` | | `\chemid{benz.cl,benz.br,benz.i}` | `1a-c` | | `\chemid{benz.cl,benz.br}` | `1a,b` | | `\chemid{benz.cl,benz.i}` | `1a,1c` | | `\chemid{benz,amine.a}` | `1 and 2a` | | `\chemid{target}` | `final_target` | | `\chemid{unknown}` | `??` + error | Context is taken into account automatically: clickable link in the text, captions and displayed titles; **no** link in the table of contents or the list of figures (the entry is already a link to the section); plain text in PDF bookmarks. ## Options At load time, or via `\chemidsetup{...}`: `list-sep`, `last-sep`, `sub-sep`, `range-sep`, `range-threshold`, `format`, `main-style`, `sub-style` (+ `lower-greek`), `prefix`, `unknown-text`, `purify`, `implicit-parent`, `strict-anchors`, `links`, `anchor-children`, `auto-lang`. `version` is load-time only: it is the single option the loader reads. ## Anchors and links `\chemidhere{key}` places the target of the link, in the figure showing the compound. It takes a list, and naming a **parent** anchors the whole family: ```latex \chemidhere{cmbr.4,cmbr.6,cmbr.8} % three keys, three anchors \chemidhere{cmbr} % the same three, plus cmbr itself \chemidhere{cmbr,cmal} % two families in one call ``` A child carrying an anchor of its own wins, silently; `anchor-children=false` keeps `\chemidhere{parent}` to the parent alone. **A compound with no anchor is not a link.** Rather than point at nothing, its number is printed as it is (`strict-anchors`, on by default) — anchors travelling through the `.aux`, links settle on the second compilation. If a parent is not anchored but its children are, `\chemid{parent}` goes to the first anchored child. `strict-anchors=false` restores version 1's behaviour, and `links=false` drops everything: no link, no anchor, and no missing-anchor warning left. `\herechemid` was version 1's name for it: it still works, and says once per document that it has been renamed. ## Templated families When the members of a series are told apart by something the chemist already has a name for — chain length, oxidation state, substituent — the parent holds the stem and each child carries only what varies: ```latex \chemidfamily{lcoum}{ name = Lcoum-C , placeholder = n } \chemid*{lcoum.four}{4} \chemid*{lcoum.eight}{8} \chemid*{lcoum.twelve}{12} ``` | Call | Result | |---|---| | `\chemid{lcoum.four}` | Lcoum-C₄ | | `\chemid{lcoum.four,lcoum.eight}` | Lcoum-C₄,₈ | | `\chemid{lcoum}` | Lcoum-Cₙ | The stem is printed once for a whole group, exactly as `1a,b` factors out the `1`, and every value keeps its own link. Options: `name`, `raw`, `sub-style`, `child-format` (`subscript` by default, `superscript`, `plain`, or code containing `\chemidvalue`), `placeholder`, `placeholder-raw`. A child declared with no value is numbered by the family's `sub-style`, `lower-greek` included: ```latex \chemidfamily{ser}{ name = Series , sub-style = lower-greek , child-format = plain } \chemid*{ser.a}\chemid*{ser.b}\chemid*{ser.c} % \chemid{ser.a,ser.b,ser.c} -> Seriesα-γ ``` Automatically numbered children contract into a range; values given by hand never do (`4-12` would claim something nobody wrote). Inside one family, either every child carries a value or none does: mixing the two is an error. ## Multilingual documents (babel) By default (without babel, or outside a multilingual document), the separator before the last item is the English `and` (`last-sep`). To choose it yourself: ```latex \usepackage[last-sep={~and~}]{chemidentifier} % at load time \chemidsetup{last-sep={~and~}} % or at any time ``` With `babel`, the separator automatically follows the current language set by `\selectlanguage` — useful for a thesis mixing several languages: ```latex \usepackage[french,ngerman,spanish,italian,english]{babel} ... \selectlanguage{french} \chemid{a,b} % ... et ... \selectlanguage{ngerman} \chemid{a,b} % ... und ... \selectlanguage{spanish} \chemid{a,b} % ... y ... \selectlanguage{italian} \chemid{a,b} % ... e ... \selectlanguage{english} \chemid{a,b} % ... and ... ``` Five languages are known by default, with their usual babel variants: `english` (`american`, `british`, `australian`, `UKenglish`, `USenglish`), `french` (`francais`, `acadian`, `canadien`), `german` (`ngerman`, `austrian`, `naustrian`), `spanish` (`mexican`), `italian`. `\chemidaddlanguage{language}{separator}` adds or redefines an entry, for example `\chemidaddlanguage{french}{ ou }`. Without `babel`, or for an unregistered language, the package falls back to `last-sep`. `auto-lang=false` disables the automatic switch to keep only `last-sep`, including locally inside a group. The chemistry-journal convention (bold numbers): ```latex \usepackage[format=\textbf]{chemidentifier} ``` The full manual is in `doc/chemidentifier-doc.pdf` (`make doc`). ## Diagnostics The package reports: undeclared key, key declared twice, key with more than one level, malformed key, anchor placed twice, anchor on an unknown key, implicitly created parent, compound used without an anchor (at the end of compilation), missing `hyperref`, `\herechemid` used for `\chemidhere`, and, for families: key that is not a parent, family declared twice, unknown family option, given and automatic values mixed. ## Tests ```sh make test # 19 checks, with pdflatex make test-all # the same, with pdflatex, lualatex and xelatex make update-refs # regenerates the references (review before committing) ``` The produced PDFs are kept in `test/pdf/`, named `-.pdf`, for visual inspection. For each test document, the suite compares the text extracted from the PDF and the messages from the `.log` against frozen references. It also checks two structural properties: - the target count of every link annotation in the PDF, which detects a stray link showing up in the table of contents; - that an anchor never shifts any word on the page, by comparing the boxes of every word with and without anchors (measured deviation: 0.0000 pt under pdflatex and lualatex, 0.0062 pt under xelatex, a placement rounding). The ten version 1 documents are compiled with `version=1` and compared against their original references: that is what guarantees the frozen version does not move. Added to them are the link count of several documents and the content of the bookmarks, the only place the plain-text rendering shows from the outside. The three engines give the same result; only xelatex's text extraction differs, ligatures being rendered there as a single character (`ffi` → `ffi`). An engine-specific reference is only created when it actually differs from the common reference. ## Declaring several keys at once `\chemid*{key1,key2,...}` declares each of them, auto-numbered in turn — the same convention as `\chemid`: ```latex \chemid*{mol1,mol2,mol3} % three parents: 1, 2, 3 \chemid*{mol1.a,mol1.b} % two children of mol1: 1a, 1b ``` A custom name cannot accompany a multiple declaration (`\chemid*{a,b}{name}` would be ambiguous) — error, declare that key on its own. A comma inside a single key is rejected. Declaring children in bulk without ever declaring their parent on its own also works: the parent is created implicitly, and `\chemid{molz}` (its name alone) prints its number without error. ## Declaring after using `\chemid`/`\chemidhere` may appear **before** the `\chemid*` that declares the key — like a `\ref` before its `\label`. The first compilation shows `??` (the `.aux` is still empty); the second resolves it, and the result stays stable afterwards, the order of declarations never depending on where they are used: ```latex Compound \chemid{mol1} is introduced here, but declared further down. ... \chemid*{mol1} ``` A declaration at the top of the preamble nonetheless remains the simplest approach if you have no particular constraint: the number is then known as soon as the key is read, with no forward reference to resolve. ## Text substitution in .pdf_tex figures (LuaLaTeX only) A scheme exported by Inkscape (a `.pdf_tex` + `.pdf` pair) can have its compound labels wired to `\chemid`, the same way `psfrag` once patched text into `.eps` figures — without the `.eps`/`psfrag` baggage: a `.pdf_tex` is just LaTeX text calling `\includegraphics`, so a plain, line-by-line substitution done in Lua is enough. Requires compiling with `lualatex` (or another engine providing `\directlua`); the file on disk is never modified, so re-exporting from Inkscape loses nothing. Put a plain-text placeholder in the drawing for each compound label (`TMP1`, `TMP2`... anything, as long as it does not also occur as a substring elsewhere in the figure text), then: ```latex \usepackage{graphicx} % needed by the .pdf_tex itself \usepackage{chemidentifier} \chemidsetup{ pdftex-font = \sffamily\small } % optional, once \chemid*{precursor} \chemid*{product} \begin{figure} \centering \chemidkey{TMP1}{precursor} % TMP1 -> \chemid{precursor} \chemidkey[1.3]{TMP2}{product} % 1.3x bigger than the rest \chemidnote{TMPCOND}{K$_2$CO$_3$, acetone, 70~°C} % free text \chemidscheme[0.8]{figures/scheme.pdf_tex} % scale is optional \chemidhere{precursor}\chemidhere{product} \caption{Synthesis of \chemid{product} from \chemid{precursor}.} \end{figure} ``` | Command | Role | |---|---| | `\chemidkey[factor]{motif}{key}` | placeholder → the compound's current number, e.g. `\chemid{key}` | | `\chemidnote[factor]{motif}{text}` | placeholder → any other text, free-form | | `\chemidscheme[scale]{path}` | reads the file, substitutes, typesets; also adds its folder to `\graphicspath` | `\chemidscheme` consumes the pending `\chemidkey`/`\chemidnote` list as it reads the file, so the next figure automatically starts from an empty list — there is no separate "clear" step to remember. The size of a substituted label is the product of three independent factors, so a figure scaled down still reads fine without retouching every label by hand: 1. **`pdftex-font`** (`\chemidsetup`) — the base style, set once, independently of the body text (Inkscape otherwise reinjects the document's own family, at whatever size the drawing used, typically too large), e.g. `\chemidsetup{ pdftex-font = \sffamily\fontsize{9}{11}\selectfont }`. 2. **the `[scale]` of `\chemidscheme`** — the same number handed to the figure's own `\svgscale`, so labels shrink/grow together with the drawing. 3. **the optional `[factor]` of `\chemidkey`/`\chemidnote`** — one label singled out, relative to the others in the same figure; defaults to `1`. Under a non-Lua engine, `\chemidscheme` raises a clear error instead of silently doing nothing. `\chemidkey` takes the compound's *current* number: it does not declare or renumber anything, so keys still need a matching `\chemid*{key}` elsewhere. *Why LuaLaTeX only?* A pure-TeX, catcode-trick alternative (à la `psfrag`) was considered and rejected: a `.pdf_tex` is genuine TeX/PGF code, full of `\`, `{`, `}`, `%`, `#`, `_`, `~`... Reading it verbatim and then re-executing it as code would require the same character to carry two contradictory catcodes — inert while captured, active while replayed — for arbitrary content, which is exactly what made `psfrag` fragile. Lua sidesteps this entirely by treating the file as a plain string throughout, and handing the result back to TeX only at the very end, read under the document's own, ordinary catcode regime. ## Assumed limitations - A single level of hierarchy (`parent.child`), families included. - Lists are neither sorted nor deduplicated: `\chemid{a,b,a}` prints `1, 2 and 1`, without error. - `cleveref` is not handled. - If a key is removed from the document, a reference that still points to it keeps resolving to its last known value until the `.aux` file is cleared — the same limitation as `\ref`/`\label`. ## Author and license Aliocha SKRZYPCZAK This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license or (at your option) any later version. This work has the LPPL maintenance status `maintained`. See `LICENSE` for the full text.