Introducing: Representatives. swedishwin.com, chud.win, and soyzellig.party positions are vacant.
The new Community missions system is now live! Where anyone can propose a task, discuss nominations, or join the current mission. Community missions give editors a place to turn requests from the Janny noticeboard into focused projects. No mission can be too small
Module:News/contents
From Soyjak Wiki, the free ensoyclopedia
Jump to navigationJump to search
| This module is rated as ready for general use. It is considered stable and may be used wherever appropriate. Improvements should be developed and tested in a sandbox before changing the live module. |
| This module depends on the following other modules: |
This module contains self-reading tools for the newspaper issues. Both entry points will read the current page's wikitext live and in preview.
Entry points
{{#invoke:News/contents|contents|mode=|level=}}- the "In this issue" list automatically generated by this module by counting (default2,== ==) heading levels in page order. The counts are automatically linked to its section, under thecontentslabel from config. Links, bold, italic marks are removed from heading text.modesets the class, by default the stylesheet is expecting it to betopbar.
{{#invoke:News/contents|check}}- a "hidden" sanity checker, called by the issue nameplate. It silently counts to check for errors. If any are found, it will report them in red under the folio:- unknown parameters on any
News/...template on the page. - Unbalanced
News/rowandNews/boxpairs, when the number of openers and enders differ.
- unknown parameters on any
Any problem also adds the error category from the config.
local p = {}
local News = require('Module:News')
local parser = require('Module:WikitextParser')
local openers = { ['News/row'] = true, ['News/box'] = true }
local closers = { ['News/row end'] = 'News/row', ['News/box end'] = 'News/box' }
local function clean(text)
text = text:gsub('%[%[[^%]|]*|([^%]]*)%]%]', '%1')
text = text:gsub('%[%[([^%]]*)%]%]', '%1')
text = text:gsub("'''", ''):gsub("''", '')
return mw.text.trim(text)
end
function p.contents(frame)
local marks = string.rep('=', tonumber(frame.args.level) or 2)
local text = mw.title.getCurrentTitle():getContent() or ''
local state = News.newState()
local items = {}
for line in (text .. '\n'):gmatch('([^\n]*)\n') do
local inner = line:match('^' .. marks .. '([^=].-)' .. marks .. '%s*$')
if inner then
local heading = clean(inner)
table.insert(items, '* [[#' .. heading .. '|' .. heading .. ']]')
end
end
if #items == 0 then return '' end
return News.finish(
state,
'<div class="sn-news-contents sn-news-contents-'
.. frame.args.mode
.. '"><div class="sn-news-contents-heading">'
.. News.text(state, 'contents')
.. '</div>\n'
.. table.concat(items, '\n')
.. '\n</div>'
)
end
-- part 1: Check for unknown parameters
local function unknown(state, name, args)
local title = mw.title.new(name, 10)
local source = title and title:getContent()
if not source then return {} end
local known = {}
for param in source:gmatch('{{{%s*([^|}]-)%s*[|}]') do
known[param] = true
end
if next(known) == nil then return {} end
local names = {}
for arg in pairs(args) do
arg = mw.text.trim(tostring(arg))
if not known[arg] then table.insert(names, arg) end
end
table.sort(names)
local out = {}
for _, arg in ipairs(names) do
table.insert(out, News.errorText(state, 'unknownParam', { name = arg, template = name }))
end
return out
end
local function headings(text)
local list = {}
for pos, line in (text .. '\n'):gmatch('()([^\n]*)\n') do
local inner = line:match('^==+([^=].-)==+%s*$')
if inner then table.insert(list, { pos = pos, text = clean(inner) }) end
end
return list
end
local function place(under)
if under then return News.fill(News.need('messages').placeUnder, { heading = under }) end
return News.need('messages').placeTop
end
-- part2: check for opening / closing misbalance
function p.check(frame)
local text = mw.title.getCurrentTitle():getContent() or ''
local lang = mw.language.getContentLanguage()
local state = News.newState()
local heads = headings(text)
local h = 0
local stack, out = {}, {}
for pos, template in text:gmatch('()({%b{}})') do
if template:sub(1, 3) ~= '{{#' then
while heads[h + 1] and heads[h + 1].pos < pos do
h = h + 1
end
local under = heads[h] and heads[h].text
local name = lang:ucfirst((mw.text.trim(parser.getTemplateName(template) or ''):gsub('_', ' ')))
if openers[name] then
table.insert(stack, { name = name, under = under })
elseif closers[name] then
local match
for i = #stack, 1, -1 do
if stack[i].name == closers[name] then
match = i
break
end
end
if not match then
table.insert(out, News.errorText(state, 'unopened', { name = name:sub(6), place = place(under) }))
else
if match < #stack then
local top = stack[#stack]
table.insert(
out,
News.errorText(state, 'crossed', {
name = name:sub(6),
place = place(under),
open = top.name:sub(6),
where = place(top.under),
})
)
end
for i = #stack, match, -1 do
table.remove(stack, i)
end
end
end
if name:sub(1, 5) == 'News/' then
for _, message in ipairs(unknown(state, name, parser.getTemplateParameters(template))) do
table.insert(out, message)
end
end
end
end
for _, item in ipairs(stack) do
table.insert(out, News.errorText(state, 'unclosed', { name = item.name:sub(6), place = place(item.under) }))
end
return News.finish(state, table.concat(out, ' '))
end
return p
