Difference between revisions of "Module:Automatic archive navigator/sandbox"
Jump to navigation
Jump to search
blackwiki>Mr. Stradivarius (add blurb-making methods) |
blackwiki>Mr. Stradivarius (various tweaks, start a function to find the archive numbers to output) |
||
Line 5: | Line 5: | ||
require('Module:No globals') | require('Module:No globals') | ||
local checkType = require('libraryUtil').checkType | local checkType = require('libraryUtil').checkType | ||
− | + | local yesno = require('Module:Yesno') | |
− | |||
− | |||
− | |||
− | |||
− | local | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
Line 30: | Line 13: | ||
local function makeWikilink(page, display) | local function makeWikilink(page, display) | ||
return string.format('[[%s|%s]]', page, display) | return string.format('[[%s|%s]]', page, display) | ||
+ | end | ||
+ | |||
+ | local function escapePattern(s) | ||
+ | -- Escape punctuation in a string so it can be used in a Lua pattern. | ||
+ | pattern = pattern:gsub('%p', '%%%0') | ||
+ | return pattern | ||
end | end | ||
Line 50: | Line 39: | ||
function Archive:makeLink(current) | function Archive:makeLink(current) | ||
local subpage = self.prefix .. tostring(self.num) | local subpage = self.prefix .. tostring(self.num) | ||
− | local | + | local link = makeWikilink('/' .. subpage, subpage) |
− | |||
if current and self.num == current then | if current and self.num == current then | ||
link = string.format('<span style="font-size:115%;">%s</span>', link) | link = string.format('<span style="font-size:115%;">%s</span>', link) | ||
Line 66: | Line 54: | ||
function Navigator.new(args, cfg, currentTitle) | function Navigator.new(args, cfg, currentTitle) | ||
− | local obj = {} | + | local obj = setmetatable({}, Navigator) |
− | |||
− | -- Set inputs | + | -- Set inputs |
obj.args = args | obj.args = args | ||
obj.cfg = cfg | obj.cfg = cfg | ||
obj.currentTitle = currentTitle | obj.currentTitle = currentTitle | ||
− | -- Define object structure | + | -- Define object structure |
obj.links = {} | obj.links = {} | ||
+ | |||
+ | -- Archive prefix | ||
+ | -- Decode HTML entities so users can enter things like "Archive " from | ||
+ | -- wikitext. | ||
+ | obj.archivePrefix = obj.args.prefix or self:message('archive-prefix') | ||
+ | obj.archivePrefix = mw.text.decode(obj.archivePrefix) | ||
+ | |||
+ | -- Current archive number | ||
+ | do | ||
+ | local pattern = string.format( | ||
+ | '^%s([1-9][0-9]*)$', | ||
+ | escapePattern(obj.archivePrefix) | ||
+ | ) | ||
+ | obj.currentArchiveNum = obj.currentTitle.subpageText:match(pattern) | ||
+ | obj.currentArchiveNum = tostring(obj.currentArchiveNum) | ||
+ | end | ||
+ | |||
+ | -- Highest archive number | ||
+ | obj.highestArchiveNumber = require('Module:Highest archive number')._main( | ||
+ | obj.currentTitle.baseText .. obj.archivePrefix | ||
+ | ) | ||
return obj | return obj | ||
Line 99: | Line 107: | ||
ret = ret .. args.text | ret = ret .. args.text | ||
else | else | ||
− | |||
local talkLink = makeWikilink( | local talkLink = makeWikilink( | ||
− | + | self.currentTitle.nsText .. ':' .. self.currentTitle.baseText, | |
self:message('blurb-talk-link-display') | self:message('blurb-talk-link-display') | ||
) | ) | ||
− | + | if args.period then | |
− | ret = ret .. self:message( | + | ret = ret .. self:message('blurb-period', talkLink, args.period) |
+ | else | ||
+ | ret = ret .. self:message('blurb-noperiod', talkLink) | ||
+ | end | ||
end | end | ||
return ret | return ret | ||
Line 134: | Line 144: | ||
}) | }) | ||
− | return mbox | + | return mbox .. '__NONEWSECTIONLINK__ __NOEDITSECTION__' |
+ | end | ||
+ | |||
+ | function Navigator:getArchiveNums() | ||
+ | -- Returns an array of the archive numbers to format. | ||
+ | local noArchives = tonumber(self.args.links) or self:message('default-link-count') | ||
+ | noArchives = math.floor(noArchives) | ||
+ | local allowRedLinks = not yesno(self.args.noredlinks) | ||
+ | local current = self.currentArchiveNum | ||
+ | local highest = self.highestArchiveNum | ||
+ | if allowRedLinks then | ||
+ | -- Allow exactly one red link. | ||
+ | highest = highest + 1 | ||
+ | end | ||
+ | |||
+ | if not current or not highest or noArchives < 1 then | ||
+ | return {} | ||
+ | elseif noArchives == 1 then | ||
+ | return {current} | ||
+ | end | ||
+ | |||
+ | local function getArchiveOffset(i, current) | ||
+ | -- Gets the positive offset for an archive given i, the position in the | ||
+ | -- array away from the current archive, and the current archive number. | ||
+ | if i <= 2 then | ||
+ | return i | ||
+ | elseif i <= 3 then | ||
+ | -- TODO | ||
+ | else | ||
+ | -- TODO | ||
+ | end | ||
+ | end | ||
+ | |||
+ | local iArchive = 0 | ||
+ | -- Archives below the current one. | ||
+ | for i = 1, math.floor((noArchives - 1) / 2) do | ||
+ | end | ||
end | end | ||
Line 140: | Line 186: | ||
-- Makes a single-row wikitable from an array of links | -- Makes a single-row wikitable from an array of links | ||
local ret = {} | local ret = {} | ||
− | ret[#ret + 1] = '{| style="width: 32em; background: transparent; margin: 0 auto 0.5em; text-align: center"' | + | ret[#ret + 1] = '{| style="width:32em;background:transparent;' .. |
+ | 'margin:0 auto 0.5em;text-align:center"' | ||
for _, link in ipairs(self.links) do | for _, link in ipairs(self.links) do | ||
ret[#ret + 1] = '\n| ' | ret[#ret + 1] = '\n| ' | ||
Line 149: | Line 196: | ||
end | end | ||
− | + | function Navigator:__tostring() | |
− | + | return self:makeMessageBox() | |
− | + | end | |
− | |||
− | |||
local function getSubpageLink(offset, currentTitle) | local function getSubpageLink(offset, currentTitle) | ||
Line 176: | Line 221: | ||
return nil | return nil | ||
end | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
Line 270: | Line 290: | ||
end | end | ||
− | + | ------------------------------------------------------------------------------- | |
− | + | -- Exports | |
+ | ------------------------------------------------------------------------------- | ||
− | + | local p = {} | |
− | |||
− | |||
− | |||
− | + | function p._aan(args, cfg, currentTitle) | |
− | + | cfg = cfg or require('Module:AutomaticArchiveNavigator/config') | |
− | + | currentTitle = currentTitle or mw.title.getCurrentTitle() | |
− | + | local aan = Navigator.new(args, cfg, currentTitle) | |
− | + | return tostring(aan) | |
− | |||
− | |||
− | |||
− | |||
end | end | ||
Line 293: | Line 307: | ||
args.noredlinks = args.noredlinks or false | args.noredlinks = args.noredlinks or false | ||
return p._aan(args) | return p._aan(args) | ||
+ | end | ||
+ | |||
+ | function p._exportClasses() | ||
+ | return { | ||
+ | Archive = Archive, | ||
+ | Navigator = Navigator | ||
+ | } | ||
end | end | ||
Line 306: | Line 327: | ||
end | end | ||
end}) | end}) | ||
− | |||
− | |||
− | |||
return p | return p |
Revision as of 06:44, 8 October 2014
Documentation for this module may be created at Module:Automatic archive navigator/sandbox/doc
--
-- This module implements {{Automatic archive navigator}}
--
require('Module:No globals')
local checkType = require('libraryUtil').checkType
local yesno = require('Module:Yesno')
-------------------------------------------------------------------------------
-- Helper functions
-------------------------------------------------------------------------------
local function makeWikilink(page, display)
return string.format('[[%s|%s]]', page, display)
end
local function escapePattern(s)
-- Escape punctuation in a string so it can be used in a Lua pattern.
pattern = pattern:gsub('%p', '%%%0')
return pattern
end
-------------------------------------------------------------------------------
-- Archive class
-------------------------------------------------------------------------------
local Archive = {}
Archive.__index = Archive
function Archive.new(basePageName, prefix, num)
checkType('Archive.new', 1, num, 'number')
local obj = setmetatable({}, Archive)
obj.basePageName = basePageName
obj.prefix = prefix
obj.num = num
return obj
end
function Archive:makeLink(current)
local subpage = self.prefix .. tostring(self.num)
local link = makeWikilink('/' .. subpage, subpage)
if current and self.num == current then
link = string.format('<span style="font-size:115%;">%s</span>', link)
end
return link
end
-------------------------------------------------------------------------------
-- Navigator class
-------------------------------------------------------------------------------
local Navigator = {}
Navigator.__index = Navigator
function Navigator.new(args, cfg, currentTitle)
local obj = setmetatable({}, Navigator)
-- Set inputs
obj.args = args
obj.cfg = cfg
obj.currentTitle = currentTitle
-- Define object structure
obj.links = {}
-- Archive prefix
-- Decode HTML entities so users can enter things like "Archive " from
-- wikitext.
obj.archivePrefix = obj.args.prefix or self:message('archive-prefix')
obj.archivePrefix = mw.text.decode(obj.archivePrefix)
-- Current archive number
do
local pattern = string.format(
'^%s([1-9][0-9]*)$',
escapePattern(obj.archivePrefix)
)
obj.currentArchiveNum = obj.currentTitle.subpageText:match(pattern)
obj.currentArchiveNum = tostring(obj.currentArchiveNum)
end
-- Highest archive number
obj.highestArchiveNumber = require('Module:Highest archive number')._main(
obj.currentTitle.baseText .. obj.archivePrefix
)
return obj
end
function Navigator:message(key, ...)
local msg = self.cfg[key]
if select('#', ...) > 0 then
return mw.message.newRawMessage(msg, ...):plain()
else
return msg
end
end
function Navigator:makeBlurb()
local args = self.args
if args[1] == '1' then
-- The old template used "|1" to suppress the blurb.
return ''
else
local ret = '----\n'
if args.text then
ret = ret .. args.text
else
local talkLink = makeWikilink(
self.currentTitle.nsText .. ':' .. self.currentTitle.baseText,
self:message('blurb-talk-link-display')
)
if args.period then
ret = ret .. self:message('blurb-period', talkLink, args.period)
else
ret = ret .. self:message('blurb-noperiod', talkLink)
end
end
return ret
end
end
function Navigator:makeMessageBox()
local args = self.args
local image
if args.image then
image = args.image
else
local icon = args.icon or self:message('default-icon')
image = string.format(
'[[File:%s|%s|alt=|link=]]',
icon,
self:message('image-size')
)
end
local mbox = require('Module:Message box').main('tmbox', {
image = image,
imageright = args.imageright,
style = args.style or 'width:80%;margin-left:auto;margin-right:auto',
textstyle = args.textstyle or 'text-align:center',
text = self:makeBlurb()
})
return mbox .. '__NONEWSECTIONLINK__ __NOEDITSECTION__'
end
function Navigator:getArchiveNums()
-- Returns an array of the archive numbers to format.
local noArchives = tonumber(self.args.links) or self:message('default-link-count')
noArchives = math.floor(noArchives)
local allowRedLinks = not yesno(self.args.noredlinks)
local current = self.currentArchiveNum
local highest = self.highestArchiveNum
if allowRedLinks then
-- Allow exactly one red link.
highest = highest + 1
end
if not current or not highest or noArchives < 1 then
return {}
elseif noArchives == 1 then
return {current}
end
local function getArchiveOffset(i, current)
-- Gets the positive offset for an archive given i, the position in the
-- array away from the current archive, and the current archive number.
if i <= 2 then
return i
elseif i <= 3 then
-- TODO
else
-- TODO
end
end
local iArchive = 0
-- Archives below the current one.
for i = 1, math.floor((noArchives - 1) / 2) do
end
end
function Navigator:makeLinksWikitable()
-- Makes a single-row wikitable from an array of links
local ret = {}
ret[#ret + 1] = '{| style="width:32em;background:transparent;' ..
'margin:0 auto 0.5em;text-align:center"'
for _, link in ipairs(self.links) do
ret[#ret + 1] = '\n| '
ret[#ret + 1] = link
end
ret[#ret + 1] = '\n|}'
return table.concat(ret)
end
function Navigator:__tostring()
return self:makeMessageBox()
end
local function getSubpageLink(offset, currentTitle)
-- Get a formatted link to the subpage a certain distance away, or nil
-- if that subpage does not exist. e.g. If the current subpage is
-- /Archive 27, then getSubpageLink(3, currentTitle) returns a link to Archive 30.
local subpageName
local archiveNum = currentTitle.subpageText:match('^Archive ([1-9][0-9]*)$')
archiveNum = tonumber(archiveNum)
if archiveNum then
subpageName = 'Archive ' .. (archiveNum + offset)
elseif tonumber(currentTitle.subpageText) then
subpageName = currentTitle.subpageText + offset
else
return nil -- Couldn't parse out a subpage number
end
local subpageTitle = mw.title.new(currentTitle.baseText .. '/' .. subpageName, currentTitle.namespace)
if subpageTitle.exists then
return makeWikilink('/' .. subpageName, subpageName)
else
return nil
end
end
local function getLinksText(args, currentTitle)
local nbsp = ' '
local arrowSpacer, linkSpacer
if mw.ustring.len(currentTitle.subpageText) <= 4 then
-- If page names are short, we want more space.
arrowSpacer = nbsp:rep(5)
linkSpacer = nbsp:rep(7)
else
arrowSpacer = nbsp:rep(2)
linkSpacer = nbsp:rep(4)
end
local ret = {}
for offset = -5, -3 do
local link = getSubpageLink(offset, currentTitle)
if link then
if offset == -3 then
ret[#ret + 1] = link
ret[#ret + 1] = linkSpacer
else
ret[#ret + 1] = link
ret[#ret + 1] = ' ←'
ret[#ret + 1] = arrowSpacer
end
break
end
end
for offset = -2, -1 do
local link = getSubpageLink(offset, currentTitle)
if link then
ret[#ret + 1] = link
ret[#ret + 1] = linkSpacer
end
end
ret[#ret + 1] = '<span style="font-size:115%;">'
ret[#ret + 1] = makeWikilink(currentTitle.prefixedText, currentTitle.subpageText)
ret[#ret + 1] = '</span>'
for offset = 1, 2 do
local link = getSubpageLink(offset, currentTitle)
if link then
ret[#ret + 1] = linkSpacer
ret[#ret + 1] = link
end
end
for offset = 5, 3, -1 do
local link = getSubpageLink(offset, currentTitle)
if link then
if offset == 3 then
ret[#ret + 1] = linkSpacer
ret[#ret + 1] = link
else
ret[#ret + 1] = arrowSpacer
ret[#ret + 1] = '→ '
ret[#ret + 1] = link
end
break
end
end
return table.concat(ret)
end
-------------------------------------------------------------------------------
-- Exports
-------------------------------------------------------------------------------
local p = {}
function p._aan(args, cfg, currentTitle)
cfg = cfg or require('Module:AutomaticArchiveNavigator/config')
currentTitle = currentTitle or mw.title.getCurrentTitle()
local aan = Navigator.new(args, cfg, currentTitle)
return tostring(aan)
end
function p._tan(args)
args.links = args.links or 3
args.noredlinks = args.noredlinks or false
return p._aan(args)
end
function p._exportClasses()
return {
Archive = Archive,
Navigator = Navigator
}
end
setmetatable(p, {__index = function(t, k)
return function(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = {
'Template:Automatic archive navigator',
'Template:Talk archive navigation'
}
})
return p['_' .. k](args)
end
end})
return p