-- A miniature stand-in for the Scintillua lexer module, just enough for the -- syntax-highlight checks to drive every path through the filter without the -- real collection installed. load() hands out one of the toy lexers below by -- name and detect() recognises a single filename suffix, so a check can tell -- the detection path apart from the extension path by which lexer ends up -- running. Anything the filter treats as optional, a lexer that will not -- load or one that raises while lexing, has a name here too. local M = {} -- Tokens come back the way Scintillua returns them, one flat list of a tag -- name and the position just past the token it names. Letter runs are -- keywords, digit runs are numbers, a single quoted run carries a dotted tag -- so the dotted first component lookup gets exercised, and any other byte is -- whitespace, which maps to no css class. local function lex_words(self, text) local tokens = {} local pos = 1 while pos <= #text do local start, stop = text:find("^%a+", pos) if not start then start, stop = text:find("^%d+", pos) if start then tokens[#tokens + 1] = "number" else start, stop = text:find("^'[^']*'", pos) if start then tokens[#tokens + 1] = "string.double" else stop = pos tokens[#tokens + 1] = "whitespace" end end else tokens[#tokens + 1] = "keyword" end tokens[#tokens + 1] = stop + 1 pos = stop + 1 end return tokens end -- Tags only the first four bytes and stops, so the filter has to append the -- untagged tail itself or the check for it fails. local function lex_short(self, text) if #text < 5 then return {} end return { "keyword", 5 } end local function lex_raise(self, text) error("this lexer always raises") end local lexers = { fake = { lex = lex_words }, short = { lex = lex_short }, badlex = { lex = lex_raise }, } function M.load(name) local lexer = lexers[name] if lexer == nil then error("no fake lexer named " .. tostring(name)) end return lexer end function M.detect(filename) if filename:match("%.viadetect$") then return "fake" end return nil end return M