Modul:Proofreadpage index template
Aspect

![]() | Acest format utilizează Lua: |
![]() | Acest modul utilizează TemplateStyles: |
Acesta este un modul care implementează logica pentru MediaWiki:Proofreadpage index template
--[=[
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('Modul:Arguments').getArgs
local messageBox = require('Modul:Message box')
local ISO_639 = require('Modul:ISO 639')
local p = {} --p stands for package
local DEFAULTS = {
Source = '_empty_',
}
-- mapping of field ID to field properties
local headings = {
title = {
txt = 'Titlu',
},
progress = {
txt = 'Progres',
},
oclc = {
txt = 'OCLC',
},
transclusion = {
txt = 'Transcludere',
},
validation_date = {
txt = 'Validat pe',
},
source = {
txt = 'Sursă'
},
place = {
txt = 'Loc'
},
year = {
txt = 'An'
},
publisher = {
txt = 'Editură'
},
author = {
txt = 'Autor'
},
editor = {
txt = 'Editor'
},
translator = {
txt = 'Traducător'
},
illustrator = {
txt = 'Ilustrator'
},
doi = {
txt = 'DOI'
},
volumes = {
txt = 'Volume'
},
rules = {
txt = 'Reguli de editare'
}
}
local indicators = {
pagegame = {
name = "WS Page Game",
image = "File:OOjs UI icon page number.svg",
link = "{{fullurl:toolforge:ws-page-game|wikisource=ro&index={{PAGENAMEE}}&lang=ro}}",
caption = "Wikisource Page Game (construiește o listă de numere de pagini pas cu pas)"
},
purge = {
name = "purge file",
image = "File:OOjs UI icon reload.svg",
link = "{{fullurl:commons:File:{{PAGENAME}}|action=purge}}",
caption = "Curățați cache-ul fișierului"
},
book2scroll = {
name = "book2scroll",
image = "File:Library-logo-blue-outline.png",
link = "{{fullurl:toolforge:book2scroll|lang=en&file={{PAGENAMEE}}}}",
caption = "Deschideți în Book2Scroll"
},
bookreader = {
name = "bookreader",
image = "File:BookReader-favicon.svg",
link = "{{fullurl:toolforge:bookreader/ro/{{PAGENAMEE}}}}",
caption = "Deschide fișierul în BookReader"
},
}
local function get_heading(id)
if headings[id] then
return headings[id]['txt']
end
error( "Nu se poate obține denumirea pentru ID: " .. id )
end
-- mapping from status code to category and status text
local index_status_data = {
T = {
cat = 'Index validat',
txt = 'Terminat—Toate paginile lucrării propriu-zise sunt validate',
},
V = {
cat = 'Index verificat',
txt = 'Verificat—Toate paginile lucrării propriu-zise sunt verificate, dar nu toate sunt validate',
},
C = {
cat = 'Index neverificat',
txt = 'Trebuie să fie verificat',
},
MS = {
cat = 'Index - gata pentru transcludere',
txt = 'Pregătit pentru transcludere',
},
OCR = {
cat = 'Index - strat text solicitat',
txt = 'Fișierul sursă are nevoie de un strat de text OCR',
},
L = {
cat = 'Index - fișier de reparat',
txt = 'Fișierul sursă trebuie reparat înainte de transcriere',
error = true,
},
X = {
cat = 'Index - fișier de verificat',
txt = 'Creați o listă de pagini pentru fișierul sursă înainte de a începe transcrierea (pentru a verifica că fișierul este corect)',
error = true
},
_default = {
cat = 'Index - progres necunoscut',
txt = 'Progres necunoscut (eroare de format)',
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 .. '[[Categorie:' .. sd['cat'] .. ']]'
local link_text = tostring(maybe_error_span(sd['txt'], sd['error']))
local catlink = '[[:Categorie:' .. sd['cat'] .. '|' .. link_text .. ']]'
out = out .. construct_field("progress", catlink)
return out
end
local transclusion_data = {
yes = {
cat = 'Complet transclus',
text = 'Complet transclus',
help = 'Lucrarea este complet transclusă, inclusiv prima și ultima pagină și imagini'
},
notimg = {
cat = 'Imaginile nu au fost complet transcluse',
text = 'Imaginile nu au fost complet transcluse',
help = 'Lucrarea este complet transclusă, dar unele imagini lipsesc încă sau trebuie îmbunătățite',
},
notadv = {
cat = 'Reclamele nu au fost transcluse',
text = 'Reclamele nu au fost transcluse',
help = 'Corpul principal al operei este transclus în mod corespunzător, dar materialul publicitar de pe primele sau ultimele pagini nu'
},
held = {
cat = 'Transcludere pe pauză',
text = 'Transcludere pe pauză',
help = 'Există o problemă cu transcluderea lucrării (care ar trebui explicată pe pagina de discuție)'
},
check = {
cat = 'Transcluderea trebuie verificată',
text = 'Transcluderea trebuie verificată',
help = ' Transcluderea lucrării este incompletă sau necesită verificare'
},
no = {
cat = 'Indexul nu a fost transclus',
text = 'Indexul nu a fost transclus sau revizuit',
help = ' Această lucrare nu este transclusă sau nu a fost revizuită pentru transcludere'
}
}
local function construct_cat(cat)
return "[[Categorie:" .. 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("Stare a indexului necunoscută: " .. status)
end
local catlink = '[[:Categorie:' .. 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 = 'Indexuri validate pe ' .. date
local indicator_text = 'Validat pe ' .. date
local out = '[[Categorie:' .. cat .. ']]'
local catlink = '[[:Categorie:' .. cat .. '|' .. date .. ']]'
out = out .. construct_field("validation_date", catlink)
out = out .. '<indicator name="validated-index-date">[[File:Yes Check Circle.svg|15px|link=Categorie:' .. cat .. '|' .. indicator_text .. '|alt=Pagină de index validată.]]</indicator>'
return out
end
local function getLanguageCat(l)
-- get the name or nil
local lang = ISO_639.language_name(l)
if lang then
return "Pagini de index ale lucrărilor în original în " .. 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['TITLU'], args['VOLUM'])
s = s .. construct_field('author', args['AUTOR'])
s = s .. construct_field('translator', args['TRADUCĂTOR'])
s = s .. construct_field('editor', args['EDITOR'])
s = s .. construct_field('illustrator', args['ILUSTRATOR'])
s = s .. construct_field('year', args['AN'])
s = s .. construct_field('publisher', args['EDITURĂ'])
s = s .. construct_field('rules', args['RE'])
s = s .. construct_location_field(args['LOC'])
s = s .. construct_source_field(args['SURSĂ'])
s = s .. construct_status_field(args['PROGRES'])
-- always do this, even if the arg is not set
s = s .. construct_transclusion_status(args["TRANSCLUDERE"], args['DATA_TRANSCLUDERII'])
if args["DATA_VALIDĂRII"] then
s = s .. construct_validated_date(args["DATA_VALIDĂRII"])
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['VOLUME'])
-- language categorisations
if args["LIMBĂ"] then
local langs = mw.text.split( args["LIMBĂ"], ',%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('Pagini de index ale lucrărilor traduse dintr-o limbă necunoscută')
end
end
if #langs > 1 then
s = s .. construct_cat('Pagini de index ale lucrărilor în mai multe limbi în original')
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, "Note rapide")
return frame:expandTemplate{
title = "Remarci discuție index",
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['IMAGINE'] == 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['IMAGINE']) == nil then
local s = ""
if mw.ustring.find(args['IMAGINE'], '^%[%[') ~= nil then
-- It's a full image specification
s = s .. args['IMAGINE']
else
-- Assume it's a filename with or without File: prefix
local file = mw.ustring.gsub(args['IMAGINE'], "^[Ff]ile:", "")
s = s .. "[[" .. "File:" .. file .. "|250px|class=ws-cover]]"
end
-- Add a tracking category
s = s .. "[[" .. "Categorie:Indexuri bazate pe imagini" .. "]]"
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 = "[[File:Placeholder book-ro.svg|250px|link="
s = s .. fileTitle.prefixedText .. "|class=ws-cover]]"
s = s .. "[[" .. "Categorie:Indexuri cu fișiere lipsă" .. "]]"
return s
end
-- File exists and we have page number for the cover
local s = "[[" .. fileTitle.prefixedText .. "|250px"
s = s .. "|page=" .. tonumber(args['IMAGINE']) .. "|class=ws-cover]]"
return s
end
function p.remarks(frame)
local args = getArgs(frame)
if args['REMARCI'] ~= nil and args['REMARCI'] ~= "" then
return '<td id="ws-index-remarks">' .. args['REMARCI'] .. '</td>'
else
return '<td id="ws-index-remarks-empty"></td>'
end
end
function p.sortkey(frame)
local args = getArgs(frame)
local sortkey = ""
if args['CHEIE'] ~= nil and args['CHEIE'] ~= "" then
sortkey = args['CHEIE']
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("Modul: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 .. "[[" .. "Categorie:" .. cat .. "]]"
end
return cats
end
function CATS:makeCatLink(cat, label)
if label ~= nil and label ~= "" then
return "[[:" .. "Categorie:" .. cat .. "|" .. label .. "]]"
end
return "[[:" .. "Categorie:" .. 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">[[File: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('Modul: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, "Note rapide")
local s = "Reguli de formatare specifice acestei lucrări pot să "
s = s .. "fi fost deja stabilite. Verificați "
s = s .. "[[" .. talkText .. "|pagina de discuție]] pentru detalii."
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['IMAGINE']) == nil then
if mw.ustring.find(args['IMAGINE'], '^%[%[') ~= nil then
s = s .. args['IMAGINE'] -- It's a full image specification
else
-- Assume it's a filename with or without File: prefix
local file = mw.ustring.gsub(args['IMAGINE'], "^[Ff]ile:", "")
s = s .. "[[" .. "File:" .. file .. "|250px|class=ws-cover ws-index-cover]]"
end
-- Add a tracking category
CATS:addCat("Indexuri bazate pe imagini")
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 .. "[[File:Placeholder book-ro.svg|250px|link="
s = s .. fileTitle.prefixedText .. "|class=ws-cover ws-index-cover]]"
CATS:addCat("Indexuri cu fișiere lipsă")
return s
end
-- File exists and we have page number for the cover
s = s .. "[[" .. fileTitle.prefixedText .. "|250px"
s = s .. "|page=" .. tonumber(args['IMAGINE']) .. "|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("Pagini")
:wikitext(" ") -- Force a space between heading and legend.
:tag("span")
:addClass("ws-index-pagelist-heading-legend")
:wikitext("(cheie către [[Ajutor:Starea paginilor|Starea paginilor]])")
: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["PAGINI"]) .. '\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['TITLU'] or ""
if args['VOLUM'] ~= nil and args['VOLUM'] ~= "" then
title = title .. ", " .. args['VOLUM']
end
s = s .. __makeRow('title', title)
s = s .. __makeRow('author', args['AUTOR'])
s = s .. __makeRow('translator', args['TRADUCĂTOR'])
s = s .. __makeRow('editor', args['EDITOR'])
s = s .. __makeRow('illustrator', args['ILUSTRATOR'])
s = s .. __makeRow('year', args['AN'])
s = s .. __makeRow('publisher', args['EDITURĂ'])
s = s .. __makeRow('place', args['LOC'])
local location = args["SURSĂ"]
local file = mw.title.new(mw.title.getCurrentTitle().text, 'File')
if file.exists then
location = "[[:" .. file.fullText .. "|" .. args["SURSĂ"] .. "]]"
end
s = s .. __makeRow('source', location)
local status = cfg.status[args['PROGRES']] 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["TRANSCLUDERE"] 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["DATA_VALIDĂRII"] then
local valcat = 'Indexuri validate pe ' .. args["DATA_VALIDĂRII"]
local valtxt = 'Validat pe ' .. args["DATA_VALIDĂRII"]
CATS:addCat(valcat)
local valcatlink = CATS:makeCatLink(valcat, args["DATA_VALIDĂRII"])
s = s .. __makeRow("validation_date", valcatlink)
s = s .. frame:extensionTag{ -- FIXME: need the frame here!
name = "indicator",
content = '[[File:Yes Check Circle.svg|15px|link=Categorie:' .. valcat .. '|' .. valtxt .. '|alt=Validated index page.]]',
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['VOLUME'])
-- language categorisations
if args["LIMBĂ"] then
local langs = mw.text.split(args["LIMBĂ"], ',%s?', false)
for _, lang in pairs(langs) do
local langcat = "Pagini de index ale lucrărilor traduse din "
langcat = langcat .. ISO_639.language_name(lang) or "o limbă necunoscută"
CATS:addCat(langcat)
end
if #langs > 1 then
CATS:addCat('Pagini de index ale lucrărilor în mai multe limbi în original')
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['REMARCI'] == nil or args['REMARCI'] == "" then
remarks:addClass("ws-index-remarks-empty")
end
remarks:wikitext(args['REMARCI'])
-- 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>Pagini</em> <span id="ws-index-pagelist-legend">(cheie către [[Ajutor:Starea paginilor{{!}}Starea paginilor]])</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["PAGINI"] or '') .. '\n')
outertr:wikitext(p.remarks(frame))
s = s .. tostring(outertable)
s = s .. p.sortkey(frame)
return s
end
return p