Module:Color
Aller à la navigation
Aller à la recherche
Ce module est utilisé par le Modèle:Color pour afficher des carrés de couleur selon le nom précisé. Les noms de couleurs utilisables peuvent être vus dans le Module:Color/codes.
local p = {}
local Utility = require( 'Module:Utility' )
local colorCodes = mw.loadData( 'Module:Color/codes' )
local colorIds = mw.loadData( 'Module:Color/ids' )
local SQUARE_SIZE = 20
function p.parseRgbHex( hex )
hex = hex:gsub( '#', '' )
return {
tonumber( '0x'..hex:sub( 1, 2 ) ),
tonumber( '0x'..hex:sub( 3, 4 ) ),
tonumber( '0x'..hex:sub( 5, 6 ) )
}
end
function p.selectTextColor( color )
return ( color[1] * 0.2126 + color[2] * 0.7152 + color[3] * 0.0722 > (0.5 * 255) ) and 'black' or 'white'
end
local function findColorName(colorId)
for name, id in pairs(colorIds) do
if id == colorId then
return name
end
end
return ''
end
function p.colors( f )
local args = f:getParent().args
local colorBlocks = {}
local size = 20
local colorNameLower = ''
local colorId = 0
local colorCode = ''
local unknownId = 256
--This slices one parameter into a variable number of parameters with a comma as a delimiter.
--This allows the list to be called into another Template as its own parameter.
local M_SLICES = {}
for part in string.gmatch((args[1])..',', "([^,]*),") do
local slice = part:match "^%s*(.-)%s*$"
if #slice <= 3 and tonumber(slice) ~= nil then
slice = findColorName(slice)
end
table.insert(M_SLICES, slice)
end
local colorIdsOrdered={}
for _, colorNameInput in ipairs(M_SLICES) do
colorNameLower = colorNameInput:gsub('%W',''):lower()
colorId = colorIds[colorNameLower]
if colorId ~= nil then
colorId = tonumber(colorId)
end
-- colorId must be a number for the sorting later
-- internally in this module, an unknown id is represented by numbers > 256
if colorId == nil then
colorId = unknownId
unknownId = unknownId + 1
end
colorCode = colorCodes[colorNameLower]
if colorCode ~= nil and not p.isColorNameInTable(colorIdsOrdered, colorNameLower) then
table.insert(colorIdsOrdered, {colorId, colorCode, colorNameInput})
end
end
-- the sorting function must be stable, i.e. a==b => b==a
table.sort(colorIdsOrdered, function(a,b) return a[1] < b[1] end)
-- colorInfo[1]: color Id
-- colorInfo[2]: color code (hex)
-- colorInfo[3]: color name as entered in the template call
for _, colorInfo in ipairs(colorIdsOrdered) do
table.insert( colorBlocks, string.format(
'<div class="color-square" style="height:%dpx; width: %dpx; background: %s; color: %s" title="%s (%s)">%s</div>',
size, size, colorInfo[2], p.selectTextColor( p.parseRgbHex( colorInfo[2] ) ), colorInfo[3],
(colorInfo[1] < 256 and colorInfo[1] or 'no id'),
(colorInfo[1] < 256 and '<span>'..colorInfo[1]..'</span>' or '')
) )
end
return '<div class="color-container">'..table.concat(colorBlocks)..'</div>'
end
function p.isColorNameInTable(tab, colorNameLower)
for _, colorInfo in ipairs(tab) do
if colorInfo[3] == colorNameLower then return true end
end
return false
end
function p.queryColorTable()
local results = Utility.runCachedCargoQuery( 'ColorTable', {
tableName = 'Colors',
fields = 'Id, Name, sRGB',
expiryTime = 60 * 60 * 8,
options = {
orderBy = 'Id ASC',
},
} )
for index = 1, #results do
results[index].Id = tonumber( results[index].Id )
end
return results
end
function p.findRecord( records, needle )
if tonumber( needle ) ~= nil then
needle = tonumber( needle )
elseif type( needle ) == 'string' then
needle = mw.text.trim( string.lower( needle ) )
end
for index = 1, #records do
local record = records[index]
local compared
if type( needle ) == 'number' then
compared = record.Id
else
compared = string.lower( record.Name )
end
if compared == needle then
return record
end
end
return nil
end
function p.selectSubset( records, needles )
local out = {}
local needleMap = {}
local expectedCount = 0
for index = 1, #needles do
local needle = needles[index]
if tonumber( needle ) ~= nil then
needle = tonumber( needle )
elseif type( needle ) == 'string' then
needle = mw.text.trim( string.lower( needle ) )
end
if needle ~= '' and needleMap[needle] == nil then
needleMap[needle] = true
expectedCount = expectedCount + 1
end
end
for index = 1, #records do
local record = records[index]
if needleMap[record.Id] or needleMap[string.lower( record.Name )] then
out[#out + 1] = record
end
end
if expectedCount ~= #out then
--error( 'Une ou des couleurs non pas été trouvées dans le tableau' )
out[#out + 1] = {
Id = 0,
Name = 'Non définie',
sRGB = '00000000'
}
end
return out
end
function p.makeColoredSquares( records )
local out = {}
table.sort( records, function ( a, b ) return a.Id < b.Id end )
for index = 1, #records do
local record = records[index]
out[#out + 1] = string.format(
'<div class="color-square" style="height: %dpx; width: %dpx; background: #%s; color: %s" '
.. 'title="%s (%d)"><span>%d</span></div>',
SQUARE_SIZE,
SQUARE_SIZE,
record.sRGB,
p.selectTextColor( p.parseRgbHex( record.sRGB ) ),
record.Name,
record.Id,
record.Id
)
end
return string.format( '<div class="color-container">%s</div>', table.concat( out, '' ) )
end
function p.selectTextColorW( frame )
return p.selectTextColor( p.parseRgbHex( frame.args[1] ) )
end
function p.queryW( frame )
local record = p.findRecord( p.queryColorTable(), frame.args[1] )
if record == nil then
error( 'Couleur non trouvée : ' .. frame.args[1] )
end
return record[frame.args[2]]
end
function p.makeColoredSquaresW( frame )
local colors = mw.text.split( frame.args[1], ',', true )
local records = p.selectSubset( p.queryColorTable(), colors )
return p.makeColoredSquares( records )
end
return p