Jump to content
Wikipedia The Free Encyclopedia

Module:Excerpt/sandbox

From Wikipedia, the free encyclopedia
This is the module sandbox page for Module:Excerpt (diff).
See also the companion subpage for test cases.
Module documentation[view] [edit] [history] [purge]
Beta This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected.
[画像:Protected] This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing.
Warning This Lua module is used on approximately 12,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them.
This module depends on the following other modules:

This module implements Template:Excerpt.

Portals

[edit ]

Portals use a previous version of this module:

The above documentation is transcluded from Module:Excerpt/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (edit) pages.
Add categories to the /doc subpage. Subpages of this module.
 -- Module:Excerpt implements the Excerpt template
 -- Documentation and master version: https://en.wikipedia.org/wiki/Module:Excerpt
 -- Authors: User:Sophivorus, User:Certes, User:Aidan9382 & others
 -- License: CC-BY-SA-3.0

 local parser = require( 'Module:WikitextParser' )
 local yesno = require( 'Module:Yesno' )

 local ok, config = pcall( require, 'Module:Excerpt/config' )
 if not ok then config = {} end

 local Excerpt = {}

 -- Main entry point for templates
 function Excerpt.main( frame )

	-- Make sure the requested page exists and get the wikitext
	local page = Excerpt.getArg( 1 )
	if not page or page == '{{{1}}}' then return Excerpt.getError( 'no-page' ) end
	local title = mw.title.new( page )
	if not title then return Excerpt.getError( 'invalid-title', page ) end
	local fragment = title.fragment -- save for later
	if title.isRedirect then title = title.redirectTarget end
	if not title.exists then return Excerpt.getError( 'page-not-found', page ) end
	page = title.prefixedText
	local wikitext = title:getContent()

	-- Get the template params and process them
	local params = {
		hat = yesno( Excerpt.getArg( 'hat', true ) ),
		this = Excerpt.getArg( 'this' ),
		only = Excerpt.getArg( 'only' ),
		files = Excerpt.getArg( 'files' ),
		lists = Excerpt.getArg( 'lists' ),
		tables = Excerpt.getArg( 'tables' ),
		templates = Excerpt.getArg( 'templates' ),
		paragraphs = Excerpt.getArg( 'paragraphs' ),
		references = yesno( Excerpt.getArg( 'references', true ) ),
		subsections = yesno( Excerpt.getArg( 'subsections', false ) ),
		links = yesno( Excerpt.getArg( 'links', true ) ),
		bold = yesno( Excerpt.getArg( 'bold', false ) ),
		briefDates = yesno( Excerpt.getArg( 'briefdates', false ) ),
		inline = yesno( Excerpt.getArg( 'inline' ) ),
		quote = yesno( Excerpt.getArg( 'quote' ) ),
		more = yesno( Excerpt.getArg( 'more' ) ),
		class = Excerpt.getArg( 'class' ),
		displayTitle = Excerpt.getArg( 'displaytitle', page ),
	}

	-- Make sure the requested section exists and get the excerpt
	local excerpt
	local section = Excerpt.getArg( 2, fragment )
	section = mw.text.trim( section )
	if section == '' then section = nil end
	if section then
		excerpt = parser.getSectionTag( wikitext, section )
		if not excerpt then
			if params.subsections then
				excerpt = parser.getSection( wikitext, section )
			else
				local sections = parser.getSections( wikitext )
				excerpt = sections[ section ]
			end
		end
		if not excerpt then return Excerpt.getError( 'section-not-found', section ) end
		if excerpt == '' then return Excerpt.getError( 'section-empty', section ) end
	else
		excerpt = parser.getLead( wikitext )
		if excerpt == '' then return Excerpt.getError( 'lead-empty' ) end
	end

	-- Filter various elements from the excerpt
	excerpt = Excerpt.filterFiles( excerpt, params.files )
	excerpt = Excerpt.filterLists( excerpt, params.lists )
	excerpt = Excerpt.filterTables( excerpt, params.tables )
	excerpt = Excerpt.filterParagraphs( excerpt, params.paragraphs )

	-- If no file is found, try to get one from the infobox
	if ( params.only == 'file' or params.only == 'files' or not params.only and ( not params.files or params.files ~= '0' ) ) -- caller asked for files
		and not section -- and we're in the lead section
		and config.captions -- and we have the config option required to try finding files in infoboxes
		and #parser.getFiles( excerpt ) == 0 -- and there're no files in the excerpt
	then
		excerpt = Excerpt.addInfoboxFile( excerpt )
	end

	-- Filter the templates by appending the templates blacklist to the templates filter
	if config.blacklist then
		local blacklist = table.concat( config.blacklist, ',' )
		if params.templates then
			if string.sub( params.templates, 1, 1 ) == '-' then
				params.templates = params.templates .. ',' .. blacklist
			end
		else
			params.templates = '-' .. blacklist
		end
	end
	excerpt = Excerpt.filterTemplates( excerpt, params.templates )

	-- Leave only the requested elements
	if params.only == 'file' or params.only == 'files' then
		local files = parser.getFiles( excerpt )
		excerpt = params.only == 'file' and files[1] or table.concat( files, '\n\n' )
	end
	if params.only == 'list' or params.only == 'lists' then
		local lists = parser.getLists( excerpt )
		excerpt = params.only == 'list' and lists[1] or table.concat( lists, '\n\n' )
	end
	if params.only == 'table' or params.only == 'tables' then
		local tables = parser.getTables( excerpt )
		excerpt = params.only == 'table' and tables[1] or table.concat( tables, '\n\n' )
	end
	if params.only == 'paragraph' or params.only == 'paragraphs' then
		local paragraphs = parser.getParagraphs( excerpt )
		excerpt = params.only == 'paragraph' and paragraphs[1] or table.concat( paragraphs, '\n\n' )
	end
	if params.only == 'template' or params.only == 'templates' then
		local templates = parser.getTemplates( excerpt )
		excerpt = params.only == 'template' and templates[1] or table.concat( templates, '\n\n' )
	end

	-- @todo Make more robust and move downwards
	if params.briefDates then
		excerpt = Excerpt.fixDates( excerpt )
	end

	-- Remove unwanted elements
	excerpt = Excerpt.removeComments( excerpt )
	excerpt = Excerpt.removeSelfLinks( excerpt )
	excerpt = Excerpt.removeNonFreeFiles( excerpt )
	excerpt = Excerpt.removeBehaviorSwitches( excerpt )

	-- Fix or remove the references
	if params.references then
		excerpt = Excerpt.fixReferences( excerpt, page, wikitext )
	else
		excerpt = Excerpt.removeReferences( excerpt )
	end

	-- Remove wikilinks
	if not params.links then
		excerpt = Excerpt.removeLinks( excerpt )
	end

	-- Link the bold text and then remove it
	excerpt = Excerpt.linkBold( excerpt, page )
	if not params.bold then
		excerpt = Excerpt.removeBold( excerpt )
	end

	-- Remove extra line breaks but leave one before and after so the parser interprets lists, tables, etc. correctly
	excerpt = string.gsub( excerpt, '\n\n\n+', '\n\n' )
	excerpt = mw.text.trim( excerpt )
	excerpt = '\n' .. excerpt .. '\n'

	-- Remove nested categories
	excerpt = frame:preprocess( excerpt )
	excerpt = Excerpt.removeCategories( excerpt )

	-- Add tracking categories
	if config.categories then
		excerpt = Excerpt.addTrackingCategories( excerpt )
	end

	-- Build the final output
	if params.inline then
		return mw.text.trim( excerpt )
	end

	local tag = params.quote and 'blockquote' or 'div'
	local block = mw.html.create( tag ):addClass( 'excerpt-block' ):addClass( params.class )

	if config.styles then
		local styles = frame:extensionTag( 'templatestyles', '', { src = config.styles } )
		block:node( styles )
	end

	if params.hat then
		local hat = Excerpt.getHat( page, section, params )
		block:node( hat )
	end

	excerpt = mw.html.create( 'div' ):addClass( 'excerpt' ):wikitext( excerpt )
	block:node( excerpt )

	if params.more then
		local more = Excerpt.getReadMore( page, section )
		block:node( more )
	end

	return block
 end

 -- Filter the files in the given wikitext against the given filter
 function Excerpt.filterFiles( wikitext, filter )
	if not filter then return wikitext end
	local filters, isBlacklist = Excerpt.parseFilter( filter )
	local files = parser.getFiles( wikitext )
	for index, file in pairs( files ) do
		local name = parser.getFileName( file )
		if isBlacklist and ( Excerpt.matchFilter( index, filters ) or Excerpt.matchFilter( name, filters ) )
		or not isBlacklist and ( not Excerpt.matchFilter( index, filters ) and not Excerpt.matchFilter( name, filters ) ) then 
			wikitext = Excerpt.removeString( wikitext, file )
		end
	end
	return wikitext
 end

 -- Filter the lists in the given wikitext against the given filter
 function Excerpt.filterLists( wikitext, filter )
	if not filter then return wikitext end
	local filters, isBlacklist = Excerpt.parseFilter( filter )
	local lists = parser.getLists( wikitext )
	for index, list in pairs( lists ) do
		if isBlacklist and Excerpt.matchFilter( index, filters )
		or not isBlacklist and not Excerpt.matchFilter( index, filters ) then 
			wikitext = Excerpt.removeString( wikitext, list )
		end
	end
	return wikitext
 end

 -- Filter the tables in the given wikitext against the given filter
 function Excerpt.filterTables( wikitext, filter )
	if not filter then return wikitext end
	local filters, isBlacklist = Excerpt.parseFilter( filter )
	local tables = parser.getTables( wikitext )
	for index, t in pairs( tables ) do
		local id = string.match( t, '{|[^\n]-id%s*=%s*["\']?([^"\'\n]+)["\']?[^\n]*\n' )
		if isBlacklist and ( Excerpt.matchFilter( index, filters ) or Excerpt.matchFilter( id, filters ) )
		or not isBlacklist and ( not Excerpt.matchFilter( index, filters ) and not Excerpt.matchFilter( id, filters ) ) then 
			wikitext = Excerpt.removeString( wikitext, t )
		end
	end
	return wikitext
 end

 -- Filter the paragraphs in the given wikitext against the given filter
 function Excerpt.filterParagraphs( wikitext, filter )
	if not filter then return wikitext end
	local filters, isBlacklist = Excerpt.parseFilter( filter )
	local paragraphs = parser.getParagraphs( wikitext )
	for index, paragraph in pairs( paragraphs ) do
		if isBlacklist and Excerpt.matchFilter( index, filters )
		or not isBlacklist and not Excerpt.matchFilter( index, filters ) then 
			wikitext = Excerpt.removeString( wikitext, paragraph )
		end
	end
	return wikitext
 end

 -- Filter the templates in the given wikitext against the given filter
 function Excerpt.filterTemplates( wikitext, filter )
	if not filter then return wikitext end
	local filters, isBlacklist = Excerpt.parseFilter( filter )
	local templates = parser.getTemplates( wikitext )
	for index, template in pairs( templates ) do
		local name = parser.getTemplateName( template )
		if isBlacklist and ( Excerpt.matchFilter( index, filters ) or Excerpt.matchFilter( name, filters ) )
		or not isBlacklist and ( not Excerpt.matchFilter( index, filters ) and not Excerpt.matchFilter( name, filters ) ) then 
			wikitext = Excerpt.removeString( wikitext, template )
		end
	end
	return wikitext
 end

 function Excerpt.addInfoboxFile( excerpt )
	-- We cannot distinguish the infobox from the other templates, so we search them all
	local templates = parser.getTemplates( excerpt )
	for _, template in pairs( templates ) do
		local parameters = parser.getTemplateParameters( template )
		local file, captions, caption, cssClasses, cssClass
		for _, pair in pairs( config.captions ) do
			file = pair[1]
			file = parameters[file]
			if file and Excerpt.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
				-- Check for CSS classes
				-- 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
					end
				end
				local class = cssClass and ( '|class=' .. cssClass ) or ''
				return '[[File:' .. file .. class .. '|thumb|' .. ( caption or '' ) .. ']]' .. excerpt
			end
		end
	end
	return excerpt
 end

 function Excerpt.removeNonFreeFiles( wikitext )
	local files = parser.getFiles( wikitext )
	for _, file in pairs( files ) do
		local fileName = 'File:' .. parser.getFileName( file )
		local fileTitle = mw.title.new( fileName )
		if fileTitle then
			local fileDescription = fileTitle:getContent()
			if not fileDescription or fileDescription == '' then
				local frame = mw.getCurrentFrame()
				fileDescription = frame:preprocess( '{{' .. fileName .. '}}' ) -- try Commons
			end
			if fileDescription and string.match( fileDescription, '[Nn]on%-free' ) then
				wikitext = Excerpt.removeString( wikitext, file )
			end
		end
	end
	return wikitext
 end

 function Excerpt.getHat( page, section, params )
	local hat

	-- Build the text
	if params.this then
		hat = params.this
	elseif params.quote then
		hat = Excerpt.getMessage( 'this' )
	elseif params.only then
		hat = Excerpt.getMessage( params.only )
	else
		hat = Excerpt.getMessage( 'section' )
	end
	hat = hat .. ' ' .. Excerpt.getMessage( 'excerpt' )

	-- Build the link
	if section then
		hat = hat .. ' [[:' .. page .. '#' .. mw.uri.anchorEncode( section ) .. '|' .. params.displayTitle
			.. ' § ' .. mw.ustring.gsub( section, '%[%[([^]|]+)|?[^]]*%]%]', '%1' ) .. ']].' -- remove nested links
	else
		hat = hat .. ' [[:' .. page .. '|' .. params.displayTitle .. ']].'
	end

	-- Build the edit link
	local title = mw.title.new( page )
	local editUrl = title:fullUrl( 'action=edit' )
	hat = hat .. '<span class="mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span>['
	hat = hat .. editUrl .. ' ' .. mw.message.new( 'editsection' ):plain()
	hat = hat .. ']<span class="mw-editsection-bracket">]</span></span>'

	if config.hat then
		local frame = mw.getCurrentFrame()
		hat = config.hat .. hat .. '}}'
		hat = frame:preprocess( hat )
	else
		hat = mw.html.create( 'div' ):addClass( 'dablink excerpt-hat' ):wikitext( hat )
	end

	return hat
 end

 function Excerpt.getReadMore( page, section )
	local link = "'''[[" .. page
	if section then
		link = link .. '#' .. section
	end
	local text = Excerpt.getMessage( 'more' )
	link = link .. '|' .. text .. "]]'''"
	link = mw.html.create( 'div' ):addClass( 'noprint excerpt-more' ):wikitext( link )
	return link
 end

 -- Fix birth and death dates, but only in the first paragraph
 -- @todo Use parser.getParagraphs() to get the first paragraph
 function Excerpt.fixDates( excerpt )
	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
	return excerpt
 end

 -- Replace the first call to each reference defined outside of the excerpt for the full reference, to prevent undefined references
 -- Then prefix the page title to the reference names to prevent conflicts
 -- that is, replace <ref name="Foo"> for <ref name="Title of the article Foo">
 -- and also <ref name="Foo" /> for <ref name="Title of the article Foo" />
 -- also remove reference groups: <ref name="Foo" group="Bar"> for <ref name="Title of the article Foo">
 -- and <ref group="Bar"> for <ref>
 -- @todo The current regex may fail in cases with both kinds of quotes, like <ref name="Darwin's book">
 function Excerpt.fixReferences( excerpt, page, wikitext )
	local references = parser.getReferences( excerpt )
	local fixed = {}
	for _, reference in pairs( references ) do
		local name = parser.getTagAttribute( reference, 'name' )
		if not fixed[ name ] then
			local content = parser.getTagContent( reference )
			if not content then -- reference is self-closing
				local full = parser.getReference( excerpt, name )
				if not full then -- the reference is not defined in the excerpt
					full = parser.getReference( wikitext, name )
					table.insert( fixed, name ) -- search each reference only once
					if full then
						excerpt:gsub( Excerpt.escapeString( reference ), main, 1 )
					end
				end
			end
		end
	end
	-- Prepend the page title to the reference names to prevent conflicts with other references in the transcluding page
	excerpt = excerpt:gsub( '< *[Rr][Ee][Ff][^>]*name *= *["\']?([^"\'>/]+)["\']?[^>/]*(/?) *>', '<ref name="' .. page:gsub( '"', '' ) .. ' %1"%2>' )
	-- Remove reference groups because they don't apply to the transcluding page
	excerpt = excerpt:gsub( '< *[Rr][Ee][Ff] *group *= *["\']?[^"\'>/]+["\'] *>', '<ref>' )
	return excerpt
 end

 function Excerpt.removeReferences( excerpt )
	local references = parser.getReferences( excerpt )
	for _, reference in pairs( references ) do
		excerpt = Excerpt.removeString( excerpt, reference )
	end
	return excerpt
 end

 function Excerpt.removeCategories( excerpt )
	local categories = parser.getCategories( excerpt )
	for _, category in pairs( categories ) do
		excerpt = Excerpt.removeString( excerpt, category )
	end
	return excerpt
 end

 function Excerpt.removeBehaviorSwitches( excerpt )
	return string.gsub( excerpt, '__[A-Z]+__', '' )
 end

 function Excerpt.removeComments( excerpt )
	return string.gsub( excerpt, '<!%-%-.-%-%->', '' )
 end

 function Excerpt.removeBold( excerpt )
	return string.gsub( excerpt, "'''", '' )
 end

 function Excerpt.removeLinks( excerpt )
	local links = parser.getLinks( excerpt )
	for _, link in pairs( links ) do
		excerpt = Excerpt.removeString( excerpt, link )
	end
	return excerpt
 end

 -- @todo Use parser.getLinks
 function Excerpt.removeSelfLinks( excerpt, page )
	local lang = mw.language.getContentLanguage()
	local page = Excerpt.escapeString( mw.title.getCurrentTitle().prefixedText )
	local ucpage = lang:ucfirst( page )
	local lcpage = lang:lcfirst( page )
	excerpt = excerpt
		:gsub( '%[%[(' .. ucpage .. ')%]%]', '%1' )
		:gsub( '%[%[(' .. lcpage .. ')%]%]', '%1' )
		:gsub( '%[%[' .. ucpage .. '|([^]]+)%]%]', '%1' )
		:gsub( '%[%[' .. lcpage .. '|([^]]+)%]%]', '%1' )
	return excerpt
 end

 -- Replace the bold title or synonym near the start of the page by a link to the page
 function Excerpt.linkBold( excerpt, page )
	local lang = mw.language.getContentLanguage()
	local position = mw.ustring.find( excerpt, "'''" .. lang:ucfirst( page ) .. "'''", 1, true ) -- look for "'''Foo''' is..." (uc) or "A '''foo''' is..." (lc)
		or mw.ustring.find( excerpt, "'''" .. lang:lcfirst( page ) .. "'''", 1, true ) -- plain search: special characters in page represent themselves
	if position then
		local length = mw.ustring.len( page )
		excerpt = mw.ustring.sub( excerpt, 1, position + 2 ) .. '[[' .. mw.ustring.sub( excerpt, position + 3, position + length + 2 ) .. ']]' .. mw.ustring.sub( excerpt, position + length + 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)
		excerpt = mw.ustring.gsub( excerpt, "()'''(.-'*)'''", function ( a, b )
			if not mw.ustring.find( b, '%[' ) and not mw.ustring.find( b, '%{' ) then -- if not wikilinked or some weird template
				return "'''[[" .. page .. '|' .. b .. "]]'''" -- replace '''Foo''' by '''[[page|Foo]]'''
			else
				return nil -- instruct gsub to make no change
			end
		end, 1 ) -- "end" here terminates the anonymous replacement function(a, b) passed to gsub
	end
	return excerpt
 end

 function Excerpt.addTrackingCategories( excerpt )
	local currentTitle = mw.title.getCurrentTitle()
	local contentCategory = config.categories.content
	if contentCategory and currentTitle.isContentPage then
		excerpt = excerpt .. '[[Category:' .. contentCategory .. ']]'
	end
	local namespaceCategory = config.categories[ currentTitle.namespace ]
	if namespaceCategory then
		excerpt = excerpt .. '[[Category:' .. namespaceCategory .. ']]'
	end
	return excerpt
 end

 -- Helper method to match from a list of regular expressions
 -- Like so: match pre..list[1]..post or pre..list[2]..post or ...
 function Excerpt.matchAny( text, pre, list, post, init )
	local match = {}
	for i = 1, #list do
		match = { mw.ustring.match( text, pre .. list[ i ] .. post, init ) }
		if match[1] then return unpack( match ) end
	end
	return nil
 end

 -- Helper function to get arguments
 -- args from Lua calls have priority over parent args from template
 function Excerpt.getArg( key, default )
	local frame = mw.getCurrentFrame()
	for k, value in pairs( frame:getParent().args ) do
		if k == key and mw.text.trim( value ) ~= '' then
			return value
		end
	end
	for k, value in pairs( frame.args ) do
		if k == key and mw.text.trim( value ) ~= '' then
			return value
		end
	end
	return default
 end

 -- Helper method to get an error message
 -- This method also categorizes the current page in one of the configured error categories
 function Excerpt.getError( key, value )
	local message = Excerpt.getMessage( 'error-' .. key, value )
	local markup = mw.html.create( 'div' ):addClass( 'error' ):wikitext( message )
	if config.categories and config.categories.errors and mw.title.getCurrentTitle().isContentPage then
		markup:node( '[[Category:' .. config.categories.errors .. ']]' )
	end
	return markup
 end

 -- Helper method to get a localized message
 -- This method uses Module:TNT to get localized messages from https://commons.wikimedia.org/wiki/Data:I18n/Module:Excerpt.tab
 -- If Module:TNT is not available or the localized message does not exist, the key is returned instead
 function Excerpt.getMessage( key, value )
	local ok, TNT = pcall( require, 'Module:TNT' )
	if not ok then return key end
	local ok2, message = pcall( TNT.format, 'I18n/Module:Excerpt.tab', key, value )
	if not ok2 then return key end
	return message
 end

 -- Helper method to escape a string for use in regexes
 function Excerpt.escapeString( str )
	return str:gsub( '[%^%$%(%)%.%[%]%*%+%-%?%%]', '%%%0' )
 end

 -- Helper method to remove a string from a text
 -- @param text Text from where to remove the string
 -- @param str String to remove
 -- @return The given text with the string removed
 function Excerpt.removeString( text, str )
	local pattern = Excerpt.escapeString( str )
	if #pattern > 9999 then -- strings longer than 10000 bytes can't be put into regexes
		pattern = Excerpt.escapeString( mw.ustring.sub( str, 1, 999 ) ) .. '.-' .. Excerpt.escapeString( mw.ustring.sub( str, -999 ) )
	end
	return string.gsub( text, pattern, '' )
 end

 -- Helper method to convert a comma-separated list of numbers or min-max ranges into a list of booleans
 -- @param filter Required. Comma-separated list of numbers or min-max ranges, for example '1,3-5'
 -- @return Map from integers to booleans, for example {1=true,2=false,3=true,4=true,5=true}
 -- @return Boolean indicating whether the filters should be treated as a blacklist or not
 -- @note Merging this into matchFilter is possible, but way too inefficient
 function Excerpt.parseFilter( filter )
	local filters = {}
	local isBlacklist = false
	if string.sub( filter, 1, 1 ) == '-' then
		isBlacklist = true
		filter = string.sub( filter, 2 )
	end
	local values = mw.text.split( filter, ',' ) -- split values: '1,3-5' to {'1','3-5'}
	for _, value in pairs( values ) do
		value = mw.text.trim( value )
		local min, max = mw.ustring.match( value, '^(%d+)%s*[-–—]%s*(%d+)$' ) -- '3-5' to min=3 max=5
		if not max then min, max = string.match( value, '^((%d+))$' ) end -- '1' to min=1 max=1
		if max then
			for i = min, max do filters[ i ] = true end
		else
			filters[ value ] = true -- if we reach this point, the string had the form 'a,b,c' rather than '1,2,3'
		end
	end
	return filters, isBlacklist
 end

 -- Helper function to see if a value matches any of the given filters
 function Excerpt.matchFilter( value, filters )
	value = tostring( value )
	local lang = mw.language.getContentLanguage()
	local lcvalue = lang:lcfirst( value )
	local ucvalue = lang:ucfirst( value )
	for filter in pairs( filters ) do
		filter = tostring( filter )
		if value == filter
		or lcvalue == filter
		or ucvalue == filter
		or mw.ustring.match( value, filter ) then
			return true
		end
	end
 end

 -- Entry points for backwards compatibility
 -- @todo Verify that no one uses them and remove them
 function Excerpt.lead( frame ) return Excerpt.main( frame ) end
 function Excerpt.excerpt( frame ) return Excerpt.main( frame ) end

 return Excerpt

AltStyle によって変換されたページ (->オリジナル) /