Module:Numlinks 2-num: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Ganaram inukshuk (talk | contribs)
mNo edit summary
Ganaram inukshuk (talk | contribs)
m update todo
 
(9 intermediate revisions by the same user not shown)
Line 7: Line 7:


-- TODO: add arrows
-- TODO: add arrows
-- TODO: add checks for edge cases


-- Main function
-- Main function
Line 62: Line 61:
local display_text = string.format(current_fmt, num_1, num_2)
local display_text = string.format(current_fmt, num_1, num_2)
return string.format("%s", display_text)
return string.format("%s", display_text)
end
local function clamp(value, min_val, max_val)
    return math.min(math.max(value, min_val), max_val)
end
end
-- Create a grid of links
-- Create a grid of links.
local num_rows = 1 + num_links_2 * 2
-- Offsets are the number of cells from the left and upper edges, capped
local num_cols = 1 + num_links_1 * 2
-- between the number of links in each direction and the allowed minima for
local row_offset = 1 + num_links_2
-- each direction.
local col_offset = 1 + num_links_1
local row_offset = clamp(num_links_2, num_links_2 + 1, curr_num_2)
local col_offset = clamp(num_links_1, num_links_1 + 1, curr_num_1)
local num_rows = num_links_2 + row_offset
local num_cols = num_links_1 + col_offset
local links = {}
local links = {}
for j = 1, num_rows do
for j = 1, num_rows do
local row = {}
local row = {}
for i = 1, num_cols do
for i = 1, num_cols do
local num_2 = format_number(num_rows + j - row_offset, is_ordinal_2)
local num_2 = format_number(j - row_offset + curr_num_2, is_ordinal_2)
local num_1 = format_number(num_cols + i - col_offset, is_ordinal_1)
local num_1 = format_number(i - col_offset + curr_num_1, is_ordinal_1)
if i == num_links_1 + 1 and j == num_links_2 + 1 then
if i == col_offset and j == row_offset then
table.insert(row, make_current(num_1, num_2)) -- Text is for the current page
table.insert(row, make_current(num_1, num_2)) -- Text is for the current page
else
else
Line 85: Line 91:
end
end


-- Produce table of links
local lines = {}
local lines = {}
-- Produce table of links
table.insert(lines, '{| style="width: 100%;"')
table.insert(lines, '{| style="width: 100%;"')
local middle_cell_width = 100 / (num_links_1 + 2)
for j = 1, num_rows do
for j = 1, num_rows do
-- New row
-- New row
table.insert(lines, '|-')
table.insert(lines, '|-')
for i = 1, num_cols do
for i = 1, num_cols do
if i == num_links_1 + 1 then
if i == col_offset and j == row_offset then
if j == num_links_2 + 1 then
-- Insert text for current-page cell
-- Insert text for current-page cell
table.insert(lines, string.format('| %s', links[j][i]))
table.insert(lines, string.format('| style="width: %d%%;" | %s', middle_cell_width, links[i][j]))
else
-- Insert text for non-current middle cell
table.insert(lines, string.format('| style="font-size: 0.75em; width: %d%%;" | %s', middle_cell_width, links[i][j]))
end
else
else
-- Insert text for non-middle cell
-- Insert text for non-current middle cell
table.insert(lines, string.format('| style="font-size: 0.75em;" | %s', links[i][j]))
table.insert(lines, string.format('| style="font-size: 0.75em; | %s', links[j][i]))
end
end
end
end
Line 133: Line 132:


return result
return result
end
function p.tester()
local args = {
["Current Num 1"] = 5,
["Current Num 2"] = 2,
["Link Count 1"] = 7,
["Link Count 2"] = 4,
["Link Format"] = "%sL %ss"
}
return p._numlinks_2_num(args)
end
end


return p
return p

Latest revision as of 07:51, 16 October 2025

Module documentation[view] [edit] [history] [purge]
This module implements a metatemplate, and may be invoked by templates using its corresponding template Template:Numlinks 2-num, or used directly from other modules.

This module generates previous and next links for a numbered page with two varying numbers.


Introspection summary for Module:Numlinks 2-num 
Functions provided (3)
Line Function Params
11 _numlinks_2_num (main) (args)
115 numlinks_2_num (invokable) (frame)
136 tester none
Lua modules required (3)
Variable Module Functions used
getArgs Module:Arguments getArgs
ordinal Module:Ordinal _ordinal
yesno Module:Yesno yesno

No function descriptions were provided. The Lua code may have further information.


-- This module follows [[User:Ganaram inukshuk/Provisional style guide for Lua]]
local getArgs = require("Module:Arguments").getArgs
local ordinal = require("Module:Ordinal"  )._ordinal
local yesno   = require("Module:Yesno"    )

local p = {}

-- TODO: add arrows

