背景:在 Bash 中,$#
代表参数的数量,并#
开始注释。
考虑以下 Bash 脚本:
# This is a comment
while [[ $# -gt 0 ]]; do
echo $1
shift
done
请注意,此处 StackExchange 的语法着色是不正确! #
in$#
被视为注释标记。
不幸的是,该listings
软件包给了我相同的结果:
\documentclass{article}
\usepackage{listings}
\lstset{language=Bash}
\pagenumbering{gobble}
\begin{document}
\begin{lstlisting}
# This is a comment
while [[ $# -gt 0 ]]; do
echo $1
shift
done
\end{lstlisting}
\end{document}
我该如何修复这个问题并listings
显示正确的输出?
答案1
编写该listings
语言的人bash
可能没有预料到这种情况。实际上,该listings
包与适当的词法分析器相差甚远,并且没有提供进行这种语法突出显示的简洁方法。就listings
'Bash
语言而言,#
在正常“处理”模式下遇到的字符会开始注释,仅此而已。
一个简单的(虽然很丑陋)修复方法是使用literate
键将模式的所有实例替换$#
为......好吧......它本身......以防止#
字符在前面开始注释$
:
不幸的是,这个技巧有副作用:如果columns=fullflexible
使用,后面的空格字符$#
(如果有)会被吞噬,这是不可取的。解决这个问题的一种方法是使用选项keepspaces
。
更新:实际上,Manuel 提到的防止空间被吞噬的解决方法他的回答最好设置keepspaces
;看看。
\documentclass{article}
\usepackage{listings}
\lstset{
language = Bash,
literate = {\$\#}{{{\$\#}}}2,
columns = fullflexible,
keepspaces,
}
\pagenumbering{gobble}
\begin{document}
\begin{lstlisting}
# This is a comment
while [[ $# -gt 0 ]]; do
echo $1
shift
done
\end{lstlisting}
\end{document}
答案2
如果你不介意在列表中添加标记,你可以定义escapechar
并隐藏#
\documentclass{article}
\usepackage{listings}
\lstset{language=Bash,escapechar=^}
\pagenumbering{gobble}
\begin{document}
\begin{lstlisting}
# This is a comment
while [[ $^\#^ -gt 0 ]]; do
echo $1
shift
done
\end{lstlisting}
\end{document}
答案3
\documentclass{article}
\usepackage{listings}
\lstset
{
language = Bash,
literate = {\$\#}{{{\$\#}}}2 {\$\# }{{{\$\# }}}2,
columns = fullflexible,
}
\pagenumbering{gobble}
\begin{document}
\begin{lstlisting}
# This is a comment
while [[ $# -gt 0 ]]; do
echo $1
shift
done
\end{lstlisting}
\end{document}
答案4
我建议使用pythontex
。当列表发生变化时,需要运行该程序pythontex
。示例使用beramono
粗体,因此等宽字体中可以区分粗体。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{beramono}
\usepackage[pygopt={style=bw}]{pythontex}
\begin{document}
\begin{pygments}{bash}
# This is a comment
while [[ $# -gt 0 ]]; do
echo $1
shift
done
\end{pygments}
\end{document}