CTAN Comprehensive TeX Archive Network

Directory macros/latex/contrib/chemidentifier

README.md

chemidentifier

Version française

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 3 (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:

\usepackage{chemidentifier}             % version 2
\usepackage[version=1]{chemidentifier}  % version 1, frozen

Installation

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
\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:

\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:

\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:

\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:

\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:

\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):

\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

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 <test>-<engine>.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). 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:

\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:

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 .pdftex figures (Lua 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 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:

\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 Lua only? A pur, catcode-trick alternative (à la psfrag) was considered and rejected: a .pdf_tex is genuine /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 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 <aliochask.pro@gmail.com>

This work may be distributed and/or modified under the conditions of the 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.

Download the contents of this package in one zip archive (1.6M).

Chemidentifier – Synthesis-order numbering and hyperlinking of chemical compounds

chemidentifier numbers the compounds of a synthesis-chemistry paper in the logical order of the synthesis – the order in which they are declared – rather than the order in which they first appear in the text. Every printed number is clickable and jumps to the scheme or paragraph that introduces the compound.

Three commands cover the common case: \chemid* declares a compound (optionally with a rich display form and a raw bookmark form), \chemid uses it anywhere in running text, captions or headings, and \chemidhere marks the point a number should link to – typically next to a reaction scheme. Multiple declarations and uses are accepted as comma-separated lists and are automatically contracted into ranges (1a-c) or contiguous groups (1a,b) the way a human author would write them by hand.

Compounds can be organized in a single level of parent/child hierarchy (benz, benz.cl, benz.br...), and \chemidfamily declares a templated family where the numbering style, child format (subscript, superscript, Greek letters...) and a placeholder value are set once for every child.

The package is written in 3 (expl3). Like \ref/\label, numbering and links settle over two compilations. It works with or without hyperref, and with pdf, Lua and ; an optional Lua-only helper substitutes compound labels directly inside Inkscape-exported .pdf_tex figures.

Version 2 (the default) adds templated families, anchors that carry the links themselves, and stricter validation; version 1 is frozen and stays available via the version=1 package option for documents written against it.

PackageChemidentifier
Repository
Version2.0.0
LicensesThe Project Public License 1.3c
Copyright2026 Aliocha SKRZYPCZAK
MaintainerAliocha Skrzypczak
Contained inTeX Live as chemidentifier
TopicsHyper
Label and References
Chemistry
See alsochemnum
...
Guest Book Sitemap Contact Contact Author