考虑以下代码:
\documentclass[10pt,letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepackage{calc}
\usepackage{tikz}
\usepackage{listings}
\usepackage[listings,skins,theorems]{tcolorbox}
\newlength{\numlen}
\newcommand{\getnumlen}[1]{
\setlength{\numlen}{\widthof{\fontfamily{cmtt}\selectfont#1 0123456789}}
\setlength{\numlen}{0.1\numlen}
}
\newtcblisting{mytcblisting}[1][]{
before = {\getnumlen{#1}},
enhanced,
left = 4.\numlen,%\numlen is correct here
listing only,
listing options = {
language = C++,
basicstyle=\fontfamily{cmtt}\selectfont#1,
showstringspaces = false,
numbers = left,
numbersep = 4.\numlen,%\numlen seems to be 0 here
},
}
\begin{document}
\begin{mytcblisting}[\tiny]
int main(int argc, char* argv[]) {
return 0;
}
\end{mytcblisting}
\end{document}
我希望left
数字和代码之间的测量和分离numbersep
基于在cmtt
系列中写入的数字的典型长度,其大小作为参数传递mytcblisting
。
但是使用此代码,left
选项可以正常工作,但不能numbersep
。
如何让它工作?
答案1
显然,在使用和设置listing options
之前先进行评估。这意味着必须在此特殊选项块中调用-- > 。before=\getnumlen{#1}
numlen
numlen
0pt
\getnumlen{#1}
肮脏的试验 -->在选项\getnumlen{#1}
中使用basicstyle
--> 它是一个有效的代码宏,没有排版/字体宏,所以它不会造成危害。
\documentclass[10pt,letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepackage{calc}
\usepackage{tikz}
\usepackage{listings}
\usepackage[listings,skins,theorems]{tcolorbox}
\newlength{\numlen}
\newcommand{\getnumlen}[1]{%
\setlength{\numlen}{\widthof{\fontfamily{cmtt}\selectfont#1 0123456789}}%
\setlength{\numlen}{0.1\numlen}%
}
\newtcblisting{mytcblisting}[1][]{%
listing options = {%
language = C++,
basicstyle=\getnumlen{#1}\fontfamily{cmtt}\selectfont#1,
showstringspaces = false,
numbers = left,
numbersep = 4.\numlen,%\numlen seems to be 0 here
},%
before = {\getnumlen{#1}},
enhanced,
left = 4.\numlen,%\numlen is correct here
listing only
}
\begin{document}
\begin{mytcblisting}[\tiny]
int main(int argc, char* argv[]) {
return 0;
}
\end{mytcblisting}
\end{document}
编辑一种更简洁的方法:向密钥系列中添加一个密钥lst
:
\documentclass[10pt,letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepackage{calc}
\usepackage{tikz}
\usepackage{listings}
\usepackage[listings,skins,theorems]{tcolorbox}
\makeatletter
\define@key{lst}{numlen}[\protect\tiny]{%%
\getnumlen{#1}%
}
\makeatother
\newlength{\numlen}
\newcommand{\getnumlen}[1]{%
\setlength{\numlen}{\widthof{\fontfamily{cmtt}\selectfont#1 0123456789}}%
\setlength{\numlen}{0.1\numlen}%
}
\newtcblisting{mytcblisting}[1][]{%
listing options = {%
language = C++,
basicstyle=\fontfamily{cmtt}\selectfont#1,
showstringspaces = false,
numbers = left,
numlen={\protect #1},
numbersep = 6.\numlen,%\numlen seems to be 0 here
},%
before = {\getnumlen{\protect #1}},
enhanced,
left = 4.\numlen,%\numlen is correct here
listing only
}
\begin{document}
\begin{mytcblisting}[\tiny]
int main(int argc, char* argv[]) {
return 0;
}
\end{mytcblisting}
\end{document}