如何将 tikz 代码作为参数传递?

如何将 tikz 代码作为参数传递?

我想准备一个环境来显示一个显示器视图,并使用一些 tikz 代码作为可选参数来标记其上的某些内容。第一个“屏幕”显示带有硬编码节点的结果,但我需要像在第二个“屏幕”中一样将其作为参数传递,但它在编译期间会抛出错误。

如何解决?

代码

\documentclass{article}

\usepackage{geometry}
\usepackage{float}
\usepackage{adjustbox}
\usepackage{graphicx}

\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{fit}

\usepackage{blindtext}
\usepackage{wrapfig}
\usepackage[babel=true]{microtype}

\newcommand{\fontsmall}{\fontsize{5pt}{6pt}\selectfont}
\newcommand{\fontnormal}{\fontsize{10pt}{12pt}\selectfont}

\floatstyle{boxed}
\newfloat{myfloat}{tbp}{extdisplay}
\newcommand\displayenvargument{}
\newenvironment{display}[1][]{%
    \renewcommand{\displayenvargument}{#1}
    \setlength{\intextsep}{10pt}%
    \SetTracking{encoding={*}}{150}%
    \bfseries%
    \fontnormal%
    \wrapfloat{myfloat}{O}[0ex]{17\baselineskip}%
    \begin{tikzpicture}[
        numer/.style={draw, red, thick, circle, inner sep=0.2ex},
        element/.style={draw, blue, thick, rectangle, rounded corners, inner sep=0},
        strzala/.style={-stealth,red,thick},
        linia/.style={red,thick},
        ]
        \node[anchor=south west,inner sep=0] (image) at (0,0) 
        \bgroup
            \adjustbox{scale={1.25}{1.00}}\bgroup
            \begin{minipage}[][7.75\baselineskip][t]{12\baselineskip}%
            \lsstyle%
}{%
            \end{minipage}%
            \egroup
        \egroup;
        \begin{scope}[x={(image.south east)},y={(image.north west)}]
            % grid
            \draw[help lines,ultra thin,xstep=.10,ystep=.10,lightgray] (0,0) grid (1,1);
            \foreach \x in {1,...,9} { \node [red,anchor=north] at (\x/10,0) {\tiny 0.\x}; }
            \foreach \y in {1,...,9} { \node [red,anchor=east] at (0,\y/10) {\tiny 0.\y}; }
            % argument
            \displayenvargument
            % BEGIN OF ARGUMENT CONTENT
            \node (text_num) at (0.2,0.3) [numer] {1};
            \node (text) [element, fit={(0.4,0.6)(0.6,0.73)}] {};
            \draw [strzala] (text_num) -- (text);
            % END OF ARGUMENT CONTENT
        \end{scope}
    \end{tikzpicture}
    \endwrapfloat%
    \par%
}

\begin{document}

\begin{display}%
    ~\par
    ~\par
    \begin{center}
    text
    \end{center}\par
    ~\par
    ~\par
    ~\par
    ~\par
    ~\par
\end{display}%

\blindtext

\begin{display}[%
    % this doesn't work
    % BEGIN OF ARGUMENT CONTENT
%   \node (text_num) at (0.8,0.7) [numer] {1};
%   \node (text) [element, fit={(0.4,0.22)(0.6,0.34)}] {};
%   \draw [strzala] (text_num) -- (text);
    % END OF ARGUMENT CONTENT
]
    ~\par
    ~\par
    ~\par
    ~\par
    ~\par
    \begin{center}
    text
    \end{center}\par
    ~\par
    ~\par
\end{display}%

\blindtext

\end{document}

enter image description here

答案1

好的,我自己用\NewDocumentEnvironmentfromxparse创建环境解决了这个问题。

并添加星号版本以显示或不显示网格。

\documentclass{article}

\usepackage{geometry}
\usepackage{float}
\usepackage{adjustbox}
\usepackage{graphicx}
\usepackage{xparse}

\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{fit}

\usepackage{blindtext}
\usepackage{wrapfig}
\usepackage[babel=true]{microtype}

\newcommand{\fontsmall}{\fontsize{5pt}{6pt}\selectfont}
\newcommand{\fontnormal}{\fontsize{10pt}{12pt}\selectfont}

\floatstyle{boxed}
\newfloat{myfloat}{tbp}{extdisplay}
\NewDocumentEnvironment{display}{sO{}}{%
    \setlength{\intextsep}{10pt}%
    \SetTracking{encoding={*}}{150}%
    \bfseries%
    \fontnormal%
    \wrapfloat{myfloat}{O}[0ex]{17\baselineskip}%
    \begin{tikzpicture}[
        numer/.style={draw, red, thick, circle, inner sep=0.2ex},
        element/.style={draw, blue, thick, rectangle, rounded corners, inner sep=0},
        strzala/.style={-stealth,red,thick},
        linia/.style={red,thick},
        ]
        \node[anchor=south west,inner sep=0] (image) at (0,0) 
        \bgroup
            \adjustbox{scale={1.25}{1.00}}\bgroup
            \begin{minipage}[][7.75\baselineskip][t]{12\baselineskip}%
            \lsstyle%
}{%
            \end{minipage}%
            \egroup
        \egroup;
        \begin{scope}[x={(image.south east)},y={(image.north west)}]
            % grid
            \IfBooleanT {#1}{
            \draw[help lines,ultra thin,xstep=.10,ystep=.10,lightgray] (0,0) grid (1,1);
            \foreach \x in {1,...,9} { \node [red,anchor=north] at (\x/10,0) {\tiny 0.\x}; }
            \foreach \y in {1,...,9} { \node [red,anchor=east] at (0,\y/10) {\tiny 0.\y}; }
            }%
            % argument
            \noexpand{#2}   % without \noexpand first line of argument does not appear
            % BEGIN OF ARGUMENT CONTENT
            \node (text_num) at (0.2,0.3) [numer] {1};
            \node (text) [element, fit={(0.4,0.6)(0.6,0.73)}] {};
            \draw [strzala] (text_num) -- (text);
            % END OF ARGUMENT CONTENT
        \end{scope}
    \end{tikzpicture}
    \endwrapfloat%
    \par%
}
\ExplSyntaxOn
\cs_new:cpn {display*} {\display*}
\cs_new_eq:cN {enddisplay*} \enddisplay
\ExplSyntaxOff

\begin{document}

\begin{display*}
    ~\par
    ~\par
    \begin{center}
    text
    \end{center}\par
    ~\par
    ~\par
    ~\par
    ~\par
    ~\par
\end{display*}

\blindtext

\begin{display*}[
   \node (text_num) at (0.8,0.7) [numer] {2};
   \node (text) [element, fit={(0.4,0.22)(0.6,0.34)}] {};
   \draw [strzala] (text_num) -- (text);
]
    ~\par
    ~\par
    ~\par
    ~\par
    ~\par
    \begin{center}
    text
    \end{center}\par
    ~\par
    ~\par
\end{display*}%

\blindtext

\begin{display}[
   \node (text_num) at (0.8,0.7) [numer] {2};
   \node (text) [element, fit={(0.4,0.22)(0.6,0.34)}] {};
   \draw [strzala] (text_num) -- (text);
]
    ~\par
    ~\par
    ~\par
    ~\par
    ~\par
    \begin{center}
    text
    \end{center}\par
    ~\par
    ~\par
\end{display}

\blindtext

\end{document}

附言:我不知道它为什么有效,但对我的目的来说有效。

相关内容