Module:Sandbox/Blippy1998
local p = {}
-- Helper to mimic PHP's explode(delimiter, string, 2)
local function split_once(str, delimiter)
local pos = mw.ustring.find(str, delimiter, 1, true)
if pos then
return mw.ustring.sub(str, 1, pos - 1), mw.ustring.sub(str, pos + mw.ustring.len(delimiter))
end
return str, nil
end
function p.parseTablesToData(text)
local lines = mw.text.split(text, "\n")
local parsed_data = {}
local current_table = nil
local current_row = nil
for _, outLine in ipairs(lines) do
local line = mw.text.trim(outLine)
-- Equivalent to skipping via 'continue'
if line ~= '' then
local first_char = mw.ustring.sub(line, 1, 1)
local first_two = mw.ustring.sub(line, 1, 2)
local indent_match, attributes_match = mw.ustring.match(line, "^(:*)%s*%{%|(.*)$")
if indent_match then
-- Start a new table
current_table = {
attributes = mw.text.unstrip(attributes_match),
rows = {}
}
table.insert(parsed_data, current_table)
current_row = nil
elseif not current_table then
-- Not inside a table, do nothing (skip)
elseif first_two == '|}' then
-- End the current table
current_table = nil
current_row = nil
elseif first_two == '|-' then
-- Start a new row
line = mw.ustring.gsub(line, "^|%-+", "")
current_row = {
attributes = mw.text.unstrip(line),
cells = {}
}
table.insert(current_table.rows, current_row)
elseif first_char == '|' or first_char == '!' or first_two == '|+' then
-- Process cells, headers, or captions
-- Handle implicit rows (if cell data appears before a |- tag)
if not current_row and first_two ~= '|+' then
current_row = { attributes = "", cells = {} }
table.insert(current_table.rows, current_row)
end
if first_two == '|+' then
first_char = '+'
line = mw.ustring.sub(line, 3)
current_table.caption = mw.text.trim(mw.text.unstrip(line))
else
line = mw.ustring.sub(line, 2)
if first_char == '!' then
line = mw.ustring.gsub(line, "!!", "||")
end
local cells = mw.text.split(line, "||", true)
for _, cell_str in ipairs(cells) do
local cell_type = (first_char == '!') and "th" or "td"
local cell_attr_str, cell_content_str = split_once(cell_str, "|")
local cell_obj = {
type = cell_type,
attributes = "",
content = ""
}
-- Replicate PHP's logic to check for [[ links or -{ language converter tags
-- to ensure a pipe inside a link isn't mistaken for an attribute delimiter.
if not cell_content_str or mw.ustring.match(cell_attr_str, "%[%[") or mw.ustring.match(cell_attr_str, "%-%{") then
cell_obj.content = mw.text.trim(cell_str)
else
cell_obj.attributes = mw.text.unstrip(cell_attr_str)
cell_obj.content = mw.text.trim(cell_content_str)
end
table.insert(current_row.cells, cell_obj)
end
end
end
end
end
return parsed_data
end
function p.testLoadPage(frame)
-- 1. Define the page title to load.
-- Note: Testing this on the full US Reps page immediately will yield a massive dump string.
-- I recommend creating a subpage with a small test table first.
local page_title = "List of current United States representatives#List of representatives"
local titleObj = mw.title.new(page_title)
if not titleObj then return "Error: Invalid title." end
-- 2. Fetch the raw wikitext
local content = titleObj:getContent()
if not content then return "Error: Page not found or empty." end
-- 3. Run the parser
local parsed_data = p.parseTablesToData(content)[6]
-- 4. Dump the resulting Lua table as a preformatted string so you can read the structure
return "<pre>\n" .. mw.dumpObject(parsed_data) .. "\n</pre>"
end
function p.tallyParties(frame)
-- 1. Load the page and parse the text
local page_title = "List of current United States representatives#List of representatives"
local titleObj = mw.title.new(page_title)
if not titleObj then return "Error: Invalid title." end
local content = titleObj:getContent()
if not content then return "Error: Page not found or empty." end
local parsed_data = p.parseTablesToData(content)[6]
if not parsed_data then return "Error: Table not found." end
-- 2. Build a dynamic column map from the header row
local column_map = {}
local current_col = 1
local header_row = parsed_data.rows[1]
for _, cell in ipairs(header_row.cells) do
-- Clean the header text (removes <ref> tags and hidden spans)
local header_text = mw.ustring.gsub(cell.content, "<[^>]+>", "")
header_text = mw.text.trim(header_text)
-- Check if this header spans multiple columns (e.g., colspan=2)
local colspan = 1
local colspan_match = mw.ustring.match(cell.attributes, "colspan%s*=%s*[\"']?(%d+)[\"']?")
if colspan_match then
colspan = tonumber(colspan_match)
end
column_map[header_text] = {
start_index = current_col,
span = colspan,
-- For Party, the text name is in the right-most cell of the span
end_index = current_col + colspan - 1
}
current_col = current_col + colspan
end
-- Abort if we can't find the Party column
if not column_map["Party"] then return "Error: Could not find 'Party' column." end
-- Extract the exact index we need to check in the data rows
local party_col_index = column_map["Party"].end_index
-- 3. Initialize the tally counters
local tallies = {
Democratic = 0,
Republican = 0,
Independent = 0,
Vacant = 0
}
-- 4. Iterate through the data rows
for i = 2, #parsed_data.rows do
local row = parsed_data.rows[i]
local cells = row.cells
if #cells > 0 then
-- Check for vacant seats (vacant rows use a massive colspan, yielding fewer cells)
if #cells < party_col_index then
assert(#cells == 2, "Row had " .. #cells .. " cells. Expected 2.")
assert(cells[2].content == "''Vacant''", "Expected ''Vacant'', got: " .. tostring(cells[2].content))
tallies.Vacant = tallies.Vacant + 1
else
-- 5. Extract the party using the dynamic index
local party = cells[party_col_index].content
party = mw.ustring.gsub(party, "<[^>]+>", "")
party = mw.text.trim(party)
if tallies[party] ~= nil then
tallies[party] = tallies[party] + 1
else
tallies[party] = 1
end
end
end
end
-- 6. Format the output
local output = "'''Current House Tallies:'''\n"
output = output .. "* Democratic: " .. tallies.Democratic .. "\n"
output = output .. "* Republican: " .. tallies.Republican .. "\n"
output = output .. "* Independent: " .. tallies.Independent .. "\n"
output = output .. "* Vacant: " .. tallies.Vacant .. "\n"
return output
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.