# chemidentifier *[English version](README.md)* Paquetage LaTeX pour numéroter les composés d'un article de chimie de synthèse dans **l'ordre logique de la synthèse** — l'ordre où vous les déclarez — et non dans l'ordre où ils apparaissent dans le texte. Chaque numéro imprimé est cliquable et renvoie au schéma qui montre le composé. Écrit en LaTeX3 (expl3). Comme `\ref`/`\label`, tout se stabilise en **deux compilations**. La version 2 est celle chargée par défaut ; la version 1 est figée et reste disponible pour les documents écrits avec elle : ```latex \usepackage{chemidentifier} % version 2 \usepackage[version=1]{chemidentifier} % version 1, figée ``` ## Installation ```sh make install # dans ~/texmf make install TEXMF=/chemin/vers/texmf ``` Ou, plus simplement, copiez `chemidentifier.sty` à côté de votre document. ## En trois commandes | Commande | Rôle | Affichage | |---|---|---| | `\chemid*{clé}` | déclaration | aucun | | `\chemid{clé}` | utilisation | le numéro, cliquable | | `\chemidhere{clé}` | ancre | aucun | | `\chemidfamily{clé}{options}` | famille à gabarit | aucun | ```latex \usepackage{hyperref} % de préférence avant \usepackage{chemidentifier} \chemid*{benz} % 1 \chemid*{benz.cl,benz.br} % 1a, 1b -- declaration multiple \chemid*{amine} % 2 \chemid*{cible}{cible\textsubscript{finale}}[cible finale] \begin{document} Le composé \chemid{benz} donne \chemid{benz.cl,benz.br}, puis \chemid{cible}. \begin{figure} \includegraphics{schema} \chemidhere{benz} % le parent et ses enfants d'un coup \caption{Halogénation de \chemid{benz}} \end{figure} \end{document} ``` ## Règles d'affichage | Appel | Résultat | |---|---| | `\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 et 2a` | | `\chemid{cible}` | `cible_finale` | | `\chemid{inconnue}` | `??` + erreur | Le contexte est pris en compte automatiquement : lien cliquable dans le texte, les légendes et les titres affichés ; **pas** de lien dans la table des matières ni la liste des figures (l'entrée est déjà un lien vers la section) ; texte brut dans les signets PDF. ## Options Au chargement ou 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` ne se donne qu'au chargement : c'est la seule option lue par le chargeur. ## Ancres et liens `\chemidhere{clé}` pose la cible du lien, dans la figure qui montre le composé. Elle accepte une liste, et nommer un **parent** ancre toute la famille : ```latex \chemidhere{cmbr.4,cmbr.6,cmbr.8} % trois clés, trois ancres \chemidhere{cmbr} % les mêmes trois, plus cmbr \chemidhere{cmbr,cmal} % deux familles en un appel ``` Un enfant qui porte une ancre à lui l'emporte, sans avertissement ; `anchor-children=false` limite `\chemidhere{parent}` au parent seul. **Un composé sans ancre n'est pas un lien.** Plutôt que de renvoyer dans le vide, son numéro est imprimé tel quel (`strict-anchors`, actif par défaut) — les ancres passant par le `.aux`, les liens se stabilisent à la deuxième compilation. Si un parent n'est pas ancré mais que ses enfants le sont, `\chemid{parent}` pointe vers le premier enfant ancré. `strict-anchors=false` rétablit le comportement de la version 1, et `links=false` supprime tout : aucun lien, aucune ancre, et plus aucun avertissement d'ancre manquante. `\herechemid` était le nom de la version 1 : il fonctionne toujours, et signale une fois par document qu'il a été renommé. ## Familles à gabarit Quand les membres d'une série se distinguent par quelque chose que le chimiste nomme déjà — longueur de chaîne, degré d'oxydation, substituant — le parent porte le radical et chaque enfant ne porte que ce qui varie : ```latex \chemidfamily{lcoum}{ name = Lcoum-C , placeholder = n } \chemid*{lcoum.quatre}{4} \chemid*{lcoum.huit}{8} \chemid*{lcoum.douze}{12} ``` | Appel | Résultat | |---|---| | `\chemid{lcoum.quatre}` | Lcoum-C₄ | | `\chemid{lcoum.quatre,lcoum.huit}` | Lcoum-C₄,₈ | | `\chemid{lcoum}` | Lcoum-Cₙ | Le radical est imprimé une fois pour tout un groupe, exactement comme `1a,b` factorise le `1`, et chaque valeur garde son lien. Options : `name`, `raw`, `sub-style`, `child-format` (`subscript` par défaut, `superscript`, `plain`, ou du code contenant `\chemidvalue`), `placeholder`, `placeholder-raw`. Un enfant déclaré sans valeur est numéroté par le `sub-style` de la famille, `lower-greek` compris : ```latex \chemidfamily{ser}{ name = Série , sub-style = lower-greek , child-format = plain } \chemid*{ser.a}\chemid*{ser.b}\chemid*{ser.c} % \chemid{ser.a,ser.b,ser.c} -> Sérieα-γ ``` Les enfants numérotés automatiquement se contractent en intervalle ; les valeurs données à la main, jamais (`4-12` affirmerait ce que personne n'a écrit). Dans une famille, soit tous les enfants portent une valeur, soit aucun : mélanger les deux est une erreur. ## Documents multilingues (babel) Par défaut (sans babel, ou hors document multilingue), le séparateur avant le dernier élément est l'anglais `and` (`last-sep`). Pour le choisir vous-même : ```latex \usepackage[last-sep={~et~}]{chemidentifier} % au chargement \chemidsetup{last-sep={~et~}} % ou à tout moment ``` Avec `babel`, le séparateur suit automatiquement la langue courante fixée par `\selectlanguage` — utile pour une thèse mêlant des parties en plusieurs langues : ```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 ... ``` Cinq langues sont connues par défaut, avec leurs variantes babel usuelles : `english` (`american`, `british`, `australian`, `UKenglish`, `USenglish`), `french` (`francais`, `acadian`, `canadien`), `german` (`ngerman`, `austrian`, `naustrian`), `spanish` (`mexican`), `italian`. `\chemidaddlanguage{langue}{séparateur}` ajoute ou redéfinit une entrée, par exemple `\chemidaddlanguage{french}{ ou }`. Sans `babel`, ou pour une langue non enregistrée, le paquetage retombe sur `last-sep`. `auto-lang=false` désactive la bascule automatique pour ne garder que `last-sep`, y compris localement dans un groupe. La convention des revues de chimie (numéros en gras) : ```latex \usepackage[format=\textbf]{chemidentifier} ``` Le manuel complet est dans `doc/chemidentifier-doc.pdf` (`make doc`). ## Diagnostics Le paquetage signale : clé non déclarée, clé déclarée deux fois, clé à plus d'un niveau, clé malformée, ancre posée deux fois, ancre sur une clé inconnue, parent créé implicitement, composé utilisé sans ancre (en fin de compilation), absence de `hyperref`, `\herechemid` employé pour `\chemidhere`, et, pour les familles : clé qui n'est pas un parent, famille déclarée deux fois, option de famille inconnue, valeurs données et automatiques mélangées. ## Tests ```sh make test # 19 vérifications, avec pdflatex make test-all # les mêmes, avec pdflatex, lualatex et xelatex make update-refs # régénère les références (à relire avant de committer) ``` Les PDF produits sont conservés dans `test/pdf/`, nommés `-.pdf`, pour inspection visuelle. La suite compare, pour chaque document de test, le texte extrait du PDF et les messages du `.log` à des références figées. Elle vérifie en outre deux propriétés structurelles : - le décompte des cibles de toutes les annotations de lien du PDF, ce qui détecte l'apparition d'un lien parasite dans la table des matières ; - qu'une ancre ne déplace aucun mot de la page, en comparant les boîtes de tous les mots avec et sans ancres (écart mesuré : 0,0000 pt sous pdflatex et lualatex, 0,0062 pt sous xelatex, soit un arrondi de placement). Les dix documents de la version 1 sont compilés avec `version=1` et comparés à leurs références d'origine : c'est ce qui garantit que la version figée ne bouge pas. S'y ajoutent le décompte des liens de plusieurs documents et le contenu des signets, seul endroit où le rendu en texte brut est visible de l'extérieur. Les trois moteurs donnent le même résultat ; seule l'extraction de texte de xelatex diffère, les ligatures y étant rendues par un caractère unique (`ffi` → `ffi`). Une référence propre à un moteur n'est créée que lorsqu'elle diffère réellement de la référence commune. ## Déclarer plusieurs clés d'un coup `\chemid*{clé1,clé2,...}` déclare chacune, auto-numérotée à son tour — même convention que `\chemid` : ```latex \chemid*{mol1,mol2,mol3} % trois parents : 1, 2, 3 \chemid*{mol1.a,mol1.b} % deux enfants de mol1 : 1a, 1b ``` Un nom personnalisé ne peut pas accompagner une déclaration multiple (`\chemid*{a,b}{nom}` serait ambigu) — erreur, déclarez cette clé seule. Une virgule à l'intérieur d'une seule clé est rejetée. Déclarer des enfants en bloc sans jamais déclarer leur parent à part fonctionne aussi : le parent est créé implicitement, et `\chemid{molz}` (son nom seul) affiche son numéro sans erreur. ## Déclarer après avoir utilisé `\chemid`/`\chemidhere` peuvent apparaître **avant** le `\chemid*` qui déclare la clé — comme un `\ref` avant son `\label`. La première compilation affiche `??` (l'`.aux` est encore vide) ; la deuxième résout, et le résultat reste stable ensuite, l'ordre des déclarations ne dépendant jamais de l'endroit où elles sont utilisées : ```latex Le composé \chemid{mol1} est présenté ici, mais déclaré plus loin. ... \chemid*{mol1} ``` Une déclaration en tête de préambule reste néanmoins ce qu'il y a de plus simple si vous n'avez pas de contrainte particulière : le numéro est connu dès la lecture de la clé, sans référence en avant à résoudre. ## Substitution de texte dans les figures .pdf_tex (LuaLaTeX uniquement) Un schéma exporté par Inkscape (une paire `.pdf_tex` + `.pdf`) peut avoir ses étiquettes de composés reliées à `\chemid`, comme `psfrag` rustinait autrefois du texte dans des figures `.eps` — sans les scories du `.eps`/psfrag : un `.pdf_tex` n'est que du texte LaTeX qui appelle `\includegraphics`, donc une simple substitution ligne par ligne suffit. Nécessite de compiler avec `lualatex` (ou tout autre moteur fournissant `\directlua`) ; le fichier sur le disque n'est jamais modifié, donc réexporter depuis Inkscape ne perd rien. Placez dans le dessin un marqueur texte brut pour chaque étiquette de composé (`TMP1`, `TMP2`... ce que vous voulez, tant qu'il n'apparaît pas aussi comme sous-chaîne ailleurs dans le texte de la figure), puis : ```latex \usepackage{graphicx} % necessaire au .pdf_tex lui-meme \usepackage{chemidentifier} \chemidsetup{ pdftex-font = \sffamily\small } % optionnel, une fois \chemid*{precurseur} \chemid*{produit} \begin{figure} \centering \chemidkey{TMP1}{precurseur} % TMP1 -> \chemid{precurseur} \chemidkey[1.3]{TMP2}{produit} % 1,3x plus gros que le reste \chemidnote{TMPCOND}{K$_2$CO$_3$, acetone, 70~°C} \chemidscheme[0.8]{figures/schema.pdf_tex} % echelle optionnelle \chemidhere{precurseur}\chemidhere{produit} \caption{Synthèse de \chemid{produit} à partir de \chemid{precurseur}.} \end{figure} ``` | Commande | Rôle | |---|---| | `\chemidkey[facteur]{motif}{clé}` | marqueur → numéro courant du composé, ex. `\chemid{clé}` | | `\chemidnote[facteur]{motif}{texte}` | marqueur → tout autre texte, libre | | `\chemidscheme[échelle]{chemin}` | lit le fichier, substitue, compose ; étend aussi `\graphicspath` | `\chemidscheme` consomme la liste `\chemidkey`/`\chemidnote` en attente au fur et à mesure qu'il lit le fichier : la figure suivante repart donc automatiquement d'une liste vide — pas d'étape « vider » séparée à retenir. La taille d'une étiquette substituée est le produit de trois facteurs indépendants, pour qu'une figure réduite reste lisible sans retoucher chaque étiquette à la main : 1. **`pdftex-font`** (`\chemidsetup`) — la police de base, réglée une fois pour toutes, indépendamment du texte du corps (sinon Inkscape réinjecte la famille du document, à la taille du dessin, souvent trop grande), ex. `\chemidsetup{ pdftex-font = \sffamily\fontsize{9}{11}\selectfont }`. 2. **l'`[échelle]` de `\chemidscheme`** — le même nombre transmis au `\svgscale` de la figure, pour que les étiquettes suivent la taille du dessin. 3. **le `[facteur]` optionnel de `\chemidkey`/`\chemidnote`** — une étiquette isolée par rapport aux autres de la même figure ; vaut `1` par défaut. Sous un moteur non-Lua, `\chemidscheme` déclenche une erreur claire plutôt que de ne rien faire silencieusement. `\chemidkey` prend le numéro *courant* du composé : elle ne déclare ni ne renumérote rien, les clés doivent donc toujours avoir leur `\chemid*{clé}` déclaré par ailleurs. *Pourquoi LuaLaTeX seulement ?* Une alternative en TeX pur, à base de manipulation de catcodes (à la `psfrag`), a été envisagée puis écartée : un `.pdf_tex` est du vrai code TeX/PGF, plein de `\`, `{`, `}`, `%`, `#`, `_`, `~`... Le lire tel quel puis le ré-exécuter comme du code demanderait qu'un même caractère porte deux catcodes contradictoires — inerte pendant la lecture, actif pendant l'exécution — pour un contenu arbitraire : exactement ce qui rendait `psfrag` fragile. Lua contourne le problème en traitant le fichier comme une simple chaîne de bout en bout, et ne rend la main à TeX qu'à la toute fin, lu alors sous le régime de catcodes ordinaire du document. ## Limites assumées - Un seul niveau de hiérarchie (`parent.enfant`), familles comprises. - Les listes ne sont ni triées ni dédoublonnées : `\chemid{a,b,a}` affiche `1, 2 et 1`, sans erreur. - `cleveref` n'est pas géré. - Si une clé est supprimée du document, une référence qui y pointe encore continue de se résoudre à sa dernière valeur connue tant que l'`.aux` n'a pas été effacé — la même limite que `\ref`/`\label`. ## Auteur et licence Aliocha SKRZYPCZAK Ce travail peut être distribué et/ou modifié selon les conditions de la LaTeX Project Public License, version 1.3c de cette licence ou (à votre choix) toute version ultérieure. Ce travail a le statut de maintenance LPPL « maintained ». Voir `LICENSE` pour le texte complet.