diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua new file mode 100644 index 00000000000..5a1337a1327 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua @@ -0,0 +1,280 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua,v 1.10 2013/12/20 14:44:46 tantau Exp $ + + + +-- Imports +local Storage = require "pgf.gd.lib.Storage" + + +--- +-- This class, which is a subclass of |Binding|, binds the graph +-- drawing system to the \pgfname\ display system by overriding (that +-- is, implementing) the methods of the |Binding| class. As a typical +-- example, consider the implementation of the function |renderVertex|: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--function BindingToPGF:renderVertex(v) +-- local info = assert(self.infos[v], "thou shalt not modify the syntactic digraph") +-- tex.print( +-- string.format( +-- "\\pgfgdcallbackrendernode{%s}{%fpt}{%fpt}{%fpt}{%fpt}{%fpt}{%fpt}{%s}", +-- 'not yet positionedPGFINTERNAL' .. v.name, +-- info.x_min, +-- info.x_max, +-- info.y_min, +-- info.y_max, +-- v.pos.x, +-- v.pos.y, +-- info.box_count)) +--end +--\end{codeexample} +-- +-- As can be seen, the main job of this function is to call a function +-- on the \TeX\ layer that is called |\pgfgdcallbackrendernode|, which gets +-- several parameters like the name of the to-be-rendered node or the +-- (new) position for the node. For almost all methods of the +-- |Binding| class there is a corresponding ``callback'' macro on the +-- \TeX\ layer, all of which are implemented in the \pgfname\ library +-- |graphdrawing|. For details on these callbacks, +-- please consult the code of that file and of the class +-- |BindingToPGF| (they are not documented here since they are local +-- to the binding and should not be called by anyone other than the +-- binding class). + +local BindingToPGF = { + storage = Storage.newTableStorage () -- overwrite default storage +} +BindingToPGF.__index = BindingToPGF +setmetatable(BindingToPGF, require "pgf.gd.bindings.Binding") -- subclass of Binding + + +-- Namespace +require("pgf.gd.bindings").BindingToPGF = BindingToPGF + +-- Imports +local lib = require "pgf.gd.lib" + +-- The implementation + +-- Forward +local table_in_pgf_syntax + + + + +-- Scope handling + +function BindingToPGF:resumeGraphDrawingCoroutine(text) + tex.print(text) + tex.print("\\directlua{pgf.gd.interface.InterfaceToDisplay.resumeGraphDrawingCoroutine()}") +end + + +-- Declarations + +function BindingToPGF:declareCallback(t) + tex.print("\\pgfgdcallbackdeclareparameter{" .. t.key .. "}{" .. (t.type or "nil") .. "}") +end + + + +-- Rendering + +function BindingToPGF:renderStart() + tex.print("\\pgfgdcallbackbeginshipout") +end + +function BindingToPGF:renderStop() + tex.print("\\pgfgdcallbackendshipout") +end + + +-- Rendering collections + +function BindingToPGF:renderCollection(collection) + tex.print("\\pgfgdcallbackrendercollection{".. collection.kind .. "}{" + .. table_in_pgf_syntax(collection.generated_options) .. "}") +end + +function BindingToPGF:renderCollectionStartKind(kind, layer) + tex.print("\\pgfgdcallbackrendercollectionkindstart{" .. kind .. "}{" .. tostring(layer) .. "}") +end + +function BindingToPGF:renderCollectionStopKind(kind, layer) + tex.print("\\pgfgdcallbackrendercollectionkindstop{" .. kind .. "}{" .. tostring(layer) .. "}") +end + +-- Printing points + +local function to_pt(x) + return string.format("%.12fpt", x) +end + + +-- Managing vertices (pgf nodes) + +local boxes = {} +local box_count = 0 + +function BindingToPGF:everyVertexCreation(v) + local info = self.storage[v] + + -- Save the box! + box_count = box_count + 1 + boxes[box_count] = node.copy_list(tex.box[info.tex_box_number]) + + -- Special tex stuff, should not be considered by gd algorithm + info.box_count = box_count +end + +function BindingToPGF:renderVertex(v) + local info = assert(self.storage[v], "thou shalt not modify the syntactic digraph") + tex.print( + string.format( + "\\pgfgdcallbackrendernode{%s}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%s}", + 'not yet positionedPGFINTERNAL' .. v.name, + info.x_min, + info.x_max, + info.y_min, + info.y_max, + v.pos.x, + v.pos.y, + info.box_count)) +end + +function BindingToPGF:retrieveBox(index, box_num) + tex.box[box_num] = assert(boxes[index], "no box stored at given index") + boxes[index] = nil -- remove from memory +end + +function BindingToPGF:renderVerticesStart() + tex.print("\\pgfgdcallbackbeginnodeshipout") +end + +function BindingToPGF:renderVerticesStop() + tex.print("\\pgfgdcallbackendnodeshipout") +end + + +local function rigid(x) + if type(x) == "function" then + return x() + else + return x + end +end + + +-- Managing edges + +function BindingToPGF:renderEdge(e) + local info = assert(self.storage[e], "thou shalt not modify the syntactic digraph") + + local function get_anchor(e, anchor) + local a = e.options[anchor] + if a and a ~= "" then + return "." .. a + else + return "" + end + end + + local callback = { + '\\pgfgdcallbackedge', + '{', e.tail.name .. get_anchor(e, "tail anchor"), '}', + '{', e.head.name .. get_anchor(e, "head anchor"), '}', + '{', e.direction, '}', + '{', info.pgf_options or "", '}', + '{', info.pgf_edge_nodes or "", '}', + '{', table_in_pgf_syntax(e.generated_options), '}', + '{' + } + + local i = 1 + while i <= #e.path do + local c = e.path[i] + assert (type(c) == "string", "illegal path operand") + + if c == "lineto" then + i = i + 1 + local d = rigid(e.path[i]) + callback [#callback + 1] = '--(' .. to_pt(d.x) .. ',' .. to_pt(d.y) .. ')' + i = i + 1 + elseif c == "moveto" then + i = i + 1 + local d = rigid(e.path[i]) + callback [#callback + 1] = '(' .. to_pt(d.x) .. ',' .. to_pt(d.y) .. ')' + i = i + 1 + elseif c == "closepath" then + callback [#callback + 1] = '--cycle' + i = i + 1 + elseif c == "curveto" then + local d1, d2, d3 = rigid(e.path[i+1]), rigid(e.path[i+2]), rigid(e.path[i+3]) + i = i + 3 + callback [#callback + 1] = '..controls(' .. to_pt(d1.x) .. ',' .. to_pt(d1.y) .. ')and(' + .. to_pt(d2.x) .. ',' .. to_pt(d2.y) .. ')..' + callback [#callback + 1] = '(' .. to_pt(d3.x) .. ',' .. to_pt(d3.y) .. ')' + i = i + 1 + else + error("illegal operation in edge path") + end + end + + callback [#callback + 1] = '}' + + -- hand TikZ code over to TeX + tex.print(table.concat(callback)) +end + + +function BindingToPGF:renderEdgesStart() + tex.print("\\pgfgdcallbackbeginedgeshipout") +end + +function BindingToPGF:renderEdgesStop() + tex.print("\\pgfgdcallbackendedgeshipout") +end + + +-- Vertex creation + +function BindingToPGF:createVertex(init) + -- Now, go back to TeX... + coroutine.yield( + table.concat({ + "\\pgfgdcallbackcreatevertex{", init.name, "}", + "{", init.shape, "}", + "{", table_in_pgf_syntax(init.generated_options), ",", init.pgf_options or "", "}", + "{", (init.text or ""), "}" + })) + -- ... and come back with a new node! +end + + + +-- Local helpers + +function table_in_pgf_syntax (t) + local prefix = "/graph drawing/" + local suffix = "/.try" + return table.concat( lib.imap( t, function(table) + if table.value then + return prefix .. table.key .. suffix .. "={" .. tostring(table.value) .. "}" + else + return prefix .. table.key .. suffix + end + end), ",") +end + + + +return BindingToPGF
\ No newline at end of file |