Module:Location map/multi: Difference between revisions

From Ikwipedia
No edit summary
Tag: Reverted
No edit summary
Tag: Reverted
Line 42: Line 42:
     end
     end


     debugLog("DEBUG: Retrieved args -> " .. mw.text.dumpObject(args))
    -- Log the args as JSON
     debugLog("DEBUG: Initial map value -> " .. mw.text.dumpObject(map or {}))
     debugLog("DEBUG: Retrieved args -> " .. mw.text.jsonEncode(args))
     debugLog("DEBUG: Initial map value -> " .. mw.text.jsonEncode(map or {}))


     -- Process map if not provided
     -- Process map if not provided
Line 96: Line 97:
         end
         end


         debugLog("DEBUG: Distributed places across maps -> " .. mw.text.dumpObject(permaplaces))
         debugLog("DEBUG: Distributed places across maps -> " .. mw.text.jsonEncode(permaplaces))


         -- Handle AlternativeMap and overlays
         -- Handle AlternativeMap and overlays
         local altmaps = switcherSeparate(args.AlternativeMap)
         local altmaps = switcherSeparate(args.AlternativeMap)
         debugLog("DEBUG: Alternative maps -> " .. mw.text.dumpObject(altmaps))
         debugLog("DEBUG: Alternative maps -> " .. mw.text.jsonEncode(altmaps))
         if #altmaps > #map then
         if #altmaps > #map then
             error(string.format('%d AlternativeMaps were provided, but only %d maps were provided', #altmaps, #map))
             error(string.format('%d AlternativeMaps were provided, but only %d maps were provided', #altmaps, #map))
Line 106: Line 107:


         local overlays = switcherSeparate(args.overlay_image)
         local overlays = switcherSeparate(args.overlay_image)
         debugLog("DEBUG: Overlay images -> " .. mw.text.dumpObject(overlays))
         debugLog("DEBUG: Overlay images -> " .. mw.text.jsonEncode(overlays))
         if #overlays > #map then
         if #overlays > #map then
             error(string.format('%d overlay_images were provided, but only %d maps were provided', #overlays, #map))
             error(string.format('%d overlay_images were provided, but only %d maps were provided', #overlays, #map))
Line 141: Line 142:
     end
     end
end
end





Revision as of 22:26, 19 November 2024

Documentation for this module may be created at Module:Location map/multi/doc

require('strict')


local debugLogs = {}

local function debugLog(msg)
    table.insert(debugLogs, tostring(msg))
end

local function renderDebugLogs()
    if #debugLogs > 0 then
        return '<pre style="background: #f9f9f9; border: 1px solid #ccc; padding: 10px; margin-top: 10px;">'
            .. table.concat(debugLogs, "\n")
            .. '</pre>'
    end
    return ''
end


local p = {}

local getArgs = require('Module:Arguments').getArgs
local locmap = require('Module:Location map')

local function switcherSeparate(s)
	if s == nil then return {} end
	local retval = {}
	for i in string.gmatch(s .. '#', '([^#]*)#') do
		i = mw.text.trim(i)
		retval[#retval + 1] = (i ~= '' and i)
	end
	return retval
end

function p.container(frame, args, map)
    debugLog("DEBUG: Entered container function")
    local caption_list = {}

    -- Retrieve args if not provided
    if not args then
        args = getArgs(frame, {wrappers = 'Template:Location map+', valueFunc = locmap.valueFunc})
    end

    -- Log the args as JSON
    debugLog("DEBUG: Retrieved args -> " .. mw.text.jsonEncode(args))
    debugLog("DEBUG: Initial map value -> " .. mw.text.jsonEncode(map or {}))

    -- Process map if not provided
    if not map then
        if args[1] then
            map = {}
            for mapname in string.gmatch(args[1], '[^#]+') do
                debugLog("DEBUG: Processing mapname -> " .. mapname)
                table.insert(map, locmap.getMapParams(mapname, frame))
            end

            -- Handle caption logic
            if args['caption'] then
                debugLog("DEBUG: Processing captions -> " .. args['caption'])
                if args['caption'] == "" then
                    while #caption_list < #map do
                        table.insert(caption_list, args['caption'])
                    end
                else
                    for caption in mw.text.gsplit(args['caption'], '##', true) do
                        table.insert(caption_list, caption)
                    end
                end
            end

            if #map == 1 then
                debugLog("DEBUG: Single map detected, simplifying structure")
                map = map[1]
            end
        else
            debugLog("DEBUG: No map specified, defaulting to 'World'")
            map = locmap.getMapParams('World', frame)
        end
    end

    -- Handle multiple maps
    if type(map) == 'table' then
        local placeslist = mw.text.gsplit(args.places, '#PlaceList#')
        local permaplaces = {}
        local numbermaps = #map
        local count = 0

        -- Initialize map-specific places
        for i = 1, numbermaps do
            permaplaces[i] = {}
        end

        -- Distribute places across maps
        for place in placeslist do
            table.insert(permaplaces[count % numbermaps + 1], place)
            count = count + 1
        end

        debugLog("DEBUG: Distributed places across maps -> " .. mw.text.jsonEncode(permaplaces))

        -- Handle AlternativeMap and overlays
        local altmaps = switcherSeparate(args.AlternativeMap)
        debugLog("DEBUG: Alternative maps -> " .. mw.text.jsonEncode(altmaps))
        if #altmaps > #map then
            error(string.format('%d AlternativeMaps were provided, but only %d maps were provided', #altmaps, #map))
        end

        local overlays = switcherSeparate(args.overlay_image)
        debugLog("DEBUG: Overlay images -> " .. mw.text.jsonEncode(overlays))
        if #overlays > #map then
            error(string.format('%d overlay_images were provided, but only %d maps were provided', #overlays, #map))
        end

        -- Validate caption count
        if #caption_list > #map then
            error(string.format('%d captions were provided, but only %d maps were provided', #caption_list, #map))
        end

        -- Generate output for each map
        local outputs = {}
        args.autoSwitcherLabel = true
        for k, v in ipairs(map) do
            debugLog("DEBUG: Processing map " .. k)
            args.AlternativeMap = altmaps[k]
            args.overlay_image = overlays[k]
            args.caption = caption_list[k]
            args.places = table.concat(permaplaces[k])
            outputs[k] = p.container(frame, args, v)
        end

        local finalOutput = '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
        debugLog("DEBUG: Final output for multiple maps -> " .. finalOutput)
        return finalOutput .. renderDebugLogs()
    else
        -- Single map handling
        debugLog("DEBUG: Processing single map")
        local finalOutput = locmap.top(frame, args, map) ..
            (args.places and args.places:gsub('%s*\n%s*', '') or '') ..
            locmap.bottom(frame, args, map)
        debugLog("DEBUG: Final output for single map -> " .. finalOutput)
        return finalOutput .. renderDebugLogs()
    end
end



local function manyMakeArgs(fullArgs, n)
	if n == 1 then
		return {
			lat = fullArgs.lat1 or fullArgs.lat,
			long = fullArgs.long1 or fullArgs.long,
			coordinates = fullArgs.coordinates1 or fullArgs.coordinates,
			lat_deg = fullArgs.lat1_deg or fullArgs.lat_deg,
			lat_min = fullArgs.lat1_min or fullArgs.lat_min,
			lat_sec = fullArgs.lat1_sec or fullArgs.lat_sec,
			lat_dir = fullArgs.lat1_dir or fullArgs.lat_dir,
			lon_deg = fullArgs.lon1_deg or fullArgs.lon_deg,
			lon_min = fullArgs.lon1_min or fullArgs.lon_min,
			lon_sec = fullArgs.lon1_sec or fullArgs.lon_sec,
			lon_dir = fullArgs.lon1_dir or fullArgs.lon_dir,
			outside = fullArgs.outside1 or fullArgs.outside,
			mark = fullArgs.mark1 or fullArgs.mark,
			marksize = fullArgs.mark1size or fullArgs.marksize,
			link = fullArgs.link1 or fullArgs.link,
			label = fullArgs.label1 or fullArgs.label,
			label_size = fullArgs.label1_size or fullArgs.label_size,
			label_width = fullArgs.label1_width or fullArgs.label_width,
			position = fullArgs.position1 or fullArgs.pos1 or fullArgs.position or fullArgs.pos,
			background = fullArgs.background1 or fullArgs.bg1 or fullArgs.background or fullArgs.bg
		}
	else
		return {
			lat = fullArgs['lat' .. n],
			long = fullArgs['long' .. n],
			coordinates = fullArgs['coordinates' .. n],
			lat_deg = fullArgs['lat' .. n .. '_deg'],
			lat_min = fullArgs['lat' .. n .. '_min'],
			lat_sec = fullArgs['lat' .. n .. '_sec'],
			lat_dir = fullArgs['lat' .. n .. '_dir'],
			lon_deg = fullArgs['lon' .. n .. '_deg'],
			lon_min = fullArgs['lon' .. n .. '_min'],
			lon_sec = fullArgs['lon' .. n .. '_sec'],
			lon_dir = fullArgs['lon' .. n .. '_dir'],
			outside = fullArgs['outside' .. n],
			mark = fullArgs['mark' .. n],
			marksize = fullArgs['mark' .. n .. 'size'],
			link = fullArgs['link' .. n],
			label = fullArgs['label' .. n],
			label_size = fullArgs['label' .. n .. '_size'],
			label_width = fullArgs['label' .. n .. '_width'],
			position = fullArgs['position' .. n] or fullArgs['pos' .. n],
			background = fullArgs['background' .. n] or fullArgs['bg' .. n]
		}
	end
end

function p.many(frame, args, map)
	if not args then
		args = getArgs(frame, {wrappers = 'Template:Location map many', valueFunc = locmap.valueFunc})
	end
	if not args[1] then
		args[1] = 'World'
	end
	if not map then
		map = {}
		for mapname in string.gmatch(args[1], '[^#]+') do
			map[#map + 1] = locmap.getMapParams(mapname, frame)
		end
		if #map ~= 1 then
			local outputs = {}
			args.autoSwitcherLabel = true
			for k,v in ipairs(map) do
				outputs[k] = p.many(frame, args, v)
			end
			return '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
		end
		map = map[1]
	end
	local marks = {}
	local markhigh
	if args.markhigh then
		mw.log('Removed parameter markhigh used.')
		local parent = frame:getParent()
		if parent then
			mw.log('Parent is ' .. parent:getTitle())
		end
		mw.logObject(args, 'args')
		markhigh = true
	end
	for k, v in pairs(args) do -- @todo change to uargs once we have that
		if v then
			if string.sub(k, -4) == '_deg' then
				k = string.sub(k, 1, -5)
			end
			if string.sub(k, 1, 3) == 'lat' then
				k = tonumber(string.sub(k, 4))
				if k then
					table.insert(marks, k)
				end
			elseif string.sub(k, 1, 11) == 'coordinates' then
				k = tonumber(string.sub(k, 12))
				if k then
					table.insert(marks,k)
				end
			end
		end
	end
	table.sort(marks)
	if marks[1] ~= 1 and (args.lat or args.lat_deg or args.coordinates) then
		table.insert(marks, 1, 1)
	end
	local body = ''
	for _, v in ipairs(marks) do
		-- don't try to consolidate this into the above loop. ordering of elements from pairs() is unspecified
		body = body .. tostring( locmap.mark(frame, manyMakeArgs(args, v), map) )
		if args['mark' .. v .. 'high'] then
			mw.log('Removed parameter mark' .. v .. 'high used.')
			local parent = frame:getParent()
			if parent then
				mw.log('Parent is ' .. parent:getTitle())
			end
			mw.logObject(args, 'args')
			markhigh = true
		end
	end
	args.label = nil -- there is no global label
	return locmap.top(frame, args, map) .. body .. locmap.bottom(frame, args, map) .. (markhigh and '[[Category:Location maps with possible errors|Page using removed parameter]]' or '')
end

function p.load(frame, args, map)
	if not args then
		args = getArgs(frame, {frameOnly = true})
	end
	local dataModule = mw.loadData(args[1])
	local containerArgs = dataModule.containerArgs
	if not map then
		map = {}
		for mapname in string.gmatch(containerArgs[1], '[^#]+') do
			map[#map + 1] = locmap.getMapParams(mapname, frame)
		end
		if #map ~= 1 then
			local outputs = {}
			args.autoSwitcherLabel = true
			for k,v in ipairs(map) do
				outputs[k] = p.load(frame, args, v)
			end
			return '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
		end
		map = map[1]
	end
	local marks = {}
	if dataModule.marks then
		for k,markArgs in ipairs(dataModule.marks) do
			marks[k] = tostring(locmap.mark(frame, markArgs, map))
		end
	end
	if dataModule.secondaryModules then
		for _,modname in ipairs(dataModule.secondaryModules) do
			for _,markArgs in ipairs(mw.loadData(modname).marks) do
				marks[#marks + 1] = tostring(locmap.mark(frame, markArgs, map))
			end
		end
	end
	if args.autoSwitcherLabel then
		local TableTools = require('Module:TableTools')
		containerArgs = TableTools.shallowClone(containerArgs)
		containerArgs.autoSwitcherLabel = true
	end
	return locmap.top(frame, containerArgs, map) .. table.concat(marks) .. locmap.bottom(frame, containerArgs, map)
end

return p