Conflicto entre flotadores finales y flotadores de figuras incluidos mediante macro

Conflicto entre flotadores finales y flotadores de figuras incluidos mediante macro

Yo suelo \newcommandincluir cifras rápidamente. Pero combinado con endfloat, arroja un error. ¿Alguna idea de cómo enviar flotadores al final cuando se incluyen de esta manera?

\documentclass{article}
\usepackage{graphicx}
%\usepackage{endfloat}  % this causes an error

\newcommand{\addfig}[1]{ 
\begin{figure}[htbp]  % when float environment is included here
\centering 
  \includegraphics[width=\textwidth]{#1}  
\end{figure} 
} 

\begin{document}
\addfig{fig1}
\end{document} 

Respuesta1

Aunque, hasta donde yo sé, no puede configurarlo endfloatpara que reconozca el comando \addfigadecuadamente, puede configurarlo para que reconozca entornos flotantes adicionales como addfig.

Por ejemplo:

\documentclass{article}
\usepackage{graphicx}
\newenvironment{addfig}[1]{%
\begin{figure}
\centering
  \includegraphics[width=\textwidth]{#1}
}{\end{figure}}
\usepackage{endfloat}
\DeclareDelayedFloatFlavor{addfig}{figure}

\begin{document}
\begin{addfig}{example-image-a}
\end{addfig}
\end{document}

tipo flotante personalizado retrasado

Respuesta2

Aquí hay un enfoque que escribe cada figura utilizada en el formulario de comando \addfig[<opts>]{<image>}en un archivo tmpfig.texy luego lee inmediatamente en ese archivo:

ingrese la descripción de la imagen aquí

\documentclass{article}

\usepackage{graphicx,newfile,endfloat}

\newoutputstream{tmpimg}

\newcommand{\addfig}[2][width=\textwidth]{%
  \openoutputfile{tmpfig.tex}{tmpimg}% Open tmpfig.tex for (over)writing
  % Add figure environment...
  \addtostream{tmpimg}{\protect\begin{figure}[htbp]}
  \addtostream{tmpimg}{\protect\centering}
  \addtostream{tmpimg}{\protect\includegraphics[#1]{#2}}
  \addtostream{tmpimg}{\protect\end{figure}}
  \closeoutputstream{tmpimg}% Close tmpfig.tex
  \input{tmpfig}% Input tmpfig.tex
}

\begin{document}

Some text.

\begin{figure}[htbp]  % when float environment is included here
  \centering
  \includegraphics[width=\textwidth]{example-image-a}
\end{figure} 

\addfig{example-image-b}

\addfig[width=.5\textwidth]{example-image-c}

\end{document}

Respuesta3

Por último, pero no menos importante, una solución que intenta parchear el endfloatpaquete lo menos posible:

\documentclass{article}
\usepackage{graphicx}
\usepackage{mwe}

\newcommand{\addfig}[1]{%
\begin{figure}[htbp]  % when float environment is included here
\centering 
  \includegraphics[width=\textwidth]{#1}  
\end{figure} 
} 

\usepackage{endfloat}[2011/12/25] % we need at least v2.5d
\usepackage{etoolbox}

% Adapt \addfig to the endfloat package
% First of all we make \addfig known to the endfloat package as variant of the figure environment
\DeclareDelayedFloatFlavour{addfig}{figure}
\makeatletter
% Special variant of \efloat@xfloat for commands (instead of environments):
% This macro will be expanded with every line read until \efloat@found@end is used.
% The original version tests if #2 (the actual line read) is "\end{}",
% and uses \efloat@iwrite in case of no and \efloat@found@end in case of yes.
% Our version just writes the line (containing the command and the rest of the line)
% using \efloat@iwrite and finishes the verbatim reading using \efloat@found@end afterwards.
{\catcode`\^^M=12 \endlinechar=-1 %
 \long\gdef\my@efloat@xfloat#1#2^^M{%
  \efloat@iwrite{#1}{#2}% write 1st line (containing the command)...
  \efloat@found@end{#1}%  ...and end verbatim reading afterwards
  \next}}              %  process next line
% Since \addfig is a command and not an environment we need to start a group for our own
% using \begingroup, so it behaves like we would have written \begin{addfig}.
% (Note: The endfloat package is designed to work with environments, not with commands.)
% Additionally we patch \efloat@xfloat to use our own variant of it for this command.
\pretocmd\addfig{%
  \begingroup
  \let\efloat@xfloat\my@efloat@xfloat}{}{}
\makeatother

\begin{document}
\addfig{example-image}
\end{document}

Pero esta solución tiene dos advertencias:

  1. Todo lo escrito en la misma línea después del uso del comando también se escribirá en el archivo que contiene los entornos flotantes. Por lo tanto, no es posible escribir \addfig{example-image} Some text...en una línea ya que, de lo contrario, "Algo de texto..." también se retrasaría.

  2. El comando y sus argumentos deben escribirse en la misma línea. Por lo tanto, no es posible dividir su uso en más líneas, por ejemplo, \addfig{%como primera y example-image}segunda línea.

En total estamos usando los tres comandos internos \efloat@xfloat, \efloat@iwritey \efloat@float@endaquí.

Anexo 2018-03-25

Desde endfloat v2.6 las cosas se vuelven un poco más fáciles ya que la prueba "¿Es esta la última línea del entorno?" ahora está disponible como \efloat@if@end, por lo que este es el único comando interno que necesitamos parchear:

\documentclass{article}
\usepackage{graphicx}
\usepackage{mwe}

\newcommand{\addfig}[1]{%
\begin{figure}[htbp]  % when float environment is included here
\centering
  \includegraphics[width=\textwidth]{#1}
\end{figure}
}

\usepackage{endfloat}[2018/01/01] % we need at least v2.6
\usepackage{etoolbox}

% Adapt \addfig to the endfloat package
% First of all we make \addfig known to the endfloat package as variant of the figure environment
\DeclareDelayedFloatFlavour{addfig}{figure}
\makeatletter
% Since \addfig is a command and not an environment we need to start a group for our own
% using \begingroup, so it behaves like we would have written \begin{addfig}.
% (Note: The endfloat package is designed to work with environments, not with commands.)
% Additionally we patch \efloat@if@end (usually expanding to \@firstoftwo or \@secondoftwo)
% so the very first command line will be written to the file and the verbatim reading will be
% finished afterwards.
\newcommand\my@efloat@if@end[3]{#3#2}
\pretocmd\addfig{%
  \begingroup
  \let\efloat@if@end\my@efloat@if@end}{}{}
\makeatother

\begin{document}
\addfig{example-image}
\end{document}

Respuesta4

He aquí una solución basada enla respuesta de wernerpero que elimina el uso de endfloatpor completo. De todos modos, una vez que escribimos las cifras en un archivo externo, no parece haber mucha necesidad, endfloatya que podemos simplemente leer las cifras del archivo al final del documento.

Sucede que usa la expl3sintaxis, pero eso es realmente por cierto. expl3no le ofrece nada especial aquí: es solo una sintaxis alternativa.

Hay una macro:

\addfig[<options>]{<filename>}{<caption>}

Obviamente, el argumento opcional es para pasar opciones a \includegraphics, el segundo argumento es para el nombre del archivo de imagen y el tercero es para el título.

\documentclass{article}
\usepackage{graphicx,xparse,kantlipsum}
\ExplSyntaxOn
\AtBeginDocument
{
  \iow_new:N \l_strongbad_addfigs_stream
  \iow_open:Nn \l_strongbad_addfigs_stream { \jobname.addfigs }
}
\AtEndDocument
{
  \iow_close:N \l_strongbad_addfigs_stream
  \listoffigures
  \file_input:n { \jobname.addfigs }
}
\cs_new_protected:Nn \strongbad_addfig:nnn
{
  \group_begin:
  \str_set:Nn \l_tmpa_str { \setcounter{figure} }
  \str_put_right:Nx \l_tmpa_str { \c_left_brace_str }
  \str_put_right:Nx \l_tmpa_str { \thefigure }
  \str_put_right:Nx \l_tmpa_str { \c_right_brace_str }
  \iow_now:Nx \l_strongbad_addfigs_stream { \l_tmpa_str }
  \iow_now:Nn \l_strongbad_addfigs_stream
  {
    \begin{ figure }
      \centering
      \includegraphics [ #1 ] { #2 }
      \caption { #3 }
    \end{ figure }
  }
  \stepcounter{figure}
  \skip_vertical:N \bigskipamount
  \centering
  [~\figurename{}~\thefigure{}~about~here~]
  \skip_vertical:N \bigskipamount
  \group_end:
}
\NewDocumentCommand \addfig { O {} m +m }
{
  \strongbad_addfig:nnn { #1 } { #2 } { #3 }
}
\ExplSyntaxOff
\begin{document}
\kant[1]
\addfig{example-image-a}{first end figure}
\kant[2]
\addfig  {example-image-b}{second end figure}
\kant[3]
\addfig [width=.25\textwidth] {tiger} {third end figure}
\kant[4-5]
\end{document}

flota para terminar sin <code>endfloat</code>

información relacionada