为什么 upquote 不能与 tabularx 一起使用?

为什么 upquote 不能与 tabularx 一起使用?

为什么不可以upquote使用tabularx

\documentclass{article}
\usepackage{upquote}
\usepackage{tabularx}

\begin{document}
This works:

\begin{tabular}{c}
  Inline \verb|`code`| \\   
\end{tabular}

This doesn't work:

\begin{tabularx}{\linewidth}{X}
  Inline \verb|`code`| \\   
\end{tabularx}
\end{document}

在此处输入图片描述

我也有警告:

\verb may be unreliable inside tabularx

对于我的实际情况,我使用\textasciigravefromtextcomp包解决了。有没有更快的方法?

答案1

正如 Henri Menke 在他的回答中提到的那样,tabularx扫描整个环境tabularx并修复 catcodes。\verb另一方面,依赖于可变的 catcodes 才能正常工作。作为一种解决方法,tabularx提供了一个版本\verb(请参阅文档完整列表),因此您会收到警告。

upquote包更改了一个内部\verb宏,使'`处于活动状态,并让它们扩展为各自的字形表示。如上所述,catcode 更改不适用于tabularx,但我们仍然可以扩展\verb它提供的替代方案:

\documentclass{article}
\usepackage{upquote}
\usepackage{tabularx}

\makeatletter

\let\@upquote@quote=\textquotesingle
\let\@upquote@grave=\textasciigrave
\ifx\encodingdefault\upquote@OTone
  \ifx\ttdefault\upquote@cmtt
    \def\@upquote@quote{\char13 }
    \def\@upquote@grave{\char18 }
  \fi
\fi

\def\@upquote@repl#1{%
  \if\relax\detokenize{#1}\relax\else\@upquote@repl@#1\@end\fi
}
\def\@upquote@repl@#1#2\@end{%
  \if#1`\@upquote@grave\else
    \if#1'\@upquote@quote\else#1\fi
  \fi
  \if\relax\detokenize{#2}\relax\else\@upquote@repl@#2\@end\fi
}

\begingroup
\catcode`\*=\catcode`\#
\catcode`\#=12
\gdef\TX@vfirst{%
  \if\@tempa#%
    \def\@tempb{\TX@v@#}%
  \else
    \let\@tempb\TX@v@
    \if\@tempa\space~\else
      \expandafter\@upquote@repl\expandafter{\@tempa}%
    \fi
  \fi
  \@tempb
}

\gdef\TX@v@hash*1##*2{%
  \@upquote@repl{*1}%
  \ifx*2\relax\else#\expandafter\TX@v@hash\fi*2%
}
\endgroup

\makeatother

\begin{document}
This works:

\begin{tabular}{c}
  Inline \verb|`code`| \\
\end{tabular}

This works now, too:

\begin{tabularx}{\linewidth}{X}
  Inline \verb|`code`| \\
\end{tabularx}
\end{document}

首先,我们设置\@upquote@quote和分别映射到和\@upquote@grave的直立字形。接下来是辅助宏的定义,该宏用相应的字形替换其参数文本中出现的每个和。'`\@upquote@repl'`

现在,我们可以在打印最终输出之前在正确的位置调整\verb内部辅助宏以应用。事实证明,我们需要更改,它对第一个逐字字符有一些特殊处理,以及,它处理其余文本。结果符合预期:\upquote@repl\TX@vfirst\TX@v@hash

在此处输入图片描述

答案2

tabularx将其主体收集为参数,因此对输入进行标记。这会破坏逐字材料,类似于为什么\section{\verb|`code`|}不起作用。将逐字材料转发到浮动参数的唯一可能性是先将其保存在框中。在这种情况下,tabularx您也必须这样做,\copy而不是\box因为算法的多通道性质。

\documentclass{article}
\pagestyle{empty}
\usepackage{upquote}
\usepackage{tabularx}

\begin{document}
This works:

\begin{tabular}{c}
  Inline \verb|`code`| \\   
\end{tabular}

This doesn't work:

\setbox0=\hbox{\verb|`code`|}
\begin{tabularx}{\linewidth}{X}
  Inline \copy0 \\   
\end{tabularx}
\end{document}

相关内容