Module:Header: Difference between revisions

Content deleted Content added
mNo edit summary
add option to require a language (use for translations)
(52 intermediate revisions by 3 users not shown)
Line 13:
local yesno = require('Module:Yesno')
local getArgs = require('Module:Arguments').getArgs
 
local headerStructure = require('Module:Header structure')
local construct_header = headerStructure.construct_header
local get_noexport_stylesheet = headerStructure.get_noexport_stylesheet
 
local tableTools = require('Module:TableTools')
 
local ISO_639_language_name = require('Module:ISO 639').language_name
local parent_links = require('Module:Auto parents')._parent_links
 
local construct_header = require('Module:Header structure').construct_header
local headerAttributions = require('Module:Header/attribution')
local construct_defaultsort = require('Module:Header/sort')._construct_defaultsort
local construct_year = require('Module:Header/year').construct_year
 
local current_title = mw.title.getCurrentTitle()
 
--[=[
-- get the param_override or param parameter in that order
Wrap stylesheet in noexport div
-- nil if neither is there
]=]
local function get_arg_or_override(args, param)
local function get_noexport_stylesheet(template)
if args["override_" .. param] then
return tostring(mw.html.create('div'):addClass('ws-noexport'):wikitext(mw.getCurrentFrame():extensionTag('templatestyles', '', {src = template .. '/styles.css'})))
return args["override_" .. param]
elseif args[param] then
return args[param]
end
return nil
end
 
Line 60 ⟶ 54:
-- override to show the microformat
if yesno(args['show_microformatshow-microformat']) then
mf_div:addClass('ws-data-show')
end
Line 79 ⟶ 73:
end
local author = args['override-section-author'] or args['section-author'] or args['override-author'] or args['author']
local author = get_arg_or_override(args, 'section_author')
if not author then
author = get_arg_or_override(args, 'author')
end
if author then
mf['ws-author'] = author
end
local translator = get_arg_or_override(args,['override-translator'] or args['translator')]
if translator then
mf['ws-translator'] = translator
end
local year = get_arg_or_override(args, ['year')]
if year then
mf['ws-year'] = year
Line 117 ⟶ 108:
end
 
local function check_non_existent_author_pages(args, paramcategories, categoriescheckArgs)
-- check for cases that aren't supposed to produce a valid link
if args[param] then
-- some pages expect an invalid author
local specialparam = falsecheckArgs.param
local tracking_cat = checkArgs.tracking_cat or 'Works with non-existent author pages'
local lower_arg = string.lower(args[param])
if lower_arg == "unknown" or lower_arg == "not mentioned" then
if not param or not args[param] or yesno(args[param .. '-nolink']) then
special = true
endreturn
if not special then
local target = mw.title.makeTitle("Author", args[param])
-- expensive function!
if not target or not target.exists then
table.insert(categories, "Works with non-existent author pages")
end
end
end
local lower_arg = string.lower(args[param])
local attr_data = headerAttributions.attr_data[param] or headerAttributions.attr_data[string.gsub(param, 'section%-', '')]
if attr_data and attr_data['special_cases'] and attr_data['special_cases'][lower_arg] then
return
end
-- check if page exists
local target = mw.title.makeTitle('Author', args[param])
-- expensive function!
if not target or not target.exists then
table.insert(categories, tracking_cat)
end
return
end
 
