Capefeather (talk | contribs) (revert) |
Capefeather (talk | contribs) No edit summary |
||
Line 58: | Line 58: | ||
if string.sub(wikitable, pos, pos + string.len(str) - 1) == str then |
if string.sub(wikitable, pos, pos + string.len(str) - 1) == str then |
||
for n = 1, rows(wikitable) do |
for n = 1, rows(wikitable) do |
||
− | if n > pos then |
+ | if rowP[n] > pos then |
if newCol == 0 then |
if newCol == 0 then |
||
− | return n - 1 |
+ | return rowP[n - 1] |
else |
else |
||
rowContent = fetchOneRow(wikitable, n - 1) |
rowContent = fetchOneRow(wikitable, n - 1) |
||
colP = columnPositions(rowContent) |
colP = columnPositions(rowContent) |
||
for m = 1, columns(rowContent) do |
for m = 1, columns(rowContent) do |
||
− | if m > pos and m - 1 == newCol then |
+ | if colP[m] > pos and colP[m - 1] == newCol then |
− | return m - 1 |
+ | return colP[m - 1] |
end |
end |
||
end |
end |
Revision as of 21:11, 8 June 2020
Module for searching and manipulating wikitables.
-- Module for searching and manipulating wikitables.
local p = {}
local function delimiterPositions(wikitable, delimiter, ender)
-- Gets the positions and number of instances of a delimiter in a table's wikitext. By "position", we mean that, for example, the letter "e" in "hello" is in position 2, and the pattern "ll" in "hello" is in position 3.
local positions = {}
local index = 1
for pos = 1, string.len(wikitable) - 1 do
if string.sub(wikitable, pos, pos + string.len(delimiter) - 1) == delimiter then
positions[index] = pos
index = index + 1
elseif string.sub(wikitable, pos, pos + string.len(ender) - 1) == ender then
positions[index] = pos
break
end
end
return {positions, index - 1}
end
local function rowPositions(wikitable)
-- Gets the positions of instances of the row delimiter |- in a table's wikitext.
return delimiterPositions(wikitable, "|-", "|}")[1]
end
local function rows(wikitable)
-- Gets the number of rows in a table's wikitext.
return delimiterPositions(wikitable, "|-", "|}")[2]
end
local function fetchRows(wikitable, firstRow, lastRow)
-- Gets the contents of the rows between firstRow and lastRow inclusively. For example, fetchRows(wikitable, 3, 7) returns rows 3, 4, 5, 6, and 7 of the table.
local rowP = rowPositions(wikitable)
return string.sub(wikitable, rowP[firstRow], rowP[lastRow + 1])
end
local function fetchOneRow(wikitable, row)
-- Gets the contents of a single row.
return fetchRows(wikitable, row, row)
end
local function columnPositions(rowText)
-- Gets the positions of instances of the column delimiter | in a table row's wikitext.
return delimiterPositions(rowtext, "|", "$")[1]
end
local function columns(rowtext)
-- Gets the number of columns in a table's wikitext.
return delimiterPositions(rowtext, "|", "$")[2]
end
local function findFirstRow(wikitable, str, col)
newCol = col or 0
rowP = rowPositions(wikitable)
for pos = 1, string.len(wikitable) - 1 do
if string.sub(wikitable, pos, pos + string.len(str) - 1) == str then
for n = 1, rows(wikitable) do
if rowP[n] > pos then
if newCol == 0 then
return rowP[n - 1]
else
rowContent = fetchOneRow(wikitable, n - 1)
colP = columnPositions(rowContent)
for m = 1, columns(rowContent) do
if colP[m] > pos and colP[m - 1] == newCol then
return colP[m - 1]
end
end
end
end
end
end
end
return 0
end
local function columns(wikitable)
-- Gets the names of the columns.
names = {}
posTable = delimiterPositions(wikitable, "!", "|-")
for n = 1, posTable[2] do
names[n] = string.sub(wikitable, posTable[1][n] + 1, posTable[1][n + 1] - 1)
end
return names
end
function p.partialTable(frame)
-- Constructs a subtable of the given table containing the specified range of rows. For example, {{#invoke:table|partialTable|(table)|3|7}} produces a table using rows 3-7 of the original table.
local wikitable = frame.args[1]
local rowP = rowPositions(wikitable)
local length = rows(wikitable)
local firstRow = math.max(frame.args[2], 1) or 1
local lastRow = math.min(frame.args[3], length) or length
local header = string.sub(wikitable, 1, rowP[1] - 1)
local body = fetchRows(wikitable, firstRow, lastRow)
return header .. body .. "}"
end
function p.conditionalPartialTable(frame)
-- Like p.partialTable but with row ranges specified using table contents. Usage: {{#invoke:table|conditionalPartialTable|(table)|first=|last=|col=(column number (optional))}}
-- For example, {{#invoke:table|conditionalPartialTable|(table)|1970|1980|col=1}} finds the first row where column 1 contains 1970 and the first row where column 1 contains 1980, and produces a table using all the rows in between except the row containing 1980.
local wikitable = frame.args[1]
local rowP = rowPositions(wikitable)
local length = rows(wikitable)
local firstRow = findFirstRow(wikitable, frame.args["first"], frame.args["col"]) or findFirstRow(wikitable, frame.args["first"]) or 1
local lastRow = findFirstRow(wikitable, frame.args["last"], frame.args["col"]) or findFirstRow(wikitable, frame.args["last"]) or length
lastRow = lastRow - 1
local header = string.sub(wikitable, 1, rowP[1] - 1)
local body = fetchRows(wikitable, firstRow, lastRow)
return header .. body .. "}"
end
return p
--[[Category:Modules]]