Modulo:Transcluder: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Nuova pagina: local p = {} -- Helper function to test for truthy and falsy values local function truthy(value) if not value or value == '' or value == 0 or value == '0' or value ==...
 
Update from master using #Synchronizer
 
(9 versioni intermedie di 3 utenti non mostrate)
Riga 1:
-- Module:Transcluder is a general-purpose transclusion engine
-- Documentation and master version: https://en.wikipedia.org/wiki/Module:Transcluder
-- Authors: User:Sophivorus, User:Certes & others
-- License: CC-BY-SA-3.0
 
local p = {}
 
-- Helper function to test for truthy and falsy values
-- @todo Somehow internationalize it
local function truthy(value)
if not value or value == '' or value == 0 or value == '0' or value == 'false' or value == 'no' or value == 'non' then
return false
end
Line 9 ⟶ 15:
end
 
-- Helper function to match from a list of regular expressions
-- Like so: match pre..list[1]..post or pre..list[2]..post or ...
local function matchAny(text, pre, list, post, init)
Line 20 ⟶ 26:
end
 
-- Like matchAny but for Category/File links with less overhead
local function matchAnyLink(text, list)
local match
for _, v in ipairs(list) do
match = string.match(text, '%[%[%s*' .. v .. '%s*:.*%]%]')
if match then break end
end
return match
end
 
-- Helper function to escape a string for use in regexes
local function escapeString(str)
return mw.ustringstring.gsub(str, '[%^%$%(%)%.%[%]%*%+%-%?%%]', '%%%0')
end
 
Line 30 ⟶ 47:
pattern = escapeString(mw.ustring.sub(str, 1, 999)) .. '.-' .. escapeString(mw.ustring.sub(str, -999))
end
return mw.ustringstring.gsub(text, pattern, '')
end
 
Line 36 ⟶ 53:
-- @param flags Comma-separated list of numbers or min-max ranges, for example '1,3-5'
-- @return Map from integers to booleans, for example {1=true,2=false,3=true,4=true,5=true}
-- @return Boolean indicating wetherwhether the flags should be treated as a blacklist or not
local function parseFlags(value)
local flags = {}
Line 45 ⟶ 62:
if type(value) == 'number' then
if value < 0 then
value = value * -1value
blacklist = true
end
Line 51 ⟶ 68:
 
elseif type(value) == 'string' then
if mw.ustringstring.sub(value, 1, 1) == '-' then
blacklist = true
value = mw.ustringstring.sub(value, 2)
end
local ranges = mw.text.split(value, ',') -- split ranges: '1,3-5' to {'1','3-5'}
for _, range in pairs(ranges) do
range = mw.text.trim(range)
local min, max = mw.ustring.match(range, '^(%d+)%s*%[-–—]%s*(%d+)$') -- '3-5' to min=3 max=5
if not max then min, max = mw.ustringstring.match(range, '^((%d+))$') end -- '1' to min=1 max=1
if max then
for pi = min, max do flags[pi] = true end
else
flags[range] = true -- if we reach this point, the string had the form 'a,b,c' rather than '1,2,3'
Line 67 ⟶ 84:
end
 
-- List has the form { [1] = false, [2] = true, ['c'] = false }
-- Convert it to { [1] = true, [2] = true, ['c'] = true }
-- But if ANY value is set to false, treat the list as a blacklist
elseif type(value) == 'table' then
 
