Module:Broodkrummels
Module om broodkrummels vir navigasie neer te lê. Die module word in {{Broodkrummels}} gebruik.
local p = {}
-- Openingstag voor alle tabellen in de broodkruimel
p.table = '<table cellspacing="1" cellpadding="0">'
-- Curly dinges voor achter vertakkingen
p.curly = '<big>}</big>'
-- Wolkje voor weggelaten categorieen
p.wolkje = '(...)'
-- Maximaal aantal categorieen voor we het voor gezien houden
p.MAX = 50
-- Categorie waar we pagina's met broodkruimelproblemen in zetten
p.probleemcat = 'Wikipedia:Broodkrummelprobleme'
-- We houden bij of we problemen tegenkomen. Het soort probleem
-- geven we aan met een letter die als sorteersleutel in de
-- probleemcategorie gebruiken. Als er meer problemen zijn, nemen
-- we gewoon de laatste.
-- "P": parameterprobleem: er is een ongeldige waarde voor
-- een parameter opgegeven
-- "L": lege broodkruimel: de categorieboom is te ingewikkeld
-- of de opgegeven pagina heeft geen categorieen
-- "M": we hebben p.MAX bereikt, dus de boom is niet af
p.problemen = ""
--[[
broodkruimel( frame )
Maakt een broodkruimelnavigatie voor de categorieen van een pagina.
Als frame.args[pagina] opgegeven is, wordt die pagina gebruikt.
Zoniet, en frame.args[1] is opgegeven, dan wordt die pagina gebruikt.
Als geen van beiden opgegeven is, wordt de huidige pagina gebruikt.
]]
function p.broodkrummel( frame )
-- Voor welke pagina?
local title = frame.args.bladsy or frame.args[1]
if ( not title or title == "" ) then
title = mw.title.getCurrentTitle().prefixedText
end
-- Hoogte?
local level = 8
p.force = false
if ( frame.args.lengte and frame.args.lengte ~= "" ) then
n = tonumber( frame.args.lengte )
if ( n ~= nil and n > 0 ) then
level = n
if ( frame.args.forseer and frame.args.forseer ~= "" ) then
p.force = true
end
else
p.probleem( "P" )
end
end
-- Maximale aantal parallelle vertakkingen?
p.max_branch = 4
if ( frame.args.maxbranch and frame.args.maxbranch ~= "" ) then
local n = tonumber( frame.args.maxbranch )
if ( n ~= nil and n > 0 ) then
p.max_branch = n
else
p.probleem( "P" )
end
end
-- Text verkleinen?
local txtsize = 20
p.verklein = false
if ( frame.args.begingrootte and frame.args.begingrootte ~= "" ) then
p.verklein = true
local n = tonumber( frame.args.begingrootte )
if ( n ~= nil and n > 0 ) then
txtsize = 2 * n
else
p.probleem( "P" )
end
end
-- Maak boom
local trees = p.createCategoryTree( title, level )
-- Maak kruimel
local ntitle, ntree = next( trees )
local kruimel = ""
if ( type( ntree ) == "table" and next( ntree ) ) then
kruimel = p.createBreadCrumb( ntitle, ntree, txtsize )
else
p.probleem( "L" )
end
return kruimel .. p.printprobleem()
end
--[[
parseCategories( wikitext )
Zoekt geldige categorieen in wikitext.
]]
function p.parseCategories( txt )
if ( txt == nil ) then return {} end
local cats = {}
local pattern = "%[%[%s*[Kk][Aa][Tt][Ee][Gg][Oo][Rr][YyIi][Ee]?%s*:%s*([^|%]]+)[|%]]"
for category in mw.ustring.gmatch( txt, pattern ) do
-- Spaties aan het eind verwijderen
category = mw.text.trim( category )
-- Eerste letter omzetten naar hoofdletter
category = mw.language.getContentLanguage():ucfirst( category )
-- Underscores naar spaties
category = mw.ustring.gsub( category, "_", " " )
-- Sla categorieen met gekke dingen over: sjablonen e.d.
if ( mw.ustring.find( category, "[{}%[%]]" ) == nill) then
-- Als de naam langer is dan 50 tekens is er waarschijnlijk
-- iets mis (ontbrekende sluit-]]?)
if ( mw.ustring.len( category ) < 50 ) then
cats["Kategorie:" .. category] = ""
p.branchcount = p.branchcount + 1
end
end
end
return cats
end
--[[
createCategoryTree( title, maxlevel )
Maakt een boom van de categorieen boven title, tot een afstand van
maxlevel. Stopt als de boom meer dan p.max_branch takken bevat.
]]
function p.createCategoryTree( title, maxlevel )
local level = 0
local tree = { [title] = "" }
p.seen = {}
p.count = 0
while level < maxlevel do
level = level + 1
p.branchcount = 0
local new_tree = p.addLevel( mw.clone (tree) )
if ( not p.force and p.branchcount > p.max_branch ) then
return tree
elseif ( new_tree == nil ) then
return tree
end
tree = new_tree
end
return tree
end
function p.addLevel ( tree )
local result = {}
for cat,rest in pairs( tree ) do
if ( rest == "" ) then
if ( p.seen[cat] ) then
if ( cat == "Categorie:Alles" ) then
result[cat] = {}
else
result[cat] = { ["..."] = {} }
p.branchcount = p.branchcount + 1
end
else
p.count = p.count + 1
if ( p.count > p.MAX ) then
p.probleem( "M" )
return nil
end
page = mw.title.new( cat )
local cats = p.parseCategories( page:getContent() )
result[cat] = cats
p.seen[cat] = true
end
else
local temp = p.addLevel( rest )
if ( temp == nil ) then
return nil
else
result[cat] = temp
end
end
end
return result
end
--[[
createBreadCrumb( title, trees, txtsize )
Maakt een breadcrumb navigatie voor trees.
title: de titel van de pagina waarvoor de breadcrumb is
trees: de categoriebomen zoals gemaakt door createCategoryTrees(title)
txtsize: lettergrootte
]]
function p.createBreadCrumb( title, tree, txtsize )
tree = tree or {}
local str = ""
if ( p.verklein ) then
str = str .. '<div style="font-size: ' .. math.floor( txtsize/2 ) .. 'pt">'
end
str = str .. p.table .. '<tr><td align="right">'
local count = 0
for ntitle, ntree in pairs( tree ) do
count = count + 1
if ( ntitle == "..." ) then
str = str .. p.wolkje
else
if ( type( ntree ) == "table" ) then
str = str .. p.createBreadCrumb( ntitle, ntree, txtsize-1 )
else
str = str .. p.createBreadCrumb( ntitle, {}, txtsize-1 )
end
end
end
str = str .. "</td><td>"
if ( count > 1 ) then
str = str .. p.curly .. '</td><td align="right">'
end
if ( count > 0 ) then
str = str .. '</td><td> → </td><td>'
end
str = str .. "[[:" .. title .. "|" .. p.removeCatNS( title ) .. "]]"
str = str .. "</td></tr></table>"
if ( p.verklein ) then str = str .. "</div>" end
return str
end
--[[
removeCatNS( title )
Verwijdert "Categorie:" of "Category:"
]]
function p.removeCatNS( title )
title = mw.ustring.gsub( title, "^[Kk][Aa][Tt][Ee][Gg][Oo][Rr][Yy]:", "" )
title = mw.ustring.gsub( title, "^[Kk][Aa][Tt][Ee][Gg][Oo][Rr][Ii][Ee]:", "" )
return title
end
function p.printprobleem( )
if ( p.problemen ~= nil and p.problemen ~= "" ) then
return "[[Kategorie:" .. p.probleemcat .. "|" .. p.problemen .. "]]"
else
return ""
end
end
function p.probleem( letter )
p.problemen = letter
end
--[[
pptable( table )
Maakt een string van een table gemaakt door createCategoryTrees().
Alleen voor testen en debuggen.
]]
function p.pptable( table )
local str = ""
table = table or {}
for k,v in pairs( table ) do
str = str .. k .. ": "
if ( type( v ) == "string" ) then
else
str = str .. "{" .. p.pptable(v) .. "}, "
end
end
return str
end
return p