% ============================================================
%  tikz-chemlab-doc.tex
%  tikz-chemlab 使用手册
%  参考 pst-labo-doc.tex (Herbert Voß 等) 改写为 TikZ 版本
% ============================================================
\documentclass[11pt,a4paper,oneside]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{microtype}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{listings}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{array}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{enumitem}
\usepackage{caption}
\usepackage{marginnote}
\usepackage{colortbl}
\usepackage{tabularx}

\usetikzlibrary{arrows.meta,calc,patterns,patterns.meta,shadings,decorations.pathmorphing,decorations.pathreplacing}
\usepackage{tikz-chemlab}

% --- 颜色定义 ---
\definecolor{hellgelb}{rgb}{1,1,0.8}
\definecolor{shadecolor}{rgb}{0.92,0.92,0.92}
\definecolor{codebg}{rgb}{0.96,0.96,0.96}
\definecolor{keywordcolor}{rgb}{0.13,0.29,0.53}
\definecolor{commentcolor}{rgb}{0.5,0.5,0.5}
\definecolor{stringcolor}{rgb}{0.63,0.12,0.12}
\definecolor{linkblue}{rgb}{0.1,0.3,0.7}
\definecolor{tableheadcolor}{gray}{0.85}
\definecolor{tablerowcolor}{gray}{0.95}

% --- listings 设置 ---
\lstset{
  basicstyle=\ttfamily\footnotesize,
  backgroundcolor=\color{codebg},
  keywordstyle=\color{keywordcolor}\bfseries,
  commentstyle=\color{commentcolor}\itshape,
  stringstyle=\color{stringcolor},
  showstringspaces=false,
  breaklines=true,
  breakatwhitespace=false,
  postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
  tabsize=2,
  columns=flexible,
  keepspaces=true,
  frame=single,
  framerule=0pt,
  rulecolor=\color{gray!30},
  xleftmargin=8pt,
  xrightmargin=8pt,
  aboveskip=8pt,
  belowskip=8pt,
  morekeywords={tkzTestTube,tkzRoundFlask,tkzHeatTube,tkzHeatFlask,
    tkzTitration,tkzDistillation,tkzGraduatedCylinder,tkzPipette,tkzLargePipette,
    tkzFunnel,tkzSeparatoryFunnel,tkzStand,tkzChampagneBubbles,tkzBubbles,
    tkzFilaments,tkzBalls,tkzBubblesThreeD,tkzIronNail,tkzCopperTurnings,
    tkzZincGranules,tkzColumn,tkzRoundFlaskReflux,tkzHeaterRoundFlask,
    chemlabset,chemlabUpdateLineWidths,
    tikzpicture,begin,end,scope,shift,scale,rotate,draw,fill,node,at,
    useasboundingbox,rectangle,ellipse,arc,clip,foreach,pgfkeys,
    line width,line cap,line join,fill,draw,filldraw,pattern,
    bottom color,top color,inner color,outer color,shading,ball color,
    rounded corners,arrow,Stealth,->,--,cycle,controls,and},
  literate={\\}{{\textcolor{keywordcolor}\textbackslash}}1
}

% --- hyperref 设置 ---
\hypersetup{
  colorlinks=true,
  linkcolor=linkblue,
  urlcolor=linkblue,
  citecolor=linkblue,
  pdftitle={tikz-chemlab Documentation},
  pdfauthor={tikz-chemlab},
}

