-- Module:Excerpt implements the Excerpt template
local p = {}
-- Documentation and master version: https://en.wikipedia.org/wiki/Module:Excerpt
local mRedirect = require('Module:Redirect')
-- Authors: User:Sophivorus, User:Certes, User:Aidan9382 & others
-- License: CC-BY-SA-3.0
local Transcluder = require( 'Module:Transcluder' )
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 yesno = require( 'Module:Yesno' )
-- In text, match pre..list[1]..post or pre..list[2]..post or ...
local function matchany(text, pre, list, post)
local match
for i = 1, #list do
match = mw.ustring.match(text, pre .. list[i] .. post)
if match then return match end
end
return nil
end
local ok, config = pcall( require, 'Module:Excerpt/config' )
-- Check image for suitability
if not ok then config = {} end
local function checkimage(image)
local page = matchany(image, "", {"[Ff]ile", "[Ii]mage"}, "%s*:[^|%]]*") -- match File:(name) or Image:(name)
if not page then return false end
local p = {}
-- Limit to image types: .gif, .jpg, .jpeg, .png, .svg, .tiff, .xcf (exclude .ogg audio etc.)
if not matchany(page, "%.", {"[Gg][Ii][Ff]", "[Jj][Pp][Ee]?[Gg]", "[Pp][Nn][Gg]", "[Ss][Vv][Gg]", "[Tt][Ii][Ff][Ff]", "[Xx][Cc][Ff]"}, "%s*$") then
return false
end
local title = mw.title.new(":" .. page) -- Read description page (for :File:Foo rather than File:Foo)
if not title then return false end
local redir = mRedirect.getTarget(title)
if redir then title = mw.title.new(redir) end
local frame = mw.getCurrentFrame()
local desc = frame:preprocess("{{" .. title.prefixedText .. "}}")
return desc and desc ~= "" and not mw.ustring.match(desc, "[Nn]on%-free") -- hide non-free image
end
-- Helper function to get arguments
-- Attempt to parse [[File:...]] or [[Image:...]], either anywhere (start=false) or at the start only (start=true)
local args
local function parseimage(text, start)
local startrefunction =getArg( ""key, default )
local value = args[ key ]
if start then startre = "^" end -- a true flag restricts search to start of string
if value and mw.text.trim( value ) ~= '' then
local image = matchany(text, startre .. "%[%[%s*", {"[Ff]ile", "[Ii]mage"}, "%s*:.*") -- [[File: or [[Image: ...
return value
if image then
image = mw.ustring.match(image, "%b[]%s*") -- matching [[...]] to handle wikilinks nested in caption
end
return imagedefault
end
-- Helper function to handle errors
-- Parse a caption, which ends at a | (end of parameter) or } (end of infobox) but may contain nested [..] and {..}
local function parsecaptiongetError(caption message, value )
if nottype( captionmessage then) return== nil'string' endthen
message = Transcluder.getError( message, value )
local len = mw.ustring.len(caption)
local pos = 1
while pos <= len do
local linkstart, linkend = mw.ustring.find(caption, "%b[]", pos)
linkstart = linkstart or len + 1 -- avoid comparison with nil when no link
local templatestart, templateend = mw.ustring.find(caption, "%b{}", pos)
templatestart = templatestart or len + 1 -- avoid comparison with nil when no template
local argend = mw.ustring.find(caption, "[|}]", pos) or len + 1
if linkstart < templatestart and linkstart < argend then
pos = linkend + 1 -- skip wikilink
elseif templatestart < argend then
pos = templateend + 1 -- skip template
else -- argument ends before the next wikilink or template
return mw.ustring.sub(caption, 1, argend - 1)
end
end
if config.categories and config.categories.errors and mw.title.getCurrentTitle().isContentPage then
end
message:node( '[[Category:' .. config.categories.errors .. ']]' )
-- Attempt to construct a [[File:...]] block from {{infobox ... |image= ...}}
local function argimage(text)
local token = nil
if mw.ustring.match(text, "{{%s*[Ii]nfobox") then
local image = matchany(text, "|%s*", {"image", "PD_image", "image_flag", "Ship image", "Cover"}, "%s*=%s*(.*)")
if image then -- add in relevant optional parameters: caption, alt text and image size
token = parseimage(image, true) -- look for image=[[File:...]] etc.
if not token then
image = mw.ustring.match(image, "^[^}|]*") -- remove later arguments
token = "[[" -- Add File: unless name already begins File: or Image:
if not matchany(image, "^", {"[Ff]ile", "[Ii]mage"}, "%s*:") then
token = token .. "File:"
end
token = token .. image
local caption = parsecaption(matchany(text, "|%s*", {"[Cc]aption", "Ship caption"}, "%s*=%s*(.*)"))
if caption and mw.ustring.match(caption, "%S") 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 and mw.ustring.match(image_size, "%S") then token = token .. "|" .. image_size end
token = token .. "]]"
end
token = mw.ustring.gsub(token, "\n","") .. "\n"
end
end
return message
return token
end
-- HelpHelper gsubfunction to removeget unwantedlocalized templatesmessages
local function getMessage( key )
-- If template is unwanted then return "" (gsub will replace by nothing), else return nil (gsub will keep existing string)
local ok, TNT = pcall( require, 'Module:TNT' )
local function striptemplate(t)
if not ok then return key end
local unwanted = {"[Ee]fn", "[Ee]fn%-[lu]a", "[Ee]l[mn]", "[Rr]p?", "[Ss]fn[bmp]", "[Ss]f[bn]", "NoteTag", "#[Tt]ag:%s*[Rr]ef", "[Rr]efn?",
return TNT.format( 'I18n/Module:Excerpt.tab', key )
"[CcDd]n", "[Cc]itation needed", "[Dd]isambiguation needed", "[Ff]eatured article", "[Gg]ood article"}
for _, u in pairs(unwanted) do
if mw.ustring.match(t, "^{{%s*" .. u .. "%s*%f[|}]") then return "" end -- unwanted template: remove
end
return nil -- not an unwanted template: keep
end
-- Main entry point for templates
-- Main function returns a string value: text of the lead of a page
local function p.main(pagenames, optionsframe )
args = Transcluder.parseArgs( frame )
errors = options.errors -- set the module level boolean used in local function err
-- Make sure the requested page exists
if not pagenames or #pagenames < 1 then return err("No page names given") end
local pagenamepage = getArg( 1 )
if not page or page == '{{{1}}}' then return getError( 'no-page' ) end
local text
local pagecounttitle = #pagenamesmw.title.new(page)
if not title then return getError( 'invalid-title', 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 from the template parameters
-- read the page, or a random one if multiple pages were provided
local section = getArg( 2, mw.ustring.match( getArg( 1 ), '[^#]+#(.+)' ) )
if pagecount > 1 then math.randomseed(os.time()) end
local hat = yesno( getArg( 'hat', true ) )
while not text and pagecount > 0 do
local edit = yesno( getArg( 'edit', 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', getArg( 'file', ( only == 'file' and 1 ) ) )
if pagename and pagename ~= "" then
local lists = getArg( 'lists', getArg( 'list', ( only == 'list' and 1 ) ) )
pagename = mw.ustring.match(pagename, "%[%[%s*(.-)[]|#]") or pagename -- "[[Foo|Bar]]" → "Foo"
local tables = getArg( 'tables', getArg( 'table', ( only == 'table' and 1 ) ) )
pagename = mw.ustring.gsub(pagename, "^%s+", "") -- strip leading ...
local templates = getArg( 'templates', getArg( 'template', ( only == 'template' and 1 ) ) )
pagename = mw.ustring.gsub(pagename, "%s+$", "") -- ...and trailing white space
local paragraphs = getArg( 'paragraphs', getArg( 'paragraph', ( only == 'paragraph' and 1 ) ) )
local references = getArg( 'references' )
local subsections = not yesno( getArg( 'subsections' ) )
local noLinks = not yesno( getArg( 'links', true ) )
local noBold = not yesno( getArg( 'bold' ) )
local onlyFreeFiles = yesno( getArg( 'onlyfreefiles', true ) )
local briefDates = yesno( getArg( 'briefdates', false ) )
local inline = yesno( getArg( 'inline' ) )
local quote = yesno( getArg( 'quote' ) )
local more = yesno( getArg( 'more' ) )
local class = getArg( 'class' )
local displaytitle = getArg( 'displaytitle' ) or page
-- 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' )
pagename = redir or pagename
elseif only then
texthat = title:getContentgetMessage( only )
endelse
hat = getMessage( 'section' )
end
hat = hat .. ' ' .. getMessage( 'excerpt' ) .. ' '
if not text then table.remove(pagenames, pagenum) end -- this one didn't work; try another
if section then
pagecount = pagecount - 1 -- ensure that we exit the loop after at most #pagenames iterations
hat = hat .. '[[:' .. page .. '#' .. mw.uri.anchorEncode( section ) .. '|' .. displaytitle
.. ' § ' .. mw.ustring.gsub( section, '%[%[([^]|]+)|?[^]]*%]%]', '%1' ) .. ']].' -- remove nested links
else
hat = hat .. '[[:' .. page .. '|' .. displaytitle .. ']].'
end
if edit then
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>'
end
if config.hat then
hat = config.hat .. hat .. '}}'
hat = frame:preprocess( hat )
else
hat = mw.html.create( 'div' ):addClass( 'dablink excerpt-hat' ):wikitext( hat )
end
else
hat = nil
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
end
text = mw.ustring.gsub(text, "%b{}", striptemplate) -- remove unwanted templates such as references
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 parameters and the desired defaults
local allparas = true -- keep all paragraphs?
iflocal options.paraflags then= {
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,
sections = subsections,
categories = 0,
references = references,
only = only and mw.text.trim( only, 's' ) .. 's',
noLinks = noLinks,
noBold = noBold,
noSelfLinks = true,
noNonFreeFiles = onlyFreeFiles,
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 ) == '' and not only then
if section then return getError( 'section-empty', section ) else return getError( 'lead-empty' ) end
end
-- Fix birth and death dates, but only in the first paragraph
local maxfile = 0 -- for efficiency, stop checking images after this many have been found
if options.fileflagsbriefDates then
local startpos = 1 -- skip initial templates
for k, v in pairs(options.fileflags) do
local s
if v and k > maxfile then maxfile = k end -- set maxfile = highest key in fileflags
local e = 0
repeat
startpos = e + 1
s, e = mw.ustring.find( excerpt, "%s*%b{}%s*", startpos )
until not s or s > startpos
s, e = mw.ustring.find( excerpt, "%b()", startpos ) -- get (...), which may be (year–year)
if s and s < startpos + 100 then -- look only near the start
local year1, conjunction, year2 = mw.ustring.match( mw.ustring.sub( excerpt, s, e ), '(%d%d%d+)(.-)(%d%d%d+)' )
if year1 and year2 and (mw.ustring.match( conjunction, '[%-–—]' ) or mw.ustring.match( conjunction, '{{%s*[sS]nd%s*}}' )) then
local y1 = tonumber(year1)
local y2 = tonumber(year2)
if y2 > y1 and y2 < y1 + 125 and y1 <= tonumber( os.date( "%Y" )) then
excerpt = mw.ustring.sub( excerpt, 1, s ) .. year1 .. "–" .. year2 .. mw.ustring.sub( excerpt, e )
end
end
end
end
-- aIf basicno parserfile was found, try to trimget one downfrom the leadinfobox
local fileNamespaces = Transcluder.getNamespaces( 'File' )
local leadstart = nil -- have we found some text yet?
if ( ( only == 'file' or only == 'files' ) or ( not only and ( files ~= '0' or not files ) ) ) and -- caller asked for files
local t = "" -- the stripped down output text
not Transcluder.matchAny( excerpt, '%[%[', fileNamespaces, ':' ) and -- and there are no files in Transcluder's output
local files = 0 -- how many images so far
config.captions -- and we have the config option required to try finding files in templates
local paras = 0 -- how many paragraphs so far
then
-- We cannot distinguish the infobox from the other templates so we search them all
text = mw.ustring.gsub(text,"^%s*","") -- remove initial white space
local infobox = Transcluder.getTemplates( excerpt );
repeat -- loop around parsing a template, image or paragraph
infobox = table.concat( infobox )
local token = mw.ustring.match(text, "^%b{}%s*") or false -- {{Template}}
local parameters = Transcluder.getParameters( infobox )
if token then -- found a template
local file, captions, caption, cssclasses, cssclass
if leadstart then -- lead has already started, so keep the template within the text
for _, pair in pairs( config.captions ) do
t = t .. token
file = pair[1]
elseif files < maxfile then -- discard template, but if we are still collecting images...
file = parameters[file]
local image = argimage(token) or parseimage(token, false) -- look for embedded [[File:...]], |image=, etc.
if file and Transcluder.matchAny( file, '^.*%.', { '[Jj][Pp][Ee]?[Gg]', '[Pp][Nn][Gg]', '[Gg][Ii][Ff]', '[Ss][Vv][Gg]' }, '.*' ) then
if image and checkimage(image) then -- if image is found and qualifies (not a sound file, non-free, etc.)
file = mw.ustring.match( file, '%[?%[?.-:([^{|]+)%]?%]?' ) or file -- [[File:Example.jpg{{!}}upright=1.5]] to Example.jpg
captions = pair[2]
files = files + 1 -- count the file, whether displaying it or not
for _, p in pairs( captions ) do
if options.fileflags and options.fileflags[files] then -- if displaying this image
if parameters[ p ] then caption = parameters[ p ] break end
image = mw.ustring.gsub(image, "|%s*frameless%s*%f[|%]]", "") -- make image a thumbnail, not frameless etc.
end
image = mw.ustring.gsub(image, "|%s*framed?%s*%f[|%]]", "")
if not matchany(image, "|%s*", {"thumb", "thumbnail"}, "%s*%f[|%]]") then
-- Check for CSS classes
image = mw.ustring.gsub(image, "(%]%]%s*)$", "|thumb%1")
-- We opt to use skin-invert-image instead of skin-invert
-- in all other cases, the CSS provided in the infobox is used
if pair[3] then
cssclasses = pair[3]
for _, p in pairs(cssclasses) do
if parameters[p] then
cssclass = ((parameters[p] == 'skin-invert') and 'skin-invert-image' or parameters[p])
break
end
if options.fileargs then image = mw.ustring.gsub(image, "(%]%]%s*)$", "|" .. options.fileargs .. "%1") end
t = t .. image
end
end
end
excerpt = '[[File:' .. file ..
else -- the next token in text is not a template
(cssclass and ('|class=' .. cssclass) or '') ..
token = parseimage(text, true)
'|thumb|' .. (caption or '') .. ']]' .. excerpt
if token then -- the next token in text looks like an image
if ( onlyFreeFiles ) then
if files < maxfile and checkimage(token) then -- if more images are wanted and this is a wanted image
excerpt = Transcluder.removeNonFreeFiles( excerpt )
files = files + 1
if options.fileflags and options.fileflags[files] then
local image = token -- copy token for manipulation by adding |right etc. without changing the original
if options.fileargs then image = mw.ustring.gsub(image, "(%]%]%s*)$", "|" .. options.fileargs .. "%1") end
t = t .. image
end
end
break
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 -- position of next paragraph delimiter (or end of text)
local endpos = math.min( -- find position of whichever comes first: [[File:, [[Image: or paragraph delimiter
mw.ustring.find(text, "%[%[%s*[Ff]ile%s*:") or afterend,
mw.ustring.find(text, "%[%[%s*[Ii]mage%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
leadstart = leadstart or mw.ustring.len(t) + 1 -- we got a paragraph, so mark the start of the lead section
paras = paras + 1
if allparas or (options.paraflags and options.paraflags[paras]) then t = t .. token end -- add if this paragraph wanted
end -- of "else got a paragraph"
end -- of "else not a template"
if token then text = mw.ustring.sub(text, mw.ustring.len(token)+1) end -- remove parsed token from remaining text
until not text or text == "" or not token or token == "" -- loop until all text parsed
text = mw.ustring.gsub(t, "\n+$", "") -- remove trailing line feeds, so "{{Transclude text excerpt|Foo}} more" flows on one line
-- replace the bold title or synonym near the start of the article by a wikilink to the article
local lang = mw.language.getContentLanguage()
local pos = mw.ustring.find(text, "'''" .. lang:ucfirst(pagename) .. "'''", 1, true) -- look for "'''Foo''' is..." (uc) or "A '''foo''' is..." (lc)
or mw.ustring.find(text, "'''" .. lang:lcfirst(pagename) .. "'''", 1, true) -- plain search: special characters in pagename represent themselves
if pos then
local len = mw.ustring.len(pagename)
text = mw.ustring.sub(text, 1, pos + 2) .. "[[" .. mw.ustring.sub(text, pos + 3, pos + len + 2) .. "]]" .. mw.ustring.sub(text, pos + len + 3, -1) -- link it
else -- look for anything unlinked in bold, assumed to be a synonym of the title (e.g. a person's birth name)
text = mw.ustring.gsub(text, "(.-''')(.-'*)'''", function(a, b)
if mw.ustring.len(a) < 100 + (leadstart or 0) and not mw.ustring.find(b, "%[") then ---if early in article and not wikilinked
return a .. "[[" .. pagename .. "|" .. b .. "]]'''" -- replace '''Foo''' by '''[[pagename|Foo]]
else
return nil -- instruct gsub to make no change
end
end
end, 1) -- "end" here terminates the anonymous replacement function(a, b) passed to gsub
end
-- Unlike other elements, templates are filtered here
if options.more then text = text .. " '''[[" .. pagename .. "|" .. options.more .. "]]'''" end -- wikilink to article for more info
-- because we had to search the infoboxes for files
local trash
return text
if only and ( only == 'template' or only == 'templates' ) then
end
trash, excerpt = Transcluder.getTemplates( excerpt, templates );
else -- Remove blacklisted templates
-- 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 blacklist = config.blacklist and table.concat( config.blacklist, ',' ) or ''
local function numberflags(str)
if templates then
local ranges = mw.text.split(str, ",") -- parse ranges, e.g. "1,3-5" → {"1","3-5"}
if string.sub( templates, 1, 1 ) == '-' then --Unwanted templates. Append to blacklist
local flags = {}
blacklist = templates .. ',' .. blacklist
for _, r in pairs(ranges) do
else --Wanted templates. Replaces blacklist and acts as whitelist
local min, max = mw.ustring.match(r, "^%s*(%d+)%s*%-%s*(%d+)%s*$") -- "3-5" → min=3 max=5
blacklist = templates
if not max then min, max = mw.ustring.match(r, "^%s*((%d+))%s*$") end -- "1" → min=1 max=1
end
if max then
else
for p = min, max do flags[p] = true end
blacklist = '-' .. blacklist
end
trash, excerpt = Transcluder.getTemplates( excerpt, blacklist );
end
return flags
end
-- Remove extra line breaks but leave one before and after so the parser interprets lists, tables, etc. correctly
-- Shared template invocation code for lead and random functions
excerpt = mw.text.trim( excerpt )
local function invoke(frame, articlekey)
excerpt = string.gsub( excerpt, '\n\n\n+', '\n\n' )
-- args = { 1,2,... = page names, paragraphs = list e.g. "1,3-5", files = list, more = text}
excerpt = '\n' .. excerpt .. '\n'
local args = {} -- args[k] = frame.args[k] or frame:getParent().args[k] for all k in either (numeric or not)
for k, v in pairs(frame:getParent().args) do args[k] = v end
-- Remove nested categories
for k, v in pairs(frame.args) do args[k] = v end -- args from a Lua call have priority over parent args from template
excerpt = frame:preprocess( excerpt )
local categories, excerpt = Transcluder.getCategories( excerpt, options.categories )
-- Add tracking categories
local pagenames = {}
if config.categories then
local articlecount = #args
local contentCategory = config.categories.content
if articlekey then -- 1 for lead template; "selected" for selected template
if contentCategory and mw.title.getCurrentTitle().isContentPage then
articlekey = tonumber(articlekey) or args[articlekey]
excerpt = excerpt .. '[[Category:' .. contentCategory .. ']]'
if tonumber(articlekey) then
-- normalise article number into the range 1..#args
if articlecount < 1 then err("No articles provided") end
articlekey = articlekey % articlecount
if articlekey == 0 then articlekey = articlecount end
end
local namespaceCategory = config.categories[ mw.title.getCurrentTitle().namespace ]
pagenames = { args[articlekey] }
if namespaceCategory then
else
excerpt = excerpt .. '[[Category:' .. namespaceCategory .. ']]'
-- For random, accept any number of page names. If more than one, we'll pick one randomly
if articlecount < 1 then err("No articles provided") end
for i, p in pairs(args) do
if p and type(i) == 'number' then table.insert(pagenames, p) end
end
end
-- Load the styles
local options = args -- pick up miscellaneous options: more, errors, fileargs
local styles
options.paraflags = numberflags(args["paragraphs"] or "") -- parse paragraphs, e.g. "1,3-5" → {"1","3-5"}
if config.styles then
options.fileflags = numberflags(args["files"] or "") -- parse file numbers
styles = frame:extensionTag( 'templatestyles', '', { src = config.styles } )
if options.more and options.more == "" then options.more = "Read more..." end -- more= is short for this default text
end
-- Combine and return the elements
local text = main(pagenames, options)
if inline then
return frame:preprocess(text)
return mw.text.trim( excerpt )
end
local tag = 'div'
if quote then
tag = 'blockquote'
end
excerpt = mw.html.create( 'div' ):addClass( 'excerpt' ):wikitext( excerpt )
local block = mw.html.create( tag ):addClass( 'excerpt-block' ):addClass( class )
return block:node( styles ):node( hat ):node( excerpt ):node( more )
end
-- Entry points for templatebackwards callers using #invoke:compatibility
function p.lead( frame ) return invokep.main( frame, 1) end -- {{Transclude lead article}} reads the first and only article
function p.randomexcerpt( frame ) return invokep.main( frame ) end -- {{Transclude random article}} reads any article (default for invoke with one argument)
function p.selected(frame) return invoke(frame, "selected") end -- {{Transclude selected article}} reads the article whose key is in the selected= parameter
return p
|