如何围绕示例源代码(列表)用花式盒子(tikz)定义新环境?

如何围绕示例源代码(列表)用花式盒子(tikz)定义新环境?

这就是我想要做的:

\documentclass{beamer}

\begin{document}

\begin{frame}[fragile]{Frame 1}

    Some \structure{Python} code here:

    % I want to define a new "pythoncode" environment, so I can use it like this:
    \begin{pythoncode}[hello.py]
    #!/usr/bin/env python
    def main():
        print "Hello, World!"
    if __name__ == '__main__':
        main()
    \end{pythoncode}

\end{frame}

\end{document}

但是我想自定义源代码框,超出listings软件包允许的范围。Jan Hlavacek 推荐了我使用tikz包来实现这一点,并指出一些例子

好的,太棒了!Tikz 给了我足够的能力和自由来进行定制!我现在需要做的就是创建一个新的环境,这样我就可以像上面的代码一样使用这个环境。

tikz但是,我在新环境中遇到了麻烦listings。我尝试了以下代码,但它不起作用(我得到缺少插入的 \endcsname。):

\usepackage{listings}
\usepackage{tikz}
\usepackage{environ}

\tikzstyle{sourcecodebox} = [
    draw=blue, very thick,
    rectangle, rounded corners,
    inner sep=10pt
]
\tikzstyle{sourcecodetitle} = [
    fill=black, text=white,
    rectangle, rounded corners
]
\NewEnviron{pythoncode}[1]{
    \begin{tikzpicture}
    \node[sourcecodebox](box){
        \begin{lstlisting}[
            language=Python,
            basicstyle=\ttfamily\footnotesize,
            escapeinside={(*@}{@*)},
            %numbers=left,
            breaklines=true,
            breakatwhitespace=true,
            showspaces=false,
            showstringspaces=false,
            frame=shadowbox,
            frameround=rrrt,
            rulecolor=\color{black},
            rulesepcolor=\color{gray}
        ]
        \BODY
        \end{lstlisting}
    };
    \node[sourcecodetitle] at (box.north west) {#1};
    \end{tikzpicture}
}

相关问题:

答案1

请注意,\NewEnviron不支持逐字记录。文档应该指出这一点。正如已经评论的那样,必须\lstnewenvironment使用。或者将逐字记录文件放入外部文件中,然后使用读取\listinputlisting

下面是我的解决方案,首先将结果列表存储到一个框中,然后在 TikZ 节点内使用。恕我直言,您不应该将列表 frame参数与 TikZ 中的其他框架混合使用。您应该使用 TikZ 生成所有框架(不要与 beamers\frame宏/环境混淆)。Beamer 也提供了一些不错的框架框!

我必须添加linewidth参数和\makebox,否则列表框架太宽了。您可能需要调整它。

祝好,马丁

\documentclass{beamer}

\usepackage{listings}
\usepackage{tikz}

\tikzstyle{sourcecodebox} = [
    draw=blue, very thick,
    rectangle, rounded corners,
    inner sep=10pt
]
\tikzstyle{sourcecodetitle} = [
    fill=black, text=white,
    rectangle, rounded corners
]

\makeatletter
\lstnewenvironment{pythoncode}[1][]{%
    \def\pythoncodetitle{#1}%
    \lstset{%
        language=Python,
        basicstyle=\ttfamily\footnotesize,
        escapeinside={(*@}{@*)},
        %numbers=left,
        breaklines=true,
        breakatwhitespace=true,
        showspaces=false,
        showstringspaces=false,
        frame=shadowbox,
        frameround=rrrt,
        linewidth=.75\linewidth,
        rulecolor=\color{black},
        rulesepcolor=\color{gray}
    }%
    \setbox\@tempboxa=\hbox\bgroup\color@setgroup
}%
{%
    \color@endgroup\egroup
    \begin{tikzpicture}
        \node[sourcecodebox] (box)
            % Makebox is needed to take the frame added by listings into account
            {\makebox[.75\linewidth][l]{\box\@tempboxa}};
        \node[sourcecodetitle] at (box.north west) {\pythoncodetitle};
    \end{tikzpicture}
}

\begin{document}

\begin{frame}[fragile]{Frame 1}

    Some \structure{Python} code here:
    \begin{pythoncode}[hello.py]
    #!/usr/bin/env python
    def main():
        print "Hello, World!"
    if __name__ == '__main__':
        main()
    \end{pythoncode}

\end{frame}

\end{document}

答案2

tcblisting来自的环境tcolorbox包是定义源代码周围的漂亮盒子的良好工具。tcolorbox提供周围的盒子并与listings包一起minted格式化源代码。

接下来只是一个展示一些自定义选项的示例:

\documentclass{beamer}

\usepackage[most]{tcolorbox}

\newtcblisting{pythoncode}[2][]{%
    enhanced, title=#2, colframe=blue!50!black, 
    colback=blue!10!white, sharp corners,
    fonttitle=\ttfamily, coltitle=white,
    attach boxed title to top left = {yshift=-.5mm} ,
    boxed title style={sharp corners, size=small, colback=blue!75!black},
    listing only,listing options={language=python},#1}

\begin{document}

\begin{frame}[fragile]{Frame 1}

    Some \structure{Python} code here:

    % I want to define a new "pythoncode" environment, so I can use it like this:
    \begin{pythoncode}{hello.py}
    #!/usr/bin/env python
    def main():
        print "Hello, World!"
    if __name__ == '__main__':
        main()
    \end{pythoncode}

\end{frame}

\end{document}

在此处输入图片描述

相关内容