% --- 自定义命令 ---
\newcommand{\Lpack}[1]{\texttt{#1}}
\newcommand{\Lcmd}[1]{\texttt{\textbackslash#1}}
\newcommand{\Lopt}[1]{\texttt{#1}}
\newcommand{\Lfile}[1]{\texttt{#1}}
\newcommand{\Lenv}[1]{\texttt{#1}}
\newcommand{\Larg}[1]{\texttt{\{#1\}}}

% --- 表格行颜色 ---
\let\oldtabularnewline\tabularnewline
\renewcommand{\arraystretch}{1.15}

% --- 表格宽度辅助 ---
% 0.8\textwidth 的表格总宽, 各列按比例分配
\newlength{\tblw}
\setlength{\tblw}{0.8\textwidth}

% --- 标题信息 ---
\title{\textbf{tikz-chemlab}\\[4pt]
\large A TikZ port of \texttt{pst-labo} for chemical laboratory drawings}
\author{Aihua Wang\\
\small \texttt{https://github.com/aihua/tikz-chemlab}\\
\small Ported from \texttt{pst-labo} by Denis Girou, Christophe Jorssen,\\
Manuel Luque, Herbert Vo\ss}
\date{\today}

\begin{document}
\maketitle

% 允许 LaTeX 在必要时拉伸空白, 减少 overfull \hbox
\sloppy
\emergencystretch=3em

\begin{abstract}
\noindent
\Lpack{tikz-chemlab} is a TikZ-based reimplementation of the well-known
\Lpack{pst-labo} package.  It provides a collection of high-level macros
for drawing chemical laboratory glassware---test tubes, flasks, beakers,
burettes, distillation apparatus, separating funnels, and many
more---using the TikZ drawing engine instead of PSTricks.

The main differences from \Lpack{pst-labo} are:

\begin{itemize}[nosep,leftmargin=1.5em]
  \item Command names: \texttt{pst} prefix $\to$ \texttt{tkz} prefix;
        French words $\to$ English (e.g.\ \texttt{TubeEssais}
        $\to$ \texttt{TestTube}, \texttt{Eprouvette} $\to$
        \texttt{GraduatedCylinder}, \texttt{Ballon} $\to$
        \texttt{RoundFlask}).
  \item Option keys: French $\to$ English (e.g.\ \texttt{niveauLiquide1}
        $\to$ \texttt{liquidLevel1}, \texttt{tubePenche} $\to$
        \texttt{tiltAngle}, \texttt{bouchon} $\to$ \texttt{stopper}).
  \item \Lenv{pspicture} environments are replaced by \Lenv{tikzpicture}
        environments.
  \item \Lcmd{rput} is replaced by \Lcmd{begin}\Larg{scope}\texttt{[shift=\Larg{\Larg{x,y}}]}
        or \Lcmd{node}\texttt{ at (x,y)}.
  \item \Lcmd{psset}\Larg{unit=Ncm} is replaced by
        \Lenv{tikzpicture}\texttt{[scale=N]} or
        \Lcmd{begin}\Larg{scope}\texttt{[scale=N]}.
  \item PSTricks \Lcmd{psline}, \Lcmd{psframe}, \Lcmd{psellipse} are
        replaced by their TikZ equivalents (\Lcmd{draw}, \Lcmd{fill},
        \Lcmd{filldraw}).
  \item \Lcmd{newpsstyle} is replaced by \Lcmd{tikzset}\Larg{\dots}.
\end{itemize}

This document describes all macros, options, predefined colours and
styles, and provides ready-to-compile examples.
\end{abstract}

\vfill
\noindent\textit{Thanks to the original \texttt{pst-labo} authors for
their excellent work, which made this port possible.}

\medskip
\noindent\textbf{Repository:} \url{https://github.com/aihua/tikz-chemlab}\\
\textbf{Support:} \url{https://github.com/aihua/tikz-chemlab/issues}

\clearpage
\tableofcontents
\clearpage

% ============================================================
\section{Installation and loading}\label{sec:install}
% ============================================================

The package consists of three files which must be placed in the same
directory or in the TeX search path:

\begin{center}
\footnotesize
\begin{tabularx}{0.8\textwidth}{@{}l X@{}}
\toprule
\textbf{File} & \textbf{Role} \\
\midrule
\Lfile{tikz-chemlab.sty}      & LaTeX package wrapper (loads TikZ + main file) \\
\Lfile{tikz-chemlab.tex}      & Main implementation (parameter system + high-level macros) \\
\Lfile{tikz-chemlabObj.tex}   & Shape library (low-level drawing primitives) \\
\bottomrule
\end{tabularx}
\end{center}

Load the package in the preamble:

\begin{lstlisting}
\usepackage{tikz-chemlab}
\end{lstlisting}

This automatically loads \Lpack{tikz} and the required libraries
(\texttt{arrows.meta}, \texttt{calc}, \texttt{patterns},
\texttt{shadings}, \texttt{decorations.pathmorphing},
\texttt{decorations.pathreplacing}).

% ============================================================
\section{Quick start}\label{sec:quickstart}
% ============================================================

A minimal example:

\begin{lstlisting}
\documentclass{standalone}
\usepackage{tikz-chemlab}
\begin{document}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube
\end{tikzpicture}
\end{document}
\end{lstlisting}

This draws a standard test tube at 50\% scale.  The correspondence
between \Lpack{pst-labo} and \Lpack{tikz-chemlab} is:

\begin{center}
\footnotesize
\begin{tabularx}{0.78\textwidth}{@{}XX@{}}
\toprule
\textbf{pst-labo} & \textbf{tikz-chemlab} \\
\midrule
\Lcmd{psset}\Larg{unit=0.5cm}    & \Lenv{tikzpicture}\texttt{[scale=0.5]} \\
\Lcmd{psset}\Larg{glassType=ballon} & pass as option: \texttt{[glassType=roundFlask]} \\
\Lcmd{rput}\texttt{(x,y)}\Larg{obj} & \Lcmd{begin}\Larg{scope}\texttt{[shift=\{(x,y)\}]} \dots\Lcmd{end}\Larg{scope} \\
\Lcmd{psline}\texttt{\{->\}(a,b)(c,d)} & \Lcmd{draw}\texttt{[-\{Stealth\}] (a,b) -- (c,d);} \\
\Lcmd{psgrid}                     & \texttt{[help lines]} or \Lcmd{draw}\texttt{[help lines] (0,0) grid (N,N);} \\
\bottomrule
\end{tabularx}
\end{center}

% ============================================================
\section{Parameters}\label{sec:parameters}
% ============================================================

Table~\ref{tab:parameters} lists all parameters recognised by
\Lpack{tikz-chemlab}.  They are set either via
\Lcmd{chemlabset}\Larg{\dots} (global, equivalent to
\Lcmd{psset}\texttt{[pst-labo]}\Larg{\dots}) or as optional arguments
to individual macros.

{\footnotesize
\begin{longtable}{@{}l l p{0.42\textwidth}@{}}
\caption{All parameters of \Lpack{tikz-chemlab}}\label{tab:parameters} \\
\toprule
\textbf{Parameter} & \textbf{Default} & \textbf{Description} \\
\midrule
\endfirsthead
\multicolumn{3}{c}{{\bfseries Table~\ref{tab:parameters} (continued)}} \\
\toprule
\textbf{Parameter} & \textbf{Default} & \textbf{Description} \\
\midrule
\endhead
\rowcolor{tablerowcolor}
\Lopt{glassType} & \texttt{tube} & Type of glass container: \texttt{tube}, \texttt{roundFlask}, \texttt{beaker}, \texttt{erlenmeyer}, \texttt{reagentBottle}, \texttt{volumetricFlask}, \texttt{watchGlass} \\
\Lopt{stopper} & \texttt{false} & Inserts a stopper \\
\rowcolor{tablerowcolor}
\Lopt{clamp} & \texttt{false} & Attaches a wooden test-tube clamp \\
\Lopt{straightTube} & \texttt{false} & Inserts a straight narrow glass tube \\
\rowcolor{tablerowcolor}
\Lopt{elbowTube} & \texttt{false} & Inserts a right-angled glass tube \\
\Lopt{uTube} & \texttt{false} & Inserts a U-shaped glass tube \\
\rowcolor{tablerowcolor}
\Lopt{uTubeLong} & \texttt{false} & U-shaped tube extending to bottom \\
\Lopt{curvedTube} & \texttt{false} & Creates a gas-collection device with burner \\
\rowcolor{tablerowcolor}
\Lopt{curvedTubeShort} & \texttt{false} & Gas-collection device without burner \\
\Lopt{doubleTube} & \texttt{false} & Two narrow tubes, one with stopcock \\
\rowcolor{tablerowcolor}
\Lopt{condenserBulbs} & \texttt{false} & Ball condenser (reflux setup) \\
\Lopt{label} & \texttt{false} & Displays the label defined by \Lopt{Number} \\
\rowcolor{tablerowcolor}
\Lopt{Number} & \texttt{(empty)} & Label text (used with \Lopt{label}) \\
\Lopt{tiltAngle} & \texttt{0} & Tilt angle in degrees ($-65\ldots+65$) \\
\rowcolor{tablerowcolor}
\Lopt{liquidLevel1} & \texttt{50} & Liquid level 1 (0--100, percentage) \\
\Lopt{liquidLevel2} & \texttt{0} & Liquid level 2 \\
\rowcolor{tablerowcolor}
\Lopt{liquidLevel3} & \texttt{0} & Liquid level 3 \\
\Lopt{liquidStyle1} & \texttt{liquidStyle1} & Style for liquid 1 \\
\rowcolor{tablerowcolor}
\Lopt{liquidStyle2} & \texttt{liquidStyle2} & Style for liquid 2 \\
\Lopt{liquidStyle3} & \texttt{liquidStyle3} & Style for liquid 3 \\
\rowcolor{tablerowcolor}
\Lopt{substance} & \texttt{(empty)} & Substance macro (e.g.\ \Lcmd{tkzChampagneBubbles}) \\
\Lopt{solid} & \texttt{(empty)} & Solid substance macro \\
\rowcolor{tablerowcolor}
\Lopt{burette} & \texttt{true} & Show/hide burette (in \Lcmd{tkzTitration}) \\
\Lopt{pHMeter} & \texttt{false} & Show pH-meter \\
\rowcolor{tablerowcolor}
\Lopt{magneticStirrer} & \texttt{true} & Show magnetic stirrer / hotplate \\
\Lopt{bunsenBurner} & \texttt{true} & Show Bunsen burner \\
\rowcolor{tablerowcolor}
\Lopt{bubbling} & \texttt{false} & Adds bubbling test tube \\
\Lopt{gasCollection} & \texttt{false} & Adds gas-collection vessel \\
\rowcolor{tablerowcolor}
\Lopt{tubeOnly} & \texttt{false} & Suppresses extra container space \\
\Lopt{buretteLevel} & \texttt{20} & Burette liquid level \\
\rowcolor{tablerowcolor}
\Lopt{buretteColor} & \texttt{VeryPaleOrange} & Burette liquid colour \\
\Lopt{reagentLevel} & \texttt{2} & Reagent level (pipette) \\
\rowcolor{tablerowcolor}
\Lopt{reagentColor} & \texttt{PaleOrange} & Reagent colour \\
\Lopt{MixtureStyle} & \texttt{BlueDiffusion} & Distillation mixture style \\
\rowcolor{tablerowcolor}
\Lopt{DistillateColor} & \texttt{yellow} & Distillate colour \\
\Lopt{TapOpen} & \texttt{false} & Separating funnel tap open/closed \\
\rowcolor{tablerowcolor}
\Lopt{buretteReagent} & \texttt{(empty)} & Burette reagent label text \\
\Lopt{beakerReagent} & \texttt{(empty)} & Beaker reagent label text \\
\bottomrule
\end{longtable}
}

% ============================================================
\subsection{\texttt{glassType}}\label{subsec:glassType}
% ============================================================

\Lopt{glassType} selects the type of glass container.  A normal test
tube is used by default.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube
\end{tikzpicture}

\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[glassType=roundFlask]
\end{tikzpicture}

\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[glassType=erlenmeyer]
\end{tikzpicture}

\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[glassType=beaker]
\end{tikzpicture}

\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[glassType=reagentBottle]
\end{tikzpicture}

\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[glassType=volumetricFlask]
\end{tikzpicture}

\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[glassType=watchGlass]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{stopper}}\label{subsec:stopper}
% ============================================================

The option \Lopt{stopper} seals the glass container with a stopper.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.45]
  \tkzTestTube[glassType=tube,stopper=true]

  \begin{scope}[xshift=3cm]
    \tkzTestTube[glassType=roundFlask,stopper=true]
  \end{scope}

  \begin{scope}[xshift=6cm]
    \tkzTestTube[glassType=erlenmeyer,stopper=true]
  \end{scope}

  \begin{scope}[xshift=9cm]
    \tkzTestTube[glassType=reagentBottle,stopper=true]
  \end{scope}

  \begin{scope}[xshift=12cm]
    \tkzTestTube[glassType=watchGlass,stopper=true]
  \end{scope}
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{clamp}}\label{subsec:clamp}
% ============================================================

The option \Lopt{clamp} attaches a wooden test-tube clamp.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[glassType=tube,stopper=true,clamp=true]
  \tkzTestTube[glassType=erlenmeyer,stopper=true,clamp=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{straightTube}}\label{subsec:straightTube}
% ============================================================

\Lopt{straightTube} inserts a narrow straight glass tube.  It is normally
combined with \Lopt{stopper=true}.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[straightTube=true]
  \tkzTestTube[glassType=roundFlask,straightTube=true]
  \tkzTestTube[glassType=erlenmeyer,straightTube=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{elbowTube}}\label{subsec:elbowTube}
% ============================================================

\Lopt{elbowTube} is identical to \Lopt{straightTube} but draws a
right-angled glass tube.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[glassType=erlenmeyer,elbowTube=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{uTube} and \texttt{uTubeLong}}\label{subsec:uTube}
% ============================================================

\Lopt{uTube} draws a U-shaped glass tube.
\Lopt{uTubeLong} extends the U-tube to the bottom (used in
\Lcmd{tkzHeatFlask}).

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatFlask[glassType=roundFlask,uTube=true]
  \tkzHeatFlask[glassType=roundFlask,uTubeLong=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{label} and \texttt{Number}}\label{subsec:label}
% ============================================================

\Lopt{label} toggles display of labels defined by \Lopt{Number}.

\textit{Important:} In \Lpack{tikz-chemlab}, \Lcmd{tkzTestTube} resets
parameters to defaults on each call.  Therefore \Lopt{label} must
be passed explicitly to each invocation, even if
\Lcmd{chemlabset}\Larg{label} was used globally.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[label=true,Number=1]
  \tkzTestTube[label=true,Number=2]
  \tkzTestTube[glassType=reagentBottle,stopper=true,%
                 label=true,Number={\small Cu$^{2+}$}]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{tiltAngle}}\label{subsec:tiltAngle}
% ============================================================

\Lopt{tiltAngle} tilts the device to any angle in the range
$-65\ldots+65$ degrees while keeping the liquid surface horizontal.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[straightTube=true,tiltAngle=40]
  \tkzTestTube[tiltAngle=-20,stopper=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{tubeOnly}}\label{subsec:tubeOnly}
% ============================================================

\Lopt{tubeOnly} influences the bounding box of \Lcmd{tkzHeatTube}.
When set, no extra space is reserved for an additional container on the
right.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatTube[bunsenBurner=true,bubbling=true,glassType=roundFlask]
\end{tikzpicture}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatTube[tubeOnly=true,glassType=roundFlask]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{bunsenBurner}}\label{subsec:bunsenBurner}
% ============================================================

\Lopt{bunsenBurner} toggles the Bunsen burner.  It defaults to
\texttt{true} for \Lcmd{tkzHeatTube} and \texttt{false} for
\Lcmd{tkzHeatFlask}.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatTube[tubeOnly=true]
  \tkzHeatTube[tubeOnly=true,bunsenBurner=false]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{bubbling}}\label{subsec:bubbling}
% ============================================================

\Lopt{bubbling} creates an additional test tube connected via a narrow
glass tube.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatTube[tubeOnly=true]
  \tkzHeatTube[bubbling=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{substance}}\label{subsec:substance}
% ============================================================

\Lopt{substance} selects the type of substance inside the container.
Table~\ref{tab:substance} lists the available macros.

\begin{table}[htb]
\centering
\caption{Macros for the option \Lopt{substance}}\label{tab:substance}
\footnotesize
\begin{tabular}{@{}p{0.48\tblw}p{0.12\tblw}p{0.2\tblw}@{}}
\toprule
\textbf{Macro} & \textbf{Default} & \textbf{Comment} \\
\midrule
\rowcolor{tablerowcolor}
\Lcmd{tkzChampagneBubbles}\texttt{[N]} & 25 & Champagne bubbles \\
\Lcmd{tkzFilaments}\texttt{[N]}\Larg{color} & 5 & Filaments \\
\rowcolor{tablerowcolor}
\Lcmd{tkzBalls}\texttt{[N]} & 50 & 2D balls \\
\Lcmd{tkzBubblesThreeD}\texttt{[N]}\Larg{color} & 50 & 3D balls \\
\bottomrule
\end{tabular}
\end{table}

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube
  \tkzTestTube[substance=\tkzChampagneBubbles]
  \tkzTestTube[substance=\tkzFilaments{red}]
  \tkzTestTube[substance=\tkzBalls]
  \tkzTestTube[substance=\tkzBubblesThreeD{white}]
\end{tikzpicture}
\end{lstlisting}

When using optional parameters for the internal loop count, enclose the
macro call in curly braces:

\begin{lstlisting}
\tkzTestTube[substance={\tkzChampagneBubbles[80]}]
\tkzTestTube[substance={\tkzFilaments[20]{black}}]
\tkzTestTube[substance={\tkzBalls[80]}]
\tkzTestTube[substance={\tkzBubblesThreeD[20]{white}}]
\end{lstlisting}

% ============================================================
\subsection{\texttt{solid}}\label{subsec:solid}
% ============================================================

\Lopt{solid} describes solid substances.  Table~\ref{tab:solid}
lists the available macros.

\begin{table}[htb]
\centering
\caption{Macros for the option \Lopt{solid}}\label{tab:solid}
\begin{tabular}{@{}p{0.5\tblw}p{0.2\tblw}@{}}
\toprule
\textbf{Macro} & \textbf{Default} \\
\midrule
\rowcolor{tablerowcolor}
\Lcmd{tkzCopperTurnings}\texttt{[N]} & 30 \\
\Lcmd{tkzIronNail}\texttt{[N]} & 60 \\
\rowcolor{tablerowcolor}
\Lcmd{tkzZincGranules}\texttt{[N]} & 25 \\
\bottomrule
\end{tabular}
\end{table}

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube[solid=\tkzCopperTurnings]
  \tkzTestTube[solid=\tkzIronNail]
  \tkzTestTube[solid=\tkzZincGranules]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{curvedTube} and \texttt{curvedTubeShort}}\label{subsec:curvedTube}
% ============================================================

\Lopt{curvedTube} creates a device to collect exhaust gas from the
glass container, including a Bunsen burner.
\Lopt{curvedTubeShort} does the same without a burner.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatFlask[glassType=erlenmeyer,
                gasCollection=true,substance=\tkzCopperTurnings]
  \tkzHeatFlask[glassType=erlenmeyer,
                gasCollection=true,substance=\tkzCopperTurnings,
                curvedTube=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{doubleTube}}\label{subsec:doubleTube}
% ============================================================

\Lopt{doubleTube} arranges two narrow glass tubes, one with a stopcock.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzRoundFlask
  \tkzRoundFlask[doubleTube=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{condenserBulbs}}\label{subsec:condenserBulbs}
% ============================================================

\Lopt{condenserBulbs} outputs a reflux setup with a ball condenser.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzRoundFlask[condenserBulbs=true,glassType=roundFlask,substance=\tkzIronNail]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{gasCollection}}\label{subsec:gasCollection}
% ============================================================

\Lopt{gasCollection} adds a device for collecting expanded gases.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatFlask[glassType=reagentBottle,curvedTube=true,
                substance={\tkzFilaments[10]{red}}]
  \tkzHeatFlask[glassType=reagentBottle,curvedTube=true,
                substance={\tkzFilaments[10]{red}},
                gasCollection=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{burette}}\label{subsec:burette}
% ============================================================

\Lcmd{tkzTitration} displays a burette by default.  \Lopt{burette=false}
suppresses it.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.4]
  \tkzTitration[glassType=erlenmeyer]
  \tkzTitration[glassType=erlenmeyer,burette=false]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{buretteLevel} and \texttt{buretteColor}}\label{subsec:buretteLevel}
% ============================================================

These control the amount and colour of the fluid in the burette.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.4]
  \tkzTitration[buretteLevel=25,buretteColor=cyan]
  \tkzTitration[buretteLevel=10]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{MixtureStyle} and \texttt{DistillateColor}}\label{subsec:MixtureStyle}
% ============================================================

\Lopt{MixtureStyle} defines the colour of the chemical mixture in the
distillation flask (must be a gradient style).  \Lopt{DistillateColor}
defines the distillate colour without restriction.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.4]
  \tkzDistillation
  \tkzDistillation[MixtureStyle=Diffusion,DistillateColor=red]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{pHMeter}}\label{subsec:pHMeter}
% ============================================================

\Lopt{pHMeter} displays a pH-meter (only with \Lcmd{tkzTitration}).

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTitration
  \tkzTitration[pHMeter=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{magneticStirrer}}\label{subsec:magneticStirrer}
% ============================================================

\Lopt{magneticStirrer} is active by default and displays a
hotplate with a magnetic stirrer.  When deactivated, only a plain
rectangle is drawn.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTitration
  \tkzTitration[magneticStirrer=false]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\texttt{liquidLevel1/2/3} and \texttt{liquidStyle1/2/3}}\label{subsec:niveauLiquide}
% ============================================================

These define fluid level (0--100) and style for up to three liquid
layers, where \texttt{liquidLevel1} > \texttt{liquidLevel2} > \texttt{liquidLevel3}.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.4]
  \tkzTitration[buretteLevel=18,liquidLevel1=30,%
             liquidStyle1=Champagne,pHMeter=true]
  \tkzTitration[buretteLevel=20,liquidLevel1=40,%
             liquidStyle1=Champagne,pHMeter=false,%
             magneticStirrer=false]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\section{Predefined colours and styles}\label{sec:styles}
