我想使用tcolorbox listing
环境以有趣的方式格式化列表。对于每个列表,我希望以某种方式有一个标题,默认情况下它将是这样的Listing (number)
,但如果指定(作为可选参数),它将是指定的文本。此文本也应在底层用作装饰。
在下一个 MWE 中,第一的环境clisting
可以运行,但没有参数化,主要展示我想要实现的目标。
第二环境cxparselisting
显示了我认为它应该如何实现。/tcb/xparse
库命令\NewTCBListing
被使用并用于O{text}
,但它不起作用并且在所述内容中首字母被解释为可选参数(如下所述:text
#1
cxparselisting
#
tcblisting 的问题:缺少第一个列出的 LaTeX 命令)。
我一定是误解了如何在中创建可选参数xparse
。
第三环境,xmllisting
也展示了我想要实现的目标,而且令人惊讶的是,它可以与非xparse
语法一起使用(尽管首先?令牌 标签被吸收)。
我如何构造(最好)\NewTCBListing
一个具有默认值的可选参数(即参数化的,因此可以在多个 tcbox 选项中使用)?
MWE:(删除注释环境附近的%以禁用不工作cxparselisting
并能够编译 MWE)
\documentclass [a4paper, 11pt, twoside, openright] {scrbook}
\usepackage{comment}
\usepackage[dvipsnames,x11names,svgnames,table]{xcolor}
\usepackage{enumitem}
\usepackage[skins, vignette, breakable, hooks, xparse, minted, raster]{tcolorbox}
\tcbset{listing engine=minted}
\newcounter{ccounter}
\newtcblisting[use counter=ccounter]{clisting}{% Works, but without parametrization
colframe=green!75!black,%
listing only,%
% title=#1,
title=C listing \theccounter,
minted language=C,
underlay middle and last={%
\ifnumequal{\numexpr\tcbsegmentstate}{2}{\begin{tcbclipinterior}\fill[red!10!blue!10!white] ([xshift=-7mm]frame.south east)
rectangle (frame.north east) node [anchor=south east,rotate=90] {\bfseries \textcolor{black}{C listing \theccounter -- Output}};\end{tcbclipinterior}%
}
{\begin{tcbclipinterior}\fill[red!10!blue!10!white] ([xshift=-7mm]frame.south east)
rectangle (frame.north east) node [anchor=south east,rotate=90] {\bfseries \textcolor{black}{C listing \theccounter}};\end{tcbclipinterior}%
}
},%
}
%\begin{comment}
\NewTCBListing[use counter=ccounter]{cxparselisting}{ O{C~listing~\theccounter} }{% Doesnt work, probably still grabs first letter in optional argument scan
colframe=green!75!black,%
listing only,%
title=#1,
minted language=C,
underlay middle and last={%
\ifnumequal{\numexpr\tcbsegmentstate}{2}{\begin{tcbclipinterior}\fill[red!10!blue!10!white] ([xshift=-7mm]frame.south east)
rectangle (frame.north east) node [anchor=south east,rotate=90] {\bfseries \textcolor{black}{#1 -- Output}};\end{tcbclipinterior}%
}
{\begin{tcbclipinterior}\fill[red!10!blue!10!white] ([xshift=-7mm]frame.south east)
rectangle (frame.north east) node [anchor=south east,rotate=90] {\bfseries \textcolor{black}{#1}};\end{tcbclipinterior}%
}
},%
}
%\end{comment}
\newcounter{xmlcounter}
\newtcblisting[use counter=xmlcounter]{xmllisting}[1][XML listing \thexmlcounter]{% Surprisingly, works ...
colframe=blue!75!black,%
listing only,%
title=#1,
minted language=XML,
underlay middle and last={%
\ifnumequal{\numexpr\tcbsegmentstate}{2}{\begin{tcbclipinterior}\fill[red!10!blue!10!white] ([xshift=-7mm]frame.south east)
rectangle (frame.north east) node [anchor=south east,rotate=90] {\bfseries \textcolor{black}{#1 -- Output}};\end{tcbclipinterior}%
}
{\begin{tcbclipinterior}\fill[red!10!blue!10!white] ([xshift=-7mm]frame.south east)
rectangle (frame.north east) node [anchor=south east,rotate=90] {\bfseries \textcolor{black}{#1}};\end{tcbclipinterior}%
}
},%
}
\begin{document}
\begin{clisting}
#include <stdio.h>
int main() {
printf(''Hello World!\n'');
return 0;
}
\end{clisting}
\bigskip
%\begin{comment}
\begin{cxparselisting}
#include <stdio.h>
int main() {
printf(''Hello World!\n'');
return 0;
}
\end{cxparselisting}
%\end{comment}
\bigskip
\begin{xmllisting}
<message>
<text>Hello, world!</text>
</message>
\end{xmllisting}
\end{document}
答案1
文档第 453 页tcolorbox
解释了该问题:
自 2018-05-12 起,xparse [13] 包更改了参数收集过程。现在,空格会被忽略,这会导致列出以 O{} 等可选参数结尾的环境发生严重变化。可以通过添加“!”来保留以前尊重空格的行为。
xparse
后来进行了调整以减少该问题的发生,但tcblisting
文档中的陈述仍然是正确的(不幸的是)。
因此,你必须更换
\NewTCBListing[use counter=ccounter]{cxparselisting}{ O{C~listing~\theccounter} }{%
经过
\NewTCBListing[use counter=ccounter]{cxparselisting}{ !O{C~listing~\theccounter} }{%
解决(规避)问题。