Mô đun:Convert/show

-- Prepare tables of wikitext to display simple documentation about
-- specified units. Data is obtained by calling Module:Convert.
-- Also provides a function to show convert usage examples.

local function collection()
-- Return a table to hold items.
return {
n = 0,
add = function (self, item)
self.n = self.n + 1
self[self.n] = item
end,
join = function (self, sep)
return table.concat(self, sep)
end,
}
end

local function strip(text)
-- Return text with no leading/trailing whitespace.
return text:match("^%s(.-)%s$")
end

local function frame(self_args, parent_args)
-- Simulate enough of a MediaWiki module frame for convert.
return {
args = self_args,
parent = parent_args and frame(parent_args, nil),
getParent = function (self) return self.parent end,
}
end

local cvt_function
local function call_convert(args)
if not cvt_function then
-- A testing program can set the global variable 'is_test_run'.
cvt_function = require(is_test_run and 'convert' or 'Module:Convert').convert
end
return cvt_function(frame({}, args))
end

local function maketable(results, units)
results:add()
results:add()
end

-- Commonly used units for main documentation.
-- Can only be input units (not combinations or multiples).
local common_units = {
["Area"] = {
heading = "Area",
examples = { "1.5|sqmi|km2", "1.5|sqmi|km2|abbr=on" },
"acre",
"ha",
"m2",
"cm2",
"km2",
"sqin",
"sqft",
"sqyd",
"sqmi",
},
["Fuel efficiency"] = {
heading = "Fuel efficiency",
examples = { "12|mpgus|km/L", "12|mpgus|km/L|abbr=on" },
"km/L",
"mpgimp",
"mpgus",
"L/km",
"L/100 km",
},
["Length"] = {
heading = "Length",
examples = { "123|cm|in", "123|cm|in|sp=us|abbr=off", "123|cm|in|abbr=on" },
"uin",
"in",
"ft",
"yd",
"mi",
"nmi",
"m",
"cm",
"mm",
"km",
"angstrom",
},
["Mass"] = {
heading = "Mass",
examples = { "72.3|kg|lb", "72.3|kg|lb|abbr=on" },
"g",
"kg",
"oz",
"lb",
"st",
"LT",
"MT",
"ST",
},
["Pressure"] = {
heading = "Pressure",
examples = { "28|psi|Pa", "28|psi|Pa|abbr=on" },
"atm",
"mbar",
"psi",
"Pa",
},
["Speed"] = {
heading = "Speed",
examples = { "60|mph|km/h", "60|mph|km/h|abbr=on" },
"km/h",
"km/s",
"kn",
"mph",
},
["Temperature"] = {
heading = "Temperature",
examples = { "100|C|F", "100|C|F|abbr=off", "100|C-change|F-change", "100|C-change|F-change|abbr=out" },
"C",
"F",
"K",
"C-change",
"F-change",
"K-change",
},
["Torque"] = {
heading = "Torque",
examples = { "12.5|Nm|lb.in", "12.5|Nm|lb.in|abbr=on", "12.5|Nm|lb.in|abbr=on|lk=on" },
"lb.in",
"lb.ft",
"Nm",
},
["Volume"] = {
heading = "Volume",
examples = { "125|cuin|l", "125|cuin|l", "125|cuin|l|abbr=on" },
"cuin",
"cuft",
"cuyd",
"cumi",
"impgal",
"impoz",
"usgal",
"usoz",
"L",
"l",
"m3",
"cc",
"mm3",
},
}

-- Order in which sections are wanted when doing all common units.
local common_sections = {
"Area",
"Fuel efficiency",
"Length",
"Mass",
"Pressure",
"Speed",
"Temperature",
"Torque",
"Volume",
}

local function _show_examples(frame, results, examples, want_table)
local fmt
if want_table then
results:add()
end
end

local function _show_units(frame, results, args)
local do_full
if args[1] == nil then
do_full = true
args = common_sections
end
local group = collection()
for _, item in ipairs(args) do
local units = common_units[item] or common_units[item:sub(1, 1):upper() .. item:sub(2)]
if units then
if group.n > 0 then
maketable(results, group)
group = collection()
end
if do_full then
if units.heading then
results:add('' .. units.heading .. '')
end
if units.examples then
results:add('Examples:')
_show_examples(frame, results, units.examples)
end
end
maketable(results, units)
else
group:add(item)
end
end
if group.n > 0 then
maketable(results, group)
end
end

local function show_examples(frame, want_table)
local results = collection()
local ok, msg = pcall(_show_examples, frame, results, frame.args, want_table)
if ok then
return results:join('\n')
end
return 'Error\n' .. msg
end

local function show_units(frame)
local results = collection()
local ok, msg = pcall(_show_units, frame, results, frame.args)
if ok then
return results:join('\n')
end
return 'Error\n' .. msg
end

return {
unit = show_units,
units = show_units,
['list'] = function (frame) return show_examples(frame, false) end,
['table'] = function (frame) return show_examples(frame, true) end,
}