% ============================================================

The following colours and styles are predefined in
\Lpack{tikz-chemlab}.  All can be redefined by the user.

\subsection*{Colours}

\begin{lstlisting}
\definecolor{Beige}          {rgb}{0.96,0.96,0.86}
\definecolor{LightGray}      {gray}{0.80}
\definecolor{VeryLightGray}  {cmyk}{0,0,0,0.1}
\definecolor{VeryPaleOrange} {cmyk}{0,0.1,0.3,0}
\definecolor{PaleOrange}     {rgb}{1.00,0.78,0.55}
\definecolor{LightBlue1}      {rgb}{0.60,0.80,1.00}
\definecolor{LightBlue}      {rgb}{0.68,0.85,0.90}
\definecolor{Copper}         {cmyk}{0,0.9,0.9,0.2}
\definecolor{Brown}         {rgb}{0.50,0.25,0.00}
\definecolor{woodColor}      {rgb}{0.957,0.84,0.69}
\definecolor{AqueousPhaseColor}{cmyk}{0.215686,0.062745,0,0}
\definecolor{OrganicPhaseColor}{cmyk}{0.223529,0.094118,0.501961,0}
\end{lstlisting}

\subsection*{Liquid styles (TikZ \texttt{\textbackslash tikzset})}

\begin{lstlisting}
\tikzset{
  liquidStyle1/.style={fill=cyan,draw=none},
  liquidStyle2/.style={fill=yellow,draw=none},
  liquidStyle3/.style={fill=magenta,draw=none},
  Ball3D/.style={shading=ball,ball color=cyan,draw=none},
  Champagne/.style={fill=Beige,draw=none},
  Blood/.style={fill=red,draw=none},
  Cobalt/.style={fill=blue,line width=0.2cm},
  Oil/.style={fill=yellow,draw=none},
  Vinegar/.style={fill=magenta,draw=none},
  Diffusion/.style={bottom color={rgb,255:red,0;green,25;blue,242},
                    top color=cyan,draw=none},
  MixtureDiffusion2/.style={bottom color=white,top color=red,draw=red},
  flameAndGrill/.style={bottom color=PaleOrange,top color=yellow,draw=none},
  YellowStripes/.style={pattern=north east lines,pattern color=yellow},
  BlueDiffusion/.style={bottom color=green,top color=cyan,draw=none},
  AqueousPhase/.style={fill=AqueousPhaseColor,draw=none},
  OrganicPhase/.style={fill=OrganicPhaseColor,draw=none},
}
\end{lstlisting}

