55

This is a follow-up question to Clever beamer animation? Writing a script that changes a tikz picture in beamer?

as suggested there, I will put a bounty on this one.

What I seek is a set of macros, perhaps a package for a scripting language for beamer/tikz animations.

I proceed carefully here, since I am not sure whether some of the concrete requests and suggestions are possible as is. At the same time, I do not wish to hinder the resourcefulness of whoever tries to respond here. I am also aware that I might be asking for the wrong set of features: things that are not really needed, and missing real useful features.

And of course, I would not expect any "full" solution; I would be infinitely grateful even if a small part of this "plan" is implemented.

So, please take whatever follows as a very very initial draft, and feel free to change.

The desired set of features, revolves around three ingredients: role, action(or "say"), and script. Each graphical element can take several roles, and can associate with each of these a default "action".

The concrete visualization problem that lead me to this question is related to the simulation of the execution of a flow chart.

First I define the notion of a "role", which is something that can take the place of a tikz definition. So, if "role" is a non-terminal symbol in an EBNF, I would like to be able to write "

Concrete syntax is:

 role -> 'r' opCode nameSayList
 opCode -> '=' //Resets the roles list
           '+=' // Add to the roles list
           '-=' // Remove items from the role list (not sure it is needed)

  nameSayList -> singleSay
                  '{' singleSay, ... '}'

  singleSay -> roleName 
               roleName '/' keyList

  roleName -> Any unique identifier, with whichever syntax

  keyList -> singleKey
             '{' manyKeys '}'

  singleKey -> any pgf key
  manyKeys -> any list of pgf keys with their assignments

Semantics of the above specification: for each graphical element (which may be even a scope) the package computes a set of pairs. The first element of each pair is a "role name", and the second, and optional element, is a list of pgf key assignments.

Now, a script can be specified with the following:

 script -> \script{ Stages } picture
 picture -> \begin{tikzpicture} ... \end{tikzpicture}
 stages -> stage, ...
 stage  -> singleActivation
           '{' singleAction, ... '}'
 singleActivation -> role
                     role/says
 says -> singleSay
         '{' singleSay, .... '}'
 singleSay -> key [= value]

This model does not include the "fadeOut" and the "introduction" of a graphical element, by which such an element with a role is activated with specific key setting in the stage before (or after) its designated stage.

To demonstrate, think of a flow-chart diagram.

Each node belong in a class: decision, IO, process, etc. You can run a script on the diagram that would highlight all the nodes of a certain class as the speaker speaks about the different kinds of components.

Or, you can run a simulation, in which edges and nodes are highlighted, as the flowchart progresses through the computation. A stage including several roles could be used for highlighting the current input, current output, etc.

(Feel free to use a "Turing Machine" or "Finite State Automaton" if you dislike flowcharts as much as I do.)

           '
  • 1
    I like the animate package (ctan.org/pkg/animate) and its timeline option, but that's another story, I'm afraid... – Malipivo Mar 29 '14 at 15:33
  • 1
    PDF interactions can be done in JavaScript, this is completely independent of LaTeX but packages exist. – marczellm May 28 '14 at 11:55
  • 1
    Why is animate + media9 in beamer no possibility? – Peter Ebelsberger Mar 23 '15 at 23:12
  • 3
    I don't quite get your question. Do you want the tikz-picture to be updated in place, e.g. a new Latex run, or do you want a precomputed set of images (e.g. a movie)? – Dux Jan 25 '16 at 9:02
  • 2
    That's why I suggested showing us the input you'd like to give for a given output. Take the animation produced by the accepted answer to the other question. What do you want the input to be? If you don't know that, how can you expect us to understand the question? If you do know, how can you expect us to understand without telling us? I'm starting to think that the real problem is that you do not really know what your question is because you don't really know what you want. (This isn't a criticism - sometimes it can be very, very hard to know this.) – cfr Jun 7 '16 at 1:26
7

It seems that this question has been around for a while, so I'm making some kind of attempt towards a solution, even if the only outcome would be that the question itself might become more clear. TL;DR: I am making use of styles and /.append style to control parts of the drawing.

I couldn't quite understand the purpose of the keys in roles (r=role/key?) so roles are just labels reminiscent of CSS classes. They are realized by role: keys attached to elements (could be nodes, edges, scopes, etc.). Then my drawing is a command parameterized by additional styles for the rules.

