Module:FR:RailwaySignalState

From OpenStreetMap Wiki
Jump to navigation Jump to search
[Edit] [Purge] Documentation

Exemple

{{#invoke:FR:RailwaySignalState|render}}

-- /!\ Work in progress.
local p = {}

-- Signal names
local signalNames = {
    CARRE = {name = "Carré" },
    S = {name = "Sémaphore" },
    D = {name = "Disque" },
    CV = {name = "Carré violet" },
}

-- Signal shapes mapped to signal types and widths
local signalShapes = {
    A = {signal = "S", width = "60"},
    C = {signal = "CARRE", width = "60"},
    F = {signal = "CARRE", width = "120"},
    H = {signal = "CARRE", width = "120"},
    R = {signal = "D", width = "120"},
    K = {signal = "CV", width = "46"}
}

-- Information by state
local stateInfo = {
    C = {
        fullname = "Carré",
        description = "Two horizontal or vertical fixed red lights.",
        information = "The signal is equipped with both a clearing light ('''œilleton''') and a '''Nf''' (Non franchissable) plate. " ..
        			  "The clearing light is always turned on except when the Carré (C) state is displayed.",
        action = "Absolute Stop.",
        targets = {
            main = { "C1", "F1", "H1" }
        }
    },
    CV = {
        fullname = "Carré violet",
        description = "One single fixed purple light.",
        action = "Absolute stop.",
        targets = {
            main = { "C2", "F2", "H2" },
            shunting = { "A2", "K2" }
        }
    },
    S = {
        fullname = "Sémaphore",
        description = "One single fixed red light.",
        action = "Stop",
        targets = {
            main = { "A1", "A3", "C1", "F1", "H1", "K1" }
        }
    },
    ["(S)"] = {
        fullname = "Feu rouge clignotant.",
        description = "One single flashing red light.",
        action = "The driver may proceed without stopping, en marche à vue, but must not exceed 15 km/h when crossing this signal.\n\n" ..
                 "This state is used on gradients to avoid a complete stop and difficult restart for a heavy train, " ..
                 "or in place of a warning (avertissement) signal for a very short block, "..
                 "or on an occupied track, e.g., for positioning a locomotive at the head (mise en tête).",
        targets = {
            main = { "A1", "A3", "C1", "F1", "H1", "K1" }
        }
    },
    D = {
        fullname = "Disque",
        description = "Both a yellow light and a red light, horizontally aligned.",
        action = "TBD",
        targets = {
            distant = {"R6"}
        }
    },
    A = {
        fullname = "Avertissement",
        description = "One fixed yellow light.",
        action = "TBD",
        targets = {
            main = { "A1", "C1", "F1", "H1" },
            distant = { "R6" }           
        }
    },
    ["(A)"] = {
        fullname = "Feu jaune clignotant",
        description = "One flashing yellow light.",
        action = "Ralentir. TBD",
        targets = {
            main = { "A1", "A3", "C1", "F1", "H1" },
            distant = { "R6" }           
        }
    },
    R = {
        fullname = "Ralentissement 30",
        description = "Two fixed horizontal yellow lights.",
        action = "Ralentir.",
        targets = {
            main = { "F1", "H1" },
            distant = { "R6" }           
        }
    },
    ["R+A"] = {
        fullname = "Ralentissement 30 et avertissement",
        description = "Two fixed horizontal yellow lights and one additional fixed yellow light.",
        action = "TBD",
        targets = {
            main = { "F1", "H1" },
            distant = { "R6" }           
        }
    },
    ["R+(A)"] = {
        fullname = "Ralentissement 30 et feu jaune clignotant",
        description = "Two fixed horizontal yellow lights and one additional flashing yellow light.",
        action = "TBD",
        targets = {
            main = { "F1", "H1" },
            distant = { "R6" }           
        }
    },
    ["(R)"] = {
        fullname = "Ralentissement 60",
        description = "Two flashing horizontal yellow lights.",
        action = "TBD",
        targets = {
            main = { "F1", "H1" },
            distant = { "R6" }           
        }
    },
    ["(R)+A"] = {
        fullname = "Ralentissement 60 et avertissement",
        description = "Two flashing horizontal yellow lights and one additional fixed yellow light.",
        action = "TBD",
        targets = {
            main = { "F1", "H1" },
            distant = { "R6" }           
        }
    },
    ["(R)+(A)"] = {
        fullname = "Ralentissement 60 et feu jaune clignotant",
        description = "Two flashing horizontal yellow lights and one additional flashing yellow light.",
        action = "TBD",
        targets = {
            main = { "F1", "H1" },
            distant = { "R6" }           
        }
    },
    RR = {
        fullname = "Rappel 30",
        description = "Two fixed vertical yellow lights.",
        action = "TBD",
        targets = {
            main = { "H1" }
        }
    },
    ["RR+A"] = {
        fullname = "Rappel 30 et avertissement",
        description = "Two fixed vertical yellow lights and one additional fixed yellow light.",
        action = "TBD",
        targets = {
            main = { "H1" }
        }
    },
    ["RR+(A)"] = {
        fullname = "Rappel 30 et feu jaune clignotant",
        description = "Two fixed vertical yellow lights and one additional flashing yellow light.",
        action = "TBD",
        targets = {
            main = { "H1" }
        }
    },
    ["(RR)"] = {
        fullname = "Rappel 60",
        description = "Two flashing vertical yellow lights.",
        action = "TBD",
        targets = {
            main = { "H1" }
        }
    },
    ["(RR)+A"] = {
        fullname = "Rappel 60 et avertissement",
        description = "Two flashing vertical yellow lights and one additional fixed yellow light.",
        action = "TBD",
        targets = {
            main = { "H1" }
        }
    },
    ["(RR)+(A)"] = {
        fullname = "Rappel 60 et feu jaune clignotant",
        description = "Two flashing vertical yellow lights and one additional flashing yellow light.",
        action = "TBD",
        targets = {
            main = {  "H1" }
        }
    },
    M = {
        fullname = "Feu blanc",
        description = "One single fixed white light.",
        action = "Shunting allowed.",
        targets = {
            main = { "C2", "F2", "H2" },
            shunting = { "A2", "K2" }
        }
    },
    ["(M)"] = {
        fullname = "Feu blanc clignotant",
        description = "One single flashing white light.",
        action = "Shunting allowed on a short distance.",
        targets = {
            main = { "C2", "F2", "H2" },
            shunting = { "A2", "K2" }
        }
    },
    VL = {
        fullname = "Voie Libre",
        description = "One single fixed green light.",
        action = "The track ahead is clear. The driver may continue or resume normal speed if there was a previous speed restriction.",
        targets = {
            main = { "A1", "A3", "C1", "F1", "H1", "K1" },
            distant = { "R1" }
        }
    },
    ["(VL)"] = {
        fullname = "Feu vert clignotant",
        description = "One single flashing green light.",
        action = "La voie est libre, continuer. Reduce speed to 160.",
        targets = {
            main = { "A1", "A3", "C1", "F1", "H1", "K1" },
            distant = { "R1" }
        }
    }
}

-- Main function to generate content based on parameters
function p.render(frame)
    local args = frame:getParent().args
    local state = args.state or ""
    local category = args.category or "main"
    local info = stateInfo[state]
    if not info then
        return "Unknown state!"
    end

    -- Determine the image extensions based on the state
    -- MediaWiki does not support flashing lights in SVG; use animated GIFs instead.
    local ext = "svg"
    if string.find(state, "%b()") then
        ext = "gif"
    end
    
    -- Build the page
	local result = {}
    table.insert(result, "== State ==\n")
    table.insert(result, "'''" .. info.fullname .. "''' ['''" .. state .. "''']\n")
    if info.information then
        table.insert(result, "\n" .. info.information .. "\n\n")
    else
        table.insert(result, "\n")
    end
    table.insert(result, "== Description ==\n\n" .. info.description .. "\n\n")
    table.insert(result, "== Action ==\n\n" .. info.action .. "\n\n")
    table.insert(result, "== Examples ==\n\nRendering on different types of signals.\n\n")

    local targets = info.targets[category]

    if targets then
		local signalKey = "railway:signal:" .. category
    	local stateValue = frame:expandTemplate{title = "TagValue", args = {signalKey .. ":states", "FR:" .. state }}
	    local currentSection = ""

        for _, target in ipairs(targets) do
            local shape = string.sub(target, 1, 1)
        	local shapeInfo = signalShapes[shape]
        	local signalInfo = signalNames[shapeInfo.signal]
			local tagArgs = {
    			{signalKey, "FR:" .. shapeInfo.signal},
    			{signalKey .. ":shape", "FR:" .. shape},
    			{signalKey .. ":type", "FR:" .. target},
    			{signalKey .. ":states", "", stateValue .. ";*"}
			}

	        if currentSection ~= signalInfo.name then
                table.insert(result, "=== " .. signalInfo.name .. " ===\n\n")
        	    currentSection = signalInfo.name
        	end

            table.insert(result, "==== Target type \"" .. target .. "\" ====\n\n")
            table.insert(result, "[[File:" .. state .. " Cible " .. target .. "." .. ext .. "|frameless|" .. shapeInfo.width .. "px]]\n")

			for _, args in ipairs(tagArgs) do
    			table.insert(result, "*" .. frame:expandTemplate{title = "Tag", args = args} .. "\n")
			end
		end
		table.insert(result, "V1.3\n")
    else
        table.insert(result, "No targets available for the category \"" .. category .. "\".\n\n")
    end
    
    return table.concat(result)
end

return p