\subsection*{Defining a custom style}

Use \Lcmd{tikzset} to define a new liquid style:

\begin{lstlisting}
\tikzset{Nickel/.style={fill=green,draw=none}}
\tkzTestTube[liquidStyle1=Nickel]
\end{lstlisting}

% ============================================================
\section{Line width and styles}\label{sec:linewidth}
% ============================================================

\Lpack{tikz-chemlab} provides a sophisticated line-width system that
automatically scales with the current TikZ \Lopt{scale}.  Six
presets are available via \Lcmd{chemlabset}\Larg{style=\dots}:

\begin{table}[htb]
\centering
\caption{Predefined line-width styles}\label{tab:linestyles}
\footnotesize
\begin{tabularx}{0.8\textwidth}{@{}l l l l l@{}}
\toprule
\textbf{Style} & \textbf{Outline} & \textbf{Ellipse} & \textbf{Tube ellipse} & \textbf{Graduation} \\
\midrule
\rowcolor{tablerowcolor}
\texttt{default}      & 0.053\,cm & 0.07\,cm & 0.08\,cm & 0.02\,cm \\
\texttt{publication}  & 0.4\,pt   & 0.6\,pt  & 0.8\,pt  & 0.4\,pt \\
\rowcolor{tablerowcolor}
\texttt{presentation} & 0.8\,pt   & 1.2\,pt  & 1.6\,pt  & 0.6\,pt \\
\texttt{schematic}    & 0.6\,pt   & 0.8\,pt  & 1.2\,pt  & 0.4\,pt \\
\rowcolor{tablerowcolor}
\texttt{draft}        & 0.4\,pt   & 0.4\,pt  & 0.4\,pt  & 0.4\,pt \\
\texttt{bold}         & 1.2\,pt   & 1.6\,pt  & 1.6\,pt  & 0.8\,pt \\
\bottomrule
\end{tabularx}
\end{table}

\begin{lstlisting}
\chemlabset{style=publication}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube
\end{tikzpicture}
\end{lstlisting}

Individual line widths can also be set:

\begin{lstlisting}
\chemlabset{outline line width=0.04cm}
\chemlabset{graduation line width=thick}
\chemlabset{line width=0.5pt}  % sets all four at once
\end{lstlisting}

Valid values for named widths: \texttt{thin} (0.4\,pt),
\texttt{semithick} (0.6\,pt), \texttt{thick} (0.8\,pt),
\texttt{very thick} (1.2\,pt), \texttt{ultra thick} (1.6\,pt), or any
numeric value (e.g.\ \texttt{0.04cm}, \texttt{1pt}).

% ============================================================
\section{Macros}\label{sec:macros}
% ============================================================

% ============================================================
\subsection{\textbackslash tkzTestTube}\label{sec:tkzTestTube}
% ============================================================

Displays the simplest glass container.  Default is a test tube
(\texttt{glassType=tube}).

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTestTube
  \tkzTestTube[glassType=beaker]
  \tkzTestTube[glassType=erlenmeyer,liquidLevel1=80]
  \tkzTestTube[glassType=reagentBottle]
  \tkzTestTube[glassType=roundFlask,liquidLevel1=20,liquidStyle1=BlueDiffusion]
  \tkzTestTube[glassType=volumetricFlask]
  \tkzTestTube[glassType=watchGlass]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzHeatTube}\label{sec:tkzHeatTube}
% ============================================================

Enhances \Lcmd{tkzTestTube} with a heat block, Bunsen burner, or
second narrow glass tube.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatTube[tubeOnly=true]
  \tkzHeatTube[glassType=roundFlask,bunsenBurner=false,tubeOnly=true]
  \tkzHeatTube[glassType=erlenmeyer,bunsenBurner=true,clamp=true,tubeOnly=true]
  \tkzHeatTube[bunsenBurner=true,bubbling=true,glassType=reagentBottle]
  \tkzHeatTube[bunsenBurner=true,elbowTube=true,glassType=roundFlask,%
                    liquidLevel1=20,liquidStyle1=BlueDiffusion,%
                    tubeOnly=true,clamp=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzRoundFlask}\label{sec:tkzRoundFlask}
% ============================================================

Identical to \Lcmd{tkzTestTube} with additional options (reflux
condenser, double tube, etc.).

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzRoundFlask
  \tkzRoundFlask[glassType=erlenmeyer]
  \tkzRoundFlask[condenserBulbs=true]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzHeatFlask}\label{sec:tkzHeatFlask}
% ============================================================

Enhances \Lcmd{tkzRoundFlask} by displaying a Bunsen burner by default.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzHeatFlask
  \tkzHeatFlask[bubbling=true,uTubeLong=true,bunsenBurner=true,%
                       substance=\tkzBalls]
  \tkzHeatFlask[glassType=reagentBottle,gasCollection=true,%
                       curvedTubeShort=true,%
                       substance={\tkzFilaments[10]{red}}]
  \tkzHeatFlask[doubleTube=true,gasCollection=true,%
                       substance=\tkzIronNail]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzFunnel}\label{sec:tkzFunnel}
