以下代码显示了问题。我已声明一个\newtcblisting
带有可选参数的。
\newtcblisting{codiltxb}[1][]{listing only, #1}
当可选参数出现在进一步的声明中时,列表是正确的。(图中的第 1 个和第 2 个框)
\begin{codiltxb}[colback=green!20]
\Some code. Correct if the optional argument is present.
\end{codiltxb}
\begin{codiltxb}[]
\Some code. Correct if the optional argument, although empty, is present.
\end{codiltxb}
但是,如果可选参数不存在并且列表中的第一个单词以\
(如\LaTeX
命令)开头,则该第一个命令将从结果列表中消失。(第三个框)
\begin{codiltxb}
\Some code. FAIL! No optional argument. First word (\LaTeX command) missing.
\end{codiltxb}
如果可选参数不存在并且第一个单词不以 开头\
,则列表再次正确。(第 4 个框)
\begin{codiltxb}
Some code. Correct! No optional argument. First word not \LaTeX command.
\end{codiltxb}
我的代码有什么问题?
\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[most]{tcolorbox}
\newtcblisting{codiltxb}[1][]{listing only, #1}
\begin{document}
\begin{frame}[fragile]
\frametitle{Listing}
\begin{codiltxb}[colback=green!20]
\Some code. Correct if the optional argument is present.
\end{codiltxb}
\begin{codiltxb}[]
\Some code. Correct if the optional argument, although empty, is present.
\end{codiltxb}
\begin{codiltxb}
\Some code. FAIL! No optional argument. First word (\LaTeX command) missing.
\end{codiltxb}
\begin{codiltxb}
Some code. Correct! No optional argument. First word not \LaTeX command.
\end{codiltxb}
\end{frame}
\end{document}
备注 (2018-06-13):尽管 Thomas F. Sturm 的答案直到现在仍然有效,但最近(2018-05-12)进行了一些更改xparse
(参见:xparse 使用可选参数吞噬字符)使其再次失败。在等待更好的解决方案时,一个可行的解决方案是
\NewTCBListing{codiltxb}{ !O{} }{listing only, #1}
答案1
更新:
!O{}
代替O{}
内部\NewTCBListing{codiltxb}{ !O{} }{listing only, #1}
以适应xparse
2018-05-12 日期的变化。
已知 仅对一个可选参数存在解析问题\newtcblisting
。tcolorbox
手册在第 245 页 (v2.60) 对此发出警告,并建议改用\NewTCBListing
。
\@ifnextchar
原因是抓取了可选参数,正如 egreg 在他的回答中所解释的那样。如果使用,则由标准完成\newtcblisting
。如果使用\NewTCBListing
,xparse
则使用更适合该任务的代码。
因此,替换
\newtcblisting{codiltxb}[1][]{listing only, #1}
经过
\NewTCBListing{codiltxb}{ !O{} }{listing only, #1}
你得到了正确的结果。
\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[most]{tcolorbox}
\NewTCBListing{codiltxb}{ !O{} }{listing only, #1}
\begin{document}
\begin{frame}[fragile]
\frametitle{Listing}
\begin{codiltxb}[colback=green!20]
\Some code. Correct if the optional argument is present.
\end{codiltxb}
\begin{codiltxb}[]
\Some code. Correct if the optional argument, although empty, is present.
\end{codiltxb}
\begin{codiltxb}
\Some code. FAIL! No optional argument. First word (\LaTeX command) missing.
\end{codiltxb}
\begin{codiltxb}
Some code. Correct! No optional argument. First word not \LaTeX command.
\end{codiltxb}
\end{frame}
\end{document}
答案2
这与可选参数的抓取有关;如果我使用\new@ifnextchar
并amsmath
以\codiltxb
困难的方式重新定义,我会得到预期的结果;这导致在右括号和之间不能有空格[
,但这不是什么大问题。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[most]{tcolorbox}
\usepackage{amsmath}
\newtcblisting{codiltxb}[1][]{listing only, #1}
\makeatletter
\renewcommand{\codiltxb}{%
\new@ifnextchar[\@codiltxb{\tcblisting {listing only,options@for=codiltxb}}%
}
\def\@codiltxb[#1]{\tcblisting {listing only,#1,options@for=codiltxb}}
\makeatother
\begin{document}
\begin{codiltxb}[colback=green!20]
\Some code. Correct if the optional argument is present.
\end{codiltxb}
\begin{codiltxb}[]
\Some code. Correct if the optional argument, although empty, is present.
\end{codiltxb}
\begin{codiltxb}
\Some code. FAIL! No optional argument. First word (\LaTeX command) missing.
\end{codiltxb}
\begin{codiltxb}
Some code. Correct! No optional argument. First word not \LaTeX command.
\end{codiltxb}
\end{document}