Module:Sandbox

From Wikisource
Jump to navigation Jump to search
Module documentation[create]
-- This is an module to implement "ppoem" (a.k.a. proper poem)
-- The aim here is to provide a poem syntax that's simple, but semantically
-- correct and able to handle things like export and line wrapping.

local p = {} --p stands for package

--[=[
Construct a "proper poem"
]=]
function p.ppoem(frame)
	local args = frame:getParent().args

	local lines = mw.text.split(mw.text.trim(args[1]), "\r?\n", false)

	local s = ""
	
	local open = args['start'] == "open" or args['start'] == nil or args['start'] == ""
	local close = args['end'] == "end" or args['end'] == nil or args['end'] == ""
	
	-- in Page namespace, we always open a fresh environment and close it at the end
	if mw.title.getCurrentTitle():inNamespace(104) then
		open = true
		close = true
	end

	if open then 
		s = s .. "<div class=\"ppoem"
		if args['class'] ~= nil then
			s = s .. " " .. args['class']
		end
		
		s = s .. "\""
		
		local style = ""
		
		if args["gutter"] == "left" or args["gutter"] == "both" then
			style = style .. "padding-left: 2em;"
		end
		if args["gutter"] == "right" or args["gutter"] == "both" then
			style = style .. "padding-right: 2em;"
		end

		if args['style'] ~= nil and args['style'] ~= "" then
			style = style .. args['style']
		end
		
		if style ~= "" then
			s = s .. " style=\"" .. style .. "\""
		end

		s = s .. ">"
	end
	
	if open or args['start'] == "stanza" then 
		s = s .. "<p class=\"stanza\">"
	end

	for k,v in pairs(lines) do
		
		-- replace leading spaces with &nbsp;
		v = v:gsub("^ +", function(spaces)
			local nbsp = "&nbsp;"
			return nbsp:rep(spaces:len())
		end, 1)
		
		v = v:gsub("^:+", function(colons)
			local nbsp = "&emsp;"
			return nbsp:rep(colons:len())
		end, 1)
		
		local right = false
		v = v:gsub("^>>", function(colons)
			right = true
			return ""
		end, 1)

		local line_num;
		v = v:gsub("%s*>>%s*(.+)$", function(line_num_str)
			line_num = line_num_str;
			return ""
		end, 1)
		
		local verse_num;
		v = v:gsub("^(%S)%s*<<%s*", function(verse_num_str)
			verse_num = verse_num_str;
			return ""
		end, 1)
		
		if v == "" then
			s = s .. "</p><p class=\"stanza\">"
		else
			if line_num ~= nil and line_num ~= "" then
				local ln = mw.html.create("span")
					:addClass("line_num")
					:wikitext(line_num)
				s = s .. tostring(ln)
			end
			
			if verse_num ~= nil and verse_num ~= "" then
				local vn = mw.html.create("span")
					:addClass("verse_num")
					:wikitext(verse_num)
				s = s .. tostring(vn)
			end
			
			local tag = mw.html.create("span")
				:addClass("line")
				:css({
				--	["display"]="table"
				})
				:wikitext(v .. "<br/>")
				
			if right then
				tag:addClass("line_right")
			end

			s = s .. tostring(tag)
		end
	end

	if args['end'] == "stanza" or close then
		s = s .. "</p>"
	end
			
	if close then
		s = s .. "</div>"
	end

	return s
end

return p