% ============================================================

Displays a funnel.  Called without parameters it is combined with a
test tube.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzFunnel
  \tkzFunnel[glassType=beaker,tiltAngle=-20]
  \tkzFunnel[glassType=reagentBottle,label=true,Number={37},%
                liquidStyle1=BlueDiffusion,liquidLevel1=80]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzGraduatedCylinder}\label{sec:tkzGraduatedCylinder}
% ============================================================

Displays a measuring cylinder.  Its size can be changed with the
TikZ \Lopt{scale} factor.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzGraduatedCylinder
  \tkzGraduatedCylinder[liquidLevel1=100,liquidLevel2=60,liquidLevel3=30]
\end{tikzpicture}
\end{lstlisting}

\begin{lstlisting}
% yunit=0.5cm -> yscale=0.5 (only y, x stays 1)
\begin{tikzpicture}
  \begin{scope}[yscale=0.5]\tkzGraduatedCylinder\end{scope}
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzPipette}\label{sec:tkzPipette}
% ============================================================

Displays a pipette.  Its scaling can be altered with TikZ scale factors.

\begin{lstlisting}
% unit=0.5cm -> scale=0.5
\begin{tikzpicture}[scale=0.5]
  \tkzPipette
\end{tikzpicture}

% yunit=0.5cm -> yscale=0.5 (only y, x stays 1)
\begin{tikzpicture}[yscale=0.5]
  \tkzPipette
\end{tikzpicture}
\end{lstlisting}

\textit{Note:} The option \Lopt{tiltAngle} has no effect on
\Lcmd{tkzPipette}, matching the original \Lpack{pst-labo} behaviour.

% ============================================================
\subsection{\textbackslash tkzTitration}\label{sec:tkzTitration}
% ============================================================

Displays a titration setup with a burette (max.\ 25\,mL).  An optional
pH-meter or hotplate can be selected.  Multiple \Lcmd{tkzTitration} calls
in the same \Lenv{tikzpicture} are automatically placed side by side.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzTitration
  \tkzTitration[glassType=beaker,pHMeter=true]
  \tkzTitration[buretteLevel=10,liquidLevel1=60,%
             liquidStyle1=Champagne,glassType=reagentBottle,%
             magneticStirrer=false]
  \tkzTitration[glassType=erlenmeyer,burette=false]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzDistillation}\label{sec:tkzDistillation}
% ============================================================

Displays a fractional distillation apparatus.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzDistillation
  \tkzDistillation[MixtureStyle=Diffusion,DistillateColor=red]
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzSeparatoryFunnel}\label{sec:tkzSeparatoryFunnel}
% ============================================================

Displays a separating funnel (separatory funnel) on a support stand.
Options: \Lopt{TapOpen} (tap open/closed), \Lopt{stopper} (stopper),
\Lopt{liquidLevel1} (aqueous phase level),
\Lopt{liquidLevel2} (organic phase level).

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \useasboundingbox (-2,-6) rectangle (6,16);
  \tkzStand
  \tkzSeparatoryFunnel[TapOpen=false,stopper=true]
\end{tikzpicture}
\quad
\begin{tikzpicture}[scale=0.5]
  \useasboundingbox (-2,-6) rectangle (6,16);
  \tkzStand
  \tkzSeparatoryFunnel[TapOpen=false,stopper=false,%
                     liquidLevel1=-1,liquidLevel2=10]
  % beaker below
  \begin{scope}[shift={(-0.25,-4.4)}]
    \tkzTestTube[glassType=beaker,liquidStyle1=AqueousPhase]
  \end{scope}
\end{tikzpicture}
\quad
\begin{tikzpicture}[scale=0.5]
  \useasboundingbox (-2,-6) rectangle (6,16);
  \tkzSeparatoryFunnel[TapOpen=true,stopper=false,%
                     liquidLevel1=1,liquidLevel2=1]
  \begin{scope}[shift={(-0.25,-4.4)}]
    \tkzTestTube[glassType=beaker,liquidStyle1=OrganicPhase,%
                   liquidLevel1=30]
  \end{scope}
  \tkzStand
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{\textbackslash tkzStand}\label{sec:tkzStand}
% ============================================================

Displays a support stand (retort stand) with clamp.  Used together with
\Lcmd{tkzSeparatoryFunnel}.

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \tkzStand
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\section{Positioning and coordinate mapping}\label{sec:positioning}
% ============================================================

\subsection{From \texttt{\textbackslash rput} to TikZ \texttt{shift}}

In PSTricks, \Lcmd{rput}\texttt{(x,y)}\Larg{obj} places the
\textbf{bbox centre} of \texttt{obj} at \texttt{(x,y)} (default
\Lopt{ref=c}).  In TikZ, \Lcmd{begin}\Larg{scope}\texttt{[shift=\{(x,y)\}]}
places the \textbf{local origin} \texttt{(0,0)} at \texttt{(x,y)}.

The conversion formula is:

\begin{quote}
\texttt{shift = rput\_position $-$ bbox\_centre}
\end{quote}

\subsubsection*{Example: \texttt{\textbackslash tkzGraduatedCylinder}}

\Lcmd{tkzGraduatedCylinder} bbox: \texttt{(-2,0)(2,6)}, centre \texttt{(0,3)}.
For \Lcmd{rput}\texttt{(-4.5,4.0)}:

\begin{lstlisting}
% pst-labo: \rput(-4.5,4.0){\pstEprouvette[...]}
% shift = (-4.5 - 0, 4.0 - 3) = (-4.5, 1.0)
\begin{scope}[shift={(-4.5,1.0)}]
  \tkzGraduatedCylinder[...]
\end{scope}
\end{lstlisting}

\subsubsection*{Example: \texttt{\textbackslash tkzTestTube} (beaker)}

\Lcmd{tkzTestTube} bbox (beaker, tiltAngle=0):
\texttt{(-0.5,0)(1,2.8)}, centre \texttt{(0.25,1.4)}.
For \Lcmd{rput}\texttt{(0,-3)}:

\begin{lstlisting}
% pst-labo: \rput(0,-3){\pstTubeEssais[glassType=becher,...]}
% shift = (0 - 0.25, -3 - 1.4) = (-0.25, -4.4)
\begin{scope}[shift={(-0.25,-4.4)}]
  \tkzTestTube[glassType=beaker,...]
\end{scope}
\end{lstlisting}

\subsubsection*{Bbox centre table}

\begin{table}[htb]
\centering
\caption{Bounding-box centres for \texttt{\textbackslash rput} alignment}
\footnotesize
\begin{tabular}{@{}p{0.36\tblw}p{0.24\tblw}p{0.2\tblw}@{}}
\toprule
\textbf{Condition} & \textbf{Bbox} & \textbf{Centre} \\
\midrule
\rowcolor{tablerowcolor}
\multicolumn{3}{l}{\Lcmd{tkzTestTube} (tiltAngle=0):} \\
\quad glassType=beaker          & (-0.5,0)(1,2.8)   & (0.25, 1.4) \\
\rowcolor{tablerowcolor}
\quad other (tube, roundFlask, \dots) & (-1.5,0)(1.5,4) & (0, 2) \\
\multicolumn{3}{l}{\Lcmd{tkzTestTube} (tiltAngle$\neq$0):} \\
\rowcolor{tablerowcolor}
\quad tiltAngle$>$0            & (-3,0)(1,4)       & (-1, 2) \\
\quad tiltAngle$<$0            & (-1,0)(3,4)       & (1, 2) \\
\rowcolor{tablerowcolor}
\quad elbowTube=true            & (-1,0)(6,4)       & (2.5, 2) \\
\Lcmd{tkzGraduatedCylinder}            & (-2,0)(2,6)       & (0, 3) \\
\rowcolor{tablerowcolor}
\Lcmd{tkzFunnel}             & (-2,-2)(2,5)      & (0, 1.5) \\
\Lcmd{tkzTitration} (burette, pHMeter) & (-5,0)(3,16) & (-1, 8) \\
\rowcolor{tablerowcolor}
\Lcmd{tkzTitration} (burette, no pHMeter) & (-2,0)(2,16) & (0, 8) \\
\Lcmd{tkzTitration} (no burette, pHMeter) & (-5,0)(3,5) & (-1, 2.5) \\
\rowcolor{tablerowcolor}
\Lcmd{tkzTitration} (no burette, no pHMeter) & (-2,0)(2,5) & (0, 2.5) \\
\bottomrule
\end{tabular}
\end{table}

