Moduli:Вложенный список

On otettu Рувики-späi

Tämän moduulin ohjeistuksen voi tehdä sivulle Moduli:Вложенный список/ohje

--
-- Implements {{Вложенный список}} in one module
-- Allows us to potentially move towards a more accessible markup for the template when the time is right
-- Previously, the template broke the lists {{Вложенный список}} or {{NL2}} or {{NL3}} are in
-- Heavily borrows from https://en.wikipedia.org/wiki/Module:Excerpt_slideshow
--
local getArgs = require('Module:Arguments').getArgs

local errorCat = 'Рувики:Страницы с ошибками шаблона Вложенный список'

local noTitle = 'Нет названия страницы.'
local noContent = 'Ошибка при включении страницы «[[%s]]».'

local p = {}

--[[
	@param {String} wikitext: Wikitext of just the list (i.e. each line is a list item)
	@param {String} symbol:   Special character used in the wikitext markup for the list, e.g. '*' or '#'
	@param {String} outerTag: Text portion of the tag for each list or sublist, e.g. 'ul' or 'ol'
	@param {String} innerTag: Text portion of the tag for each list item, e.g. 'li'
]]
local wikitextToHtmlList = function(wikitext, symbol, outerTag, innerTag)
	local listParts = {}
	for level, item in mw.ustring.gmatch('\n'..wikitext..'\n', '\n(%'..symbol..'+)(.-)%f[\n]') do
	    table.insert(listParts, {level=level, item=item})
	end
	table.insert(listParts, {level='', item=''})
	
	local htmlList = {}
	for i, this in ipairs( listParts ) do
		local isFirstItem = (i == 1)
		local isLastItem = (i == #listParts)
	    local lastLevel = isFirstItem and '' or listParts[i-1]['level']
	    local tags
	    if #lastLevel == #this.level then
	    	tags = '</'..innerTag..'><'..innerTag..'>'
	    elseif #this.level > #lastLevel then
	    	tags = string.rep('<'..outerTag..'><'..innerTag..'>', #this.level - #lastLevel)
	    elseif isLastItem then
	    	tags = string.rep('</'..innerTag..'></'..outerTag..'>', #lastLevel)
	    else -- ( #this.level < #lastLevel ) and not last item
	    	tags = string.rep('</'..innerTag..'></'..outerTag..'>', #lastLevel - #this.level ) .. '</'..innerTag..'><'..innerTag..'>'
	    end
	    table.insert(htmlList, tags .. this.item)
	end
	return table.concat(htmlList)
end


--[[
	@param {String} wikitext: Wikitext excertp containg zero or more lists
	@param {String} symbol:   Special character used in the wikitext markup for the list, e.g. '*' or '#'
	@param {String} outerTag: Text portion of the tag for each list or sublist, e.g. 'ul' or 'ol'
	@param {String} innerTag: Text portion of the tag for each list item, e.g. 'li'
]]
local gsubWikitextLists = function(wikitext, symbol, outerTag, innerTag)
	-- temporarily remove list linebreaks... 
	wikitext = mw.ustring.gsub(wikitext..'\n', '\n%'..symbol, '¿¿¿'..symbol) 
	-- ...so we can grab the whole list (and just the list)...
	return mw.ustring.gsub(
		wikitext,
		'¿¿¿%'..symbol..'[^\n]+', 
		function(listWikitext)
			-- ...and then reinstate linebreaks...
			listWikitext = mw.ustring.gsub(listWikitext, '¿¿¿%'..symbol, '\n'..symbol)
			-- ...and finally do the conversion
			return wikitextToHtmlList(listWikitext, symbol, outerTag, innerTag)
		end
	)
end

function p.main(frame)
	local args = getArgs(frame)
	
	local title = args[1]
	local displayedTitle = args[2] and '|' .. args[2] or ''
	local appendedText = args[3] and ' ' .. args[3] or ''
	
	if title == nil or title == '' then
		return '<div class="error">' .. noTitle .. '</div>'
	end
	
	local intro = string.format('<span class="dabhide">[[%s%s]]</span>%s:', title, displayedTitle, appendedText)
	-- frame:expandTemplate is used because mw.title:getContent() does not handle redirects
	local sublistExists, sublist = pcall(function ()
		return frame:expandTemplate{ title = ':' .. title }
	end)
	
	-- The page does not exist or returns empty
	if sublistExists ~= true or mw.text.trim(sublist) == '' then
		return intro .. '<div class="error">' .. string.format(noContent, title) .. '</div>'
			.. string.format('[[Category:%s]]', errorCat)
	end
	
	-- Replace list markers with HTML list openers
	sublist = gsubWikitextLists('\n' .. sublist, '*', 'ul', 'li')
	
	-- Replace all line breaks to avoid breaking the list
	sublist = mw.ustring.gsub(mw.text.trim(sublist), '\n\n', '<p>')
	sublist = mw.ustring.gsub(mw.text.trim(sublist), '\n', '<br>')
	
	return intro .. sublist
end

return p