Module:Transcluder and Module:Transcluder/sandbox: Difference between pages
Appearance
(Difference between pages)
Content deleted Content added
Sophivorus (talk | contribs) Add page decoding |
Sophivorus (talk | contribs) 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 & |
-- 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 |
local parameters = {} |
||
local paramOrder = {} |
|||
local flags, blacklist = parseFlags(flags) |
local flags, blacklist = parseFlags(flags) |
||
local params |
local params = WikitextParser.getTemplateParameters(text) |
||
for |
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 |
|||
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, |
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 = |
text = text:gsub('< *ref[^>/]*>.-< */ *ref *>', '') |
||
text = |
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 |
|||
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) |
|||
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 .. ' |
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 .. ' |
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 .. ' |
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 |