Skip to content

Instantly share code, notes, and snippets.

@aminophen
Last active January 30, 2020 13:33
Show Gist options
  • Save aminophen/8c2de78c6958d479c3d76fca6700e7a0 to your computer and use it in GitHub Desktop.
Save aminophen/8c2de78c6958d479c3d76fca6700e7a0 to your computer and use it in GitHub Desktop.
pgfmath: add pTeX-specific units and pdfTeX-specific units
\documentclass[dvipdfmx]{article}
\usepackage{tikz}
\makeatletter % TEX CODE BEGIN
%
\usepackage{etoolbox}
%
% missing for pdfTeX and LuaTeX:
\pgfmath@tokens@make{unit}{{nc}{nd}}% double character units are ok
%
% missing for pTeX and friends:
\pgfmath@tokens@make{unit}{{zh}{zw}}% double character units are ok
\pgfmath@tokens@make{unit}{{H}{Q}} % single character units; see below
%
% hack to support single-character units
\patchcmd{\pgfmath@parse@@number}{%
% It isn't numeric (i.e., 012345679.), so it might be units...
\expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax%
}{%
% It isn't numeric (i.e., 012345679.), so it might be units...
\expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax%
\expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\endcsname\relax%
}{}{}
\patchcmd{\pgfmath@parse@@number}{%
\else% ...but here it is units.
\global\pgfmathunitsdeclaredtrue%
\pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next\relax%
\edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
\expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
\let\pgfmath@parse@next=\pgfmath@parse@@operator%
\fi%
}{%
\else% ...but here it is units.
\global\pgfmathunitsdeclaredtrue%
\pgfmath@dimen=\pgfmath@number\pgfmath@token\relax%
\edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
\expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
\let\pgfmath@parse@next=\pgfmath@parse@@operator%
\fi%
\else% ...but here it is units.
\global\pgfmathunitsdeclaredtrue%
\pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next\relax%
\edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
\expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
\let\pgfmath@parse@next=\pgfmath@parse@@operator%
\fi%
}{}{}
%
\makeatletter % TEX CODE END
\begin{document}
\begin{tikzpicture}
\draw (0,0) rectangle (3,3);
\node[yshift=\dimexpr1zw\relax] at (0,0) {Hello!}; % OK
\end{tikzpicture}
\begin{tikzpicture}
\draw (0,0) rectangle (3,3);
\node[yshift=1zw] at (0,0) {Hello!}; % !!
\end{tikzpicture}
% without patch,
% => ! Package PGF Math Error: Unknown operator `z' or `zw' (in '1zw').
\begin{tikzpicture}
\draw (0,0) rectangle (3,3);
\node[yshift=1Q] at (0,0) {Hello!}; % !!
\end{tikzpicture}
% without patch,
% => ! Package PGF Math Error: Unknown operator `Q' or `Q@' (in '1Q').
\begin{tikzpicture}
\draw (0,0) rectangle (3,3);
\node[yshift=1nd] at (0,0) {Hello!}; % error expected
\end{tikzpicture}
% => ! Illegal unit of measure (pt inserted).
\end{document}
@aminophen
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment