模块:Wikitable.lua:修订间差异
来自「荏苒之境」
无编辑摘要 |
无编辑摘要 |
||
第7行: | 第7行: | ||
local BYTE_SEPARATOR = string.byte('|') | local BYTE_SEPARATOR = string.byte('|') | ||
local BYTE_EXCLAMATION = string.byte('!') | local BYTE_EXCLAMATION = string.byte('!') | ||
local BYTE_ADD = string.byte('+') | |||
local BYTE_MINUS = string.byte('-') | local BYTE_MINUS = string.byte('-') | ||
第50行: | 第51行: | ||
while true do | while true do | ||
local b = string.byte(str, pos) | local b = string.byte(str, pos) | ||
if b == | if b == BYTE_SEPARATOR or b == BYTE_EXCLAMATION then | ||
break | break | ||
elseif b == nil then | elseif b == nil then | ||
pos = nil | pos = nil | ||
break | break | ||
elseif b ~= BYTE_ENTER then | |||
bytes[#bytes+1] = b | bytes[#bytes+1] = b | ||
end | end | ||
pos = pos + 1 | pos = pos + 1 | ||
end | |||
if bytes[#bytes] == BYTE_NEWLINE then | |||
bytes[#bytes] = nil | |||
end | end | ||
第67行: | 第70行: | ||
elseif head == BYTE_SEPARATOR then | elseif head == BYTE_SEPARATOR then | ||
local fst_byte = bytes[1] | local fst_byte = bytes[1] | ||
if fst_byte == BYTE_MINUS then | if fst_byte == BYTE_ADD then | ||
return pos, " | return pos, "header_start" | ||
elseif fst_byte == BYTE_MINUS then | |||
return pos, "row_start" | |||
elseif fst_byte == BYTE_CLOSE_CURLY then | elseif fst_byte == BYTE_CLOSE_CURLY then | ||
return pos, "table_end" | return pos, "table_end" | ||
第92行: | 第97行: | ||
if cell_type == "header" then | if cell_type == "header" then | ||
header[#header+1] = cell_content | header[#header+1] = cell_content | ||
elseif cell_type == " | elseif cell_type == "row_start" then | ||
if curr_row ~= nil then | |||
if curr_row then | |||
rows[#rows+1] = curr_row | rows[#rows+1] = curr_row | ||
end | end | ||
curr_row = {} | curr_row = {} | ||
elseif cell_type == "table_end" then | |||
if curr_row ~= nil then | |||
rows[#rows+1] = curr_row | |||
end | end | ||
break | |||
elseif cell_type == "text" then | |||
if curr_row == nil then | if curr_row == nil then | ||
curr_row = {} | curr_row = {} |
2025年8月6日 (三) 00:54的版本
此模块的文档可以在模块:Wikitable.lua/doc创建
local unpack = unpack or table.unpack
local BYTE_ENTER = string.byte('\r')
local BYTE_NEWLINE = string.byte('\n')
local BYTE_OPEN_CURLY = string.byte('{')
local BYTE_CLOSE_CURLY = string.byte('}')
local BYTE_SEPARATOR = string.byte('|')
local BYTE_EXCLAMATION = string.byte('!')
local BYTE_ADD = string.byte('+')
local BYTE_MINUS = string.byte('-')
local wikitable = {}
local function skip_to_next_line(str, pos)
while true do
local b = string.byte(str, pos)
if b == BYTE_NEWLINE or b == BYTE_ENTER then
return pos + 1
elseif b == nil then
return nil
end
pos = pos + 1
end
end
local function find_character(str, pos, cbyte)
while true do
local b = string.byte(str, pos)
if b == cbyte then
return pos
elseif b == nil then
return nil
end
pos = pos + 1
end
end
local function find_table_start(str, pos)
pos = find_character(str, pos, BYTE_OPEN_CURLY)
if pos == nil then return nil end
pos = find_character(str, pos, BYTE_SEPARATOR)
if pos == nil then return nil end
return pos + 1
end
local function parse_cell(str, pos)
local head = string.byte(str, pos)
pos = pos + 1
local bytes = {}
while true do
local b = string.byte(str, pos)
if b == BYTE_SEPARATOR or b == BYTE_EXCLAMATION then
break
elseif b == nil then
pos = nil
break
elseif b ~= BYTE_ENTER then
bytes[#bytes+1] = b
end
pos = pos + 1
end
if bytes[#bytes] == BYTE_NEWLINE then
bytes[#bytes] = nil
end
if head == BYTE_EXCLAMATION then
return pos, "header", string.char(unpack(bytes))
elseif head == BYTE_SEPARATOR then
local fst_byte = bytes[1]
if fst_byte == BYTE_ADD then
return pos, "header_start"
elseif fst_byte == BYTE_MINUS then
return pos, "row_start"
elseif fst_byte == BYTE_CLOSE_CURLY then
return pos, "table_end"
else
return pos, "text", string.char(unpack(bytes))
end
end
end
wikitable.parse = function(str)
local header = {}
local rows = { header = header }
local curr_row
local pos = find_table_start(str, 1)
if pos == nil then return rows end
pos = skip_to_next_line(str, pos)
local cell_type, cell_content
while pos ~= nil do
pos, cell_type, cell_content = parse_cell(str, pos)
if cell_type == "header" then
header[#header+1] = cell_content
elseif cell_type == "row_start" then
if curr_row ~= nil then
rows[#rows+1] = curr_row
end
curr_row = {}
elseif cell_type == "table_end" then
if curr_row ~= nil then
rows[#rows+1] = curr_row
end
break
elseif cell_type == "text" then
if curr_row == nil then
curr_row = {}
end
curr_row[#curr_row+1] = cell_content
end
end
return rows
end
return wikitable