\subsection{Scale mapping: \texttt{unit=Ncm} to \texttt{scale=N}}

PSTricks \Lcmd{psset}\Larg{unit=N} sets the unit to $N$\,cm.  In TikZ,
\Lopt{scale=N} scales all coordinates by $N$.

When \Lopt{scale=N} is applied to a scope containing a macro, the
macro's internal coordinates are multiplied by $N$.  The \Lcmd{shift}
value is in the \textbf{parent} (unscaled) coordinate system.

\begin{lstlisting}
% pst-labo: \rput(3,0){\pstDosage[...,unit=0.5]}
% tkzTitration bbox centre (pHMeter) = (-1,8)
% scale=0.5, physical centre = (0.5*(-1), 0.5*8) = (-0.5, 4)
% shift = (3 - (-0.5), 0 - 4) = (3.5, -4)
\begin{scope}[shift={(3.5,-4)},scale=0.5]
  \tkzTitration[...,pHMeter=true]
\end{scope}
\end{lstlisting}

\subsection{\texttt{xunit} / \texttt{yunit} mapping}

PSTricks \Lopt{xunit} and \Lopt{yunit} scale only one axis:

\begin{center}
\begin{tabular}{@{}p{0.3\tblw}p{0.3\tblw}@{}}
\toprule
\textbf{PSTricks} & \textbf{TikZ} \\
\midrule
\rowcolor{tablerowcolor}
\Lopt{unit=N}    & \Lopt{scale=N} \\
\Lopt{xunit=N}   & \Lopt{xscale=N} \\
\rowcolor{tablerowcolor}
\Lopt{yunit=N}   & \Lopt{yscale=N} \\
\bottomrule
\end{tabular}
\end{center}

% ============================================================
\section{Examples}\label{sec:examples}
% ============================================================

% ============================================================
\subsection{Titration setup with labels}\label{sec:ex-dosage}
% ============================================================

\begin{lstlisting}
\begin{tikzpicture}
  \useasboundingbox (0,-4) rectangle (7,4);
  % \rput(3,0){\pstDosage[...,unit=0.5]}
  \begin{scope}[shift={(3.5,-4)},scale=0.5]
    \tkzTitration[buretteLevel=25,liquidLevel1=30,%
    liquidStyle1=Champagne,glassType=beaker,pHMeter=true]
  \end{scope}

  \node at (2,3) {B\"urette};
  \node at (4.7,3.6) {25 mL};
  \node at (5.2,-2.2) {H$_3$O$^+$+Cl$^-$};
  \node at (.8,-3) {PH-Messer};
  \node at (5,-2.8) {20 mL};
  \node at (5,1) {Na$^+$+OH$^-$};
  \node at (6.4,-3.6) {Heizplatte};
  \draw[-{Stealth}] (2.7,2.9) -- (3.4,2.9);
\end{tikzpicture}
\begin{tikzpicture}
  \useasboundingbox (-3,-2) rectangle (2,3);
  \begin{scope}[scale=0.5]
    \begin{scope}[shift={(-4.25,1.5)}]
      \tkzGraduatedCylinder[tiltAngle=-60,liquidLevel1=90,liquidLevel2=50]
    \end{scope}
    \begin{scope}[shift={(0.25,-0.75)}]
      \tkzFunnel[glassType=reagentBottle,liquidLevel1=30]
    \end{scope}
  \end{scope}
  \node[draw] at (0.25,3.75) {%
  \begin{minipage}{3.2cm}Nach der Dekantation
    sind die einzelnen Phasen getrennt.
  \end{minipage}};
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{Test tube rack with labels}\label{sec:ex-rack}
% ============================================================

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5,
  Nickel/.style={fill=green,draw=none}]
  \tkzTestTube[liquidLevel1=20,liquidStyle1=Champagne,%
    Number=1,label=true]
  \begin{scope}
    \tkzTestTube[liquidLevel1=30,liquidStyle1=Cobalt,%
      Number=2,label=true]
  \end{scope}
  \begin{scope}[xshift=2cm]
    \tkzTestTube[liquidLevel1=40,liquidStyle1=Blood,%
      Number=3,label=true]
  \end{scope}
  \begin{scope}[xshift=4cm]
    \tkzTestTube[Number=4,label=true]
  \end{scope}
  \begin{scope}[xshift=6cm]
    \tkzTestTube[liquidStyle1=Vinegar,%
      Number={\footnotesize MnO$_4^-$},%
      label=true,stopper=true,glassType=reagentBottle]
  \end{scope}
  \begin{scope}[xshift=8.2cm]
    \tkzTestTube[liquidStyle1=Oil,%
      Number={\footnotesize Ce$^{4+}$},%
      label=true,stopper=true,glassType=reagentBottle]
  \end{scope}
  \begin{scope}[xshift=10.5cm]
    \tkzTestTube[liquidStyle1=Nickel,%
      Number={\footnotesize Ni$^{2+}$},%
      label=true,stopper=true,glassType=reagentBottle]
  \end{scope}
  \begin{scope}[xshift=13cm]
    \tkzTestTube[Number={\footnotesize Cu$^{2+}$},%
      label=true,stopper=true,glassType=reagentBottle]
    \end{scope}
  \begin{scope}[xshift=15.5cm]
    \tkzTestTube[liquidLevel1=30,liquidStyle1=Champagne,%
      Number={\footnotesize NaOH},%
      label=true,stopper=true,glassType=reagentBottle]
  \end{scope}
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\subsection{Separating funnel with beakers}\label{sec:ex-funnel}
% ============================================================

\begin{lstlisting}
\begin{tikzpicture}[scale=0.5]
  \useasboundingbox (-2,-6) rectangle (6,16);
  \tkzStand
  \tkzSeparatoryFunnel[TapOpen=false,stopper=true]
\end{tikzpicture}
\quad
\begin{tikzpicture}[scale=0.5]
  \useasboundingbox (-2,-6) rectangle (6,16);
  \tkzStand
  \tkzSeparatoryFunnel[TapOpen=false,stopper=false,%
                     liquidLevel1=-1,liquidLevel2=10]
  \begin{scope}[shift={(-0.25,-4.4)}]
    \tkzTestTube[glassType=beaker,liquidStyle1=AqueousPhase]
  \end{scope}
\end{tikzpicture}
\quad
\begin{tikzpicture}[scale=0.5]
  \useasboundingbox (-2,-6) rectangle (6,16);
  \tkzSeparatoryFunnel[TapOpen=true,stopper=false,%
                     liquidLevel1=1,liquidLevel2=1]
  \begin{scope}[shift={(-0.25,-4.4)}]
    \tkzTestTube[glassType=beaker,liquidStyle1=OrganicPhase,%
                   liquidLevel1=30]
  \end{scope}
  \tkzStand
\end{tikzpicture}
\end{lstlisting}

% ============================================================
\section{Migration from pst-labo}\label{sec:migration}
% ============================================================

\subsection{Checklist}

\begin{enumerate}[nosep,leftmargin=2em]
  \item Replace \Lcmd{usepackage}\Larg{pst-labo} with
        \Lcmd{usepackage}\Larg{tikz-chemlab}.
  \item Rename all commands: \texttt{pst} prefix $\to$ \texttt{tkz}
        prefix; French words $\to$ English.  See
        Table~\ref{tab:cmd-mapping} for the full mapping.
  \item Rename all option keys: French $\to$ English.  See
        Table~\ref{tab:key-mapping}.
  \item Rename \texttt{glassType} values: French $\to$ English (e.g.\
        \texttt{ballon} $\to$ \texttt{roundFlask}, \texttt{becher}
        $\to$ \texttt{beaker}).
  \item Replace \Lenv{pspicture} with \Lenv{tikzpicture}.
  \item Replace \Lcmd{psset}\Larg{unit=Ncm} with
        \Lenv{tikzpicture}\texttt{[scale=N]} or
        \Lcmd{begin}\Larg{scope}\texttt{[scale=N]}.
  \item Replace \Lcmd{rput}\texttt{(x,y)}\Larg{obj} with
        \Lcmd{begin}\Larg{scope}\texttt{[shift=\{(x,y)\}]} \dots{}
        \Lcmd{end}\Larg{scope} (remember to subtract the bbox centre).
  \item Replace \Lcmd{psline}, \Lcmd{psframe}, \Lcmd{psellipse} with
        \Lcmd{draw}, \Lcmd{fill}, \Lcmd{filldraw}.
  \item Replace \Lcmd{newpsstyle}\Larg{name}\Larg{\dots} with
        \Lcmd{tikzset}\Larg{name/.style=\dots}.
  \item Replace \Lcmd{psgrid} with \Lcmd{draw}\texttt{[help lines]
        (0,0) grid (N,N);} or the \Lopt{help lines} option.
  \item Pass \Lopt{label=true} explicitly to each
        \Lcmd{tkzTestTube} call (the global \Lcmd{chemlabset} setting
        is reset by \Lcmd{tikzchemlabdefaults}).
