Jump to content

Module:Hatnote group

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Nihiltres (talk | contribs) at 17:51, 6 October 2016 (Been tossing around this idea for handling groups of hatnotes, here's a basic implementation). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

local mHatnote = require('Module:Hatnote')
local p = {}

--Passes through single argument from parent frame
function p.group (frame)
	return p._group(frame:getParent().args[1], frame:getParent().args.category)	
end

function p._group (inputText, category)
	--If there's an error element, pass everything through unchanged for easier
	--error resolution
	if string.find(inputText, '<%a- class="error"', 1, true) then return inputText end
	
	--Heavily reused hatnote data capture pattern
	local hatnotePattern = '(<div role="note" class="hatnote%s?(.-)">(.-)</div>)'
	
	--Capture hatnote divs and "loose" categories; we'll ignore everything else
	local rawDivs = {}
	local looseCategories = ''
	for x in string.gmatch(inputText, hatnotePattern) do
		table.insert(rawDivs, x)
	end
	for x in string.gmatch(inputText, '[[Category:.-]]') do
		looseCategories = looseCategories .. x
	end

	--if no inner hatnotes, return an error
	if not rawDivs[1] then
		return mHatnote.makeWikitextError(
			'no inner hatnotes detected',
			'Template:Hatnote group',
			category
		)
	end

	--Preprocess divs into strings and classes
	local innerHatnotes = {}
	for k, v in pairs(rawDivs) do
		row = {}
		row.text = string.gsub(
			v,
			hatnotePattern,
			'%3'
		)
		--Here we set class names as keys for easier intersection later
		row.classes = {}
		for k, v in ipairs(
			mw.text.split(
				string.gsub(
					v,
					hatnotePattern,
					'%2'
				),
				' ',
				true
			)
		) do
			row.classes[v] = true
		end
			
		table.insert(innerHatnotes, row)
	end
	
	--Identify any universal classes ("hatnote" ignored by omission earlier)
	local universalClasses = innerHatnotes[1].classes
	for k, v in ipairs(innerHatnotes) do
		for l, w in ipairs(v.classes) do
			universalClasses[l] = (universalClasses[l] and w)
		end
	end
	
	--Remove universal classes from div items, then create class strings per row
	for k, v in ipairs(innerHatnotes) do
		for l, w in ipairs(v.classes) do
			if universalClasses[l] then v.classes[l] = nil end
		end
		v.classString = table.concat(v.classes, " ")
	end
	
	--Process div items into classed span items
	local innerSpans = {}
	for k, v in ipairs(innerHatnotes) do
		table.insert(
			innerSpans,
			string.format(
				'<span class="%s">%s</span>',
				v.classString,
				v.text
			)
		)
	end

	--Concatenate spans and categories, and return wrapped as a single hatnote
	local outputText = table.concat(innerSpans, " ") .. looseCategories
	local hnOptions = {extraClasses = table.concat(universalClasses, " ")}
	return mHatnote._hatnote(outputText)
end

return p