Module:Gradient
Jump to navigation
Jump to search
g = {};
convert = require( "Module:BaseConvert" );
math_mod = require( "Module:Math" );
function hexToDec( val )
return convert.convert( { n = val, base = 10, from = 16, precision = 0, width = 3 } );
end
function decToHex( val )
return convert.convert( { n = val, base = 16, precision = 0, width = 2 } );
end
function getTriplet( hex_code )
local v1, v2, v3;
v1 = hexToDec( hex_code:sub(1,2) );
v2 = hexToDec( hex_code:sub(3,4) );
v3 = hexToDec( hex_code:sub(5,6) );
return v1, v2, v3;
end
function makeTriplet( v1, v2, v3 )
local val = {
decToHex( v1 ),
decToHex( v2 ),
decToHex( v3 )
}
return table.concat( val );
end
function g.export_gradient( frame )
local result = {};
local index = 1;
local pos, color;
local v1,v2,v3;
while true do
pos = frame.args[index];
color = frame.args[index + 1];
index = index + 2;
if color == nil or pos == nil then
break;
end
pos = tonumber( pos );
color = color:match( "^%s*(.-)%s*$" );
if color:sub(1,1) == '#' then
color = color:sub(2);
end
v1, v2, v3 = getTriplet( color );
table.insert( result, pos .. ': ' .. v1 .. ', ' .. v2 .. ', ' .. v3 .. '; ' );
end
return table.concat( result );
end
function importGradient( gradientString )
local pattern_table = {};
gradientString = gradientString:gsub( ' ', '' );
for pos, v1, v2, v3 in string.gmatch( gradientString , "([-%d%.]*):(%d+),(%d+),(%d+);") do
table.insert( pattern_table, { tonumber(pos), tonumber(v1), tonumber(v2), tonumber(v3) } );
end
comp = function( a, b ) return a[1] < b[1]; end
table.sort( pattern_table, comp );
return pattern_table;
end
function getGradientValue( value, gradient_table )
local last_pos = nil;
local last_item = nil;
for _, v in ipairs( gradient_table ) do
if v[1] >= value then
if last_item == nil then
return v[2], v[3], v[4];
else
local shift = (value - last_item[1]) / (v[1] - last_item[1]);
return shift*v[2] + (1-shift)*last_item[2],
shift*v[3] + (1-shift)*last_item[3],
shift*v[4] + (1-shift)*last_item[4]
end
end
last_item = v;
end
return last_item[2], last_item[3], last_item[4];
end
function g.gradient_value( frame )
local gradient = frame.args.gradient;
local value = tonumber( frame.args[1] or frame.args.value );
local v1, v2, v3;
if gradient == nil then
return '';
end
gradient = importGradient( gradient );
v1, v2, v3 = getGradientValue( value, gradient );
return makeTriplet( v1, v2, v3 );
end
function g.gradient_test( frame )
local gradient = frame.args.gradient;
local step = frame.args.step;
local row_break = tonumber( frame.args.cells_per_row or 20 );
if gradient == nil then
return '';
end
gradient = importGradient( gradient );
local min_value = nil;
local max_value = nil;
for _, v in ipairs( gradient ) do
if min_value == nil or min_value > v[1] then
min_value = v[1];
end
if max_value == nil or max_value < v[1] then
max_value = v[1];
end
end
if step == nil then
step = (max_value - min_value)/30;
step = math_mod._round( step, math.max( math_mod._precision( max_value ), math_mod._precision( min_value ) ) + 1 );
end
local result = "{| class=wikitable \n";
local v1, v2, v3, color;
local count = 0;
for i = min_value,max_value+step/2,step do
v1, v2, v3 = getGradientValue( i, gradient );
color = makeTriplet( v1, v2, v3 );
result = result .. '| style="background-color:#' .. color .. '; width:2em; text-align:center;" | ' .. i ..
'<br \><span style="color:#FFFFFF">' .. i .. '</span>\n';
count = count + 1;
if count == row_break then
result = result .. '|- \n';
count = 0;
end
end
result = result .. "|}"
return result;
end
return g;