Jump to content

Module:Transcluder and Module:Transcluder/sandbox: Difference between pages

(Difference between pages)
Page 1
Page 2
Content deleted Content added
Add page decoding
 
mNo edit summary
 
Line 1: Line 1:
-- Module:Transcluder is a general-purpose transclusion engine
-- Module:Transcluder is a general-purpose transclusion engine
-- Documentation and master version: https://en.wikipedia.org/wiki/Module:Transcluder
-- Documentation and master version: https://en.wikipedia.org/wiki/Module:Transcluder
-- Authors: User:Sophivorus, User:Certes & others
-- Authors: User:Sophivorus, User:Certes & User:Aidan9382
-- License: CC-BY-SA-3.0
-- License: CC-BY-SA-3.0


local p = {}
local p = {}

local WikitextParser = require( 'Module:WikitextParser' )


-- Helper function to test for truthy and falsy values
-- Helper function to test for truthy and falsy values
Line 177: Line 179:


return text, title.prefixedText
return text, title.prefixedText
end

-- Get the requested tags from the given wikitext.
-- @param text Required. Wikitext to parse.
-- @param flags Range of tags to return, for example 2 or '1,3-5'. Omit to return all tags.
-- @return Sequence of strings containing the wikitext of the requested tags.
-- @return Original wikitext minus requested tags.
local function getTags(text, flags)
local tags = {}
local flags, blacklist = parseFlags(flags)
for count, tag in pairs(WikitextParser.getTags(text)) do
local name = string.match(tag, '< ?(.-)[ >]')
if not blacklist and ( not flags or flags[count] or flags[name] )
or blacklist and flags and not flags[count] and not flags[name] then
table.insert(tags, tag)
else
text = removeString(text, tag)
end
end
return tags, text
end
end


Line 187: Line 209:
local files = {}
local files = {}
local flags, blacklist = parseFlags(flags)
local flags, blacklist = parseFlags(flags)
for count, file in pairs(WikitextParser.getFiles(text)) do
local fileNamespaces = getNamespaces('File')
local name = string.match(file, '%[%[[^:]-:([^]|]+)')
local name
if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )
local count = 0
or blacklist and flags and not flags[count] and not matchFlag(name, flags) then
for file in string.gmatch(text, '%b[]') do
table.insert(files, file)
if matchAnyLink(file, fileNamespaces) then
else
name = string.match(file, '%[%[[^:]-:([^]|]+)')
text = removeString(text, file)
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(files, file)
else
text = removeString(text, file)
end
end
end
end
end

return files, text
return files, text
end
end
Line 214: Line 229:
local tables = {}
local tables = {}
local flags, blacklist = parseFlags(flags)
local flags, blacklist = parseFlags(flags)
for count, t in pairs(WikitextParser.getTables(text)) do
local id
local id = string.match(t, '{|[^\n]-id%s*=%s*["\']?([^"\'\n]+)["\']?[^\n]*\n')
local count = 0
if not blacklist and ( not flags or flags[count] or flags[id] )
for t in string.gmatch('\n' .. text, '\n%b{}') do
or blacklist and flags and not flags[count] and not flags[id] then
if string.sub(t, 1, 3) == '\n{|' then
table.insert(tables, t)
id = string.match(t, '\n{|[^\n]-id%s*=%s*["\']?([^"\'\n]+)["\']?[^\n]*\n')
else
count = count + 1
text = removeString(text, t)
if not blacklist and ( not flags or flags[count] or flags[id] )
or blacklist and flags and not flags[count] and not flags[id] then
table.insert(tables, t)
else
text = removeString(text, t)
end
end
end
end
end
Line 239: Line 249:
local templates = {}
local templates = {}
local flags, blacklist = parseFlags(flags)
local flags, blacklist = parseFlags(flags)
for count, template in pairs(WikitextParser.getTemplates(text)) do
local name
local name = string.match( template, '^{{ *([^}|\n]+)' )
local count = 0
if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )
for template in string.gmatch(text, '{%b{}}') do
or blacklist and flags and not flags[count] and not matchFlag(name, flags) then
if string.sub(template, 1, 3) ~= '{{#' then -- skip parser functions like #if
table.insert(templates, template)
name = mw.text.trim( string.match(template, '{{([^}|\n]+)') or "" ) -- get the template name
else
if name ~= "" then
text = removeString(text, template)
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
end
end
end
Line 258: Line 261:
end
end


