Module:Sandbox/MonkeysHK

local getArgs = require('Module:Arguments').getArgs

local p = {}

local function splitAngleBrackets(str) local head = 1 local bracketLevel = 0 local ret = {} for i = 1, #str do		local c = str:sub(i, i)		if c == '<' then bracketLevel = bracketLevel + 1 if bracketLevel == 1 then -- on enter angle brackets -> save string as parsing string table.insert(ret, { s = str:sub(head, i - 1):gsub('/', '\n'), parse = true }) head = i			end elseif c == '>' then bracketLevel = bracketLevel - 1 if bracketLevel == 0 then -- on exit angle brackets -> save string as non-parsing string table.insert(ret, { s = str:sub(head, i), parse = false }) head = i + 1 end elseif c == '\n' then -- reset bracket level and save string bracketLevel = 0 table.insert(ret, { s = str:sub(head, i), parse = false }) head = i + 1 end end -- save the remaining parsing string table.insert(ret, { s = str:sub(head):gsub('/', '\n'), parse = true }) return ret end

local function parseString(str) local all = {} for _, v in ipairs(splitAngleBrackets(str)) do		if (v.parse) then local t = mw.text.split(v.s, '\n') for i, l in ipairs(t) do				-- add trailing &r l = l .. '&r' -- handle colors and formatting while (l:match('&[0-9a-fk-o]')) do					l = l:gsub('&([0-9a-fk-o])(.-)(&[0-9a-fr])', ' %2&r %3', 1) end t[i] = l			end v.s = table.concat(t, '\n') end table.insert(all, v.s)	end return all end

function p.raw( frame ) local args = getArgs(frame) return p._raw(args[1], args.size or args[2], args.class, args.style) end

function p._raw( str, size, class, style ) size = tonumber(size) and (size .. 'px') or size or '12px' local s = str:gsub('\\\\', '%%%%BACKSLASH%%%%'):gsub('\\/', '%%%%FORSLASH%%%%'):gsub('\\&', '%%%%AMPERSAND%%%%'):gsub('\\<', '%%%%ANGLEBRACL%%%'):gsub('\\>', '%%%%ANGLEBRACR%%%') s = s:gsub(' ', '\n') local all = parseString(str) s = table.concat(all):gsub('\n', ' ') s = s:gsub('&r', ''):gsub('%%%%BACKSLASH%%%%', '\\\\'):gsub('%%%%FORSLASH%%%%', '\\/'):gsub('%%%%AMPERSAND%%%%', '\\&'):gsub('%%%%ANGLEBRACL%%%', '\\<'):gsub('%%%%ANGLEBRACR%%%', '\\>'):gsub('\\(.)', '%1') return (' %s '):format(class or , size, style or , s) end

function p.dialogue( frame ) local args = getArgs(frame) return p._dialogue(args[1], args.size or args[2], args.class, args.style) end

function p._dialogue( str, size, class, style ) size = size and (tonumber(size) and (size .. 'px') or size) or nil local s = str:gsub('\\\\', '%%%%BACKSLASH%%%%'):gsub('\\/', '%%%%FORSLASH%%%%'):gsub('\\&', '%%%%AMPERSAND%%%%'):gsub('\\<', '%%%%ANGLEBRACL%%%'):gsub('\\>', '%%%%ANGLEBRACR%%%') s = s:gsub(' ', '\n') local all = parseString(s) s = table.concat(all) local t = mw.text.split(s, '\n') for i, l in ipairs(t) do		-- handle modifiers local availableMods = 'cr' -- put all available modifiers here local pttn, lineclass = '^$%[[' .. availableMods .. ']+%]', 		local modifiers = l:match(pttn)		if modifiers then			if modifiers:match('c') then lineclass = 'centertxt' end			if modifiers:match('r') then lineclass = 'righttxt' end			l = l:gsub(pttn, )		end		l = l:gsub('^%s*$', '%%%%AMPERSAND%%%%nbsp;')		l = ' ' .. l .. ' '		t[i] = l	end	s = table.concat(t)	s = s:gsub('&r', ):gsub('%%%%BACKSLASH%%%%', '\\\\'):gsub('%%%%FORSLASH%%%%', '\\/'):gsub('%%%%AMPERSAND%%%%', '\\&'):gsub('%%%%ANGLEBRACL%%%', '\\<'):gsub('%%%%ANGLEBRACR%%%', '\\>'):gsub('\\(.)', '%1')	return (' %s '):format(		class or , (size and ('font-size:' .. size) or ) .. (style or ), s	) end

return p