„Modul:Excerpt“ – Versionsunterschied
Erscheinungsbild
[gesichtete Version] | [ungesichtete Version] |
Inhalt gelöscht Inhalt hinzugefügt
Keine Bearbeitungszusammenfassung Markierungen: Mobile Bearbeitung Mobile Web-Bearbeitung |
Resetting page to the current content of mw:Module:Excerpt. (docs) |
||
Zeile 1: | Zeile 1: | ||
local Transcluder = require('Module:Transcluder') |
|||
local p = {} |
|||
local mRedirect = require('Modul:Redirect') |
|||
local yesno = require('Module:Yesno') |
|||
local errors |
|||
-- Return blank text, or an error message if requested |
|||
local function err(text) |
|||
if errors then error(text, 2) end |
|||
return "" |
|||
end |
|||
local ok, config = pcall(require, 'Module:Excerpt/config') |
|||
-- Check image for suitablity |
|||
if not ok then config = {} end |
|||
local function checkimage(image) |
|||
local page = mw.ustring.match(image, "([Ff]ile%s*:[^|%]]*)") -- File:(name) ... |
|||
or mw.ustring.match(image, "([Ii]mage%s*:[^|%]]*)") -- or Image:(name) ... |
|||
if not page then return nil end |
|||
local p = {} |
|||
local title = mw.title.new(":" .. page) -- Read description page (for :File:Foo rather than File:Foo) |
|||
if not title then return nil end |
|||
-- Helper function to get arguments |
|||
local redir = mRedirect.getTarget(title) |
|||
local args |
|||
if redir then title = mw.title.new(redir) end |
|||
function getArg(key, default) |
|||
value = args[key] |
|||
local frame = mw.getCurrentFrame() |
|||
if value and mw.text.trim(value) ~= '' then |
|||
local desc = frame:preprocess("{{" .. title.prefixedText .. "}}") |
|||
return value |
|||
return desc and desc ~= "" and not mw.ustring.match(desc, "[Nn]on%-free") -- hide non-free image |
|||
end |
|||
return default |
|||
end |
end |
||
-- Helper function to handle errors |
|||
-- Attempt to parse [[File:...]] or [[Image:...]], either anywhere or at the start |
|||
function getError(message, value) |
|||
if type(message) == 'string' then |
|||
local startre = "" |
|||
message = Transcluder.getError(message, value) |
|||
if start then startre = "^" end -- a true flag restricts search to start of string |
|||
end |
|||
local image = mw.ustring.match(text, startre .. "%[%[%s*[Ff]ile%s*:.*") -- [[File: ... |
|||
if config.categories and config.categories.errors and mw.title.getCurrentTitle().isContentPage then |
|||
or mw.ustring.match(text, startre .. "%[%[%s*[Ii]mage%s*:.*") -- or [[Image: ... |
|||
message:node('[[Category:' .. config.categories.errors .. ']]') |
|||
if image then |
|||
image = mw.ustring.match(image, "%b[]%s*") -- match [[...]] to handle nesting |
|||
end |
end |
||
return |
return message |
||
end |
end |
||
-- Helper function to get localized messages |
|||
-- Attempt to construct a [[File:...]] block from {{infobox ... |image= ...}} |
|||
function getMessage(key) |
|||
local |
local ok, TNT = pcall(require, 'Module:TNT') |
||
if not ok then return key end |
|||
if mw.ustring.match(text, "%{%{%s*[Ii]nfobox") then |
|||
return TNT.format('I18n/Module:Excerpt.tab', key) |
|||
local image = mw.ustring.match(text, "|%s*image%s*=%s*([^%}|]*)") -- parse image= argument... |
|||
or mw.ustring.match(text, "|%s*Cover%s*=%s*([^%}|]-)") -- or Cover= from Infobox album |
|||
if image then -- add in relevant parameters: caption, alt text and image size |
|||
token = "[[File:" .. image |
|||
local caption = mw.ustring.match(text, "|%s*[Cc]aption%s*=%s*([^%}|]*)") |
|||
if caption then token = token .. "|" .. caption end |
|||
local alt = mw.ustring.match(text, "|%s*alt%s*=%s*([^%}|]*)") |
|||
if alt then token = token .. "|alt=" .. alt end |
|||
local image_size = mw.ustring.match(text, "|%s*image_size%s*=%s*([^%}|]*)") |
|||
if image_size then token = token .. "|" .. image_size end |
|||
token = mw.ustring.gsub(token, "\n","") .. "]]\n" |
|||
end |
|||
end |
|||
return token |
|||
end |
end |
||
function p.main(frame) |
|||
-- Entry point for Lua callers |
|||
args = Transcluder.parseArgs(frame) |
|||
-- Returns a string value: text of the lead of a page |
|||
function p._lead(pagenames, options) |
|||
errors = options.errors |
|||
-- Make sure the requested page exists |
|||
if not pagenames or #pagenames < 1 then return err("No page names given") end |
|||
local |
local page = getArg(1) |
||
if not page then return getError('no-page') end |
|||
local text |
|||
local |
local title = mw.title.new(page) |
||
if not title then return getError('no-page') end |
|||
local firstpage = pagenames[1] or "(nil)" -- save for error message, as it the name will be deleted |
|||
if title.isRedirect then title = title.redirectTarget end |
|||
if not title.exists then return getError('page-not-found', page) end |
|||
page = title.prefixedText |
|||
-- Set variables |
|||
-- read the page, or a random one if multiple pages were provided |
|||
local fragment = getArg('fragment') |
|||
if pagecount > 1 then math.randomseed(os.time()) end |
|||
local section = fragment or getArg(2, getArg('section', mw.ustring.match(getArg(1), '[^#]+#([^#]+)') ) ) |
|||
while not text and pagecount > 0 do |
|||
local hat = yesno( getArg('hat', true) ) |
|||
local pagenum = 1 |
|||
local this = getArg('this') |
|||
if pagecount > 1 then pagenum = math.random(pagecount) end -- pick a random title |
|||
local only = getArg('only') |
|||
pagename = pagenames[pagenum] |
|||
local files = getArg('files') |
|||
if pagename and pagename ~= "" then |
|||
local lists = getArg('lists') |
|||
pagename = mw.ustring.match(pagename, "%[%[%s*(.-)[]|#]") or pagename -- "[[Foo|Bar]]" → "Foo" |
|||
local tables = getArg('tables') |
|||
pagename = mw.ustring.match(pagename, "%S.*%S") -- strip leading and trailing white space |
|||
local sections = not yesno( getArg('sections') ) |
|||
local templates = table.concat((config.templates or {}), ',') |
|||
local paragraphs = getArg('paragraphs') |
|||
local references = getArg('references') |
|||
local noBold = not yesno( getArg('bold') ) |
|||
local inline = yesno( getArg('inline') ) |
|||
local quote = yesno( getArg('quote') ) |
|||
local more = yesno( getArg('more') ) |
|||
local class = getArg('class') |
|||
-- Build the hatnote |
|||
if pagename and pagename ~= "" then |
|||
if hat and not inline then |
|||
local title = mw.title.new(pagename) -- Find the lead section of the named page |
|||
if this then |
|||
if not title then return err("No title for page name " .. pagename) end |
|||
hat = this |
|||
local redir = mRedirect.getTarget(title) |
|||
elseif quote then |
|||
if redir then title = mw.title.new(redir) end |
|||
hat = getMessage('this') |
|||
elseif only then |
|||
text = title:getContent() |
|||
hat = getMessage(only) |
|||
end |
|||
else |
|||
hat = getMessage('section') |
|||
end |
end |
||
hat = hat .. ' ' .. getMessage('excerpt') .. ' ' |
|||
if not text then table.remove(pagenames, pagenum) end -- this one didn't work; try another |
|||
if section and not fragment then |
|||
pagecount = pagecount - 1 -- ensure that we exit the loop eventually |
|||
hat = hat .. '[[' .. page .. '#' .. mw.uri.anchorEncode(section) .. '|' .. page |
|||
.. ' § ' .. mw.ustring.gsub(section, '%[%[([^]|]+)|?[^]]*%]%]', '%1') .. ']]' -- remove nested links |
|||
else |
|||
hat = hat .. '[[' .. page .. ']]' |
|||
end |
|||
hat = hat .. "''" .. '<span class="mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span>[' |
|||
hat = hat .. title:fullUrl('action=edit') .. ' ' .. mw.message.new('editsection'):plain() |
|||
hat = hat .. ']<span class="mw-editsection-bracket">]</span></span>' .. "''" |
|||
local ok, Hatnote = pcall(require, 'Module:Hatnote') |
|||
if ok then |
|||
hat = Hatnote._hatnote( hat, { extraclasses = 'dablink excerpt-hat', selfref = true } ) |
|||
else |
|||
hat = mw.html.create('div'):addClass('dablink excerpt-hat'):wikitext(hat) |
|||
end |
|||
else |
|||
hat = nil |
|||
end |
end |
||
if not text then return err("Cannot read a valid page: first name is " .. firstpage) end |
|||
-- Build the "Read more" link |
|||
text = mw.ustring.gsub(text, "<!%-%-.-%-%->","") -- remove HTML comments |
|||
if more and not inline then |
|||
text = mw.ustring.gsub(text, "%c%s*==.*","") -- remove first heading and everything after it |
|||
more = "'''[[" .. page .. '#' .. (section or '') .. "|" .. getMessage('more') .. "]]'''" |
|||
text = mw.ustring.gsub(text, "<noinclude>.-</noinclude>", "") -- remove noinclude bits |
|||
more = mw.html.create('div'):addClass('noprint excerpt-more'):wikitext(more) |
|||
text = mw.ustring.gsub(text, "<%s*ref[^>]-/%s*>", "") -- remove refs cited elsewhere |
|||
else |
|||
text = mw.ustring.gsub(text, "<%s*ref.->.-<%s*/%s*ref%s*>", "") -- remove refs |
|||
more = nil |
|||
text = mw.ustring.gsub(text, "<%s*imagemap.->.-<%s*/%s*imagemap%s*>", "") -- remove imagemaps |
|||
for _, t in pairs {"[Ee]fn", "[Ee]fn-la", "[Ee]l[mn]", "[Rr]p?", "[Ss]fn[bp]", "[Ss]f[bn]", "NoteTag", "#[Tt]ag:%s*[Rr]ef", |
|||
"[CcDd]n", "Citation needed", "Disambiguation needed"} do |
|||
text = mw.ustring.gsub(text, "{{%s*" .. t .. "%s*|.-}}", "") -- remove ref and footnote templates |
|||
end |
end |
||
text = mw.ustring.gsub(text, "\n%s*{{%s*[Tt][Oo][Cc].-}}", "\n") -- remove most common tables of contents |
|||
-- Build the options for Module:Transcluder out of the template arguments and the desired defaults |
|||
local allparas = true -- keep all paragraphs? |
|||
local options = { |
|||
files = files, |
|||
for _, v in pairs(options.paraflags) do |
|||
lists = lists, |
|||
if v then allparas = false end -- if any para specifically requested, don't keep all |
|||
tables = tables, |
|||
end |
|||
paragraphs = paragraphs, |
|||
end |
|||
templates = templates ~= '' and '-' .. templates, |
|||
sections = sections, |
|||
categories = 0, |
|||
references = references, |
|||
only = only and mw.text.trim(only, 's') .. 's', |
|||
noBold = noBold, |
|||
noSelfLinks = true, |
|||
noNonFreeFiles = true, |
|||
noBehaviorSwitches = true, |
|||
fixReferences = true, |
|||
linkBold = true, |
|||
} |
|||
-- Get the excerpt itself |
|||
local maxfile = 0 -- for efficiency, stop checking images after this many have been found |
|||
local title = page .. '#' .. (section or '') |
|||
if options.fileflags then |
|||
local ok, excerpt = pcall(Transcluder.get, title, options) |
|||
for k, v in pairs(options.fileflags) do |
|||
if not ok then return getError(excerpt) end |
|||
if mw.text.trim(excerpt) == '' then |
|||
end |
|||
if section then return getError('section-empty', section) else return getError('lead-empty') end |
|||
end |
end |
||
-- Add a line break in case the excerpt starts with a table or list |
|||
-- a basic parser to trim down the lead |
|||
excerpt = '\n' .. excerpt |
|||
local inlead = false -- have we found some text yet? |
|||
local t = "" -- the stripped down output text |
|||
local files = 0 -- how many [[Image: or [[File: so far |
|||
local paras = 0 -- how many paragraphs so far |
|||
-- If no file was found, try to excerpt one from the removed infoboxes |
|||
text = mw.ustring.gsub(text,"^%s*","") -- remove initial white space |
|||
local fileNamespaces = Transcluder.getNamespaces('File') |
|||
repeat -- loop around parsing a template, image or paragraph |
|||
if (files ~= '0' or not files) and not Transcluder.matchAny(excerpt, '%[%[', fileNamespaces, ':') and config.captions then |
|||
local token = mw.ustring.match(text, "^%b{}%s*") or false -- {{Template}} |
|||
local templates = Transcluder.get(title, { only = 'templates', templates = templates, fixReferences = true } ) |
|||
if token then |
|||
local parameters = Transcluder.getParameters(templates) |
|||
if inlead then -- keep comments and templates only within text body |
|||
local file, captions, caption |
|||
t = t .. token |
|||
for _, pair in pairs(config.captions) do |
|||
elseif files < maxfile then -- look for [[File:... embedded in an infobox etc. in the preamble |
|||
file = pair[1] |
|||
local image = parseimage(token, false) or argimage(token) |
|||
file = parameters[file] |
|||
if image and checkimage(image) then -- keep comments and templates only within text body |
|||
if file and Transcluder.matchAny(file, '^.*%.', {'[Jj][Pp][Ee]?[Gg]','[Pp][Nn][Gg]','[Gg][Ii][Ff]','[Ss][Vv][Gg]'}, '.*') then |
|||
files = files + 1 |
|||
file = mw.ustring.match(file, '%[?%[?.-:([^{|]+)%]?%]?') or file -- [[File:Example.jpg{{!}}upright=1.5]] to Example.jpg |
|||
if options.fileflags and options.fileflags[files] then |
|||
captions = pair[2] |
|||
image = mw.ustring.gsub(image, "|%s*frameless%s*%f[|%]]", "") -- make image a thumbnail, not frameless etc. |
|||
for _, p in pairs(captions) do |
|||
image = mw.ustring.gsub(image, "|%s*framed?%s*%f[|%]]", "") |
|||
if parameters[p] then caption = parameters[p] break end |
|||
if not mw.ustring.match(image, "|%s*thumb%s*%f[|%]]") |
|||
and not mw.ustring.match(image, "|%s*thumbnail%s*%f[|%]]") then |
|||
image = mw.ustring.gsub(image, "(%]%]%s*)$", "|thumb%1") |
|||
end |
|||
if options.fileargs then image = mw.ustring.gsub(image, "(%]%]%s*)$", "|" .. options.fileargs .. "%1") end |
|||
t = t .. image |
|||
end |
|||
end |
end |
||
excerpt = '[[File:' .. file .. '|thumb|' .. (caption or '') .. ']]' .. excerpt |
|||
end |
|||
break |
|||
token = parseimage(text, true) |
|||
if token then |
|||
if files < maxfile and checkimage(token) then |
|||
files = files + 1 |
|||
if options.fileflags and options.fileflags[files] then |
|||
local image = token |
|||
if options.fileargs then image = mw.ustring.gsub(image, "(%]%]%s*)$", "|" .. options.fileargs .. "%1") end |
|||
t = t .. image |
|||
end |
|||
end |
|||
else -- got a paragraph, which ends at a file, image, blank line or end of text |
|||
local afterend = mw.ustring.len(text) + 1 |
|||
local blankpos = mw.ustring.find(text, "\n%s*\n") or afterend |
|||
local endpos = math.min( |
|||
mw.ustring.find(text, "%[%[%s*[Ff]ile%s*:") or afterend, |
|||
mw.ustring.find(text, "%[%[%s*[Ff]ile%s*:") or afterend, |
|||
blankpos) |
|||
token = mw.ustring.sub(text, 1, endpos-1) |
|||
if blankpos < afterend and blankpos == endpos then -- paragraph ends with a blank line |
|||
token = token .. mw.ustring.match(text, "\n%s*\n", blankpos) |
|||
end |
|||
inlead = true |
|||
paras = paras + 1 |
|||
if allparas or (options.paraflags and options.paraflags[paras]) then t = t .. token end |
|||
end |
end |
||
end |
|||
if token then text = mw.ustring.sub(text, mw.ustring.len(token)+1) end |
|||
until not text or text == "" or not token or token == "" |
|||
text = mw.ustring.gsub(t, "\n+$", "") -- remove trailing line feeds, so "{{Transclude text excerpt|Foo}} more" flows on one line |
|||
if options.more then text = text .. " '''[[" .. pagename .. "|" .. options.more .. "]]'''" end |
|||
return text |
|||
end |
|||
-- Convert a comma-separated list of numbers or min-max ranges into a list of booleans, e.g. "1,3-5" → {1=true,2=false,3=true,4=true,5=true} |
|||
local function numberflags(str) |
|||
local ranges = mw.text.split(str, ",") -- parse ranges, e.g. "1,3-5" → {"1","3-5"} |
|||
local flags = {} |
|||
for _, r in pairs(ranges) do |
|||
local min, max = mw.ustring.match(r, "^%s*(%d+)%s*%-%s*(%d+)%s*$") -- "3-5" → min=3 max=5 |
|||
if not max then min, max = mw.ustring.match(r, "^%s*((%d+))%s*$") end -- "1" → min=1 max=1 |
|||
if max then |
|||
for p = min, max do flags[p] = true end |
|||
end |
end |
||
end |
end |
||
return flags |
|||
end |
|||
-- Remove nested categories |
|||
-- Shared template invocation code for lead and random functions |
|||
excerpt = frame:preprocess(excerpt) |
|||
local function leadrandom(frame, israndom) |
|||
local categories, excerpt = Transcluder.getCategories(excerpt, options.categories) |
|||
-- args = { 1,2,... = page names, paragraphs = list e.g. "1,3-5", files = list, more = text} |
|||
local args = frame.args -- from calling module |
|||
local pargs = frame:getParent().args -- from template |
|||
-- Add tracking categories |
|||
local pagenames = { args[1] or pargs[1] } -- For lead, ignore all but the first unnamed argument |
|||
if |
if config.categories then |
||
local contentCategory = config.categories.content |
|||
-- For random, accept any number of page names. If more than one, we'll pick one randomly |
|||
if contentCategory and mw.title.getCurrentTitle().isContentPage then |
|||
for i, p in pairs(args) do |
|||
excerpt = excerpt .. '[[Category:' .. contentCategory .. ']]' |
|||
if p and type(i) == 'number' and i > 1 then table.insert(pagenames, p) end |
|||
end |
end |
||
local namespaceCategory = config.categories[ mw.title.getCurrentTitle().namespace ] |
|||
for i, p in pairs(pargs) do |
|||
if namespaceCategory then |
|||
if p and type(i) == 'number' and i > 1 and not args[i] then table.insert(pagenames, p) end |
|||
excerpt = excerpt .. '[[Category:' .. namespaceCategory .. ']]' |
|||
end |
end |
||
end |
end |
||
-- Load the styles |
|||
local options = {} |
|||
local styles |
|||
options.paraflags = numberflags(args["paragraphs"] or pargs["paragraphs"] or "") -- parse paragraphs, e.g. "1,3-5" → {"1","3-5"} |
|||
if config.styles then |
|||
options.fileflags = numberflags(args["files"] or pargs["files"] or "") -- parse file numbers |
|||
styles = frame:extensionTag( 'templatestyles', '', { src = config.styles } ) |
|||
options.fileargs = args["fileargs"] or pargs["fileargs"] |
|||
end |
|||
options.more = args["more"] or pargs["more"] |
|||
if options.more and options.more == "" then options.more = "weiterlesen..." end -- more= is short for this default text |
|||
options.errors = args["errors"] or pargs["errors"] |
|||
-- Combine and return the elements |
|||
local text = p._lead(pagenames, options) |
|||
local tag1 = 'div' |
|||
return frame:preprocess(text) |
|||
local tag2 = 'div' |
|||
if inline then |
|||
tag1 = 'span' |
|||
tag2 = 'span' |
|||
elseif quote then |
|||
tag2 = 'blockquote' |
|||
end |
|||
excerpt = mw.html.create(tag1):addClass('excerpt'):wikitext(excerpt) |
|||
local block = mw.html.create(tag2):addClass('excerpt-block'):addClass(class) |
|||
return block:node(styles):node(hat):node(excerpt):node(more) |
|||
end |
end |
||
-- Entry points for |
-- Entry points for backwards compatibility |
||
function p.lead(frame) return |
function p.lead(frame) return p.main(frame) end |
||
function p. |
function p.excerpt(frame) return p.main(frame) end |
||
return p |
return p |
Version vom 1. September 2020, 17:06 Uhr
Vorlage:Shared Template Warning
local Transcluder = require('Module:Transcluder')
local yesno = require('Module:Yesno')
local ok, config = pcall(require, 'Module:Excerpt/config')
if not ok then config = {} end
local p = {}
-- Helper function to get arguments
local args
function getArg(key, default)
value = args[key]
if value and mw.text.trim(value) ~= '' then
return value
end
return default
end
-- Helper function to handle errors
function getError(message, value)
if type(message) == 'string' then
message = Transcluder.getError(message, value)
end
if config.categories and config.categories.errors and mw.title.getCurrentTitle().isContentPage then
message:node('[[Category:' .. config.categories.errors .. ']]')
end
return message
end
-- Helper function to get localized messages
function getMessage(key)
local ok, TNT = pcall(require, 'Module:TNT')
if not ok then return key end
return TNT.format('I18n/Module:Excerpt.tab', key)
end
function p.main(frame)
args = Transcluder.parseArgs(frame)
-- Make sure the requested page exists
local page = getArg(1)
if not page then return getError('no-page') end
local title = mw.title.new(page)
if not title then return getError('no-page') end
if title.isRedirect then title = title.redirectTarget end
if not title.exists then return getError('page-not-found', page) end
page = title.prefixedText
-- Set variables
local fragment = getArg('fragment')
local section = fragment or getArg(2, getArg('section', mw.ustring.match(getArg(1), '[^#]+#([^#]+)') ) )
local hat = yesno( getArg('hat', true) )
local this = getArg('this')
local only = getArg('only')
local files = getArg('files')
local lists = getArg('lists')
local tables = getArg('tables')
local sections = not yesno( getArg('sections') )
local templates = table.concat((config.templates or {}), ',')
local paragraphs = getArg('paragraphs')
local references = getArg('references')
local noBold = not yesno( getArg('bold') )
local inline = yesno( getArg('inline') )
local quote = yesno( getArg('quote') )
local more = yesno( getArg('more') )
local class = getArg('class')
-- Build the hatnote
if hat and not inline then
if this then
hat = this
elseif quote then
hat = getMessage('this')
elseif only then
hat = getMessage(only)
else
hat = getMessage('section')
end
hat = hat .. ' ' .. getMessage('excerpt') .. ' '
if section and not fragment then
hat = hat .. '[[' .. page .. '#' .. mw.uri.anchorEncode(section) .. '|' .. page
.. ' § ' .. mw.ustring.gsub(section, '%[%[([^]|]+)|?[^]]*%]%]', '%1') .. ']]' -- remove nested links
else
hat = hat .. '[[' .. page .. ']]'
end
hat = hat .. "''" .. '<span class="mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span>['
hat = hat .. title:fullUrl('action=edit') .. ' ' .. mw.message.new('editsection'):plain()
hat = hat .. ']<span class="mw-editsection-bracket">]</span></span>' .. "''"
local ok, Hatnote = pcall(require, 'Module:Hatnote')
if ok then
hat = Hatnote._hatnote( hat, { extraclasses = 'dablink excerpt-hat', selfref = true } )
else
hat = mw.html.create('div'):addClass('dablink excerpt-hat'):wikitext(hat)
end
else
hat = nil
end
-- Build the "Read more" link
if more and not inline then
more = "'''[[" .. page .. '#' .. (section or '') .. "|" .. getMessage('more') .. "]]'''"
more = mw.html.create('div'):addClass('noprint excerpt-more'):wikitext(more)
else
more = nil
end
-- Build the options for Module:Transcluder out of the template arguments and the desired defaults
local options = {
files = files,
lists = lists,
tables = tables,
paragraphs = paragraphs,
templates = templates ~= '' and '-' .. templates,
sections = sections,
categories = 0,
references = references,
only = only and mw.text.trim(only, 's') .. 's',
noBold = noBold,
noSelfLinks = true,
noNonFreeFiles = true,
noBehaviorSwitches = true,
fixReferences = true,
linkBold = true,
}
-- Get the excerpt itself
local title = page .. '#' .. (section or '')
local ok, excerpt = pcall(Transcluder.get, title, options)
if not ok then return getError(excerpt) end
if mw.text.trim(excerpt) == '' then
if section then return getError('section-empty', section) else return getError('lead-empty') end
end
-- Add a line break in case the excerpt starts with a table or list
excerpt = '\n' .. excerpt
-- If no file was found, try to excerpt one from the removed infoboxes
local fileNamespaces = Transcluder.getNamespaces('File')
if (files ~= '0' or not files) and not Transcluder.matchAny(excerpt, '%[%[', fileNamespaces, ':') and config.captions then
local templates = Transcluder.get(title, { only = 'templates', templates = templates, fixReferences = true } )
local parameters = Transcluder.getParameters(templates)
local file, captions, caption
for _, pair in pairs(config.captions) do
file = pair[1]
file = parameters[file]
if file and Transcluder.matchAny(file, '^.*%.', {'[Jj][Pp][Ee]?[Gg]','[Pp][Nn][Gg]','[Gg][Ii][Ff]','[Ss][Vv][Gg]'}, '.*') then
file = mw.ustring.match(file, '%[?%[?.-:([^{|]+)%]?%]?') or file -- [[File:Example.jpg{{!}}upright=1.5]] to Example.jpg
captions = pair[2]
for _, p in pairs(captions) do
if parameters[p] then caption = parameters[p] break end
end
excerpt = '[[File:' .. file .. '|thumb|' .. (caption or '') .. ']]' .. excerpt
break
end
end
end
-- Remove nested categories
excerpt = frame:preprocess(excerpt)
local categories, excerpt = Transcluder.getCategories(excerpt, options.categories)
-- Add tracking categories
if config.categories then
local contentCategory = config.categories.content
if contentCategory and mw.title.getCurrentTitle().isContentPage then
excerpt = excerpt .. '[[Category:' .. contentCategory .. ']]'
end
local namespaceCategory = config.categories[ mw.title.getCurrentTitle().namespace ]
if namespaceCategory then
excerpt = excerpt .. '[[Category:' .. namespaceCategory .. ']]'
end
end
-- Load the styles
local styles
if config.styles then
styles = frame:extensionTag( 'templatestyles', '', { src = config.styles } )
end
-- Combine and return the elements
local tag1 = 'div'
local tag2 = 'div'
if inline then
tag1 = 'span'
tag2 = 'span'
elseif quote then
tag2 = 'blockquote'
end
excerpt = mw.html.create(tag1):addClass('excerpt'):wikitext(excerpt)
local block = mw.html.create(tag2):addClass('excerpt-block'):addClass(class)
return block:node(styles):node(hat):node(excerpt):node(more)
end
-- Entry points for backwards compatibility
function p.lead(frame) return p.main(frame) end
function p.excerpt(frame) return p.main(frame) end
return p