Line 142 ⟶ 140:
local categories = {}
if args["override_author"'override-author'] then
table.insert(categories, "Pages with override author")
end
if current_title:inNamespaces(0, 114)args['override-translator'] then
table.insert(categories, "Pages with override translator")
check_non_existent_author_pages(args, 'author', categories)
end
check_non_existent_author_pages(args, 'editor', categories)
check_non_existent_author_pages(args, 'translator', categories)
if current_title:inNamespaces(0, 114) or args.testing then
check_non_existent_author_pages(args, 'section_translator', categories)
local params_to_check = {
check_non_existent_author_pages(args, 'section_author', categories)
{param = 'author'},
{param = 'editor'},
{param = 'translator'},
{param = 'composer', tracking_cat = 'Works with non-existent composer pages'},
{param = 'illustrator', tracking_cat = 'Works with non-existent illustrator pages'}
}
for k, v in pairs(params_to_check) do
check_non_existent_author_pages(args, categories, v)
check_non_existent_author_pages(args, categories, {param = 'section-' .. v.param, tracking_cat = v.tracking_cat})
end
end
if args['section_authorsection-author'] then
table.insert(categories, 'Pages with contributor')
end
if args['override_section_authoroverride-section-author'] then
table.insert(categories, 'Pages with override contributor')
end
local author = get_arg_or_override(args,['override-author'] "or args['author")']
if author and (string.lower(author) == "'unknown"') and not args['nocat'] then
if args.template_name == 'Translation header' then
table.insert(categories, 'Translations of anonymous works')
Line 170 ⟶ 178:
end
local editor = get_arg_or_override(args,['override-editor'] "or args['editor")']
if editor and not args['nocat'] then
editor = string.lower(editor)
if editor == "'unknown"' or editor == "'?"' then
table.insert(categories, "Works with unknown editors")
elseif editor == "'not mentioned"' then
table.insert(categories, "Works with unmentioned editors")
end
end
local translator = get_arg_or_override(args,['override-translator'] "or args['translator")']
if translator and not args['nocat'] then
translator = string.lower(translator)
if translator == "'unknown"' or translator == "'not mentioned"' or translator == "'?"' then
table.insert(categories, "'Translations without translator information specified"')
end
end
Line 190 ⟶ 198:
if args["shortcut"] then
if current_title:inNamespaces(0) then
table.insert(categories, "'Mainspace pages with shortcuts"')
elseif current_title:inNamespaces(114) then
table.insert(categories, 'Translation namespace pages with shortcuts')
Line 196 ⟶ 204:
end
if args["override_year"'noyear'] then
table.insert(categories, "Pages with override year")
end
if args["noyear"] then
table.insert(categories, "Pages with noyear")
end
if yesno(args["'noyearcat"']) then
table.insert(categories, "Pages with noyearcat")
end
if args["'cover"'] then
table.insert(categories, "Pages with an export cover")
end
Line 214 ⟶ 219:
-- allow_explicit_formatting parameter suppresses this check
-- used by, for example, [[Template:Versions]]
if not yesno(args['allow_explicit_formattingallow-explicit-formatting']) then
if args['title'] and explicit_formatting(args['title']) then
table.insert(categories, "Pages with explicit formatting in header fields")
Line 224 ⟶ 229:
-- translation header categories
local isMainPage = ((current_title:inNamespaces(0, 114) and not current_title.isSubpage) or args['testing'])
if args.template_name == 'Translation header' then
if args.template_name == 'Translation header' and isMainPage then
if args.language then
if not args['nocat'] then
table.insert(categories, 'Works originally in ' .. (args.language_name or 'an undefined language'))
if args.language then
else
table.insert(categories, 'Wikisource translations withof noworks originalin ' .. (args.language_name or 'an undefined language'))
else
table.insert(categories, 'Wikisource translations with no original language')
end
end
Line 234 ⟶ 242:
table.insert(categories, 'Wikisource translations with no original source')
end
elseif not args['nocat'] and isMainPage then
if not current_titleargs.isSubpagelanguage then
table.insert(categories, 'WikisourceWorks translationsoriginally in ' .. (args.language_name or 'an undefined language'))
elseif args['language-required'] then
table.insert(categories, 'Translations with no original language')
end
end
Line 242 ⟶ 252:
-- detect inappropriate template use
--[=[
if (args.template_name['template-name'] ~= 'Translation header' and translator and string.lower(translator) == 'wikisource')
or (current_title:inNamespaces(114) and args.template_name['template-name'] ~= 'Translation header') then
-- tracking category for pages that should be using translation header?
end
if current_title:inNamespaces(0) and args.template_name['template-name'] == 'Translation header' then
-- tracking category for translation header in mainspace?
end
Line 256 ⟶ 266:
end
return table.concat(category_links)
end
 
--[=[
Check for numerical parameters (which shouldn't be used)
]=]
local function check_for_numerical_arguments(args)
for k, v in pairs(args) do
if type(k) == 'number' then
return '[[Category:' .. 'Headers with numerical arguments' .. ']]'
end
end
return ''
end
 
Line 294 ⟶ 316:
 
--[=[
Assemble the title
Generate a {{DEFAULTSORT}} magic word according to the defaultsort parameter
]=]
local function construct_defaultsortheader_title(args)
local defsortKeytitle = args.title or ''
local titleSpan = tostring(mw.html.create('span'):attr('id', 'header-title-text'):wikitext(title))
local title = current_title.text
local year = construct_year(args)
if args.defaultsort then
local attr = headerAttributions.construct_attributions(args)
defsortKey = args.defaultsort or args.sortkey
local section = headerAttributions.construct_section(args)
else
-- construct defaultsort automatically by stripping A/An/The as needed
local title_table = mw.text.split(title, '/')
local sorted_title
local sorted_title_table = {}
local articles = {'A', 'An', 'The'}
for k, part in pairs(title_table) do
local sorted_part = part
local disambig = string.match(sorted_part, ' %(.*%)$')
if disambig then
sorted_part = string.gsub(sorted_part, ' %(.*%)$', '')
else
disambig = ''
end
for j, article in pairs(articles) do
if string.len(sorted_part) > string.len(article) and string.sub(sorted_part, 1, string.len(article) + 1) == (article .. ' ') then
sorted_part = string.sub(sorted_part, string.len(article) + 2) .. ', ' .. article .. disambig
break
end
end
table.insert(sorted_title_table, sorted_part .. disambig)
end
defsortKey = table.concat(sorted_title_table, '/')
if defsortKey == title then
defsortKey = nil
end
end
if attr ~= '' and title ~= '' then
-- if a suitable key is found or constructed, apply it
attr = '<br id=\"header-title=break\" />' .. attr
if defsortKey == title then
return '[[Category:' .. 'Headers with DefaultSort equal to page title' .. ']]'
elseif defsortKey then
return mw.getCurrentFrame():callParserFunction('DEFAULTSORT', {defsortKey}) .. '[[Category:' .. 'Headers applying DefaultSort key' .. ']]'
end
return table.concat({titleSpan, year, attr, section})
-- otherwise, don't do anything and use the default
return ''
end
 
--[=[
[[Template:Header]]
Construct the year span
--]=]
function p._header(args, argsWithBlanks)
local function getYearFromTimestamp(timestamp)
argsWithBlanks = argsWithBlanks or args
-- example timestamps: +2016-10-05T00:00:00Z, -1752-00-00T00:00:00Z
local split = mw.text.split(timestamp, '-', true)
local year
local bce = ''
if split[1] == '' then
year = tonumber(split[2])
bce = ' BCE'
else
year = tonumber(split[1])
end
return {year = year, bce = bce}
end
 
local function formatYear(year, precision)
if precision == 7 then
local suffixes = {
[1] = 'st',
[2] = 'nd',
[3] = 'rd',
default = 'th'
}
local century = (year - year % 100)/100 + 1
return century .. (suffixes[century] or suffixes['default']) .. ' century'
elseif precision == 8 then
return year .. 's'
else
return year
end
end
 
local function getYearFromSingleStatement(statement, args)
local snak = statement.mainsnak
if not snak or not snak.datavalue or not snak.datavalue.value or not snak.datavalue.value.time then
return nil
end
-- aliases
if args['noprint'] and args['nocat'] then
local dup_cat = ''
return nil
local newArgs = {}
end
for k, v in pairs(args) do
local cats = {} -- tracking categories
local newkey = string.lower(string.gsub(string.gsub(tostring(k), '_', '-'), ' ', '-'))
if newkey ~= tostring(k) then
--[=[ Precision:
if argsWithBlanks[newkey] then
0 - billion years
dup_cat = '[[Category:' .. 'Pages using duplicate arguments in template calls' .. ']]'
1 - hundred million years,
2 - ten million years,
3 - million years,
4 - hundred thousand years,
5 - ten thousand years,
6 - millenia,
7 - centuries,
8 - decades,
9 - years,
10 - months,
11 - days
12 - hours
13 - minutes
14 - seconds
]=]
local precision = math.min(snak.datavalue.value.precision, 9)
local year
local circa = ''
local start_times = {}
local end_times = {}
local start_years = {}
local end_years = {}
local start_year
local end_year
if statement.qualifiers then
-- Check if date is approximate
-- P1480 = sourcing circumstances, Q5727902 = circa
if statement.qualifiers.P1480 then
for _, qualifier in pairs(statement.qualifiers.P1480) do
if qualifier.datavalue and qualifier.datavalue.value.id == 'Q5727902' then
precision = precision - 1
circa = 'c. '
break
end
end
if not args[newkey] then
end
newArgs[newkey] = newArgs[newkey] or v
-- P580 = start time
if statement.qualifiers.P580 then
for k, v in pairs(statement.qualifiers.P580) do
local startt = getYearFromSingleStatement({mainsnak = v}, {nocat = true, noprint = false, ['table'] = true})
if startt then
table.insert(start_times, startt)
end
end
for k, v in pairs(start_times) do
table.insert(start_years, v.year)
end
start_years = tableTools.removeDuplicates(start_years)
table.sort(start_years)
if #start_years > 1 then
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
end
start_year = start_years[1]
end
-- P582 = end time
if statement.qualifiers.P582 then
for k, v in pairs(statement.qualifiers.P582) do
local endt = getYearFromSingleStatement({mainsnak = v}, {nocat = true, noprint = false, ['table'] = true})
if endt then
table.insert(end_times, endt)
end
end
for k, v in pairs(end_times) do
table.insert(end_years, v.year)
end
end_years = tableTools.removeDuplicates(end_years)
table.sort(end_years)
if #end_years > 1 then
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
end
end_year = end_years[1]
end
end
for k, v in pairs(newArgs) do
args[k] = v
if precision < 9 then
argsWithBlanks[k] = v
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
end
newArgs = {}
if precision < 7 then
local aliases = {
if args['noprint'] then
['section-author'] = 'contributor',
year = ''
['section-translator'] = 'contributing%-translator'
else
}
year = string.gsub(string.gsub(mw.wikibase.formatValue(statement.mainsnak), '^<span>', ''), '</span>$', '')
for arg, alias in pairs(aliases) do
end
for k, v in pairs(args) do
return circa .. year .. table.concat(cats)
local newkey = string.gsub(k, alias, arg)
end
if newkey ~= tostring(k) then
if argsWithBlanks[newkey] then
local timestamp_info = getYearFromTimestamp(snak.datavalue.value.time)
dup_cat = '[[Category:' .. 'Pages using duplicate arguments in template calls' .. ']]'
year = timestamp_info.year
end
local bce = timestamp_info.bce
if not args[newkey] then
newArgs[newkey] = v
-- approximate year, precision 8: year - year % 10 for decade
end
-- approximate decade, precision 7: year - year % 100 for century
if circa ~= '' then
year = year - (year % math.pow(10, 9 - precision))
end
year = formatYear(year, precision)
if start_year and start_year ~= year then
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
end
local printed_year = circa .. year .. bce
if (start_year or end_year) and start_year ~= end_year then
printed_year = circa .. (start_year or '') .. '–' .. (end_year or '') .. bce
end
if start_year and end_year and start_year ~= end_year then
local start_decade = start_year - start_year % 10
local end_decade = end_year - end_year % 10
local start_century = start_year - start_year % 100
local end_century = end_year - end_year % 100
if start_decade == end_decade then
table.insert(cats, '[[Category:' .. start_decade .. 's' .. bce .. ' works' .. ']]')
elseif start_century == end_century then
table.insert(cats, '[[Category:' .. formatYear(end_year, 7) .. bce .. ' works' .. ']]')
end
else
table.insert(cats, '[[Category:' .. year .. bce .. ' works' .. ']]')
end
if args['noprint'] then
printed_year = ''
end
if not args['nocat'] then
cats = tableTools.removeDuplicates(cats)
printed_year = printed_year .. table.concat(cats)
end
if args['table'] then
return {year = year, printed_year = printed_year, circa = circa, bce = bce}
end
return printed_year
end
 
local function parse_wikidata_year_and_categorise(args)
-- Fetch entity object for Wikidata item connected to the current page
-- Let manually-specified Wikidata ID override if given and valid
if not (args.wikidata and mw.wikibase.isValidEntityId(args.wikidata)) then
args.wikidata = mw.wikibase.getEntityIdForCurrentPage()
end
local item = mw.wikibase.getEntity(args.wikidata)
if not item then
return nil
end
local statements = item:getBestStatements('P577') -- publication date
if #statements == 0 then
return nil
end
local years = {}
for _, statement in pairs(statements) do
local year = getYearFromSingleStatement(statement, args)
if year then
table.insert(years, year)
end
end
local cat = ''
years = tableTools.removeDuplicates(years)
if #years == 0 then
return nil
elseif #years > 1 and not args['nocat'] then
cat = '[[Category:' .. 'Works of uncertain date' .. ']]'
end
return table.concat(years, '/') .. cat
end
 
local function parse_year_and_categorise(args)
if args['override_year'] then
return args['override_year']
end
local year = args['year']
-- Use Wikidata if year param is empty
if not year then
return parse_wikidata_year_and_categorise(args)
end
local cats = {}
local bce = ''
local circa = ''
local ret = ''
-- Extract common era info to make it easier to process
if string.match(year, "BCE$") then
bce = ' BCE'
year = string.gsub(year, '%s*BCE', '')
-- Also tag it as a non-numeric year
table.insert(cats, '[[Category:' .. 'Works with non-numeric dates' .. ']]')
end
-- If the year provided is a plain year (all digits)
if tonumber(year) then
table.insert(cats, '[[Category:' .. year .. bce .. ' works]]')
if not args['noprint'] then
ret = year .. bce
end
if not args['nocat'] then
ret = ret .. table.concat(cats)
end
-- For simple years we're done.
return ret
end
-- Add tracking category for all non-numeric dates
table.insert(cats, '[[Category:' .. 'Works with non-numeric dates' .. ']]')
-- Explicitly tagged as being of unknown date
if year == '?' or string.lower(year) == 'unknown' then
table.insert(cats, '[[Category:' .. 'Works of unknown date' .. ']]')
if not args['noprint'] then
ret = 'unknown'
end
if not args['nocat'] then
ret = ret .. table.concat(cats)
end
-- For explicitly given unknown years we're done.
return ret
end
-- Now figure out a complex date
-- Year ranges
year = string.gsub(string.gsub(year, '%-', '–'), '—', '–')
-- Approximate years
-- Lua patterns can't do ^c(irca)?( |%.|/)* because they don't do alternation or apply quantifiers to groups
if string.match(year, '^circa') or string.match(year, '^c%s*%.') or string.match(year, '^c%s*/') then
circa = 'c. '
year = string.gsub(string.gsub(string.gsub(year, '^circa%s*', ''), '^c%s*%.%s*', ''), '^c%s*/%s*', '')
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
-- circa a specific year
if tonumber(year) then
year = tonumber(year)
local decade = (year - year % 10) .. 's'
table.insert(cats, '[[Category:' .. decade .. bce .. ' works]]')
if not args['noprint'] then
ret = circa .. year .. bce
end
if not args['nocat'] then
ret = ret .. table.concat(cats)
end
-- For approximate years with a known decade we're done
return ret
end
end
for k, v in pairs(newArgs) do
args[k] = v
-- Check if it looks like a decade
argsWithBlanks[k] = v
if string.match(year, '^%d*0s$') then
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
table.insert(cats, '[[Category:' .. year .. bce .. ' works]]')
-- For explicitly given decades we're done
if not args['noprint'] then
ret = circa .. year .. bce
end
if not args['nocat'] then
ret = ret .. table.concat(cats)
end
return ret
end
-- Or a centuryaliases
args.sortkey = args.defaultsort or args.sortkey
-- Lua patterns can't do '^%d*(st|nd|rd|th) century$'
if string.match(year, '^%d*st century$') or string.match(year, '^%d*nd century$') or string.match(year, '^%d*rd century$') or string.match(year, '^%d*th century$') then
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
table.insert(cats, '[[Category:' .. year .. bce .. ' works]]')
-- For explicitly given centuries we're done
if not args['noprint'] then
ret = circa .. year .. bce
end
if not args['nocat'] then
ret = ret .. table.concat(cats)
end
return ret
end
-- default values
-- Or a range of years
args.template_name = args.template_name or 'Header'
local start_year, end_year
if string.match(year, '^%d*–%d*$') then
start_year, end_year = string.match(year, '^(%d*)–(%d*)$')
elseif string.match(year, '^%d*/%d*$') then
start_year, end_year = string.match(year, '^(%d*)/(%d*)$')
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
end
args.testing = yesno(args.testing or current_title.fullText == 'Template:Header/testcases' or current_title.fullText == 'Template:Translation header/testcases')
if start_year or end_year then
start_year = tonumber(start_year)
end_year = tonumber(end_year)
if start_year and end_year and start_year == end_year and circa == '' then
table.insert(cats, '[[Category:' .. start_year .. bce .. ' works' .. ']]')
if not args['noprint'] then
ret = circa .. start_year .. bce
end
if not args['nocat'] then
ret = ret .. table.concat(cats)
end
return ret
elseif start_year and end_year then
local start_decade = start_year - start_year % 10
local end_decade = end_year - end_year % 10
local start_century = start_year - start_year % 100
local end_century = end_year - end_year % 100
if start_decade == end_decade then
table.insert(cats, '[[Category:' .. start_decade .. 's' .. bce .. ' works' .. ']]')
elseif start_century == end_century then
table.insert(cats, '[[Category:' .. formatYear(end_year, 7) .. bce .. ' works' .. ']]')
end
elseif end_year then
table.insert(cats, '[[Category:' .. 'Works of uncertain date' .. ']]')
end
-- check isn't redundant since the year might just be –
if start_year or end_year then
if not args['noprint'] then
ret = circa .. year .. bce
end
if not args['nocat'] then
ret = ret .. table.concat(cats)
end
return ret
end
end
args.nocat = yesno(args.nocat) or false
-- If we're here we didn't manage to parse it.
-- noyearcat has different behavior for nil and false
table.insert(cats, '[[Category:' .. 'Works with unrecognised dates' .. ']]')
if not args['noprint'].nocat == true then
args.noyearcat = true
ret = circa .. year .. bce
end
if not args['nocat'] then
ret = ret .. table.concat(cats)
end
if args.language then
-- Return whatever we have and the tracking cats
args.language_name = ISO_639_language_name(args.language)
return ret
end
 
local function construct_year(args)
local year = mw.html.create('span'):attr('id', 'header_year_text')
local year_args = {
['year'] = args['year'],
noprint = yesno(args['noyear']) or false,
wikidata = args.wikidata
}
year_args['nocat'] = yesno(args['noyearcat'])
if year_args['nocat'] == nil then
year_args['nocat'] = (
yesno(args['disambiguation']) -- Disambiguations never categorise
or not current_title:inNamespaces(0, 114) -- Only categorize in mainspace and Translation
or current_title.isSubpage -- Only categorise if this is a base page
or false
)
end
local year_text = parse_year_and_categorise(year_args)
args['language-required'] = yesno(args['language-required']) or false
if year_text then
year:wikitext(year_text)
if year_args['noprint'] then
return tostring(year)
else
return ' (' .. tostring(year) .. ')'
end
elseif year_args['nocat'] then
return ''
else
return '[[Category:' .. 'Undated works' .. ']]'
end
end
 
-- author/editor/translator/illustrator
 
local attr_data = {
{
param_name = 'author',
section_param_name = 'contributor',
prefix = 'by',
special_cases = {
['?'] = 'by Unknown',
unknown = 'by Unknown',
['not mentioned'] = 'by Unknown'
}
},
{
param_name = 'editor',
prefix = 'edited by',
special_cases = {
['?'] = 'editor unknown',
unknown = 'editor unknown',
['not mentioned'] = 'editor unknown'
}
},
{
param_name = 'translator',
prefix = 'translated by',
special_cases = {
['?'] = 'translator unknown',
unknown = 'translator unknown',
['not mentioned'] = 'translator unknown',
wikisource = 'translated by [[Wikisource:Translations|Wikisource]]'
}
},
{
param_name = 'illustrator',
prefix = 'illustrated by',
special_cases = {
['?'] = 'illustrator unknown',
unknown = 'illustrator unknown',
['not mentioned'] = 'illustrator unknown'
}
}
}
 
local function construct_attributions(args)
local attributions = {}
for i = 1, #attr_data do
local param_name = attr_data[i]['param_name']
local prefix = attr_data[i]['prefix'] .. ' '
local sep = ', '
local wrap_fn = true
if param_name == 'author' and args['override_' .. param_name] then
-- FIXME: remove special case?
-- would need to check existing uses to remove resulting "by by"s
sep = '<br/>'
prefix = ''
elseif #attributions == 0 and not args['section'] then
sep = '<br/>'
elseif #attributions == 0 then
sep = ' '
else
sep = ', '
end
if param_name == 'translator' and args.language then
prefix = 'translated from ' .. (args.language_name or 'unrecognized language') .. ' by '
end
local atext = get_arg_or_override(args, param_name)
if atext or args.template_name == 'Translation header' then
if atext and not args['override_' .. param_name] then
local special = false
for k, v in pairs(attr_data[i]['special_cases']) do
if string.lower(atext) == k then
atext = v
special = true
end
end
if args.template_name == 'Translation header' and param_name == 'translator' and atext == attr_data[i]['special_cases']['wikisource'] then
atext = nil
elseif special then
prefix = ''
wrap_fn = false
else
atext = '[[Author:' .. atext .. '|' .. atext .. ']]'
end
end
if args.template_name == 'Translation header' and param_name == 'translator' then
if atext then
atext = atext .. ' and [[Wikisource:Translations|Wikisource]]'
elseif not atext then
atext = '[[Wikisource:Translations|Wikisource]]'
end
end
if atext then
local aspan = mw.html.create('span'):addClass('vcard'):attr('id', 'header_' .. param_name .. '_text')
if wrap_fn then
aspan:tag('span'):addClass('fn'):wikitext(atext)
else
aspan:wikitext(atext)
end
table.insert(
attributions,
tostring(mw.html.create('span')
:addClass('contributor_text')
:wikitext(sep .. prefix .. tostring(aspan))
)
)
end
end
end
return table.concat(attributions)
end
 
-- section
 
local function construct_section(args)
if not args['section'] then
return ''
end
-- add values to argsWithBlanks
local s = {
for k, v in pairs(args) do
args['section']
if not argsWithBlanks[k] then
}
argsWithBlanks[k] = v
local attributions = {}
for i = 1, #attr_data do
local param_name = attr_data[i]['param_name']
local section_param_name = attr_data[i]['section_param_name'] or param_name
local prefix = attr_data[i]['prefix']
local contributor = get_arg_or_override(args, 'section_' .. param_name)
if contributor then
local container_span = mw.html.create('span'):addClass('contributor_text')
local contributor_span = mw.html.create('span'):addClass('fn')
if args['override_section_' .. param_name] then
contributor_span:wikitext(contributor)
else
contributor_span:wikitext('[[Author:' .. contributor .. '|' .. contributor .. ']]')
end
container_span:wikitext(prefix .. ' ' .. tostring(mw.html.create('span'):attr('id', 'header_' .. section_param_name .. '_text'):addClass('vcard'):wikitext(tostring(contributor_span))))
table.insert(attributions, tostring(container_span))
end
end
-- default values for title and section (allow override by setting to blank)
-- add a line return to split to two lines due to length if section translator exists
if #attributionsnot > 1argsWithBlanks['title'] then
args['title'] = parent_links({})
table.insert(s, '<br/>')
argsWithBlanks['title'] = args['title']
elseif #attributions == 1 then
table.insert(s, ' ')
end
table.insert(s, table.concat(attributions, ', '))
return tostring(mw.html.create('div'):addClass('header_section_text'):wikitext(table.concat(s)))
end
 
--[=[
Assemble the title
]=]
local function header_title(args)
return table.concat({
tostring(mw.html.create('span'):attr('id', 'header_title_text'):wikitext(args.title)),
construct_year(args),
construct_attributions(args),
construct_section(args)
})
end
 
--[=[
[[Template:Header]]
]=]
function p._header(args, argsWithBlanks)
argsWithBlanks = argsWithBlanks or args
-- aliases
local dup_cat = ''
local aliases = {
section_author = 'contributor',
section_translator = 'contributing_translator'
}
for k, v in pairs(aliases) do
if (args[k] and args[v]) or (args['override_' .. k] and args['override_' .. v]) then
dup_cat = '[[Category:' .. 'Pages using duplicate arguments in template calls' .. ']]'
end
args[k] = args[k] or args[v]
args['override_' .. k] = args['override_' .. k] or args['override_' .. v]
end
-- default values
args.template_name = args.template_name or 'Header'
args.title = args.title or parent_links({})
-- default value for section (allow override by setting section to blank)
if not argsWithBlanks['section'] and current_title.isSubpage then
args['section'] = current_title.subpageText
argsWithBlanks['section'] = args['section']
end
Line 991 ⟶ 424:
args.header_class = 'wst-header ws-header ws-noexport noprint dynlayout-exempt ' .. (args.header_class or '')
args.main_class = 'headertemplate'
 
args.notes_id = args.notes_id or 'navigationNotes'
args.language_name = ISO_639_language_name(args.language)
-- title
args.main_title = header_title(args)
Line 1,001 ⟶ 432:
if args.template_name == 'Translation header' and args.language then
interwiki = tostring(mw.html.create('span'):addClass('interwiki-info'):attr('id', args.language):attr('title', '(original)'))
if args.original and (args.language_namelanguage == 'ang' or args.language == 'enm' or args.language == 'sco') then
-- cycle to mul.ws and back around to en.ws
if args.language == 'ang' or args.language == 'enm' or args.language == 'sco' then
interwiki = interwiki .. '[[' .. args.language .. ':en:' .. args.original .. ']]'
-- cycle to mul.ws and back around to en.ws
interwiki = interwikielseif args..original '[[' ..and args.language .. ':en:' ..and args.original ..language_name ']]'then
-- general interwiki link
else
interwiki = interwiki .. '[[' .. args.language .. ':' .. args.original .. ']]'
-- general interwiki link
interwiki = interwiki .. '[[' .. args.language .. ':' .. args.original .. ']]'
end
end
end
-- defaultsort tracking categories
args.equalsortcat = '[[Category:' .. 'Headers with DefaultSort equal to page title' .. ']]'
args.diffsortcat = '[[Category:' .. 'Headers applying DefaultSort key' .. ']]'
args.post_notes = table.concat({
Line 1,017 ⟶ 450:
manual_categories(args),
construct_categories(args),
check_for_numerical_arguments(argsWithBlanks),
construct_defaultsort(args),
dup_cat,
Line 1,036 ⟶ 470:
]=]
function p._translation_header(args, argsWithBlanks)
argsWithBlanks = argsWithBlanks or args
args.header_class = 'wst-translation-header'
args.template_name = 'Translation header'
args.main_idnotes_class = 'translationheadertemplateheader-notes'
args.notes_id = 'translation_notes'
args.notes_class = 'header_notes'
return get_noexport_stylesheet(args.template_name'Translation header') .. p._header(args, argsWithBlanks)
end