\end{enumerate}

\subsection{Command name mapping}\label{sec:cmd-mapping}

Table~\ref{tab:cmd-mapping} shows the full mapping from pst-labo
command names to tikz-chemlab names.

\begin{center}
\scriptsize
\textbf{Table~\ref{tab:cmd-mapping}: Command name mapping (pst-labo $\to$ tikz-chemlab)}\label{tab:cmd-mapping}
\medskip
\begin{tabularx}{0.8\textwidth}{@{}ll@{}}
\toprule
\textbf{pst-labo} & \textbf{tikz-chemlab} \\
\midrule
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstTubeEssais}       & \texttt{\textbackslash tkzTestTube} \\
\texttt{\textbackslash pstChauffageTube}    & \texttt{\textbackslash tkzHeatTube} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstChauffageBallon}  & \texttt{\textbackslash tkzHeatFlask} \\
\texttt{\textbackslash pstDosage}           & \texttt{\textbackslash tkzTitration} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstEprouvette}       & \texttt{\textbackslash tkzGraduatedCylinder} \\
\texttt{\textbackslash pstpipette}          & \texttt{\textbackslash tkzPipette} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstBigPipette}       & \texttt{\textbackslash tkzLargePipette} \\
\texttt{\textbackslash pstBallon}           & \texttt{\textbackslash tkzRoundFlask} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstEntonnoir}        & \texttt{\textbackslash tkzFunnel} \\
\texttt{\textbackslash pstSeparateFunnel}   & \texttt{\textbackslash tkzSeparatoryFunnel} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstDistillation}     & \texttt{\textbackslash tkzDistillation} \\
\texttt{\textbackslash pstSupport}          & \texttt{\textbackslash tkzStand} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pscolon}             & \texttt{\textbackslash tkzColumn} \\
\texttt{\textbackslash pstBullesChampagne}  & \texttt{\textbackslash tkzChampagneBubbles} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstBULLES}           & \texttt{\textbackslash tkzBubblesThreeD} \\
\texttt{\textbackslash pstbulles}           & \texttt{\textbackslash tkzBubbles} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstFilaments}        & \texttt{\textbackslash tkzFilaments} \\
\texttt{\textbackslash pstBilles}           & \texttt{\textbackslash tkzBalls} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstClouFer}          & \texttt{\textbackslash tkzIronNail} \\
\texttt{\textbackslash pstTournureCuivre}   & \texttt{\textbackslash tkzCopperTurnings} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstGrenailleZinc}    & \texttt{\textbackslash tkzZincGranules} \\
\texttt{\textbackslash pstBecBunsen}        & \texttt{\textbackslash tkzBunsenBurner} \\
\rowcolor{tablerowcolor}
\texttt{\textbackslash pstFlammeGrille}     & \texttt{\textbackslash tkzFlameGrill} \\
\texttt{\textbackslash pstThermo}           & \texttt{\textbackslash tkzThermometer} \\
\bottomrule
\end{tabularx}
\end{center}

\subsection{Option key mapping}\label{sec:key-mapping}

Table~\ref{tab:key-mapping} shows the mapping from pst-labo option
keys to tikz-chemlab keys.

\begin{center}
\footnotesize
\textbf{Table~\ref{tab:key-mapping}: Option key mapping (pst-labo $\to$ tikz-chemlab)}\label{tab:key-mapping}
\medskip
\begin{tabularx}{0.8\textwidth}{@{}ll@{}}
\toprule
\textbf{pst-labo} & \textbf{tikz-chemlab} \\
\midrule
\rowcolor{tablerowcolor}
\texttt{tubePenche}              & \texttt{tiltAngle} \\
\texttt{niveauLiquide1/2/3}     & \texttt{liquidLevel1/2/3} \\
\rowcolor{tablerowcolor}
\texttt{aspectLiquide1/2/3}     & \texttt{liquidStyle1/2/3} \\
\texttt{niveauReactif}          & \texttt{reagentLevel} \\
\rowcolor{tablerowcolor}
\texttt{couleurReactif}         & \texttt{reagentColor} \\
\texttt{niveauReactifBurette}   & \texttt{buretteLevel} \\
\rowcolor{tablerowcolor}
\texttt{couleurReactifBurette}  & \texttt{buretteColor} \\
\texttt{reactifBurette}         & \texttt{buretteReagent} \\
\rowcolor{tablerowcolor}
\texttt{reactifBecher}          & \texttt{beakerReagent} \\
\texttt{CouleurDistillat}       & \texttt{DistillateColor} \\
\rowcolor{tablerowcolor}
\texttt{AspectMelange}          & \texttt{MixtureStyle} \\
\texttt{bouchon}                & \texttt{stopper} \\
\rowcolor{tablerowcolor}
\texttt{pince}                  & \texttt{clamp} \\
\texttt{tubeDroit}              & \texttt{straightTube} \\
\rowcolor{tablerowcolor}
\texttt{tubeCoude}              & \texttt{elbowTube} \\
\texttt{tubeCoudeU}             & \texttt{uTube} \\
\rowcolor{tablerowcolor}
\texttt{tubeCoudeUB}            & \texttt{uTubeLong} \\
\texttt{tubeRecourbe}           & \texttt{curvedTube} \\
\rowcolor{tablerowcolor}
\texttt{tubeRecourbeCourt}      & \texttt{curvedTubeShort} \\
\texttt{doubletube}             & \texttt{doubleTube} \\
\rowcolor{tablerowcolor}
\texttt{refrigerantBoulles}     & \texttt{condenserBulbs} \\
\texttt{becBunsen}              & \texttt{bunsenBurner} \\
\rowcolor{tablerowcolor}
\texttt{barbotage}              & \texttt{bubbling} \\
\texttt{recuperationGaz}        & \texttt{gasCollection} \\
\rowcolor{tablerowcolor}
\texttt{tubeSeul}               & \texttt{tubeOnly} \\
\texttt{tubeDegagementDroit}    & \texttt{gasTubeStraight} \\
\rowcolor{tablerowcolor}
\texttt{etiquette}              & \texttt{label} \\
\texttt{Numero}                 & \texttt{Number} \\
\rowcolor{tablerowcolor}
\texttt{phmetre}                & \texttt{pHMeter} \\
\texttt{agitateurMagnetique}    & \texttt{magneticStirrer} \\
\rowcolor{tablerowcolor}
\texttt{OpenTap}                & \texttt{TapOpen} \\
\texttt{solide}                 & \texttt{solid} \\
\bottomrule
\end{tabularx}
\end{center}

\subsection{\texttt{glassType} value mapping}

The \Lopt{glassType} values have also been translated:

\begin{center}
\begin{tabular}{@{}p{0.3\tblw}p{0.3\tblw}@{}}
\toprule
\textbf{pst-labo} & \textbf{tikz-chemlab} \\
\midrule
\rowcolor{tablerowcolor}
\texttt{tube} (unchanged) & \texttt{tube} \\
\texttt{ballon} & \texttt{roundFlask} \\
\rowcolor{tablerowcolor}
\texttt{becher} & \texttt{beaker} \\
\texttt{erlen} & \texttt{erlenmeyer} \\
\rowcolor{tablerowcolor}
\texttt{flacon} & \texttt{reagentBottle} \\
\texttt{fioleJauge} & \texttt{volumetricFlask} \\
\rowcolor{tablerowcolor}
\texttt{verre} & \texttt{watchGlass} \\
\bottomrule
\end{tabular}
\end{center}

