Permanently protected module
From Wikipedia, the free encyclopedia


-- Module:Excerpt implements the Excerpt template

-- Documentation and master version: /info/en/?search=Module:Excerpt

-- Authors: User:Sophivorus, User:Certes, User:Aidan9382 & others

-- License: CC-BY-SA-3.0



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

local function getArg( key, default )

	local value = args key 

	if value and mw.text.trim( value ) ~= '' then

		return value

	end

	return default

end



-- Helper function to handle errors

local 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

local 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



-- Main entry point for templates

function p.main( frame )

	args = Transcluder.parseArgs( frame )



	-- Make sure the requested page exists

	local page = getArg( 1 )

	if not page or page == '{{{1}}}' then return getError( 'no-page' ) end

	local title = mw.title.new(page)

	if not title then return getError( 'invalid-title', 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 from the template parameters

	local section = getArg( 2, mw.ustring.match( getArg( 1 ), '[^#]+#(.+)' ) )

	local hat = yesno( getArg( 'hat', true ) )

	local  = yesno( getArg( 'edit', true ) )

	local this = getArg( 'this' )

	local only = getArg( 'only' )

	local files = getArg( 'files', getArg( 'file', ( only == 'file' and 1 ) ) )

	local lists = getArg( 'lists', getArg( 'list', ( only == 'list' and 1 ) ) )

	local tables = getArg( 'tables', getArg( 'table', ( only == 'table' and 1 ) ) )

	local templates = getArg( 'templates', getArg( 'template', ( only == 'template' and 1 ) ) )

	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 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 then

			hat = hat .. '[[:' .. page .. '#' .. mw.uri.anchorEncode( section ) .. '|' .. displaytitle

				.. ' § ' .. mw.ustring.gsub( section, '%[%[([^]|]+)|?[^]]*%]%]', '%1' ) .. ']].' -- remove nested links

		else

			hat = hat .. '[[:' .. page .. '|' .. displaytitle .. ']].'

		end

		if  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



	-- 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 parameters and the desired defaults

	local options = {

		files = files,

		lists = lists,

		tables = tables,

		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

	if briefDates then

		local startpos = 1 -- skip initial templates

		local s

		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



	-- If no file was found, try to get one from the infobox

	local fileNamespaces = Transcluder.getNamespaces( 'File' )

	if ( ( only == 'file' or only == 'files' ) or ( not only and ( files ~= '0' or not files ) ) ) and -- caller asked for files

		not Transcluder.matchAny( excerpt, '%[%[', fileNamespaces, ':' ) and -- and there are no files in Transcluder's output

		config.captions -- and we have the config option required to try finding files in templates

	then

		-- We cannot distinguish the infobox from the other templates so we search them all

		local infobox = Transcluder.getTemplates( excerpt );

		infobox = table.concat( infobox )

		local parameters = Transcluder.getParameters( infobox )

		local file, captions, caption

		for _, pair in pairs( config.captions ) do

			file = pair1

			file = parametersfile

			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 = pair2

				for _, p in pairs( captions ) do

					if parameters p  then caption = parameters p  break end

				end

				excerpt = '[[File:' .. file .. '|thumb|' .. ( caption or '' ) .. ']]' .. excerpt

				if ( onlyFreeFiles ) then

					excerpt = Transcluder.removeNonFreeFiles( excerpt )

				end

				break

			end

		end

	end



	-- Unlike other elements, templates are filtered here

	-- because we had to search the infoboxes for files

	local trash

	if only and ( only == 'template' or only == 'templates' ) then

		trash, excerpt = Transcluder.getTemplates( excerpt, templates );

	else -- Remove blacklisted templates

		local blacklist = config.blacklist and table.concat( config.blacklist, ',' ) or ''

		if templates then

			if string.sub( templates, 1, 1 ) == '-' then --Unwanted templates. Append to blacklist

				blacklist = templates .. ',' .. blacklist

			else --Wanted templates. Replaces blacklist and acts as whitelist

				blacklist = templates

			end

		else

			blacklist = '-' .. blacklist

		end

		trash, excerpt = Transcluder.getTemplates( excerpt, blacklist );

	end



	-- Remove extra line breaks but leave one before and after so the parser interprets lists, tables, etc. correctly

	excerpt = mw.text.trim( excerpt )

	excerpt = string.gsub( excerpt, '\n\n\n+', '\n\n' )

	excerpt = '\n' .. excerpt .. '\n'



	-- 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

	if inline then

		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 backwards compatibility

function p.lead( frame ) return p.main( frame ) end

function p.excerpt( frame ) return p.main( frame ) end



return p
Permanently protected module
From Wikipedia, the free encyclopedia


-- Module:Excerpt implements the Excerpt template

-- Documentation and master version: /info/en/?search=Module:Excerpt

-- Authors: User:Sophivorus, User:Certes, User:Aidan9382 & others

-- License: CC-BY-SA-3.0



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

local function getArg( key, default )

	local value = args key 

	if value and mw.text.trim( value ) ~= '' then

		return value

	end

	return default

end



-- Helper function to handle errors

local 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

local 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



-- Main entry point for templates

function p.main( frame )

	args = Transcluder.parseArgs( frame )



	-- Make sure the requested page exists

	local page = getArg( 1 )

	if not page or page == '{{{1}}}' then return getError( 'no-page' ) end

	local title = mw.title.new(page)

	if not title then return getError( 'invalid-title', 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 from the template parameters

	local section = getArg( 2, mw.ustring.match( getArg( 1 ), '[^#]+#(.+)' ) )

	local hat = yesno( getArg( 'hat', true ) )

	local  = yesno( getArg( 'edit', true ) )

	local this = getArg( 'this' )

	local only = getArg( 'only' )

	local files = getArg( 'files', getArg( 'file', ( only == 'file' and 1 ) ) )

	local lists = getArg( 'lists', getArg( 'list', ( only == 'list' and 1 ) ) )

	local tables = getArg( 'tables', getArg( 'table', ( only == 'table' and 1 ) ) )

	local templates = getArg( 'templates', getArg( 'template', ( only == 'template' and 1 ) ) )

	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 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 then

			hat = hat .. '[[:' .. page .. '#' .. mw.uri.anchorEncode( section ) .. '|' .. displaytitle

				.. ' § ' .. mw.ustring.gsub( section, '%[%[([^]|]+)|?[^]]*%]%]', '%1' ) .. ']].' -- remove nested links

		else

			hat = hat .. '[[:' .. page .. '|' .. displaytitle .. ']].'

		end

		if  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



	-- 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 parameters and the desired defaults

	local options = {

		files = files,

		lists = lists,

		tables = tables,

		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

	if briefDates then

		local startpos = 1 -- skip initial templates

		local s

		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



	-- If no file was found, try to get one from the infobox

	local fileNamespaces = Transcluder.getNamespaces( 'File' )

	if ( ( only == 'file' or only == 'files' ) or ( not only and ( files ~= '0' or not files ) ) ) and -- caller asked for files

		not Transcluder.matchAny( excerpt, '%[%[', fileNamespaces, ':' ) and -- and there are no files in Transcluder's output

		config.captions -- and we have the config option required to try finding files in templates

	then

		-- We cannot distinguish the infobox from the other templates so we search them all

		local infobox = Transcluder.getTemplates( excerpt );

		infobox = table.concat( infobox )

		local parameters = Transcluder.getParameters( infobox )

		local file, captions, caption

		for _, pair in pairs( config.captions ) do

			file = pair1

			file = parametersfile

			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 = pair2

				for _, p in pairs( captions ) do

					if parameters p  then caption = parameters p  break end

				end

				excerpt = '[[File:' .. file .. '|thumb|' .. ( caption or '' ) .. ']]' .. excerpt

				if ( onlyFreeFiles ) then

					excerpt = Transcluder.removeNonFreeFiles( excerpt )

				end

				break

			end

		end

	end



	-- Unlike other elements, templates are filtered here

	-- because we had to search the infoboxes for files

	local trash

	if only and ( only == 'template' or only == 'templates' ) then

		trash, excerpt = Transcluder.getTemplates( excerpt, templates );

	else -- Remove blacklisted templates

		local blacklist = config.blacklist and table.concat( config.blacklist, ',' ) or ''

		if templates then

			if string.sub( templates, 1, 1 ) == '-' then --Unwanted templates. Append to blacklist

				blacklist = templates .. ',' .. blacklist

			else --Wanted templates. Replaces blacklist and acts as whitelist

				blacklist = templates

			end

		else

			blacklist = '-' .. blacklist

		end

		trash, excerpt = Transcluder.getTemplates( excerpt, blacklist );

	end



	-- Remove extra line breaks but leave one before and after so the parser interprets lists, tables, etc. correctly

	excerpt = mw.text.trim( excerpt )

	excerpt = string.gsub( excerpt, '\n\n\n+', '\n\n' )

	excerpt = '\n' .. excerpt .. '\n'



	-- 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

	if inline then

		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 backwards compatibility

function p.lead( frame ) return p.main( frame ) end

function p.excerpt( frame ) return p.main( frame ) end



return p

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook