@@ -3,96 +3,129 @@ local h = require('h')
3
3
local originalRequire = require
4
4
5
5
local function decentParserAST (input )
6
- local pos = 1
7
6
local output = " "
8
- local isTag = 0
9
- local isTextNode = 0
7
+ local pos = 1
10
8
local deepNode = 0
9
+ local deepString = false
10
+ local deepStringApos = false
11
+ local isTag = false
12
+ local textNode = false
13
+ local textNodeStart = false
14
+ local var = false
11
15
12
16
while pos <= # input do
13
- local char = input :sub (pos , pos )
17
+ local tok = input :sub (pos , pos )
14
18
-- simple decent parser
19
+ -- escape " ' encapsulation
15
20
-- opening tag
16
- if char == " <" then
17
- local tagName = input :match ( " <(%w+) " , pos )
18
- local tagNameEnd = input :match ( " </(%w+)> " , pos )
19
- if isTag == 2 and tagName ~= nil then
20
- -- children tag
21
- output = output .. " , "
22
- end
23
- if tagName then
24
- deepNode = deepNode + 1
25
- isTag = 1
26
- output = output .. tagName .. " ({ "
27
- pos = pos + # tagName + 1
28
- elseif tagNameEnd then
29
- deepNode = deepNode - 1
30
- if deepNode == 0 then
31
- isTag = 0
21
+ if tok == " <" and not deepString and not deepStringApos then
22
+ local nextSpacingPos = input :find ( ' %s ' , pos )
23
+ local tagRange = input :sub ( pos , nextSpacingPos )
24
+ local tagName = tagRange : match ( " <(%w+) " , 0 )
25
+ local tagNameEnd = tagRange : match ( " </(%w+)> " , 0 )
26
+ if tagName then deepNode = deepNode + 1 end
27
+ if tagNameEnd then deepNode = deepNode - 1 end
28
+ pos = pos + 1
29
+
30
+ if tagName and not deepString then
31
+ isTag = true
32
+ textNode = false
33
+ if deepNode > 1 then
34
+ output = output .. " , " .. tagName .. " ({ "
35
+ else
36
+ output = output .. tagName .. " ({ "
32
37
end
33
- if isTextNode == 2 then
34
- isTextNode = 0
38
+ local step = 1
39
+ -- enclose attributes if it empty
40
+ if tagRange :sub (# tagRange - 1 , # tagRange ):gsub (" [\r\n ]" , " " ):match (" ^%s*(.-)$" ) == ' >' then step = 0 end
41
+ pos = pos + # tagName + step
42
+ elseif tagNameEnd then
43
+ if isTag and not textNode then
44
+ isTag = not isTag
45
+ local trail = input :sub (0 , pos - 2 ):gsub (" [%s\r\n ]" , " " )
46
+ if trail :sub (# trail - 1 , # trail - 1 ) == ' /' then
47
+ output = output .. " )"
48
+ else
49
+ output = output .. " })"
50
+ end
51
+ elseif isTag and textNode then
35
52
output = output .. " ]])"
36
53
else
37
- output = output .. " )"
54
+ if textNodeStart then
55
+ textNodeStart = not textNodeStart
56
+ output = output .. " ]])"
57
+ else
58
+ output = output .. " )"
59
+ end
38
60
end
39
61
pos = pos + # tagNameEnd + 2
40
62
else
63
+ output = output .. tok
41
64
pos = pos + 1
42
65
end
43
- elseif char == " >" then
44
- if isTag == 1 then
45
- output = output .. " }"
46
- isTag = 2
66
+ elseif tok == ' "' and deepNode > 0 then
67
+ deepString = not deepString
68
+ output = output .. tok
69
+ pos = pos + 1
70
+ elseif tok == " '" and deepNode > 0 then
71
+ deepStringApos = not deepStringApos
72
+ output = output .. tok
73
+ pos = pos + 1
74
+ elseif tok == " >" and deepNode > 0 and not deepString and not deepStringApos then
75
+ if not textNode and isTag and input :sub (pos - 1 , pos - 1 ) ~= " /" then
76
+ isTag = not isTag
77
+ textNode = not textNode
78
+ output = output .. ' }'
79
+ else
80
+ isTag = not isTag
81
+ -- textNode = not textNode
82
+ output = output .. ' })'
47
83
end
48
84
pos = pos + 1
49
- elseif char == " /" then
85
+ elseif tok == " /" and input : sub ( pos + 1 , pos + 1 ) == ' > ' and not deepString and not deepStringApos then
50
86
deepNode = deepNode - 1
51
- -- self closing tag
52
- if deepNode == 0 then
53
- isTag = 0
87
+ output = output .. ' })'
88
+ pos = pos + 2
89
+ elseif tok == ' {' and deepNode > 0 and not deepString and not deepStringApos then
90
+ var = not var
91
+ if not isTag then
92
+ output = output .. ' ,'
54
93
end
55
- output = output .. " })"
56
94
pos = pos + 1
57
- else
58
- local skip = false
59
- if char and isTag == 2 then
60
- isTextNode = 1
61
- isTag = 3
62
- output = output .. " , "
63
- elseif isTag == 1 then
64
- -- attributes
65
- if char :match (" %s" ) then
66
- if output :sub (- 1 ) ~= " {" and output :sub (- 1 ) == " \" " then
67
- output = output .. " ,"
68
- elseif input :sub (pos - 1 , pos - 1 ) == " }" then
69
- output = output .. " ,"
70
- end
71
- skip = false
72
- elseif char == " {" or char == " }" then
73
- skip = true
95
+ elseif tok == ' }' and deepNode > 0 and not deepString and not deepStringApos then
96
+ var = not var
97
+ pos = pos + 1
98
+ elseif deepNode > 0 and not deepString and not deepStringApos then
99
+ if tok :match (" %s" ) then
100
+ if isTag and output :sub (- 1 ) ~= " {" and output :sub (- 1 ) == " \" " or
101
+ isTag and input :sub (pos - 1 , pos - 1 ) == " }" then
102
+ output = output .. " ,"
74
103
end
75
104
end
76
105
77
- if isTag ~= 0 then
78
- -- add bracket to all attributes key
79
- if isTextNode == 1 and char == " {" or char == " }" then
80
- skip = true
81
- isTextNode = 3
82
- elseif isTextNode == 1 then
83
- isTextNode = 2
84
- if char ~= ' \n ' then
85
- output = output .. " [["
86
- end
106
+ if textNode and not textNodeStart then
107
+ local subNode = input :match (" %s*<(%w+)" , pos )
108
+ if not isTag and not subNode and not var then
109
+ textNodeStart = not textNodeStart
110
+ output = output .. " , [["
87
111
end
88
112
end
89
113
90
- if skip == false then
91
- output = output .. char
92
- end
93
- if char :match (" %=" ) then
94
- output = output :gsub (' ([%w%-_]+)%=' , ' ["%1"]=' )
114
+ output = output .. tok
115
+ pos = pos + 1
116
+ else
117
+ if not textNode and not deepString and not deepStringApos then
118
+ textNode = not textNode
119
+ if textNode then
120
+ local subNode = input :match (" %s*<(%w+)" , pos )
121
+ if isTag and not subNode then
122
+ output = output .. " }, [["
123
+ elseif deepNode > 0 and not subNode then
124
+ output = output .. " [["
125
+ end
126
+ end
95
127
end
128
+ output = output .. tok
96
129
pos = pos + 1
97
130
end
98
131
end
102
135
local function preprocessLuaFile (inputFile )
103
136
local inputCode = io.open (inputFile , " r" ):read (" *all" )
104
137
local transformedCode = decentParserAST (inputCode )
138
+ -- this to add [] bracket to table attributes
139
+ transformedCode = transformedCode :gsub (' ([%w%-_]+)%=([^%s]+)' , ' ["%1"]=%2' )
140
+ -- print(transformedCode)
105
141
return transformedCode
106
142
end
107
143
0 commit comments