\subsection{Common pitfalls}

\begin{description}[nosep,leftmargin=2em]
  \item[\texttt{\textbackslash useasboundingbox}] In tikz-chemlab,
        top-level macros like \Lcmd{tkzTitration} use
        \Lcmd{useasboundingbox} internally.  If you place them inside a
        \Lenv{tikzpicture} that also has
        \Lcmd{useasboundingbox}, the inner one does \textbf{not}
        override the outer one (scope-local).  However, for nested
        macros like \Lcmd{tkzGraduatedCylinder} inside a figure,
        \Lcmd{useasboundingbox} was intentionally removed to avoid
        conflicts.
  \item[\texttt{label}] The global \Lcmd{chemlabset}\Larg{label}
        does \textbf{not} persist into \Lcmd{tkzTestTube} because
        \Lcmd{tikzchemlabdefaults} resets it.  Always pass
        \Lopt{label=true} as a macro option.
  \item[\texttt{tiltAngle} on \texttt{\textbackslash tkzPipette}]
        The original \Lpack{pst-labo} \Lcmd{tkzPipette} does not read
        \Lopt{tiltAngle}.  This behaviour is faithfully preserved.
  \item[\texttt{unit} vs \texttt{scale}] PSTricks \Lopt{unit=N} scales
        everything including line widths.  TikZ \Lopt{scale=N} does not
        scale line widths by default, but \Lpack{tikz-chemlab}
        intercepts \Lcmd{chemlabUpdateLineWidths} to scale them
        automatically.
\end{description}

% ============================================================
\section{Basic objects (internal)}\label{sec:objects}
% ============================================================

The file \Lfile{tikz-chemlabObj.tex} contains all low-level shape
primitives.  These are normally not called directly by the user, but
can be used for custom extensions.  Table~\ref{tab:objects} gives an
overview.

{\scriptsize
\begin{longtable}{@{}p{0.5\tblw}p{0.3\tblw}@{}}
\caption{Low-level objects in \texttt{tikz-chemlabObj.tex}}\label{tab:objects} \\
\toprule
\textbf{Macro} & \textbf{Description} \\
\midrule
\endfirsthead
\toprule
\textbf{Macro} & \textbf{Description} \\
\midrule
\endhead
\rowcolor{tablerowcolor}
\Lcmd{tkzBuretteBody}        & Burette body \\
\Lcmd{tkzBuretteStopcock}     & Burette stopcock \\
\rowcolor{tablerowcolor}
\Lcmd{tkzBuretteGraduation}   & Burette graduation marks \\
\Lcmd{tkzTitrationPHMeter}       & pH-meter box \\
\rowcolor{tablerowcolor}
\Lcmd{tkzTitrationStand}       & Hotplate / stirrer support \\
\Lcmd{tkzTitrationStirBar}        & Magnetic stirrer bar \\
\rowcolor{tablerowcolor}
\Lcmd{tkzPipetteBody}        & Pipette body \\
\Lcmd{tkzLargePipetteBody}          & Large pipette \\
\rowcolor{tablerowcolor}
\Lcmd{tkzDrop}              & Liquid drop \\
\Lcmd{tkzGraduatedCylinderBody}     & Measuring cylinder body \\
\rowcolor{tablerowcolor}
\Lcmd{tkzGraduatedCylinderRim}    & Measuring cylinder rim \\
\Lcmd{tkzGraduatedCylinderBase}      & Measuring cylinder base/foot \\
\rowcolor{tablerowcolor}
\Lcmd{tkzGraduatedCylinderGraduation} & Measuring cylinder graduation \\
\Lcmd{tkzDistillationFractionated} & Fractional distillation assembly \\
\rowcolor{tablerowcolor}
\Lcmd{tkzBunsenBurner}           & Bunsen burner \\
\Lcmd{tkzFlameGrill}        & Flame with grille \\
\rowcolor{tablerowcolor}
\Lcmd{tkzBunsenBurnerGrill}     & Bunsen burner with grille \\
\Lcmd{tkzRoundFlaskSimple}        & Round-bottom flask body \\
\rowcolor{tablerowcolor}
\Lcmd{tkzRoundFlaskGrill}        & Round-bottom flask with grille \\
\Lcmd{tkzTestTubeStopper}   & Test-tube stopper \\
\rowcolor{tablerowcolor}
\Lcmd{tkzTestTubeBody}     & Test-tube body \\
\Lcmd{tkzTestTubeStraightTube}     & Straight narrow tube \\
\rowcolor{tablerowcolor}
\Lcmd{tkzTestTubeElbowTube}     & Right-angled tube \\
\Lcmd{tkzTestTubeUTube}    & U-shaped tube \\
\rowcolor{tablerowcolor}
\Lcmd{tkzTestTubeUTubeLong}   & U-tube to bottom \\
\Lcmd{tkzCurvedTube}        & Curved exhaust tube (with burner) \\
\rowcolor{tablerowcolor}
\Lcmd{tkzCurvedTubeShort}   & Short curved exhaust tube \\
\Lcmd{tkzTestTubeDoubleTube} & Double-tube assembly \\
\rowcolor{tablerowcolor}
\Lcmd{tkzTestTubeClamp}     & Test-tube clamp \\
\Lcmd{tkzVolumetricFlask}          & Volumetric flask \\
\rowcolor{tablerowcolor}
\Lcmd{tkzCrystallizingDish}       & Crystallising dish \\
\Lcmd{tkzBeakerRim}        & Beaker rim \\
\rowcolor{tablerowcolor}
\Lcmd{tkzBeakerBody}         & Beaker body \\
\Lcmd{tkzErlenmeyerBody}          & Erlenmeyer flask body \\
\rowcolor{tablerowcolor}
\Lcmd{tkzReagentBottleBody}         & Reagent bottle body \\
\Lcmd{tkzWatchGlassBody}          & Watch glass body \\
\rowcolor{tablerowcolor}
\Lcmd{tkzWatchGlassBase}           & Watch glass foot \\
\Lcmd{tkzFunnelBody}      & Funnel body \\
\rowcolor{tablerowcolor}
\Lcmd{tkzCondenserStem}         & Ball condenser stem \\
\Lcmd{tkzCondenserBulbs}  & Ball condenser \\
\rowcolor{tablerowcolor}
\Lcmd{tkzHeaterRoundFlask}       & Flask heater (mantle) \\
\Lcmd{tkzRoundFlaskReflux}        & Reflux flask assembly \\
\rowcolor{tablerowcolor}
\Lcmd{tkzSeparatoryFunnelBody}        & Separating funnel body \\
\Lcmd{tkzSeparatoryFunnelOutlineClip}  & Separating funnel clip path \\
\rowcolor{tablerowcolor}
\Lcmd{tkzStopper}             & Stopper (funnel) \\
\Lcmd{tkzTapOpen}             & Open tap \\
\rowcolor{tablerowcolor}
\Lcmd{tkzTapClosed}           & Closed tap \\
\Lcmd{tkzStand}             & Support stand \\
\bottomrule
\end{longtable}
}

% ============================================================
\section{Version history and credits}\label{sec:credits}
% ============================================================

\Lpack{tikz-chemlab} (v1.0.0) is a TikZ port of \Lpack{pst-labo}
(v2.07, 2025/07/15) by Denis Girou, Christophe Jorssen, Manuel Luque,
and Herbert Vo\ss.  The port was created by Aihua Wang.

\noindent\textbf{Repository:} \url{https://github.com/aihua/tikz-chemlab}\\
\textbf{Support:} \url{https://github.com/aihua/tikz-chemlab/issues}

The port preserves the original command names, option keys, default
values, and visual appearance as closely as possible.  All shape
coordinates were derived from the original \Lfile{pst-laboObj.tex}.

\medskip\noindent
\textbf{Key differences from pst-labo:}
\begin{itemize}[nosep,leftmargin=1.5em]
  \item Uses TikZ instead of PSTricks (no PostScript dependency;
        works with pdflatex, xelatex, lualatex, tectonic).
  \item Line widths automatically scale with \Lopt{scale} via
        \Lcmd{chemlabUpdateLineWidths}.
  \item Six predefined line-width styles (\texttt{publication},
        \texttt{draft}, etc.) not present in the original.
  \item Flame colours and scale are configurable via
        \Lcmd{chemlabset}\Larg{flame outer color=\dots,
        flame scale=\dots}.
\end{itemize}

\end{document}
