Moduuli:Hiekkalaatikko/Ejs-80

Wikisanakirjasta

Tämän moduulin ohjeistuksen voi tehdä sivulle Moduuli:Hiekkalaatikko/Ejs-80/ohje

local arkistoLista = require( 'Module:Archive list' )

local p = {}


local function poista_linkit(alkup)
	local result = alkup

    -- Poistetaan sisäiset linkitykset ja mahdolliset [[-merkinnän jälkeiset
    -- kaksoispisteet (esim. [[: Luokka:Sejase]] → Luokka:Sejase).
	result = string.gsub(result, '%[%[.-|(.-)%]%]', '%1')
	result = string.gsub(result, '%[%[%s-:?%s-(.-)%]%]', '%1')

	-- Poistetaan http:-alkuiset ulkoiset linkitykset.
	result = string.gsub(result, '%[http.-%/%/%S.-%s%s-(.-)%]', '%1')
	
	return mw.text.trim(result)
end

 
 -- paikallinen funktio hakemistolinkin luomiseen
 local function hakemistolinkki(indeksoitava_sivu, otsake, nro, substaus)
	local linkin_alkuosa, linkin_loppuosa
 	local linkki, subst

	if nro == nil or nro < 1 then
		nro = 1
	else
		nro = math.floor(nro)
	end
	if substaus == nil then
		subst = false
	else
		subst = substaus
	end

	if(otsake ~= nil) then
		-- Trimmataan turha whitespace pois otsakkeesta. 
		-- Muodostetaan linkki kahdessa osassa, jotta tietyn osan 
		-- käsittely erikseen onnistuu mutkattomasti. 
		linkin_alkuosa = mw.text.trim(otsake)
		linkin_loppuosa = linkin_alkuosa
	else 
		linkki = ''
		return linkki
	end

	-- Poistetaan kohdelinkistä <nowiki>-, <pre>-, <code>- ja <tt>-tagit. 
  	linkin_alkuosa = string.gsub(linkin_alkuosa, 
  		'<[nN][oO][wW][iI][kK][iI]>(.-)</[nN][oO][wW][iI][kK][iI]%s->', '%1')
  	linkin_alkuosa = string.gsub(linkin_alkuosa, 
  		'<[pP][rR][eE]>(.-)</[pP][rR][eE]%s->', '%1')
  	linkin_alkuosa = string.gsub(linkin_alkuosa, 
  		'<[cC][oO][dD][eE][^><]->(.-)</[cC][oO][dD][eE]%s->', '%1')
  	linkin_alkuosa = string.gsub(linkin_alkuosa, 
  		'<[tT][tT][^><]->(.-)</[tT][tT]%s->', '%1')

  	-- Korvataan kohdelinkissä {{m|Malline...}} tekstillä {{Malline...}}
  	linkin_alkuosa = string.gsub(linkin_alkuosa, '{{%s-[Mm]%s-|(.-)}}', '{{%1}}')
	linkin_alkuosa = string.gsub(linkin_alkuosa, '{{%s-[Mm]alline%s-|(.-)}}', '{{%1}}')

	-- Jos ei haluta substata moduulin tulostetta, otetaan linkin loppuosaksi eli
	-- näkyväksi osaksi aiemmissa vaiheissa aikaansaatu otsikon siivottu versio.
	if subst == false then
		linkin_loppuosa = linkin_alkuosa
	end

	-- Siistitään kohdelinkin <span>tekstiä</span>-tyyppiset osat.
   	linkin_alkuosa = string.gsub(linkin_alkuosa, '<span.->(.-)</span>', '%1')
   	
	-- Poistetaan kohdelinkistä kursivointi ja lihavointi. 
   	linkin_alkuosa = string.gsub(linkin_alkuosa, "'?''(.-)'''?", '%1')

	-- Prosenttikoodataan harmaita hiuksia aiheuttavat merkit mw.uri.encoden avulla.
     linkin_alkuosa = mw.uri.encode( linkin_alkuosa, 'WIKI' )
     
     -- Otetaan tarvittaessa toistuvan otsikon järjestysnumero huomioon linkityksessä.
     if nro > 1 then
		linkin_alkuosa = linkin_alkuosa..'_'..nro
     end

	-- Koostetaan linkki.
	linkin_alkuosa = indeksoitava_sivu..'#'..linkin_alkuosa
	linkki = '[['..linkin_alkuosa..'|'..linkin_loppuosa..']]'
	return mw.text.trim(linkki)
end


-- muuntaa html-otsikot wikiformaattiin
local function hWikitys(hAlku,heading,hLoppu)
	if hAlku == nil or heading == nil or hLoppu == nil then
		return ''
	end

	local i
	local merkki = {}
	local otsake = heading
	local alkuTaso = tonumber(hAlku) 
	local loppuTaso = tonumber(hLoppu) 

	if alkuTaso == nil or loppuTaso == nil then
		return ''
	end

	if alkuTaso < 1 or alkuTaso > 6 or loppuTaso < 1 or loppuTaso > 6 then
		return ''
	end

    for i = 1, alkuTaso do
    	table.insert(merkki, '=')
    end
    otsake = string.gsub(otsake, '\n', '') 
	return '\n\n'..table.concat(merkki)..otsake..table.concat(merkki)..'\n\n'	
end


-- sivun hakemiston automaattisesti generoiva funktio
local function hakemisto(sivu, nimiavaruus)
	-- Haetaan sivun sisältö. 
    local title = mw.title.new(sivu, nimiavaruus)
	local aineisto = title:getContent()
	assert(title, 'Valitettavasti sivun sisällön hakeminen ei onnistunut (virhe 1)')
	assert(aineisto, 'Valitettavasti sivun sisällön hakeminen ei onnistunut (virhe 2)')

	local alku, loppu, i, w, taso, aiempi_taso
	local otsikko, paljas_otsikko
	local hakemisto = {}
    local otsikot = {}

	-- Otsikoiden etsimistä yksinkertaistavia toimenpiteitä.
	aineisto = '\n'..aineisto..'\n'
    aineisto = string.gsub(aineisto, '=%s%s-\n', '=\n' ) 
	aineisto = string.gsub(aineisto, '(\n(=[^\n]-[^\n%s][^\n]-=)\n)', '\n%1\n' ) 

	-- Poistetaan kokonaan tyhjät otsikot. 
    aineisto = string.gsub(aineisto, '\n==-%s-==-\n', '\n\n' ) 

    aineisto = string.gsub(aineisto,'\n<', '\n <')
    aineisto = string.gsub(aineisto,'<[pP][rR][eE]%s[^>]->', '<pre>')
    aineisto = string.gsub(aineisto,'<[nN][oO][wW][iI][kK][iI]%s[^>]->', '<nowiki>')
    aineisto = string.gsub(aineisto,'<syntaxhighlight%s[^>]->', 
    	'<syntaxhighlight>')
    aineisto = string.gsub(aineisto,'<[pP][oO][eE][mM]%s[^>]->', '<poem>')

	-- Otsikko muodostuu (yksirivisenä), vaikka sen sisällä olevien <pre>- 
	-- <nowiki>-, <syntaxhighlight>- ja <poem>-tagien välissä olisi 
	-- rivinvaihtoja, joten poistetaan ko. tagien sisällä olevat rivinvaihdot. 
    aineisto = string.gsub(aineisto, 
    	'<[pP][rR][eE]>(.-)</[pP][rR][eE]%s->', 
    	function (z) return string.gsub(z, '\n', '') end )
    aineisto = string.gsub(aineisto, 
    	'<[nN][oO][wW][iI][kK][iI]>.-</[nN][oO][wW][iI][kK][iI]%s->', 
    	function (z) return string.gsub(z, '\n', '') end )
    aineisto = string.gsub(aineisto, 
    	'<syntaxhighlight>(.-)</syntaxhighlight%s->', 
    	function (z) return string.gsub(z, '\n', '') end )
    aineisto = string.gsub(aineisto, 
    	'<[pP][oO][eE][mM]>.-</[pP][oO][eE][mM]%s->', 
    	function (z) return string.gsub(z, '\n', '') end )

	-- Karsitaan pois <pre>-, <nowiki>-, <syntaxhighlight>- ja <poem>--tagein 
	-- merkitty sisältö, joka sijaitsee muualla kuin otsikoiden sisällä, jotta 
	-- ko. tagien sisällä olevat otsikot vältetään otsikoita haettaessa.
    aineisto = string.gsub(aineisto, 
    	'(\n[^=][^\n]-)<[pP][rR][eE]>.-</[pP][rR][eE]%s->', '%1')
    aineisto = string.gsub(aineisto, 
    	'(\n[^=][^\n]-)<[nN][oO][wW][iI][kK][iI]>.-</[nN][oO][wW][iI][kK][iI]%s->', '%1')
    aineisto = string.gsub(aineisto, 
    	'<synt.->.-</synt.->', '%1')
    aineisto = string.gsub(aineisto, 
    	'(\n[^=][^\n]-)<[pP][oO][eE][mM]>.-</[pP][oO][eE][mM]%s->', '%1')

	-- Poistetaan kaikki piilokommentit.
    aineisto = string.gsub(aineisto, '<%!%-%-.-%-%->', '' )

	-- Muunnetaan html-tageilla luodut otsikot wikiformaattin, jotta 
	-- kaikki otsikot saadaan purkkiin samalla haulla.
	aineisto = string.gsub(aineisto,'(</?[hH]%d)%s[^>]-(>)', '%1%2')
    aineisto = string.gsub(aineisto, '<[hH](%d)%s->(.-)</[hH](%d)%s->', hWikitys)

    -- Etsitään ensimmäisen otsikon alku ja loppu.
    alku, loppu = string.find(aineisto, '\n=[^\n]-[^\n%s][^\n]-=\n')

	if 1 == 1 then
	    local alkup = mw.title.new(sivu, nimiavaruus)
		return 'Sivulta ei löytynyt yhtään otsikkoa! ' 
		.. 'Sivun getContent-funktiolla haettu sisältö:<br /><br />'..alkup:getContent()
		.. '<br /><br /><br />Aineisto hakemistomoduulin tekemien muutosten jälkeen:<br /><br />'..aineisto
	end

	-- Haetaan sivun otsikot tauluun. 
    for w in string.gfind(aineisto, '\n(=[^\n]-[^\n%s][^\n]-=)\n') do
      table.insert(otsikot, w)
    end

	table.insert(hakemisto, '<ol>')
	aiempi_taso = 2

	-- Silmukka käy läpi kaikki sivulta löytyneet otsikot. 
    for index, otsikko in ipairs(otsikot) do 
		
		-- Lasketaan while-silmukan avulla yhtäsuuruusmerkkien määrä (eli 
		-- käytännössä otsikkotaso) ja pannaan se muistiin.
		i = 1
		while string.sub(otsikko,i,i) == '=' do
        	i = i + 1
        end
        taso = i - 1
        
		-- Otsikkotason muuttuessa lisätään riittävä määrä järjestetyn 
		-- luettelon aloitus-/lopetustageja, jotta otsikot saadaan 
		-- lopulliseen hakemistoon oikeille tasoilleen.
        if taso > aiempi_taso then
			for i = 1, (taso - aiempi_taso) do 
				table.insert(hakemisto, '<ol>')
        	end
        elseif taso < aiempi_taso then
        	for i = 1, (aiempi_taso - taso) do
				table.insert(hakemisto, '</ol>')
        	end
        end
        
		-- Pistetään otsikkotaso muistiin silmukan seuraavaa kierrosta varten.
        aiempi_taso = taso

		-- Poistetaan otsikosta linkitykset sekä yhtäsuuruusmerkit alusta ja lopusta.
		paljas_otsikko = poista_linkit(string.sub(otsikko, taso+1, -taso-1))

		-- Lasketaan montako kertaa otsikko on aiemmin esiintynyt hakemistossa.
		-- Jos otsikossa on Luan erikoismerkkejä, lisätään gsubia varten 
		-- %-merkki niiden eteen, jotta ne eivät sekoita pattern matchingia 
		-- (laskeminen tapahtuu gsubin suorittamien korvaustoimintojen lukumäärän 
		-- perusteella).
		i = select(2, table.concat(hakemisto):gsub('|'..
			paljas_otsikko:gsub('([%(%)%%%.%+%-%*%[%]%?])', '%%%1')..
			'%]%]</li>', ''))
			
		-- Lisätään hakemistoon seuraava hakemistolinkki-funktiolla 
		-- linkitettävä otsikko.  
		table.insert(hakemisto, '<li>')
    	table.insert(hakemisto, hakemistolinkki(title.fullText, paljas_otsikko, i+1))
    	table.insert(hakemisto,'</li>')
	end

	-- Viimeistellään hakemisto.
	if (taso > 2) then
		for i = 2, taso do
			table.insert(hakemisto,'</ol>')
		end
	elseif (taso > 1) then
		table.insert(hakemisto,'</ol>')
	end
	return table.concat( hakemisto )
end


-- Muodostaa yksittäisen sivun hakemiston. 
function p.luo_hakemisto(frame)
	-- Käsitellään pari virhetilannetta.
	assert(frame.args['nimiavaruus'], 'Nimiavaruus tarvitaan hakemiston tuottamiseksi')
	assert(frame.args['sivu'], 'Sivun nimi tarvitaan hakemiston tuottamiseksi')
	
	local nimiavaruus = frame.args['nimiavaruus']
	nimiavaruus = string.gsub(nimiavaruus, '%s', '_')

	return hakemisto(frame.args['sivu'], nimiavaruus)
end


--[[Funktio arkistot muodostaa hakemistot halutuista tai kaikista arkistosivuista. 
Käyttöesimerkkejä: 
{{#invoke:Hakemisto|arkistot|nimiavaruus=User_talk|sivu=Ejs-80|ensimmäinen=4|viimeinen=8}}
{{#invoke:Hakemisto|arkistot|nimiavaruus=Wikipedia|sivu=Ylläpitäjien ilmoitustaulu}}
{{#invoke:Hakemisto|arkistot|nimiavaruus=Wikipedia|sivu=Botit/pyynnöt|väli=ei}}
]]--
function p.arkistot(frame)
	-- Käsitellään pari virhetilannetta.
	assert(frame.args['nimiavaruus'], 'Nimiavaruus tarvitaan hakemiston tuottamiseksi')
	assert(frame.args['sivu'], 'Sivun nimi tarvitaan hakemiston tuottamiseksi')
	
	local nimiavaruus = frame.args['nimiavaruus']
	nimiavaruus = string.gsub(nimiavaruus, '%s', '_')

	local sivu = frame.args['sivu']
	local aloitusNro, lopetusNro
	local etuliite
	local arkistohakemisto = {}
	local space 
	local i = 1

	-- Otetaan arkistoissa käytetty etuliite joko argumentista 'etuliite' 
	-- tai asetetaan sen arvoksi 'Arkisto'. 
	if frame.args['etuliite'] ~= nil then
		etuliite = frame.args['etuliite']
		if etuliite == '' then
			etuliite = 'Arkisto'
		end
	else
		etuliite = 'Arkisto'
	end

	-- Lisätään välilyönti arkistonumeron edelle paitsi jos 'väli'-argumentin
	-- välityksellä on annettu tieto, jonka mukaan arkistoissa ei käytetä 
	-- välilyöntiä arkiston numeron edellä. 
	space = 'yes'
	if frame.args['väli'] ~= nil then
		if frame.args['väli'] == 'ei' then
			space = ''
		end
	end

	-- Muuttujaan aloitusNro tulee sen arkistosivun nro, 
	-- josta hakemistojen luominen aloitetaan.
	if tonumber(frame.args['ensimmäinen']) ~= nil then
		aloitusNro = tonumber(frame.args['ensimmäinen'])
	else
		aloitusNro = 1
	end

	-- argumentit Archive list -moduulin count-funktiota varten
	local arkistoArgs = { 
		root = nimiavaruus..':'..sivu,
        prefix = etuliite, 
        prefixspace = space, 
        alku = aloitusNro
	}
	-- Muuttujaan lopetusNro tulee sen arkistosivun nro, 
	-- johon hakemistojen luominen lopetetaan.
	if tonumber(frame.args['viimeinen']) ~= nil then
		lopetusNro = tonumber (frame.args['viimeinen'])
	else
		-- Jos argumenteissa ei ole kerrottu arkistonumeroa, johon 
		-- hakemistojen teko halutaan lopettaa, etsitään suurin 
		-- arkistonumero Archive list -moduulin count-funktiolla. 
		lopetusNro = arkistoLista.count(arkistoArgs)
		if lopetusNro == nil then 
			lopetusNro = 1
		end
	end
	
	-- Tässä for-silmukassa lisätään otsikot ja muodostetaan 
	-- käsiteltävien arkistosivujen hakemistot hakemisto-funktiolla. 
	for i = aloitusNro, lopetusNro, 1 do 
		if space == 'yes' then 
			sivu = frame.args['sivu'] .. '/' .. etuliite .. ' ' .. i
		else
			sivu = frame.args['sivu'] .. '/' .. etuliite .. i
		end
		table.insert(arkistohakemisto, '<h2>[[' .. nimiavaruus..':'..sivu)
		table.insert(arkistohakemisto, '|Arkisto ' .. i ..']]')
		table.insert(arkistohakemisto, '</h2>\n')
		table.insert(arkistohakemisto, hakemisto(sivu, nimiavaruus))
		table.insert(arkistohakemisto, '\n')
	end
		
	-- Koostetaan arkistohakemisto-tauluun kertyneet merkkijonot
	-- yhteen ja palautetaan koko satsi funktion kutsujalle. 
	return table.concat( arkistohakemisto )
end


return p