问题

问题

我尝试制作一个非浮动的图形环境。

问题

当两个图形足够接近时,第二个图形会被 TeX 分页机制推到下一页,而第一个图形则会被忽略。

图片列表

这里我们看到了我自制的图形列表的输出,其命名恰当,\mylistoffiguresenter image description here

缺少图片

这里我们看到了上面未列出的缺失数字: enter image description here

代码

我的代码编写方式使得 image.jpg 不是必需的。我调整了标签参考系统以使用我的运行计数器。这是因为我需要从打印计数器中抽象出一个唯一的数字,因为我\thefigure在每个语言版本中重置了打印,由 模拟\setcurrentlanguage

\documentclass{article}
\usepackage{fontspec}% xelatex
\usepackage{xparse}
\usepackage{environ}
\usepackage{lipsum}
\usepackage{tikz}
\usepackage{hyperref}
\makeatletter

% Define counter
\newcounter{runningfigurecounter}% latex counter, equiv of \global\newcount\runningfigurecounter\runningfigurecounter=0

% Redefine hyperref unique label
\renewcommand*{\theHfigure}{runningfigurecounter.\the\value{runningfigurecounter}} % Sets fifth field in second component of \newlabel to provide unique labels independent of what gets printed i.e. the counter \c@figure etc.

