--[[nef_20221122 PARSER The function log.bb_iterate returns the three values used for iteration. The arguments: 1. The string to be parsed. 2. First index into the string. Typically 0 (or nil). Default nil. Returning values for the iteration function: 1. The next index into the string. Will be nil if the string is exhausted. 2. The preamble text (the text before the bbcode). Null string if there is none. 3. The bbcode in table form. This will be nil if the string is terminating with text. The bbcode table contains the following fields: bb: bbcode - see the table bb_alias for valid codes open: bb is the first (or only) part of a bbcode sequence (boolean) close: bb is the second (or only) part of a bbcode sequence (boolean) options: table containing fields in the form (key, value): (option identifier, option value) the valid identifiers are listed in the table keywords; the value will be a string or number depending on the identifier. The table log.bb_alias is also included for convenience. -]] do -- PARSER local function get_string(arg_text, current) local Start, End, arg = arg_text: find('(%b"")%s*', current) if arg then return arg: gsub('"',''), End end end local function get_num (arg_text, current) local Start, End, arg = arg_text: find('(%d+)%s*', current) if arg then return tonumber(arg), End end end local keywords = setmetatable( { name = get_string; foreground = get_string; background = get_string; target = get_string; fg = get_string; bg = get_string; tgt = get_string; id = get_num; x = get_num; y = get_num; }, { __index = function () return function () end end; }) local bb_forms = { "%[%s*%/%s*(%a%w*)%s*(.-)%s*%]"; -- 1 close "%[%s*(%a%w*)%s*(.-)%s*%/%s*%]"; -- 2 both "%[%s*(%a%w*)%s*(.-)%s*%]"; -- 3 open } local function get_arg (arg_text) -- upvalue keywords local P1, args = 0, {} while P1 and P1 < #arg_text do local S, P2, key = arg_text: find("(%a%w*)%s*=%s*", P1 +1) if P2 and P2 < #arg_text then args [key], P2 = keywords [key] (arg_text, P2 +1) else P2 = nil end if P2 then P1 = P2 else S, P1 = arg_text: find("^%s+%s*", P1 +1) end end; return P1 or #arg_text, args end -- get_arg end local _ENV = _ENV _ENV = log bb_alias = { bold = 'b';underline = 'u';italic = 'i'; strike = 's';color ='c';link = 'l'; b = 'b';u = 'u';i = 'i'; s = 's';c ='c';l = 'l'; } function bb_iterate(text, P0) return function (text, P0) -- upvalue alias, bb_forms, get_arg if P0 < #text then local current = P0 +1 local Start, End, bb_text = text: find(".-(%b[])", current) if Start then for form = 1,3 do local S, E, bbcode, arg_text = bb_text: find(bb_forms [form]) if bbcode and bb_alias [bbcode] then local P1, args = get_arg (arg_text) return End, text: sub(current, current + P1), {bb = bbcode, open = form > 1, close = form < 3, options = args} end end end return #text, text: sub(current) -- , nil (no bbcode at end) end end, text, P0 or 0 end end ----------- end PARSER