模組:Sports table
可在模組:Sports table/doc建立此模組的說明文件
-- Module to build tables for standings in Sports-- See documentation for detailsrequire('strict')local p = {}-- Main functionfunction p.main(frame)-- Declare localslocal getArgs = require('Module:Arguments').getArgslocal Args = getArgs(frame, {parentFirst = true})local ii_start, ii_end, N_rows_res = 0local text_field_resultlocal notes_exist = falselocal t = {}local t_footer = {}local t_return = {}local team_list = {}local jj, jjj-- Exit early if we are using section transclusion for a different sectionlocal tsection = frame:getParent().args['transcludesection'] or frame:getParent().args['section'] or ''local bsection = frame.args['section'] or ''if( tsection ~= '' and bsection ~= '' ) thenif( tsection ~= bsection ) thenreturn ''endendlocal templatestyles = frame:extensionTag{name = 'templatestyles', args = { src = 'Module:Sports table/styles.css' }}-- Edit links if requestedlocal baselink = frame:getParent():getTitle()if mw.title.getCurrentTitle().text == baselink thenbaselink = '' endlocal template_name = (baselink ~= '' and (':' .. baselink .. (Args['article_section'] and '#' .. Args['article_section'] or '')))or ''-- Get the custom start point for the table (most will start by default at 1)local top_pos = tonumber(Args['highest_pos']) or 1-- Get the custom end point for the table (unrestricted if bottom_pos is < top_pos)local bottom_pos = tonumber(Args['lowest_pos']) or 0local N_teams = top_pos - 1 -- Default to 0 at start, but higher number needed to skip certain entries-- Load moduleslocal yesno = require('Module:Yesno')-- Load style and (sub) moduleslocal style_def = Args['style'] or 'WDL'-- Historically 'football' exists as style, this is now forwarded to WDLif style_def == 'football' then style_def = 'WDL' endlocal p_style = require('Module:Sports table/'..style_def)local p_sub = require('Module:Sports table/sub')-- Random value used for uniquenessmath.randomseed( os.clock() * 10^8 )local rand_val = math.random()-- Declare colour schemelocal result_col = {}result_col = {green1='#BBF3BB', green2='#CCF9CC', green3='#DDFCDD', green4='#EEFFEE',blue1='#BBF3FF', blue2='#CCF9FF', blue3='#DDFCFF', blue4='#EEFFFF',yellow1='#FFFFBB', yellow2='#FFFFCC', yellow3='#FFFFDD', yellow4='#FFFFEE',red1='#FFBBBB', red2='#FFCCCC', red3='#FFDDDD', red4='#FFEEEE',black1='#BBBBBB', black2='#CCCCCC', black3='#DDDDDD', black4='#EEEEEE',orange1='#FEDCBA', orange2='#FEEAD5',white1='inherit',['']='inherit'}-- Show all stats in table or just matches played and pointslocal full_table = truelocal hide_results = yesno(Args['hide_results'] or 'no')local pld_pts_val = string.lower(Args['only_pld_pts'] or 'no')local show_class_rules = yesno(Args['show_class_rules'] or 'yes') and true or false-- True if par doesn't exist, false otherwiseif yesno(pld_pts_val) thenfull_table = falseelseif pld_pts_val=='no_hide_class_rules' thenfull_table = trueshow_class_rules = falseend-- Declare results column headerlocal results_header = {}results_header = {Q='Qualification', QR='Qualification or relegation',P='Promotion', PQR='Promotion, qualification or relegation',PR='Promotion or relegation', PQ='Promotion or qualification', R='Relegation'}local results_defined = false -- Check whether this would be needed-- Possible prefix for result fieldslocal respre = (Args['result_prefix'] or '') .. '_'respre = (respre == '_') and '' or respre-- Now define line for column header (either option or custom)local local_res_header = results_header[Args[respre..'res_col_header']] or Args[respre..'res_col_header'] or ''-- Check whether it includes a notelocal res_head_note = Args['note_header_res']local res_head_note_text = ''if full_table and res_head_note thennotes_exist = trueres_head_note_text = frame:expandTemplate{ title = 'efn', args = { group='lower-alpha', res_head_note} }endlocal results_header_txt = '! scope="col" |'..local_res_header..res_head_note_text..'\n'-- Get status optionlocal t_status = p_style.status(Args)-- Alternative syntax for team listif Args['team_order'] and Args['team_order'] ~= '' thenlocal team_order_offset = (tonumber(Args['team_order_start']) or 1) - 1local tlist = mw.text.split(Args['team_order'], '%s*[;,]%s*')for k, tname in ipairs(tlist) doif tname ~= '' thenArgs['team' .. (k + team_order_offset)] = tnameendendend-- Read in number of consecutive teams (ignore entries after skipping a spot)while Args['team'..N_teams+1] ~= nil and (bottom_pos < top_pos or N_teams < bottom_pos) doN_teams = N_teams+1-- Sneakily add it twice to the team_list parameter, once for the actual-- ranking, the second for position lookup in sub-tables-- This is possible because Lua allows both numbers and strings as indices.team_list[N_teams] = Args['team'..N_teams] -- i^th entry is team Xteam_list[Args['team'..N_teams]] = N_teams -- team X entry is position iend-- Optional totalslocal total_row_name = 'SPORTS_TABLE_TOTAL'if yesno(Args['show_totals'] or 'no') thenN_teams = N_teams+1Args['team' .. N_teams] = total_row_nameArgs['name_' .. total_row_name] = 'Total'Args['result' .. N_teams] = total_row_nameArgs['col_' .. total_row_name] = '#eee'team_list[N_teams] = Args['team' .. N_teams]team_list[Args['team'..N_teams]] = N_teamsend-- Show positionlocal position_col = yesno(Args['show_positions'] or 'yes') and true or false-- Show groups or notelocal group_col = yesno(Args['show_groups'] or 'no') and true or false-- Show match_table or notlocal match_table = yesno(Args['show_matches'] or 'no') and true or falselocal p_matches = match_table and (style_def == 'Chess' and require('Module:Sports results/'..style_def) or require('Module:Sports results'))-- Custom position column label or notelocal pos_label = Args['postitle'] or '<abbr title="Bà̤-miàng">Miàng</abbr>'if position_col == false then pos_label = nil end-- Show status or notlocal show_status = yesno(Args['show_status'] or 'yes') and true or false-- Get VTE button text (but only for non-empty text)local VTE_text = ''if (template_name ~= '') thenVTE_text = require('Module:Navbar')._navbar({template_name,mini=1,style='float:right',brackets=1})-- remove the next part if https://en.wikipedia.org/w/index.php?oldid=832717047#Sortable_link_disables_navbar_links?-- is ever fixedif yesno(Args['sortable_table'] or 'no') thenVTE_text = mw.ustring.gsub(VTE_text, '<%/?abbr[^<>]*>', ' ')endend-- Add source to title if specified and possiblelocal title_source = falseif Args['title'] and Args['title_source'] thenArgs['title'] = Args['title'] .. Args['title_source']title_source = trueelseif Args['table_header'] and Args['table_header_source'] thenArgs['table_header'] = Args['table_header'] .. Args['table_header_source']title_source = trueend-- Write column headerst_return = p_style.header(t,Args,p_sub,pos_label,group_col,VTE_text,full_table,results_header_txt)if match_table then-- Add empty column headert_return.count = t_return.count+1table.insert(t_return.tab_text,'! scope="row" class="unsortable" style="background-color:white;border-top:white;border-bottom:white;line-width:3pt;"| \n')-- Add rest of headert_return = p_matches.header(t_return,Args,p_sub,N_teams,team_list,tonumber(Args['legs']) or 1)endt = t_return.tab_textlocal N_cols = t_return.count-- Determine what entries go into table-- Find out which team to show (if any)local ii_show = team_list[Args['showteam'] or nil] -- nil if non-existant-- Start and end positions to showlocal n_to_show = tonumber(Args['show_limit']) or N_teams-- Check for "legal value", if not legal (or non declared), then show alllocal check_n = ((n_to_show>=(N_teams-top_pos+1)) or (n_to_show<=1) or (n_to_show~=math.floor(n_to_show)))-- Also check whether there is a valid ii_showif check_n or (not ii_show) thenii_start = top_posii_end = N_teamselse-- It's a proper integer between top_pos+1 and N_teams-1-- If it is in the middle show the same number above and below-- If it is in the top or bottom, show the exact number-- How many to show on the sidelocal n_show_side = math.floor(n_to_show/2)if (ii_show-top_pos+1)<=n_show_side then-- Top teamii_start = top_posii_end = top_pos+n_to_show-1elseif ii_show>=(N_teams+1-n_show_side) then-- Bottom teamii_start = N_teams+1-n_to_showii_end = N_teamselse-- Normal caseii_start = ii_show-n_show_sideii_end = ii_show+n_show_sideendend-- For results columnlocal new_res_ii = ii_start-- Pre-check for existence of columnif not hide_results thenfor ii = ii_start, ii_end doif Args[respre..'result'..ii] and Args[respre..'text_' .. Args[respre..'result'..ii]] then results_defined = true endendend-- Remove results header if it is unusedif full_table and not results_defined then-- First get it as one string, then use string replace to replace that header by empty stringlocal t_str = tostring(table.concat(t))t_str = mw.ustring.gsub( t_str, results_header_txt, '' )N_cols = N_cols-1 -- There is actually one column lesst = {}table.insert(t, t_str)end-- Write rowslocal team_name, team_code_ii, team_code_jj, pos_num, group_txt, note_locallocal note_string, note_local, note_local_num, note_idlocal note_id_list = {}local hth_id_list = {}for ii = ii_start, ii_end do-- First get codeteam_code_ii = team_list[ii]-- Now read valuespos_num = Args['pos_'..team_code_ii]or iigroup_txt = Args['group_'..team_code_ii]or ' 'team_name = Args['name_'..team_code_ii] or team_code_iinote_local = Args['note_'..team_code_ii] or nil-- Does it need a promotion/qualification/relegation taglocal result_local = Args[respre..'result'..ii] or nillocal bg_col = nil-- Get local background colourif result_local thenbg_col = result_col[Args[respre..'col_'..result_local]] or Args[respre..'col_'..result_local] or 'inherit'bg_col = 'background-color:'..bg_col..';' -- Full style tagendif not bg_col then bg_col = 'background-color:transparent;' end -- Becomes default if undefined-- Bold this line or notlocal ii_fw = ii == ii_show and 'font-weight: bold;' or 'font-weight: normal;'if yesno(Args['show_totals'] or 'no') and team_code_ii == total_row_name thenii_fw = 'font-weight: bold;'end-- Check whether there is a note or not, if so get text ready for itif note_local and full_table then-- Set global check for notes to truenotes_exist = true-- There are now 3 options for notes-- 1) It is a full note-- 2) It is a referal to another note (i.e. it's just a team code; e.g. note_AAA=Text, note_BBB=AAA) in which the note for BBB should link to the same footnote as AAA, with-- 2a) The other linked note exist in the part of the table shown-- 2b) The part of the note does not exist in the part of the table shownif not Args['note_'..note_local] then-- Option 1-- Now define the identifier for thisnote_id = '"table_note_'..team_code_ii..rand_val..'"' -- Add random end for unique ID if more tables are present on article (which might otherwise share an ID)note_id_list[team_code_ii] = note_id-- Call refn templatenote_string = frame:expandTemplate{ title = 'efn', args = { group='lower-alpha', name=note_id, note_local} }else -- Option 2-- It is option 2a in either one if either the main note is inside the sub-table-- or another ref to that note is inside the sub-table-- Basically when it either has been defined, or the main link will be in the tablenote_local_num = team_list[note_local]if note_id_list[note_local] or ((note_local_num >= ii_start) and (note_local_num <= ii_end)) then-- Option 2anote_id = '"table_note_'..note_local..rand_val..'"'note_string = frame:extensionTag{ name = 'ref', args = { group = 'lower-alpha', name = note_id} }else-- Option 2b-- Now define the identifier for thisnote_id = '"table_note_'..note_local..rand_val..'"' -- Add random end for unique IDnote_id_list[note_local] = note_id-- Call refn templatenote_string = frame:expandTemplate{ title = 'efn', args = { group='lower-alpha', name=note_id, Args['note_'..note_local]} }endendelsenote_string = '';end-- Insert status when neededlocal status_string = ''local status_local = show_status and Args[respre .. 'status_'..team_code_ii] or nillocal status_let_first = truelocal curr_letter-- Only if it is definedif status_local then-- Take it letter by letterfor jjj = 1,mw.ustring.len(status_local) docurr_letter = mw.ustring.upper(mw.ustring.sub(status_local,jjj,jjj))-- See whether it existif t_status.code[curr_letter] then-- Depending on whether it is the first letter of notif status_let_first thenstatus_string = curr_lettert_status.called[curr_letter] = truestatus_let_first = falseelsestatus_string = status_string..', '..curr_lettert_status.called[curr_letter] = trueendendend-- Only add brackets/dash and bolding if it existif not status_let_first then if t_status.position == 'before' thenstatus_string = '<span style="font-weight:bold">'..string.lower(status_string)..' –</span> ' elsestatus_string = ' <span style="font-weight:bold">('..status_string..')</span>' endendend-- Now build the rowsif yesno(Args['show_totals'] or 'no') and team_code_ii == total_row_name thentable.insert(t,'|- class="sortbottom"\n')-- New rowelsetable.insert(t,'|- \n')-- New rowendif position_col thentable.insert(t,'| style="text-align: center;'..ii_fw..bg_col..'"| '..pos_num..'\n')-- Position numberendif full_table and group_col thentable.insert(t,'| style="'..ii_fw..bg_col..'" |'..group_txt..'\n') -- Group number/nameend-- Build the team string order based on status positionlocal team_stringif t_status.position == 'before' thenteam_string = status_string..team_name..note_stringelseteam_string = team_name..note_string..status_stringendtable.insert(t,'! scope="row" style="text-align: left; white-space:nowrap;'..ii_fw..bg_col..'"| '..team_string..'\n')-- Team (with possible note)-- Call to subfunctiont_return = p_style.row(frame,t,Args,p_sub,notes_exist,hth_id_list,full_table,rand_val,team_list,team_code_ii,ii_start,ii_end,ii_fw,bg_col,N_teams,ii,ii_show)t = t_return.tnotes_exist = t_return.notes_existhth_id_list = t_return.hth_id_list-- Now check what needs to be added inside the results columnif full_table thenlocal res_jjjif ii == new_res_ii then-- First check how many rows you need for thisN_rows_res = 1jjj = ii+1result_local = Args[respre..'result'..ii] or ''local cont_loop = truewhile (jjj<=ii_end) and cont_loop doif Args['split'..tostring(jjj-1)] thencont_loop = falsenew_res_ii = jjjelseres_jjj = Args[respre..'result'..jjj] or ''if result_local == res_jjj then N_rows_res = N_rows_res+1 elsecont_loop = falsenew_res_ii = jjjendendjjj = jjj+1end-- Now create this field (reuse ii_fw and bg_col)-- Bold (if in range) or notif ii_show and (ii_show>=ii) and (ii_show<=(ii+N_rows_res-1)) thenii_fw = 'font-weight: bold;'elseii_fw = 'font-weight: normal;'end-- Get background colourbg_col = nilif Args[respre..'result'..ii] thenbg_col = result_col[Args[respre..'col_'..result_local]] or Args[respre..'col_'..result_local] or 'inherit'bg_col = 'background-color:'..bg_col..';' -- Full style tagendif not bg_col then bg_col = 'background-color:transparent;' end -- Becomes default if undefined-- Check for noteslocal note_res_string, note_ref, note_text = '', '', ''if Args['note_res_'..result_local] thennotes_exist = truelocal note_res_local = Args['note_res_'..result_local]-- Split the note_res_local into a table if all the entries are validlocal multiref = 1local note_res_local_table = mw.text.split(note_res_local, '%s*,%s*')if (#note_res_local_table > 1) thenfor k, note_res_loc in ipairs(note_res_local_table) domultiref = multiref * (Args['note_res_' .. note_res_loc] and 1 or 0)endelsemultiref = 0end-- Split failed, so make a single entry table with hth_local insideif multiref < 1 thennote_res_local_table = { note_res_local }endfor k,note_res_local in ipairs(note_res_local_table) doif not Args['note_res_'..note_res_local] then-- It does not point to another result notenote_ref = respre..'res_'..result_localnote_id = '"table_note_res_'..result_local..rand_val..'"' -- Identifiernote_text = note_res_localelse-- It does point to another result notenote_ref = respre..'res_'..note_res_localnote_id = '"table_note_res_'..note_res_local..rand_val..'"' -- Identifiernote_text = Args['note_res_'..note_res_local]end-- Check whether it is already printedif not note_id_list[note_ref] then-- Print itnote_id_list[note_ref] = note_idnote_res_string = note_res_string .. frame:expandTemplate{ title = 'efn', args = { group='lower-alpha', name=note_id, note_text} }else-- Refer to itnote_res_string = note_res_string .. frame:extensionTag{ name = 'ref', args = { group = 'lower-alpha', name = note_id} }endendend-- Get textlocal text_result = Args[respre..'text_'..result_local] or ''if text_result:match('fbmulticomp') thenii_fw = 'padding:0;' .. ii_fwif text_result:match('fbmulticompefn') thennotes_exist = trueendendtext_field_result = '| style="'..ii_fw..bg_col..'" rowspan="'..tostring(N_rows_res)..'" |'..text_result..note_res_string..'\n'-- See whether it is needed (only when blank for all entries)if results_defined then table.insert(t,text_field_result) endendend-- Insert match row if neededif match_table thenlocal legs = tonumber(Args['legs']) or 1-- Add empty celltable.insert(t,'| style="background-color:white;border-top:white;border-bottom:white;"| \n')-- Now include note to match results if needed for jj=top_pos,N_teams doteam_code_jj = team_list[jj]if ii == jj then-- Nothingelsefor l=1,legs dolocal m = (legs == 1) and 'match_' or 'match' .. l .. '_'local match_note = Args[m..team_code_ii..'_'..team_code_jj..'_note']if match_note thennotes_exist = true-- Only when it exist-- First check for existence of reference for noteif not (Args['note_'..match_note] or Args[m..match_note..'_note']) then-- It's the entrynote_id = '"table_note_'..team_code_ii..'_'..team_code_jj..rand_val..'"' -- Add random end for unique ID if more tables are present on article (which might otherwise share an ID)note_id_list[team_code_ii..'_'..team_code_jj] = note_idnote_string = frame:expandTemplate{ title = 'efn', args = { group='lower-alpha', name=note_id, match_note} }else -- Check for existence elsewherenote_local_num = team_list[match_note] or ii_end + 1if note_id_list[match_note] or ((note_local_num >= ii_start) and (note_local_num <= ii_end)) then-- It existsnote_id = '"table_note_'..match_note..rand_val..'"' -- Identifiernote_string = frame:extensionTag{ name = 'ref', args = { group = 'lower-alpha', name = note_id} }else-- Now define the identifier for thisnote_id = '"table_note_'..match_note..rand_val..'"' -- Add random end for unique IDnote_id_list[match_note] = note_id-- Call refn templatenote_string = frame:expandTemplate{ title = 'efn', args = { group='lower-alpha', name=note_id, Args['note_'..match_note]} }endend-- Now append this to the match result stringArgs[m..team_code_ii..'_'..team_code_jj] = (Args[m..team_code_ii..'_'..team_code_jj] or '')..note_stringendendendend-- Add rest of match rowt = p_matches.row(t,Args,N_teams,team_list,ii,ii_show,legs)end-- Now, if needed, insert a split (solid line to indicate split in standings, but only when it is not at the last shown position)if Args['split'..ii] and (ii<ii_end) then-- Base size on N_cols (it needs 2*N_cols |)table.insert(t,'|- style="background-color:'..result_col['black1']..'; line-height:3pt;"\n')table.insert(t,string.rep('|',2*N_cols)..'\n')endend-- Close tabletable.insert(t, '|}')-- Get info for footerlocal update = Args['update']or 'unknown'local start_date = Args['start_date'] or 'unknown'local source = Args['source']or (title_source == true and '')or frame:expandTemplate{ title = 'citation needed', args = { reason='No source parameter defined', date=os.date('%B %Y') } }local class_rules = Args['class_rules']or nil-- Create footer text-- Date updatinglocal matches_text = Args['matches_text'] or 'match(es)'if string.lower(update)=='complete' then-- Do nothingelseif update=='' then-- Empty parametertable.insert(t_footer,'Updated to '..matches_text..' played on unknown. ')elseif string.lower(update)=='future' then-- Future start datetable.insert(t_footer,'First '..matches_text..' will be played on '..start_date..'. ')elsetable.insert(t_footer,'Updated to '..matches_text..' played on '..update..'. ')end-- Stack footer or notlocal footer_break = yesno(Args['stack_footer'] or 'no') and true or false-- Variable for linebreaklocal stack_string = '<br>'if footer_break and (not (string.lower(update)=='complete')) then table.insert(t_footer,stack_string) endif source ~= '' thentable.insert(t_footer,'Cṳ̆-lâiu: '..source)endif class_rules and full_table and show_class_rules thenif (#t_footer > 0) then table.insert(t_footer,'<br>') endtable.insert(t_footer,'Rules for classification: '..class_rules)end-- Now for the named statuslocal status_exist = falselocal status_string = ''local curr_letterfor jjj = 1,mw.ustring.len(t_status.letters) docurr_letter = mw.ustring.upper(mw.ustring.sub(t_status.letters,jjj,jjj))if t_status.called[curr_letter] thenif (footer_break and status_exist) thenstatus_string = status_string..stack_stringendif t_status.position == 'before' thenstatus_string = status_string..'<span style="font-weight:bold">'..string.lower(curr_letter)..' –</span> '..t_status.code[curr_letter]..'; 'elsestatus_string = status_string..'<span style="font-weight:bold">('..curr_letter..')</span> '..t_status.code[curr_letter]..'; 'endstatus_exist = trueendend-- Now if it contains entries the '; ' needs to be removedif status_exist thenif (#t_footer > 0) then table.insert(t_footer,'<br>') endstatus_string = mw.ustring.sub(status_string,1,mw.ustring.len(status_string)-2)table.insert(t_footer,status_string)end-- Add notes (if applicable)if notes_exist thenif (#t_footer > 0) then table.insert(t_footer,'<br>') endtable.insert(t_footer,'Notes:')-- As reflist size textt_footer = '<div class="sports-table-notes">'..table.concat(t_footer)..'</div>'t_footer = t_footer..frame:expandTemplate{ title = 'notelist', args = { group='lower-alpha'} }else-- As reflist size textt_footer = '<div class="sports-table-notes">'..table.concat(t_footer)..'</div>'end-- Add footer to main text tabletable.insert(t,t_footer)-- Rewrite anchor linksfor k=1,#t doif t[k]:match('%[%[#[^%[%]]*%|') thent[k] = mw.ustring.gsub(t[k], '(%[%[)(#[^%[%]]*%|)', '%1' .. baselink .. '%2')endend-- Generate trackingif not Args['notracking'] thenlocal getTracking = require('Module:Sports table/argcheck').checklocal warning_categories, tracking_categories = getTracking(Args, frame:getParent().args)if #warning_categories > 0 thenif frame:preprocess( "{{REVISIONID}}" ) == "" thenfor k=1,#warning_categories dowarning_categories[k] = mw.ustring.gsub(warning_categories[k], '^%[%[Category:Pages using sports table with (.*)|(.*)%]%]$', '<div style="color:red">Warning: %1 = %2</div>')endendendfor k=1,#warning_categories dotable.insert(t, warning_categories[k])endfor k=1,#tracking_categories dotable.insert(t, tracking_categories[k])endif(Args['showteam'] == nil) thenlocal getWarnings = require('Module:Sports table/totalscheck').checklocal total_warnings = getWarnings(Args, team_list, ii_start, ii_end)if #total_warnings > 0 thenif frame:preprocess( "{{REVISIONID}}" ) == "" thenfor k=1,#total_warnings dotable.insert(t, '<div style="color:green">Possible problem: ' .. total_warnings[k] .. '</div>')endendendendelsetable.insert(t, '[[Category:Pages using sports table with notracking]]')endif Args['float'] thenreturn frame:expandTemplate{ title = 'stack begin', args = {clear = 'true', margin = '1', float = Args['float']} }.. templatestyles .. '\n' .. table.concat(t) .. frame:expandTemplate{ title = 'stack end'}endreturn templatestyles .. '\n' .. table.concat(t)end return p
🔥 Top keywords: