# Module:Subject bar

local getPortalImage = require('Module:Portal').image  

local p = {}  

local function getArgNums(prefix, args)  
-- Returns a table containing the numbers of the arguments that exist for the specified prefix. For example, if the  
-- prefix was 'data', and 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.  
local nums = {}  
for k, v in pairs(args) do  
local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')  
if num then table.insert(nums, tonumber(num)) end  
end  
table.sort(nums)  
return nums  
end  

local function makeHorizontalRule  
local row = mw.html.create('tr')  
row  
:tag('td')  
:attr('colspan', '2')  
:tag('hr', {selfClosing = true})  
return tostring(row)  
end  

local function makeItem(image, text)  
local root = mw.html.create('li')  
root  
:css('float', '')  
:css('margin-', '0.3em')  
:css('height', '3.6em')  
:tag('span')  
:css('display', 'inline-block')  
:css('margin-', '0.3em')  
:css('width', '')  
:css('line-height', '3.6em')  
:css('text-align', '')  
:wikitext(image)  
:done  
:tag('span')  
:css('display', 'inline-block')  
:css('width', '11em')  
:css('vertical-align', 'middle')  
:wikitext(text)  
return tostring(root)  
end  

local function makeRow(items, heading, subheading, options)  
if #items < 1 then return end  
local swapHeadingSize = type(options) == 'table' and options.swapHeadingSize or false  
local row = mw.html.create('tr')  
row  
:tag('td')  
:css('width', '')  
:cssText('-:solid black; padding-:; padding-:;')  
:tag('span')  
:css('font-size', swapHeadingSize and '90%' or '125%')  
:wikitext(heading)  
:done  
:tag('br', {selfClosing = true})  
:done  
:tag('span')  
:css('font-size', swapHeadingSize and '125%' or '90%')  
:wikitext(subheading)  
local list = row:tag('td'):css('text-align', ''):tag('ul')  
for i, item in ipairs(items) do  
local image = item[1]  
local text = item[2]  
list  
:wikitext(makeItem(image, text))  
end  
return tostring(row)  
end  

local function makeNumberedRow(prefix, args, heading, subheading, getItemValsFunc, options)  
if args[prefix] then  
args[prefix .. '1'] = args[prefix]  
end  
local argNums = getArgNums(prefix, args)  
local items = {}  
for i, argNum in ipairs(argNums) do  
local image, text = getItemValsFunc(args[prefix .. tostring(argNum)])  
table.insert(items, {image, text})  
end  
return makeRow(items, heading, subheading, options)  
end  

local function checkPortalExists(portal)  
return not (mw.title.makeTitle(100, portal).id == 0)  
end  

local trackingEnabled = true  

-- Check whether to do tracking in this namespace  
-- Returns true unless the page is one of the banned namespaces  
local function checkTrackingNamespace  
local thisPage = mw.title.getCurrentTitle  
if (thisPage.namespace == 1) -- Talk  
or (thisPage.namespace == 2) -- User  
or (thisPage.namespace == 3) -- User talk  
or (thisPage.namespace == 5) -- Wikipedia talk  
or (thisPage.namespace == 7) -- File talk  
or (thisPage.namespace == 11) -- Template talk  
or (thisPage.namespace == 15) -- Category talk  
or (thisPage.namespace == 101) -- Portal talk  
or (thisPage.namespace == 118) -- Draft  
or (thisPage.namespace == 119) -- Draft talk  
or (thisPage.namespace == 829) -- Module talk  
then  
return false  
end  
return true  
end  

-- Check whether to do tracking on this pagename  
-- Returns false if the page title matches one of the banned strings  
-- Otherwise returns true  
local function checkTrackingPagename  
local thisPage = mw.title.getCurrentTitle  
local thisPageLC = mw.ustring.lower(thisPage.text)  
if (string.match(thisPageLC, "/archive") ~= nil) then  
return false  
end  
if (string.match(thisPageLC, "/doc") ~= nil) then  
return false  
end  
if (string.match(thisPageLC, "/test") ~= nil) then  
return false  
end  
return true  
end  

local redlinkedportal = ""  

function p._main(args)  
-- Tracking is on by default.  
-- It is disabled if any of the following is true  
-- 1/ the parameter "tracking" is set to 'no, 'n', or 'false'  
-- 2/ the current page fails the namespace tests in checkTrackingNamespace  
-- 3/ the current page fails the pagename tests in checkTrackingPagename  
if (args.tracking == 'no') or (args.tracking == 'n') or (args.tracking == 'false') then  
trackingEnabled = false  
end  
if (checkTrackingNamespace == false) then  
trackingEnabled = false  
end  
if (checkTrackingPagename == false) then  
trackingEnabled = false  
end  

local rows = {}  
--[=[ disabled per  
-- Get the book row text.  
local bookHeading = "****"  
local bookSubheading = 'View or order collections of articles'  
local function getBookItemVals(book)  
local image = ''  
local text = mw.ustring.format("***%s***", book, book)  
return image, text  
end  
local bookRow = makeNumberedRow('book', args, bookHeading, bookSubheading, getBookItemVals)  
table.insert(rows, bookRow)  
]=]  
-- Get the portal row text  
local portalHeading = "****"  
local portalSubheading = 'Access related topics'  
local function getPortalItemVals(portal)  
local image = mw.ustring.format('', getPortalImage{portal})  
local text = mw.ustring.format("***%s portal***", portal, portal)  
if not pcall(checkPortalExists, portal) or not checkPortalExists(portal) then  
-- Getting here means a redlinked portal has been found  
if trackingEnabled then  
redlinkedportal = ''  
end  
end  
return image, text  
end  
local portalRow = makeNumberedRow('portal', args, portalHeading, portalSubheading, getPortalItemVals)  
table.insert(rows, portalRow)  

-- Get the sister projects row text.  
local sisters = {  
{arg = 'commons', image = 'Commons-logo.svg', prefix = 'commons', display = 'Media', from = 'Commons'},  
{arg = 'species', image = 'Wikispecies-logo.svg', prefix = 'wikispecies', display = 'Species directories', from = 'Wikispecies'},  
{arg = 'voy', image = 'Wikivoyage-Logo-v3-icon.svg', prefix = 'voy', display = 'Travel guides', from = 'Wikivoyage'},  
{arg = 'n', image = 'Wikinews-logo.svg', prefix = 'wikinews', display = 'News stories', from = 'Wikinews'},  
{arg = 'wikt', image = 'Wiktionary-logo-v2.svg', prefix = 'wiktionary', postfix = 'English', display = 'Definitions', from = 'Wiktionary'},  
{arg = 'b', image = 'Wikibooks-logo.svg', prefix = 'wikibooks', display = 'Textbooks', from = 'Wikibooks'},  
{arg = 'q', image = 'Wikiquote-logo.svg', prefix = 'wikiquote', display = 'Quotations', from = 'Wikiquote'},  
{arg = 's', image = 'Wikisource-logo.svg', prefix = 'wikisource', display = 'Source texts', from = 'Wikisource'},  
{arg = 'v', image = 'Wikiversity logo 2017.svg', prefix = 'wikiversity', display = 'Learning resources', from = 'Wikiversity'},  
{arg = 'd', image = 'Wikidata-logo.svg', prefix = 'wikidata', display = 'Data', from = 'Wikidata'},  
{arg = 'spoken', image = 'Sound-icon.svg', prefix = 'spoken wikipedia', display = 'Listen to this page', from = 'Spoken Wikipedia'},  
}  
local sisterItems = {}  
for i, t in ipairs(sisters) do  
if args[t.arg] then  
-- Get the image value.  
local image = mw.ustring.format('', t.image)  
-- Get the text value.  
local prefix = t.prefix  
local search = args[t.arg .. '-search'] or mw.title.getCurrentTitle.text  
local postfix = t.postfix  
postfix = postfix and ('#' .. postfix) or ''  
local display = t.display  
local from = t.from  
local text = mw.ustring.format(  
'%s  
from %s',  
prefix, search, postfix, display, from  
if t.arg == 'spoken' then  
text = mw.ustring.format('%s on %s  
',  
display, from, args[t.arg]  
end  
-- Add the values to the items table.  
table.insert(sisterItems, {image, text})  
end  
end  
local sisterHeading = "**விக்கிப்பீடியா**  
பற்றி மேலும் அறியவும்"  
local sisterSubheading = "**பிற திட்டங்கள்**"  
local sisterRow = makeRow(sisterItems, sisterHeading, sisterSubheading, {swapHeadingSize = true})  
table.insert(rows, sisterRow)  

-- Make the table.  
local root = mw.html.create('table')  
root  
:attr('role', 'presentation')  
:addClass('subjectbar')  
:addClass('noprint')  
:addClass('metadata')  
:addClass('plainlist')  
:wikitext(table.concat(rows, makeHorizontalRule))  

return tostring(root)  
end  

function p.main  
-- If called via #invoke, use the args passed into the invoking template, or the args passed to #invoke if any exist. Otherwise  
-- assume args are being passed directly in from the debug console or from another Lua module.  
local origArgs  
if == mw.getCurrentFrame then  
origArgs = :getParent.args  
for k, v in pairs(.args) do  
origArgs = .args  
break  
end  
else  
origArgs =  
end  
-- Remove blank arguments.  
local args = {}  
for k, v in pairs(origArgs) do  
if v ~= '' then  
args[k] = v  
end  
end  
return :extensionTag{ name = 'templatestyles', args = { src = 'Subject bar/styles.css'} } .. p._main(args) .. redlinkedportal  
end  

return p