-- Invocation functions for English Wikipedia templates -- May not work properly or at all on other wikis  local e = require("Module:Excerpt") local p = {}  -- Shared invocation function used by templates meant for portals local function portal(frame, template) 	local args = e.parseArgs(frame)  	errors = args['errors'] or false -- disable error reporting unless requested  	-- There should be at least one argument except with selected=Foo and Foo=Somepage 	if #args < 1 and not (template == "selected" and args[template] and args[args[template]]) then 		return e.wikiError("noPage") 	end  	-- Figure out the page to excerpt 	local page 	local candidates = {}  	if template == "lead" then 		page = args[1] 		page = mw.text.trim(page) 		if not page or page == "" then return e.wikiError("noPage") end 		candidates = { page }  	elseif template == "selected" then 		local key = args[template] 		local count = #args 		if tonumber(key) then -- normalise article number into the range 1..#args 			key = key % count 			if key == 0 then key = count end 		end 		page = args[key] 		page = mw.text.trim(page) 		if not page or page == "" then return e.wikiError("noPage") end 		candidates = { page }  	elseif template == "linked" or template == "listitem" then 		local source = args[1] 		local text, source = e.getContent(source) 		if not source then 			return e.wikiError("noPage") 		elseif not text then 			return e.wikiError("noPage") 		end 		local section = args.section 		if section then -- check relevant section only 			text = e.getSection(text, section) 			if not text then return e.wikiError("sectionNotFound", section) end 		end 		-- Replace annotated links with real links 		text = mw.ustring.gsub(text, "{{%s*[Aa]nnotated[ _]link%s*|%s*(.-)%s*}}", "%1") 		if template == "linked" then 			for candidate in mw.ustring.gmatch(text, "%[%[%s*([^%]|\n]*)") do table.insert(candidates, candidate) end 		else -- listitem: first wikilink on a line beginning *, :#, etc. except in "See also" or later section 			text = mw.ustring.gsub(text, "\n== *আরও দেখুন.*", "") 			for candidate in mw.ustring.gmatch(text, "\n:*[%*#][^\n]-%[%[%s*([^%]|\n]*)") do table.insert(candidates, candidate) end 		end  	elseif template == "random" then 		for key, value in pairs(args) do 			if value and type(key) == "number" then table.insert(candidates, value) end 		end 	end  	-- Build an options array for the Excerpt module out of the arguments and the desired defaults 	local options = { 		errors = args['errors'] or false, 		fileargs = args['fileargs'], 		fileflags = e.numberFlags( args['files'] ), 		paraflags = e.numberFlags( args['paragraphs'] ) 	}  	-- Select a random candidate and make sure its valid 	local text 	local candidateCount = #candidates 	if candidateCount > 0 then 		local candidateKey = 1 		local candidateString 		local candidateArgs 		if candidateCount > 1 then math.randomseed(os.time()) end 		while (not text or text == "") and candidateCount > 0 do 			if candidateCount > 1 then candidateKey = math.random(candidateCount) end -- pick a random candidate 			candidateString = candidates[candidateKey] 			if candidateString and candidateString ~= "" then 				-- We have page or page or text, possibly followed by |opt1|opt2... 				page, candidateArgs = mw.ustring.match(candidateString, "^%s*(%[%b[]%])%s*|?(.*)") 				if page and page ~= "" then 					page = mw.ustring.match(page, "%[%[([^|%]]*)") -- turn text into page, discarding text 				else -- we have page or page|opt... 					page, candidateArgs = mw.ustring.match(candidateString, "%s*([^|]*[^|%s])%s*|?(.*)") 				end 				-- candidate arguments (even if value is "") have priority over global arguments 				if candidateArgs and candidateArgs ~= "" then 					for _, t in pairs(mw.text.split(candidateArgs, "|")) do 						local k, v = mw.ustring.match(t, "%s*([^=]-)%s*=(.-)%s*$") 						if k == 'files' then options.fileflags = e.numberFlags(v) 						elseif k == 'paragraphs' then options.paraflags = e.numberFlags(v) 						elseif k == 'more' then args.more = v 						else options[k] = v end 					end 				end 				if page and page ~= "" then 					local section = mw.ustring.match(page, "[^#]+#?([^#]*)") -- save the section 					text, page = e.getContent(page) -- make sure the page exists 					if page and page ~= "" and text and text ~= "" then 						if args.nostubs then 							local isStub = mw.ustring.find(text, "%s*{{[^{|}]*%-[Ss]tub%s*}}") 							if isStub then text = nil end 						end 						page = page .. '#' .. section -- restore the section 						text = e.get(page, options) 					end 				end 			end 			table.remove(candidates, candidateKey) -- candidate processed 			candidateCount = candidateCount - 1 -- ensure that we exit the loop after all candidates are done 		end 	end 	if not text or text == "" then return e.wikiError("No valid pages found") end  	if args.showall then 		local separator = args.showall 		if separator == "" then separator = "" end 		for _, candidate in pairs(candidates) do 			local t = e.get(candidate, options) 			if t ~= "" then 				text = text .. separator .. t 			end 		end 	end  	-- If more= then append a link to article for more info 	if args.more then 		local more = "Read more..." -- default text 		if args.more ~= "" then more = args.more end -- use the given text 		text = text .. " " .. more .. "" 	end  	-- Add a collapsed list of pages which might appear 	if args.list and not args.showall then 		local list = args.list 		if list == "" then list = "Other articles" end 		text = text .. "{{hlist" 		for _, candidate in pairs(candidates) do 			if mw.ustring.match(candidate, "%S") then text = text .. "|" .. mw.text.trim(candidate) .. "" end 		end 		text = text .. "}}\n" 	end  	return frame:preprocess(text) end  -- Invocation function used by  local function excerpt(frame) 	local args = e.parseArgs(frame)  	-- Make sure the requested page exists 	local page = args[1] or args.article or args.source or args.page 	if not page then return e.wikiError("noPage") end 	local title = mw.title.new(page) 	if not title then return e.wikiError("noPage") end 	if title.isRedirect then title = title.redirectTarget end 	if not title.exists then return e.wikiError("pageNotFound", page) end 	page = title.prefixedText  	-- Define some useful variables 	local section = args[2] or args.section or mw.ustring.match(args[1], "[^#]+#([^#]+)") 	local tag = args.tag or 'div'  	-- Define the HTML elements 	local block = mw.html.create(tag):addClass('excerpt-block') 	if e.is(args.indicator) then block:addClass('excerpt-indicator') end  	local style = frame:extensionTag{ name = 'templatestyles', args = { src = 'Excerpt/styles.css' } }  	local hatnote 	if not args.nohat then 		if args.this then 			hatnote = args.this 		elseif args.indicator then 			hatnote = 'This is' 		elseif args.only == 'file' then 			hatnote = 'This file is' 		elseif args.only == 'file' then 			hatnote = 'These files are' 		elseif args.only == 'list' then 			hatnote = 'This list is' 		elseif args.only == 'lists' then 			hatnote = 'These lists are' 		elseif args.only == 'table' then 			hatnote = 'This table is' 		elseif args.only == 'tables' then 			hatnote = 'These tables are' 		else 			hatnote = 'This section is' 		end 		hatnote = hatnote .. ' an excerpt from ' 		if section then 			hatnote = hatnote .. '' .. page .. ' § ' .. section .. '' 		else 			hatnote = hatnote .. '' .. page .. '' 		end 		hatnote = hatnote .. "" .. '[[' 		hatnote = hatnote .. title:fullUrl('action=edit') .. ' edit' 		hatnote = hatnote .. ']]' .. "" 		hatnote = require('Module:Hatnote')._hatnote(hatnote, {selfref=true}) or e.wikiError('Error generating hatnote') 	end  	-- Build the module options out of the template arguments and the desired defaults 	local options = { 		fileflags = e.numberFlags( args['files'] or 1 ), 		paraflags = e.numberFlags( args['paragraphs'] ), 		filesOnly = e.is( args['only'] == 'file' or args['only'] == 'files' ), 		listsOnly = e.is( args['only'] == 'list' or args['only'] == 'lists'), 		tablesOnly = e.is( args['only'] == 'table' or args['only'] == 'tables' ), 		keepTables = e.is( args['tables'] or true ), 		keepRefs = e.is( args['references']  or true ), 		keepSubsections = e.is( args['subsections'] ), 		nobold = not e.is( args['bold'] ), 		fragment = args['fragment'] 	}  	-- Get the excerpt itself 	if section then page = page .. '#' .. section end 	local ok, excerpt = pcall(e.get, page, options) 	if not ok then return e.wikiError(excerpt) end 	excerpt = "\n" .. excerpt -- line break is necessary to prevent broken tables and lists 	if mw.title.getCurrentTitle().isContentPage then excerpt = excerpt .. 'Category:Articles with excerpts' end 	excerpt = frame:preprocess(excerpt) 	excerpt = mw.html.create(tag):addClass('excerpt'):wikitext(excerpt)  	-- Combine and return the elements 	return block:node(style):node(hatnote):node(excerpt) end  -- Entry points for English Wikipedia templates function p.lead(frame) return portal(frame, "lead") end --  reads a randomly selected article linked from the given page function p.linked(frame) return portal(frame, "linked") end --  reads a randomly selected article linked from the given page function p.listitem(frame) return portal(frame, "listitem") end --  reads a randomly selected article listed on the given page function p.random(frame) return portal(frame, "random") end --  reads any article (default for invoke with one argument) function p.selected(frame) return portal(frame, "selected") end --  reads the article whose key is in the selected= parameter function p.excerpt(frame) return excerpt(frame) end --  transcludes part of an article into another article  return p