Documentation for this module may be created at Module:Infobox user/doc

local p = {}

-- Main function.
function p.main(frame)
  -- Debug me as `=p.main({ ["key"]="value" })` in the debug console.
  local args
  if frame == mw.getCurrentFrame() then
    args = frame:getParent().args
  else
    args = frame
  end

  -- Gets and sorts the given keys.
  local sortedKeys = {}
  for key, _ in pairs(args) do
    table.insert(sortedKeys, key)
  end
  table.sort(sortedKeys)

  -- Creates a `<table>`.
  local tableElement = mw.html.create('table')
    :css('text-align', 'left')

  -- Category names to which the page will belong.
  local categories = {}

  -- Iterates over the items.
  for _, key in ipairs(sortedKeys) do
    local value = args[key]
    key = key:gsub('^%d+%s*', '', 1)

    -- Extracts and strips the `__XXX__` magic word from the value.
    local MAGIC_WORD_PATTERN = '^__(%w+)__%s*'
    local _, _, magicWord = value:find(MAGIC_WORD_PATTERN)
    if magicWord ~= nil then
      value = value:gsub(MAGIC_WORD_PATTERN, '', 1)
    end

    -- Categorization.
    if magicWord ~= 'NOCAT' then
      local lowerKey = string.lower(key)

      if magicWord == 'USER' then
        table.insert(categories, lowerKey .. ' users')
      else
        local lowerValue = string.lower(value)
        table.insert(categories, lowerKey .. ' ' .. lowerValue)
      end
    end

    tableElement
      :tag('tr')
        :tag('th')
          :css('vertical-align', 'top')
          :wikitext(key)
          :done()
        :tag('td')
          :wikitext(value)
          :done()
        :done()
  end

  wikitext = tostring(tableElement)
  for _, category in ipairs(categories) do
    wikitext = wikitext .. '\n[[Category:' .. category .. ']]'
  end

  return wikitext
end

return p