Module:Footnotes/whitelist/sort explained

----------------------------< U N S O R T E D _ A D D >------------------------------------------------------

add members of the unsorted list based on first character(upper or lower case) following 'CITEREF'. If is longer than one character (ODNB, UNSORTED, whatever), return without making any additions

local function unsorted_add (index, unsorted, temp) local pattern;

if 1 < index:len and 'OTHER' ~= index then -- only add citerefs to the single-character lists return; end

if '#'

index then pattern = '%[\'CITEREF%d'; -- first character is a digit else pattern = '%[\'CITEREF[' .. index .. index:lower .. ']'; end for k, v in pairs (unsorted) do -- spin through the unsorted listing if not k:match ('CITEREF') then -- must have 'CITEREF' return 'malformed key: ' .. k; -- return an error message end if v and k:match (pattern) and 'OTHER' ~= index then -- if not nil and matches the pattern temp[k] = true; -- add to the alpha listing unsorted[k] = nil; -- and then disable this one in the unsorted listing end if v and 'OTHER'

index then -- if not nil and OTHER index if mw.ustring.match (k, '%[\'CITEREF%a') then temp[k] = true; -- add to the OTHER listing unsorted[k] = nil; -- and then disable this one in the unsorted listing end end endend

----------------------------< L I S T _ P A R S E >----------------------------------------------------------

parse apart plain-text list of a key / value pair into a table where the plain-text k/v becomes the key in a luatable with the assigned value true. Do this to catch multiples of the same k/v and to support the easy insertionof k/v pairs from the unsorted list.

also normalize k/v format

local function list_parse (index, list, temp) for citeref in list[index]:gmatch ('\t*([^\r\n]+)') do citeref = mw.text.trim (citeref); citeref = citeref:gsub (' *%[*\' *', '[\''); -- normalize opening sq brackets citeref = citeref:gsub (' *\' *%] *', '\']'); -- normalize closing sq brackets citeref = citeref:gsub (' *'); -- normalize closing braces citeref = citeref:gsub ('([%]}]) *, *', '%1,'); -- normalize trailing comma citeref = citeref:gsub (' *= *', ' = '); -- normalize assignment operator if not temp[citeref] then temp[citeref] = true; -- a constant value so that we can know if the 'key' already exists (avoid duplication) end endend

--

local function whitelist_sort(frame) local headers = ; -- headings are stored here and used for loop control local list = -- table of tables of the plain-text citerefs local unsorted = ; -- table of k/v pairs where k is the unsorted citerefs and v is true or nil (after added to alpha list) local result = ; -- sorted and formatted section end up here local temp, temp2 =, ;

local content = mw.title.new('Module:Footnotes/whitelist'):getContent; -- read the module plain text local find_pattern = '%s*local%s+whitelist%s+=%s+'; -- find the whitelist table local tstart, tend = content:find (find_pattern);

content = content:match ('%b', tstart); -- get the content of the whitelist table content = content:gsub ('^$', ); -- remove whitespace and terminal brace

for header in content:gmatch ('%-+<([#%a%d%s]+)>%-+') do -- get pseudo-headers table.insert (headers, mw.text.trim (header)); -- save the captures in the headers table end

for i, header in ipairs (headers) do -- separate whitelist entries into individual alpha groupings local pattern = '%-+<%s*' .. header .. '%s*>%-+'; tstart, tend = content:find (pattern); -- find this header if tstart and headers[1+i] then -- if not the last header list[header] = mw.text.trim (content:match ('([^<]-)%-+<', tend+1)); -- begin at end of header; +1 to leave-off the last '-' in the header elseif tstart then -- must be the last header (usually UNSORTED) list[header] = mw.text.trim (content:match ('.*', tend+1)); -- begin at end of header; +1 to leave-off the last '-' in the header else error ('shouldn\'t be here; header: ' .. header or '(nil or empty string)' .. '; tstart: ' .. tstart or '(nil or empty string)'); end end

list_parse ('UNSORTED', list, unsorted); -- make a separate unsorted list list['UNSORTED'] = ; -- blank the unsorted source

for i, v in ipairs (headers) do temp, temp2 =, ; -- reinit temp & temp2

list_parse (v, list, temp); -- parse the list local err_msg; err_msg = unsorted_add (v, unsorted, temp); -- then add appropriate citerefs from the unsorted list if err_msg then return err_msg; end

for k, v in pairs (temp) do -- get 'key' value from temp and make a sequence from it in temp2 so it can be sorted if v then table.insert (temp2, k); -- unsorted listing gets 'emptied' by setting v nil; don't add nil citerefs to temp2 end end table.sort (temp2); -- sort this section table.insert (result, '----------< ' .. v .. ' >----------\n\t' .. table.concat (temp2, '\n\t') .. '\n\n'); -- add a header, make a long string, and add to result end

return frame:extensionTag ;end

---------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------

return