Modulen är avsedd för internlänkning i vilken bok som helst (med en .djvu-fil i botten). Finessen är att den länkar olika beroende på från vilken namnrymd den anropas.

Funktionen pg anropas med databladets namn som första parameter, bokens sidnummer som andra och eventuellt löpnummer för avsnitt som tredje.

  • om anropet görs från Sida eller Index översätts sidnumret till motsvarande sida i djvu-filen och en länk till Sida: returneras.
  • om anropet görs från huvudnamnrymden översätts sidnumret till titeln på det avsnitt sidan ingår i, och en länk till det avsnittet, med sidnumret som ankarlänk, returneras till huvudnamnrymden.
Om det finns flera avsnitt på samma sidnummer behöver referensen kompletteras med en siffra för vilket av sidans avsnitt referensen ska peka på, räknat löpande uppifrån på sidan. Om denna komplettering saknas kommer länken att gå till sidans första avsnitt, men med två röda frågetecken efter sidnumret som en signal om att det kan vara fel.

Modulen förutsätter alltså att man har skapat ett datablad för aktuell bok under Modul:Datablad. Namnet på detta datablad skickas med som första parameter i anropet, som lämpligen görs från en verk-specifik mall, typ Mall:stna.
Databladet beskrivs under Modul:Datablad/Svenska teatern del 6.


Det finns ytterligare en funktion tit2pages, som - med viss försiktighet - kan användas medan man skapar en kapitelsida. Den anropas med databladets namn som parameter: {{ #invoke:Test Avdelning|tit2pages|Svenska teatern del 6 }} (namnet på den nya sidan behöver man inte skriva, det följer med ändå) och returnerar ett <pages>-intervall med eventuella fromsection och tosection, som visas när man förhandsgranskar. Då kan man kopiera ner den raden och ersätta modulanropet. Man kan därmed skapa sidan utan att behöva titta efter precis var avsnittet börjar och slutar - men man får ju inte tro att sidan är klar innan man manuellt har ersatt modulanropet med dess resultat.
Funktionen använder samma datablad som ovan, så det blir inget extraarbete.


local p = {}

function p.pg(frame)
-- anropas med [1] databladets namn och [2] sidnummer i boken samt ev [3] löpnummer för sektion på sidan
	local bok
	local bokData="Modul:Datablad/" .. frame.args[1] 
	local ok,s2 = validera(frame)	-- kolla efter vanliga inmatningsfel
	if ok then
		ok,bok = pcall(mw.loadData,bokData)		-- läs in databladet
	end
	if ok then		-- både inmatningen och databladet verkar ok
		local retstr = ""		-- retursträng, så småningom
		local hitno = 0			-- räknar antalet träffar, när det är mer än ett avsnitt på en boksida
		local hits = {}			-- lagrar möjliga avsnittsrubriker
	   	local oklart = false	-- håller reda på om resultatet är entydigt eller ej
		local strPag = frame.args[2]			-- efterfrågad sida, som sträng
		local numPag = tonumber(frame.args[2])	-- sidnumret som tal
		local pDjvu = numPag + bok.offset		-- motsvarande sidnummer i djvu-filen
	-- kolla vilken namnrymd anropet kommer ifrån
		local base = mw.title.getCurrentTitle()
		local ns = base.namespace
		if ns > 0 and ns ~= 2 then		-- inte huvudnamnrymden (eller Användare, för teständamål)
			-- Returnera länk till rätt djvu-sida i sidnamnrymden (inkl hakparenteserna)
			retstr = "[[Sida:" .. bok.djvu .. "/" .. pDjvu .. "|" .. strPag .."]]"
		else	-- översätt till titel och skicka till huvudnamnrymden
	      	for i,v in pairs(bok.kapitel) do
				if tonumber(v.fpage) <= numPag and tonumber(v.tpage) >= numPag then 	-- träff på rätt sida 
					hitno = hitno + 1			-- räkna upp antalet träffar
					hits[hitno] = v.titel		-- spara den hittade titeln 
				end
				if v.fpage > numPag then		-- nu har vi kommit förbi, ingen idé att leta längre
					break
				end
			end
			if hitno > 1 then	-- det finns flera avsnitt på det sidnumret, därför flera träffar
				if frame.args[3] == "{{{3}}}" then	-- det finns ingen specifikation medskickad
					oklart = true
				else
					local sektion = tonumber(frame.args[3])
					if sektion <= hitno then			-- kolla så vi inte hamnar utanför
						hits[1] = hits[sektion]			-- vi lägger den som etta, för enkelhetens skull
					else
						oklart = true
						s2 = ' Felaktigt avsnitt!'
					end
				end
			end
			if hitno > 0 then		-- normalfallet, vi har fått åtminstone en träff
				retstr = '[[' .. bok.proj ..'/'.. hits[1] ..'#s' .. strPag .. '|' .. strPag .. ']]'
				if oklart then 
					retstr = retstr .. '<span style="color:red">' .. s2 .. '</span>'
				end
			else					-- vi fick ingen träff alls
				retstr = '<span style="color:red">' .. strPag .. ' - ogiltigt sidnummer!</span>'
			end
		end
		return retstr
	else
		if s2 == "??" then
			s2 = "Hittar inte databladet!"
		end
		return '<span style="color:red">' .. s2 .. '</span>'
	end
end

function validera(frame)
	local ok = true
	local s2 = "??"
	if frame.args[2] == '' or frame.args[3] == '' then	-- vertikalstreck finns men värde saknas
		ok = false
		s2 = "Tom parameter"
	end
	if string.match(frame.args[2], '[^0-9]') then	-- kolla att det bara är siffror
		ok = false
		s2 = "Ogiltigt tecken: " .. frame.args[2]
	end
	if frame.args[3] ~= '{{{3}}}' then	-- att det inte fanns någon tredje parameter är helt ok 
		if string.match(frame.args[3], '[^0-9]') then	-- kolla att det bara är siffror
			ok = false
			s2 = "Ogiltigt tecken: " .. frame.args[3]
		end
	end
	return ok, s2
end

function p.tit2pages(frame)	-- Returnerar "<pages index=xx from=## fromsection=yy to=## tosection=zz header=1 />"
-- anropas från ns0/huvudnamnrymden med databladets namn som enda parameter
-- kapitelrubriken behöver inte skickas med, den hämtas via mw.title.getCurrentTitle()
	local bokData="Modul:Datablad/" .. frame.args[1]
	local ok,bok = pcall(mw.loadData,bokData)
	local base = mw.title.getCurrentTitle()
	local titel = base.subpageText
	if ok then
		local ut = ''
    	for i,v in pairs(bok.kapitel) do
        	if titel == v.titel then
				ut = '<pages index="' .. bok.djvu .. '" from=' .. v.fpage + bok.offset
				if v.fsect > "" then
					ut = ut .. ' fromsection=' .. v.fsect
				end
				ut = ut .. ' to=' .. v.tpage + bok.offset
				if v.tsect > "" then
					ut = ut .. ' tosection=' .. v.tsect
				end
				ut = ut .. ' header=1 />'
				return ut
			end
		end
		return "FEL - hittade inte titeln!"
	else
		return "FEL - hittade inte tillhörande datablad!"
	end
end 	

return p