モジュール:Shogi diagramtest

このモジュールについての説明文ページを モジュール:Shogi diagramtest/doc に作成できます

local shogiobject = {}

-----------------------
-- internal functions 
-----------------------


-- returns a japanese character for a roman letter abbreviation
-- called by the shogiboard() function
local function piecesymbol(abbreviation)
	-- the abbreviation argument is a string of 1-3 letters that stand for the English names of the shogi pieces
	-- the abbreviation is extracted out of a longer string by the processString() function
	
	-- letter to character mapping (hash table)
	local piecenames = {
		p = '歩',
		t = 'と',
		l = '香',
		pl = '杏',
		n = '桂',
		pn = '圭',
		s = '銀',
		ps = '全',
		g = '金',
		b = '角',
		h = '馬',
		r = '飛',
		d = '龍',
		k = '玉',
		ak = '王',
		tx = '个',
		plx = '仝',
		pnx = '今',
		dx = '竜',
		e = '象',
		a = '太',
	}
	-- spit out the character corresponding to abbreviation
	-- if the abbreviation string is empty, then spit out nobreak space (for html tables)		
	piece = piecenames[abbreviation] or ' '
	return string.format( piece )
end


-- function separates out the piece, the side, and the boldness info present in the string argument
-- it returns an array with these three values plus the color (for promoted pieces)
-- this info is passed to the makeTD() function
function processString(ss)
	-- strip whitespace
	ss = mw.text.trim(ss)
	
	-- get the last character of the string
	local lastchar = mw.ustring.sub(ss, -1)
	
	-- chop off last character of string
	local restofstring = mw.ustring.sub(ss, 1, -2)

	-- default is normal font
	-- but if the string ends with 'l' for 'last move', then the font should be bold and we need to get a new string with the this 'l' chopped off (with a new last character)
	local boldness = 'normal'
	if lastchar:match('l') then
		boldness = 'bold'
		lastchar = mw.ustring.sub(restofstring, -1)
		restofstring = mw.ustring.sub(restofstring, 1, -2)
	end
	
	-- the side is either 'g' for 'gote' or 's' for 'sente'
	-- it's the last character in the string (and if the string ended)
	local side = lastchar
	
	-- the leftover string is the shogi piece abbreviation
	local pieceabbr = restofstring
	
	-- default is black font
	-- if the piece is promoted (one the abbreviations below), then the piece should be red
	local color = 'black'
	if pieceabbr:match('t') or pieceabbr:match('pl') or pieceabbr:match('pn') or pieceabbr:match('ps') or pieceabbr:match('h') or pieceabbr:match('d') then
		color = 'red'
	end
	-- this is an exceptional bit:
	-- gote's king is usually 王 instead of 玉 by convention, 
	-- but it's convenient to use the 'k' code for both sente and gote and let the default character be side-dependent
	if pieceabbr:match('k') and side:match('g') then
		pieceabbr = 'ak'
	end
	-- similar to above exception, reverse default
	if pieceabbr:match('ak') and side:match('s') then
		pieceabbr = 'k'
	end
	-- convert abbreviation to Japanese character
	local piecechar = piecesymbol(pieceabbr)
	
	if ss:match('yy') or ss:match('gr') or ss:match('bck') or ss:match('ha') or ss:match('rat') or ss:match('lat') or ss:match('uat') or ss:match('dat') or ss:match('lra') or ss:match('las') or ss:match('ras') or ss:match('uda') or ss:match('das') or ss:match('uas') or ss:match('da') or ss:match('dau') or ss:match('dad') or ss:match('daus') or ss:match('dads') or ss:match('daa') or ss:match('daad') or ss:match('daau') or ss:match('daaus') or ss:match('daads') or ss:match('kar') or ss:match('kal') or ss:match('kadr') or ss:match('kadl') or ss:match('rah') or ss:match('lah') or ss:match('dah') or ss:match('uah') or ss:match('durh') or ss:match('dulh') or ss:match('ddrh') or ss:match('ddlh') or ss:match('ddl') or ss:match('ddr') or ss:match('dul') or ss:match('dur') then
		piecechar = '[[File:shogi_' .. ss .. '22.svg|21px]]'
		side = 'arrow'
		color = 'arrow'
		boldness = 'arrow'
	end
	
	local result = {piecechar, side, color, boldness}
	return result
end


