在存在 xkeyval 值的情况下传递参数

在存在 xkeyval 值的情况下传递参数

我的宏中的参数传递仍然存在一些问题。下面的 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会产生非常丑陋的结果。

相关内容