Module:Koptekst
Documentatie voor deze module kan aangemaakt worden op de volgende pagina: Module:Koptekst/doc
require( 'strict' )
local p = {}
local getArgs = require('Module:Arguments').getArgs
local vraagWikidata = require('Module:Wikidata Boek').vraagWikidata
local function rangtelwoord(getal)
local rangtelwoorden = {
'eerste', 'tweede', 'derde', 'vierde', 'vijfde',
'zesde', 'zevende', 'achtste', 'negende'
}
local woord = rangtelwoorden[getal]
if not woord then
woord = tostring(getal) .. 'e'
end
return woord
end
local function tekenAuteurs(auteurs)
-- auteurs dient een lege tabel te zijn als er geen auteurs zijn, niet nil!
if #auteurs == 0 then
return nil
end
-- anders concateneren en als wikitext aan een .ws-koptekst-auteur div toevoegen
local auteurs_tekst = table.concat(auteurs, ', ')
local auteurs_html = mw.html.create('div')
:addClass('ws-koptekst-auteur')
:wikitext(auteurs_tekst)
return auteurs_html
end
local function tekenTitel(titel)
-- een titel komt er altijd, desnoods met ''titelloos werk''
local titel_html = mw.html.create('div')
:addClass('ws-koptekst-volledige-titel')
local titel_tag = titel_html
:tag('div')
:addClass('ws-koptekst-titel')
if titel.titel then
titel_tag:wikitext(titel.titel)
else
titel_tag:node('<i>titelloos werk</i>')
end
if titel.ondertitel then
titel_html:tag('div')
:addClass('ws-koptekst-ondertitel')
:wikitext(titel.ondertitel)
end
return titel_html
end
local function tekenVertalers(vertalers)
-- vertalers dient een lege tabel te zijn als er geen auteurs zijn, niet nil!
if #vertalers == 0 then
return nil
end
-- anders concateneren en als wikitext aan een .ws-koptekst-auteur div toevoegen
local vertalers_tekst = table.concat(vertalers, ', ')
local vertalers_html = mw.html.create('div')
:addClass('ws-koptekst-vertaler')
:wikitext('Vertaald door ' .. vertalers_tekst)
return vertalers_html
end
local function krijgDruktekst(druk)
-- als er een oorspronkelijke schrijfwijze is gebruiken we die:
if druk.schrijfwijze then
return druk.schrijfwijze
elseif druk.nummer then
-- altijd een string, maar misschien een getal
local druknummer = tonumber(druk.nummer)
if druknummer then
local telwoord = rangtelwoord(druknummer)
local telwoord = string.gsub(telwoord, '^%l', string.upper) -- eerste letter hoofdletter
return telwoord .. ' druk'
else
return druk.nummer
end
else
return error('Onverwachte error: er is info over de druk, maar geen getal.') -- onmogelijk om te komen
end
end
local function formatteerUitgegeven(drukInfo)
local tekst = ''
if drukInfo.plaats then
tekst = tekst .. drukInfo.plaats .. ': '
end
if drukInfo.uitgever then
tekst = tekst .. drukInfo.uitgever .. ', '
end
if drukInfo.jaar then
tekst = tekst .. drukInfo.jaar .. '.'
else
tekst = tekst .. '<i>onbekende datum</i>.'
end
return tekst
end
local function tekenDrukInfo(drukInfo, eersteDrukInfo)
local info_html = mw.html.create('table')
:addClass('ws-koptekst-info')
if not eersteDrukInfo.jaar then
info_html:attr("style", "max-width: 40%;")
end
-- de table head rij verschijnt waneer er ofwel bekend is welke druk dit is,
-- ofwel er een jaar van eerste druk bestaat.
if drukInfo.druk or eersteDrukInfo.jaar then
local eerste_rij = info_html:tag('tr')
local deze_druk_html = eerste_rij
:tag('th')
:addClass('ws-koptekst-info-druk')
local druktekst
if drukInfo.druk then
druktekst = krijgDruktekst(drukInfo.druk)
else
druktekst = 'Deze druk'
end
if drukInfo.taal then
druktekst = druktekst .. ' (' .. drukInfo.taal .. ')'
end
deze_druk_html:wikitext(druktekst)
if eersteDrukInfo.jaar then
local eerste_druk_html = eerste_rij
:tag('th')
:addClass('ws-koptekst-info-eerste-druk')
local eerstedruktekst
if eersteDrukInfo.druk then
eerstedruktekst = krijgDruktekst(eersteDrukInfo.druk)
else
eerstedruktekst = 'Eerste druk'
end
if eersteDrukInfo.taal then
eerstedruktekst = eerstedruktekst .. ' (' .. eersteDrukInfo.taal .. ')'
end
eerste_druk_html:wikitext(eerstedruktekst)
end
end
-- dan de tweede rij. die verschijnt altijd, want zelfs als er niets te
-- melden is komt er ''onbekende datum'' te staan.
local tweede_rij = info_html:tag('tr')
local deze_druk_info = tweede_rij:tag('td'):addClass('ws-koptekst-info-druk')
deze_druk_info:node(formatteerUitgegeven(drukInfo))
if eersteDrukInfo.jaar then
local eerste_druk_info = tweede_rij:tag('td'):addClass('ws-koptekst-info-eerste-druk')
eerste_druk_info:node(formatteerUitgegeven(eersteDrukInfo))
end
return info_html
end
function p.tekenKoptekst(data)
local koptekst = mw.html.create('div')
:addClass('ws-noexport')
:addClass('ws-koptekst')
koptekst:node(tekenAuteurs(data.auteurs))
koptekst:node(tekenTitel(data.titel))
koptekst:node(tekenVertalers(data.vertalers))
koptekst:node(tekenDrukInfo(data.drukInfo, data.eersteDrukInfo))
return koptekst
end
local function interpreteerMultilevelInhoud(inhoud_string)
local rootTable = {}
rootTable.root = true
local currentLevel = 1
local currentTable = rootTable
for line in mw.text.gsplit(inhoud_string, "\n", true) do
local asterisks, text = mw.ustring.match(line, "^%s*(%**)%s*([^*].-)%s*$")
if asterisks then
local asterisks = string.len(asterisks)
if asterisks == currentLevel then
-- nothing
elseif asterisks == currentLevel+1 then
-- descend into last element
currentTable = currentTable[#currentTable]
currentLevel = currentLevel + 1
elseif asterisks < currentLevel then
-- go up for each level back
while asterisks < currentLevel do
currentTable = currentTable.parent
currentLevel = currentLevel - 1
end
else
return '<span class=error>Kan niet meer dan één level dieper tegelijk gaan</span>'
end
local newTable = {}
newTable.parent = currentTable
newTable.name = text
if #currentTable > 0 then
newTable.prevElem = currentTable[#currentTable]
currentTable[#currentTable].nextElem = newTable
end
table.insert(currentTable, newTable)
currentTable[newTable.name] = newTable
end
end
return rootTable
end
local function genereerLinkLijst(werk_titel, pagina_tabel)
if not pagina_tabel or pagina_tabel.root then
local tabel = {}
tabel.link_root = werk_titel
return tabel
end
local lijst = genereerLinkLijst(werk_titel, pagina_tabel.parent)
local nieuwe_rij = {}
if pagina_tabel.prevElem then
nieuwe_rij.vorige = '[[' .. lijst.link_root .. '/' .. pagina_tabel.prevElem.name .. '|' .. pagina_tabel.prevElem.name .. ']]'
end
nieuwe_rij.sectie = pagina_tabel.name
nieuwe_rij.sectie = '[[' .. lijst.link_root .. '/' .. pagina_tabel.name .. '|' .. pagina_tabel.name .. ']]'
if pagina_tabel.nextElem then
nieuwe_rij.volgende = '[[' .. lijst.link_root .. '/' .. pagina_tabel.nextElem.name .. '|' .. pagina_tabel.nextElem.name .. ']]'
end
lijst.link_root = lijst.link_root .. '/' .. pagina_tabel.name
table.insert(lijst, nieuwe_rij)
return lijst
end
--[[
Deze functie tekent de tabel onder de koptekst die de links naar vorige en
volgende hoofdstukken bevatten.
lijst: een lijst van tabellen met mogelijke waardes voor vorige, volgende,
sectie
returnt: De gegenereerde mw.html tabel
]]
local function tekenKoptekstNavigatie(lijst)
if not lijst or #lijst == 0 then
-- geen waardes: return niks
return nil
end
local nav_tabel = mw.html.create('table')
:addClass('ws-onder-koptekst-navigatie')
for i, v in ipairs(lijst) do
local nav_rij = nav_tabel:tag('tr')
local vorige_td = nav_rij:tag('td')
:addClass('ws-onder-koptekst-vorige')
if v.vorige then
vorige_td:tag('span')
:wikitext(v.vorige)
-- TODO automatische footer weer doen werken
end
local sectie_td = nav_rij:tag('td')
:addClass('ws-onder-koptekst-sectie')
if v.sectie then
sectie_td:wikitext(v.sectie)
end
local volgende_td = nav_rij:tag('td')
:addClass('ws-onder-koptekst-volgende')
if v.volgende then
volgende_td:tag('span')
:wikitext(v.volgende)
end
end
return nav_tabel
end
function p.tekenOnderKoptekst(args)
local sectie, vorige, volgende =
args.Sectie or args.current,
args.Vorige or args.prev,
args.Volgende or args.next
local onder_koptekst = mw.html.create('div')
:addClass('ws-noexport')
:addClass('ws-onder-koptekst')
if args.nestedinhoud and #args.nestedinhoud > 0 then
local inhoud_tabel = interpreteerMultilevelInhoud(args.nestedinhoud)
local titel = mw.title.getCurrentTitle()
local titel_delen = mw.text.split(titel.text, '/', true)
local werk_titel = table.remove(titel_delen, 1)
-- pagina vinden
local pagina_tabel = inhoud_tabel
while #titel_delen > 0 do
pagina_tabel = pagina_tabel[titel_delen[1]]
table.remove(titel_delen, 1)
end
local link_lijst = genereerLinkLijst(werk_titel, pagina_tabel)
local koptekst_navigatie = tekenKoptekstNavigatie(link_lijst)
onder_koptekst:node(koptekst_navigatie)
elseif sectie or vorige or volgende then
local nav = onder_koptekst:tag('table')
:addClass('ws-onder-koptekst-navigatie')
:tag('tr')
if vorige or volgende then
local td = nav:tag('td')
:addClass('ws-onder-koptekst-vorige')
if vorige then
td:tag('span')
:attr('id', 'headerprevious') -- voor de automatische footer
:wikitext(vorige)
end
end
if sectie then
nav:tag('td')
:addClass('ws-onder-koptekst-sectie')
:wikitext(sectie)
end
if vorige or volgende then
local td = nav:tag('td')
:addClass('ws-onder-koptekst-volgende')
if volgende then
td:tag('span')
:attr('id', 'headernext')
:wikitext(volgende)
end
end
end
if args.extra_info and #args.extra_info > 0 then
onder_koptekst:tag('div')
:addClass('ws-onder-koptekst-opmerkingen')
:wikitext(args.extra_info)
end
return onder_koptekst
end
function p.koptekst(frame)
local args = getArgs(frame, {removeBlanks = false})
local wikidata_id
local data
if args.wikidata and #args.wikidata > 0 then
wikidata_id = args.wikidata
else
-- wikidata van de titel uit de magic header
if args.titel then -- anders proberen we of de titelpagina een wikidata heeft
string.gsub(args.titel, '^%[%[([^]|]*).*$', function(paginatitel)
wikidata_id = mw.wikibase.getEntityIdForTitle(paginatitel)
end)
end
-- wikidata van deze pagina
if not wikidata_id then
wikidata_id = mw.wikibase.getEntityIdForCurrentPage()
end
-- wikidata van een hoofdpagina
if not wikidata_id then
local paginatitel = mw.title.getCurrentTitle().text
while string.find(paginatitel, '/', 1, true) do
paginatitel = string.gsub(paginatitel, '^(.*)/.*$', function(parentPagina)
wikidata_id = mw.wikibase.getEntityIdForTitle(parentPagina)
if wikidata_id then
return '' -- klaar
else
return parentPagina
end
end)
end
end
end
assert(wikidata_id, 'Geen wikidata ID gevonden.')
data = vraagWikidata(wikidata_id)
local style = frame:extensionTag{name = 'templatestyles', args = { src = 'Gebruiker:Raketsla/klad/styles.css'}}
local koptekst = p.tekenKoptekst(data)
local onder_koptekst = p.tekenOnderKoptekst(args)
local categorizering = "[[Categorie:Wikisource:Pagina's die de experimentele koptekst gebruiken]]"
return tostring(style) .. tostring(koptekst) .. tostring(onder_koptekst) .. categorizering
end
return p