Module:ColorParse: Difference between revisions

From Caves of Qud Wiki
Jump to navigation Jump to search
bordered works now
No edit summary
 
(27 intermediate revisions by 3 users not shown)
Line 6: Line 6:
local shaders = require'Module:ColorParse/Templates'
local shaders = require'Module:ColorParse/Templates'
local stringbyte, stringchar = string.byte, string.char
local stringbyte, stringchar = string.byte, string.char
local shader_to_class = {
['y'] = 'y-dark',
['gray'] = 'y-dark',
['Y'] = 'y',
['white'] = 'y',
['silvery'] = 'y',
['b'] = 'b-dark',
['dark blue'] = 'b-dark',
['B'] = 'b',
['blue'] = 'b',
['azure'] = 'b',
['c'] = 'c-dark',
['dark cyan'] = 'c-dark',
['teal'] = 'c-dark',
['C'] = 'c',
['cyan'] = 'c',
['freezing'] = 'c',
['rules'] = 'c',
['r'] = 'r-dark',
['R'] = 'r',
['o'] = 'o-dark',
['O'] = 'o',
['w'] = 'w-dark',
['emote'] = 'w-dark',
['brown'] = 'w-dark',
['dark keybind'] = 'w-dark',
['W'] = 'w',
['gold'] = 'w',
['yellow'] = 'w',
['important'] = 'w',
['keybind'] = 'w',
['electrical'] = 'w',
['hotkey'] = 'w',
['internals'] = 'w',
['g'] = 'g-dark',
['G'] = 'g',
['m'] = 'm-dark',
['M'] = 'm',
['k'] = 'k-dark',
['K'] = 'k',
}


--[Utility stuff]--
--[Utility stuff]--
Line 11: Line 52:
function normalize(input, type)
function normalize(input, type)
   type = type or 'xml'
   type = type or 'xml'
  local b = clean(input)
   local a = '&y'  
   local a = '&y'  
   if type == 'notxml' then
   if type == 'notxml' then
     a = '&y'
     a = '&y'
   end
   end
  local b = input:gsub("(~J211)", "")
   if not b:match('^%&') then
   if not b:match('^%&') then
     b = a .. b  
     b = a .. b  
  end
  b = b:gsub("(%*)", "*")
  if type == 'xml' then
    b = b:gsub("([{}])", "")
   end
   end
   b = b:gsub("(\\n)","\n")
   b = b:gsub("(\\n)","\n")
   return b
   return b
end
end
function clean(input)
  local b = input:gsub("(~J211)", "")
  b = b:gsub("([{}])", "")
  return b
end
function p.determinexml(input)
  return (input:match('&') ~= nil)
end


function strtotbl(str)
function strtotbl(str)
Line 34: Line 84:
     return tbl
     return tbl
end
end


function p.linebreaks(frame)
function p.linebreaks(frame)
   local b = string.gsub(frame,"(~)","\n\n")
   local b = string.gsub(frame,"(~)","\n")
   return b
   return b
end
end


