Jump to content
Wikipedia The Free Encyclopedia

Module:Build bracket/Params

From Wikipedia, the free encyclopedia
Module documentation[create] [purge]
You might want to create a documentation page for this Scribunto module.
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
 localParams={}

 -- =========================
 -- 1) MODULE BINDINGS
 -- =========================
 -- Upvalues bound per call
 localstate,config,Helpers,StateChecks

 -- Stdlib aliases
 localstr_format=string.format
 localt_insert=table.insert
 localt_sort=table.sort

 -- Locals filled on bind (with safe fallbacks)
 localisempty,notempty,bargs,getPArg,getFArg,toChar,split

 localfunction_toCharFallback(n)
 n=tonumber(nor0)or0
 ifn>=1andn<=26then
 returnstring.char(96+n)-- 'a'..'z'
 end
 returntostring(n)
 end

 localfunctionbind(_state,_config,_Helpers,_StateChecks)
 state,config,Helpers,StateChecks=_state,_config,_Helpers,_StateChecks
 isempty=HelpersandHelpers.isemptyorfunction(v)
 returnv==nilorv==""
 end
 notempty=HelpersandHelpers.notemptyorfunction(v)
 returnv~=nilandv~=""
 end
 bargs=HelpersandHelpers.bargs
 getPArg=HelpersandHelpers.getPArg
 getFArg=HelpersandHelpers.getFArg
 toChar=(HelpersandHelpers.toChar)or_toCharFallback
 split=HelpersandHelpers.split
 end

 -- Try both RDj[a]-X and RDj[A]-X; falls back to "" if not present
 localfunctionreadPerHeaderArg(j,k,suffix)
 localch=toChar(k)-- e.g. 'a' with Helpers.toChar
 localkey1="RD"..j..ch..suffix
 localv=bargs(key1)
 ifv~=nilandv~=""then
 returnv
 end
 localkey2="RD"..j..string.upper(ch)..suffix
 v=bargs(key2)
 ifv~=nilandv~=""then
 returnv
 end
 return""
 end

 -- =========================
 -- 2) ARG HELPERS
 -- =========================
 -- Trim + split a comma list frame arg (returns {} on blank)
 localfunctionreadCsvArg(name)
 localraw=(getFArg(name)or""):gsub("%s+","")
 returnsplit(raw,{","},true)
 end

 -- ========================================
 -- 3) BUILD SKELETON (formerly getCells)
 -- ========================================
 localfunctionbuildSkeleton()
 localDEFAULT_TPM=2
 localmaxrow=1
 localcolentry={}
 localhasNoHeaders=true

 -- ensure containers
 state.entries=state.entriesor{}
 state.shift=state.shiftor{}
 state.teamsPerMatch=state.teamsPerMatchor{}
 state.maxtpm=state.maxtpmor0

 localCmin,Cmax=config.minc,config.c

 -- Phase 1: Determine header presence and teamsPerMatch
 forj=Cmin,Cmaxdo
 ifnotempty(getFArg("col"..j.."-headers"))then
 hasNoHeaders=false
 end
 localtpm=
 tonumber(getFArg("RD"..j.."-teams-per-match"))ortonumber(getFArg("col"..j.."-teams-per-match"))or
 tonumber(getFArg("teams-per-match"))or
 DEFAULT_TPM
 state.teamsPerMatch[j]=tpm
 iftpm>state.maxtpmthen
 state.maxtpm=tpm
 end
 end

 -- Phase 2: Build colentry for each column
 forj=Cmin,Cmaxdo
 state.entries[j]={}
 state.shift[j]=tonumber(bargs("RD"..j.."-shift"))ortonumber(bargs("shift"))or0

 colentry[j]={
 readCsvArg("col"..j.."-headers"),
 readCsvArg("col"..j.."-matches"),
 readCsvArg("col"..j.."-lines"),
 readCsvArg("col"..j.."-text"),
 readCsvArg("col"..j.."-groups")-- reserved for user-specified groups
 }

 -- inject a default header if none were specified anywhere (unless noheaders=y/yes)
 localnoheaders=(getFArg("noheaders")or""):lower()
 ifhasNoHeadersand(noheaders~="y"andnoheaders~="yes")then
 t_insert(colentry[j][1],1)
 end
 end

 -- Ctype mapping for colentry positions
 localCTYPE_MAP={"header","team","line","text","group"}

 -- Helpers to populate entries (preserve legacy shapes)
 localfunctionpopulateTeam(j,rowIndex,n)
 localTPM=state.teamsPerMatch[j]
 -- scaffold a text row above when needed (legacy behavior)
 ifstate.entries[j][rowIndex-1]==nilandstate.entries[j][rowIndex-2]==nilthen
 state.entries[j][rowIndex-2]={ctype="text",index=n}
 state.entries[j][rowIndex-1]={ctype="blank"}
 end
 -- first team (top)
 state.entries[j][rowIndex]={ctype="team",index=TPM*n-(TPM-1),position="top"}
 state.entries[j][rowIndex+1]={ctype="blank"}
 -- remaining teams in the match (every 2 rows)
 form=2,TPMdo
 localidx=TPM*n-(TPM-m)
 localr=rowIndex+2*(m-1)
 state.entries[j][r]={ctype="team",index=idx}
 state.entries[j][r+1]={ctype="blank"}
 end
 end

 localfunctionpopulateText(j,rowIndex,index)
 state.entries[j][rowIndex]={ctype="text",index=index}
 state.entries[j][rowIndex+1]={ctype="blank"}
 end

 localfunctionpopulateLine(j,rowIndex)
 -- first segment draws its bottom edge
 state.entries[j][rowIndex]={ctype="line",border="bottom"}
 state.entries[j][rowIndex+1]={ctype="blank"}
 -- second segment draws its top edge
 state.entries[j][rowIndex+2]={ctype="line",border="top"}
 state.entries[j][rowIndex+3]={ctype="blank"}
 end

 localfunctionpopulateGroup(j,rowIndex,n)
 state.entries[j][rowIndex]={ctype="group",index=n}
 state.entries[j][rowIndex+1]={ctype="blank"}
 end

 localfunctionpopulateDefault(j,rowIndex,n)
 state.entries[j][rowIndex]={ctype="header",index=n,position="top"}
 state.entries[j][rowIndex+1]={ctype="blank"}
 end

 -- Phase 3: Populate entries for each column
 forj=Cmin,Cmaxdo
 localtextindex=0
 localTPM=state.teamsPerMatch[j]
 localshiftJ=state.shift[j]

 fork,positionsinipairs(colentry[j])do
 t_sort(positions)
 localctype=CTYPE_MAP[k]

 forn=1,#positionsdo
 ifshiftJ~=0andpositions[n]>1then
 positions[n]=positions[n]+shiftJ
 end
 localrowIndex=2*positions[n]-1
 locallastRow=rowIndex+2*TPM-1
 iflastRow>maxrowthen
 maxrow=lastRow
 end

 ifctype=="team"then
 populateTeam(j,rowIndex,n)
 textindex=n
 elseifctype=="text"then
 populateText(j,rowIndex,textindex+n)
 elseifctype=="line"then
 populateLine(j,rowIndex)
 elseifctype=="group"then
 populateGroup(j,rowIndex,n)
 else
 populateDefault(j,rowIndex,n)
 end
 end
 end
 end

 ifisempty(config.r)then
 config.r=maxrow
 end
 end

 -- ========================================
 -- 4) NAME RESOLUTION HELPERS
 -- ========================================
 localfunctionparamNames(cname,j,i,l)
 localfunctiongetArg(key)
 returnbargs(key)or""
 end
 localfunctiongetP(key)
 returngetPArg(key)or""
 end

 locale=state.entries[j][i]
 localRD="RD"..j
 localhidx=e.headerindex
 localhchar=toChar(hidx)
 localRDh=RD..hchar

 localSYNONYMS={legs={"legs","sets"}}

 -- Try a list of names against base+index(+suffix); returns first non-empty
 localfunctiontryAny(base,names,idx,suffix)
 suffix=suffixor""
 for_,nminipairs(names)do
 locala=bargs(base.."-"..nm..idx..suffix)or""
 ifisempty(a)then
 a=bargs(base.."-"..nm..string.format("%02d",idx)..suffix)or""
 end
 ifnotempty(a)then
 returna
 end
 end
 return""
 end

 localfunctiontryBoth(base,name,idx,suffix)
 suffix=suffixor""
 locala=getArg(base.."-"..name..idx..suffix)
 ifisempty(a)then
 a=getArg(base.."-"..name..str_format("%02d",idx)..suffix)
 end
 returna
 end

 -- Round names (prefer altname when present)
 localRDlabel=getArg(RD.."-altname")orRD
 localRDhlabel=getArg(RDh.."-altname")orRDh

 localrname={{RD,RDlabel},{RDh,RDhlabel}}
 localname={cname,getArg(cname.."-altname")orcname}
 localnameKeys=SYNONYMS[cname]or{name[1]}
 localindex={e.index,e.altindex}
 localresult={}

 ifcname=="header"then
 ifhidx==1then
 for_,baseinipairs({rname[1],rname[2]})do
 fork=2,1,-1do
 result[#result+1]=getArg(base[k])
 end
 end
 else
 fork=2,1,-1do
 result[#result+1]=getArg(rname[2][k])
 end
 end
 elseifcname=="pheader"then
 ifhidx==1then
 for_,baseinipairs({rname[1],rname[2]})do
 fork=2,1,-1do
 result[#result+1]=getP(base[k])
 end
 end
 else
 fork=2,1,-1do
 result[#result+1]=getP(rname[2][k])
 end
 end
 elseifcname=="score"then
 localbases={rname[2][2],rname[2][1],rname[1][2],rname[1][1]}
 localidxs={index[2],index[2],index[1],index[1]}
 forn=1,4do
 ifl==1then
 result[#result+1]=tryAny(bases[n],nameKeys,idxs[n])
 end
 result[#result+1]=tryAny(bases[n],nameKeys,idxs[n],"-"..l)
 end
 elseifcname=="shade"then
 fork=2,1,-1do
 localbase=(hidx==1)andrname[1][k]orrname[2][k]
 result[#result+1]=getArg(base.."-"..name[1])
 end
 result[#result+1]=getArg("RD-shade")
 result[#result+1]=(config.COLORSandconfig.COLORS.cell_bg_dark)or"#eaecf0"
 elseifcname=="text"then
 localbases={rname[2][2],rname[2][1],rname[1][2],rname[1][1]}
 localidxs={index[2],index[2],index[1],index[1]}
 localnames={name[2],name[1]}
 forni=1,2do
 forn=1,4do
 result[#result+1]=tryBoth(bases[n],names[ni],idxs[n])
 end
 end
 else
 localbases={rname[2][2],rname[2][1],rname[1][2],rname[1][1]}
 localidxs={index[2],index[2],index[1],index[1]}
 forn=1,4do
 result[#result+1]=tryAny(bases[n],nameKeys,idxs[n])
 end
 end

 for_,valinipairs(result)do
 ifnotempty(val)then
 returnval
 end
 end
 return""
 end

 -- ========================================
 -- 5) NUMBERED PARAM MODE
 -- ========================================
 localmasterindex=1

 localfunctionnumberedParams(j)
 localrow=state.entries[j]
 ifnotrowthen
 return
 end

 localfunctionnextArg()
 localv=bargs(tostring(masterindex))or""
 masterindex=masterindex+1
 returnv
 end

 localR=config.r
 fori=1,Rdo
 locale=row[i]
 ifethen
 localct=e.ctype
 ifct=="team"then
 locallegs=state.rlegs[j]

 ifconfig.forceseedsthen
 e.seed=nextArg()
 end

 e.team=nextArg()
 e.legs=paramNames("legs",j,i)
 e.score={weight={}}
 e.weight="normal"

 ifnotempty(e.legs)then
 legs=tonumber(e.legs)orlegs
 end

 forl=1,legsdo
 e.score[l]=nextArg()
 e.score.weight[l]="normal"
 end

 ifconfig.aggregateandlegs>1then
 e.score.agg=nextArg()
 e.score.weight.agg="normal"
 end
 elseifct=="header"then
 e.header=paramNames("header",j,i)
 e.pheader=paramNames("pheader",j,i)
 e.shade=paramNames("shade",j,i)
 elseifct=="text"then
 e.text=nextArg()
 elseifct=="group"then
 e.group=nextArg()
 elseifct=="line"ande.hastext==truethen
 e.text=nextArg()
 end
 end
 end
 end

 -- ========================================
 -- 6) NAMED MODE ASSIGNERS (per-ctype)
 -- ========================================
 localfunctioncellHasMeaningfulContent(e)
 ifnotethen
 returnfalse
 end
 ife.ctype=="team"then
 returnnotempty(e.team)
 end
 ife.ctype=="text"then
 returnnotempty(e.text)
 end
 ife.ctype=="group"then
 returnnotempty(e.group)
 end
 ife.ctype=="line"ande.hastext==truethen
 returnnotempty(e.text)
 end
 returnfalse
 end

 localfunctionenforceContentUnhide(j)
 ifnot(state.hideandstate.hide[j])then
 return
 end
 localexplicit=(state._hideExplicitandstate._hideExplicit[j])or{}
 localR=config.r

 -- If master hid a header, but we later discover content in that header,
 -- flip it visible unless there was an EXPLICIT per-header hide.
 fori=1,Rdo
 locale=state.entries[j][i]
 ifeande.headerindexthen
 localh=e.headerindex
 ifstate.hide[j][h]andcellHasMeaningfulContent(e)then
 state.hide[j][h]=false
 end
 end
 end
 end

 localfunctionassignTeamParams(j,i)
 locallegs=state.rlegs[j]
 locale=state.entries[j][i]

 e.seed=paramNames("seed",j,i)
 e.team=paramNames("team",j,i)
 e.legs=paramNames("legs",j,i)
 e.score={weight={}}
 e.weight="normal"

 ifnotempty(e.legs)then
 legs=tonumber(e.legs)orlegs
 end

 ifconfig.autolegsthen
 locall=1
 repeat
 e.score[l]=paramNames("score",j,i,l)
 e.score.weight[l]="normal"
 l=l+1
 untilisempty(paramNames("score",j,i,l))
 legs=l-1
 else
 forl=1,legsdo
 e.score[l]=paramNames("score",j,i,l)
 e.score.weight[l]="normal"
 end
 end

 ifconfig.aggregateandlegs>1then
 e.score.agg=paramNames("score",j,i,"agg")
 e.score.weight.agg="normal"
 end
 end

 localfunctionassignHeaderParams(j,i)
 locale=state.entries[j][i]
 e.header=paramNames("header",j,i)
 e.pheader=paramNames("pheader",j,i)
 e.shade=paramNames("shade",j,i)

 -- Did shade originate from an RD*-shade param?
 localhchar=toChar(e.headerindex)
 localrdNames={
 "RD"..j.."-shade",
 "RD"..j..hchar.."-shade",
 "RD-shade"
 }
 e.shade_is_rd=false
 for_,pnameinipairs(rdNames)do
 localv=bargs(pname)
 ifnotempty(v)ande.shade==vthen
 e.shade_is_rd=true
 break
 end
 end
 end

 localfunctionassignTextParams(j,i)
 state.entries[j][i].text=paramNames("text",j,i)
 end

 localfunctionassignGroupParams(j,i)
 state.entries[j][i].group=paramNames("group",j,i)
 end

 localfunctionassignLineTextParams(j,i)
 state.entries[j][i].text=paramNames("text",j,i)
 end

 -- ========================================
 -- 7) TABLE-WIDE ASSIGNMENT PASS
 -- ========================================
 localfunctiongetScalarRoundParam(j,bases)-- e.g. {"legs","sets"}
 -- prefer per-round keys, then global
 for_,baseinipairs(bases)do
 localv=bargs("RD"..j.."-"..base)
 ifnotempty(v)then
 returnv
 end
 end
 for_,baseinipairs(bases)do
 localv=bargs(base)
 ifnotempty(v)then
 returnv
 end
 end
 return""
 end

 localfunctionassignParams()
 masterindex=1
 localmaxcol=1

 localCmin,Cmax,R=config.minc,config.c,config.r

 forj=Cmin,Cmaxdo
 -- prepare per-round containers
 state.hide[j]=state.hide[j]or{}
 state.byes[j]=state.byes[j]or{}

 -- Set legs for this column
 localvlegs=getScalarRoundParam(j,{"legs","sets"})
 state.rlegs[j]=tonumber(vlegs)or1
 ifnotempty(vlegs)then
 config.autolegs=false
 end

 -- assign params
 ifconfig.paramstyle=="numbered"then
 numberedParams(j)
 else
 localcol=state.entries[j]
 fori=1,Rdo
 localcell=col[i]
 ifcell~=nilthen
 localct=cell.ctype
 ifct=="team"then
 assignTeamParams(j,i)
 elseifct=="header"then
 assignHeaderParams(j,i)
 elseifct=="text"then
 assignTextParams(j,i)
 elseifct=="group"then
 assignGroupParams(j,i)
 elseifct=="line"andcell.hastext==truethen
 assignLineTextParams(j,i)
 end
 end
 ifconfig.autocolandnotStateChecks.isBlankEntry(j,i)andj>maxcolthen
 maxcol=j
 end
 end
 end

 enforceContentUnhide(j)

 -- parent header text forces visible
 fori=1,Rdo
 locale=state.entries[j][i]
 ifeande.ctype=="header"then
 localhidx=e.headerindex
 if(Helpers.notemptyandHelpers.notempty(e.pheader))then
 state.hide[j][hidx]=false
 end
 end
 end
 end

 ifconfig.autocolthen
 config.c=maxcol
 end
 end

 -- ========================================
 -- 8) STRUCTURE DISCOVERY (hide/byes/indices)
 -- ========================================
 localfunctiongetHide(j)
 state.hide[j]={}
 state._hideExplicit=state._hideExplicitor{}
 state._hideExplicit[j]={}

 -- master round-level hide flag: RD{j}-hide
 localmasterRaw=bargs("RD"..j.."-hide")or""
 localmasterOn=(HelpersandHelpers.yesandHelpers.yes(masterRaw))orfalse

 fork=1,state.headerindex[j]do
 state.hide[j][k]=masterOn

 -- per-header override
 localrh=readPerHeaderArg(j,k,"-hide")
 ifrh~=""then
 ifHelpersandHelpers.yesandHelpers.yes(rh)then
 state.hide[j][k]=true
 state._hideExplicit[j][k]=true
 elseifHelpersandHelpers.noandHelpers.no(rh)then
 state.hide[j][k]=false
 state._hideExplicit[j][k]=true
 end
 end
 end
 end

 localfunctiongetByes(j)
 state.byes[j]={}
 fork=1,state.headerindex[j]do
 -- global byes
 localbyes=(bargs("byes")or""):lower()
 if(Helpers.yesandHelpers.yes(byes))then
 state.byes[j][k]=true
 elseiftonumber(byes)then
 state.byes[j][k]=(j<=tonumber(byes))
 else
 state.byes[j][k]=false
 end
 -- per-round byes
 localr=(bargs("RD"..j.."-byes")or""):lower()
 if(Helpers.yesandHelpers.yes(r))then
 state.byes[j][k]=true
 elseifr=="no"orr=="n"then
 state.byes[j][k]=false
 end
 -- per-header byes
 localrh=(readPerHeaderArg(j,k,"-byes")or""):lower()
 if(Helpers.yesandHelpers.yes(rh))then
 state.byes[j][k]=true
 elseifrh=="no"orrh=="n"then
 state.byes[j][k]=false
 end
 end
 end

 localfunctiongetAltIndices()
 localCmin,Cmax,R=config.minc,config.c,config.r

 forj=Cmin,Cmaxdo
 state.headerindex[j]=0

 -- per-round counters
 localteamindex,textindex,groupindex=1,1,1
 localrow=state.entries[j]

 -- if the very first cell is nil, bump headerindex once (legacy quirk)
 ifrowandrow[1]==nilthen
 state.headerindex[j]=state.headerindex[j]+1
 end

 -- walk rows in the round
 fori=1,Rdo
 locale=rowandrow[i]ornil
 ifethen
 localct=e.ctype
 ifct=="header"then
 e.altindex=state.headerindex[j]
 teamindex,textindex=1,1
 state.headerindex[j]=state.headerindex[j]+1
 elseifct=="team"then
 e.altindex=teamindex
 teamindex=teamindex+1
 elseifct=="text"or(ct=="line"ande.hastext==true)then
 e.altindex=textindex
 textindex=textindex+1
 elseifct=="group"then
 e.altindex=groupindex
 groupindex=groupindex+1
 end
 e.headerindex=state.headerindex[j]
 end
 end

 getByes(j)
 getHide(j)
 end
 end

 -- ========================================
 -- 9) PUBLIC API
 -- ========================================
 functionParams.buildSkeleton(_state,_config,_Helpers,_StateChecks)
 bind(_state,_config,_Helpers,_StateChecks)
 buildSkeleton()
 end

 functionParams.scanStructure(_state,_config,_Helpers,_StateChecks)
 bind(_state,_config,_Helpers,_StateChecks)
 getAltIndices()
 end

 functionParams.assign(_state,_config,_Helpers,_StateChecks)
 bind(_state,_config,_Helpers,_StateChecks)
 assignParams()
 end

 -- ========================================
 -- 10) SLICING FOR MIN ROUND (base offset)
 -- ========================================
 localfunctionshiftCols(tbl,base,c)
 ifnottblthen
 return{}
 end
 localout={}
 forj=base+1,cdo
 out[j-base]=tbl[j]
 end
 returnout
 end

 functionParams.sliceForMinround(_state,_config)
 localbase=_config.baseor0
 ifbase<=0then
 return
 end

 localoldC=_config.c
 localnewC=oldC-base
 ifnewC<1then
 newC=1
 end

 -- Shift all column-indexed tables
 _state.entries=shiftCols(_state.entries,base,oldC)
 _state.headerindex=shiftCols(_state.headerindex,base,oldC)
 _state.rlegs=shiftCols(_state.rlegs,base,oldC)
 _state.maxlegs={}-- recompute later
 _state.hascross={}-- rebuild later
 _state.crossCell={}-- rebuild later
 _state.pathCell={}-- rebuild later
 _state.skipPath={}-- rebuild later
 _state.hide=shiftCols(_state.hide,base,oldC)
 _state.byes=shiftCols(_state.byes,base,oldC)
 _state.teamsPerMatch=shiftCols(_state.teamsPerMatch,base,oldC)
 _state.matchgroup={}-- recompute

 -- Update view range: now we render 1..newC
 _config.c=newC
 _config.minc=1
 end

 returnParams

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