2

I want to create an environment for drawing same-styled derivation trees in my document. I sometimes want this environment placed in a certain float, but sometimes I want a different one (like using a landscape-rotated page or whatever), so I split my favorite float to be an outer environment and my inner float to be the tikz tree. unfortunately, this created a recursion in tex that exploded my stack. Here's a code example:

\documentclass[12pt]{article}    
\usepackage{environ}
\usepackage{tikz}

\NewEnviron{AST}{
\begin{tikzpicture}
        [
                sibling distance = 6em,
                level distance = 6em,
                align = center,
                grow' = right,
                every node/.style = {shape=rectangle, rounded corners,
                        draw, align=center,
                        top color=white, bottom color=blue!20},
                leaf/.style = {font=\ttfamily}
        ]
        \BODY\
\end{tikzpicture}
        }

% #1 is short name for figure
% #2 is long name for figure
\NewEnviron{ASTfig}[2]{
\begin{figure}[hbp]
  \begin{center}
    \begin{AST}
        \BODY\
    \end{AST}
  \end{center}
\caption[AST - #1]{Abstract Syntax Tree - #2}
\end{figure}
}

\begin{document}
\begin{ASTfig}{shambalulu}{bambashushu}
\node {root}
        child { node {node}
                child { node [leaf] {leafy} }
                child { node [leaf] {mcleaf} }
                }
        };
\end{ASTfig}
\end{document}

I guess it's because tex is trying to replace \BODY\ with \BODY\ ad infinitum. I flipped through the documentation and tried using the \environbodyname command, but it changed \BODY on both cases and did not solve the problem.

what am I missing?

Nailo
  • 37

3 Answers3

1

Not exactly sure what you are trying to do, but it seems that \AST should be a macro , not an environment:

enter image description here

Reference:

Code:

\documentclass[12pt]{article}    
\usepackage{environ}
\usepackage{tikz}

\newcommand{\AST}[1]{% \begin{tikzpicture} [ sibling distance = 6em, level distance = 6em, align = center, grow' = right, every node/.style = {shape=rectangle, rounded corners, draw, align=center, top color=white, bottom color=blue!20}, leaf/.style = {font=\ttfamily} ] #1 \end{tikzpicture}% }

% #1 is short name for figure % #2 is long name for figure \NewEnviron{ASTfig}[2]{% \begin{figure}[hbp] \centering \AST{\BODY} \caption[AST - #1]{Abstract Syntax Tree - #2} \end{figure}% }

\begin{document} \begin{ASTfig}{shambalulu}{bambashushu} \node {root} child { node {node} child { node [leaf] {leafy} } child { node [leaf] {mcleaf} } } ; \end{ASTfig} \end{document}

Peter Grill
  • 223,288
  • on what do you base the choice of defining AST as a macro and not an environments? what qualifies for a good environment? – Nailo May 28 '18 at 17:50
  • @Nailo: Good question. I don't really have a good reason that I can articulate right now. Just "seemed" that it should be to me. – Peter Grill May 28 '18 at 21:36
0

The inner \BODY in \begin{AST}\BODY\end{ast} needs to be renamed before environment AST ist called, e.g.:

\documentclass[12pt]{article}
\usepackage{environ}
\usepackage{tikz}

\NewEnviron{AST}{%
  \begin{tikzpicture}
    [
      sibling distance = 6em,
      level distance = 6em,
      align = center,
      grow' = right,
      every node/.style = {
        shape=rectangle, rounded corners,
        draw, align=center,
        top color=white, bottom color=blue!20},
      leaf/.style = {font=\ttfamily}
    ]
    \BODY
  \end{tikzpicture}%
}

% #1 is short name for figure
% #2 is long name for figure
\NewEnviron{ASTfig}[2]{%
  \begin{figure}[hbp]
    \centering
    \let\INNERBODY\BODY
    \begin{AST}
      \INNERBODY
    \end{AST}
    \caption[AST - #1]{Abstract Syntax Tree - #2}
  \end{figure}%
}

\begin{document}
\begin{ASTfig}{shambalulu}{bambashushu}
\node {root}
  child {
    node {node}
    child { node [leaf] {leafy} }
    child { node [leaf] {mcleaf} }
  };
\end{ASTfig}
\end{document}

Result

Additional remarks:

  • \centering instead of environment center is preferred, because environment center adds additional vertical spacing. But figure already adds vertical space.

  • There is no point in using the backslash after the command in \BODY\. The environment ends anyway and forcing a space here makes no sense.

  • End of lines usually adds a space. The example comments some line ends in the definitions to prevent leaking spaces.

Heiko Oberdiek
  • 271,626
0

You don't need \NewEnviron for the inner environment.

I suggest to use xparse, so you can avoid \NewEnviron also for the outer one.

\documentclass[12pt]{article}    
\usepackage{xparse}
\usepackage{tikz}

\NewDocumentEnvironment{AST}{}
 {%
  \begin{tikzpicture}[
    sibling distance = 6em,
    level distance = 6em,
    align = center,
    grow' = right,
    every node/.style = {
      shape=rectangle,
      rounded corners,
      draw,
      align=center,
      top color=white,
      bottom color=blue!20
    },
      leaf/.style = {font=\ttfamily}
  ]
 }
 {\end{tikzpicture}}

% #1 is short name for figure
% #2 is long name for figure
\NewDocumentEnvironment{ASTfig}{O{#2}m}
 {%
  \begin{figure}[hbp]
  \centering
  \begin{AST}
 }
 {%
  \end{AST}
  \caption[AST - #1]{Abstract Syntax Tree - #2}
  \end{figure}
 }

\begin{document}
\begin{ASTfig}[shambalulu]{bambashushu}
  \node {root}
    child {
      node {node}
      child { node [leaf] {leafy} }
      child { node [leaf] {mcleaf} }
    };
\end{ASTfig}
\end{document}

The syntax is a bit different, but in my opinion more convenient. You call

\begin{ASTfig}{xyz}

if the short caption is equal to the long caption; you call

\begin{ASTfig}[short]{long}

if they're different.

enter image description here

egreg
  • 1,121,712