用于投影仪动画的脚本语言?

用于投影仪动画的脚本语言?

这是巧妙的 Beamer 动画?编写脚本来更改 Beamer 中的 tikz 图片?

正如那里所建议的,我将为此提供赏金。

我寻求的是一组宏,也许是用于 beamer/tikz 动画的脚本语言包。

我在这里谨慎行事,因为我不确定一些具体的要求和建议是否可以按原样实现。同时,我不想妨碍任何试图在这里做出回应的人的智慧。我也知道我可能要求了错误的功能集:不是真正需要的东西,缺少真正有用的功能。

当然,我并不期待任何“完整”的解决方案;即使这个“计划”的一小部分能够得以实施,我也会无限感激。

因此,请将以下内容视为初步草案,并可随意更改。

所需的功能集围绕三个要素:角色、动作(或“说”)和脚本。每个图形元素可以承担多个角色,并且可以将每个角色与默认“动作”相关联。

引导我想到这个问题的具体可视化问题与流程图执行的模拟有关。

首先,我定义了“角色”的概念,它可以代替 tikz 定义。因此,如果“角色”是 EBNF 中的非终端符号,我希望能够写“

具体语法为:

 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

上述规范的语义:对于每个图形元素(甚至可能是范围),包都会计算一组对。每对的第一个元素是“角色名称”,第二个元素(可选)是 pgf 键分配列表。

现在,可以使用以下内容指定脚本:

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

该模型不包括图形元素的“淡出”和“引入”,通过该模型,具有角色的元素在其指定阶段之前(或之后)的阶段中通过特定的键设置来激活。

为了演示,请想象一个流程图。

每个节点都属于一个类:决策、IO、流程等。您可以在图表上运行一个脚本,当演讲者谈论不同类型的组件时,该脚本将突出显示某个类的所有节点。

或者,您可以运行模拟,其中边缘和节点在流程图计算过程中突出显示。包含多个角色的阶段可用于突出显示当前输入、当前输出等。

(如果您和我一样不喜欢流程图,请随意使用“图灵机”或“有限状态自动机”。)

           '

答案1

似乎这个问题已经存在了一段时间了,所以我正在尝试寻找解决方案,即使唯一的结果是问题本身可能会变得更加清晰。TL;DR:我正在利用样式来/.append style控制绘图的各个部分。

我不太明白角色中的键的用途(r=role/key?),所以角色只是让人联想到 CSS 类的标签。它们通过role:附加到元素的键来实现(可以是节点、边、范围等)。然后我的绘图是一个由规则的附加样式参数化的命令。

我使用 LuaTeX 是因为 TeX 宏扩展让我很郁闷。一个 Lua 函数将角色初始化为空样式,另一个函数生成适当的/.append style属性。注意:适用于 LuaTeX 0.80,最新版(0.95)已更改newtokentoken

我认为只要我们能够渲染单个帧,投影仪集成就是正交的。所以我举了一个渲染standalone文档的例子。

输出文件

\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}  

问题:这有点冗长,因为样式总是需要定义 - 所以我必须“声明”所有带有空样式的角色。我认为 OP 想要保留一个框架与另一个框架之间的状态;LuaTeX 可能在这里派上用场,只需添加一种清除样式的方法。

TikZ 样式的另一个问题是您无法扩展“连词”,即“我希望所有标有‘a’的边都变成棕色”,因此您被迫定义此类角色的笛卡尔积(的子集)。

相关内容