在此示例中,tabularx 对 subfig 做了什么?

在此示例中,tabularx 对 subfig 做了什么?

这是我用来隐藏图形的环境的简化版本,仅显示标题。

其中一个挑战是,我不仅想忽略\includegraphics,还想忽略围绕各个图形排列的整个表格结构。同时,标签和子标签仍应可访问。为什么这很难?因为这会打印??,因此\phantom不会使其参数中的标签可访问:

\documentclass{article}
\begin{document}
\begin{figure}
    \caption{Label}
    \phantom{\label{label}}
\end{figure}
\ref{label}
\end{document}

\phantom[有没有不存在该问题的版本?]

我想,这就是我解决问题的方法。但是,在这个例子中, 中的子标签tabularx被称为 b,而 a 是正确的。(我将其与endfloat和其他几个包结合在一起,因此很难用旧版本的代码完全重现相同的问题。使用 时,问题确实出现在我的大文档中endfloat,但没有 时则不会出现。我不确定我如何在没有 的情况下将其简化为这个 MWE endfloat。此外,问题不会出现在tabular或中tabular*,我碰巧在手稿修订之间从一个切换到另一个。)

那么,简而言之:使用时出了什么问题tabularx

收到关于多次定义标签的警告(aux文件证实了这一点),我怀疑使用 tabularx 时,输入以某种方式被处理了两次。经过进一步调试,似乎\envlabels只设置了一次(即\g@addto@macro只执行了一次),也只执行了一次;但它的内容重复了:使用

        \renewcommand{\label}[1]{
            \typeout{This is printed once.}
            \g@addto@macro\envlabels{
                \typeout{But this is printed twice.}
                \orgsubfloat{\label{####1}}}}

macro:->\orgsubfloat {\label {subfloat}}\orgsubfloat {\label{subfloat}}

怎么会这样呢?

这是我的(大大简化的)代码:

\documentclass{article}
\usepackage{newenviron}
\usepackage{tabularx}
\usepackage{subfig}
\makeatletter
\newenviron{hidecontent}{
    \gdef\envlabels{}
    \let\orgsubfloat=\subfloat
    \renewcommand{\subfloat}[2][]{
        \renewcommand{\label}[1]{
            \g@addto@macro\envlabels{\orgsubfloat{\label{####1}}}}
        ##2}
    \begin{figure}
        \phantom{\envbody}
        \envlabels
    \end{figure}}{}

\begin{document}
Subfloat \subref{subfloat} is wrong, it should be (a).
\begin{hidecontent}
    \begin{tabularx}{\linewidth}{l}
        \subfloat{\label{subfloat}}
    \end{tabularx}
\end{hidecontent}
\end{document}

答案1

广告问题 1:\label内部发生的事件\phantom 无法访问

\label放置在\phantoms 内部的 s 无法访问的原因是:

\label命令确实会触发将信息写入辅助文件。
\protected@write用于此目的。
\protected@write确实会触发以\immediate延迟方式而不是时尚方式写入内容。 这意味着: 当遇到写入指令时,不会立即写入内容,而是在处理构造过程中\write发生相关命令的框并根据输出例程将其发送出/写入 .pdf 文件/.dvi 文件时写入内容。 (这样做是有原因的:例如,在构造框时通常不知道页码,但在输出例程准备页面时知道页码\shipout。 诸如还将页码写入辅助文件之类的事情\label,以便您可以\pageref在连续的 latex 运行/再次编译文档时进行引用。)

所有\phantom东西都放在一个盒子里,这个盒子永远不会运出,因为它只用于测量,然后创建另一个相同尺寸的空盒子。

因此,一种方法是重新定义\protected@write以将其自己的调用添加到某些宏的定义中并在外部调用该宏\phantom

\documentclass{article}

\makeatletter
\newcommand\phantomWithDelayedWrites[1]{%
  \begingroup
  \gdef\CollectedCallsToProtected@write{}%
  \long\def\protected@write##1##2##3{%
    \g@addto@macro\CollectedCallsToProtected@write{\protected@write{##1}{##2}{##3}}%
  }%
  \phantom{#1}%
  \expandafter\endgroup\CollectedCallsToProtected@write
}%
\makeatother

\begin{document}

\newcounter{mycounter}
\setcounter{mycounter}{9}

\begin{figure}
    \caption{Label}%

    A\phantomWithDelayedWrites{ Text Text \label{label} Text Text \stepcounter{mycounter}}B%

    A Text Text  Text Text B%
\end{figure}

Reference to figure 1 even while the correesponding \verb|\label|-command occured
inside \verb|phantom|: \ref{label}

By the way: Did you realize that counters etc get stepped inside \verb|\phantom|?
If this was not the case, then \verb|mycounter| would still have the value \verb|9|
but it has value {\csname verbatim@font\endcsname\selectfont\themycounter}.

\end{document}

在此处输入图片描述

顺便一提:

\specials您可能会遇到将超链接和/或类似名称的目标放置到生成的输出文件中的问题。例如,当使用hyperref-package,如果放置超链接的指令出现在 中,则超链接的目标将不会出现在 .pdf 文件中。\phantom使用hyperref,然后分段命令(如\caption或)触发此类/目的地\section的放置......\specials

我认为一个功能不是基于放置相等尺寸的空框,而是基于在生成的 .pdf 输出文件中完全无色且不可见的文本(可能具有不可复制粘贴的属性),这将是很好的:

如果有最新的软件可用,并且你的目标是生成 pdf 文件,那么你可以\phantom通过 Heiko Oberdiek 的transparent包。
在使用 transparent包,相关文档至少需要编译两次。终端或 .log 文件中的警告消息将通知您有关此情况。

如果你还希望防止复制粘贴不可见的文本,你可以使用 Heiko Oberdiek 的accsupp用于提供通过复制粘贴提供的替代文本的包。

\documentclass[12pt]{article}
\usepackage[unicode]{hyperref}
\usepackage{accsupp}[2007/11/14]
\usepackage{color}
\usepackage{transparent}
\usepackage{graphicx}

\parindent=0ex
\parskip=.66\baselineskip

\begin{document}

\textbf{Here inside the {\csname verbatim@font\endcsname\string\fbox} the
``non-phan\-to\-mi\-zed'' thing:}

Here the start:
\fbox{%
  \parbox{4cm}{%
    Some text. When you try to copy-paste, with the ``non-phan\-to\-mi\-zed'' thing the
    pas\-ting-re\-sult may be nice and with the ``phantomized'' thing the pas\-ting-re\-sult 
    may be the advice not to do this.\\
    \includegraphics[width=4cm]{example-image-a}%
  }%
}
Here the end.

\textbf{Here inside the {\csname verbatim@font\endcsname\string\fbox} the
``phantomized'' thing:}

Here the start: %
\fbox{%
  \begingroup 
  % Make the text inside the group transparent and thus invisible within the pdf-viewer:
  \transparent{0.0}%
  % Within AccSupp provide replacement-text when attempting to copy-paste the material:
  \BeginAccSupp{method=pdfstringdef, space, unicode, ActualText={DO NOT COPY-PASTE THIS!}}%
  %
  \parbox{4cm}{%
    Some text. When you try to copy-paste, with the ``non-phan\-to\-mi\-zed'' thing the
    pas\-ting-re\-sult may be nice and with the ``phantomized'' thing the pas\-ting-re\-sult 
    may be the advice not to do this.\\
    \includegraphics[width=4cm]{example-image-a}%
  }%
  %
  \EndAccSupp{}%
  \endgroup
}
Here the end.

\end{document}

在此处输入图片描述

\label广告问题 2:在宏内收集调用时定义多个标签tabularx

为了调整单元格的宽度,tabularx需要进行多次测试运行,在此期间,构成表格单元格内容的标记会被执行。
因此,tabularx您的\g@addto@macro指令也会被执行多次。
您需要确保您的\g@addto@macro指令仅在最后一次运行中执行,而不是在测试运行期间执行。

怎么做? :

在测试运行中\@footnotetext让其等于\TX@trial@ftn(参见 tabularx 包,David Carlisle,2016/02/03,⟨http://mirrors.ctan.org/macros/latex/required/tools/tabularx.pdf⟩,第 5 节宏,代码第 119 行),因此您可以编写一个宏,通过检查定义在测试运行时进行测试\@footnotetext

\documentclass{article}
\usepackage{newenviron}
\usepackage{tabularx}

\makeatletter
\newcommand\DoIfNotTabularxTestRun{%
  \ifx\@footnotetext\TX@trial@ftn\expandafter\@gobble\else\expandafter\@firstofone\fi
}%
\makeatother

\usepackage{subfig}

\makeatletter
\newenviron{hidecontent}{%
  \gdef\envlabels{}%
  \let\orgsubfloat=\subfloat
  \renewcommand{\subfloat}[2][]{%
    \begingroup %<-tabularx is a restricting scope on its own.
                %  but you may need this scope when using hidecontent's subfloat
                % without additional environments. Otherise \subfloat's redefinition
                % will remain effective even at the time of carrying out \envlabels
    \renewcommand{\label}[1]{%
      \DoIfNotTabularxTestRun{\myg@addto@macro\envlabels{\orgsubfloat{\protect\label{####1}}}}%
    }%
    ##2%
   \endgroup
  }%
  \begin{figure}%
    \phantom{\envbody}%
    \envlabels
  \end{figure}%
}{}%
\makeatother

\begin{document}
Subfloat \subref{subfloat} should be (a). Is it?
\begin{hidecontent}
    \begin{tabularx}{\linewidth}{l}
        \subfloat{\label{subfloat}}
    \end{tabularx}
\end{hidecontent}
\end{document}

在此处输入图片描述

相关内容