Module:Proofreadpage index template/sandbox 2

require('strict')

--[=[ This is a module to implement logic for MediaWiki:Proofreadpage index template ]=]

local p = {} -- p stands for package

local getArgs = require('Module:Arguments').getArgs local messageBox = require('Module:Message box') local ISO_639 = require('Module:ISO 639') local tableTools = require('Module:TableTools') local construct_defaultsort = require('Module:Header/sort')._construct_defaultsort

local cfg = mw.loadData('Module:Proofreadpage index template/config/sandbox')

local current_title = mw.title.getCurrentTitle local current_frame = mw.getCurrentFrame

local function construct_cat(cat) return "" end

local function makeCatLink(cat, label) if label then return "" .. label .. "" else return "Category:" .. cat .. "" end end

local function indicator(content, args) return current_frame:extensionTag { name = 'indicator', content = content, args = args } end

-- construct a basic "field" row

local function construct_field(id, content) if not id or not content then return nil end -- mapping of field ID to field properties local row = mw.html.create('tr') :attr('id', 'ws-index-' .. id .. '-row') :addClass('ws-index-row') :tag('th') :attr('id', 'ws-index-' .. id .. '-label') :addClass('ws-index-label') :attr('scope', 'row') :wikitext(cfg['headings'][id]['txt'] or error('Can\'t find heading for ID: ' .. id)) :done :tag('td') :attr('id', 'ws-index-' .. id .. '-value') :addClass('ws-index-value') :wikitext(content) :allDone return row end

-- construct the title field (include volume after title if present)

local function construct_title_field(args) local content if args['Title'] and args['Volume'] then content = args['Title'] .. ', ' .. args['Volume'] else content = args['Title'] or args['Volume'] end return construct_field('title', content) end

-- construct the source field

local function construct_source_field(args) args['Source'] = args['Source'] or error('No source') local value local file = mw.title.new(current_title.text, 'File') if file.file.exists then -- if a file exists, link it value =  .. args['Source'] ..  else -- otherwise just show the text value = args['Source'] end return construct_field('source', value) end

-- construct the status (proofread/validated/etc.) field

local function construct_status_field(args) -- mapping from status code to category and status text local sd = cfg['status'][args['Progress']] -- construct a span which might be classed "error" local progress_text = mw.html.create('span'):wikitext(sd['txt']) if sd['error'] then progress_text:addClass('error') end return construct_cat(sd['cat']) .. construct_field('progress', makeCatLink(sd['cat'], tostring(progress_text))) end

-- construct the transclusion status field

local function construct_transclusion_status(args) local td = cfg['transclusion'][args['Transclusion']] or error('Unknown index status: ' .. args['Transclusion']) return construct_field('transclusion', makeCatLink(td['cat'], td['txt'])) .. construct_cat(td['cat']) end

-- construct the validation field

local function construct_validated_date(args) if not args['Validation_date'] then return nil end local cat = 'Indexes validated in ' .. args['Validation_date'] return construct_cat(cat) .. construct_field('validation_date', makeCatLink(cat, args['Validation_date'])) .. indicator('', {name = 'validated-index-date'}) end

-- construct external link fields

local function construct_url_gen(args, linktype) if not args[linktype] then return nil end return construct_field(linktype, '[' .. cfg["url_prefixes"][linktype] .. mw.uri.encode(args[linktype]) .. ' ' .. args[linktype] .. ']') end

-- construct language categories

local function construct_language_cat(args) if not args['Language'] then return nil end local langs = mw.text.split(args['Language'], ',%s?', false) local cats = {} for _, lang in pairs(langs) do table.insert(cats, construct_cat('Index pages of works originally in ' .. (ISO_639.language_name(lang) or 'an unknown language'))) end if #langs > 1 then table.insert(cats, construct_cat('Index pages of works originally in multiple languages')) end return table.concat(cats) end

-- get the metadata fields.

local function _fields(args) local field_list = { construct_title_field(args), construct_field('author', args['Author']), construct_field('translator', args['Translator']), construct_field('editor', args['Editor']), construct_field('illustrator', args['Illustrator']), construct_field('year', args['Year']), construct_field('publisher', args['Publisher']), construct_field('place', args['Address']), construct_source_field(args), construct_status_field(args), construct_transclusion_status(args), construct_validated_date(args), construct_url_gen(args, 'OCLC'), construct_url_gen(args, 'DOI'), construct_field('volumes', args['Volumes']), construct_language_cat(args) }	field_list = tableTools.compressSparseArray(field_list) return field_list end

function p.fields(frame) return table.concat(_fields(getArgs(frame))) end

-- construct wrapper for fields

local function _metadata(args) local metadatatable = mw.html.create('table') :attr('id', 'ws-index-metadata') :addClass('ws-index-metadata') local fields = _fields(args) for i = 1, #fields do		if type(fields[i]) == 'string' then metadatatable:wikitext(fields[i]) else metadatatable:node(fields[i]) end end return metadatatable end

function p.metadata(frame) return _metadata(getArgs(frame)) end

-- talk page message box

