@@ -4,7 +4,6 @@ local tablex = require("pl.tablex")
44
55local node_types = {}
66local node_to_type
7- local dedent
87
98local FluentNode = class ({
109 discardable = false ,
@@ -33,7 +32,13 @@ local FluentNode = class({
3332 self .value = node
3433 else
3534 if not self .elements then self .elements = {} end
36- table.insert (self .elements , node )
35+ if # self .elements >= 1 then
36+ if not self .elements [# self .elements ]:append (node ) then
37+ table.insert (self .elements , node )
38+ end
39+ else
40+ table.insert (self .elements , node )
41+ end
3742 end
3843 end ,
3944
@@ -100,36 +105,60 @@ node_types.Pattern = class({
100105 _base = FluentNode ,
101106 _init = function (self , node )
102107 self :super (node )
103- -- TODO: merge sequential mergables in elements
104- -- TODO: move dedent to here after merge?
108+ self :dedent ()
109+ end ,
110+ dedent = function (self )
111+ local mindent = function (node )
112+ local indents = {}
113+ if type (node .value ) == " string" then
114+ for indent in string.gmatch (node .value , " \n *%S" ) do
115+ table.insert (indents , # indent - 2 )
116+ end
117+ end
118+ return tablex .reduce (math.min , indents ) or 0
119+ end
120+ local striplen = tablex .reduce (math.min , tablex .imap (mindent , self .elements )) or 0
121+ local i , strippref = 1 , " \n "
122+ while i <= striplen do
123+ strippref = strippref .. " "
124+ i = i + 1
125+ end
126+ local strip = function (node , key , len )
127+ if type (node .value ) == " string" then
128+ local value = string.gsub (node .value , " \r\n " , " \n " )
129+ if len >= 1 then
130+ value = string.gsub (value , strippref , " \n\n " )
131+ end
132+ -- local function next_is_text
133+ value = key == 1 and string.gsub (value , " ^[\n ]+" , " " ) or value
134+ value = key == # self .elements and string.gsub (value , " [\n ]+$" , " " ) or value
135+ self .elements [key ].value = value
136+ end
137+ end
138+ tablex .foreachi (self .elements , strip , striplen )
105139 end ,
106140 format = function (self , parameters )
107- local value = # self . elements >= 2 and dedent () or self . elements [ 1 ]. value
108- -- Todo parse elements and actually format a value
141+ local function evaluate ( node ) return node : format ( parameters ) end
142+ local value = table.concat ( tablex . map ( evaluate , self . elements ))
109143 return value , parameters
110144 end
111145 })
112- -- local lasttype = "none"
113- -- for key, value in ipairs(stuff) do
114- -- if lasttype == value.id then
115- -- ast.elements[#ast.elements] = ast.elements[#ast.elements].value .. value.value
116- -- else
117- -- table.insert(ast.elements, self(value))
118- -- lasttype = value.id
119- -- end
120- -- end
121- -- for key, value in ipairs(ast.elements) do
122- -- if key == "value" then
123- -- ast.elements[key] = dedent(value)
124- -- end
125- -- end
126146
127147node_types .TextElement = class ({
128148 appendable = true ,
129149 _base = FluentNode ,
130150 _init = function (self , node )
131151 node .id = " TextElement"
132152 self :super (node )
153+ end ,
154+ __add = function (self , node )
155+ if self :is_a (node :is_a ()) and self .appendable and node .appendable then
156+ self .value = (self .value or " " ) .. " \n " .. (node .value or " " )
157+ return self
158+ end
159+ end ,
160+ format = function (self )
161+ return self .value
133162 end
134163 })
135164
@@ -142,6 +171,9 @@ node_types.Placeable = class({
142171 if node .expression then
143172 self .expression = node_to_type (node .expression [1 ])
144173 end
174+ end ,
175+ format = function (self , parameters )
176+ return self .expression :format (parameters )
145177 end
146178 })
147179
@@ -157,20 +189,39 @@ node_types.StringLiteral = class({
157189 _base = FluentNode ,
158190 _init = function (self , node )
159191 self :super (node )
192+ end ,
193+ format = function (self )
194+ return self .value
160195 end
161196 })
162197
163198node_types .NumberLiteral = class ({
164199 _base = FluentNode ,
165200 _init = function (self , node )
166201 self :super (node )
202+ end ,
203+ format = function (self )
204+ return self .value
167205 end
168206 })
169207
170208node_types .VariableReference = class ({
171209 _base = FluentNode ,
172210 _init = function (self , node )
173211 self :super (node )
212+ end ,
213+ format = function (self , parameters )
214+ return parameters [self .id .name ]
215+ end
216+ })
217+
218+ node_types .MessageReference = class ({
219+ _base = FluentNode ,
220+ _init = function (self , node )
221+ self :super (node )
222+ end ,
223+ format = function (self )
224+ return self .value
174225 end
175226 })
176227
@@ -235,25 +286,6 @@ node_to_type = function (node)
235286 end
236287end
237288
238- dedent = function (content )
239- local min
240- for indent in string.gmatch (content , " \n *%S" ) do
241- min = min and math.min (min , # indent ) or # indent
242- end
243- local common = function (shortest )
244- local i = 0
245- local s = " "
246- while i < shortest do
247- s = s .. " "
248- i = i + 1
249- end
250- return s
251- end
252- local sp = common (min - 2 )
253- local rep = string.gsub (content , " \n " .. sp , " \n " )
254- return rep
255- end
256-
257289local FluentResource = class ({
258290 type = " Resource" ,
259291 index = {},
0 commit comments