I used LuaTeX because I got frustrated with TeX macro expansion hell. One Lua function initializes the roles to empty styles, another generates appropriate /.append style attributes. Notice: works with LuaTeX 0.80, for newest (0.95) change newtoken to token.

I think the beamer integration is orthogonal as long as we can render the individual frames. So I give an example that renders a standalone document.

output document

\documentclass[border=1mm]{standalone}

\usepackage[dvipsnames]{xcolor}

\usepackage{tikz}
\usetikzlibrary{arrows,positioning}

\directlua{
% Initializes all roles with empty styles
init_roles = function(name, roles)
  render_cmd = name
  for h in comma_sep(roles) do
    tex.sprint("\noexpand\\tikzset{role:" .. h .. "/.style=}")
  end
end

% Create an invocation of the form
% \render_cmd{role:role1/.append style=style1, ...}
say = function(actions)
  local attrs = {}
  for say in comma_sep(actions) do
    local role, style = string.match(say, "(.+)/(.+)")
    table.insert(attrs, "role:" .. role .. "/.append style=" .. style)
  end
  tex.sprint("\noexpand\\" .. render_cmd .. "{" .. table.concat(attrs, ",") .. "}")
end

comma_sep = function(s) 
  return string.gmatch(s, "[^, ][^,]*[^, ]") 
end

nxt = newtoken.scan_string
}

\def\initroles{\directlua{init_roles(nxt(), nxt())}}
\def\say{\directlua{say(nxt())}}


\begin{document}

\tikzset{>=latex,
         state/.style={draw,circle},
         tr/.style=->,
         accept/.style=double,
         hide/.style={opacity=0},
         show/.style={opacity=1}}%

% Roles (could avoid by parsing and extracting from the figure)
\initroles{automaton}{init,s1,s2,s3,fin,s0 on a,s2 on b,s1 on b,s3 on c,check}%

\newcommand\automaton[1]{
\begin{tikzpicture}[#1]
  \node[state, role:init](s0) {$s_0$};
  \node[state, above right=of s0, role:s1](s1) {$s_1$};
  \node[state, below right=of s0, role:s2](s2) {$s_2$};
  \node[state, right=of s1, role:s3](s3) {$s_3$};
  \node[state, accept, below right=of s3, role:fin](s4) {$s_4$};

  \draw (s0) edge[tr,out=60,in=180] node[above left,role:s0 on a] {a} (s1);
  \draw (s0) edge[tr,out=-60,in=180] node[below left,role:s0 on a] {a} (s2);
  \draw (s2) edge[tr,loop,out=0,in=90,looseness=8] node[above right,role:s2 on b] {b} (s2.north);

  \draw (s1) edge[tr] node[above,role:s1 on b] {b} (s3);

  \draw (s3) edge[tr,out=0,in=90] node[above,role:s3 on c] {c} (s4);

  \node[hide, role:check, below=1mm of s4] {yes!};
\end{tikzpicture}
}

% Animation actions
\tikzset{current/.style={fill=yellow},
         enabled/.style={circle,draw=gray,inner sep=1pt,outer sep=2pt},
         final accept/.style={fill=green},
         final reject/.style={fill=red}}%

\begin{tabular}{ll}
\say{init/current} &
\say{init/current, s0 on a/enabled} \\
\say{s1/current, s2/current} &
\say{s1/current, s2/current, s1 on b/enabled, s2 on b/enabled} \\
\say{s3/current, s2/current} &
\say{s3/current, s2/current, s3 on c/enabled} \\
\say{fin/final accept, check/show}
\end{tabular}

\end{document}  

Problems: It's more than a bit verbose, because styles always have to be defined - so I have to "declare" all roles with empty styles attached to them. I think OP wanted to preserve the state between one frame to the other; LuaTeX might come in handy here, just have to add a way to clear styles.

Another problem with TikZ styles is that you cannot extend a "conjunction", that is, "I want all edges that are labeled with 'a' to be brown", so you are forced to define (a subset of) the cartesian product of such roles.

  • Interesting. Note that \tikzstyle is deprecated and ought to be avoided. – cfr Jul 12 '16 at 22:33
  • Good news! I managed to learn just enough LuaTeX to write what's needed for this specific task. Looks nicer now. Thanks @cfr for pointing out the deprecation of \tikzstyle. – corwin.amber Jul 16 '16 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.