Module:Shogi diagram

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 = '龍', gyoku = '玉', ou = '王', 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 = 'ou' end if pieceabbr:match('k') and side:match('s') then pieceabbr = 'gyoku' end -- similar to above exception, reverse default if pieceabbr:match('ak') and side:match('s') then pieceabbr = 'ou' end if pieceabbr:match('ak') and side:match('g') then pieceabbr = 'gyoku' end -- convert abbreviation to Japanese character local piecechar = piecesymbol(pieceabbr) if ss:match('yy') or ss:match('gr') 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 = '' side = 'arrow' color = 'arrow' boldness = 'arrow' end local result = {piecechar, side, color, boldness} return result end

-- function makes a 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 local td = root:tag('td') td:css('border', 'black 1px solid') td:css('width', '20px') td:css('height', '20px') td:css('padding', '0') td:css('line-height', '0') td:css('font-family', '"Hiragino Mincho ProN", serif') if not side:match('arrow') then td:wikitext( piecechar ) end -- g = gote -- gote should be upside down text if side:match( 'g' ) then td:css('transform', 'rotate(180deg)') 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 of shogi diagrams within Japanese shogi books td:css('font-family', ' HiraginoSans-W5, sans-serif') end -- for arrow svgs if side:match('arrow') then td:css('padding', '0') td:css('width', '20px') td:css('height', '20px') td:css('font-size', '1px') td:css('line-height', '0') td:wikitext( piecechar ) end return tostring(root) end

-- function makes the shogi diagram -- this is basically a enclosing a .css wrapper with a inside function shogiboard(args) -- these are the column coordinate labels 9-1 local colLabels = {'9', '8', '7', '6', '5', '4', '3', '2', '1', ' '} -- 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) -- this isn't set up for use yet local rowLabelsJP = {'一', '二', '三', '四', '五', '六', '七', '八', '九'} local headerarg = args[2] local toppieceinhandarg = args[3] local root = mw.html.create('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 with .css formating local pieceinhandtopdiv = shogiboardwrapper:tag('div') pieceinhandtopdiv:css('padding', '0') pieceinhandtopdiv:css('font-size', '12px') -- &#9651; is a white triangle symbol pieceinhandtopdiv:wikitext('&#9651; pieces in hand: ') -- i was going to put the actual argument text into conditional .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('border', '1') :css('border-collapse', 'collapse') :css('border', 'none') :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 	for i,v in ipairs(colLabels) do 		local td = columnlabelrow:tag('td') :css('border', 'none') :css('width', '20px') :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 -- 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 	-- iterate over 9 pieces in the row for irow = 1,9 do		trow:wikitext( makeTD(args[(irow+nx)]) ) end -- add row coordinate label 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', '12px') pieceinhandbottomdiv:wikitext('&#9650; pieces in hand: ') 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