我正在尝试操纵我在互联网上找到的环境,在 GUIT 论坛. 这是最小示例
\documentclass[a4paper,10pt,twoside,openright,titlepage,fleqn,headinclude,footinclude,BCOR5mm,numbers=noenddot,cleardoublepage=empty,captions=tableheading]{scrreprt}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[italian]{babel}
\usepackage{amsmath,amsfonts}
\usepackage{framed,color,lipsum}
\usepackage{listings}
\newlength\sidebar
\newlength\envrule
\newlength\envborder
\setlength\sidebar{1.5mm}
\setlength\envrule{0.4pt}
\setlength\envborder{2.5mm}
\makeatletter
\long\def\fboxs#1{%
\leavevmode
\setbox\@tempboxa\hbox{%
\color@begingroup
\kern\fboxsep{#1}\kern\fboxsep
\color@endgroup}%
\@frames@x\relax}
\def\frameboxs{%
\@ifnextchar(%)
\@framepicbox{\@ifnextchar[\@frameboxs\fboxs}}
\def\@frameboxs[#1]{%
\@ifnextchar[%]
{\@iframeboxs[#1]}%
{\@iframeboxs[#1][c]}}
\long\def\@iframeboxs[#1][#2]#3{%
\leavevmode
\@begin@tempboxa\hbox{#3}%
\setlength\@tempdima{#1}%
\setbox\@tempboxa\hb@xt@\@tempdima
{\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep}%
\@frames@x{\kern-\fboxrule}%
\@end@tempboxa}
\def\@frames@x#1{%
\@tempdima\fboxrule
\advance\@tempdima\fboxsep
\advance\@tempdima\dp\@tempboxa
\hbox{%
\lower\@tempdima\hbox{%
\vbox{%
%\hrule\@height\fboxrule
\hbox{%
\vrule\@width\fboxrule
#1%
\vbox{%
\vskip\fboxsep
\box\@tempboxa
\vskip\fboxsep}%
#1%
}%\vrule\@width\fboxrule}%
}%\hrule\@height\fboxrule}%
}%
}%
}
\def\esefcolorbox#1#{\esecolor@fbox{#1}}
\def\esecolor@fbox#1#2#3{%
\color@b@x{\fboxsep\z@\color#1{#2}\fboxs}{\color#1{#3}}}
\makeatother
\definecolor{exampleborder}{rgb}{0,0,.7}
\definecolor{examplebg}{rgb}{.9,.9,1}
\definecolor{statementborder}{rgb}{.9,0,0}
\definecolor{statementbg}{rgb}{1,.9,.9}
\newenvironment{eseframed}{%
\def\FrameCommand{\fboxrule=\the\sidebar \fboxsep=\the\envborder%
\esefcolorbox{exampleborder}{examplebg}}%
\MakeFramed{\FrameRestore}}%
{\endMakeFramed}
\newcounter{codeblock}
\numberwithin{codeblock}{section}
\renewcommand{\thecodeblock}{\thesection.\arabic{codeblock}}
%%% CODE ENVIRONMENT. PUT TEXT INTO COLORED FRAME %%%
\newenvironment{codeblock}
{\par\medskip\refstepcounter{codeblock}%
\hbox{%
\fboxsep=\the\sidebar\hspace{-\envborder}\hspace{-.5\sidebar}%
\colorbox{exampleborder}{%
\hspace{\envborder}\footnotesize\sffamily\bfseries%
\textcolor{white}{Code\enspace\thecodeblock\hspace{\envborder}}
}
}
\nointerlineskip\vspace{-\topsep}%
\begin{eseframed}\noindent\ignorespaces%
}
{\end{eseframed}\vspace{-\baselineskip}\medskip}
\begin{document}
\begin{codeblock}
\lipsum[2]
\end{codeblock}
\end{document}
现在,我想创建一个命令,它使用 listing 包获取一个 .cpp 文件并将其插入到此块中。我修改此环境以使其具有一个可选参数,该参数将是文件的名称(将其作为标题),然后在新命令中使用修改后的环境。这是我的新最小代码:
\documentclass[a4paper,10pt,twoside,openright,titlepage,fleqn,headinclude,footinclude,BCOR5mm,numbers=noenddot,cleardoublepage=empty,captions=tableheading]{scrreprt}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[italian]{babel}
\usepackage{amsmath,amsfonts}
\usepackage{framed,color,lipsum}
\usepackage{listings}
\newlength\sidebar
\newlength\envrule
\newlength\envborder
\setlength\sidebar{1.5mm}
\setlength\envrule{0.4pt}
\setlength\envborder{2.5mm}
\makeatletter
\long\def\fboxs#1{%
\leavevmode
\setbox\@tempboxa\hbox{%
\color@begingroup
\kern\fboxsep{#1}\kern\fboxsep
\color@endgroup}%
\@frames@x\relax}
\def\frameboxs{%
\@ifnextchar(%)
\@framepicbox{\@ifnextchar[\@frameboxs\fboxs}}
\def\@frameboxs[#1]{%
\@ifnextchar[%]
{\@iframeboxs[#1]}%
{\@iframeboxs[#1][c]}}
\long\def\@iframeboxs[#1][#2]#3{%
\leavevmode
\@begin@tempboxa\hbox{#3}%
\setlength\@tempdima{#1}%
\setbox\@tempboxa\hb@xt@\@tempdima
{\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep}%
\@frames@x{\kern-\fboxrule}%
\@end@tempboxa}
\def\@frames@x#1{%
\@tempdima\fboxrule
\advance\@tempdima\fboxsep
\advance\@tempdima\dp\@tempboxa
\hbox{%
\lower\@tempdima\hbox{%
\vbox{%
%\hrule\@height\fboxrule
\hbox{%
\vrule\@width\fboxrule
#1%
\vbox{%
\vskip\fboxsep
\box\@tempboxa
\vskip\fboxsep}%
#1%
}%\vrule\@width\fboxrule}%
}%\hrule\@height\fboxrule}%
}%
}%
}
\def\esefcolorbox#1#{\esecolor@fbox{#1}}
\def\esecolor@fbox#1#2#3{%
\color@b@x{\fboxsep\z@\color#1{#2}\fboxs}{\color#1{#3}}}
\makeatother
\definecolor{exampleborder}{rgb}{0,0,.7}
\definecolor{examplebg}{rgb}{.9,.9,1}
\definecolor{statementborder}{rgb}{.9,0,0}
\definecolor{statementbg}{rgb}{1,.9,.9}
\newenvironment{eseframed}{%
\def\FrameCommand{\fboxrule=\the\sidebar \fboxsep=\the\envborder%
\esefcolorbox{exampleborder}{examplebg}}%
\MakeFramed{\FrameRestore}}%
{\endMakeFramed}
\newcounter{codeblock}
\numberwithin{codeblock}{section}
\renewcommand{\thecodeblock}{\thesection.\arabic{codeblock}}
%%% MODIFIED ENVIRONMENT WITH ARGUMENT %%%
\newenvironment{codeblock}[1]
{\par\medskip\refstepcounter{codeblock}%
\hbox{%
\fboxsep=\the\sidebar\hspace{-\envborder}\hspace{-.5\sidebar}%
\colorbox{exampleborder}{%
\hspace{\envborder}\footnotesize\sffamily\bfseries%
\textcolor{white}{#1\enspace\thecodeblock\hspace{\envborder}}
}
}
\nointerlineskip\vspace{-\topsep}%
\begin{eseframed}\noindent\ignorespaces%
}
{\end{eseframed}\vspace{-\baselineskip}\medskip}
%%% COMMAND THAT USE PREVIOUS ENVIRONMENT AND LISTING ENVIRONMENT %%%
\newcommand{\sourcecode}[1]{\begin{codeblock}[#1]%
\begin{lstlisting}%
\input{#1}%
\end{lstlisting}%
\end{codeblock}}
\begin{document}
\sourcecode{code/hello_world.cpp}
\end{document}
命令 \sourcecode 将文件名作为输入,然后将其文本包含到 codeblock/lstlisting 环境中。当我尝试编译它时,无论如何,我收到以下错误:
! Missing $ inserted.
<inserted text>
$
l.106 \sourcecode{code/hello_world.cpp}
?
! Emergency stop.
<inserted text>
$
l.106 \sourcecode{code/hello_world.cpp}
我不知道我做错了什么。任何帮助创建正确命令的帮助都会很感激。请帮帮我。
提前感谢您的回复。
答案1
将定义改为
%%% COMMAND THAT USE PREVIOUS ENVIRONMENT AND LISTING ENVIRONMENT %%%
\newcommand{\sourcecode}[1]{%
\begin{codeblock}{#1}%
\lstinputlisting{#1}%
\end{codeblock}}
请注意后面的是括号\begin{codeblock}
而不是方括号。
如果文件名包含下划线,则保护它:
\sourcecode{file\string_with\string_underscores.cpp}
抱歉,但调试这么大一段代码是件很困难的事。
问题是由于您试图打印带有下划线的字符串,如果下划线没有以某种方式受到保护,这是不可能的。
一个出路可能是
\newcommand{\sourcecode}{\begingroup\catcode`_=12 \dosourcecode}
\newcommand{\dosourcecode}[1]{%
\begin{codeblock}{#1}%
\lstinputlisting{#1}%
\end{codeblock}\endgroup}
因此,当下划线变成可打印字符时,就会推迟读取参数。
或者,正如 Heiko 所建议的那样,
\newcommand{\sourcecode}[1]{%
\begin{codeblock}{\detokenize{#1}}%
\lstinputlisting{#1}%
\end{codeblock}\endgroup}