Produceert broodkruimelnavigaties. Roep deze module niet direct aan, maar gebruik altijd sjabloon {{Broodkruimel}}.
Overgenomen van Module:Broodkruimel op de Nederlandstalige Wikipedia.
local p = {}
-- Openingstag voor alle tabellen in de broodkruimel
p.table = '<table cellspacing="1" cellpadding="0">'
-- Curly dinges voor achter vertakkingen
p.curly = '<span style="font-size:120%">}</span>'
-- 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 = 'WikiWoordenboek:Broodkruimelproblemen'
-- 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.
-- "C": er is iets mis met de wikitekst. Mogelijk een ontbrekende
-- sluittag oid.
-- "P": parameterprobleem: er is een ongeldige waarde voor
-- een parameter opgegeven
-- "M": we hebben p.MAX bereikt, dus de boom is niet af
-- "O": de pagina (of categorie) is ongecategoriseerd
p.problemen = ""
--[[
broodkruimel( frame )
Maakt een broodkruimelnavigatie voor de categorieen van een pagina.
Als frame.args opgegeven is, wordt die pagina gebruikt.
Zoniet, en frame.args is opgegeven, dan wordt die pagina gebruikt.
Als geen van beiden opgegeven is, wordt de huidige pagina gebruikt.
]]
function p.broodkruimel( frame )
-- Voor welke pagina?
local title = frame.args.pagina or frame.args
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.forceer and frame.args.forceer ~= "" ) 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.startgrootte and frame.args.startgrootte ~= "" ) then
p.verklein = true
local n = tonumber( frame.args.startgrootte )
if ( n ~= nil and n > 0 ) then
txtsize = 2 * n
else
p.probleem( "P" )
end
end
-- Negeerlijst?
p.negeerlijst = {}
if ( frame.args.negeer and frame.args.negeer ~= "" ) then
p.negeerlijst = p.parseNegeerLijst( frame.args.negeer )
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
-- Als we geen broodkruimel kunnen maken omdat de pagina
-- in meer dan max_branch cats zit, printen we simpelweg de
-- bovenliggende cats: i.v.m. de layout moeten we in ieder
-- geval iets tonen.
kruimel = p.printcats( p.hoofdcats )
if ( p.hoofdcats == nil or next( p.hoofdcats ) == nil ) then
-- ongecategoriseerde pagina
p.probleem( "O" )
end
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*:%s*(]+)]"
for category in mw.ustring.gmatch( txt, pattern ) do
category = p.cleanupCatTitle( 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
if ( mw.ustring.len( category ) < 100 ) then
if ( p.negeerlijst == nil ) then
cats = ""
p.branchcount = p.branchcount + 1
end
else
if ( p.hoofdcats == nil ) then
p.probleem( "C" )
end
end
end
end
if ( p.hoofdcats == nil ) then
-- De cats direct boven de pagina slaan we op voor: die
-- gebruiken we als we geen boom kunnen maken
p.hoofdcats = cats
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 = { = "" }
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 ) then
if ( cat == "Categorie:Alles" ) then
result = {}
else
result = { = {} }
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 = cats
p.seen = true
end
else
local temp = p.addLevel( rest )
if ( temp == nil ) then
return nil
else
result = 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 .. "]"
str = str .. "</td></tr></table>"
if ( p.verklein ) then str = str .. "</div>" end
return str
end
--[[
cleanupCatTitle( title )
Standaardiseert een categorienaam: overbodige spaties aan begin en
eind weg, underscores vervangen door spaties, de eerste letter een
hoofdletter, naamruimte ervoor.
]]
function p.cleanupCatTitle( title )
title = mw.text.trim( title )
title = p.removeCatNS( title )
title = mw.ustring.gsub( title, "_", " " )
title = mw.language.getContentLanguage():ucfirst( title )
title = "Categorie:" .. title
return title
end
--[[
removeCatNS( title )
Verwijdert "Categorie:" of "Category:"
]]
function p.removeCatNS( title )
title = mw.ustring.gsub( title, "^%s*:%s*", "" )
title = mw.ustring.gsub( title, "^%s*:%s*", "" )
return title
end
--[[
parseNegeerLijst( str )
Parsed een door komma's gescheiden lijst van categorienamen
]]
function p.parseNegeerLijst( str )
local lijst = {}
cats = mw.text.split( str, ',', true )
for _, cat in pairs( cats ) do
cat = p.cleanupCatTitle( cat )
lijst = ""
end
return lijst
end
--[[
printCats( cats )
Print de categorieen in cats.
Als we geen broodkruimel kunnen we maken gebruiken we deze functie
om simpelweg de direct bovenliggende cats te tonen.
]]
function p.printcats( cats )
local str = ""
str = str .. "<div style='text-align: left;'> Categorieën: "
if ( ( type( cats ) ~= "table" ) or next( cats ) == nil ) then
str= str .. "''Geen''"
else
for cat in pairs( cats ) do
str = str .. ']'
if ( next( cats, cat ) ~= nil ) then
str = str .. " • "
end
end
end
str = str .. '</div>'
return str
end
function p.printprobleem( )
if ( p.problemen ~= nil and p.problemen ~= "" ) then
return "]"
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