# Making an environment to draw over a picture with TikZ

Following up on this answer, I've decided to just make this a new environment. Below is my MWE using packages xparse and tikz:

\documentclass[10pt,a4paper]{article}
\usepackage{xparse,tikz}

\NewDocumentEnvironment{overdraw}{ o o m +b } {
{ % begin "\begin{overdraw}"
\begin{tikzpicture}
\node[anchor=south west, inner sep = 0] (image) at (0,0) {
\includegraphics{#3}
}; % add image at coordinate (0, 0)
\IfNoValueTF{#2} {
\IfNoValueTF{#1} {
\begin{scope}[x={(image.south east)},y={(image.north west)}]
% If Optional Arg #1 is empty
} { \begin{scope}[x={(image.south east)/#1},y={(image.north west)}] }
% #1 not empty
} % If Optional Arg #2 is empty
{ \begin{scope}[x={(image.south east)/#1},y={(image.north west)/#2}] }
% #2 not empty
} % end "\begin{overdraw}"
{ % begin "\end{overdraw}"
\end{scope}
\end{tikzpicture}
} % end "\end{overdraw}"
}

\begin{document}
\begin{overdraw}{sample.jpg}
\draw[red,ultra thick,rounded corners] (0.62,0.65) rectangle (0.78,0.75);
\end{overdraw}
\end{document}


Compiling this returns an error message that goes:

pdfTeX warning (ext4): destination with the same identifier (name{page.1}) has
been already used, duplicate ignored
<to be read again>
\relax
l.16 \newpage
[1]

! Package tikz Error: A node must have a (possibly empty) label text.

See the tikz package documentation for explanation.
Type  H <return>  for immediate help.
...

l.20 \end
{overdraw}
?
! Emergency stop.
...

l.20 \end
{overdraw}
End of file on the terminal!


What does \newpage have to do with anything I wrote? Is there any way to fix this problem?

EDIT: The package repository in full can be found HERE at Github. Passers-by are welcome to leave comments and notes on tips for managing and developing a good package :D

• I doesn't solve the problem, but \includegraphics{#3};} should be \includegraphics{#3}};. – Ignasi May 28 at 7:40
• @Ignasi it definitely should, what an embarrassing typo. And indeed, it wasn't a solution to the major problem here... – Paul Kim May 28 at 8:01

# Overview

You have a brace matching problem, and the divisions on the x and y vectors were written in a way that isn't supported by TikZ. The following works for me. I have removed your +b argument specifier, since you don't use this argument at all.

\documentclass{article}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{calc}

\usepackage{xparse}

\NewDocumentEnvironment{overdraw}{ o o m }%
{%
\begin{tikzpicture}
\node[anchor=south west, inner sep = 0] (image) at (0,0) {
\includegraphics{#3}
}; % add image at coordinate (0, 0)

\IfNoValueTF{#2} {% optional argument #2 not provided
\IfNoValueTF{#1} {% optional argument #1 not provided
\begin{scope}[x={(image.south east)},y={(image.north west)}]
}{% #1 provided
\pgfmathparse{1/(#1)}
\begin{scope}[x={($\pgfmathresult*(image.south east)$)},
y={(image.north west)}]
}
}{% #2 provided
\pgfmathsetmacro{\myXfactor}{1/(#1)}
\pgfmathsetmacro{\myYfactor}{1/(#2)}

\begin{scope}[x={($\myXfactor*(image.south east)$)},
y={($\myYfactor*(image.north west)$)}]
}
}{
\end{scope}
\end{tikzpicture}%
}% end "\end{overdraw}"

\begin{document}
\begin{overdraw}[1.5][0.8]{example-image}
\draw[red,ultra thick,rounded corners] (0.62,0.65) rectangle (0.78,0.75);
\end{overdraw}
\end{document}


# Code formatting and extraneous spaces

I reformatted the code to make it a bit easier to read (IMHO). Beware of introducing extraneous spaces, since you are not using \ExplSyntaxOn here (note the place of the % characters at environment start, before \begin{tikzpicture}, and at environment end, after \end{tikzpicture}). To see my point, try the above code with:

\begin{document}
a\begin{overdraw}{example-image}
\draw[red,ultra thick,rounded corners] (0.62,0.65) rectangle (0.78,0.75);
\end{overdraw}b
\end{document}


You'll get this:

See the a and b lying on the image baseline? Now, remove the two percent characters I mentioned (before \begin{tikzpicture} and after \end{tikzpicture}) and you'll obtain this:

The whole takes two lines because one \linewidth isn't large enough to hold the indentation box, the a, the b, two interword spaces and the image (given the default value of \parindent).

# Dividing a vector by a scalar in TikZ

I added \pgfmathparse computations and the calc TikZ library in order to do the divisions on the x and y vectors that you apparently desired.

# On the “non-empty” vs. “provided“ argument check

• xparse's \IfNoValueTF test does not test if the optional argument is empty, it tests whether it has been provided. One can provide an empty argument, it is still provided. If the criterion you want to decide against is emptiness, I suggest using O{} in the argument specification of \NewDocumentEnvironment and then checking with, for instance, etoolbox's \ifblank command (i.e., 1) you declare the argument as an optional one whose default value is empty, and 2) you check whether it is empty).
• Using \IfValueTF instead of \IfNoValueTF is likely to make the logic easier to follow, especially when there are imbricated tests like here.
• Not sure why, but there was no overprint until I deleted +m in the argument specification. – sgmoye May 28 at 12:24
• Ah, right, +m is a mandatory argument and we don't provide it! Either provide one or remove the arg specifier. – frougon May 28 at 12:31
• Just TeXed your altered file. No change. With the { o o m +m} argument specification, there is no red rectangle overprint. Removing the +m fixes the problem. I'm using MacTeX 2019, recently updated. – sgmoye May 28 at 12:32
• Look in the last edit: I provided an empty arg when the environment is used. Otherwise, remove the +m since you don't use it. I let it in place because I thought it is part of your future plans for the environment. PS.: the rectangle is drawn with current code. – frougon May 28 at 12:33