summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua
blob: 8473eb3f109452634d5c8c102eea94f8bb922e2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
-- 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$



---
-- This class provides the core functionality of the interface between
-- all the different layers (display layer, binding layer, and
-- algorithm layer). The two classes |InterfaceToAlgorithms| and
-- |InterfaceToDisplay| use, in particular, the data structures
-- provided by this class.
--
-- @field binding This field stores the ``binding''. The graph drawing
-- system is ``bound'' to the display layer through such a binding (a
-- subclass of |Binding|). Such a binding can be thought of as a
-- ``driver'' in operating systems terminology: It is a small set of
-- functions needed to adapt the functionality to one specific display
-- system. Note that the whole graph drawing scope is bound to exactly
-- one display layer; to use several bindings you need to setup a
-- completely new Lua instance.
--
-- @field scopes This is a stack of graph drawing scopes. All
-- interface methods refer to the top of this stack.
--
-- @field collection_kinds This table stores which collection kinds
-- have been defined together with their properties.
--
-- @field algorithm_classes A table that maps algorithm keys (like
-- |tree layout| to class objects).
--
-- @field keys A lookup table of all declared keys. Each entry of this
-- table consists of the original entry passed to the |declare|
-- method. Each of these tables is both index at a number (so you can
-- iterate over it using |ipairs|) and also via the key's name.

local InterfaceCore = {
  -- The main binding. Set by |InterfaceToDisplay.bind| method.
  binding             = nil,

  -- The stack of Scope objects.
  scopes              = {},

  -- The collection kinds.
  collection_kinds    = {},

  -- The algorithm classes
  algorithm_classes   = {},

  -- The declared keys
  keys                = {},

  -- The phase kinds
  phase_kinds         = {},

  -- Internals for handling the options stack
  option_stack        = {},
  option_cache_height = nil,
  option_initial      = {
    algorithm_phases = {
      ["preprocessing stack"] = {},
      ["edge routing stack"] = {},
      ["postprocessing stack"] = {},
    }
  },
  option_aliases      = {
    [{}] = true -- Remove, once Lua Link Bug is fixed
  },

  -- Constant strings for special collection kinds.
  sublayout_kind      = "INTERNAL_sublayout_kind",
  subgraph_node_kind  = "INTERNAL_subgraph_node_kind",
}

-- Namespace
require("pgf.gd.interface").InterfaceCore = InterfaceCore


InterfaceCore.option_initial.__index = InterfaceCore.option_initial
InterfaceCore.option_initial.algorithm_phases.__index = InterfaceCore.option_initial.algorithm_phases


-- Imports
local Coordinate = require "pgf.gd.model.Coordinate"


--- Returns the top scope
--
-- @return The current top scope, which is the scope in which
--         everything should happen right now.

function InterfaceCore.topScope()
  return assert(InterfaceCore.scopes[#InterfaceCore.scopes], "no graph drawing scope open")
end



local factors = {
  cm=28.45274,
  mm=2.84526,
  pt=1.0,
  bp=1.00374,
  sp=0.00002,
  pc=12.0,
  em=10,
  ex=4.30554,
  ["in"]=72.27,
  dd=1.07,
  cc=12.8401,
  [""]=1,
}

local time_factors = {
  s=1,
  ms=0.001,
  min=60,
  h=3600
}

local directions = {
  down = -90,
  up = 90,
  left = 180,
  right = 0,
  south = -90,
  north = 90,
  west = 180,
  east = 0,
  ["north east"] = 45,
  ["north west"] = 135,
  ["south east"] = -45,
  ["south west"] = -135,
  ["-"] = 0,
  ["|"] = -90,
}

---
-- Converts parameters types. This method is used by both the
-- algorithm layer as well as the display layer to convert strings
-- into the different types of parameters. When a parameter
-- is pushed onto the option stack, you can either provide a value of
-- the parameter's type; but you can also provide a string. This
-- string can then be converted by this function to a value of the
-- correct type.
--
-- @param s A parameter value or a string.
-- @param t The type of the parameter
--
-- @return If |s| is not a string, it is just returned. If it is a
-- string, it is converted to the type |t|.

function InterfaceCore.convert(s,t)
  if type(s) ~= "string" then
    return s
  elseif t == "number" then
    return tonumber(s)
  elseif t == "length" then
    local num, dim = string.match(s, "([%d.]+)(.*)")
    return tonumber(num) * assert(factors[dim], "unknown unit")
  elseif t == "time" then
    local num, dim = string.match(s, "([%d.]+)(.*)")
    return tonumber(num) * assert(time_factors[dim], "unknown time unit")
  elseif t == "string" then
    return s
  elseif t == "canvas coordinate" or t == "coordinate" then
    local x, y = string.match(s,"%(([%d.]+)pt,([%d.]+)pt%)")
    return Coordinate.new(tonumber(x),tonumber(y))
  elseif t == "boolean" then
    return s == "true"
  elseif t == "raw" then
    return loadstring(s)()
  elseif t == "direction" then
    return directions[s] or tonumber(s)
  elseif t == "nil" or t == nil then
    return nil
  else
    error ("unknown parameter type")
  end
end


-- Done

return InterfaceCore