-- List has the form { [1] = false, [2] = true, ['c'] = false }
-- Convert it to { [1] = true, [2] = true, ['c'] = true }
-- But if ANY value is set to false, treat the list as a blacklist
for i, v in pairs(value) do
if v == false then blacklist = true end
Line 83 ⟶ 99:
-- Helper function to see if a value matches any of the given flags
local function matchFlag(value, flags)
if type(not value) == 'number' then valuereturn = tostring(value)false end
value = tostring(value)
local lang = mw.language.getContentLanguage()
local lcvalue = lang:lcfirst(value)
local ucvalue = lang:ucfirst(value)
for flag in pairs(flags) do
if lang:lcfirst(value) == tostring(flag)
or lang:ucfirst(value)lcvalue == flag
or ucvalue == flag
or mw.ustring.match(value, flag) then
or ( not tonumber(flag) and mw.ustring.match(value, flag) ) then
return true
end
Line 125 ⟶ 145:
-- @return Local name of the namespace and all aliases, for example {'File','Image','Archivo','Imagen'}
local function getNamespaces(name)
local namespaces = mw.clone(mw.site.namespaces[name].aliases) -- Clone because https://en.wikipedia.org/w/index.php?diff=1056921358
table.insert(namespaces, mw.site.namespaces[name].name)
table.insert(namespaces, mw.site.namespaces[name].canonicalName)
Line 135 ⟶ 155:
-- For file pages, returns the content of the file description page
local function getText(page, noFollow)
page = mw.text.decode(page)
local title = mw.title.new(page)
if not title then return false, false end
Line 145 ⟶ 166:
 
-- Remove <noinclude> tags
text = mw.ustringstring.gsub(text, '<[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]>.-</[Nn][Oo][Ii][Nn][Cc][Ll][Uu][Dd][Ee]>', '') -- remove noinclude bits
 
-- Keep <onlyinclude> tags
if mw.ustringstring.find(text, '[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]onlyinclude') then -- avoid expensive search if possible
text = text
text = mw.ustring.gsub(text, '</[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]>.-<[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]>', '') -- remove text between onlyinclude sections
text = mw.ustring. :gsub(text, '^</onlyinclude>.-<[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]onlyinclude>', '') -- remove text before firstbetween onlyinclude sectionsections
text = mw.ustring. :gsub(text, '^.-</[Oo][Nn][Ll][Yy][Ii][Nn][Cc][Ll][Uu][Dd][Ee]onlyinclude>.*', '') -- remove text afterbefore lastfirst onlyinclude section
:gsub('</onlyinclude>.*', '') -- remove text after last onlyinclude section
end
 
Line 157 ⟶ 179:
end
 
-- Get the requested files out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of files to return, for example 2 or '1,3-5'. Omit to return all files.
-- @return Sequence of strings containing the wikitext of the requested files.
-- @return Original wikitext minus non-requested files.
local function getFiles(text, flags)
local files = {}
Line 168 ⟶ 190:
local name
local count = 0
for file in mw.ustringstring.gmatch(text, '%b[]') do
if matchAnymatchAnyLink(file, '%[%[%s*', fileNamespaces, '%s*:.*%]%]') then
name = mw.ustringstring.match(file, '%[%[[^:]-:([^]|]+)')
count = count + 1
if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )
Line 184 ⟶ 206:
end
 
-- Get the requested tables out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of tables to return, for example 2 or '1,3-5'. Omit to return all tables.
-- @return Sequence of strings containing the wikitext of the requested tables.
-- @return Original wikitext minus non-requested tables.
local function getTables(text, flags)
local tables = {}
Line 194 ⟶ 216:
local id
local count = 0
for t in mw.ustringstring.gmatch('\n' .. text, '\n%b{}') do
if mw.ustringstring.sub(t, 1, 3) == '\n{|' then
id = mw.ustringstring.match(t, '\n{|[^\n]-id%s*=%s*["\']?([^"\'\n]+)["\']?[^\n]*\n')
count = count + 1
if not blacklist and ( not flags or flags[count] or flags[id] )
Line 209 ⟶ 231:
end
 
