6

The following has worked for me for quite some time.

\documentclass[11pt]{book}
\usepackage[margin=1in]{geometry}            
\geometry{letterpaper}                 
\usepackage[parfill]{parskip}   

\usepackage{tikz, pgf, calc}
\usetikzlibrary{matrix, shapes, positioning, calc, decorations.pathreplacing, shapes.geometric, arrows}

\newcounter{Day}

\newcounter{pt}[Day]    % CORRECTNESS POINTS FOR HW RUBRICS
\newcommand{\pt}[2]     % NUMBER OF POINTS, ITEM IN STARBURST
    {#2\begin{tikzpicture}[remember picture, overlay]
        \node (A) [starburst, 
            draw = red, opacity = .8, 
            fill = red!20, fill opacity = .2, 
            xshift = -.5*\widthof{#2},
            yshift = .5*\heightof{#2}
            ]
            {\phantom{#2}};
        \node (B) at (current page.west) {};
        \path let \p1 = (A), \p2 = (B) in node [draw = red, 
            color = red] at (\x2+.625in,\y1) {#1 pt(s)};
    \end{tikzpicture}
    \addtocounter{pt}{#1}
    }

\begin{document}

\pt{1}{lorem}

\end{document}

Recently, I updated several packages with MikTeX 2.9. Below is a screenshot of the packages that were updated.

Updated packages

Since the updates, the \widthof and \heightof commands are causing errors. If I change the xshift and yshift to something else, everything compiles just fine (but isn't the way I want my command to work). I have two questions:

  1. Why did this work before and not now?
  2. How can I change my code to make it work correctly again?

Thanks in advance for any help!

Charlie
  • 253
  • 1
  • 9

1 Answers1

5

\widthof and \heightof (\depthof, \totalheightof, \maxof, \minof) are features of package calc and enhance the mathematical expressions in \setlength, \addtolength, \setcounter, and \addtocounter. Package pgf comes with its own math engines. I have not found \widthof in the TikZ manual. Therefore, I conclude that these measurement macros are not officially supported. On the other hand, pgfmathparser.code.tex contains:

% Stuff for calc compatiability.
\let\real=\pgfmath@calc@real
\let\minof=\pgfmath@calc@minof
\let\maxof=\pgfmath@calc@maxof
\let\ratio=\pgfmath@calc@ratio
\let\widthof=\pgfmath@calc@widthof
\let\heightof=\pgfmath@calc@heightof
\let\depthof=\pgfmath@calc@depthof

[...]

% Stuff for compatability with the calc package.
%
\def\pgfmath@calc@real#1{#1}
\def\pgfmath@calc@minof#1#2{min(#1,#2)}
\def\pgfmath@calc@maxof#1#2{max(#1,#2)}
\def\pgfmath@calc@ratio#1#2{#1/#2}
\def\pgfmath@calc@widthof#1{width("#1")}
\def\pgfmath@calc@heightof#1{height("#1")}
\def\pgfmath@calc@depthof#1{depth("#1")}

The example works with pgf functions width and height:

\documentclass[11pt]{book}
\usepackage[margin=1in]{geometry}
\geometry{letterpaper}
\usepackage[parfill]{parskip}

\usepackage{tikz, pgf, calc}
\usetikzlibrary{matrix, shapes, positioning, calc,
  decorations.pathreplacing, shapes.geometric, arrows}

\newcounter{Day}

\newcounter{pt}[Day]    % CORRECTNESS POINTS FOR HW RUBRICS
\newcommand{\pt}[2]     % NUMBER OF POINTS, ITEM IN STARBURST
    {#2 \begin{tikzpicture}[remember picture, overlay]
        \node (A) [starburst,
            draw = red, opacity = .8,
            fill = red!20, fill opacity = .2,
            xshift = {-.5*width("#2")}, % \widthof{#2},
            yshift = {.5*height("#2")}, % \heightof{#2}
            ]
            {\phantom{#2}};
        \node (B) at (current page.west) {};
        \path let \p1 = (A), \p2 = (B) in node [draw = red,
            color = red] at (\x2+.625in,\y1) {#1 pt(s)};
    \end{tikzpicture}
    \addtocounter{pt}{#1}
    }

\begin{document}

\pt{1}{lorem}

\end{document}

Result

Thus, a workaround is found.


BTW, the code in the example seems unnecessarily complicate (or I do not have understood the purposes of some constructions). For example, the text is not put in the node, but before, separated by a space. The latter is not considered in the calculations, moving the starburst node away from the center of the text.

A simplified version:

\documentclass[11pt]{book}

\usepackage{tikz}
\usetikzlibrary{shapes}

\newcounter{Day}
\newcounter{pt}[Day]

\newcommand*{\pt}[2]{%
  \textcolor{red}{\fbox{#1 pt(s)}}\quad
  \tikz[baseline=(A.base)]\node (A) [
    starburst,
    draw=red,
    fill=red!20,
    fill opacity=.2,
    text opacity=1,
  ] {#2};%
  \addtocounter{pt}{#1}%
}

\begin{document}

\pt{1}{lorem}

\pt{1}{$\pi$}

\end{document}

Result

Heiko Oberdiek
  • 271,626
  • This is working great for the example \pt{1}{lorem}, but now it no longer works for something like \pt{1}{$\pi$} (it used to when \widthof and \heightof were still working for me). Is there a way to make this work with width and height? – Charlie Feb 14 '17 at 21:40
  • @Charlie \pt{1}{$\pi$} works for me, using width("#2") in the definition as in the example of the answer. – Heiko Oberdiek Feb 14 '17 at 22:01
  • I'm sorry, you're right, that does work. (I assumed that any math in the second input would result in an error, but that's not so.) This is actually what just threw an error for me: \pt{1}{$[-1,1]$}. Very weird. Why would \pt{1}{$\pi$} work and \pt{1}{$[-1,1]$} not? – Charlie Feb 14 '17 at 22:08
  • 2
    @Charlie The parser for the optional argument of the node thinks, the closing square bracket inside width("...") is the end of the options. Adding curly braces around the value should fix the issue, see the updated answer code. – Heiko Oberdiek Feb 14 '17 at 22:20
  • I am not using your packages, but: I have discovered that if I first create a \newlength{whatever} then later \setlength\whatever{\widthof{text}} it works in situations that otherwise fail. I do not know why. Some time ago, I could directly use \widthof without first creating a length. –  Feb 15 '17 at 01:34