Module:Seal
上述文档嵌入自Module:Seal/doc。 (编辑 | 历史) 编者可以在本模块的沙盒 (编辑 | 差异)和测试样例 (创建)页面进行实验。 本模块的子页面。 |
-- lua module that draws a seal with rows of texts
require('strict')
local p = {} --p stands for package
local getArgs = require('Module:Arguments').getArgs
local make_style_string = require('Module:Optional style').make_style_string
local error_message = require('Module:Error')['error']
-- main function
function p.seal(frame)
local args = getArgs(frame, {
trim = false,
removeBlanks = false
})
return p._seal(args)
end
-- function to draw the seal
function p._seal(args)
-- arguments
local arguments = {
['color'] = args.color or 'red',
['mode'] = args.mode or 'red',
['mode_index'] = args['mode index'] or '',
['direction'] = args.direction or 'column-rl',
['font_size'] = args['font size'] or 18,
['shape'] = args.shape or 'rectangular',
['stretch'] = args.stretch or 0,
['border_size'] = args['border size'] or 2,
['border_corner'] = args['border corner'] or 0,
['border'] = args.border or 'default',
['hscale'] = args['hscale'] or ''
}
local row_number = 0
for i,line in ipairs(args) do
row_number = row_number + 1
end
if row_number == 0 then
return error_message({['message'] = '錯誤!缺少文字内容。'})
end
-- style tables
local grid = {}
local row = {}
-- stacking and writing mode
local stacking = 'v'
local direction = 'rl';
if arguments.direction == "row" then
stacking = 'h'
else
if arguments.direction == "column-lr" then
direction = 'lr'
end
grid['writing-mode'] = 'vertical-' .. direction
end
-- colors
local text_color = arguments.color
local background_color = 'white'
if arguments.mode == "white" then
text_color = 'white'
background_color = arguments.color
end
grid['background-color'] = background_color
-- mixed mode
local mode_string
if arguments.mode == "mixed" then
-- color
local mode_length = #arguments.mode_index
if mode_length > row_number then
mode_string = string.sub(arguments.mode_index,1,row_number)
else
mode_string = arguments.mode_index .. string.rep('r', row_number - mode_length)
end
end
-- font size
local font_size = tonumber(arguments.font_size)
if font_size <= 0 then
return error_message({['message'] = '錯誤!字體大小不能為0或負數'})
end
row['font-size'] = tostring(font_size) .. 'px'
-- padding
grid['padding'] = '0.5px'
-- stretch modes
-- h stretch
local stretch_h = false
local hscale_string = ''
if arguments.hscale ~= '' then
stretch_h = true
local hscale_length = #arguments.hscale
if hscale_length > row_number then
hscale_string = string.sub(arguments.hscale, 1, row_number)
else
hscale_string = arguments.hscale .. string.rep('1', row_number - hscale_length)
end
end
-- stretch
local line_height = font_size
local stretch = tonumber(arguments.stretch)
local line_scale = 1
local pad_white_row = 0
if stretch > 0 then
-- stretch the texts
line_scale = math.floor( stretch * 100 / row_number) / 100
if line_scale < 1 then
line_height = math.floor( stretch * font_size / row_number)
pad_white_row = line_height / 4
else
local row_gap = (line_scale - 1) * font_size
grid['row-gap'] = tostring(row_gap) .. 'px'
local extra_x_padding = 0.5 * (line_scale - 1) * font_size + 0.5
grid['padding'] = grid['padding'] .. ' ' .. tostring(extra_x_padding) .. 'px'
end
if not stretch_h then
if stacking == 'v' then
row['transform'] = 'scale(' .. tostring(line_scale) .. ',1)'
else
row['transform'] = 'scale(1,' .. tostring(line_scale) .. ')'
end
end
elseif arguments.shape == 'circle' then
end
if stretch > 0 or stretch_h then
row['transform-origin'] = 'center'
end
grid['line-height'] = tostring(line_height) .. 'px'
-- border
local border_size = tonumber(arguments.border_size)
if border_size < 0 then
return error_message({['message'] = '錯誤!border 大小不能為負數'})
end
grid['border'] = tostring(border_size) .. 'px solid ' .. arguments.color
-- double border
if arguments.border == 'double' then
local inner_border = math.floor( font_size /9 * 10)/10
local shadow = border_size - inner_border
local double_padding = math.min(0.5, inner_border)
grid['border'] = tostring(double_padding) .. 'px solid ' .. arguments.color
grid['padding'] = nil
grid['margin'] = tostring(shadow) .. 'px'
grid['box-shadow'] = '0 0 0 ' .. tostring(inner_border) .. 'px white, 0 0 0 ' .. tostring(shadow) .. 'px ' .. arguments.color
end
-- border corner
local border_corner = tonumber(arguments.border_corner)
local inner_corner = 0
if border_corner > 0 then
inner_corner = math.max(0, border_corner - border_size)
end
grid['border-radius'] = tostring(border_corner) .. 'px'
local corner1 = ''
local corner2 = ''
local corner3 = ''
local corner4 = ''
if inner_corner > 0 then
if stacking == 'v' then
local tail_a = (direction == 'lr' ) and 'left' or 'right'
local tail_b = (direction == 'lr' ) and 'right' or 'left'
corner1 = 'top-' .. tail_a
corner2 = 'bottom-' .. tail_a
corner3 = 'top-' .. tail_b
corner4 = 'bottom-' .. tail_b
else
corner1 = 'top-left'
corner2 = 'top-right'
corner3 = 'bottom-left'
corner4 = 'bottom-right'
end
end
-- construct the table
local grid_style = make_style_string(grid)
local row_style = make_style_string(row)
local seal_table = {}
for i,line in ipairs(args) do
local this_row = {}
if arguments.mode == "mixed" and string.sub(mode_string, i, i) == 'w' then
this_row['color'] = background_color
this_row['background-color'] = text_color
-- additional padding of rows of mode=white
if line_scale < 1 then
if stacking == 'v' then
this_row['padding'] = '0 ' .. tostring(pad_white_row) .. 'px'
this_row['margin'] = '0 -' .. tostring(pad_white_row) .. 'px'
else
this_row['padding'] = tostring(pad_white_row) .. 'px 0'
this_row['margin'] = '-' .. tostring(pad_white_row) .. 'px 0'
end
end
else
this_row['color'] = text_color
this_row['background-color'] = background_color
end
if stretch_h then
local h_scale = string.sub(hscale_string, i, i)
if h_scale ~= 1 or line_scale ~= 1 then
if stacking == 'v' then
this_row['transform'] = 'scale(' .. tostring(line_scale) .. ',' .. h_scale .. ')'
else
this_row['transform'] = 'scale(' .. h_scale .. ',' .. tostring(line_scale) .. ')'
end
end
end
if i == 1 and border_corner > 0 then
this_row['border-' .. corner1 .. '-radius'] = tostring(inner_corner) .. 'px'
this_row['border-' .. corner2 .. '-radius'] = tostring(inner_corner) .. 'px'
end
if i == row_number and border_corner > 0 then
this_row['border-' .. corner3 .. '-radius'] = tostring(inner_corner) .. 'px'
this_row['border-' .. corner4 .. '-radius'] = tostring(inner_corner) .. 'px'
end
local additional_row_style = make_style_string(this_row)
local this_row_style = mw.ustring.sub(row_style, 1, -2) .. mw.ustring.sub(additional_row_style, 8, -1)
table.insert(seal_table, '<span class="seal-row-' .. stacking .. '" ' .. this_row_style .. '>' .. line .. '</span>')
end
local seal_rows = table.concat(seal_table)
local seal_grid = '<span class="seal-grid-' .. stacking .. '" ' .. grid_style .. '>' .. seal_rows .. '</span>'
--error(seal_grid)
return seal_grid
end
return p