-- Get the requested template parameters from the given wikitext.
-- Get the requested template parameters from the given template wikitext.
-- @param text Required. Wikitext to parse.
-- @param text Required. Wikitext of the template to parse.
-- @param flags Range of parameters to return, for example 2 or '1,3-5'. Omit to return all parameters.
-- @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 Map from parameter name to value, NOT IN THE ORIGINAL ORDER
-- @return Original wikitext minus requested parameters.
-- @return Order in which the parameters were parsed.
-- @return Order in which the parameters were parsed.
local function getParameters(text, flags)
local function getParameters(text, flags)
local parameters, parameterOrder = {}, {}
local parameters = {}
local paramOrder = {}
local flags, blacklist = parseFlags(flags)
local flags, blacklist = parseFlags(flags)
local params, count, parts, key, value
local params = WikitextParser.getTemplateParameters(text)
for template in string.gmatch(text, '{%b{}}') do
for name, value in pairs(params) do
if not blacklist and ( not flags or matchFlag(name, flags) )
params = string.match(template, '{{[^|}]-|(.*)}}')
or blacklist and flags and not matchFlag(name, flags) then
if params then
count = 0
parameters[name] = value
table.insert( paramOrder, name )
-- Temporarily replace pipes in subtemplates and links to avoid chaos
for subtemplate in string.gmatch(params, '{%b{}}') do
params = string.gsub(params, escapeString(subtemplate), string.gsub(subtemplate, ".", {["%"]="%%", ["|"]="@@:@@", ["="]="@@_@@"}) )
end
for link in string.gmatch(params, '%b[]') do
params = string.gsub(params, escapeString(link), string.gsub(link, ".", {["%"]="%%", ["|"]="@@:@@", ["="]="@@_@@"}) )
end
for parameter in mw.text.gsplit(params, '|') do
parts = mw.text.split(parameter, '=')
key = mw.text.trim(parts[1])
if #parts == 1 then
value = key
count = count + 1
key = count
else
value = mw.text.trim(table.concat(parts, '=', 2))
end
value = string.gsub(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
text = removeString(text, parameter)
end
end
end
end
end
end
return parameters, text, parameterOrder
return parameters, paramOrder
end
end


Line 311: Line 289:
local lists = {}
local lists = {}
local flags, blacklist = parseFlags(flags)
local flags, blacklist = parseFlags(flags)
for count, list in pairs(WikitextParser.getLists(text)) do
local count = 0
for list in string.gmatch('\n' .. text .. '\n\n', '\n([*#].-)\n[^*#]') do
count = count + 1
if not blacklist and ( not flags or flags[count] )
if not blacklist and ( not flags or flags[count] )
or blacklist and flags and not flags[count] then
or blacklist and flags and not flags[count] then
Line 332: Line 308:
local paragraphs = {}
local paragraphs = {}
local flags, blacklist = parseFlags(flags)
local flags, blacklist = parseFlags(flags)
for count, paragraph in pairs(WikitextParser.getParagraphs(text)) do

if not blacklist and ( not flags or flags[count] )
-- Remove non-paragraphs
or blacklist and flags and not flags[count] then
local elements
table.insert(paragraphs, paragraph)
local temp = '\n' .. text .. '\n'
else
elements, temp = getLists(temp, 0) -- remove lists
text = removeString(text, paragraph)
elements, temp = getFiles(temp, 0) -- remove files
temp = mw.text.trim((temp
:gsub('\n%b{} *\n', '\n%0\n') -- add spacing between tables and block templates
:gsub('\n%b{} *\n', '\n') -- remove tables and block templates
:gsub('\n==+[^=]+==+ *\n', '\n') -- remove section titles
))

-- 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
if not blacklist and ( not flags or flags[count] )
or blacklist and flags and not flags[count] then
table.insert(paragraphs, paragraph)
else
text = removeString(text, paragraph)
end
end
end
end
end

return paragraphs, text
return paragraphs, text
end
end
Line 369: Line 327:
local categories = {}
local categories = {}
local flags, blacklist = parseFlags(flags)
local flags, blacklist = parseFlags(flags)
for count, category in pairs(WikitextParser.getCategories(text)) do
local categoryNamespaces = getNamespaces('Category')
local name = string.match(category, '%[%[[^:]-:([^]|]+)')
local name
if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )
local count = 0
or blacklist and flags and not flags[count] and not matchFlag(name, flags) then
for category in string.gmatch(text, '%b[]') do
table.insert(categories, category)
if matchAnyLink(category, categoryNamespaces) then
else
name = string.match(category, '%[%[[^:]-:([^]|]+)')
text = removeString(text, category)
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(categories, category)
else
text = removeString(text, category)
end
end
end
end
end
Line 399: Line 351:
-- doesn't remove citations like <ref name="Foo" /> if Foo is defined elsewhere
-- doesn't remove citations like <ref name="Foo" /> if Foo is defined elsewhere
if flags and not truthy(flags) then
if flags and not truthy(flags) then
text = string.gsub(text, '<%s*[Rr][Ee][Ff][^>/]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>', '')
text = text:gsub('< *ref[^>/]*>.-< */ *ref *>', '')
text = string.gsub(text, '<%s*[Rr][Ee][Ff][^>/]*/%s*>', '')
text = text:gsub('< *ref[^>/]*/ *>', '')
return references, text
return references, text
end
end


