编辑: 我已经开始了威兹提克目标是让 WhizzyEdit 能够处理任意的 TikZ 代码。现在我已经在一个项目中使用了它,效果已经很好了。
背景:
WhizzyTeX是一个显示 dvi(或 pdf)实时更新的系统。当与 主动式DVI观众也具有能力(称为Whizzy编辑) 使用鼠标移动或调整元素大小。元素必须具有特殊标记,通过源特殊标记指示其位置和大小。在 advi 中,使用鼠标进行更改,然后将其带回 emacs,在代码中更改位置(基于行号和命令名称)。重新编译时,元素位于新位置。
要使此操作有效,请使用\adviedit
宏。您可以将其包装在另一个宏中 - 只需告诉它新宏的名称,以便 WhizzyTeX 知道在源代码中要更改什么。此外,宏必须有一个类似于的第一个参数,{x=1.2,y=3.4}
以便它知道如何编辑源代码。
我的问题:
有没有办法将源特技添加到 PGF/TikZ 基元中,以便 advi 知道所有 TikZ 节点的位置,从而能够移动它们?之后可能需要一些启发式方法来编辑源,但我认为我可以处理这部分。由于我对 PGF/TikZ 内部结构一无所知,我不知道是否有可能为“每个节点”编写源特技。
我知道有一种every node
样式,但它似乎不执行代码。还有execute at begin scope
,它可能可用于确保\adviedit
和 TikZ 使用相同的单位,但它对添加特殊项没有帮助。在路径中,execute at begin to
和execute at end to
可能有用,但对于孤立节点似乎没用。
最终我想要一个可以覆盖(好吧,希望只是附加)一些内部 TikZ 宏的包,允许我移动任何TikZ 节点,甚至可以使用贝塞尔曲线等。
现在我有第一步,即绘制节点并插入的宏\adviedit
。它使用tkz-graph
,这样我就不必x=#,y=#
自己解析了。
\documentclass[12pt]{article}
\usepackage{advi}
\usepackage{tikz}
\usepackage{tkz-graph}
\begin{document}
\begin{tikzpicture}[x=1cm,y=1cm]
\SetVertexNoLabel
% For reference
\draw (0,0) rectangle (15,15);
% My attempt to
\def\mynode#1{%
\setedit{unit=1cm}
\adviedit{comm=\mynode,w=1,h=1,#1}{}
\Vertex[#1]{}
}
% "Turn off" WhizzyEdit
% \def\mynode#1{\Vertex[#1]{}}%
\mynode{x=8.9921,y=8.6836}
\mynode{x=7.2178,y=9.1965}
\mynode{x=6.464,y=6.6085}
\mynode{x=7.2497,y=7.8264}
\mynode{x=3.7562,y=6.9931}
\mynode{x=3.5366,y=10.3264}
\mynode{x=9.3650,y=7.0893}
\mynode{x=10.1343,y=5.4871}
\mynode{x=7.3460,y=12.1536}
\mynode{x=2.2179,y=1.5769}
\end{tikzpicture}
\end{document}
请注意,标签放置不正确,这就是我关闭它们的原因。这不是我的错(我不这么认为)。
答案1
我做了一些实验,并编写了一些代码,希望它们能对你有所帮助。无论如何,这都不是一个完整的解决方案。
看来,一个adviedit
可行的宏必须是 的形式,\macro{x=<value>,y=<value>}
以便whizzytex
能够将数字反馈回来。我的第一个想法是简单地为 增加一种风格,\node
使其看起来像\node[advi={x=<value,y=<value>}]
,但这似乎行不通(也许更多的实验会揭示出一种使它工作的方法)。所以我围绕命令定义了一个包装器\node
,它在开始时获取坐标,然后将控制权交给原始。由于执行给定选项\node
的方式(如),这没有问题。\node
\node[draw]
这是代码。我会在代码中对其进行注释。
\documentclass[12pt]{article}
%\url{http://tex.stackexchange.com/q/50468/86}
\usepackage{advi}
\usepackage{tikz}
% We need to use some internal commands with `@`s in them for getting
% the widths of the nodes
\makeatletter
\tikzset{
% This is the workhorse style
advi/.style={
% We do the advi stuff after the node has been placed so that we can
% get access to its width and height. What this means is that our
% node ends up being equivalent to
% \node[at=(x-value,y-value)] {node text} [advi/set advi={x=,y=}];
append after command={[advi/set advi={#1}]},
% As the advi boxes are specified by lower-left corner, we anchor our
% node at the lower-left so that the given coordinate is the node
% coordinate
anchor=south west,
% The parameter #1 is of the form "x=<value>,y=<value>". We trick
% TikZ into taking that as defining some keys in the "/tikz/advi"
% directory
advi/.cd,
#1,
% We use the values that have just been set, namely `/tikz/advi/x`
% and `/tikz/advi/y` to specify the location of the node via the
% `at` key. We need to give the full path as we're currently in at
% `/tikz/advi`
/tikz/at={(\pgfkeysvalueof{/tikz/advi/x},\pgfkeysvalueof{/tikz/advi/y})}
},
% This next bit ensures that the `/tikz/advi/x` and `y` keys can be
% used to store values.
advi/.cd,
x/.initial=0,
y/.initial=0,
% This is the part that specifies the boxes in the dvi. This is
% actually executed after the node has been processed
set advi/.code={
% As the node has been processed, we can get its width and height by
% looking at a couple of anchors.
\tikz@scan@one@point\pgfutil@firstofone(\tikzlastnode.north east)
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\tikz@scan@one@point\pgfutil@firstofone(\tikzlastnode.south west)
% We adjust the values to be multiples of `em`s as that's the default
% for advi/whizzytex
\pgfmathsetmacro{\advi@node@w}{(\pgf@xa - \pgf@x)/1em}%
\pgfmathsetmacro{\advi@node@h}{(\pgf@ya - \pgf@y)/1em}%
% Finally, we call the `\adviedit` command
\adviedit{comm=\advinode,w=\advi@node@w,h=\advi@node@h,#1}{}%}
}
}
\makeatother
% This is the command that whizzytex will look for.
\newcommand{\advinode}[1]{%
\node[advi={#1}]
}
\begin{document}
hello world, how are you?
% We use `em` units as those are the defaults for advi/whizzytex.
% Presumably this could be made configurable or some wizardry used
% to ensure that the tikz coordinates and the advi coordinates
% matched.
\begin{tikzpicture}[x=1em,y=1em]
% We can even pass ordinary styles to the node:
\advinode{x=13.6805,y=7.3048}[red,draw] {A};
\advinode{x=5.7699,y=10.5065}[circle,fill=blue!50] {B};
\advinode{x=6.464,y=6.6085} {C};
\advinode{x=7.2497,y=7.8264} {D};
\advinode{x=3.7562,y=6.9931} {E};
\advinode{x=1.8567,y=12.5472} {F};
\advinode{x=9.3650,y=7.0893} {G};
\advinode{x=13.9264,y=4.4529} {H};
\advinode{x=11.4138,y=11.5331} {I};
\advinode{x=3.3900,y=2.6800} {J};
\end{tikzpicture}
\end{document}
我不太相信可以在standalone
课堂上尝试这个,所以这里提供一个屏幕截图。
蓝色框和绿线是由 绘制的advi
。请注意,它们是在下面绘图,因此被节点的边框A
和节点的填充区域覆盖B
。它们是可拖动的。
绿线表示坐标是相对于某个东西的。实验表明,它们是相对于(0,0)
图片内部的 - 这正是它应该的样子。(快速查看代码advi.sty
表明,与 PGF 内置函数有一些交互,这可能处理了这一点)。
(最后,这看起来非常有趣,确实值得学习。)