local function _talkremarks local talkTitle = current_title.talkPageTitle local talkText = talkTitle.prefixedText -- if talk page exists, show message box -- if "Quick notes" section exists, transclude it	if talkTitle.exists then return messageBox.main(			'ombox',			{				type = 'content',		   	text = 'Formatting guidelines specific to this work may have already been established. Please check the talk page for details.'		    		.. current_frame:callParserFunction('#lsth', talkText, 'Quick notes')			}		) end return '' end

function p.talkremarks return _talkremarks end

-- indicators

local function _indicators local indicator_list = {} for k, v in pairs(cfg['indicators']) do		table.insert(			indicator_list,			indicator(mw.ustring.format('20px|link=%s|%s', v.image, v.link, v.caption), {name = v.name})		) end return table.concat(indicator_list) end

function p.indicators return _indicators end

-- cover image

local function _cover(args) -- workaround for pagelist preview that tries to parse this template -- without any context and with missing parameters via the API if not args['Image'] then return '' end local function cover_file_link(file, attrs) return '250px|class=ws-cover ws-index-cover' .. (attrs or ) ..  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 not tonumber(args['Image']) then local imglink if mw.ustring.find(args['Image'], '^%[%[') then -- assume it's a full image specification imglink = args['Image'] else -- assume it's a filename with or without File: prefix local file = mw.ustring.gsub(args['Image'], '^[Ff]ile:', '') imglink = cover_file_link('File:' .. file) end return imglink .. construct_cat('Image based indexes') end -- otherwise it's a DjVu/PDF-backed index -- so we fetch the cover image from a page in the (multipage) file local fileTitle = mw.title.makeTitle('File', current_title.text) if not fileTitle.file.exists then -- our associated file doesn't exist so we use a placeholder return cover_file_link('File:Placeholder book.svg', '|link=' .. fileTitle.prefixedText) .. construct_cat('Indexes with missing files') end -- file exists and we have a page number for the cover return cover_file_link(fileTitle.prefixedText, '|page=' .. tonumber(args['Image'])) end

function p.cover(frame) return _cover(getArgs(frame)) end

-- remarks

local function _remarks(args) if args['Remarks'] then -- TODO -- return mw.html.create('div'):addClass('ws-index-remarks ws-index-remarks-container'):wikitext(args['Remarks']) return mw.html.create('td'):attr('id', 'ws-index-remarks'):wikitext(args['Remarks']) else -- TODO -- return mw.html.create('div'):addClass('ws-index-remarks ws-index-remarks-container ws-index-remarks-empty') return mw.html.create('td'):attr('id', 'ws-index-remarks-empty') end end

function p.remarks(frame) return _remarks(getArgs(frame)) end

-- sortkey

local function _sortkey(args) args.sortkey = args['Key'] or args.sortkey return construct_defaultsort(args) end

function p.sortkey(frame) return _sortkey(getArgs(frame)) end

-- get the pagelist provided by PRP -- PRP furnishes a finished rendered pagelist -- so we just need to wrap it in a suitable container, add a legend, etc.

local function _pagelist(args) -- main container local plcontainer = mw.html.create("div") :attr("id", "ws-index-pagelist-container") -- make it collapsible -- :addClass("ws-index-pagelist-container") TODO :addClass("mw-collapsible") -- the heading/legend :tag("div") :tag("i"):wikitext("Pages"):done --[=[ TODO :addClass("ws-index-pagelist-heading") :wikitext("Pages") ]=]			:wikitext(" ") -- Force a space between heading and legend. :tag("span") :attr("id", "ws-index-pagelist-legend") -- :addClass("ws-index-pagelist-heading-legend") TODO :wikitext("(key to Page Status)") :done :done :tag("div") -- the pagelist itself :attr("id", "ws-index-pagelist") -- :addClass("ws-index-pagelist") TODO :addClass("index-pagelist") -- legacy support :addClass("mw-collapsible-content") -- make it collapsible :wikitext('\n' .. mw.text.trim(args['Pages']) .. '\n') :allDone return plcontainer end

-- assemble the overall structure function p.main(frame) local args = getArgs(frame) -- set defaults for k, v in pairs(cfg['defaults']) do		if args[k] == nil then args[k] = v		end end -- the overall html structure into which each component is inserted local indexcontainer = mw.html.create('table') :attr('id', 'ws-index-container') :tag('tr') :tag('td') :attr('id', 'ws-index-main-cell') :tag('table') :attr('id', 'ws-index-main-table') :tag('tr') -- first row :tag('td') -- get the image to use as the cover image for this index :tag('div') :attr('id', 'ws-index-cover-container') :wikitext(_cover(args)) :done -- get metadata table :node(_metadata(args)) :done :done :tag('tr') -- second row :tag('td') -- get pagelist :node(_pagelist(args)) :done :done :done :done -- get remarks :node(_remarks(args)) :allDone --[=[ TODO local indexcontainer = mw.html.create('div') :addClass('ws-index-container') :tag('div') :addClass('ws-index-cover-container') :wikitext(_cover(args)) :done :tag('div') :addClass('ws-index-metadata-container') :node(_metadata(args)) :done :node(_pagelist(args)) :node(_remarks(args)) :allDone ]=]	-- return the HTML structure and the accumulated categories return _indicators .. _talkremarks .. tostring(indexcontainer) .. _sortkey(args) end

return p