summaryrefslogtreecommitdiff
path: root/graphics/tpx/Scripts/XmlOut.lua
blob: 73fe298fff097e848701ab428575f91940716865 (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
-- *  Lua module for writing simple XML * --

-- *  Class for writing XML * --

XmlOutput = {}
-- class constructor
function XmlOutput:Create()
  obj = {
    Out = {}, IndentStep = 2, Indent = 0,
    ElStack = {len = 0}, 
    ExpectEOL = false, PreserveSpace = false,
    EOL_Str = "\n"}
  obj.ElStack.Peek = function(self)
    return self[self.len]
  end
  obj.ElStack.Push = function(self, Value)
    local len = self.len + 1
    self.len = len
    self[len] = Value
  end
  obj.ElStack.Pop = function(self)
    local len = self.len
    if len == 0 then error("Element stack is empty") end
    local value = self[len]
    self[len] = nil         -- to allow garbage collection
    self.len = len - 1
    return value
  end
  setmetatable(obj, {__index = self})
  return obj
end
-- write to output stream
function XmlOutput:GetText()
  return table.concat(self.Out)
end
-- write to output stream
function XmlOutput:Write(Data)
  if Data == "" then return end
  table.insert(self.Out, Data)
end
-- a function used internally
function XmlOutput:DataAdded()
  if self.ElStack.len ~= 0 then
    if self.ElStack:Peek().Empty then
      self:Write('>')
      self.ExpectEOL = true
    end
    self.ElStack:Peek().Empty = False
  end
  if self.ExpectEOL then
    if not self.PreserveSpace then self:Write(self.EOL_Str) end
    self.ExpectEOL = false
  end
end
-- open XML tag
function XmlOutput:OpenTag(Tag)
  self:DataAdded()
  Data = {Tag = Tag, Empty = true}
  self.ElStack:Push(Data)
  if not self.PreserveSpace then 
    self:Write(string.rep(" ", self.Indent))
  end
  self:Write("<")
  self:Write(Tag)
  self.Indent = self.Indent + self.IndentStep
end
-- add attribute to current opening tag
function XmlOutput:AddAttribute(Name, Value)
  self:Write(string.format(' %s="%s"', Name, Value))
end
-- add a list of attributes to current opening tag
function XmlOutput:AddAttributes(Attr)
  if Attr then
    for k,v in pairs(Attr) do
      self:Write(string.format(' %s="%s"', k, v))
    end
  end
end
-- add text inside current tag
function XmlOutput:AddText(Data)
  self:DataAdded()
  self:Write(Data)
end
-- close XML tag
function XmlOutput:CloseTag()
  local Data = self.ElStack:Pop()
  self.Indent = self.Indent - self.IndentStep
  if Data.Empty then
    self:Write("/>")
  else
    self:DataAdded()
    if not self.PreserveSpace then 
      self:Write(string.rep(" ", self.Indent))
    end
    self:Write(string.format("</%s>", Data.Tag))
  end
  self.ExpectEOL = true
end
-- add comment to XML
function XmlOutput:AddComment(Data)
  self:DataAdded()
  self:Write(string.format("<!--%s-->", Data))
  self.ExpectEOL = true
end