--% Kale Ewasiuk (kalekje@gmail.com) --% 2022-04-16 --% Copyright (C) 2021-2022 Kale Ewasiuk --% --% Permission is hereby granted, free of charge, to any person obtaining a copy --% of this software and associated documentation files (the "Software"), to deal --% in the Software without restriction, including without limitation the rights --% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --% copies of the Software, and to permit persons to whom the Software is --% furnished to do so, subject to the following conditions: --% --% The above copyright notice and this permission notice shall be included in --% all copies or substantial portions of the Software. --% --% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF --% ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED --% TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A --% PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT --% SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR --% ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN --% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE --% OR OTHER DEALINGS IN THE SOFTWARE. local ap = {} -- module table function ap.rtrim(s) return (s:gsub("^(.-)%s*$", "%1")) end ap.punc = {} ap.punc = {'.', '; and'} -- punctuation table, 1 is last val, 2 is 2nd last val ap.punc[0] = ';' -- [0] is default punctuation ap.total = 0 -- total num of items (int) ap.curr = 0 -- current item we're on (int) ap.itemp = '\9' -- temporary item, item which WILL be affected by autopunc ap.item = '\\item' -- item ap.omit = '\\APomit' -- flag for hiding an item from punc and count, acts as if item is not there ap.pass = '\\APpass' -- flag for passing item from punc, but still considered in count ap.code = 0 -- code for skipping punc if > 0, keep in count if == 1, omit from count if == 2 ap.autopassnested = true ap.skipnextprot = false function ap.start(s) ap.curr = 0 _, ap.total = s:gsub(ap.itemp, '') local _, omit = s:gsub(ap.omit, '') ap.total = ap.total - omit end function ap.setcode(s) local _, code1 = s:gsub(ap.pass, '', 1) local _, code2 = s:gsub(ap.omit, '', 1) ap.code = code1 + 2*code2 end function ap.addcount(s) ap.setcode(s) if ap.code < 2 then -- if not omitting, we still keep counter going ap.curr = ap.curr + 1 -- increment counter end end function ap.getdelim() local d = '' if ap.code == 0 then -- d limiter -- if not passing look at punctuation table for delimiter d = ap.punc[ap.total-ap.curr+1] or ap.punc[0] end return d end function ap.protectnest(s) local x = '' if ap.autopassnested then x = ap.pass..'{}' end s = s:gsub("\0", "\0", 0) -- dummy replacement to make code easier :gsub("\\begin%s*{itemize}", x.."\1%0") -- pad \1 and \2 in inner envirnments :gsub("\\end%s*{itemize}", "%0\2") :gsub("\\begin%s*{enumerate}", x.."\1%0") :gsub("\\end%s*{enumerate}", "%0\2") :gsub("\\begin%s*{description}", x.."\1%0") :gsub("\\end%s*{description}", "%0\2") :gsub("%b\1\2", "\0%0\0") -- use bracket to place \0 (on OUTER) nested lists only :gsub("(%Z*)%z?(%Z*)%z?", -- only affect matches outside list function(a, b) return a:gsub(ap.item, ap.itemp)..b:gsub("[\1\2]", "") end) return s end function ap.go(s) if ap.skipnextprot then s = s:gsub(ap.item, ap.itemp) else s = ap.protectnest(s) end ap.start(s) -- start counters --texio.write_nl('yooo...'..s) s = s:gsub(ap.itemp, '\0\0'):gsub('\0', '', 1) -- make all items \0\0 then change first item to one \0 s = s:gsub('(%z)(%Z*)(%z?)', -- find betwen \0 .. \0 function(it, s) -- discarding duplicate item '_it' that was made in first gsub ap.addcount(s) -- add count, helps determine delimiter return ap.rtrim(it..s)..ap.getdelim()..' ' end ) s = s:gsub('\0', ap.itemp) -- replace items s = s:gsub(ap.itemp, ap.item) -- replace items return s end function ap.gotab(s) -- very simple, does not work if \\ in tabular, doesn't factor in header or footer local s, c = s:gsub('%s*\\\\', '\0') if c > 2 then s = s:gsub('\0', ap.punc[0]..'\\\\', c-2) end if c > 1 then s = s:gsub('\0', ap.punc[2]..'\\\\', 1) end s = s:gsub('\0', ap.punc[1]..'\\\\', 1) return s end return ap