12
|
1 local Luan = require "luan:Luan.luan"
|
|
2 local error = Luan.error
|
|
3 local type = Luan.type or error()
|
|
4 local ipairs = Luan.ipairs or error()
|
|
5 local stringify = Luan.stringify or error()
|
13
|
6 local Io = require "luan:Io.luan"
|
|
7 local output_of = Io.output_of or error()
|
12
|
8 local Parsers = require "luan:Parsers.luan"
|
|
9 local bbcode_parse = Parsers.bbcode_parse or error()
|
|
10 local Html = require "luan:Html.luan"
|
|
11 local html_encode = Html.encode or error()
|
21
|
12 local html_parse = Html.parse or error()
|
12
|
13 local Table = require "luan:Table.luan"
|
|
14 local is_list = Table.is_list or error()
|
21
|
15 local concat = Table.concat or error()
|
13
|
16 local String = require "luan:String.luan"
|
|
17 local gsub = String.gsub or error()
|
21
|
18 local matches = String.matches or error()
|
23
|
19 local match = String.match or error()
|
12
|
20 local User = require "site:/lib/User.luan"
|
13
|
21 local Shared = require "site:/lib/Shared.luan"
|
|
22 local list_to_set = Shared.list_to_set or error()
|
20
|
23 local to_list = Shared.to_list or error()
|
12
|
24 local Logging = require "luan:logging/Logging.luan"
|
|
25 local logger = Logging.logger "Bbcode"
|
|
26
|
|
27
|
|
28 local Bbcode = {}
|
|
29
|
|
30 local to_html
|
|
31 local html = {}
|
|
32
|
20
|
33 function html.b(bbcode,options)
|
|
34 %><b><% to_html(bbcode.contents,options) %></b><%
|
|
35 end
|
|
36
|
|
37 function html.i(bbcode,options)
|
|
38 %><i><% to_html(bbcode.contents,options) %></i><%
|
|
39 end
|
|
40
|
|
41 function html.u(bbcode,options)
|
|
42 %><u><% to_html(bbcode.contents,options) %></u><%
|
12
|
43 end
|
|
44
|
20
|
45 function html.s(bbcode,options)
|
|
46 %><s><% to_html(bbcode.contents,options) %></s><%
|
12
|
47 end
|
|
48
|
20
|
49 function html.sup(bbcode,options)
|
|
50 %><sup><% to_html(bbcode.contents,options) %></sup><%
|
12
|
51 end
|
|
52
|
20
|
53 function html.brackets(bbcode,options)
|
|
54 %>[<% to_html(bbcode.contents,options) %>]<%
|
|
55 end
|
|
56
|
|
57 function html.url(bbcode,options)
|
12
|
58 local url = bbcode.param
|
|
59 if url == nil then
|
|
60 url = html_encode(bbcode.contents)
|
|
61 %><a href="<%=url%>"><%=url%></a><%
|
|
62 else
|
|
63 url = html_encode(url)
|
20
|
64 %><a href="<%=url%>"><% to_html(bbcode.contents,options) %></a><%
|
12
|
65 end
|
|
66 end
|
|
67
|
20
|
68 function html.code(bbcode,options)
|
|
69 local s = gsub(bbcode.contents,[[^\n]],"")
|
|
70 %><code><%= html_encode(s) %></code><%
|
|
71 options.strip_newline = true
|
12
|
72 end
|
|
73
|
20
|
74 function html.img(bbcode,options)
|
12
|
75 %><img src="<%= html_encode(bbcode.contents) %>"><%
|
|
76 end
|
|
77
|
20
|
78 function html.color(bbcode,options)
|
|
79 %><span style="color:<%=bbcode.param%>"><% to_html(bbcode.contents,options) %></span><%
|
12
|
80 end
|
|
81
|
20
|
82 function html.size(bbcode,options)
|
23
|
83 %><span style="font-size:<%=bbcode.param%>"><% to_html(bbcode.contents,options) %></span><%
|
12
|
84 end
|
|
85
|
20
|
86 function html.quote(bbcode,options)
|
12
|
87 %><blockquote><%
|
|
88 local user_name = bbcode.param
|
|
89 if user_name ~= nil then
|
|
90 local user = User.get_by_name(user_name)
|
|
91 if user == nil then
|
|
92 %><%= user_name %> wrote:<%
|
|
93 else
|
|
94 %><a href="/user_something"><%= user_name %></a> wrote:<%
|
|
95 end
|
20
|
96 else
|
|
97 options.strip_newline = true
|
12
|
98 end
|
20
|
99 to_html(bbcode.contents,options)
|
12
|
100 %></blockquote><%
|
20
|
101 options.strip_newline = true
|
12
|
102 end
|
|
103
|
23
|
104 local youtube_ptn1 = [[https://youtu.be/([a-zA-Z0-9_-]+)(?:\?t=([0-9]+))?]]
|
|
105 local youtube_ptn2 = [[https://www.youtube.com/watch\?v=([a-zA-Z0-9_-]+)(?:&t=([0-9]+)s)?]]
|
|
106 local bitchute_ptn = [[https://www.bitchute.com/video/([a-zA-Z0-9]+)/]]
|
27
|
107 local rumble_ptn = [[https://rumble.com/embed/[a-z0-9]+/\?pub=[a-z0-9]+]]
|
23
|
108
|
20
|
109 function html.video(bbcode,options)
|
23
|
110 local url = bbcode.contents
|
|
111 local id, start = match(url,youtube_ptn1)
|
|
112 if id == nil then
|
|
113 id, start = match(url,youtube_ptn2)
|
|
114 end
|
|
115 if id ~= nil then
|
|
116 %><iframe width="560" height="315" src="https://www.youtube.com/embed/<%=id%><%
|
12
|
117 if start ~= nil then
|
|
118 %>?start=<%=start%><%
|
|
119 end
|
|
120 %>" frameborder="0" allowfullscreen></iframe><%
|
23
|
121 return
|
12
|
122 end
|
23
|
123 id = match(url,bitchute_ptn)
|
|
124 if id ~= nil then
|
|
125 %><iframe width="560" height="315" scrolling="no" frameborder="0" style="border: none;" src="https://www.bitchute.com/embed/<%=id%>/"></iframe><%
|
|
126 return
|
|
127 end
|
27
|
128 if matches(url,rumble_ptn) then
|
|
129 %><iframe width="560" height="315" frameborder="0" allowfullscreen src="<%=url%>"></iframe><%
|
|
130 return
|
|
131 end
|
23
|
132 url = html_encode(url)
|
|
133 %><a href="<%=url%>"><%=url%></a><%
|
12
|
134 end
|
|
135
|
20
|
136 local function list_to_html(bbcode,options)
|
|
137 local list = to_list(bbcode.contents)
|
|
138 for _, item in ipairs(list) do
|
|
139 if type(item) == "table" and item.name == "li" then
|
|
140 %><li><% to_html(item.contents,options) %></li><%
|
|
141 end
|
|
142 end
|
|
143 options.strip_newline = true
|
|
144 end
|
|
145
|
|
146 function html.ul(bbcode,options)
|
|
147 %><ul><%
|
|
148 list_to_html(bbcode,options)
|
|
149 %></ul><%
|
|
150 end
|
|
151
|
|
152 function html.ol(bbcode,options)
|
|
153 %><ol><%
|
|
154 list_to_html(bbcode,options)
|
|
155 %></ol><%
|
|
156 end
|
|
157
|
|
158 function to_html(bbcode,options)
|
|
159 if options.strip_newline then
|
|
160 if type(bbcode) == "string" then
|
|
161 bbcode = gsub(bbcode,[[^\n]],"")
|
|
162 end
|
|
163 options.strip_newline = false
|
|
164 end
|
12
|
165 if type(bbcode) == "string" then
|
|
166 %><%= html_encode(bbcode) %><%
|
|
167 else
|
|
168 type(bbcode) == "table" or error()
|
|
169 if is_list(bbcode) then
|
|
170 for _, v in ipairs(bbcode) do
|
20
|
171 to_html(v,options)
|
12
|
172 end
|
|
173 else
|
|
174 local fn = html[bbcode.name] or error(bbcode.name.." not handled")
|
20
|
175 fn(bbcode,options)
|
12
|
176 end
|
|
177 end
|
|
178 end
|
|
179
|
|
180 function Bbcode.to_html(bbcode)
|
|
181 bbcode = bbcode_parse(bbcode)
|
20
|
182 %><div message><%
|
|
183 to_html(bbcode,{strip_newline=false})
|
|
184 %></div><%
|
12
|
185 end
|
|
186
|
13
|
187
|
|
188 local doesnt_nest = list_to_set{
|
|
189 "url"
|
|
190 "code"
|
|
191 "img"
|
|
192 "video"
|
|
193 }
|
|
194
|
|
195 local function preprocess(bbcode)
|
|
196 if type(bbcode) == "string" then
|
|
197 bbcode = gsub( bbcode, [[(^|\s)(https?://\S+)]], "$1[url]$2[/url]" )
|
|
198 %><%= bbcode %><%
|
|
199 else
|
|
200 type(bbcode) == "table" or error()
|
|
201 if is_list(bbcode) then
|
|
202 for _, v in ipairs(bbcode) do
|
|
203 preprocess(v)
|
|
204 end
|
|
205 else
|
|
206 local name = bbcode.name
|
|
207 local param = bbcode.param
|
|
208 %>[<%=name%><%
|
|
209 if param ~= nil then
|
|
210 %>=<%=param%><%
|
|
211 end
|
|
212 %>]<%
|
|
213 if doesnt_nest[name] then
|
|
214 %><%=bbcode.contents%><%
|
|
215 else
|
|
216 preprocess(bbcode.contents)
|
|
217 end
|
20
|
218 if name == "code" and param ~= nil then
|
|
219 %>[/<%=name%>=<%=param%>]<%
|
|
220 else
|
|
221 %>[/<%=name%>]<%
|
|
222 end
|
13
|
223 end
|
|
224 end
|
|
225 end
|
|
226
|
|
227 function Bbcode.preprocess(bbcode)
|
|
228 bbcode = bbcode_parse(bbcode)
|
|
229 return output_of(function()
|
|
230 preprocess(bbcode)
|
|
231 end)
|
|
232 end
|
|
233
|
21
|
234 function Bbcode.remove_html(text)
|
|
235 local ends_with_newline = matches(text,[[\n$]])
|
|
236 local t = {}
|
|
237 local html = html_parse(text)
|
|
238 local is_first = true
|
|
239 for _, v in ipairs(html) do
|
|
240 if type(v) == "string" then
|
|
241 t[#t+1] = v
|
|
242 else
|
|
243 local name = v.name
|
|
244 if name == "div" then
|
|
245 if not is_first then
|
|
246 t[#t+1] = "\n"
|
|
247 end
|
|
248 elseif name == "/div" or name == "br" then
|
|
249 -- ignore
|
|
250 else
|
|
251 error("unexpected tag: "..name)
|
|
252 end
|
|
253 end
|
|
254 is_first = false
|
|
255 end
|
|
256 if not ends_with_newline then
|
|
257 t[#t+1] = "\n"
|
|
258 end
|
|
259 return concat(t)
|
|
260 end
|
|
261
|
|
262
|
12
|
263 return Bbcode
|