我的宏中的参数传递仍然存在一些问题。下面的 MWE 编译并运行良好。如果取消注释 wide,它会\begin{figure*}
与不匹配\end{figure}
。但是,如果您也注释掉带有 的行,此错误就会消失\MEListBalls
。没有\MEListBalls
,无论有没有 wide 都可以正常工作。
相关问题:如何传递像 'backgroundcolor=\color{black}' 这样的选项?简单的文本可以轻松传递。
\documentclass{memoir}
\def\LecturePrintable{Book} % It is a kind of printable format
\def\MayFloat{YES} % Some environments are allowed to float
\def\lstsize{\scriptsize}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{xkeyval} % Allow to use key-value pairs in arguments of macros
\usepackage{listingsutf8} % Use program listings
\usepackage{etoolbox} % Utility package, mainly for packet
\usepackage[english,magyar]{babel}
\definecolor{ForestGreen}{rgb}{0.0, 0.4, 0.0}
\colorlet{HeadingColor}{ForestGreen}
\makeatletter
\define@key{MEMacros}{color}{\def\ME@color{#1}}
\define@key{MEMacros}{decorations}{\def\ME@decorations{#1}}
\define@key{MEMacros}{language}{\def\ME@language{#1}}
\define@key{MEMacros}{number}{\def\ME@number{#1}}
\define@key{MEMacros}{options}{\def\ME@options{#1}}
\define@key{MEMacros}{wide}[true]{\def\ME@wide{#1}}
\presetkeys{MEMacros}{color=green}{}%
\presetkeys{MEMacros}{number=1}{}%
\presetkeys{MEMacros}{wide=false}{}%
%%%Usage \MESourceFile[keys]{source file}{caption}{label}
\makeatletter
%% Insert a source file in the text, with optional decorations
%%%Usage \MESourceFile[keys]{source file}{caption}{label}
\newcommand\MESourceFile[4][]{
\setkeys{MEMacros}{wide=false,language={[ANSI]C},options={}, decorations={},#1}%
% % Define the environment: a 'Program' if it might float, a simple caption if not
\ifx\MayFloat\undefined
\vskip.2\baselineskip\color{HeadingColor}\bfseries\scriptsize #3\par\vskip\baselineskip
\else
\expandafter\ifstrequal\expandafter{\ME@wide}{true}
{\begin{figure*}[h!btp] }
{\begin{figure}[h!btp] }
\fi
\mbox{}\phantomsection
\lstset{language=C,keywordstyle=\bfseries\color{magenta}}
\ifx\MayFloat\undefined\else\caption{#3}\fi \vglue-.7\baselineskip
\begingroup\edef\x{\endgroup\noexpand
\lstinputlisting[language={\ME@language},\ME@options,label=#4, name=#4]{#2}}
\x
\ME@decorations % Decorating comments
\ifx\MayFloat\undefined % nothing needed
\else
\expandafter\ifstrequal\expandafter{\ME@wide}{true}
{\end{figure*}}
{\end{figure}}
\fi
}
\makeatother
\makeatletter
% % Put numbered balls after the line 'Lineno' in source 'Source'
% Usage: \MEListBalls{ListingLabel}{List of lines}
\newcounter{qan}\newcounter{qano}
\newcommand\MEListBalls[3][]{%
\setkeys{MEMacros}{color=orange,#1}%
\setkeys{MEMacros}{number=1,#1}%
\setcounter{qan}{\ME@number}
\setcounter{qano}{0}
% \begingroup%
\foreach \x in {#3}
{
\addtocounter{qano}{1}
% \only<\arabic{qano}>%
{\tikz[remember picture,overlay]
{\expandafter\node[circle, inner sep=2pt, draw,fill=\ME@color,ball color=\ME@color, shading=ball, font=\scriptsize\bfseries, drop shadow]
at ([xshift=+10pt,yshift=+2pt]{pic cs:line-#2-\x-end}) {\lstsize\arabic{qan}};\expandafter}}
\addtocounter{qan}{1}
}
% \endgroup
}
\usepackage{float} % For custom floats
\usepackage{tikz}
\usetikzlibrary{
calc,
tikzmark,
shadows,
}
\begin{document}
\MESourceFile[language={[ANSI]C},
% wide,
% options={backgroundcolor=\color{black}},
decorations={
\MEListBalls{lst:HelloWorld.c}{3,1,4}
}
]{HelloWorld.c}{Az egyszerű parancs értelmező }{lst:HelloWorld.c}
\end{document}
#include <stdio.h>
int main()
{
printf("hello, world\n");
}
答案1
这里有一种方法:定义宏\startsource
并\stopsource
采用与您的选择相关的值。这样您就可以指定一个块来导入列表。
\makeatletter
\define@key{MEMacros}{color}{\def\ME@color{#1}}
\define@key{MEMacros}{decorations}{\def\ME@decorations{#1}}
\define@key{MEMacros}{language}{\def\ME@language{#1}}
\define@key{MEMacros}{number}{\def\ME@number{#1}}
\define@key{MEMacros}{options}{\def\ME@options{#1}}
\define@boolkey{MEMacros}{wide}[true]{\def\ME@wide{#1}}
\presetkeys{MEMacros}{color=green}{}%
\presetkeys{MEMacros}{number=1}{}%
\presetkeys{MEMacros}{wide=false}{}%
%%%Usage \MESourceFile[keys]{source file}{caption}{label}
%% Insert a source file in the text, with optional decorations
%%%Usage \MESourceFile[keys]{source file}{caption}{label}
\newcommand\MESourceFile[4][]{
\setkeys{MEMacros}{wide=false,language={[ANSI]C},options={}, decorations={},#1}%
% % Define the environment: a 'Program' if it might float, a simple caption if not
\ifx\MayFloat\undefined
\def\startsource{\vskip.2\baselineskip\color{HeadingColor}\bfseries\scriptsize #3\par\vskip\baselineskip}
\def\stopsource{}
\else
\ifKV@MEMacros@wide
\def\startsource{\begin{figure*}[h!btp]}
\def\stopsource{\end{figure*}}
\else
\def\startsource{\begin{figure}[h!btp]}
\def\stopsource{\end{figure}}
\fi
\fi
\startsource
\mbox{}\phantomsection
\lstset{language=C,keywordstyle=\bfseries\color{magenta}}
\ifx\MayFloat\undefined\else\caption{#3}\fi \vglue-.7\baselineskip
\begingroup\edef\x{\endgroup\noexpand
\lstinputlisting[language={\ME@language},\ME@options,label=#4, name=#4]{#2}}
\x
\ME@decorations % Decorating comments
\stopsource
}
\makeatother
由于你正在使用xkeyval
它提供“布尔键”,我将其用作\ifKV@MEMacros@wide <true>\else <false>\fi
条件,而不是更麻烦的\expandafter\ifstrequal\expandafter{\ME@wide}{true}{<true>}{<false>}
。
答案2
您应该使用布尔键,而不是\ifstrequal
测试;
\define@boolkey{MEMacros}{wide}[true]{}
条件\ifKV@MEMacros@wide
成立;wide
在选项中使用相当于wide=true
。重要:不要“预设”此键。
对于options
,将其传递给\lstset
:
\expandafter\lstset\expandafter{\ME@options}
这是有效的,因为您拥有\lstset
任意数量的命令。
\documentclass{memoir}
\def\LecturePrintable{Book} % It is a kind of printable format
\def\MayFloat{YES} % Some environments are allowed to float
\def\lstsize{\scriptsize}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{xkeyval} % Allow to use key-value pairs in arguments of macros
\usepackage{listingsutf8} % Use program listings
\usepackage{etoolbox} % Utility package, mainly for packet
\usepackage[english,magyar]{babel}
\definecolor{ForestGreen}{rgb}{0.0, 0.4, 0.0}
\colorlet{HeadingColor}{ForestGreen}
\makeatletter
\define@key{MEMacros}{color}{\def\ME@color{#1}}
\define@key{MEMacros}{decorations}{\def\ME@decorations{#1}}
\define@key{MEMacros}{language}{\def\ME@language{#1}}
\define@key{MEMacros}{number}{\def\ME@number{#1}}
\define@key{MEMacros}{options}{\def\ME@options{#1}}
\define@boolkey{MEMacros}{wide}[true]{}
\presetkeys{MEMacros}{color=green}{}%
\presetkeys{MEMacros}{number=1}{}%
%%%Usage \MESourceFile[keys]{source file}{caption}{label}
\makeatletter
%% Insert a source file in the text, with optional decorations
%%%Usage \MESourceFile[keys]{source file}{caption}{label}
\newcommand\MESourceFile[4][]{%
\setkeys{MEMacros}{wide=false,language={[ANSI]C},options={}, decorations={},#1}%
% % Define the environment: a 'Program' if it might float, a simple caption if not
\ifx\MayFloat\undefined
\vskip.2\baselineskip\color{HeadingColor}\bfseries\scriptsize #3\par\vskip\baselineskip
\else
\ifKV@MEMacros@wide
\begin{figure*}[h!btp]
\else
\begin{figure}[h!btp]
\fi
\fi
\mbox{}\phantomsection
\lstset{language=C,keywordstyle=\bfseries\color{magenta}}
\expandafter\lstset\expandafter{\ME@options}
\ifx\MayFloat\undefined\else\caption{#3}\fi \vglue-.7\baselineskip
\begingroup\edef\x{\endgroup\noexpand
\lstinputlisting[language={\ME@language},label=#4, name=#4]{#2}}
\x
\ME@decorations % Decorating comments
\ifx\MayFloat\undefined % nothing needed
\else
\ifKV@MEMacros@wide
\end{figure*}
\else
\end{figure}
\fi
\fi
}
\makeatother
\makeatletter
% % Put numbered balls after the line 'Lineno' in source 'Source'
% Usage: \MEListBalls{ListingLabel}{List of lines}
\newcounter{qan}\newcounter{qano}
\newcommand\MEListBalls[3][]{%
\setkeys{MEMacros}{color=orange,#1}%
\setkeys{MEMacros}{number=1,#1}%
\setcounter{qan}{\ME@number}
\setcounter{qano}{0}
% \begingroup%
\foreach \x in {#3}
{
\addtocounter{qano}{1}
% \only<\arabic{qano}>%
{\tikz[remember picture,overlay]
{\expandafter\node[circle, inner sep=2pt, draw,fill=\ME@color,ball color=\ME@color, shading=ball, font=\scriptsize\bfseries, drop shadow]
at ([xshift=+10pt,yshift=+2pt]{pic cs:line-#2-\x-end}) {\lstsize\arabic{qan}};\expandafter}}
\addtocounter{qan}{1}
}
% \endgroup
}
\usepackage{float} % For custom floats
\usepackage{tikz}
\usetikzlibrary{
calc,
tikzmark,
shadows,
}
\begin{document}
\MESourceFile[language={[ANSI]C},
wide,
options={backgroundcolor=\color{gray!10}},
decorations={
\MEListBalls{lst:HelloWorld.c}{3,1,4}
}
]{HelloWorld.c}{Az egyszerű parancs értelmező }{lst:HelloWorld.c}
\end{document}
#include <stdio.h>
int main()
{
printf("hello, world\n");
}
我使用是options=\color{gray!10}
因为black
会产生非常丑陋的结果。