-- function makes a <td> containing the piece with .css stuff
-- uses the info from processString() to customize the .css based on which side, color, and boldness
function makeTD(stringarg)
	-- got to process the string argument into its informational bits
	-- this processedstring is an array (or whatever the equivalent is in Lua)
	local processedstring = processString(stringarg)
	-- saving the pieces of the array as separate objects to be referred to below
	local piecechar = processedstring[1]
	local side = processedstring[2]
	local color = processedstring[3]
	local bold = processedstring[4]
	
	-- i guess one needs a root node?
	local root = mw.html.create('')
	
	-- the default <td>
	local td = root:tag('td')
		td:css('border', 'black 1px solid')
		td:css('width', '19px')
		td:css('height', '17px')
		td:css('padding-bottom', '0')
		td:css('vertical-align', 'middle')
		td:css('align', 'center')
		td:css('font-family', '"Hiragino Mincho ProN", "ヒラギノ明朝 ProN W3", "Hiragino Mincho Pro", "ヒラギノ明朝 Pro W3", YuMincho, "MS Mincho", "MS 明朝", "MS PMincho", "MS P明朝", serif')
	
		if not side:match('arrow') then
			local celldiv = td:tag('div')
				celldiv:css('height', '17px')
				celldiv:css('width', '19px')
				celldiv:css('padding-bottom', '3px')
				celldiv:css('vertical-align', 'middle')
				celldiv:css('align', 'center')
				celldiv:wikitext( piecechar )
		end
	
	-- g = gote
	-- gote should be upside down text
	if side:match( 'g' ) then
		td:css('-moz-transform', 'rotate(180deg)')
		td:css('-ms-transform', 'rotate(180deg)')
		td:css('-o-transform', 'rotate(180deg)')
		td:css('-webkit-transform', 'rotate(180deg)')
		td:css('transform', 'rotate(180deg)')
		td:css('padding-right', '2px')
	end
	
	-- for promoted pieces
	if color:match( 'red' ) then
		-- this is a darkish reddish color
		td:css('color', '#E00303')
	end

	-- for bold pieces
	if bold:match( 'bold' ) then
		td:css('font-weight', 'bolder')
		-- traditionally bold type is gothic (sans serif) in Japanese typesetting
		td:css('font-family', ' HiraginoSans-W5, "Hiragino Sans W5", "Hiragino Sans", "ヒラギノ角ゴ Pro W6", HiraKakuPro-W6, "ヒラギノ角ゴ ProN W6", HiraKakuProN-W6, "Hiragino Kaku Gothic Pro W6", "ヒラギノ丸ゴ Pro W4", "Hiragino Kaku Gothic Pro", "ヒラギノ丸ゴ ProN W4", "Hiragino Maru Gothic ProN", "Hiragino Maru Gothic Pro", YuGothic, "MS Gothic", "MS PGothic", Osaka, Meiryo, "メイリオ", "Arial Unicode MS", ArialUnicodeMS, sans-serif')
	end
	
	-- for arrow svgs 
	if side:match('arrow') then
		td:css('padding', '0')
		td:css('width', '19px')
		td:css('height', '17px')
		td:css('font-size', '1px')
		td:css('line-height', '1px')
		td:css('font-family', 'inherit')
		td:wikitext( piecechar )
	end
	return tostring(root)
end


-- function makes the shogi diagram
-- this is basically a <div> enclosing a .css <div> wrapper with a <table> inside
function shogiboard(args)
	-- these are the column coordinate labels 9-1
	local colLabels = {'9', '8', '7', '6', '5', '4', '3', '2', '1', '&nbsp;'}
	-- these are the row coordinate labels a-i (western notation)
