Jump to content

Module:Hatnote list

Permanently protected module
From Wikipedia, the free encyclopedia

---------------------------------------------------------------------------------- Module:Hatnote list ---- ---- This module produces and formats lists for use in hatnotes. In particular, ---- it implements the for-see list, i.e. lists of "For X, see Y" statements, ---- as used in {{about}}, {{redirect}}, and their variants. Also introduced ---- are andList & orList helpers for formatting lists with those conjunctions. ----------------------------------------------------------------------------------localmArguments--initialize lazilylocalmFormatLink=require('Module:Format link')localmHatnote=require('Module:Hatnote')locallibraryUtil=require('libraryUtil')localcheckType=libraryUtil.checkTypelocalp={}---------------------------------------------------------------------------------- List stringification helper functions---- These functions are used for stringifying lists, usually page lists inside-- the "Y" portion of "For X, see Y" for-see items.----------------------------------------------------------------------------------default options table used across the list stringification functionslocalstringifyListDefaultOptions={conjunction="and",separator=",",altSeparator=";",space=" ",formatted=false}--Searches display text onlylocalfunctionsearchDisp(haystack,needle)returnstring.find(string.sub(haystack,(string.find(haystack,'|')or0)+1),needle)end-- Stringifies a list generically; probably shouldn't be used directlylocalfunctionstringifyList(list,options)-- Type-checks, defaults, and a shortcutcheckType("stringifyList",1,list,"table")if#list==0thenreturnnilendcheckType("stringifyList",2,options,"table",true)options=optionsor{}fork,vinpairs(stringifyListDefaultOptions)doifoptions[k]==nilthenoptions[k]=vendendlocals=options.space-- Format the list if requestedifoptions.formattedthenlist=mFormatLink.formatPages({categorizeMissing=mHatnote.missingTargetCat},list)end-- Set the separator; if any item contains it, use the alternate separatorlocalseparator=options.separatorfork,vinpairs(list)doifsearchDisp(v,separator)thenseparator=options.altSeparatorbreakendend-- Set the conjunction, apply Oxford comma, and force a comma if #1 has "§"localconjunction=s..options.conjunction..sif#list==2andsearchDisp(list[1],"§")or#list>2thenconjunction=separator..conjunctionend-- Return the formatted stringreturnmw.text.listToText(list,separator..s,conjunction)end--DRY functionfunctionp.conjList(conj,list,fmt)returnstringifyList(list,{conjunction=conj,formatted=fmt})end-- Stringifies lists with "and" or "or"functionp.andList(...)returnp.conjList("and",...)endfunctionp.orList(...)returnp.conjList("or",...)end---------------------------------------------------------------------------------- For see---- Makes a "For X, see [[Y]]." list from raw parameters. Intended for the-- {{about}} and {{redirect}} templates and their variants.----------------------------------------------------------------------------------default options table used across the forSee family of functionslocalforSeeDefaultOptions={andKeyword='and',title=mw.title.getCurrentTitle().text,otherText='other uses',forSeeForm='For %s, see %s.',}--Collapses duplicate punctuation at end of string, ignoring italics and linkslocalfunctionpunctuationCollapse(text)returntext:match("[.?!]('?)%1(%]?)%2%.$")andtext:sub(1,-2)ortextend-- Structures arguments into a table for stringification, & optionsfunctionp.forSeeArgsToTable(args,from,options)-- Type-checks and defaultscheckType("forSeeArgsToTable",1,args,'table')checkType("forSeeArgsToTable",2,from,'number',true)from=fromor1checkType("forSeeArgsToTable",3,options,'table',true)options=optionsor{}fork,vinpairs(forSeeDefaultOptions)doifoptions[k]==nilthenoptions[k]=vendend-- maxArg's gotten manually because getArgs() and table.maxn aren't friendslocalmaxArg=0fork,vinpairs(args)doiftype(k)=='number'andk>maxArgthenmaxArg=kendend-- Structure the data out from the parameter list:-- * forTable is the wrapper table, with forRow rows-- * Rows are tables of a "use" string & a "pages" table of pagename strings-- * Blanks are left empty for defaulting elsewhere, but can terminate listlocalforTable={}locali=fromlocalterminated=false-- If there is extra text, and no arguments are given, give nil value-- to not produce default of "For other uses, see foo (disambiguation)"ifoptions.extratextandi>maxArgthenreturnnilend-- Loop to generate rowsrepeat-- New empty rowlocalforRow={}-- On blank use, assume list's ended & break at end of this loopforRow.use=args[i]ifnotargs[i]thenterminated=trueend-- New empty list of pagesforRow.pages={}-- Insert first pages item if presenttable.insert(forRow.pages,args[i+1])-- If the param after next is "and", do inner loop to collect params-- until the "and"'s stop. Blanks are ignored: "1|and||and|3" → {1, 3}whileargs[i+2]==options.andKeyworddoifargs[i+3]thentable.insert(forRow.pages,args[i+3])end-- Increment to next "and"i=i+2end-- Increment to next usei=i+2-- Append the rowtable.insert(forTable,forRow)untilterminatedori>maxArgreturnforTableend-- Stringifies a table as formatted by forSeeArgsToTablefunctionp.forSeeTableToString(forSeeTable,options)-- Type-checks and defaultscheckType("forSeeTableToString",1,forSeeTable,"table",true)checkType("forSeeTableToString",2,options,"table",true)options=optionsor{}fork,vinpairs(forSeeDefaultOptions)doifoptions[k]==nilthenoptions[k]=vendend-- Stringify each for-see item into a listlocalstrList={}ifforSeeTablethenfork,vinpairs(forSeeTable)dolocaluseStr=v.useoroptions.otherTextlocalpagesStr=p.andList(v.pages,true)ormFormatLink._formatLink{categorizeMissing=mHatnote.missingTargetCat,link=mHatnote.disambiguate(options.title)}localforSeeStr=string.format(options.forSeeForm,useStr,pagesStr)forSeeStr=punctuationCollapse(forSeeStr)table.insert(strList,forSeeStr)endendifoptions.extratextthentable.insert(strList,punctuationCollapse(options.extratext..'.'))end-- Return the concatenated listreturntable.concat(strList,' ')end-- Produces a "For X, see [[Y]]" string from arguments. Expects index gaps-- but not blank/whitespace values. Ignores named args and args < "from".functionp._forSee(args,from,options)localforSeeTable=p.forSeeArgsToTable(args,from,options)returnp.forSeeTableToString(forSeeTable,options)end-- As _forSee, but uses the frame.functionp.forSee(frame,from,options)mArguments=require('Module:Arguments')returnp._forSee(mArguments.getArgs(frame),from,options)endreturnp
close