This module depends on the following other modules: |
The pages listed in this category are templates.
This page is part of OODA WIKI's administration and not part of the encyclopedia.
Further template category notes
This category contains pages in the template namespace. It should not be used to categorize articles or pages in other namespaces. To add a template to this category:
|
This category is an index of templates which use TemplateStyles. It is automatically populated by {{Uses TemplateStyles}}.
This module documents the Track gauge/data data page of {{Track gauge}}. Its main product is Template:Track gauge/doc/input options.
Gauges
documentGauge
Can list in complete tableform one, multiple or all gauges listed in the /data page. Gauges defined in both metric and imperial are grouped into one row.
Per gauge size a link to the category:Articles that mentions this gauge ... is added.
#invoke functions
checkData documentGauge catContent catMentions createCatMentions documentGaugeSizeFromTitle catSortFromTitle
Parameters
|1= alias |1<!--???-->= (datafile for checkData) |n=all (list) |docfrom= |docto= |doctitle= |docstate= |docstats= |displaynotfound= |docsortlabel= |docreturnargs=
Parser limits (expensive functions)
Module:Track gauge/autodocument uses expensive function calls (especially the documentGauge
listing). The wiki parser only allows 500 such calls in one page. As of July 2014, this number is almost reached in (~475 in Template:Track gauge/doc/input options). When, after adding new entries to /data or /extra, the number is reached, a "Script error" will show.
Best practice is to prevent this error: adding content category name to the /data, even if they have default name pattern or do not exist:
["contentcat"] = "5 ft 3 in gauge railways",
-- or
["contentcat"] = "",
This way, these category pages are not checked for existence.
See also
-- This module documents the track gauges
-- as defined in [[module:Track gauge/data]].
-- General note: "id" is the size-id (in mm). With this id, definitions can vary (mm, ft/in, name)
-- Alias (the normalised input value) is the primary search term
local p = {}
local getArgs = require('Module:Arguments').getArgs
local modMath = require('Module:Math')
local modTrackGauge = require('Module:Track gauge') -- /andbox here
local dataPageName = 'Module:Track gauge/data' -- /sandbox here
local gaugeDataAll = nil
local tableTools = require('Module:tableTools')
-- global counters (to keep between the id-row building calls)
local ttlSizeClassCount = {}
local ttlAliasCount = 0
local ttlEntries = 0
local ttlUnitCount = {}
local ttlAltNameCount = 0
local ttlAltName = {}
local ttlLinkCount = 0
local ttlContentCatsCount = 0
local ttlMentioningCatsCount = 0
local ttlMentioningPageCount = 0
local ttlListedRange = {}
-----------------------------------------------------------------------------------
-- prepareArgs -- Arguments coming from an #invoke or from a module
-----------------------------------------------------------------------------------
local function prepareArgs(frame)
local origArgs = getArgs(frame)
-- Trim whitespace, make lower-case and remove blank arguments for all arguments
-- searchAlias is the cleaned value of [1]. [1] is kept as rawInput for error message
local args = {}
args['searchAlias'] = ''
args['rawInput'] = origArgs[1] or ''
for k, v in pairs(origArgs) do
if tonumber(k) == nil then
-- Named argument
if k == 'docsortlabel' then -- not in TG
args[k] = v
else
args[k] = mw.ustring.lower(v)
end
else
-- Unnamed argument, alias to be searched
args[k] = modTrackGauge.normaliseAliasInput(v)
if k == 1 then
args['searchAlias'] = args[1]
end
end
end
return args
end
-----------------------------------------------------------------------------------
-- formatUnitPlaintext
-- Pattern '00016.5 mm' for table.sort and catsort.
-----------------------------------------------------------------------------------
local function formatUnitPlaintext(tgEntry, unit, fmtZeroPadding, toFracChar)
-- Returns plaintext (ASCII) only. No css.
if tgEntry == nil then
return ''
end
if (unit or tgEntry.def) == 'imp' then
-- imperial
local ft = ''
local inch = ''
local frac = ''
if tgEntry.ft then
ft = tgEntry.ft .. ' ft'
end
if tgEntry.num then
frac = ' ' .. tgEntry.num .. '/' .. tgEntry.den
if toFracChar then
-- as used in contentCat pagenames
if frac == ' 1/8' then frac = '⅛'
elseif frac == ' 1/4' then frac = '¼'
elseif frac == ' 3/8' then frac = '⅜'
elseif frac == ' 1/2' then frac = '½'
elseif frac == ' 3/4' then frac = '¾'
elseif frac == ' 7/8' then frac = '⅞'
else
frac = frac .. ' (error: fraction character missing in module:Track gauge)'
end
end
if tgEntry['in'] then
frac = ' ' .. tgEntry['in'] .. frac .. ' in'
else
frac = ' ' .. frac .. ' in'
end
else
if tgEntry['in'] then
inch = ' ' .. tgEntry['in'] .. ' in'
end
end
return mw.text.trim(ft .. inch .. frac)
else
-- metric (mm)
if fmtZeroPadding == nil or tonumber(fmtZeroPadding) <= 0 then
return tgEntry.id .. ' mm'
else
return string.rep('0', fmtZeroPadding - math.floor(math.log10(tonumber(tgEntry.id))) - 1)
.. tgEntry.id .. ' mm'
end
end
end
-----------------------------------------------------------------------------------
-- document data-sort-value
-----------------------------------------------------------------------------------
local function documentdatasortvalue(tgEntry)
local s = formatUnitPlaintext(tgEntry, 'met', 5)
return tostring(mw.html.create():tag('span'):attr('data-sort-value', s))
end
-----------------------------------------------------------------------------------
-- catSortFromTitle
-- Currently finds "600 mm" when at end of title, then returns "0600 mm" (for catSort).
-- Blank when not found. Used for cat:mentions category page.
-----------------------------------------------------------------------------------
function p.catSortFromTitle()
local title = mw.title.getCurrentTitle()
local catSort = string.match(title.text, '%s(%d+%.?%d*)%smm$') or ''
if catSort ~= '' then
catSort = string.rep('0', 4 - math.floor(math.log10(tonumber(catSort))) - 1)
.. catSort .. ' mm'
end
if catSort == '' then
return '*'
else
return catSort
end
end
-----------------------------------------------------------------------------------
-- documentGaugeClass
-----------------------------------------------------------------------------------
local function documentGaugeClass(tgEntry, countMentionings)
local size = tonumber(tgEntry.id or 0)
local j
if size > 1435 then
j = 5
elseif size == 1435 then
j = 4
elseif size > 500 then
j = 3
elseif size >= 100 then
j = 2
elseif size > 0 then
j = 1
else
j = 6
end
ttlSizeClassCount[j][2] = ttlSizeClassCount[j][2] +1
ttlSizeClassCount[j][4] = ttlSizeClassCount[j][4] + (countMentionings or 0)
return '<span data-sort-value="' .. j .. '">' .. ttlSizeClassCount[j][1] .. '</span>' --(20190920: linter closing span added)
end
-----------------------------------------------------------------------------------
-- anchor -- Anchor text *here* is: <span id="1000 mm">; anchor *there* should be: #1000 mm.
-----------------------------------------------------------------------------------
local function anchor(tgEntry, unit, herethere)
if tgEntry == nil then
return ''
end
unit = unit or tgEntry.def1
local anch = formatUnitPlaintext(tgEntry, unit, 0)
if herethere == 'there' then -- Untested, April 2014
anch = '#' .. anch
else
anch = mw.html.create():tag('span'):attr('id', anch)
end
return tostring(anch)
end
-----------------------------------------------------------------------------------
-- noWrap -- Add span tags to prevent a string from wrapping.
-----------------------------------------------------------------------------------
local function noWrap(s)
return mw.ustring.format('<span class="nowrap">%s</span>', s)
end
-----------------------------------------------------------------------------------
-- frac -- A slimmed-down version of the {{frac}} template (a single nowrap to be added with the unit)
-----------------------------------------------------------------------------------
local function frac(whole, num, den)
local templatestyles = mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Fraction/styles.css' }
}
return mw.ustring.format(
'%s<span class="frac" role="math">%s<span class="num">%s</span>⁄<span class="den">%s</span></span>',
templatestyles,
whole and (whole .. '<span class="sr-only">+</span>') or '',
num,
den
)
end
-----------------------------------------------------------------------------------
-- debugReturnArgs
-----------------------------------------------------------------------------------
function p.debugReturnArgs(frame)
local args = prepareArgs(frame)
local retArgs = {}
for k, a in pairs(args) do
table.insert(retArgs, k .. '=' .. a)
end
return 'Args: ' .. table.concat(retArgs, '; ')
end
-----------------------------------------------------------------------------------
-- checkData -- Public. Performs various checks on the /data subpage.
-- not maintained since ca. 2015
-----------------------------------------------------------------------------------
function p.checkData(frame)
--To be allowed: entry.link empty; then use entry.name.
local dataPage = frame and frame.args and frame.args[1] or dataPageName
local data = mw.loadData(dataPage)
local exists, dupes, dupeSort, ret = {}, {}, {}, {}
-- Check for duplicate aliases.
for ti, t in ipairs(data) do
for ai, alias in ipairs(t.aliases or {}) do
if not exists[alias] then
exists[alias] = { ti, ai }
else
if not dupes[alias] then
dupes[alias] = { exists[alias] }
end
table.insert(dupes[alias], { ti, ai })
end
end
end
for alias in pairs(dupes) do
table.insert(dupeSort, alias)
end
table.sort(dupeSort)
for i1, alias in ipairs(dupeSort) do
local positions = {}
for i2, aliasKeys in ipairs(dupes[alias]) do
local position = mw.ustring.format('gauge %d, alias %d (gauge id: <code>%s</code>)', aliasKeys[1], aliasKeys[2], data[aliasKeys[1]].id or '')
table.insert(positions, position)
end
local aliasText = mw.ustring.format('Duplicate aliases "%s" detected at the following positions: %s.', alias, mw.text.listToText(positions, '; '))
table.insert(ret, aliasText)
end
-- Check for numerators without denominators.
for ti, t in ipairs(data) do
local num = t.num
local den = t.den
if num and not den then
table.insert(ret, mw.ustring.format('Numerator "%s" with no denominator detected at gauge %d (id: <code>%s</code>).', num, ti, t.id or ''))
elseif den and not num then
table.insert(ret, mw.ustring.format('Denominator "%s" with no numerator detected at gauge %d (id: <code>%s</code>).', den, ti, t.id or ''))
end
end
-- Check for gauges with no imperial or no metric measurements.
for ti, t in ipairs(data) do
if not (t.ft or t['in'] or t.num or t.den) then
table.insert(ret, mw.ustring.format('No imperial measurements found for gauge %d (id: <code>%s</code>).', ti, t.id or ''))
end
if not (t.m or t.mm) then
table.insert(ret, mw.ustring.format('No metric measurements found for gauge %d (id: <code>%s</code>).', ti, t.id or ''))
end
end
-- Check for non-numeric measurements.
local measurements = { 'ft', 'in', 'num', 'den', 'm', 'mm' }
for ti, t in ipairs(data) do
for mi, measurement in ipairs(measurements) do
local measurementVal = t[measurement]
if measurementVal and not tonumber(measurementVal) then
table.insert(ret, mw.ustring.format('Non-numeric <code>%s</code> measurement ("%s") found for gauge %d (id: <code>%s</code>).', measurement, measurementVal, ti, t.id or ''))
end
end
end
-- Check for gauges with no id.
for ti, t in ipairs(data) do
if not t.id then
local aliases = {}
for i, alias in ipairs(t.aliases) do
table.insert(aliases, mw.ustring.format('<code>%s</code>', alias))
end
aliases = mw.ustring.format(' (aliases: %s)', mw.text.listToText(aliases))
table.insert(ret, mw.ustring.format('No id found for track gauge %d%s.', ti, aliases or ''))
end
end
-- Check for gauges with no aliases.
for ti, t in ipairs(data) do
if type(t.aliases) ~= 'table' then
table.insert(ret, mw.ustring.format('No aliases found for gauge %d (id: <code>%s</code>).', ti, t.id or ''))
else
local isAlias = false
for ai, alias in ipairs(t.aliases) do
isAlias = true
break
end
if not isAlias then
table.insert(ret, mw.ustring.format('No aliases found for gauge %d (id: <code>%s</code>).', ti, t.id or ''))
end
end
end
-- Check for named gauges with no links and gauges with links but no names.
-- 20140520: no link? could be acceptable. Code falls back to the unlinked name (in test now).
if false then -- skipped 2014-05-25
for ti, t in ipairs(data) do
if t.name and not t.link then
table.insert(ret, mw.ustring.format('No link found for the named gauge "%s" at position %d (id: <code>%s</code>).', t.name, ti, t.id or ''))
elseif t.link and not t.name then
table.insert(ret, mw.ustring.format('No name found for the gauge with link "%s" at position %d (id: <code>%s</code>).', t.link, ti, t.id or ''))
end
end
end
-- Check for invalid def1 values.
for ti, t in ipairs(data) do
local def = t.def1
if def ~= 'imp' and def ~= 'met' then
table.insert(ret, mw.ustring.format('Invalid def1 value "%s" found for gauge %d (id: <code>%s</code>).', def or '', ti, t.id or ''))
end
end
-- Check for unwanted whitespace.
for ti, t in ipairs(data) do
for tkey, tval in pairs(t) do
if tkey == 'aliases' and type(tval) == 'table' then
for ai, alias in ipairs(tval) do
if mw.ustring.find(alias, '%s') then
table.insert(ret, mw.ustring.format('Unwanted whitespace detected in gauge %d alias %d ("%s", gauge id: <code>%s</code>).', ti, ai, alias, t.id or ''))
end
end
elseif tkey == 'name' or tkey == 'link' or tkey == 'pagename' or tkey == 'contentcat' then
if tval ~= mw.text.trim(tval) then
table.insert(ret, mw.ustring.format('Unwanted whitespace detected in <code>%s</code> field of gauge %d ("%s", gauge id: <code>%s</code>).', tkey, ti, tval, t.id or ''))
end
elseif mw.ustring.find(tval, '%s') then
table.insert(ret, mw.ustring.format('Unwanted whitespace detected in <code>%s</code> field of gauge %d ("%s", gauge id: <code>%s</code>).', tkey, ti, tval, t.id or ''))
end
end
end
-- Added April 2014: alias should not double with another id (imp and mm not ambiguous)
local self_id = ''
local self_def = ''
for ti, t in ipairs(data) do
self_id = t.id
self_def = t.def1
for iC, aliasCheck in ipairs(t.aliases) do
if tonumber(aliasCheck) ~= nil then
if self_id ~= aliasCheck then
for iTwo, tTwo in ipairs(data) do
if aliasCheck == tTwo.id then
table.insert(ret,
mw.ustring.format('Input alias %s (%s) from <code>id=%s mm</code> ambiguous with gauge id=<code>%s mm</code> (%s)'
, aliasCheck, self_def, self_id, tTwo.id, tTwo.def1)
)
end
end
end
end
end
end
-- Return any errors found.
for i, msg in ipairs(ret) do
ret[i] = mw.ustring.format('<span class="error">%s</span>', msg)
end
if #ret > 0 then
return mw.ustring.format('Found the following errors in %s:\n* %s', dataPage, table.concat(ret, '\n* '))
else
return mw.ustring.format('No errors found in %s.', dataPage)
end
end
-----------------------------------------------------------------------------------
-- catContent -- content category for the gauge
-----------------------------------------------------------------------------------
function p.catContent(frame)
-- catContent (content category for this alias)
-- can be hardcoded in the data, or build by size (pattern)
local args = prepareArgs(frame)
local tgEntry = modTrackGauge.getTrackGaugeEntry(args.searchAlias)
if tgEntry == nil then
return args['displaynotfound'] or 'No gauge entry found for ' .. (args[1] or '""')
end
local catTitle
local label
local catC
local docsortlabel = ''
if args.docsortlabel ~= nil then
docsortlabel = '|' .. args.docsortlabel
end
if tgEntry.contentcat == '' then
catC = ''
elseif tgEntry.contentcat ~= nil then
catC = '[[:Category:' .. tgEntry.contentcat .. docsortlabel .. ']]'
else -- no name given, try default name:
local catCsuffix = ' gauge railways'
if tgEntry.def1 == 'met' then
label = formatUnitPlaintext(tgEntry, 'met')
catTitle = mw.title.makeTitle(14, label .. catCsuffix)
if catTitle.exists then
catC = '[[:' .. catTitle.fullText .. docsortlabel .. ']]'
end
elseif tgEntry.def1 == 'imp' then
label = formatUnitPlaintext(tgEntry, 'imp', nil, true)
catTitle = mw.title.makeTitle(14, label .. catCsuffix)
if catTitle.exists then
catC = '[[:' .. catTitle.fullText .. docsortlabel .. ']]'
end
end
end
return catC
end
-----------------------------------------------------------------------------------
-- catMentions -- maintenance only
-----------------------------------------------------------------------------------
function p.catMentions(frame)
local args = prepareArgs(frame)
local tgEntry = modTrackGauge.getTrackGaugeEntry(args.searchAlias)
if tgEntry == nil then
return args['displaynotfound'] or 'No gauge entry found for ' .. (args[1] or '""')
end
local catM = modTrackGauge.catMentions(tgEntry, args.docsortlabel, 'show')
return catM
end
-----------------------------------------------------------------------------------
-- fromInputToId -- Used cleaned Alias as searchkey
-----------------------------------------------------------------------------------
local function fromInputToId(searchAlias)
gaugeDataAll = mw.loadData(dataPageName)
for i, tgEntry in ipairs(gaugeDataAll) do
for j, alias in ipairs(tgEntry.aliases) do
if alias == searchAlias then
return tgEntry.id
end
end
end
-- Next search: by id (autodocument only, not in main RG)
if tonumber(searchAlias) ~= nil then
for i, tgEntry in ipairs(gaugeDataAll) do
if tgEntry.id == searchAlias then
return tgEntry.id
end
end
end
end
-----------------------------------------------------------------------------------
-- documentInchCount -- Number of inches in decimals.
-----------------------------------------------------------------------------------
local function documentInchCount(tgEntry)
local inches = 0
if tgEntry['num'] ~= nil then
inches = modMath._round(tonumber((tgEntry['num'] or 0) / (tgEntry['den'] or 1)), 4)
end
inches = tostring((tonumber(tgEntry['ft'] or 0) * 12)
+ tonumber(tgEntry['in'] or 0) + inches)
return inches
end
-----------------------------------------------------------------------------------
-- documentInchToMm -- Not used lately
-----------------------------------------------------------------------------------
local function documentInchToMm(inchCount)
return tonumber(inchCount or 0) * 25.4
end
-----------------------------------------------------------------------------------
-- documentGaugeSizeFromTitle -- Currently finds "1620 mm" when at end of title,
-- then returns "1620". Blank when not found.
-----------------------------------------------------------------------------------
function p.documentGaugeSizeFromTitle()
local title = mw.title.getCurrentTitle()
return string.match(title.text, '%s(%d+%.?%d*)%smm$') or ''
end
-----------------------------------------------------------------------------------
-- documentBuildTgList -- The table of id's to fill the table
-----------------------------------------------------------------------------------
function documentBuildTgList(args)
-- Build series from the list. idFrom and idTo are numerical
local tgList = {}
local idFrom = -1
local idTo = -1
for i, v in ipairs(args) do
if v == 'all' then
idFrom = -math.huge
idTo = math.huge
break
end
end
if args.docfrom ~= nil then
idFrom = tonumber(fromInputToId(args.docfrom)
or mw.ustring.gsub(args.docfrom, 'mm', ''))
idTo = math.huge
end
if args.docto ~= nil then
idTo = tonumber(fromInputToId(args.docto)
or mw.ustring.gsub(args.docto, 'mm', ''))
end
if idTo > 0 then -- Some subset is requested from the whole data set
if idFrom > idTo then
local dummy = idFrom
idFrom = idTo
idTo = dummy
end
for i, tgEntry in ipairs(gaugeDataAll) do
if (tonumber(tgEntry.id) >= idFrom) and (tonumber(tgEntry.id) <= idTo) then
table.insert(tgList, tonumber(tgEntry.id))
end
end
tgList = tableTools.removeDuplicates(tgList)
table.sort(tgList)
if #tgList > 1 then
ttlListedRange[1] = tgList[1] .. ' mm – ' .. tgList[#tgList] .. ' mm '
end
end
-- Individual entries can be mentioned in args (all unnamed = numbered params)
-- Need a straight table.to keep sequence right
local id
local argsAliasesIn = tableTools.compressSparseArray(args)
for i, argsAlias in ipairs(argsAliasesIn) do
id = fromInputToId(argsAlias)
if id ~= nil then
table.insert(tgList, i, tonumber(id))
table.insert(ttlListedRange, i, id .. ' mm; ')
end
end
ttlListedRange = tableTools.compressSparseArray(ttlListedRange)
ttlListedRange = tableTools.removeDuplicates(ttlListedRange)
tgList = tableTools.compressSparseArray(tgList)
tgList = tableTools.removeDuplicates(tgList)
return tgList
end
-----------------------------------------------------------------------------------
-- documentPostListStats -- build footer table, after list only
-----------------------------------------------------------------------------------
local function documentPostListStats(countTgList)
-- Report data counters
-- Data
local retFoot = {}
table.insert(retFoot, '\n*Sources')
table.insert(retFoot, ':Data pages: [[:' .. dataPageName .. ']]')
table.insert(retFoot, '*Data')
table.insert(retFoot, ':Listed: ' .. table.concat(ttlListedRange, '') .. ' (' .. countTgList .. ' rows)')
table.insert(retFoot, ":'''Entries''' (defined gauges, per unit): " .. ttlEntries)
table.insert(retFoot, ":'''Gauges''' (defined gauges, per size): " .. countTgList)
for i, stat in ipairs (ttlUnitCount) do
table.insert(retFoot, ':' .. stat[2] .. ': ' .. stat[1])
end
table.insert(retFoot, ':Aliases (input options): ' .. ttlAliasCount)
table.insert(retFoot, ':Named definitions (as output link; ' .. ttlAltNameCount .. '): ' .. table.concat(ttlAltName, '; '))
table.insert(retFoot, ':Entries with an article link: ' .. ttlLinkCount)
-- TODO table.insert(retFoot, '*Named gauges (named input)') -- todo
-- Categories (content, maintenance)
table.insert(retFoot, '*Categories')
table.insert(retFoot, ':Content categories: ' .. ttlContentCatsCount)
-- Size classes (narrow, broad, ..)
table.insert(retFoot, '*Size classes')
for i, stat in ipairs (ttlSizeClassCount) do
if stat[2] ~= 0 then
table.insert(retFoot, ':' .. stat[2] .. ' ' .. stat[3] .. ' (' .. stat[4] .. ' mentionings)')
end
end
local anchor = tostring(mw.html.create():tag('span'):attr('id', 'Statistics'))
-- help:using colors. Hue=190 (blue)
local statTable = anchor .. '\n{| class="wikitable collapsible collapsed" style="background:#e6fbff; font-size:85%; width:100%;"'
.. '\n|-'
.. '\n! style="background:#ceecf2; width:100%;" | Track gauge data statistics'
.. '\n|-'
.. '\n|' .. table.concat(retFoot, '\n')
.. '\n|}'
return statTable
end
-----------------------------------------------------------------------------------
-- documentHeader
-----------------------------------------------------------------------------------
local function documentHeader(numberOfEntries, docTitle, docState)
local docBgHeader = '#cef2e0' -- Green. See [[template:documentation]]
-- Header row 1 (title)
local pagetitle = mw.title.getCurrentTitle()
urlPurgePage = 'https://en.wikipedia.org/w/index.php?title=' .. pagetitle.nsText .. ':' .. pagetitle:partialUrl() .. '&action=purge'
urlPurgePage = '<span class="plainlinks purgelink nourlexpansion" title="Purge this page (update countings)">[' .. urlPurgePage .. ' (purge)]</span>'
if docTitle == '' then
docTitle = 'Track gauges' -- (' .. dataPageName .. ')' -- optional, sandbox here
end
docTitle = docTitle .. ' ' .. urlPurgePage
if docState == '' then
docState = 'uncollapsed'
end
-- Header row 2 (sort buttons, blank cells)
local sortColHeaders = ''
local sortClass = ''
if (numberOfEntries or 0) > 1 then
sortClass = 'sortable'
local sortCell = '! style="background:' .. docBgHeader .. ';"'
-- todo: 10 cols with bg color
sortColHeaders = '\n|- style="background:' .. docBgHeader .. '; line-height:90%;"'
.. '\n! || || || || || || || '
end
-- Header row 3 (column headers)
local catMparent = modTrackGauge.catMentions(nil, 'Mentionings', 'show')
--10 columns:
local tableStyle = 'style="text-align:right; width:100%; font-size:85%;" '
local retHdr = {}
table.insert(retHdr, '\n{| class="wikitable collapsible ' .. docState .. ' ' .. sortClass .. '" ' .. tableStyle)
table.insert(retHdr, '|-')
table.insert(retHdr, '! colspan=10 style="background:' .. docBgHeader .. ';" | ' .. docTitle)
table.insert(retHdr, '|-')
table.insert(retHdr, '! style="background:' .. docBgHeader .. ';" | Gauge<br>(mm)')
table.insert(retHdr, '! style="background:' .. docBgHeader .. ';" | Gauge<br>(ft, in)')
table.insert(retHdr, '! style="background:' .. docBgHeader .. ';" | Alt<br>name')
table.insert(retHdr, '! style="background:' .. docBgHeader .. ';" | Gauge<br>(inch)')
table.insert(retHdr, '! style="background:' .. docBgHeader .. ';" | Def<br>unit')
table.insert(retHdr, '! style="background:' .. docBgHeader .. '; width:8em;" | Aliases<br>(input options)')
table.insert(retHdr, '! style="background:' .. docBgHeader .. ';" | Class<br> ')
table.insert(retHdr, '! style="background:' .. docBgHeader .. '; min-width:5em;" | Source<br>article')
return table.concat(retHdr, '\n') .. sortColHeaders
end
-----------------------------------------------------------------------------------
-- documentFooter
-----------------------------------------------------------------------------------
local function documentFooter()
return {'\n|}'}
end
-----------------------------------------------------------------------------------
-- documentFromIdToEntrySet -- from fromIdToEntrySet
-- From one id, make the set with all one-two-three-more entries (met, inp, variants)
-----------------------------------------------------------------------------------
local function documentFromIdToEntrySet(id, searchedAlias)
local docBgColor = '#e6fff2' -- Green. See header bg color
local rowSplit = '<div style="border-top:1px solid #ccc; height:1px;"></div>'
-- From the size-id, build the set of existing entries (met, imp, and variants)
local entry = {}
local defType = 0
-- data
for i, tgEntry in ipairs(gaugeDataAll) do
if id == tgEntry.id then
if tgEntry.def1 == 'met' and entry[1] == nil then
entry[1] = tgEntry
defType = defType + 1
elseif tgEntry.def1 == 'imp' and entry[2] == nil then
entry[2] = tgEntry
defType = defType + 2
else
entry[3 + tableTools.size(entry)] = tgEntry
end
end
end
entry = tableTools.compressSparseArray(entry)
-- Entry set is now complete & clean
-- Result: the entry table with entries present in /data,
-- in sequence if present (1. met, 2. imp, any extra)
-- (to build into a single row, maybe with split cells)
--Build cell elements, then string row together.
local inchCount = documentInchCount(entry[1])
local datasortvalue = documentdatasortvalue(entry[1], 'met', 5)
local aliasList = {}
local tempEntryAltName = {}
local entryAltName = {}
local hasAltName = false
for i, e in ipairs(entry) do
local alis = {}
for j, v in ipairs(e.aliases) do
if tonumber(v) == nil then -- (plain numbers are not shown)
table.insert(alis, tostring(v))
end
end
for j, v in ipairs(alis) do
if string.match(v, '^%d') == nil then -- textual so to italic.
alis[j] = tostring(mw.html.create():tag('span'):wikitext(v):css('font-style', 'italic'))
end
end
table.insert (aliasList, table.concat(alis, '; '))
ttlAliasCount = ttlAliasCount + #alis
-- process Alt name links
if e.name or '' ~= '' then
tempEntryAltName[i] = tostring(mw.html.create():tag('span'):wikitext(e.link):css('font-weight', 'bold'))
table.insert(ttlAltName, e.id .. ': ' .. e.link)
ttlAltNameCount = ttlAltNameCount + 1
hasAltName = true
end
end
if hasAltName then
local text
for i, v in ipairs(entry) do
table.insert(entryAltName, i, tempEntryAltName[i] or ' ')
end
end
local def = {} -- Definition unit code: 'met' or 'imp'
local defText = {}
for i, v in ipairs (entry) do
table.insert(def, v.def1)
if v.def1 == 'imp' then
table.insert(defText, 'imp')
ttlUnitCount[2][1] = ttlUnitCount[2][1] + 1
elseif v.def1 == 'met' then
table.insert(defText, 'met')
ttlUnitCount[1][1] = ttlUnitCount[1][1] + 1
end
end
if #entry >= 2 then
if #entry == 2 and entry[1].def1 ~= entry[2].def1 then -- Regular pair: def in met and in imp
ttlUnitCount[3][1] = ttlUnitCount[3][1] + 1
else -- More than 2, or a double unit definition
ttlUnitCount[4][1] = ttlUnitCount[4][1] .. ' ' .. id .. ' mm (' .. #entry ..');'
end
end
-- mm; ft in -- Measurement (number & unit; met and imp; anchor to here)
local measure = {}
local unitanchor = { '', '' }
measure[1] = modTrackGauge.formatMet(entry[1])
measure[2] = modTrackGauge.formatImp(entry[1]) -- both met and imp from entry[1]
if modMath._mod(defType, 2) == 1 then
measure[1] = tostring(mw.html.create():tag('span'):wikitext(measure[1]):css('font-weight', 'bold'))
unitanchor[1] = anchor(entry[1], 'met')
end
if defType >= 2 then
measure[2] = tostring(mw.html.create():tag('span'):wikitext(measure[2]):css('font-weight', 'bold'))
unitanchor[2] = anchor(entry[1], 'imp')
end
-- Linked article
local linkArticle = {}
for i, e in ipairs(entry) do
table.insert(linkArticle, e.pagename)
end
ttlLinkCount = ttlLinkCount + #linkArticle
local eq
if #linkArticle >= 2 then
eq = true
for i, v in ipairs(linkArticle) do
if v ~= linkArticle[1] then
eq = false
break
end
end
if eq == true then
for i, v in ipairs(linkArticle) do
if i > 1 then
linkArticle[i] = nil
end
end
end
end
for i, lp in ipairs(linkArticle) do
local fmtLp = ''
fmtLp = '[[' .. lp .. ']]'
linkArticle[i] = tostring(mw.html.create():tag('span'):css('text-align', 'left'):wikitext(fmtLp))
end
-- catContent (content category for this alias). note: function p.catContent is a reduced code of this.
-- can be hardcoded in the data, or build by size (pattern)
local catContent = {}
local catTitle
local label
local skipCheck = false
for i, e in ipairs(entry) do
if e.contentcat == '' then
-- no cat; option to prevent expensive calls
skipCheck = true
elseif e.contentcat ~= nil then
label = string.match(e.contentcat, '([%S]*)') or 'nomatch'
table.insert(catContent,
'[[:Category:' .. e.contentcat .. '|cat:' .. label .. ' ...]]')
end
end
if #catContent >= 2 then
eq = true
for i, v in ipairs(catContent) do
if v ~= catContent[1] then
eq = false
break
end
end
if eq == true then
for i, v in ipairs(catContent) do
if i > 1 then
catContent[i] = nil
end
end
end
end
if #catContent == 0 and not skipCheck then
local catCsuffix = ' gauge railways'
if modMath._mod(defType, 2) == 1 then
label = formatUnitPlaintext(entry[1], 'met')
catTitle = mw.title.makeTitle(14, label .. catCsuffix)
if catTitle.exists then
table.insert(catContent,
'[[:' .. catTitle.fullText .. '|cat:' .. noWrap(label) .. ']]')
end
end
if defType >= 2 then
label = formatUnitPlaintext(entry[1], 'imp', nil, true)
catTitle = mw.title.makeTitle(14, label .. catCsuffix)
if catTitle.exists then
table.insert(catContent, '[[:' ..catTitle.fullText .. '|cat:' .. noWrap(label) .. ']]')
end
end
end
ttlContentCatsCount = ttlContentCatsCount + #catContent
-- Mentions category
local catMentions = modTrackGauge.catMentions(entry[1], "cat:mnt", 'show')
local catCount = mw.site.stats.pagesInCategory(
modTrackGauge.catMentions(entry[1], nil, 'pagename'), pages)
ttlMentioningCatsCount = ttlMentioningCatsCount + 1 -- Exists
ttlMentioningPageCount = ttlMentioningPageCount + catCount
-- class: Counter SizeClass (narrow, broad, ...)
local rgSizeClass = documentGaugeClass(entry[1], catCount)
ttlEntries = ttlEntries + #entry
sortCount = mw.text.truncate('00000' .. tostring(catCount), -5, '')
sortCount = '<span data-sort-value="' .. sortCount .. '">'
catCount = sortCount .. catCount .. ' P' .. '</span>' --(20190920: linter closing span added)
-- Compose the size-id row with all cell values (10 columns)
local row = {}
table.insert(row, datasortvalue .. unitanchor[1] .. measure[1])
table.insert(row, datasortvalue .. unitanchor[2] .. measure[2])
table.insert(row, table.concat(entryAltName, rowSplit))
table.insert(row, datasortvalue .. inchCount)
table.insert(row, table.concat(defText, rowSplit))
table.insert(row, table.concat(aliasList, rowSplit))
table.insert(row, rgSizeClass)
table.insert(row, table.concat(linkArticle, rowSplit))
return '\n|- style="background:' .. docBgColor .. '; border-top:2px solid #aaa;" |'
.. '\n|'
.. table.concat(row, ' || ')
end
-----------------------------------------------------------------------------------
-- documentGauge -- Selfdocument gauge data (one, multiple, range, all)
-----------------------------------------------------------------------------------
function p.documentGauge(frame)
local args = prepareArgs(frame)
gaugeDataAll = mw.loadData(dataPageName)
-- Init glolbal counters by table:
ttlUnitCount =
{
[1] = {0, 'Entries defined metric'},
[2] = {0, 'Entries defined imperial'},
[3] = {0, 'Gauge sizes defined both metric and imperial'},
[4] = {'', 'Gauge sizes with multiple entries in one unit'}
}
ttlSizeClassCount =
{
[1] = {'scaled', 0, 'scaled or model gauges', 0},
[2] = {'min', 0, 'minimum gauges', 0},
[3] = {'narrow', 0, 'narrow gauges', 0},
[4] = {'s.g.', 0, 'standard gauge', 0},
[5] = {'broad', 0, 'broad gauges', 0},
[6] = {'unk', 0, 'unknown', 0}
}
local tgList = documentBuildTgList(args)
-- Now loop through the prepared tgList[id] and add rows to result le
-- One row contains all available entries for the id (met, imp, a third variant)
local rowTGid = {}
for i, numId in ipairs(tgList) do
table.insert(rowTGid, documentFromIdToEntrySet(tostring(numId)))
end
-- Return args
local retArgs = ''
if args.docreturnargs == 'on' then
retArgs = '\n' .. p.debugReturnArgs(frame)
end
-- Build statistics footer
local retStats = ''
if args.docstats == 'on' then
retStats = documentPostListStats(#tgList)
end
-- Build up
return documentHeader(#tgList, args.doctitle or '', args.docstate or '')
.. table.concat(rowTGid, '')
.. table.concat(documentFooter(), '')
.. retStats
.. retArgs
end
--------------------------------------------------------
-- doc
--------------------------------------------------------
function p.docFracAliases(frame)
local args = prepareArgs(frame)
gaugeDataAll = mw.loadData(dataPageName)
local tgList = documentBuildTgList(args)
local ttlHitCount =0
local rowIMP = {}
local fracAlias =''
for i, id in ipairs(tgList) do
for j, tgEntry in pairs(gaugeDataAll) do
if nil and tostring(id) == '53.975' and tostring(id) == tgEntry.id then
fracAlias = anchor(tgEntry, 'imp', 'there')
fracAlias = mw.ustring.lower(mw.ustring.gsub(fracAlias, '[%s%,%#]', ''))
table.insert(rowIMP, fracAlias .. '||' .. i .. '||' .. id ..
'||' .. modTrackGauge.formatImp(tgEntry) .. ' || plus ' .. tgEntry.num)
end
if tostring(id) == tgEntry.id and tgEntry.def1 == 'imp' and tgEntry.num ~= nil then
if tgEntry.ft ~= nil then
ttlHitCount = ttlHitCount + 1
fracAlias = anchor(tgEntry, 'imp', 'there')
fracAlias = mw.ustring.lower(mw.ustring.gsub(fracAlias, '[%s%,%#]', ''))
fracAlias = mw.ustring.gsub(fracAlias, '⁄', '/')
table.insert(rowIMP, fracAlias .. '||' .. i .. '||' .. id ..
'||' .. modTrackGauge.formatImp(tgEntry))
fracAlias = tostring((tonumber((tgEntry.ft) or 0) * 12) + tonumber(tgEntry["in"] or 0)) .. tgEntry.num .. '/' .. tgEntry.den .. 'in'
table.insert(rowIMP, fracAlias .. '||' .. i .. '||' .. id ..
'||' .. modTrackGauge.formatImp(tgEntry))
end
end
end
end
-- return '\n|' .. ttlHitCount .. ' hits. ' .. #rowIMP
return '\n\n|-\n\n|' .. table.concat(rowIMP, '\n\n|-\n\n|')
end
return p