--	local rowLabels = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}
	-- these are the row coordinate labels 1-9 (Japanese notation)
	local rowLabels = {'一', '二', '三', '四', '五', '六', '七', '八', '九'}
	
	local headerarg = args[2]
	local toppieceinhandarg = args[3]
	
	local root = mw.html.create('div')

	-- <div> wrapper
	local shogiboardwrapper = root:tag('div')
		:addClass('shogiboardwrapper')
		:css('padding-left', '4px')
		:css('padding-bottom', '2px')
	
	-- the diagram header/caption
	local headerstring = mw.text.trim(headerarg)
	local header = shogiboardwrapper:tag('div')
		header:css('padding', '0')
		header:wikitext(headerstring)
		header:css('font-size', '14px')

	-- this is the 'piece-in-hand' argument for gote
	-- strip whitespace
	local strippedpieceinhandtop = mw.text.trim(toppieceinhandarg) or ''
	-- put it in a <div> with .css formating
	local pieceinhandtopdiv = shogiboardwrapper:tag('div')
		pieceinhandtopdiv:css('padding', '0')
		pieceinhandtopdiv:css('font-size', '13px')
		-- &#9651; is a white triangle symbol
		pieceinhandtopdiv:wikitext('&#9651;後手 持ち駒 ')
	-- i was going to put the actual argument text into conditional <span> .css formating, but i couldn't get the logical test in an if/else structure right...
	local piecesinhandtopspan = pieceinhandtopdiv:tag('span')
		piecesinhandtopspan:css('font-size', '13px')
		piecesinhandtopspan:wikitext(strippedpieceinhandtop)
	
	-- the shogi table
	local shogitable = shogiboardwrapper:tag('table')
		:addClass('shogitable')
		:attr('cellpadding', '0')
		:attr('cellspacing', '0')
		:attr('border', '1')
		:css('border-collapse', 'collapse')
		:css('border', 'none')
		:css('text-align' , 'center')
		:css('padding-top', '0')
		:css('background-color', 'white')
		
	-- font size for the shogi piece text
	piecefontsize = '17px'
	-- font size for the column/row piece coordinate labels (9-1) and (a-i)
	colrowfontsize = '11px'
	-- padding amount for the row piece coordinate labels (a-i)
	padrowlab = '1px'
	
	-- the row for the column coordinate labels
	local columnlabelrow = shogitable:tag('tr')
		:css('font-size', colrowfontsize)
		:css('background-color', '#f9f9f9')
	-- iterating over the column label to put each label in a <td>
	for i,v in ipairs(colLabels) do 
		local td = columnlabelrow:tag('td')
			:css('border', 'none')
			:css('width', '19px')
			:css('height', '5px')
			:wikitext( v )
	end
	
	-- iterate over the 81 shogi piece arguments (left to right, top to bottom)
	-- i couldn't figure out how to do this is in a clever loopy way as i couldn't figure out how to close the html tags
	-- whatever, it's repetitive, but it works
	
	-- index number displacement/offset
	-- this is just the number of arguments that precede the 81 shogi piece arguments that are in the html <table>
	-- i just keep the piece arguments as indexes 1-81, then add nx to the index value
	nx = 3
	
	-- the row for the shogi pieces
	-- row 1
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	-- put a single piece into a <td>
	-- iterate over 9 pieces in the row
	for irow = 1,9 do
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	-- add row coordinate label <td>
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('padding-top', '0')
		:css('padding-bottom', '0')
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[1] )
	-- row 2
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	for irow = 10,18 do		
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[2] )
	-- row 3
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	for irow = 19,27 do		
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[3] )
	-- row 4
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	for irow = 28,36 do		
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[4] )
	-- row 5
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	for irow = 37,45 do		
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[5] )
	-- row 6
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	for irow = 46,54 do		
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[6] )
	-- row 7
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	for irow = 55,63 do		
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[7] )
	-- row 8
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	for irow = 64,72 do		
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[8] )
	-- row 9
	local trow = shogitable:tag('tr')
		:css('font-size', piecefontsize)
	for irow = 73,81 do		
		trow:wikitext( makeTD(args[(irow+nx)]) )
	end
	local rowlabel = trow:tag('td')
		:css('border', 'none')
		:css('font-size', colrowfontsize)
		:css('padding-left', padrowlab)
		:css('background-color', '#f9f9f9')
		:wikitext( rowLabels[9] )
	
	-- this is the 'piece-in-hand' argument for sente (same as above for gote)
	-- only difference is the black triangle (&#9650;)
	local strippedpieceinhandbottom = mw.text.trim(args[81+1+nx]) or ''	
	local pieceinhandbottomdiv = shogiboardwrapper:tag('div')
		pieceinhandbottomdiv:css('padding', '0')
		pieceinhandbottomdiv:css('font-size', '13px')
		pieceinhandbottomdiv:wikitext('&#9650;先手 持ち駒 ')
	local piecesinhandbottomspan = pieceinhandbottomdiv:tag('span')
		piecesinhandbottomspan:css('font-size', '13px')
		piecesinhandbottomspan:wikitext(strippedpieceinhandbottom)
		
	return tostring(root)
end


-----------------------
-- main function 
-----------------------

function shogiobject.board(frame)
	-- need to use getParent().args for reasons i dont understand
	local args = frame:getParent().args
	return shogiboard(args)
end

return shogiobject