% https://tex.stackexchange.com/questions/273098/mimicking-latexs-table-of-contents-functionality?noredirect=1&lq=1
\long\def\myfigure@addtocontents#1#2{%
  \protected@write\@auxout%
    {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
    {\string\myfigure@writefile{#1}{#2}}}%use our own version of \@writefile

\long\def\myfigure@writefile#1#2{% Redefine our own file handler. This gets called by aux file macros.
  \@ifundefined{#1}\relax%
    {\@temptokena{#2}%
     \immediate\write\csname #1\endcsname{\the\@temptokena}% open file handler
    }%
}

\NewDocumentEnvironment{myfigure}{ O{} m O{build:fig:\therunningfigurecounter} }{% \therunningfigurecounter instead \the\runningfigurecounter because it was defined using latex and not tex
% 1: optional graphicx arg
% 2: file
% 3: label
    \myfigure@getBODY%
  }%
  {%
    \endmyfigure@getBODY%
    \refstepcounter{runningfigurecounter}% global backend figure counter
    \@temptokena{\protect\contentsline{figure}{\protect\numberline{\thefigure}\protect{\ignorespaces\myfigurecaption\relax\protect}}{\thepage}{figure.runningfigurecounter.\therunningfigurecounter}}% Contents Line (hyperref format)
    \myfigure@addtocontents{lof_\mylanguage}{\the\@temptokena}% Adds \@writefile{lof_en-US}{expanded contents of \@temptokena} to aux
    \def\@captype{figure}% see source2e for using caption outside of float
    \medbreak% adds \medskip but only if preceding space is less than what \medbreak would insert
    \centering% ensure figure and caption is centered within environment
    \vbox{% keep stuff on the same page
    \IfFileExists{#2}%
      {% ensure graphic exists in filesystem
        \caption{\myfigurecaption}% handles printed counter logic
        \label{#3}% requires redef of \label \ref \autoref \nameref to include build\mylanguage suffix
        \includegraphics[width=.8\linewidth,#1]{#2}%
      }% True
      {%
        \caption{\myfigurecaption}% handles printed counter logic
        \label{#3}% \requires redef of \label \ref \autoref \nameref to include build:\mylanguage suffix
        \tikz \draw [fill=red!15] (0,0) rectangle node [align=center] {Missing Image\\#2} (.8\linewidth, 50mm);
        \typeout{Error: Missing figure file #2.}%
      }% False
    }% end vbox
    \medbreak% adds \medskip but only if preceding space is less than what \medbreak would insert
  }%


\NewEnviron{myfigure@getBODY}% The goal of collecting \BODY of myfigure is to separate translated text from LaTeX code.
  {\global\let\myfigurecaption\BODY}%

  \NewDocumentCommand{\mylistoffigures}{}{% Provides list of figures local, works with \@mystarttoc
% to a language
  \newpage\section{\listfigurename
    \@mkboth{%
      \MakeUppercase\listfigurename}{\MakeUppercase\listfigurename}}%
  \@mystarttoc{lof_\mylanguage}\newpage% Language-specific lof file is only made if \mylistoffigures called. %\vfill% \vspace*{glue} fill vertical space below line  in which is appears %\vfill ends graf immediately ad add vertical space
}

\def\@mystarttoc#1{% imitates latex \@starttoc, except removes tf@ prefix to file handle
\begingroup
 \makeatletter
 \@input{\jobname.#1}%
 \if@filesw% Controls whether writing is enabled. Controls whether writing is enabled. Conditional returns false if    \nofiles is issued and no writing to aux has been performed.
   \expandafter\newwrite\csname #1\endcsname% make file handle
   \immediate\openout \csname #1\endcsname \jobname.#1\relax% open file handle
 \fi
 \@nobreakfalse
\endgroup}

\makeatother

\NewDocumentCommand\setcurrentlanguage{ m }{\edef\mylanguage{#1}}

\begin{document}
\setcurrentlanguage{en-US}
\mylistoffigures
\newpage
\begin{myfigure}{image.jpg}[fig:label]
Apples.
\end{myfigure}
\lipsum[1-3]

filler

filler

\begin{myfigure}{image.jpg}[fig:label]
Bananas.
\end{myfigure}
\lipsum[1-3]
\newpage
\begin{myfigure}{image.jpg}[fig:label]
Pears.
\end{myfigure}
\end{document}

答案1

你得到

\contentsline {figure}{\numberline {2}{\ignorespaces Bananas.\relax }}{2}{figure.runningfigurecounter.2}
\contentsline {figure}{\numberline {2}{\ignorespaces Bananas.\relax }}{2}{figure.runningfigurecounter.2}
\contentsline {figure}{\numberline {3}{\ignorespaces Pears.\relax }}{4}{figure.runningfigurecounter.3}

在您的 .lof 文件中,因为您只是在页面发走时写入令牌寄存器的值,所以如果一页上有多个图形,那么您得到的最后一个图形的重复次数与图形的数量一样多。

您可以使用

\myfigure@addtocontents{lof_\mylanguage}{\protect\contentsline{figure}{\protect\numberline{\thefigure}\protect{\ignorespaces\myfigurecaption\relax\protect}}{\thepage}{figure.runningfigurecounter.\therunningfigurecounter}}% Adds \@writefile{lof_en-US}{expanded contents of \@temptokena} to aux

因此只需将您的\@temptokena设置移动到 addtocontents 然后你就会得到

\contentsline {figure}{\numberline {0}{\ignorespaces Apples.\relax }}{2}{figure.runningfigurecounter.1}
\contentsline {figure}{\numberline {1}{\ignorespaces Bananas.\relax }}{2}{figure.runningfigurecounter.2}
\contentsline {figure}{\numberline {2}{\ignorespaces Pears.\relax }}{4}{figure.runningfigurecounter.3}

它获得三个不同的条目,但编号为 0,1,2 而不是 1,2,3,因为您在增加计数器之前进行了写入。

因此将其移至\caption获取之后:

enter image description here

\documentclass{article}
\usepackage{fontspec}% xelatex
\usepackage{xparse}
\usepackage{environ}
\usepackage{lipsum}
\usepackage{tikz}
\usepackage{hyperref}
\makeatletter

% Define counter
\newcounter{runningfigurecounter}% latex counter, equiv of \global\newcount\runningfigurecounter\runningfigurecounter=0

% Redefine hyperref unique label
\renewcommand*{\theHfigure}{runningfigurecounter.\the\value{runningfigurecounter}} % Sets fifth field in second component of \newlabel to provide unique labels independent of what gets printed i.e. the counter \c@figure etc.

% https://tex.stackexchange.com/questions/273098/mimicking-latexs-table-of-contents-functionality?noredirect=1&lq=1
\long\def\myfigure@addtocontents#1#2{%
  \protected@write\@auxout%
    {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
    {\string\myfigure@writefile{#1}{#2}}}%use our own version of \@writefile

\long\def\myfigure@writefile#1#2{% Redefine our own file handler. This gets called by aux file macros.
  \@ifundefined{#1}\relax%
    {\@temptokena{#2}%
     \immediate\write\csname #1\endcsname{\the\@temptokena}% open file handler
    }%
}

\NewDocumentEnvironment{myfigure}{ O{} m O{build:fig:\therunningfigurecounter} }{% \therunningfigurecounter instead \the\runningfigurecounter because it was defined using latex and not tex
% 1: optional graphicx arg
% 2: file
% 3: label
    \myfigure@getBODY%
  }%
  {%
    \endmyfigure@getBODY%
    \refstepcounter{runningfigurecounter}% global backend figure counter
    \def\@captype{figure}% see source2e for using caption outside of float
    \medbreak% adds \medskip but only if preceding space is less than what \medbreak would insert
    \centering% ensure figure and caption is centered within environment
    \vbox{% keep stuff on the same page
    \IfFileExists{#2}%
      {% ensure graphic exists in filesystem
        \caption{\myfigurecaption}% handles printed counter logic
        \label{#3}% requires redef of \label \ref \autoref \nameref to include build\mylanguage suffix
        \includegraphics[width=.8\linewidth,#1]{#2}%
      }% True
      {%
        \caption{\myfigurecaption}% handles printed counter logic
        \label{#3}% \requires redef of \label \ref \autoref \nameref to include build:\mylanguage suffix
        \tikz \draw [fill=red!15] (0,0) rectangle node [align=center] {Missing Image\\#2} (.8\linewidth, 50mm);
        \typeout{Error: Missing figure file #2.}%
      }% False
    \myfigure@addtocontents{lof_\mylanguage}{\protect\contentsline{figure}{\protect\numberline{\thefigure}\protect{\ignorespaces\myfigurecaption\relax\protect}}{\thepage}{figure.runningfigurecounter.\therunningfigurecounter}}% Adds \@writefile{lof_en-US}{expanded contents of \@temptokena} to aux
    }% end vbox
    \medbreak% adds \medskip but only if preceding space is less than what \medbreak would insert
  }%


\NewEnviron{myfigure@getBODY}% The goal of collecting \BODY of myfigure is to separate translated text from LaTeX code.
  {\global\let\myfigurecaption\BODY}%

  \NewDocumentCommand{\mylistoffigures}{}{% Provides list of figures local, works with \@mystarttoc
% to a language
  \newpage\section{\listfigurename
    \@mkboth{%
      \MakeUppercase\listfigurename}{\MakeUppercase\listfigurename}}%
  \@mystarttoc{lof_\mylanguage}\newpage% Language-specific lof file is only made if \mylistoffigures called. %\vfill% \vspace*{glue} fill vertical space below line  in which is appears %\vfill ends graf immediately ad add vertical space
}

\def\@mystarttoc#1{% imitates latex \@starttoc, except removes tf@ prefix to file handle
\begingroup
 \makeatletter
 \@input{\jobname.#1}%
 \if@filesw% Controls whether writing is enabled. Controls whether writing is enabled. Conditional returns false if    \nofiles is issued and no writing to aux has been performed.
   \expandafter\newwrite\csname #1\endcsname% make file handle
   \immediate\openout \csname #1\endcsname \jobname.#1\relax% open file handle
 \fi
 \@nobreakfalse
\endgroup}

\makeatother

\NewDocumentCommand\setcurrentlanguage{ m }{\edef\mylanguage{#1}}

\begin{document}
\setcurrentlanguage{en-US}
\mylistoffigures
\newpage
\begin{myfigure}{image.jpg}[fig:label]
Apples.
\end{myfigure}
\lipsum[1-3]

filler

filler

\begin{myfigure}{image.jpg}[fig:label]
Bananas.
\end{myfigure}
\lipsum[1-3]
\newpage
\begin{myfigure}{image.jpg}[fig:label]
Pears.
\end{myfigure}
\end{document}

相关内容