Hi, I'm KKTeX. I build LaTeX tools for teaching materials.
If you typeset chemical structural formulas in LaTeX, chemfig is the standard choice. It is flexible enough to draw everything from benzene rings to reaction schemes, but repeating the same structures across a worksheet means repeatedly matching bond lengths, line widths, and double-bond spacing.
I made KKchemstruct to package those recurring settings and structures into short commands:
\KKbenzene[2=OH,3=COOH] % salicylic acid
\KKchemchain{H-O-S(\KKdative{2}O)(\KKdative{6}O)-O-H}
\KKscheme{\KKsalicylicacid\arrow{->[\ck{CH_3OH}][Esterification]}\KKmethylsalicylate}
This article focuses on using the package rather than its implementation.
What it does
- Draw substituted benzene rings by numbered positions
- Keep bond lengths and line widths consistent in condensed structural formulas
- Assemble reaction schemes, branching reactions, and compound names
- Add leaving-group marks, hydrogen bonds, and a cross for “no reaction”
- Insert common compounds with a single command
- Scale dimensions with the surrounding text by using
em-based settings
The actual drawing is still handled by chemfig. When a prepared command is not enough, you can use ordinary chemfig syntax directly.
1. Install it
You need LuaLaTeX (recommended), or pLaTeX with dvipdfmx. The dependencies—chemfig, etoolbox, and xkeyval—are included in TeX Live.
Download KKchemstruct.sty from the GitHub repository and, for the simplest setup, put it next to your .tex file:
my-document/
├── main.tex
└── KKchemstruct.sty
Then add one line to the preamble:
\usepackage{KKchemstruct}
Here is a minimal example:
\documentclass[a4paper,11pt]{article}
\usepackage[margin=22mm]{geometry}
\usepackage{KKchemstruct}
\begin{document}
\begin{center}
\KKname{\KKsalicylicacid}{Salicylic acid}
\end{center}
\end{document}
Compile it as usual:
lualatex -interaction=nonstopmode -halt-on-error main.tex
Documents using \KKchemmark or \KKhbond need two runs so that TikZ can resolve the node positions.
2. Draw substituted benzene rings by number
Use \KKbenzene and assign substituents to numbered positions:
\KKbenzene[2=OH,3=COOH]
Position 1 is at the top, and the numbers continue clockwise:
1
6 2
5 3
4
These three commands draw salicylic acid, terephthalic acid, and unsubstituted benzene:
\KKbenzene[2=OH,3=COOH]
\KKbenzene[1=COOH,4=COOH]
\KKbenzene[]
Subscripts such as COOCH_3 work directly:
\KKbenzene[2=OH,3=COOCH_3]
Use angle to rotate a ring and sep to change the side length for that ring only:
\KKbenzene[2=OH,angle=30,sep=1.0em]
If a substituent comes too close to an inner double bond, reverse the Kekulé pattern with kekule=b:
\KKbenzene[1=OH,kekule=b]
For a horizontally connected ring inside a line of text, use one of these commands:
| Command | Purpose |
|---|---|
\KKphenylring |
An unsubstituted ring |
\KKphenyl{COOH} |
A substituent on the right |
\KKphenylene{SO_3H} |
Bonds on both sides, for inserting the ring into a chain |
Their baselines are adjusted so that they do not excessively increase the line spacing.
3. Write condensed structural formulas
Pass chains of atom labels to \KKchemchain:
\KKchemchain{CH_2(-OH)-[6,1.15]CH(-OH)-[6,1.15]CH_2-OH}
The angle numbers follow chemfig's 45-degree system. These four cover many classroom formulas:
| Value | Direction |
|---|---|
[0] |
right |
[2] |
up |
[4] |
left |
[6] |
down |
The number after the angle is a length multiplier, so [6,1.15] means downward at 1.15 times the default length.
Common fragments have shorter commands:
\KKchemchain{R_1-C\KKcarbonyl-OH}
\KKchemchain{H-O-S(\KKdative{2}O)(\KKdative{6}O)-O-H}
| Command | Result |
|---|---|
\KKcarbonyl |
Upward C=O |
\KKcarbonyldown |
Downward C=O |
\KKdative{angle} |
A coordinate bond such as S→O, P→O, or N→O |
Rings and chains have separate commands because they need different spacing rules:
-
\KKbenzeneand\KKchemringkeep atom-center distances constant to preserve regular polygons. -
\KKchemchainkeeps the visible bond lines consistent, even after a wide label such asCH_2.
Choosing the appropriate command is often enough to make a page of formulas look much more uniform.
4. Insert common compounds with one command
Frequently used compounds already have named commands:
\KKsalicylicacid
\KKmethylsalicylate
\KKaspirin
\KKphthalicanhydride
\KKmaleicacid
\KKfumaricacid
\KKnitricacid
\KKsulfuricacid
\KKphosphoricacid
\KKglycerol
\KKtriglyceride{R_1}{R_2}{R_3}
Benzoic acid, phenol, all three phthalic-acid isomers, maleic anhydride, and more are also included. See the English manual for the full list.
Use \KKname to place a name below a structure:
\KKname{\KKaspirin}{Acetylsalicylic acid}
5. Build reaction schemes
Inside \KKscheme, arrange structures with chemfig's \arrow command:
\KKscheme{%
\KKname{\KKsalicylicacid}{Salicylic acid}
\arrow{->[\ck{CH_3OH}][Esterification]}
\KKname{\KKmethylsalicylate}{Methyl salicylate}}
Arrow labels are not in math mode. Wrap formulas such as CH_3OH in \ck{...}:
\arrow{->[\ck{CH_3OH}][Esterification]}
The longer alias \KKchemformula{...} does the same thing.
For one substrate branching into two reactions, \KKbranchscheme takes seven arguments:
\KKbranchscheme
{\KKname{\KKsalicylicacid}{Salicylic acid}}
{\ck{CH_3OH}}{Esterification}
{\KKname{\KKmethylsalicylate}{Methyl salicylate}}
{\ck{(CH_3CO)_2O}}{Acetylation}
{\KKname{\KKaspirin}{Acetylsalicylic acid}}
The order is: substrate, upper reagent, upper reaction name, upper product, lower reagent, lower reaction name, lower product.
6. Add annotations
To outline a leaving group, mark two atoms with @{name} and pass the names to \KKchemmark:
\KKchemchain{R-C\KKcarbonyl-@{s}OH}\ +\
\KKchemchain{@{e}H-O-R'}%
\KKchemmark{s}{e}
To draw an intramolecular hydrogen bond:
\KKbenzene[2=@{oh}OH,3=C@{co}OOH]%
\KKhbond{oh}{co}
To place a cross over a structure:
\KKchemcross{\KKphenol}
Because \KKchemmark and \KKhbond refer to TikZ nodes, compile twice:
lualatex -interaction=nonstopmode -halt-on-error main.tex
lualatex -interaction=nonstopmode -halt-on-error main.tex
7. Adjust bond lengths and line widths together
Change global dimensions with \KKchemsetup:
\KKchemsetup{
ring sep=2.0em,
bond width=0.09em,
double bond sep=0.4em
}
Put the setup in a group when you want a local change:
\begingroup
\KKchemsetup{ring sep=2.0em,bond width=0.09em}
\KKsalicylicacid
\endgroup
% Back to the defaults here
\KKsalicylicacid
The dimensions are primarily expressed in em, so the structures follow surrounding size changes such as \small and \large.
8. Draw rings that do not have a prepared command
For fused rings and other special cases, pass raw chemfig syntax to \KKchemring:
\KKchemring[atom sep=1.75em]{%
*6(=-*5(-C(=O)-O-C(=O)-)=-=-)}
KKchemstruct is not meant to hide chemfig. Its purpose is to standardize common settings and components: use short commands for repeated structures, and drop down to chemfig syntax only for the unusual parts.
Common pitfalls
Parentheses create branches
In chemfig, ( and ) are structural branch syntax. If you only want to display a molecular formula such as CH_3(CH_2)_{11}, use \ck{...} rather than passing it directly to \KKchemchain.
Wrap formulas in arrow labels with \ck
Unlike atom labels in a structure, reaction-arrow labels are not automatically typeset in math mode:
\arrow{->[\ck{H_2SO_4}][Heat]}
Compile annotations twice
The positions used by \KKchemmark and \KKhbond are not final on the first run. If an annotation is displaced even though compilation succeeds, run LaTeX again.
Use the ring and chain commands for their intended geometry
Use \KKbenzene or \KKchemring when a regular polygon matters, and \KKchemchain for a condensed structural formula. Some inputs compile with either command, but the spacing will differ.
License and dependencies
KKchemstruct is released under the MIT License. It uses the LPPL 1.3c-licensed chemfig for drawing, plus the LPPL-licensed etoolbox and xkeyval packages. These dependencies are loaded from your TeX installation; their code is not copied into KKchemstruct.
Start with four commands
KKchemstruct keeps chemfig's flexibility while making repeated classroom structures shorter and more consistent. These four commands are enough to get started:
\KKbenzene[2=OH,3=COOH] % substituted benzene
\KKchemchain{...} % condensed structural formula
\KKscheme{...} % reaction scheme
\KKchemsetup{...} % dimensions
When you need a structure that is not predefined, use chemfig syntax through \KKchemring or \KKchemchain. If the same structure keeps appearing, that is the right time to turn it into your own command.




Top comments (0)