Module:The Color Printer tone/sandbox

From Wikisource
Jump to navigation Jump to search
require('strict')

local p = {}

local getArgs = require('Module:Arguments').getArgs
local freedImg = require('Module:FreedImg')._freedImg
local colorData = require('Module:The Color Printer tone/data').colorData
local weighted_color_blend = require('Module:The Color Printer tone/data').weighted_color_blend

--[=[
Input list of colors and weights
	{{color = {r, g, b}, weight = n}, ...}
Output color
	color-mix(in srgb, rgb(r, g, b) X%, ...)
]=]
--[=[ commented out because it's not widely supported yet
local function css_color_mix(args)
	local total_weight = 0
	for k, v in pairs(args) do
		total_weight = total_weight + v.weight
	end
	if total_weight == 0 then
		total_weight = 1
	end
	
	local colors = {}
	for k, v in pairs(args) do
		-- for some reason, concatenating rgb works but concatenating v['color'] doesn't
		local rgb = {}
		for i = 1, 3 do
			rgb[i] = v['color'][i]
		end
		table.insert(colors, 'rgb(' .. table.concat(rgb, ', ') .. ') ' .. (100 * v.weight/total_weight) .. '%')
	end
	
	return 'color-mix(in srgb, ' .. table.concat(colors, ', ') .. ')'
end
]=]

local function color_blend_text(weight, color)
	local parts_text = 'parts'
	if weight == 1 then
		parts_text = 'part'
	end
	local color_text = color
	if color == 'w' then
		color_text = 'White'
	end
	return weight .. ' ' .. parts_text .. ' of ' .. color_text
end

local function color_printer_tone(args)
	-- stylesheets
	local current_frame = mw.getCurrentFrame()
	local stylesheets = table.concat({
		current_frame:extensionTag('templatestyles', '', {src = 'Index:The color printer (1892).djvu/styles.css'}),
		current_frame:extensionTag('templatestyles', '', {src = 'Template:FreedImg/styles.css'})
	})
	
	-- image
	local image = freedImg(
		true,
		{
			['file'] = args.file or 'missing',
			width = '100px',
			alt = 'Demonstration of two-color mixture'
		})
	
	-- get number of arguments (largest-numbered parameter)
	-- can't use #args because that doesn't work consistently on tables that aren't sequences
	-- table.maxn also seems not to work
	local max_n = 0
	for k, v in pairs(args) do
		local i = tonumber(k)
		if i and i > max_n then
			max_n = i
		end
	end
	
	-- extract info
	local color_blend_args = {}
	local blend_text_args = {}
	for i = 2, max_n, 2 do
		local color = tonumber(args[i + 1]) or args[i + 1] or 'w'
		if not colorData[color] then
			error('Color ' .. color .. ' not found in colorData')
		end
		local weight = tonumber(args[i]) or 0
		table.insert(color_blend_args, {color = colorData[color]['rgb'], weight = weight})
		table.insert(blend_text_args, color_blend_text(weight, color))
	end
	
	-- swatch
	local swatch_color = 'rgb(' .. table.concat(weighted_color_blend(color_blend_args), ', ') .. ')'
	local swatch = mw.html.create('div')
		:addClass('wst-color-printer-swatch')
		:css({
			['background-color'] = swatch_color,
            ['color'] = 'inherit'
		})
	
	-- text
	local number_text = mw.html.create('div')
		:addClass('wst-color-printer-number')
		:wikitext(args[1] or '')
	
	local blend_text = table.concat(blend_text_args, '<br>')
	
	-- assemble
	local tone_div = mw.html.create('div')
		:addClass('wst-color-printer-tone')
		:wikitext(image)
		:node(swatch)
		:node(number_text)
		:wikitext(blend_text)
	
	return stylesheets .. tostring(tone_div)
end

function p.color_printer_tone(frame)
	return color_printer_tone(getArgs(frame))
end

return p