local flags, blacklist = parseFlags(flags)
local flags, blacklist = parseFlags(flags)
for count, reference in pairs(WikitextParser.getReferences(text)) do
local name
if not reference:match('^< *ref.-/ *>') then
local count = 0
local name = reference:match('< *ref.-name *= *["\']?([^"\'>/]+)["\']?')
for reference in string.gmatch(text, '<%s*[Rr][Ee][Ff][^>/]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>') do
if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )
name = string.match(reference, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?([^"\'>/]+)["\']?[^>]*%s*>')
or blacklist and flags and not flags[count] and not matchFlag(name, flags) then
count = count + 1
table.insert(references, reference)
if not blacklist and ( not flags or flags[count] or matchFlag(name, flags) )
else
or blacklist and flags and not flags[count] and not matchFlag(name, flags) then
table.insert(references, reference)
text = removeString(text, reference)
if name then
else
for citation in text:gmatch('< *ref.-name *= *["\']?' .. escapeString(name) .. '["\']?.-/ *>') do
text = removeString(text, reference)
text = removeString(text, citation)
if name then
end
for citation in string.gmatch(text, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?' .. escapeString(name) .. '["\']?[^/>]*/%s*>') do
text = removeString(text, citation)
end
end
end
end
Line 429: Line 380:
-- @return Wikitext of the lead section.
-- @return Wikitext of the lead section.
local function getLead(text)
local function getLead(text)
local lead = WikitextParser.getLead(text)
text = string.gsub('\n' .. text, '\n==.*', '')
if lead == '' then return throwError('lead-empty') end
text = mw.text.trim(text)
if not text then return throwError('lead-empty') end
return lead
return text
end
end


Line 505: Line 455:
table.insert(refNames, refName)
table.insert(refNames, refName)
refName = escapeString(refName)
refName = escapeString(refName)
refBody = mw.ustring.match(text, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?%s*' .. refName .. '%s*["\']?[^>/]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>')
refBody = mw.ustring.match(text, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?%s*' .. refName .. '["\' >][^>/]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>')
if not refBody then -- the ref body is not in the excerpt
if not refBody then -- the ref body is not in the excerpt
refBody = mw.ustring.match(full, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?%s*' .. refName .. '%s*["\']?[^/>]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>')
refBody = mw.ustring.match(full, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?%s*' .. refName .. '["\' >][^>/]*>.-<%s*/%s*[Rr][Ee][Ff]%s*>')
if refBody then -- the ref body was found elsewhere
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)
text = mw.ustring.gsub(text, '<%s*[Rr][Ee][Ff][^>]*name%s*=%s*["\']?%s*' .. refName .. '["\' >][^>]*/?%s*>', mw.ustring.gsub(refBody, '%%', '%%%%'), 1)
end
end
end
end
Line 640: Line 590:
if options.only == 'files' then elements = getFiles(text, options.files) 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 == 'tables' then elements = getTables(text, options.tables) end
if options.only == 'tags' then elements = getTags(text, options.tags) end
if options.only == 'templates' then elements = getTemplates(text, options.templates) 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 == 'parameters' then elements = getParameters(text, options.parameters) end
Line 658: Line 609:
if options.files and options.only ~= 'files' then elements, text = getFiles(text, options.files) 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.tables and options.only ~= 'tables' then elements, text = getTables(text, options.tables) end
if options.tags and options.only ~= 'tags' then elements, text = getTags(text, options.tags) end
if options.templates and options.only ~= 'templates' then elements, text = getTemplates(text, options.templates) 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.parameters and options.only ~= 'parameters' then elements, text = getParameters(text, options.parameters) end
Line 707: Line 659:
function p.getTemplates(text, flags) return getTemplates(text, flags) end
function p.getTemplates(text, flags) return getTemplates(text, flags) end
function p.getTables(text, flags) return getTables(text, flags) end
function p.getTables(text, flags) return getTables(text, flags) end
function p.getTags(text, flags) return getTags(text, flags) end
function p.getLists(text, flags) return getLists(text, flags) end
function p.getLists(text, flags) return getLists(text, flags) end
function p.getFiles(text, flags) return getFiles(text, flags) end
function p.getFiles(text, flags) return getFiles(text, flags) end