view src/lib/Bbcode.luan @ 19:da006d1c1eba

use contentEditable
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 13 Jul 2022 08:47:13 -0600
parents 0edde02b908c
children 3ea49246d6a7
line wrap: on
line source

local Luan = require "luan:Luan.luan"
local error = Luan.error
local type = Luan.type or error()
local ipairs = Luan.ipairs or error()
local stringify = Luan.stringify or error()
local Io = require "luan:Io.luan"
local output_of = Io.output_of or error()
local Parsers = require "luan:Parsers.luan"
local bbcode_parse = Parsers.bbcode_parse or error()
local Html = require "luan:Html.luan"
local html_encode = Html.encode or error()
local Table = require "luan:Table.luan"
local is_list = Table.is_list or error()
local String = require "luan:String.luan"
local gsub = String.gsub or error()
local User = require "site:/lib/User.luan"
local Shared = require "site:/lib/Shared.luan"
local list_to_set = Shared.list_to_set or error()
local Logging = require "luan:logging/Logging.luan"
local logger = Logging.logger "Bbcode"


local Bbcode = {}

local to_html
local html = {}

function html.b(bbcode)
	%><b><% to_html(bbcode.contents) %></b><%
end

function html.i(bbcode)
	%><i><% to_html(bbcode.contents) %></i><%
end

function html.u(bbcode)
	%><u><% to_html(bbcode.contents) %></u><%
end

function html.url(bbcode)
	local url = bbcode.param
	if url == nil then
		url = html_encode(bbcode.contents)
		%><a href="<%=url%>"><%=url%></a><%
	else
		url = html_encode(url)
		%><a href="<%=url%>"><% to_html(bbcode.contents) %></a><%
	end
end

function html.code(bbcode)
	%><code><%= html_encode(bbcode.contents) %></code><%
end

function html.img(bbcode)
	%><img src="<%= html_encode(bbcode.contents) %>"><%
end

function html.color(bbcode)
	%><span style="color:<%=bbcode.param%>"><% to_html(bbcode.contents) %></span><%
end

function html.size(bbcode)
	%><span style="font-size:<%=bbcode.param%>%"><% to_html(bbcode.contents) %></span><%
end

function html.quote(bbcode)
	%><blockquote><%
	local user_name = bbcode.param
	if user_name ~= nil then
		local user = User.get_by_name(user_name)
		if user == nil then
			%><%= user_name %> wrote:<%
		else
			%><a href="/user_something"><%= user_name %></a> wrote:<%
		end
	end
	to_html(bbcode.contents)
	%></blockquote><%
end

function html.video(bbcode)
	local url = html_encode(bbcode.contents)
	local site = bbcode.site
	if site == "youtube" then
		%><iframe width="420" height="315" src="https://www.youtube.com/embed/<%=bbcode.id%><%
		local start = bbcode.start
		if start ~= nil then
			%>?start=<%=start%><%
		end
		%>" frameborder="0" allowfullscreen></iframe><%
	elseif site == "bitchute" then
		%><iframe width="420" height="315" scrolling="no" frameborder="0" style="border: none;" src="https://www.bitchute.com/embed/<%=bbcode.id%>/"></iframe><%
	else
		%><a href="<%=url%>"><%=url%></a><%
	end
end

function to_html(bbcode)
	if type(bbcode) == "string" then
		%><%= html_encode(bbcode) %><%
	else
		type(bbcode) == "table" or error()
		if is_list(bbcode) then
			for _, v in ipairs(bbcode) do
				to_html(v)
			end
		else
			local fn = html[bbcode.name] or error(bbcode.name.." not handled")
			fn(bbcode)
		end
	end
end

function Bbcode.to_html(bbcode)
	bbcode = bbcode_parse(bbcode)
	%><div message><% to_html(bbcode) %></div><%
end


local doesnt_nest = list_to_set{
	"url"
	"code"
	"img"
	"video"
}

local function preprocess(bbcode)
	if type(bbcode) == "string" then
		bbcode = gsub( bbcode, [[(^|\s)(https?://\S+)]], "$1[url]$2[/url]" )
		%><%= bbcode %><%
	else
		type(bbcode) == "table" or error()
		if is_list(bbcode) then
			for _, v in ipairs(bbcode) do
				preprocess(v)
			end
		else
			local name = bbcode.name
			local param = bbcode.param
			%>[<%=name%><%
			if param ~= nil then
				%>=<%=param%><%
			end
			%>]<%
			if doesnt_nest[name] then
				%><%=bbcode.contents%><%
			else
				preprocess(bbcode.contents)
			end
			%>[/<%=name%>]<%
		end
	end
end

function Bbcode.preprocess(bbcode)
	bbcode = bbcode_parse(bbcode)
	return output_of(function()
		preprocess(bbcode)
	end)
end

return Bbcode