-- Get the requested templates out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of templates to return, for example 2 or '1,3-5'. Omit to return all templates.
-- @return Sequence of strings containing the wikitext of the requested templates.
-- @return Original wikitext minus non-requested templates.
local function getTemplates(text, flags)
local templates = {}
Line 219 ⟶ 241:
local name
local count = 0
for template in mw.ustringstring.gmatch(text, '{%b{}}') do
if mw.ustringstring.sub(template, 1, 3) ~= '{{#' then -- skip parser functions like #if
name = mw.text.trim( mw.ustringstring.match(template, '{{([^}|\n]+)') or "" ) -- get the template name
countif =name count~= +"" 1then
count = count + 1
if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )
or blacklist and flags and not flags[count] and not matchFlag(name, flags) then
table.insert(templates, template)
else
text = removeString(text, template)
end
end
end
Line 234 ⟶ 258:
end
 
-- Get the requested template parameters out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of parameters to return, for example 2 or '1,3-5'. Omit to return all parameters.
-- @return Map from parameter name to value, NOT IN THE ORIGINAL ORDER
-- @return Original wikitext minus non-requested parameters.
-- @return Order in which the parameters were parsed.
local function getParameters(text, flags)
local parameters, parameterOrder = {}, {}
local flags, blacklist = parseFlags(flags)
local params, count, parts, key, value
for template in mw.ustringstring.gmatch(text, '{%b{}}') do
params = mw.ustringstring.match(template, '{{[^|}]-|(.+*)}}')
if params then
count = 0
-- Temporarily replace pipes in subtemplates, tables and links to avoid chaos
for subtemplate in mw.ustringstring.gmatch(params, '{%b{}}') do
params = mw.ustringstring.gsub(params, escapeString(subtemplate), mw.ustring.gsub(mw.ustringstring.gsub(subtemplate, '%%'".", '{["%"]="%%')", '["|'"]="@@:@@", '["="]="@@_@@'"}) )
end
for link in mw.ustringstring.gmatch(params, '%b[]') do
params = mw.ustringstring.gsub(params, escapeString(link), mw.ustringstring.gsub(link, '".", {["%"]="%%", ["|'"]="@@:@@", '["="]="@@_@@'"}) )
end
for parameter in mw.text.gsplit(params, '|') do
parts = mw.text.split(parameter, '=')
key = mw.text.trim(parts[1])
valueif = table.concat(#parts, '=',= 1 2)then
if value == '' then
value = key
count = count + 1
key = count
else
value = mw.text.trim(valuetable.concat(parts, '=', 2))
end
value = mwstring.ustringgsub(string.gsub(value, '@@:@@', '|'), '@@_@@', '=')
if not blacklist and ( not flags or matchFlag(key, flags) )
or blacklist and flags and not matchFlag(key, flags) then
table.insert(parameterOrder, key)
parameters[key] = value
else
Line 275 ⟶ 300:
end
end
return parameters, text, parameterOrder
end
 
-- Get the requested lists out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of lists to return, for example 2 or '1,3-5'. Omit to return all lists.
-- @return Sequence of strings containing the wikitext of the requested lists.
-- @return Original wikitext minus non-requested lists.
local function getLists(text, flags)
local lists = {}
local flags, blacklist = parseFlags(flags)
local count = 0
for list in mw.ustringstring.gmatch('\n' .. text .. '\n\n', '\n([*#].-)\n[^*#]') do
count = count + 1
if not blacklist and ( not flags or flags[count] )
Line 299 ⟶ 324:
end
 
-- Get the requested paragraphs out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of paragraphs to return, for example 2 or '1,3-5'. Omit to return all paragraphs.
-- @return Sequence of strings containing the wikitext of the requested paragraphs.
-- @return Original wikitext minus non-requested paragraphs.
local function getParagraphs(text, flags)
local paragraphs = {}
Line 313 ⟶ 338:
elements, temp = getLists(temp, 0) -- remove lists
elements, temp = getFiles(temp, 0) -- remove files
temp = mw.ustringtext.gsubtrim((temp,
:gsub('\n%b{} *\n', '\n%0\n') -- add spacing between tables and block templates
temp = mw.ustring. :gsub(temp, '\n%b{} *\n', '\n') -- remove tables and block templates
temp = mw.ustring. :gsub(temp, '\n==+[^=]+==+ *\n', '\n') -- remove section titles
))
temp = mw.ustring.gsub(temp, '\n\n\n+', '\n\n')
temp = mw.text.trim(temp)
 
-- Assume that anything remaining is a paragraph
local count = 0
for paragraph in mw.text.gsplit(temp, '\n\n+') do
if mw.text.trim(paragraph) ~= '' then
count = count + 1
Line 336 ⟶ 361:
end
 
-- Get the requested categories out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of categories to return, for example 2 or '1,3-5'. Omit to return all categories.
-- @return Sequence of strings containing the wikitext of the requested categories.
-- @return Original wikitext minus non-requested categories.
local function getCategories(text, flags)
local categories = {}
Line 347 ⟶ 372:
local name
local count = 0
for category in mw.ustringstring.gmatch(text, '%b[]') do
if matchAnymatchAnyLink(category, '%[%[%s*', categoryNamespaces, '%s*:.*%]%]') then
name = mw.ustringstring.match(category, '%[%[[^:]-:([^]|]+)')
count = count + 1
if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )
Line 362 ⟶ 387:
end
 
-- Get the requested references out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of references to return, for example 2 or '1,3-5'. Omit to return all references.
-- @return Sequence of strings containing the wikitext of the requested references.
-- @return Original wikitext minus non-requested references.
local function getReferences(text, flags)
local references = {}
 
-- Remove all references, including citations, when 0 references are requested
-- This is kind of hacky but currently necessary because the rest of the code
-- doesn't remove citations like <ref name="Foo" /> if Foo is defined elsewhere
if flags and not truthy(flags) then
text = string.gsub(text, '<%s*[Rr][Ee][Ff][^>/]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>', '')
text = string.gsub(text, '<%s*[Rr][Ee][Ff][^>/]*/%s*>', '')
return references, text
end
 
local flags, blacklist = parseFlags(flags)
local name
local count = 0
for reference in mw.ustringstring.gmatch(text, '<%s*[Rr][Ee][Ff][^>/]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>') do
name = mw.ustringstring.match(reference, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?([^"\'>/]+)["\']?[^>]*%s*>')
count = count + 1
if not blacklist and ( not flags or flags[count] or flags[matchFlag(name], flags) )
or blacklist and flags and not flags[count] and not flags[matchFlag(name], flags) then
table.insert(references, reference)
else
text = removeString(text, reference)
if name then
for citation in mw.ustringstring.gmatch(text, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?' .. escapeString(name) .. '["\']?[^/>]*/%s*>') do
text = removeString(text, citation)
end
Line 390 ⟶ 425:
end
 
-- Get the lead section out offrom the given wikitext.
-- @param text Required. Wikitext to parse.
-- @return Wikitext of the lead section.
local function getLead(text)
text = mw.ustringstring.gsub('\n' .. text, '\n==.*', '')
text = mw.text.trim(text)
if not text then return throwError('lead-empty') end
Line 400 ⟶ 435:
end
 
-- Get the wikitextrequested ofsections from the requestedgiven sectionswikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of sections to return, for example 2 or '1,3-5'. Omit to return all referencessections.
-- @return Sequence of strings containing the wikitext of the requested sections.
-- @return Original wikitext minus non-requested sections.
local function getSections(text, flags)
local sections = {}
Line 410 ⟶ 445:
local count = 0
local prefix, section, suffix
for title in mw.ustringstring.gmatch('\n' .. text .. '\n==', '\n==+%s*([^=]+)%s*==+\n') do
count = count + 1
prefix, section, suffix = mw.ustringstring.match('\n' .. text .. '\n==', '\n()==+%s*' .. escapeString(title) .. '%s*==+(.-)()\n==')
if not blacklist and ( not flags or flags[count] or matchFlag(title, flags) )
or blacklist and flags and not flags[count] and not matchFlag(title, flags) then
sections[title] = section
else
text = mw.ustringstring.sub(text, 1, prefix) .. mw.ustringstring.sub(text, suffix)
text = mw.ustringstring.gsub(text, '\n?==$', '') -- remove the trailing \n==
end
end
Line 424 ⟶ 459:
end
 
-- Get the requested section outor of<section> tag from the given wikitext (including subsections).
-- @param text Required. Wikitext to parse.
-- @param section Required. Title of the section to get (in wikitext), for example 'History' or 'History of [[Athens]]'.
Line 432 ⟶ 467:
local escapedSection = escapeString(section)
-- First check if the section title matches a <section> tag
if mw.ustringstring.find(text, '<%s*[Ss]ection%s+begin%s*=%s*["\']?%s*' .. escapedSection .. '%s*["\']?%s*/>') then -- avoid expensive search if possible
text = mw.text.trim((text
text = mw.ustring.gsub(text, '<%s*[Ss]ection%s+end=%s*["\']?%s*'.. escapedSection ..'%s*["\']?%s*/>.-<%s*[Ss]ection%s+begin%s*=%s*["\']?%s*' .. escapedSection .. '%s*["\']?%s*/>', '') -- remove text between section tags
text :gsub('<%s*[Ss]ection%s+end= mw%s*["\']?%s*'.ustring.gsub(text, escapedSection ..'^%s*["\']?%s*/>.-<%s*[Ss]ection%s+begin%s*=%s*["\']?%s*' .. escapedSection .. '%s*["\']?%s*/>', '') -- remove text before firstbetween section tagtags
text = mw.ustring. :gsub(text, '^.-<%s*[Ss]ection%s+endbegin%s*=%s*["\']?%s*' .. escapedSection .. '%s*["\']?%s*/>.*', '') -- remove text afterbefore lastfirst section tag
:gsub('<%s*[Ss]ection%s+end=%s*["\']?%s*'.. escapedSection ..'%s*["\']?%s*/>.*', '') -- remove text after last section tag
text = mw.text.trim(text)
))
if text == '' then return throwError('section-tag-empty', section) end
return text
end
local level, text = mw.ustringstring.match('\n' .. text .. '\n', '\n(==+)%s*' .. escapedSection .. '%s*==.-\n(.*)')
if not text then return throwError('section-not-found', section) end
local nextSection = '\n==' .. mw.ustringstring.rep('=?', #level - 2) .. '[^=].*'
text = mw.ustringstring.gsub(text, nextSection, '') -- remove later sections with headings at this level or higher
text = mw.text.trim(text)
if text == '' then return throwError('section-empty', section) end
Line 473 ⟶ 509:
refBody = mw.ustring.match(full, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?%s*' .. refName .. '%s*["\']?[^/>]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>')
if refBody then -- the ref body was found elsewhere
text = mw.ustring.gsub(text, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?%s*' .. refName .. '%s*["\']?[^>]*/?%s*>', mw.ustring.gsub(refBody, '%%', '%%%%'), 1)
end
end
Line 481 ⟶ 517:
end
end
page = string.gsub(page, '"', '') -- remove any quotation marks from the page title
text = mw.ustring.gsub(text, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?([^"\'>/]+)["\']?[^>/]*(/?)%s*>', '<ref name="' .. page .. ' %1"%2>')
text = mw.ustring.gsub(text, '<%s*[Rr][Ee][Ff]%s*group%s*=%s*["\']?[^"\'>/]+["\']%s*>', '<ref>')
Line 487 ⟶ 524:
 
-- Replace the bold title or synonym near the start of the page by a link to the page
local function linkBold(text, page)
local lang = mw.language.getContentLanguage()
local position = mw.ustring.find(text, "'''" .. lang:ucfirst(page) .. "'''", 1, true) -- look for "'''Foo''' is..." (uc) or "A '''foo''' is..." (lc)
Line 501 ⟶ 538:
return nil -- instruct gsub to make no change
end
end, 1) -- "end" here terminates the anonymous replacement function(a, b) passed to gsub
end
return text
Line 514 ⟶ 551:
local fileDescription
local frame = mw.getCurrentFrame()
for file in mw.ustringstring.gmatch(text, '%b[]') do
if matchAnymatchAnyLink(file, '%[%[%s*', fileNamespaces, '%s*:.*%]%]') then
fileName = 'File:' .. mw.ustringstring.match(file, '%[%[[^:]-:([^]|]+)')
fileDescription, fileName = getText(fileName)
if fileName then
Line 522 ⟶ 559:
fileDescription = frame:preprocess('{{' .. fileName .. '}}') -- try Commons
end
if fileDescription and mw.ustringstring.match(fileDescription, '[Nn]on%-free') then
text = removeString(text, file)
end
Line 532 ⟶ 569:
 
-- Remove any self links
local function removeSelfLinks(text)
local lang = mw.language.getContentLanguage()
local page = escapeString( mw.title.getCurrentTitle().prefixedText )
textlocal ucpage = mw.ustring.gsub(text, '%[%[(' .. lang:ucfirst(page) .. ')%]%]', '%1')
textlocal lcpage = mw.ustring.gsub(text, '%[%[(' .. lang:lcfirst(page) .. ')%]%]', '%1')
text = text
text = mw.ustring.gsub(text, '%[%[' .. lang:ucfirst(page) .. '|([^]]+)%]%]', '%1')
text = mw.ustring. :gsub(text, '%[%[(' .. lang:lcfirst(page)ucpage .. '|([^]]+)%]%]', '%1')
:gsub('%[%[(' .. lcpage .. ')%]%]', '%1')
:gsub('%[%[' .. ucpage .. '|([^]]+)%]%]', '%1')
:gsub('%[%[' .. lcpage .. '|([^]]+)%]%]', '%1')
return text
end
 
-- Remove all wikilinks
local function removeLinks(text)
text = text
:gsub('%[%[[^%]|]+|([^]]+)%]%]', '%1')
:gsub('%[%[([^]]+)%]%]', '%1')
:gsub('%[[^ ]+ ([^]]+)%]', '%1')
:gsub('%[([^]]+)%]', '%1')
return text
end
 
-- Remove HTML comments
local function removeComments(text)
text = string.gsub(text, '<!%-%-.-%-%->', '')
return text
end
 
-- Remove behavior switches, such as __NOTOC__
local function removeBehaviorSwitches(text)
text = string.gsub(text, '__[A-Z]+__', '')
return text
end
 
-- Remove bold text
local function removeBold(text)
text = string.gsub(text, "'''", '')
return text
end
Line 546 ⟶ 614:
if not options then options = {} end
 
-- Make sure the page exists
if not page then return throwError('no-page') end
page = mw.text.trim(page)
page = mw.text.decode(page)
if page == '' then return throwError('no-page') end
local page, hash, section = mw.ustringstring.match(page, '([^#]+)(#?)([^#].*)')
local text, pagetemp = getText(page, options.noFollow)
if not pagetemp then return throwError('noinvalid-pagetitle', page) end
page = temp
if not text then return throwError('page-not-found', page) end
local full = text -- save the full text for fixReferences below
Line 563 ⟶ 634:
 
-- Keep only the requested elements
local elements
local only = parseFlags(options.only) or {}
local elements = {}
if options.sections or only.sections then
elements.sections, text = getSections(text, options.sections)
end
if options.lists or only.lists then
elements.lists, text = getLists(text, options.lists)
end
if options.files or only.files then
elements.files, text = getFiles(text, options.files)
end
if options.tables or only.tables then
elements.tables, text = getTables(text, options.tables)
end
if options.templates or only.templates then
elements.templates, text = getTemplates(text, options.templates)
end
if options.parameters or only.parameters then
elements.parameters, text = getParameters(text, options.parameters)
end
if options.paragraphs or only.paragraphs then
elements.paragraphs, text = getParagraphs(text, options.paragraphs)
end
if options.categories or only.categories then
elements.categories, text = getCategories(text, options.categories)
end
if options.references or only.references then
elements.references, text = getReferences(text, options.references)
end
 
-- If 'only' is set, return the elements in the requested order
if options.only then
if options.only == 'sections' then elements = getSections(text, options.sections) end
if options.only == 'lists' then elements = getLists(text, options.lists) end
if options.only == 'files' then elements = getFiles(text, options.files) end
if options.only == 'tables' then elements = getTables(text, options.tables) end
if options.only == 'templates' then elements = getTemplates(text, options.templates) end
if options.only == 'parameters' then elements = getParameters(text, options.parameters) end
if options.only == 'paragraphs' then elements = getParagraphs(text, options.paragraphs) end
if options.only == 'categories' then elements = getCategories(text, options.categories) end
if options.only == 'references' then elements = getReferences(text, options.references) end
text = ''
if elements then
for element in mw.text.gsplit(options.only, ',') do
for key, element in pairs(elements) do
element = elements[ mw.text.trim(element) ]
if text = text .. '\n' .. element then.. '\n'
for key, value in pairs(element) do
text = text .. '\n' .. value .. '\n'
end
end
end
end
 
-- Filter the requested elements
if options.sections and options.only ~= 'sections' then elements, text = getSections(text, options.sections) end
if options.lists and options.only ~= 'lists' then elements, text = getLists(text, options.lists) end
if options.files and options.only ~= 'files' then elements, text = getFiles(text, options.files) end
if options.tables and options.only ~= 'tables' then elements, text = getTables(text, options.tables) end
if options.templates and options.only ~= 'templates' then elements, text = getTemplates(text, options.templates) end
if options.parameters and options.only ~= 'parameters' then elements, text = getParameters(text, options.parameters) end
if options.paragraphs and options.only ~= 'paragraphs' then elements, text = getParagraphs(text, options.paragraphs) end
if options.categories and options.only ~= 'categories' then elements, text = getCategories(text, options.categories) end
if options.references and options.only ~= 'references' then elements, text = getReferences(text, options.references) end
 
-- Misc options
if truthy(options.fixReferences) then text = fixReferences(text, page, full) end
if truthy(options.linkBold) and not truthy(section) then text = linkBold(text, page) end
if truthy(options.noNonFreeFilesnoBold) then text = removeNonFreeFilesremoveBold(text) end
if truthy(options.noLinks) then text = removeLinks(text) end
if truthy(options.noSelfLinks) then text = removeSelfLinks(text) end
if truthy(options.noBoldnoNonFreeFiles) then text = mw.ustring.gsubremoveNonFreeFiles(text, "'''", '') end
if truthy(options.noBehaviorSwitches) then text = mw.ustring.gsubremoveBehaviorSwitches(text, '__[A-Z]+__', '') end
if truthy(options.noComments) then text = mw.ustring.gsubremoveComments(text, '<!%-%-.-%-%->', '') end
 
-- Remove multiple newlines left over from removing elements
text = mw.ustringstring.gsub(text, '\n\n\n+', '\n\n')
text = mw.text.trim(text)
 
Line 628 ⟶ 687:
local ok, text = pcall(get, page, args)
if not ok then return getError(text) end
local raw = args['raw']
if raw then return text end
return frame:preprocess(text)
end
Line 656 ⟶ 717:
function p.matchFlag(value, flags) return matchFlag(value, flags) end
function p.getNamespaces(name) return getNamespaces(name) end
function p.removeBold(text) return removeBold(text) end
function p.removeLinks(text) return removeLinks(text) end
function p.removeSelfLinks(text) return removeSelfLinks(text) end
function p.removeNonFreeFiles(text) return removeNonFreeFiles(text) end
function p.removeBehaviorSwitches(text) return removeBehaviorSwitches(text) end
function p.removeComments(text) return removeComments(text) end
 
return p