1

I am having issues with writing a Macro. The idea is that I am trying to setup a (simple) Macro to hold the figures for an article, but not all the figures have captions and thus I want that macro to have the option to set the:

  1. Source of the image (e.g., my_figure.png)
  2. The width with respect to the \textwidth (e.g., 0.8 -> 80% of the text width)
  3. The caption, if needed.

By using the \newcommand macro I can achieve this:

\usepackage{ifthen}

\newcommand*\tkzimage[3]{% \begin{figure}[h!] \centering \begin{tikzpicture} \node[inner sep=0pt] (w) at (0,0) {\includegraphics[width=#2\textwidth]{images/#1}}; \end{tikzpicture} \ifthenelse{\equal{#3}{}}{ }{\caption{#3}} \end{figure} }

The problem that I am having is when invoking the macro, I get the expected behavior, but the code doesn't work if I don't have \caption{<whatever>} in the empty slot:

\ifthenelse{\equal{#3}{}}{}{\caption{#3}} % Throws an error.
\ifthenelse{\equal{#3}{}}{ }{\caption{#3}} % Throws an error.
\ifthenelse{\equal{#3}{}}{<whatever>}{\caption{#3}} % Throws an error.

\ifthenelse{\equal{#3}{}}{\caption{<whatever>}>}{\caption{#3}} % Works!

The function is being invoked as:

\tkzimage{image\_text.png}{0.5}{}           # With NO caption.
\tkzimage{image\_text.png}{0.5}{Some text}  # With some caption.

I am puzzled as to why this behavior and how to solve it. The pgfkeys package is not working either, so I don't know how else to approach this; help would be appreciated.

Compiler Error

When the above code is used without the \caption code:

LaTeX Warning: `!h' float specifier changed to `!ht'.

File: images/pycharmInstallation000.png Graphic file (type png) <use images/pycharmInstallation000.png> Package luatex.def Info: images/pycharmInstallation000.png used on input line 18. (luatex.def) Requested size: 234.73523pt x 189.33287pt.

./aaf_introduction_neovim.tex:18: Package hypcap Error: You have forgotten to use \caption.

Thanks!

  • 1
    by default image\_text.png would not work you would want image_text.png – David Carlisle Feb 15 '24 at 22:13
  • Please provide an example that shows the problem, you can use example-image.png and show the exact error message copied from the log in a code block so lines are preserved. It's impossible to debug Throws an error if you do not say what the error is or provide a test file to reproduce it. – David Carlisle Feb 15 '24 at 22:15
  • \ifthenelse will only work if the caption text is safe in an edef, so no fragile commands. better would be to make that an optional argument rather than test for empty, but if you do want to test for empty see https://tex.stackexchange.com/questions/212740/safe-test-for-an-empty-expanded-macro-argument – David Carlisle Feb 15 '24 at 22:19
  • I am currently working on it, but I think that I found the problem. It might be silliness on my behalf, but apparently when using \begin{figure}...\end{figure}, the \caption command is required. Trying to find a workaround now... – Andrumen1 Feb 15 '24 at 22:20
  • 1
    No. caption is not required in the default definition offigure but as you have shown no example it's impossible to say if you are using a non standard version – David Carlisle Feb 15 '24 at 22:29
  • I am using textlive2023 in Linux Mint, let me post the error that the compiler throws at me, at least the relevant part. – Andrumen1 Feb 15 '24 at 22:35

2 Answers2

1

If a caption may or may not be present, it's an optional argument.

Here I also provide for additional setting in \includegraphics and for the optional short caption for the list of figures.

Beware that \begin{figure}[!h] is wrong as it may block the queue and cause delivery of all subsequent figures at the end of the document (or chapter).

By the way, what's the tikzpicture doing?

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

\NewDocumentCommand{\tkzimage}{mO{}moo}{% \begin{figure}[!htp]% <--- not just !h, it's wrong \centering \begin{tikzpicture} \node[inner sep=0pt] (w) at (0,0) {% \includegraphics[width=#1\textwidth,#2]{#3}% }; \end{tikzpicture} \IfValueT{#4}{% there's a caption \IfNoValueTF{#5}{% no short caption \caption{#4}% }{% there's a short caption \caption[#4]{#5}% }% } \end{figure} }

\begin{document}

\listoffigures

\section{Test}

\tkzimage{0.2}{example-image-a}[A caption]

\tkzimage{0.2}{example-image-b}[Short caption for lof][A veeeeeeeeeeery long caption]

\tkzimage{0.2}[angle=90]{example-image-c}

\end{document}

enter image description here

egreg
  • 1,121,712
  • With the Tikz picture I was just thinking of adding arrows and other floats, but not anymore...I guess..Thanks! – Andrumen1 Feb 15 '24 at 23:02
0

This is the solution that I found, it is not the most elegant solution, but it works for me:

\usepackage{ifthen}
\usepackage{caption}

\newcommand*\tkzimage[3]{ \begin{figure}[h!] \centering \begin{tikzpicture} \node[inner sep=0pt] (w) at (0,0) {\includegraphics[width=#2\textwidth]{images/#1}}; \end{tikzpicture} \ifthenelse{\equal{#3}{}}{ \captionsetup{labelformat=empty} \caption[]{} \addtocounter{figure}{-1} } { \caption{#3} } \end{figure}
}

Notice that every time that the figure environment is called, the figure counter is increased, thus, if there is no caption added then the counter should not increase; i.e., the net increment must be zero, that is the reason why the command \addtocounter{figure}{-1} is used.

  • I don't intend to make a figure table, if you have a better suggestion/answer, please do post it. Thanks! – Andrumen1 Feb 15 '24 at 22:40