--[ The main function. Takes the first argument and snips out stuff we don't need
--[ The main function. Takes the first argument and snips out stuff we don't need
--[ depending on regextype.
--[ depending on regextype.
function p.parse(frame, regextype)
function p.parse(frame, regextype)
   args = frame.args or {[1] = frame}
   args = frame.args or {[1] = frame}
   regextype = regextype
   regextype = regextype
   if regextype == nil then
   if regextype == nil then
     if args[1]:match('&') ~= nil then
     if p.determinexml(args[1]) then
      regextype = 'xml'
      regextype = 'xml'
     else
     else
      regextype = 'notxml'
      regextype = 'notxml'
     end
     end
   end
   end
Line 62: Line 113:
   local a = string.gsub(b, regex, function(color,text)
   local a = string.gsub(b, regex, function(color,text)
       if text ~= nil and text ~= "" then
       if text ~= nil and text ~= "" then
           local hexcolor = luatable.parse(color)
           local class = shader_to_class[color]
           if hexcolor == nil then
           if class == nil then
             error ("There was no specified color for color code: " .. color)
             error ("There was no specified color for color code: " .. color)
           end
           end
           text = text or ""
           text = text or ""
           return "<span style=\"color: " .. hexcolor .. ";\">"  .. text .. "</span>"
           return "<span class=\"qud-text " .. class .. "\">"  .. text .. "</span>"
       else
       else
           return ""
           return ""
Line 74: Line 125:
return a
return a
end
end


function p.main(frame)
function p.main(frame)
Line 85: Line 137:
     if arg == 'notxml' then
     if arg == 'notxml' then
         parsetype = 'notxml'
         parsetype = 'notxml'
      elseif arg == 'unbolded' then
        unbolded = true
       elseif arg == 'tildes are new lines' then
       elseif arg == 'tildes are new lines' then
         tildes = true
         tildes = true
Line 98: Line 148:
     returntext = p.linebreaks(returntext)
     returntext = p.linebreaks(returntext)
   end
   end
   if unbolded == true then
   return returntext
    return returntext
  else
  return '<b>' .. (returntext or '') .. '</b>'
  end
end
end




-- Beta Parse --
-- Shader Parse --
function p.shader(text, colors, type)
function p.shader(text, colors, type, rasterize)
     -- split the colors into a list  
     -- split the colors into a list  
     local colorlist = textutil.split(colors, '-')
     local colorlist = textutil.split(colors, '-')
Line 115: Line 161:
     -- alternation | pattern will stretch to fit word length (?)
     -- alternation | pattern will stretch to fit word length (?)
     local type = type or 'default'
     local type = type or 'default'
    local brasterize = false
    if rasterize == 'true' then
      brasterize = true
    end
     local strtbl = strtotbl(text)
     local strtbl = strtotbl(text)
     local finaltbl = {}
     local finaltbl = {}
Line 122: Line 172:
     if type == 'alternation' then
     if type == 'alternation' then
         interval = math.floor(#strtbl/#colorlist)  --sets interval that color code switches.
         interval = math.floor(#strtbl/#colorlist)  --sets interval that color code switches.
        if interval <= 0 then interval = 1 end
         overflowbehavior = function(f) return colorlist[#colorlist] end
         overflowbehavior = function(f) return colorlist[#colorlist] end
     elseif type == 'sequence' then
     elseif type == 'sequence' or type == 'solid' then
         overflowbehavior = function(f)  
         overflowbehavior = function(f)  
         local e = f%#colorlist
         local e = f%#colorlist
Line 132: Line 183:
       bordered = true
       bordered = true
       overflowbehavior = function(f)
       overflowbehavior = function(f)
         if f + #strtbl == 3 then return colorlist[2] else return colorlist[1] end
      -- If it's the first or last character, use the second color, otherwise use the first.
         if #strtbl - f <= 0  or f == 1 then return colorlist[2] else return colorlist[1] end
         end
         end
     elseif type == 'chaotic' then
     elseif type == 'chaotic' then
Line 138: Line 190:
     end
     end
     local ci = 1
     local ci = 1
    if bordered == true then
      ci = #colorlist
    end
     for i=1, #strtbl do
     for i=1, #strtbl do
       if ci > #colorlist or ci <= 0 then
       if ci > #colorlist or ci <= 0 or bordered == true then
           hexcolor = overflowbehavior(ci)
           hexcolor = overflowbehavior(ci)
       else
       else
           hexcolor = colorlist[ci]
           hexcolor = colorlist[ci]
       end
       end
      finaltbl[i] = "<span style=\"color: " .. luatable.parse(hexcolor) .. ";\">"  .. strtbl[i].. "</span>"
          if brasterize then
            finaltbl[i] = "<span style=\"color: " .. luatable.parse(hexcolor) .. ";\">"  .. strtbl[i].. "</span>"
          else
            finaltbl[i] = "&amp;" .. hexcolor .. strtbl[i]
          end
       if i%interval == 0 then
       if i%interval == 0 then
           if bordered == true then
           ci = ci + 1
              ci = ci - 1
          else
              ci = ci + 1
          end
       end       
       end       
     end
     end
Line 162: Line 211:
     local args = process_args.merge(true)
     local args = process_args.merge(true)
     if args[1] and args[2] then -- shader template
     if args[1] and args[2] then -- shader template
       output = applytemplate(args[1], args[2])
       output = applytemplate(args[1], clean(args[2]), (args['rasterize'] or 'true'))
     else
     else
       output = p.shader(args['text'], args['colors'], args['type'])
       output = p.shader(clean(args['text']), args['colors'], args['type'], (args['rasterize'] or 'true'))
     end
     end


     if (args['unbolded'] == 'true') then
     return output
      return output
end
    else
 
       return '<b>' .. (output or '') .. '</b>'
 
    end
function applytemplate(shader, text, raster)
if shader_to_class[shader] ~= nil then
return p.cssshader(text, shader_to_class[shader])
end
  if shaders[shader] == nil then
       error('There was no shader called ' .. (shader or '') .. '!')
  else
      return p.shader(text, shaders[shader][1], shaders[shader][2], raster)
  end
end
end


function applytemplate(shader, text)
function p.cssshader(text, shaderclass)
  return p.shader(text, shaders[shader][1], shaders[shader][2])
return "<span class=\"qud-text " .. shaderclass .. "\">" .. text .. "</span>"
end
end


function p.shaderlist()
function p.shaderlist()
   local tblheader = '<tr><th>Shader</th><th>Colors</th><th>Type</th></tr>'
   local tblheader = '<tr><th>Shader</th><th>Colors</th><th>Type</th></tr>'
   local tr = {}
   local tr = {}
   i = 0
   local sorted_shaders = {}
   for a, v in pairs(shaders) do
  -- Sort keys --
       tr[i] = ' <tr><td><b>' .. applytemplate(a, a) .. '</b></td><td>' .. v[1] .. '</td><td>' .. v[2] .. '</td></tr>'
   for k,v in pairs(shaders) do table.insert(sorted_shaders, k) end
      i = i + 1
  table.sort(sorted_shaders)
  -- Do logic on the sorted table --
  for i, a in ipairs(sorted_shaders) do
    local v = shaders[a]
       tr[i] = ' <tr><td>' .. applytemplate(a, a, 'true') .. '</td><td>' .. v[1] .. '</td><td>' .. v[2] .. '</td></tr>'
   end
   end
   return '<table class="wikitable">' .. tblheader  .. table.concat(tr) .. '</table>'
   return '<table class="wikitable sortable">' .. tblheader  .. table.concat(tr) .. '</table>'
end
end


function p.test()
function p.test()
     --return applytemplate('structural', 'structural')
     return applytemplate('w', '*Barathrum pauses.*', true)
     --return p.shader('Stopsvalinn', 'R-r-K-y-Y', 'sequence')
     --return applytemplate('soul', 'soulcurding')  
    return applytemplate('horned', 'horned')
end
end


return p
return p

Latest revision as of 00:08, 10 June 2025

Documentation

This module parses the game's color codes in strings and formats them for the wiki. This shouldn't be directly called anymore. Use Template:Qud text instead. If the text in question has pronouns in syntax =pronouns.(pronountype)= or a similar style, use Template:Grammar.

Usage

{{#invoke: ColorParse | parse |(your text here)}}

Code:

{{#invoke: ColorParse | parse |&RS&rt&Ko&yp&Ys&Rv&ra&Kl&yi&Yn&Rn&y}}

Result:

Stopsvalinn


local p = {}

local luatable = require'Module:Color'
local textutil = require'Module:Text Utility'
local process_args = require'Module:ProcessArgs'
local shaders = require'Module:ColorParse/Templates'
local stringbyte, stringchar = string.byte, string.char
local shader_to_class = {
	['y'] = 'y-dark',
	['gray'] = 'y-dark',
	['Y'] = 'y',
	['white'] = 'y',
	['silvery'] = 'y',
	['b'] = 'b-dark',
	['dark blue'] = 'b-dark',
	['B'] = 'b',
	['blue'] = 'b',
	['azure'] = 'b',
	['c'] = 'c-dark',
	['dark cyan'] = 'c-dark',
	['teal'] = 'c-dark',
	['C'] = 'c',
	['cyan'] = 'c',
	['freezing'] = 'c',
	['rules'] = 'c',
	['r'] = 'r-dark',
	['R'] = 'r',
	['o'] = 'o-dark',
	['O'] = 'o',
	['w'] = 'w-dark',
	['emote'] = 'w-dark',
	['brown'] = 'w-dark',
	['dark keybind'] = 'w-dark',
	['W'] = 'w',
	['gold'] = 'w',
	['yellow'] = 'w',
	['important'] = 'w',
	['keybind'] = 'w',
	['electrical'] = 'w',
	['hotkey'] = 'w',
	['internals'] = 'w',
	['g'] = 'g-dark',
	['G'] = 'g',
	['m'] = 'm-dark',
	['M'] = 'm',
	['k'] = 'k-dark',
	['K'] = 'k',
}

--[Utility stuff]--

function normalize(input, type)
  type = type or 'xml'
  local b = clean(input)
  local a = '&amp;y' 
  if type == 'notxml' then
    a = '&y'
  end
  if not b:match('^%&') then
    b = a .. b 
  end
  b = b:gsub("(\\n)","\n")
  return b
end


function clean(input)
  local b = input:gsub("(~J211)", "")
  b = b:gsub("([{}])", "")
  return b
end


function p.determinexml(input)
   return (input:match('&amp;') ~= nil)
end


function strtotbl(str)
    tbl = {stringbyte(str, 1, #str)}
    for i = 1, #tbl do
        tbl[i] = stringchar(tbl[i])
    end
    return tbl
end


function p.linebreaks(frame)
  local b = string.gsub(frame,"(~)","\n")
  return b
end


--[ The main function. Takes the first argument and snips out stuff we don't need
--[ depending on regextype.
function p.parse(frame, regextype)
  args = frame.args or {[1] = frame}
  regextype = regextype
  if regextype == nil then
    if p.determinexml(args[1]) then
       regextype = 'xml'
    else
       regextype = 'notxml'
    end
  end
  --[Determine regex type]
  local regex = "&amp;(%w)([^&\n]*)"
  if regextype == 'notxml' then
  	regex = "&(%w)([^&\n]*)"
  end

  local b = normalize(args[1],regextype)
  local a = string.gsub(b, regex, function(color,text)
       if text ~= nil and text ~= "" then
          local class = shader_to_class[color]
          if class == nil then
            error ("There was no specified color for color code: " .. color)
          end
          text = text or ""
          return "<span class=\"qud-text " .. class .. "\">"  .. text .. "</span>"
       else
          return ""
       end
  end)
return a
end


function p.main(frame)

	local parsetype = nil
  	local unbolded = false
  	local tildes = false
  	local text = ''
 	local args = process_args.merge(true)
 	for _, arg in ipairs(args) do
    	if arg == 'notxml' then
        	parsetype = 'notxml'
      	elseif arg == 'tildes are new lines' then
        	tildes = true
        elseif text == '' then
        	text = arg
      	end
  	end
    
  	local returntext = p.parse(text, parsetype)
  	if tildes  == true then 
    	returntext = p.linebreaks(returntext)
  	end
  	return returntext
end


-- Shader Parse --
function p.shader(text, colors, type, rasterize)
    -- split the colors into a list 
    local colorlist = textutil.split(colors, '-')
    -- check shader type:
    -- default     | if pattern is shorter than text, text will remain uncolored (y)
    -- sequence    | pattern will repeat until text is over
    -- alternation | pattern will stretch to fit word length (?)
    local type = type or 'default'
    local brasterize = false
    if rasterize == 'true' then
       brasterize = true
    end
    local strtbl = strtotbl(text)
    local finaltbl = {}
    local interval = 1
    local bordered = false
    local overflowbehavior = function(f) return 'y' end
    if type == 'alternation' then
        interval = math.floor(#strtbl/#colorlist)  --sets interval that color code switches.
        if interval <= 0 then interval = 1 end
        overflowbehavior = function(f) return colorlist[#colorlist] end
    elseif type == 'sequence' or type == 'solid' then
        overflowbehavior = function(f) 
         local e = f%#colorlist
         if e == 0 then e = #colorlist end
         return colorlist[e]
         end
    elseif type == 'bordered' then
       bordered = true
       overflowbehavior = function(f)
       	-- If it's the first or last character, use the second color, otherwise use the first.
        if #strtbl - f <= 0  or f == 1 then return colorlist[2] else return colorlist[1] end
        end
    elseif type == 'chaotic' then
       overflowbehavior = function(f) return 'y' end -- placeholder
    end
    local ci = 1
    for i=1, #strtbl do
       if ci > #colorlist or ci <= 0 or bordered == true then
           hexcolor = overflowbehavior(ci)
       else
           hexcolor = colorlist[ci]
       end
          if brasterize then
            finaltbl[i] = "<span style=\"color: " .. luatable.parse(hexcolor) .. ";\">"  .. strtbl[i].. "</span>"
          else 
            finaltbl[i] = "&amp;" .. hexcolor .. strtbl[i]
          end
       if i%interval == 0 then
          ci = ci + 1
       end      
    end
    return table.concat(finaltbl)
end

function p.shadermain(frame)
    local args = process_args.merge(true)
    if args[1] and args[2] then -- shader template
       output = applytemplate(args[1], clean(args[2]), (args['rasterize'] or 'true'))
    else
       output = p.shader(clean(args['text']), args['colors'], args['type'], (args['rasterize'] or 'true'))
    end

    return output
end


function applytemplate(shader, text, raster)
	if shader_to_class[shader] ~= nil then
		return p.cssshader(text, shader_to_class[shader])
	end
   if shaders[shader] == nil then
       error('There was no shader called ' .. (shader or '') .. '!')
   else
       return p.shader(text, shaders[shader][1], shaders[shader][2], raster)
   end
end

function p.cssshader(text, shaderclass)
	return "<span class=\"qud-text " .. shaderclass .. "\">" .. text .. "</span>"
end


function p.shaderlist()

   local tblheader = '<tr><th>Shader</th><th>Colors</th><th>Type</th></tr>'
   local tr = {}
   local sorted_shaders = {}
   -- Sort keys --
   for k,v in pairs(shaders) do table.insert(sorted_shaders, k) end
   table.sort(sorted_shaders)
   -- Do logic on the sorted table --
   for i, a in ipairs(sorted_shaders) do
   	   local v = shaders[a]
       tr[i] = ' <tr><td>' .. applytemplate(a, a, 'true') .. '</td><td>' .. v[1] .. '</td><td>' .. v[2] .. '</td></tr>'
   end
   return '<table class="wikitable sortable">' .. tblheader  .. table.concat(tr) .. '</table>'
end


function p.test()
    return applytemplate('w', '*Barathrum pauses.*', true)
    --return applytemplate('soul', 'soulcurding') 
end

return p