-- Main function
function p._numlinks_2_num(args)
	-- Numbers. These are assumed to be the number datatype already (EG, already
	-- parsed from a string).
	-- - Current num N is the, well, current number. EG, the 5 and 2 in 5L 2s.
	-- - Min N is the smallest allowed value. EG, with the default minimum of 1,
	--   if the page were 1L 1s, there would be no link to 0L 0s.
	-- - No option exists for the number of links in each direction.
	local curr_num_1  = args["Current Num 1"]
	local curr_num_2  = args["Current Num 2"]
	local num_links_1 = args["Link Count 1"] or 1
	local num_links_2 = args["Link Count 2"] or 1
	local min_num_1   = args["Min 1"] or 1
	local min_num_2   = args["Min 2"] or 1
	
	-- Format strings.
	-- - Link format is for the link to the page. EG, "%L %ss".
	-- - Display format is if the displayed text differs from that of the link
	--   text. EG, a link that says 4L 5s, but links to 4L 5s (3/1-equivalent).
	-- - Current page format is for the current page's text, if it's different
	--   from either link or display text.
	local link_fmt    = args["Link Format"        ] or "%s %s"	
	local display_fmt = args["Display Format"     ] or link_fmt
	local current_fmt = args["Current Page Format"] or display_fmt
	
	-- Toggles.
	-- - Is ordinal formats numbers as ordinals.
	-- - No toggle for table-based output exists; it must default to a table.
	local is_ordinal_1 = yesno(args["Is Ordinal 1"], false)
	local is_ordinal_2 = yesno(args["Is Ordinal 2"], false)
	
	-- Nested helper function to format a number.
	local function format_number(n, is_ordinal)
		local str = is_ordinal and ordinal(n) or tostring(n)
		return str
	end
	
	-- Nested helper function to make a link.
	local function make_link(num_1, num_2)
		local link_target  = string.format(link_fmt   , num_1, num_2)
		local display_text = string.format(display_fmt, num_1, num_2)

		if display_fmt == link_fmt then
			return string.format("[[%s]]", link_target)
		else
			return string.format("[[%s|%s]]", link_target, display_text)
		end
	end
	
	-- Nested helper function to make current page text.
	local function make_current(num_1, num_2)
		local display_text = string.format(current_fmt, num_1, num_2)
		return string.format("%s", display_text)
	end
		
	local function clamp(value, min_val, max_val)
	    return math.min(math.max(value, min_val), max_val)
	end
	
	-- Create a grid of links.
	-- Offsets are the number of cells from the left and upper edges, capped
	-- between the number of links in each direction and the allowed minima for
	-- each direction.
	local row_offset = clamp(num_links_2, num_links_2 + 1, curr_num_2)
	local col_offset = clamp(num_links_1, num_links_1 + 1, curr_num_1)
	local num_rows = num_links_2 + row_offset
	local num_cols = num_links_1 + col_offset
	local links = {}
	for j = 1, num_rows do
		local row = {}
		for i = 1, num_cols do
			local num_2 = format_number(j - row_offset + curr_num_2, is_ordinal_2)
			local num_1 = format_number(i - col_offset + curr_num_1, is_ordinal_1)
			
			if i == col_offset and j == row_offset then
				table.insert(row, make_current(num_1, num_2))		-- Text is for the current page
			else
				table.insert(row, make_link(num_1, num_2))			-- Text is for an adjacent link
			end
		end
		table.insert(links, row)
	end

	-- Produce table of links
	local lines = {}
	table.insert(lines, '{| style="width: 100%;"')
	for j = 1, num_rows do
		-- New row
		table.insert(lines, '|-')
		for i = 1, num_cols do
			if i == col_offset and j == row_offset then
				-- Insert text for current-page cell
				table.insert(lines, string.format('| %s', links[j][i]))
			else
				-- Insert text for non-current middle cell
				table.insert(lines, string.format('| style="font-size: 0.75em; | %s', links[j][i]))
			end
		end
	end
	table.insert(lines, '|}')
	
	return table.concat(lines, "\n")
end

-- Main function
function p.numlinks_2_num(frame)
	local args = getArgs(frame)
	
	-- Preprocess numeric input
	args["Current Num 1"] = tonumber(args["Current Num 1"])		-- Required arg
	args["Current Num 2"] = tonumber(args["Current Num 2"])		-- Required arg
	args["Min 1"] = tonumber(args["Min 1"]) or 1
	args["Min 2"] = tonumber(args["Min 2"]) or 1
	args["Link Count 1"] = tonumber(args["Link Count 1"]) or 1
	args["Link Count 2"] = tonumber(args["Link Count 2"]) or 1
	
	-- Preprocess toggles
	args["Is Ordinal 1"] = args["Is Ordinal 1"] or false
	args["Is Ordinal 2"] = args["Is Ordinal 2"] or false
	
	-- Create numbered navigation links
	local result = p._numlinks_2_num(args)

	return result
end

function p.tester()
	local args = {
		["Current Num 1"] = 5,
		["Current Num 2"] = 2,
		["Link Count 1"] = 7,
		["Link Count 2"] = 4,
		["Link Format"] = "%sL %ss"
	}
	return p._numlinks_2_num(args)
end

return p