所有内容都在标题中。我想在列出包的字符前为文本添加颜色。
例如,我想在 makefile 中为行首和:
或之间的文本添加颜色。=
我尝试使用moredelimiters
但没有成功。
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\definecolor{keycolor}{RGB}{172, 42, 42}
\definecolor{mbleu}{RGB}{64,96,127}
\definecolor{vimvert}{RGB}{46, 139, 87}
\lstdefinestyle{global}{
basicstyle=\ttfamily\scriptsize\color{black!90},%
stringstyle=\itshape\color{magenta},%
showstringspaces=false,%
keywordstyle={\bfseries\color{keycolor}},%
commentstyle=\color{blue}\slshape,%
framexleftmargin=1mm,%
backgroundcolor=\color{black!2},%
}
\lstdefinestyle{makefile}{
style=global,%
morecomment=[l][commentstyle]{\#},%
emphstyle={\color{vimvert}},%
moredelim=[s][emphstyle]{\$(}{)}%
}
\begin{document}
\begin{lstlisting}[style=makefile]
.SUFFIXES: .inc .f .f90 .F
# all CPP processed fortran files have the extension .f90
SUFFIX=.f90
#-----------------------------------------------------------------------
# this release should be fpp clean
# we now recommend fpp as preprocessor
# if this fails go back to cpp
CPP_=fpp -f_com=no -free -w0 $*.F $*$(SUFFIX)
vasp: $(SOURCE) $(FFT3D) $(INC) main.o
rm -f vasp
$(FCL) -o vasp main.o $(SOURCE) $(FFT3D) $(LIB) $(LINK)
makeparam: $(SOURCE) $(FFT3D) makeparam.o main.F $(INC)
$(FCL) -o makeparam $(LINK) makeparam.o $(SOURCE) $(FFT3D) $(LIB)
zgemmtest: zgemmtest.o base.o random.o $(INC)
$(FCL) -o zgemmtest $(LINK) zgemmtest.o random.o base.o $(LIB)
dgemmtest: dgemmtest.o base.o random.o $(INC)
$(FCL) -o dgemmtest $(LINK) dgemmtest.o random.o base.o $(LIB)
ffttest: base.o smart_allocate.o mpi.o mgrid.o random.o ffttest.o $(FFT3D) $(INC)
$(FCL) -o ffttest $(LINK) ffttest.o mpi.o mgrid.o random.o smart_allocate.o base.o $(FFT3D) $(LIB)
kpoints: $(SOURCE) $(FFT3D) makekpoints.o main.F $(INC)
$(FCL) -o kpoints $(LINK) makekpoints.o $(SOURCE) $(FFT3D) $(LIB)
clean:
-rm -f *.g *.f *.o *.L *.mod ; touch *.F
\end{lstlisting}
\end{document}
答案1
.SUFFIXES
是预定义语言中的关键字[gnu]make
。SUFFIX
是预定义的,但通过和和键ACSL
的组合加载语言似乎没有产生预期的效果。我建议您按照以下解决方法定义您的。language
alsolanguage
classoffset
makefile
解决方法 1
在此解决方案中,冒号也是彩色的。只需按如下方式:
设置:\lstdefinestyle
\lstdefinestyle{global}{
basicstyle=\ttfamily\scriptsize\color{black!90},%
stringstyle=\itshape\color{magenta},%
showstringspaces=false,%
keywordstyle={[1]\bfseries\color{keycolor}},%
keywordstyle={[2]\bfseries\color{mbleu}},%
commentstyle=\color{blue}\slshape,%
framexleftmargin=1mm,%
backgroundcolor=\color{black!2},%
}
\lstdefinestyle{makefile}{
otherkeywords={.SUFFIXES},
alsoletter={:},
morekeywords=[1]{SUFFIX, CPP_},
morekeywords=[2]{vasp:,makeparam:,zgemmtest:,dgemmtest:,ffttest:,kpoints:,clean:},
style=global,%
morecomment=[l][commentstyle]{\#},%
emphstyle={\color{vimvert}},%
moredelim=[s][\color{vimvert}]{\$(}{)}%
}
输出
解释
otherkeywords
定义包含其他字符的关键字,或以数字开头。alsoletter
构成:
一个字母,否则包含这些符号的单词将不会被识别为单词。- 您可以使用语法或制作单独的
morekeywords
或列表。这里我选择了或 ,但您可以根据自己的喜好进行修改。然后您必须将此列表与相应的或进行匹配。moreemph
morekeywords=[<number>]{<list of keywords>}
moreemph=[<number>]{<list of emphs>}
keywords
keywordstyle
emphstyle
解决方法 2
您可能不希望冒号有颜色。在这种情况下,您可以使用(猜猜是什么?)moredelim
如moredelim=[is][\color{mbleu}]{/*}{*/},
手册中所述:
更通用的分隔符可以用键 moredelim 来定义。合法的类型是
l
和s
。这些类型前面可以加i
,但这次只有分隔符会从输出中丢弃。
以下是完整代码
%\documentclass{article}
\documentclass[preview,border=5]{standalone}
\usepackage{geometry}
\geometry{margin=1in}
\usepackage[procnames]{listings}
\usepackage{xcolor}
\definecolor{keycolor}{RGB}{172, 42, 42}
\definecolor{mbleu}{RGB}{64,96,127}
\definecolor{vimvert}{RGB}{46, 139, 87}
\lstdefinestyle{global}{
basicstyle=\ttfamily\scriptsize\color{black!90},%
stringstyle=\itshape\color{magenta},%
showstringspaces=false,%
keywordstyle=\bfseries\color{keycolor},%
commentstyle=\color{blue}\slshape,%
framexleftmargin=1mm,%
backgroundcolor=\color{black!2},%
}
\lstdefinestyle{makefile}{
otherkeywords={.SUFFIXES},
morekeywords={SUFFIX, CPP_,},
moredelim=[is][\color{mbleu}]{/*}{*/},
style=global,%
morecomment=[l][commentstyle]{\#},%
emphstyle={\color{vimvert}},%
moredelim=[s][\color{vimvert}]{\$(}{)}%
}
\begin{document}
\begin{lstlisting}[style=makefile]
.SUFFIXES: .inc .f .f90 .F
# all CPP processed fortran files have the extension .f90
SUFFIX=.f90
#-----------------------------------------------------------------------
# this release should be fpp clean
# we now recommend fpp as preprocessor
# if this fails go back to cpp
CPP_=fpp -f_com=no -free -w0 $*.F $*$(SUFFIX)
/*vasp*/: $(SOURCE) $(FFT3D) $(INC) main.o
rm -f vasp
$(FCL) -o vasp main.o $(SOURCE) $(FFT3D) $(LIB) $(LINK)
/*makeparam*/: $(SOURCE) $(FFT3D) makeparam.o main.F $(INC)
$(FCL) -o makeparam $(LINK) makeparam.o $(SOURCE) $(FFT3D) $(LIB)
/*zgemmtest*/: zgemmtest.o base.o random.o $(INC)
$(FCL) -o zgemmtest $(LINK) zgemmtest.o random.o base.o $(LIB)
/*dgemmtest*/: dgemmtest.o base.o random.o $(INC)
$(FCL) -o dgemmtest $(LINK) dgemmtest.o random.o base.o $(LIB)
/*ffttest*/: base.o smart_allocate.o mpi.o mgrid.o random.o ffttest.o $(FFT3D) $(INC)
$(FCL) -o ffttest $(LINK) ffttest.o mpi.o mgrid.o random.o smart_allocate.o base.o $(FFT3D) $(LIB)
/*kpoints*/: $(SOURCE) $(FFT3D) makekpoints.o main.F $(INC)
$(FCL) -o kpoints $(LINK) makekpoints.o $(SOURCE) $(FFT3D) $(LIB)
/*clean*/:
-rm -f *.g *.f *.o *.L *.mod ; touch *.F
\end{lstlisting}
\end{document}
输出
答案2
hpesoj626 发布的答案显示了两种产生所需输出的方法;对于少量行,它们是完全可以接受的。不幸的是,随着目标数量的增加,这两种方法很快就会变得乏味且难以维护,因为它们缺乏自动化:
- 解决方法 1 需要将所有
make
目标名称(例如vasp
、makeparam
等)定义为关键字; - 解决方法 2 需要通过用自定义分隔符括住所有目标名称来改变列表。
我假设您需要一个自动化解决方案,既不需要定义一长串关键词,也不需要修改原始列表。以下假设您的问题确实是
我可以让“列表”自动突出显示给定字符之前的文本吗?如果可以,怎么做?
简短回答
是又不是;但大多情况下不是。
更详细的答案
该listings
包以非常线性的方式读取列表。据我所知,它无法真正向前看很远,然后回溯以根据找到的内容有条件地应用样式。
不过,在某些情况下,您可以listings
随意修改 的内部结构以获得所需的结果。您可以定义开关、计数器等,当遇到给定字符或标识符时,或者在某些listings
“钩子”处,它们的值会更新。然后,您可以使用这些“状态变量”有条件地应用样式。
具体来说,在这里,为了仅使make
目标以洋红色突出显示,我将每行开头的当前样式设置为洋红色(通过提供的钩子调用EveryLine
)listings
,并且一旦遇到冒号,我就会恢复为“默认”样式(黑色)。
请注意,如果您希望变量以不同于目标的样式突出显示,我的方法仍然要求您将make
变量定义为关键字;我想不出一种可靠的方法让变量自动以不同于目标的样式突出显示。但是,我相信典型 makefile 中的变量数量通常少于目标数量,因此将每个变量定义为listings
关键字应该不会太麻烦……
为什么操作中缺少制表符?
如果你简单地复制下面的代码,粘贴到你最喜欢的编辑器中,然后编译,你将不是获得与我的屏幕截图中所示的相同输出。这是因为 makefile 中的命令行前面有制表位,但 TeX.SX 用四个空格替换所有制表位。您必须在编译之前手动重新插入我的代码中的制表位;然后一切都应该按预期工作。
\documentclass{article}
\usepackage[margin=2cm]{geometry}
\usepackage{textcomp}
\usepackage{xcolor}
\usepackage{listings}
% --- color definitions ---
\definecolor{mktext} {RGB}{000, 043, 054}
\definecolor{mktarget} {RGB}{211, 054, 130}
\definecolor{mkstring} {RGB}{000, 127, 127}
\definecolor{mkvariable}{RGB}{038, 139, 210}
\definecolor{mkkeyword} {RGB}{133, 153, 000}
\definecolor{mklinecont}{RGB}{220, 050, 047}
\definecolor{mkcomment} {RGB}{088, 110, 117}
\definecolor{mkcommand} {RGB}{042, 161, 152}
% --- auxiliary macros for styles ---
\newcommand\mktextstyle{\color{mktext}}
\newcommand\mktargetstyle{\color{mktarget}}
\newcommand\mkstringstyle{\color{mkstring}}
\newcommand\mkvariablestyle{\color{mkvariable}}
\newcommand\mkkeywordstyle{\color{mkkeyword}}
\newcommand\mklinecontstyle{\color{mklinecont}}
\newcommand\mkcommentstyle{\slshape\color{mkcomment}}
\newcommand\mkcommandstyle{\color{mkcommand}}
\makeatletter
% --- context switches ---
\newif\iftarget@make@
\newif\iflinecont@make@
% --- hook into listings to keep track of context ---
\lst@AddToHook{InitVarsBOL}
{%
\iflinecont@make@%
\global\target@make@false%
\else
\global\target@make@true%
\fi
\global\linecont@make@false%
}
\lst@AddToHook{Output}
{%
\ifnum\lst@mode=\lst@Pmode%
\iftarget@make@%
\gdef\globalstyle@make{\the@lststyle}%
\def\lst@thestyle{\mktargetstyle}%
\fi
\fi
\ifnum\lst@mode=\lst@Pmode% only test for keyword if we're in "processing" mode
\lsthk@DetectKeywords%
\fi
}
\lstdefinestyle{make-pretty}
{
upquote=true,
showstringspaces=false,
basicstyle=\ttfamily\scriptsize\mktextstyle,
sensitive=true,
alsoletter=.-,
keywords = {.CC,.CFLAGS,.PHONY,.SUFFIXES,SUFFIX,CPP_},
keywordstyle = \mkkeywordstyle,
moredelim=[is][\mkvariablestyle(\aftergroup\closingparen@make]{(}{)},
moredelim=*[l][\mkcommandstyle]{\^^I},
morestring=[b]',
morestring=[b]",
stringstyle=\mkstringstyle,
literate =
{\%}{{{\mkvariablestyle\%}}}1
{\$}{{{\mkvariablestyle\$}}}1
{\$*}{{{\mkvariablestyle\$*}}}2
{\\}{{{\mklinecontstyle\lstum@backslash}}}1,
MoreSelectCharTable =
\processColon@make
\processEqual@make
\processBackslash@make
\processTab@make,
morecomment = [l]{\#},
commentstyle = \mkcommentstyle,
}
% --- helper macros ---
\newcommand\closingparen@make{{\mkvariablestyle)}}
\newcommand\processEqual@make
{%
\lst@DefSaveDef{`=}\equal@make%
{%
\equal@make%
\global\target@make@false%
\def\lst@thestyle{\globalstyle@make}%
}%
}
\newcommand\processColon@make
{%
\lst@DefSaveDef{`:}\colon@make%
{%
\colon@make%
\global\target@make@false%
\def\lst@thestyle{\globalstyle@make}%
}%
}
\newcommand\processBackslash@make
{%
\lst@DefSaveDef{`\\}\backslash@make%
{%
\backslash@make%
\ifnum\lst@mode=\lst@Pmode%
\global\linecont@make@true%
\def\lst@thestyle{\globalstyle@make}%
\fi
}%
}
\newcommand\processTab@make
{%
\lst@DefSaveDef{`^^I}\tabchar@make%
{%
\tabchar@make%
\global\target@make@false%
}%
}
\makeatother
\begin{document}
\begin{lstlisting}[style=make-pretty]
.SUFFIXES: .inc .f .f90 .F
# all CPP processed fortran files have the extension .f90
SUFFIX=.f90
#-----------------------------------------------------------------------
# this release should be fpp clean
# we now recommend fpp as preprocessor
# if this fails go back to cpp
CPP_=fpp -f_com=no -free -w0 $*.F $*$(SUFFIX)
vasp: $(SOURCE) $(FFT3D) $(INC) main.o
rm -f vasp
$(FCL) -o vasp main.o $(SOURCE) $(FFT3D) $(LIB) $(LINK)
makeparam: $(SOURCE) $(FFT3D) makeparam.o main.F $(INC)
$(FCL) -o makeparam $(LINK) makeparam.o $(SOURCE) $(FFT3D) $(LIB)
zgemmtest: zgemmtest.o base.o random.o $(INC)
$(FCL) -o zgemmtest $(LINK) zgemmtest.o random.o base.o $(LIB)
dgemmtest: dgemmtest.o base.o random.o $(INC)
$(FCL) -o dgemmtest $(LINK) dgemmtest.o random.o base.o $(LIB)
ffttest: base.o smart_allocate.o mpi.o mgrid.o random.o ffttest.o $(FFT3D) $(INC)
$(FCL) -o ffttest $(LINK) ffttest.o mpi.o mgrid.o random.o smart_allocate.o base.o $(FFT3D) $(LIB)
kpoints: $(SOURCE) $(FFT3D) makekpoints.o main.F $(INC)
$(FCL) -o kpoints $(LINK) makekpoints.o $(SOURCE) $(FFT3D) $(LIB)
clean:
rm -f *.g *.f *.o *.L *.mod ; touch *.F
\end{lstlisting}
\end{document}
答案3
我最近发现了一种使用minted
包的替代方法pygmentize
。不便之处在于它不是完整的 LaTeX 解决方案。
\documentclass{article}
\usepackage[margin=2cm]{geometry}
\usepackage{textcomp}
\usepackage{minted}
\begin{document}
\begin{minted}{make}
.SUFFIXES: .inc .f .f90 .F
# all CPP processed fortran files have the extension .f90
SUFFIX=.f90
#-----------------------------------------------------------------------
# this release should be fpp clean
# we now recommend fpp as preprocessor
# if this fails go back to cpp
CPP_=fpp -f_com=no -free -w0 $*.F $*$(SUFFIX)
vasp: $(SOURCE) $(FFT3D) $(INC) main.o
rm -f vasp
$(FCL) -o vasp main.o $(SOURCE) $(FFT3D) $(LIB) $(LINK)
makeparam: $(SOURCE) $(FFT3D) makeparam.o main.F $(INC)
$(FCL) -o makeparam $(LINK) makeparam.o $(SOURCE) $(FFT3D) $(LIB)
zgemmtest: zgemmtest.o base.o random.o $(INC)
$(FCL) -o zgemmtest $(LINK) zgemmtest.o random.o base.o $(LIB)
dgemmtest: dgemmtest.o base.o random.o $(INC)
$(FCL) -o dgemmtest $(LINK) dgemmtest.o random.o base.o $(LIB)
ffttest: base.o smart_allocate.o mpi.o mgrid.o random.o ffttest.o $(FFT3D) $(INC)
$(FCL) -o ffttest $(LINK) ffttest.o mpi.o mgrid.o random.o smart_allocate.o base.o $(FFT3D) $(LIB)
kpoints: $(SOURCE) $(FFT3D) makekpoints.o main.F $(INC)
$(FCL) -o kpoints $(LINK) makekpoints.o $(SOURCE) $(FFT3D) $(LIB)
clean:
rm -f *.g *.f *.o *.L *.mod ; touch *.F
\end{minted}
\end{document}