Module:Proofreadpage index template
Þessi síða var afrituð frá ensku Wikiheimild. Reynt hefur verið að aðlaga hana að íslensku Wikiheimildum með sem fæstum mögulegum breytingum. Það er gert til að forðast fjölverknað og spara tíma en einnig svo hægt sé að taka við uppfærslum og nýjum eiginleikum með sem minnstri fyrirhöfn. Leiðbeiningar um notkun hennar má finna á enska verkefninu. Einungis það sem lesandinn sér skal íslenskað. Ef frekari breytingar eru nauðsynlegar til að aðlaga hana að íslenska verkefninu skulu þær útskýrðar hér fyrir neðan.
--[=[
This is a module to implement logic for [[MediaWiki:Proofreadpage index template]]
It doesn't do everything yet, but over time it can accrete functions from
the template, which will become simpler and simpler until it's just an invoke.
Implemented so far:
* Status categorisation and field
* Some auxiliary data fields
]=]
local getArgs = require('Module:Arguments').getArgs
local messageBox = require('Module:Message box')
local ISO_639 = require('Module:ISO 639')
local p = {} --p stands for package
local DEFAULTS = {
Source = '_tómur_',
}
-- mapping of field ID to field properties
local headings = {
title = {
txt = 'Titill',
},
progress = {
txt = 'Framvinda',
},
oclc = {
txt = 'OCLC',
},
transclusion = {
txt = 'Innifalningar',
},
validation_date = {
txt = 'Staðfest',
},
source = {
txt = 'Uppruni'
},
place = {
txt = 'Staðsetning'
},
year = {
txt = 'Ár'
},
publisher = {
txt = 'Útgefandi'
},
author = {
txt = 'Höfundur'
},
editor = {
txt = 'Ritstjóri'
},
translator = {
txt = 'Þýðandi'
},
illustrator = {
txt = 'Myndskreytir'
},
doi = {
txt = 'DOI'
},
volumes = {
txt = 'Bindi'
}
}
local indicators = {
pagegame = {
name = "WS Page Game",
image = "Mynd:OOjs UI icon page number.svg",
link = "{{fullurl:toolforge:ws-page-game|wikisource=is&index={{PAGENAMEE}}&lang=is}}",
caption = "Wikisource Page Game (skref-fyrir-skref síðulistabyggir)"
},
purge = {
name = "purge file",
image = "Mynd:OOjs UI icon reload.svg",
link = "{{fullurl:commons:File:{{PAGENAME}}|action=purge}}",
caption = "Hreinsa skrá"
},
book2scroll = {
name = "book2scroll",
image = "Mynd:Library-logo-blue-outline.png",
link = "{{fullurl:toolforge:book2scroll|lang=en&file={{PAGENAMEE}}}}",
caption = "Opna í Book2Scroll"
},
bookreader = {
name = "bookreader",
image = "Mynd:BookReader-favicon.svg",
link = "{{fullurl:toolforge:bookreader/en/{{PAGENAMEE}}}}",
caption = "Opna í BookReader"
},
}
local function get_heading(id)
if headings[id] then
return headings[id]['txt']
end
error( "Finn ekki höfuð fyrir auðkenni: " .. id )
end
-- mapping from status code to category and status text
local index_status_data = {
T = {
cat = 'Frumrit staðfest',
txt = 'Tilbúin—Allar síður verksins eru staðfestar',
},
V = {
cat = 'Frumrit prófarkalesið',
txt = 'Prófarkalesin—Allar síður verksins eru prófarkalesnar en ekki allar staðfestar',
},
C = {
cat = 'Frumrit ekki prófarkalesið',
txt = 'Þarfnast prófarkalesturs',
},
MS = {
cat = 'Frumrit - Tilbúið fyrir Match & Split',
txt = 'Tilbúið fyrir Match & Split',
},
OCR = {
cat = 'Frumrit - Textalag umbeðið',
txt = 'Upprunaskrá þarfnast OCR-textalags',
},
L = {
cat = 'Frumrit - Skrá þarfnast lagfæringar',
txt = 'Upprunaskrá verður að laga fyrir prófarkalestur',
error = true,
},
X = {
cat = 'Frumrit - Skrá þarfnast athugunar',
txt = 'Búðu til síðulista fyrir upprunaskrá áður en byrjaður er prófarkalestur (til að staðfesta að skráin sé rétt)',
error = true
},
_default = {
cat = 'Frumrit - Óþekkt framvinda',
txt = 'Óþekkt framvinda (sniðvilla)',
error = true,
}
}
-- construct a basic "field" row
local function construct_field(id, content)
if id == nil or content == nil then
return ''
end
local title = get_heading( id )
local s = ''
s = s .. mw.ustring.format('<tr id="ws-index-%s-row" class="ws-index-row">\n', id)
s = s .. mw.ustring.format('<th id="ws-index-%s-label" class="ws-index-label" scope="row">%s</th>\n', id, title)
s = s .. mw.ustring.format('<td id="ws-index-%s-value" class="ws-index-value">%s</td>\n', id, content)
s = s .. '</tr>\n'
return s
end
local function construct_link(url, text)
return '[' .. url .. ' ' .. text .. ']'
end
local function int_link(target, text)
return '[' .. '[' .. target .. '|' .. text .. ']]'
end
-- handy URL generators (remember to use mw.uri.encode on the bits you need to)
local url_gens = {
oclc = function(id)
return 'https://www.worldcat.org/oclc/' .. id
end,
ark = function(id)
return 'https://n2t.net/' .. mw.uri.encode(id)
end,
doi = function(id)
return 'https://doi.org/' .. id
end
}
-- construct a span which might be classed "error"
local function maybe_error_span(text, error)
local span = mw.html.create('span')
:wikitext(text)
if error then
span:addClass('error')
end
return span
end
-- Construct the Title field (includes Vol. after Title if present)
local function construct_title_field(id, title, volume)
local content = title or ""
if volume ~= nil and volume ~= "" then
content = content .. ", " .. volume
end
return construct_field(id, content)
end
-- construct the source field:
-- - if a file exists, link it
-- - else just the text
local function construct_source_field(source)
local value
local file = mw.title.new( mw.title.getCurrentTitle().text, 'File' )
if file.file.exists then
value = int_link( ':' .. file.fullText, source )
else
value = source
end
local out = construct_field( 'source', value )
return out
end
local function construct_location_field( loc )
return construct_field('place', loc)
end
-- construct the status (proofread/validated/...) field
local function construct_status_field(status)
local out = ''
local sd = index_status_data[status]
if not sd then
sd = index_status_data['_default']
end
out = out .. '[[Flokkur:' .. sd['cat'] .. ']]'
local link_text = tostring(maybe_error_span(sd['txt'], sd['error']))
local catlink = '[[:Flokkur:' .. sd['cat'] .. '|' .. link_text .. ']]'
out = out .. construct_field("progress", catlink)
return out
end
local transclusion_data = {
yes = {
cat = 'Fyllilega innifalið',
text = 'Fyllilega innifalið',
help = 'Verkið er fyllilega innifalið, þar á meðal fram- og lokaefni og myndir'
},
notimg = {
cat = 'Myndir ekki fyllilega innifaldar',
text = 'Myndir ekki fyllilega innifaldar',
help = 'Verkið er fyllilega innifalið en sumar myndir vantar enn eða þarfnast endurbóta',
},
notadv = {
cat = 'Auglýsingar ekki innifaldar',
text = 'Auglýsingar ekki innifaldar',
help = 'Meginhluti verksins er rétt innifalinn þó auglýsingaefni for- eða endaefnis sé það ekki'
},
held = {
cat = 'Innifalning í bið',
text = 'Innifalning í bið',
help = 'Það er vandamál með innifalningu verksins (sem ætti að vera útskýrt á spjallsíðunni)'
},
check = {
cat = 'Athugun innifalningar krafist',
text = 'Athugun innifalningar krafist',
help = 'Innifalningu verksins er ólokið eða þarfnast athugunar'
},
no = {
cat = 'Frumrit ekki innifalið',
text = 'Frumrit ekki innifalið eða óyfirfarið',
help = 'Þetta verk er ekki innifalið eða hefur ekki verið yfirfarið fyrir innifalningu'
}
}
local function construct_cat(cat)
return "[[Flokkur:" .. cat .. "]]"
end
-- construct the transclusion status
local function construct_transclusion_status(status, date)
-- handle templates with no explicit status
if status == nil then
status = "no"
end
local td = transclusion_data[status]
if td == nil then
error("Óþekkt staða frumrits: " .. status)
end
local catlink = '[[:Flokkur:' .. td['cat'] .. '|' .. td['text'] .. ']]'
local out = construct_field("transclusion", catlink)
out = out .. construct_cat( td['cat'])
return out
end
local function construct_validated_date(date)
local cat = 'Frumrit staðfest í ' .. date
local indicator_text = 'Staðfest í ' .. date
local out = '[[Flokkur:' .. cat .. ']]'
local catlink = '[[:Flokkur:' .. cat .. '|' .. date .. ']]'
out = out .. construct_field("validation_date", catlink)
out = out .. '<indicator name="validated-index-date">[[Mynd:Yes Check Circle.svg|15px|link=Flokkur:' .. cat .. '|' .. indicator_text .. '|alt=Staðfest frumritssíða.]]</indicator>'
return out
end
local function getLanguageCat(l)
-- get the name or nil
local lang = ISO_639.language_name(l)
if lang then
return "Frumritssíður verka upprunalega á " .. lang
end
end
function p.fields(frame)
local args = getArgs(frame)
-- set any defaults
for k, v in pairs( DEFAULTS ) do
if args[ k ] == nil then
args[ k ] = DEFAULTS[ k ]
end
end
local s = ""
s = s .. construct_title_field('title', args['Title'], args['Volume'])
s = s .. construct_field('author', args['Author'])
s = s .. construct_field('translator', args['Translator'])
s = s .. construct_field('editor', args['Editor'])
s = s .. construct_field('illustrator', args['Illustrator'])
s = s .. construct_field('year', args['Year'])
s = s .. construct_field('publisher', args['Publisher'])
s = s .. construct_location_field(args['Address'])
s = s .. construct_source_field(args['Source'])
s = s .. construct_status_field(args['Progress'])
-- always do this, even if the arg is not set
s = s .. construct_transclusion_status(args["Transclusion"], args['Transclusion_date'])
if args["Validation_date"] then
s = s .. construct_validated_date(args["Validation_date"])
end
if args["OCLC"] then
local link = construct_link(url_gens['oclc'](args["OCLC"]), args['OCLC'])
s = s .. construct_field("oclc", link)
end
if args["DOI"] then
local link = construct_link(url_gens['doi'](args["DOI"]), args['DOI'])
s = s .. construct_field("doi", link)
end
s = s .. construct_field('volumes', args['Volumes'])
-- language categorisations
if args.Language then
local langs = mw.text.split( args.Language, ',%s?', false)
for _, lang in pairs(langs) do
local cat = getLanguageCat(lang)
if cat then
s = s .. construct_cat(cat)
else
s = s .. construct_cat('Frumritssíður verka upprunalega á óþekktu tungumáli')
end
end
if #langs > 1 then
s = s .. construct_cat('Frumritssíður verka upprunalega á mörgum tungumálum')
end
end
return s
end
function p.talkremarks(frame)
return _talkremarks(frame)
end
local function _talkremarks(frame)
local talkTitle = mw.title.getCurrentTitle().talkPageTitle
local talkText = talkTitle.prefixedText
if talkTitle.exists then
local notes = frame:callParserFunction("#lsth", talkText, "Quick notes")
return frame:expandTemplate{
title = "Index talk remarks",
args = {
notes = "\n" .. notes
}
}
end
return ''
end
function p.indicators(frame)
return _indicators(frame)
end
local function _indicators(frame)
local s = ''
for k, v in pairs(indicators) do
local link = frame:preprocess(v.link)
local img = mw.ustring.format("[[%s|20px|link=%s|%s]]", v.image, link, v.caption)
s = s .. frame:extensionTag{
name = "indicator",
content = img,
args = {
name = v.name
}
}
end
return s
end
function p.cover(frame)
local args = getArgs(frame)
-- Workaround for pagelist preview that tries to parse this template
-- without any context and with missing parameters via the API.
if args['Image'] == nil then
return ""
end
-- If Image param is not a (page) number then this is an image-based
-- Index, so use the provided image as the cover image.
if tonumber(args['Image']) == nil then
local s = ""
if mw.ustring.find(args['Image'], '^%[%[') ~= nil then
-- It's a full image specification
s = s .. args['Image']
else
-- Assume it's a filename with or without File: prefix
local file = mw.ustring.gsub(args['Image'], "^[Ff]ile:", "")
s = s .. "[[" .. "Mynd:" .. file .. "|250px|class=ws-cover]]"
end
-- Add a tracking category
-- s = s .. "[[" .. "Category:Image based indexes" .. "]]"
return s
end
-- Otherwise it's a DjVu/PDF-backed index, in which case we fetch the
-- cover image from a page in the (multipage) file.
local indexTitle = mw.title.getCurrentTitle()
local fileTitle = mw.title.makeTitle('File', indexTitle.text)
if not fileTitle.file.exists then
-- Our associated file doesn't exist so use a placeholder
local s = "[[Mynd:Placeholder book.svg|250px|link="
s = s .. fileTitle.prefixedText .. "|class=ws-cover]]"
-- s = s .. "[[" .. "Category:Indexes with missing files" .. "]]"
return s
end
-- File exists and we have page number for the cover
local s = "[[" .. fileTitle.prefixedText .. "|250px"
s = s .. "|page=" .. tonumber(args['Image']) .. "|class=ws-cover]]"
return s
end
function p.remarks(frame)
local args = getArgs(frame)
if args['Remarks'] ~= nil and args['Remarks'] ~= "" then
return '<td id="ws-index-remarks">' .. args['Remarks'] .. '</td>'
else
return '<td id="ws-index-remarks-empty"></td>'
end
end
function p.sortkey(frame)
local args = getArgs(frame)
local sortkey = ""
if args['Key'] ~= nil and args['Key'] ~= "" then
sortkey = args['Key']
else
sortkey = mw.title.getCurrentTitle().text
end
return frame:preprocess{text = "{{" .. "DEFAULTSORT:" .. sortkey .. "}}"}
end
-- Wrapper to output .fields with containing html table element.
function p.metadata(frame)
local metadatatable = mw.html.create("table")
metadatatable:attr("id", "ws-index-metadata")
local rows = p.fields(frame)
metadatatable:node(rows)
return tostring(metadatatable)
end
--
-- NEW EXPERIMENTAL CODE BELOW THIS LINE --
--
local cfg = mw.loadData("Module:Proofreadpage index template/config")
local CATS = {
categories = {}
}
function CATS:addCat(cat)
table.insert(self.categories, cat)
end
function CATS:getCats()
local cats = ""
for _, cat in ipairs(self.categories) do
cats = cats .. "[[" .. "Flokkur:" .. cat .. "]]"
end
return cats
end
function CATS:makeCatLink(cat, label)
if label ~= nil and label ~= "" then
return "[[:" .. "Flokkur:" .. cat .. "|" .. label .. "]]"
end
return "[[:" .. "Flokkur:" .. cat .. "]]"
end
-- construct a basic "field" row
local function __makeRow(id, content)
if id == nil or id == "" or content == nil then
return ''
end
local row = mw.html.create("tr")
row
:attr("id", "ws-index-" .. id .. "-row")
:addClass("ws-index-row")
:tag("th")
:attr("scope", "row")
:attr("id", "ws-index-" .. id .. "-label")
:addClass("ws-index-label")
:wikitext(cfg.headings[id].txt)
:done()
:tag("td")
:attr("id", "ws-index-" .. id .. "-value")
:addClass("ws-index-value")
:wikitext(content)
:allDone()
return tostring(row)
end
-- Create indicator markup based on config
--
-- Loads the config module and creates indicator extension tags after pattern
-- <indicator name="foo">[[Mynd:Foo.png|20px|link=bar]]</indcator>
-- The link is preprocessed as wikitext so it can contain parser functions etc.
local function __getIndicators(frame)
local indicators = mw.loadData('Module:Proofreadpage index template/indicators')
local s = ''
for _, v in pairs(indicators) do
local link = frame:preprocess(v.link)
local img = mw.ustring.format("[[%s|20px|link=%s|%s]]", v.image, link, v.caption)
s = s .. frame:extensionTag{
name = "indicator",
content = img,
args = {
name = v.name
}
}
end
return s
end
-- Get talk page notice if present
--
-- If the talk page associated with the current page exists, we use Labelled
-- Section Transclusion to transclude the section titled "Quick notes" and if
-- the result contains any text, return a message box with its contents.
local function __getTalkNotice(frame)
local talkTitle = mw.title.getCurrentTitle().talkPageTitle
local talkText = talkTitle.prefixedText
if talkTitle.exists then
local notes = frame:callParserFunction("#lsth", talkText, "Quick notes")
local s = "Formatting guidelines specific to this work may have "
s = s .. "already been established. Please check "
s = s .. "[[" .. talkText .. "|the talk page]] for details."
local box = messageBox.main("ombox", {
type = "content",
text = s .. notes
})
return box
end
return ''
end
-- Get the image to use as the cover image for this index
--
-- If the Image parameter contains an integer it refers to a page in a DjVu/PDF
-- and can be used directly. Otherwise it may be a full image specification
-- that we can use directly, or just an image filename that we can construct
-- an image specification for.
local function __getCoverImage(args)
local s = ""
-- If Image param is not a (page) number then this is an image-based
-- Index, so use the provided image as the cover image.
if tonumber(args['Image']) == nil then
if mw.ustring.find(args['Image'], '^%[%[') ~= nil then
s = s .. args['Image'] -- It's a full image specification
else
-- Assume it's a filename with or without File: prefix
local file = mw.ustring.gsub(args['Image'], "^[Ff]ile:", "")
s = s .. "[[" .. "Mynd:" .. file .. "|250px|class=ws-cover ws-index-cover]]"
end
-- Add a tracking category
-- CATS:addCat("Image based indexes")
return s
end
-- Otherwise it's a DjVu/PDF-backed index, in which case we fetch the
-- cover image from a page in the (multipage) file.
local indexTitle = mw.title.getCurrentTitle()
local fileTitle = mw.title.makeTitle('File', indexTitle.text)
if not fileTitle.file.exists then
-- Our associated file doesn't exist so use a placeholder
s = s .. "[[Mynd:Placeholder book.svg|250px|link="
s = s .. fileTitle.prefixedText .. "|class=ws-cover ws-index-cover]]"
CATS:addCat("Indexes with missing files")
return s
end
-- File exists and we have page number for the cover
s = s .. "[[" .. fileTitle.prefixedText .. "|250px"
s = s .. "|page=" .. tonumber(args['Image']) .. "|class=ws-cover ws-index-cover]]"
return s
end
-- Get the pagelist provided by PRP
--
-- PRP furnished a finished rendered pagelist, so we just need to wrap it in a
-- suitable container, add a legend, etc.
local function __getPagelist(args)
-- Main container
local plcontainer = mw.html.create("div")
plcontainer
:addClass("ws-index-pagelist-container")
:addClass("mw-collapsible") -- make it collapsible
:tag("div") -- The heading/legend
:addClass("ws-index-pagelist-heading")
:wikitext("Pages")
:wikitext(" ") -- Force a space between heading and legend.
:tag("span")
:addClass("ws-index-pagelist-heading-legend")
:wikitext("(lykill að [[:en:Help:Page status|síðustöðu]])")
:done()
:done()
:tag("div") -- The pagelist itself
:addClass("ws-index-pagelist")
:addClass("index-pagelist") -- legacy support
:addClass("mw-collapsible-content") -- make it collapsible
:wikitext('\n' .. mw.text.trim(args["Pages"]) .. '\n')
return tostring(plcontainer)
end
-- Get the metadata fields.
local function __getMetadata(frame, args)
-- set any defaults
for key, _ in pairs(cfg.defaults) do
if args[key] == nil then
args[key] = cfg.defaults[key]
end
end
local s = ""
-- Construct the Title field (includes Vol. after Title if present)
local title = args['Title'] or ""
if args['Volume'] ~= nil and args['Volume'] ~= "" then
title = title .. ", " .. args['Volume']
end
s = s .. __makeRow('title', title)
s = s .. __makeRow('author', args['Author'])
s = s .. __makeRow('translator', args['Translator'])
s = s .. __makeRow('editor', args['Editor'])
s = s .. __makeRow('illustrator', args['Illustrator'])
s = s .. __makeRow('year', args['Year'])
s = s .. __makeRow('publisher', args['Publisher'])
s = s .. __makeRow('place', args['Address'])
local location = args["Source"]
local file = mw.title.new(mw.title.getCurrentTitle().text, 'File')
if file.exists then
location = "[[:" .. file.fullText .. "|" .. args["Source"] .. "]]"
end
s = s .. __makeRow('source', location)
local status = cfg.status[args['Progress']] or cfg.status['_default']
CATS:addCat(status.cat) -- Add this index to that cat
local linktext = mw.html.create('span'):wikitext(status.txt)
if status.error then
linktext:addClass('error')
end
local statuslink = CATS:makeCatLink(status.cat, tostring(linktext))
s = s .. __makeRow('progress', statuslink)
local transclusion = cfg.transclusion[args["Transclusion"] or "no"] -- always do this, even if the arg is not set
CATS:addCat(transclusion.cat)
local transclusionlink = CATS:makeCatLink(transclusion.cat, transclusion.txt)
s = s .. __makeRow("transclusion", transclusionlink)
if args["Validation_date"] then
local valcat = 'Frumrit staðfestar í ' .. args["Validation_date"]
local valtxt = 'Staðfest í ' .. args["Validation_date"]
CATS:addCat(valcat)
local valcatlink = CATS:makeCatLink(valcat, args["Validation_date"])
s = s .. __makeRow("validation_date", valcatlink)
s = s .. frame:extensionTag{ -- FIXME: need the frame here!
name = "indicator",
content = '[[Mynd:Yes Check Circle.svg|15px|link=Flokkur:' .. valcat .. '|' .. valtxt .. '|alt=Staðfest frumritssíða.]]',
args = {
name = "validated-index-date"
}
}
end
if args["OCLC"] then
local link = construct_link(url_gens['oclc'](args["OCLC"]), args['OCLC'])
s = s .. __makeRow("oclc", link)
end
if args["DOI"] then
local link = construct_link(url_gens['doi'](args["DOI"]), args['DOI'])
s = s .. __makeRow("doi", link)
end
s = s .. __makeRow('volumes', args['Volumes'])
-- language categorisations
if args["Language"] then
local langs = mw.text.split(args["Language"], ',%s?', false)
for _, lang in pairs(langs) do
local langcat = "Frumritssíður verka upprunalega á "
langcat = langcat .. ISO_639.language_name(lang) or "óþekktu tungumáli"
CATS:addCat(langcat)
end
if #langs > 1 then
CATS:addCat('Frumritssíður verka upprunalega á mörgum tungumálum')
end
end
local metadatatable = mw.html.create("table")
:addClass("ws-index-metadata")
:wikitext(s)
return tostring(metadatatable)
end
local function __main(frame)
local args = getArgs(frame)
local s = "" -- Where we collect all the bits and bobs to return
-- The overall html structure in which each component is inserted
local indexcontainer = mw.html.create("div")
:addClass("ws-index-container")
if tonumber(args["tmplver"]) == 42 then
indexcontainer:addClass("ws-tng") -- Tag for "TNG" mode i asked for.
end
-- Get the indicators (NB! Needs access to the frame!)
s = s .. __getIndicators(frame)
-- Get talk page notice if present (NB! Needs access to the frame!)
s = s .. __getTalkNotice(frame)
-- Get the image to use as the cover image for this index
local cover = __getCoverImage(args)
indexcontainer:tag("div")
:addClass("ws-index-cover-container")
:wikitext(cover)
-- Get metadata table (NB! Needs access to the frame!)
local metadata = __getMetadata(frame, args)
indexcontainer:tag("div")
:addClass("ws-index-metadata-container")
:wikitext(metadata)
-- Get the pagelist for the index
local pagelist = __getPagelist(args)
indexcontainer:wikitext(pagelist)
-- Add the remarks field (toc)
local remarks = indexcontainer:tag("div")
:addClass("ws-index-remarks-container")
if args['Remarks'] == nil or args['Remarks'] == "" then
remarks:addClass("ws-index-remarks-empty")
end
remarks:wikitext(args['Remarks'])
-- Return the HTML structure and the accumulated categories.
return tostring(indexcontainer) .. CATS:getCats()
end
function p.main(frame)
local args = getArgs(frame)
local s = "" -- Where we collect all the bits and bobs to return
if args["tmplver"] ~= nil and args["tmplver"] ~= "" then
return __main(frame)
end
-- First, the talk remarks notes (nb! needs frame object!)
s = s .. _talkremarks(frame)
-- Then the indicators (nb! needs frame object!)
s = s .. _indicators(frame)
-- Construct the table
local outertable = mw.html.create("table")
outertable:attr("id", "ws-index-container")
local outertr = outertable:tag("tr")
local maincell = outertr:tag("td")
maincell:attr("id", "ws-index-main-cell")
local maintable = maincell:tag("table")
maintable:attr("id", "ws-index-main-table")
local firstrow = maintable:tag("tr")
local maincell = firstrow:tag("td")
local coverdiv = maincell:tag("div")
coverdiv:attr("id", "ws-index-cover-container")
coverdiv:wikitext(p.cover(frame))
maincell:wikitext(p.metadata(frame))
local secondrow = maintable:tag("tr")
local plcell = secondrow:tag("td")
local pldiv = plcell:tag("div")
pldiv:attr("id", "ws-index-pagelist-container")
pldiv:addClass("mw-collapsible")
pldiv:wikitext('<em>Síður</em> <span id="ws-index-pagelist-legend">(lykill að [[:en:Help:Page status{{!}}síðustöðu]])</span>')
local plinner = pldiv:tag("div")
plinner:attr("id", "ws-index-pagelist")
plinner:addClass("index-pagelist mw-collapsible-content")
plinner:wikitext('\n' .. mw.text.trim(args["Pages"]) .. '\n')
outertr:wikitext(p.remarks(frame))
s = s .. tostring(outertable)
s = s .. p.sortkey(frame)
return s
end
return p