<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://elite.mistflux.co.uk/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AGoban%2Faccessibility</id>
	<title>Module:Goban/accessibility - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://elite.mistflux.co.uk/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AGoban%2Faccessibility"/>
	<link rel="alternate" type="text/html" href="https://elite.mistflux.co.uk/w/index.php?title=Module:Goban/accessibility&amp;action=history"/>
	<updated>2026-11-01T09:31:41Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://elite.mistflux.co.uk/w/index.php?title=Module:Goban/accessibility&amp;diff=128312&amp;oldid=prev</id>
		<title>Wikipedia&gt;Kanayoko: add 3 digits</title>
		<link rel="alternate" type="text/html" href="https://elite.mistflux.co.uk/w/index.php?title=Module:Goban/accessibility&amp;diff=128312&amp;oldid=prev"/>
		<updated>2026-09-05T00:23:31Z</updated>

		<summary type="html">&lt;p&gt;add 3 digits&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
-- Module:Goban/accessibility&lt;br /&gt;
--&lt;br /&gt;
-- Screen-reader support for [[Module:Goban]]: builds a plain-language&lt;br /&gt;
-- description of a Go board position from its tile codes, and wraps text in&lt;br /&gt;
-- {{Screen reader-only}} so it is voiced but not displayed.&lt;br /&gt;
--&lt;br /&gt;
--   describe(rows, cols, cells)  -&amp;gt;  description string&lt;br /&gt;
--       cells is a function(r, c) returning the tile code shown at row r,&lt;br /&gt;
--       column c (counted from the top left, 1-based).&lt;br /&gt;
--   hide(frame, text)            -&amp;gt;  wikitext hiding text visually&lt;br /&gt;
--   description(frame, rows, cols, cells, alt)&lt;br /&gt;
--                                -&amp;gt;  hidden wikitext describing the board,&lt;br /&gt;
--                                    using alt when given, else describe()&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Template that hides text visually while leaving it for screen readers.&lt;br /&gt;
local SR_ONLY_TEMPLATE = &amp;#039;Screen reader-only&amp;#039;&lt;br /&gt;
&lt;br /&gt;
-- Column letters in the usual Go notation, which skips &amp;quot;I&amp;quot;.&lt;br /&gt;
local COLUMN_LETTERS = &amp;#039;ABCDEFGHJKLMNOPQRSTUVWXYZ&amp;#039;&lt;br /&gt;
&lt;br /&gt;
local COLOR_NAME = { b = &amp;#039;black&amp;#039;, w = &amp;#039;white&amp;#039; }&lt;br /&gt;
local MARK_NAME = { S = &amp;#039;square&amp;#039;, T = &amp;#039;triangle&amp;#039; }&lt;br /&gt;
&lt;br /&gt;
-- Escape wikitext-significant characters in text that came from a cell code.&lt;br /&gt;
local function escape(s)&lt;br /&gt;
	return (s:gsub(&amp;quot;[&amp;lt;&amp;gt;%[%]{}|&amp;amp;&amp;#039;=*#]&amp;quot;, function(ch)&lt;br /&gt;
		return &amp;#039;&amp;amp;#&amp;#039; .. string.byte(ch) .. &amp;#039;;&amp;#039;&lt;br /&gt;
	end))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Coordinate of a cell in Go notation: column letter (A-T, no I) and row&lt;br /&gt;
-- number counted from the bottom of the diagram.&lt;br /&gt;
local function coordinate(r, c, rows)&lt;br /&gt;
	local letter = COLUMN_LETTERS:sub(c, c)&lt;br /&gt;
	if letter == &amp;#039;&amp;#039; then&lt;br /&gt;
		letter = &amp;#039;column &amp;#039; .. c .. &amp;#039; &amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	return letter .. (rows - r + 1)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Build the plain-language description of the position.&lt;br /&gt;
function p.describe(rows, cols, cells)&lt;br /&gt;
	local black, white, moves, marks = {}, {}, {}, {}&lt;br /&gt;
	for r = 1, rows do&lt;br /&gt;
		for c = 1, cols do&lt;br /&gt;
			local code = cells(r, c)&lt;br /&gt;
			local at = coordinate(r, c, rows)&lt;br /&gt;
			local color, suffix = code:match(&amp;#039;^([bw])([ST]?)$&amp;#039;)&lt;br /&gt;
			local mcolor, mnumber = code:match(&amp;#039;^([bw])(%d)$&amp;#039;)&lt;br /&gt;
			if color then&lt;br /&gt;
				local list = (color == &amp;#039;b&amp;#039;) and black or white&lt;br /&gt;
				list[#list + 1] = at&lt;br /&gt;
				if suffix ~= &amp;#039;&amp;#039; then&lt;br /&gt;
					marks[#marks + 1] = MARK_NAME[suffix] .. &amp;#039; on &amp;#039;&lt;br /&gt;
						.. COLOR_NAME[color] .. &amp;#039; stone at &amp;#039; .. at&lt;br /&gt;
				end&lt;br /&gt;
			elseif mcolor then&lt;br /&gt;
				moves[#moves + 1] = {&lt;br /&gt;
					n = tonumber(mnumber), color = COLOR_NAME[mcolor], at = at,&lt;br /&gt;
				}&lt;br /&gt;
			elseif code:match(&amp;#039;^%d%d%d?$&amp;#039;) then&lt;br /&gt;
				local n = tonumber(code)&lt;br /&gt;
				moves[#moves + 1] = {&lt;br /&gt;
					n = n, color = (n % 2 == 0) and &amp;#039;white&amp;#039; or &amp;#039;black&amp;#039;, at = at,&lt;br /&gt;
				}&lt;br /&gt;
			elseif code == &amp;#039;X&amp;#039; then&lt;br /&gt;
				marks[#marks + 1] = &amp;#039;X at &amp;#039; .. at&lt;br /&gt;
			elseif code:match(&amp;#039;^%u$&amp;#039;) then&lt;br /&gt;
				marks[#marks + 1] = &amp;#039;letter &amp;#039; .. code .. &amp;#039; at &amp;#039; .. at&lt;br /&gt;
			elseif code:match(&amp;#039;^[udlr%-]*c$&amp;#039;) then&lt;br /&gt;
				marks[#marks + 1] = &amp;#039;circle at &amp;#039; .. at&lt;br /&gt;
			elseif code == &amp;#039;&amp;#039; or code == &amp;#039;-&amp;#039; or code == &amp;#039;x&amp;#039;&lt;br /&gt;
				or code:match(&amp;#039;^[udlr]+$&amp;#039;) then&lt;br /&gt;
				-- empty board: nothing to say&lt;br /&gt;
			else&lt;br /&gt;
				marks[#marks + 1] = escape(code) .. &amp;#039; tile at &amp;#039; .. at&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(moves, function(a, b)&lt;br /&gt;
		if a.n ~= b.n then&lt;br /&gt;
			return a.n &amp;lt; b.n&lt;br /&gt;
		end&lt;br /&gt;
		return a.color &amp;lt; b.color&lt;br /&gt;
	end)&lt;br /&gt;
&lt;br /&gt;
	local parts = {}&lt;br /&gt;
	if #black &amp;gt; 0 then&lt;br /&gt;
		parts[#parts + 1] = &amp;#039;Black stones: &amp;#039; .. table.concat(black, &amp;#039;, &amp;#039;) .. &amp;#039;.&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if #white &amp;gt; 0 then&lt;br /&gt;
		parts[#parts + 1] = &amp;#039;White stones: &amp;#039; .. table.concat(white, &amp;#039;, &amp;#039;) .. &amp;#039;.&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if #moves &amp;gt; 0 then&lt;br /&gt;
		local list = {}&lt;br /&gt;
		for i, m in ipairs(moves) do&lt;br /&gt;
			list[i] = m.n .. &amp;#039; &amp;#039; .. m.color .. &amp;#039; &amp;#039; .. m.at&lt;br /&gt;
		end&lt;br /&gt;
		parts[#parts + 1] = &amp;#039;Moves: &amp;#039; .. table.concat(list, &amp;#039;; &amp;#039;) .. &amp;#039;.&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if #marks &amp;gt; 0 then&lt;br /&gt;
		parts[#parts + 1] = &amp;#039;Marks: &amp;#039; .. table.concat(marks, &amp;#039;; &amp;#039;) .. &amp;#039;.&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	local text = &amp;#039;Go board, &amp;#039; .. rows .. &amp;#039; by &amp;#039; .. cols&lt;br /&gt;
	if #parts == 0 then&lt;br /&gt;
		return text .. &amp;#039;, empty.&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	return text .. &amp;#039;. &amp;#039; .. table.concat(parts, &amp;#039; &amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Wikitext that hides text visually but leaves it for screen readers.&lt;br /&gt;
-- Without a frame (unit tests) a bare span with the same class is returned.&lt;br /&gt;
function p.hide(frame, text)&lt;br /&gt;
	if frame and frame.expandTemplate then&lt;br /&gt;
		return frame:expandTemplate{ title = SR_ONLY_TEMPLATE, args = { text } }&lt;br /&gt;
	end&lt;br /&gt;
	return &amp;#039;&amp;lt;span class=&amp;quot;sr-only&amp;quot;&amp;gt;&amp;#039; .. text .. &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Hidden description of the board.  A non-blank alt replaces the generated&lt;br /&gt;
-- description.&lt;br /&gt;
function p.description(frame, rows, cols, cells, alt)&lt;br /&gt;
	local text = alt&lt;br /&gt;
	if text == nil or text:match(&amp;#039;^%s*$&amp;#039;) then&lt;br /&gt;
		text = p.describe(rows, cols, cells)&lt;br /&gt;
	else&lt;br /&gt;
		text = text:match(&amp;#039;^%s*(.-)%s*$&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	return p.hide(frame, text)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Wikipedia&gt;Kanayoko</name></author>
	</entry>
</feed>