-- version : 1.0.0 - 07/2005 (2008: lua 5.1) -- author : Hans Hagen - PRAGMA ADE - www.pragma-ade.com -- copyright : public domain or whatever suits -- remark : part of the context distribution, my first lua code -- todo: name space for local functions -- todo: the spell checking code is for the built-in lexer, the lpeg one uses its own -- loading: scite-ctx.properties -- # environment variable -- # -- # CTXSPELLPATH=t:/spell -- # -- # auto language detection -- # -- # % version =1.0 language=uk -- # -- ext.lua.startup.script=$(SciteDefaultHome)/scite-ctx.lua -- -- # extension.$(file.patterns.context)=scite-ctx.lua -- # extension.$(file.patterns.example)=scite-ctx.lua -- -- # ext.lua.reset=1 -- # ext.lua.auto.reload=1 -- # ext.lua.startup.script=t:/lua/scite-ctx.lua -- -- ctx.menulist.default=\ -- wrap=wrap_text|\ -- unwrap=unwrap_text|\ -- sort=sort_text|\ -- document=document_text|\ -- quote=quote_text|\ -- compound=compound_text|\ -- check=check_text\| -- strip=toggle_strip -- -- ctx.spellcheck.language=auto -- ctx.spellcheck.wordsize=4 -- ctx.spellcheck.wordpath=ENV(CTXSPELLPATH) -- -- ctx.spellcheck.wordfile.all=spell-uk.txt,spell-nl.txt -- -- ctx.spellcheck.wordfile.uk=spell-uk.txt -- ctx.spellcheck.wordfile.nl=spell-nl.txt -- ctx.spellcheck.wordsize.uk=4 -- ctx.spellcheck.wordsize.nl=4 -- -- command.name.21.*=CTX Action List -- command.subsystem.21.*=3 -- command.21.*=show_menu $(ctx.menulist.default) -- command.groupundo.21.*=yes -- command.shortcut.21.*=Shift+F11 -- -- command.name.22.*=CTX Check Text -- command.subsystem.22.*=3 -- command.22.*=check_text -- command.groupundo.22.*=yes -- command.shortcut.22.*=Ctrl+L -- -- command.name.23.*=CTX Wrap Text -- command.subsystem.23.*=3 -- command.23.*=wrap_text -- command.groupundo.23.*=yes -- command.shortcut.23.*=Ctrl+M -- -- # command.21.*=check_text -- # command.21.*=dofile e:\context\lua\scite-ctx.lua -- generic functions -- Once lpeg is available I will update the functions below. local props = props or { } local byte, char = string.byte, string.char local lower, upper, format = string.lower, string.upper, string.format local gsub, sub, find, rep, match, gmatch = string.gsub, string.sub, string.find, string.rep, string.match, string.gmatch local sort, concat = table.sort, table.concat local loadstring = loadstring or load local function check_output_pane() editor.StyleClearAll(output) end -- helpers : utf local magicstring = rep("", 2) local l2 = char(0xC0) local l3 = char(0xE0) local l4 = char(0xF0) local function utflen(str) local n = 0 local l = 0 for s in gmatch(str,".") do if l > 0 then l = l - 1 else n = n + 1 if s >= l4 then l = 3 elseif s >= l3 then l = 2 elseif s >= l2 then l = 1 end end end return n end local function utfchar(u) if u <= 0x7F then return char( u ) elseif u <= 0x7FF then return char ( 0xC0 | (u >> 6), 0x80 | (u & 0x3F) ) elseif u <= 0xFFFF then return char ( 0xE0 | (u >> 12), 0x80 | ((u >> 6) & 0x3F), 0x80 | (u & 0x3F) ) elseif n < 0x110000 then local n = u - 0x10000 local r = ((n & 0xF0000) >> 16) + 1 return char ( 0xF0 | (r >> 2), 0x80 | ((r & 3) << 4) | ((n & 0x0F000) >> 12), 0x80 | ((n & 0x00FC0) >> 6), 0x80 | (n & 0x0003F) ) else return utfchar(0xFFFD) end end -- helpers: system function io.exists(filename) local ok, result, message = pcall(io.open,filename) if result then io.close(result) return true else return false end end local function resultof(command) local handle = io.popen(command,"r") -- already has flush if handle then local result = handle:read("*all") or "" handle:close() return result else return "" end end function os.envvar(str) local s = os.getenv(str) if s ~= '' then return s end s = os.getenv(upper(str)) if s ~= '' then return s end s = os.getenv(lower(str)) if s ~= '' then return s end end local function loadtable(name) local f = io.open(name,"rb") if f then f:close() return dofile(name) end end -- helpers: reporting local crlf = "\n" local report = nil local trace = trace if trace then report = function(fmt,...) if fmt then trace(format(fmt,...)) end trace(crlf) io.flush() end else trace = print report = function(fmt,...) if fmt then trace(format(fmt,...)) else trace("") end io.flush() end end -- helpers: whatever (old code, we should use our libs) local function grab(str,delimiter) local list = { } for snippet in gmatch(str,delimiter) do list[#list+1] = snippet end return list end local function expand(str) return (gsub(str,"ENV%((%w+)%)", os.envvar)) end local function strip(str) return (gsub(str,"^%s*(.-)%s*$", "%1")) end local function alphasort(list,i) if i and i > 0 then local function alphacmp(a,b) return lower(gsub(sub(a,i),'0',' ')) < lower(gsub(sub(b,i),'0',' ')) end sort(list,alphacmp) else local function alphacmp(a,b) return lower(a) < lower(b) end sort(list,alphacmp) end end -- helpers: editor -- local function column_of_position(position) -- local line = editor:LineFromPosition(position) -- local oldposition = editor.CurrentPos -- local column = 0 -- editor:GotoPos(position) -- while editor.CurrentPos ~= 0 and line == editor:LineFromPosition(editor.CurrentPos) do -- editor:CharLeft() -- column = column + 1 -- end -- editor:GotoPos(oldposition) -- if line > 0 then -- return column -1 -- else -- return column -- end -- end -- local function line_of_position(position) -- return editor:LineFromPosition(position) -- end local function extend_to_start() local selectionstart = editor.SelectionStart local selectionend = editor.SelectionEnd local line = editor:LineFromPosition(selectionstart) if line > 0 then while line == editor:LineFromPosition(selectionstart-1) do selectionstart = selectionstart - 1 editor:SetSel(selectionstart,selectionend) end else selectionstart = 0 end editor:SetSel(selectionstart,selectionend) return selectionstart end local function extend_to_end() -- editor:LineEndExtend() does not work local selectionstart = editor.SelectionStart local selectionend = editor.SelectionEnd local line = editor:LineFromPosition(selectionend) while line == editor:LineFromPosition(selectionend+1) do selectionend = selectionend + 1 editor:SetSel(selectionstart,selectionend) if selectionend ~= editor.SelectionEnd then break -- no progress end end editor:SetSel(selectionstart,selectionend) return selectionend end local function getfiletype() local language = gsub(props.Language or "","script_","") if language ~= "" then return language else local firstline = editor:GetLine(0) or "" if find(firstline,"^%%") then return 'tex' elseif find(firstline,"^<%?xml") then return 'xml' else return 'unknown' end end end -- inspired by LuaExt's scite_Files -- local function get_dir_list(mask) -- local f -- if props['PLAT_GTK'] and props['PLAT_GTK'] ~= "" then -- f = io.popen('ls -1 ' .. mask) -- else -- mask = gsub(mask,'/','\\') -- local tmpfile = 'scite-ctx.tmp' -- local cmd = 'dir /b "' .. mask .. '" > ' .. tmpfile -- os.execute(cmd) -- f = io.open(tmpfile) -- end -- local files = { } -- if not f then -- path check added -- return files -- end -- for line in f:lines() do -- files[#files+1] = line -- end -- f:close() -- return files -- end --helpers : utf from editor local cat -- has to be set to editor.CharAt local function toutfcode(pos) -- if needed we can cache local c1 = cat[pos] if c1 < 0 then c1 = 256 + c1 end if c1 < 128 then return c1, 1 end if c1 < 224 then local c2 = cat[pos+1] if c2 < 0 then c2 = 256 + c2 end return c1 * 64 + c2 - 12416, 2 end if c1 < 240 then local c2 = cat[pos+1] local c3 = cat[pos+2] if c2 < 0 then c2 = 256 + c2 end if c3 < 0 then c3 = 256 + c3 end return (c1 * 64 + c2) * 64 + c3 - 925824, 3 end if c1 < 245 then local c2 = cat[pos+1] local c3 = cat[pos+2] local c4 = cat[pos+3] if c2 < 0 then c2 = 256 + c2 end if c3 < 0 then c3 = 256 + c3 end if c4 < 0 then c4 = 256 + c4 end return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168, 4 end end -- banner do check_output_pane() print("Some CTX extensions:") local wraplength = props['ctx.wraptext.length'] if wraplength and wraplength ~= "" then print("\n- ctx.wraptext.length is set to " .. wraplength) else print("\n- ctx.wraptext.length is not set") end local helpinfo = props['ctx.helpinfo'] if helpinfo and helpinfo ~= "" then print("\n- key bindings:\n") print((gsub(strip(helpinfo),"%s*|%s*","\n"))) else print("\n- no extra key bindings") end print("\n- recognized first lines:\n") print("xml length then replacement[#replacement+1] = templine templine = indentation .. snippet tempsize = startcolumn + snipsize elseif tempsize == 0 then templine = indentation .. snippet tempsize = tempsize + startcolumn + snipsize else templine = templine .. ' ' .. snippet tempsize = tempsize + 1 + snipsize end end end replacement[#replacement+1] = templine replacement[1] = gsub(replacement[1],"^%s+",'') if endcolumn == 0 then replacement[#replacement+1] = "" end editor:ReplaceSel(concat(replacement,"\n")) end function unwrap_text() local startposition = editor.SelectionStart local endposition = editor.SelectionEnd if startposition == endposition then return end editor:HomeExtend() editor:LineEndExtend() startposition = editor.SelectionStart endposition = editor.SelectionEnd local magicstring = rep("", 2) local selection = gsub(editor:GetSelText(),"[\n\r][\n\r]+", ' ' .. magicstring .. ' ') local replacement = '' for snippet in gmatch(selection,"%S+") do if snippet == magicstring then replacement = replacement .. "\n" else replacement = replacement .. snippet .. "\n" end end if endcolumn == 0 then replacement = replacement .. "\n" end editor:ReplaceSel(replacement) end function sort_text() local startposition = editor.SelectionStart local endposition = editor.SelectionEnd if startposition == endposition then return end -- local startcolumn = column_of_position(startposition) -- local endcolumn = column_of_position(endposition) -- -- editor:SetSel(startposition,endposition) local startline = props['SelectionStartLine'] local endline = props['SelectionEndLine'] local startcolumn = props['SelectionStartColumn'] - 1 local endcolumn = props['SelectionEndColumn'] - 1 startposition = extend_to_start() endposition = extend_to_end() local selection = gsub(editor:GetSelText(), "%s*$", '') local list = grab(selection,"[^\n\r]+") alphasort(list, startcolumn) local replacement = concat(list, "\n") editor:GotoPos(startposition) editor:SetSel(startposition,endposition) if endcolumn == 0 then replacement = replacement .. "\n" end editor:ReplaceSel(replacement) end do local data = { xml = { pattern = "%<%!%-%-.-%-%-%>" }, tex = { pattern = "%%.-[\r\n]" }, } function remove_comment() local filetype = getfiletype() local filedata = data[filetype] local selection = editor:GetSelText() if filedata and selection ~= "" then local startposition = editor.SelectionStart local endposition = editor.SelectionEnd selection = gsub(selection,filedata.pattern,"") selection = gsub(selection,"%s+","") editor:ReplaceSel(selection) end end end do -- I really needed we can do version numbers but no one uses them. local patterns = { "(%d+)%s+(%d+)%s+obj", "(%d+)%s+(%d+)%s+R", } local function show_pdf_object(n) local name = props.FilePath local data = resultof("mtxrun --script pdf --object=" .. n .. " " .. name) print(format("file: %s, object number: %s, object data:\n",name,n)) print(data) end function filter_pdf_object() local filetype = getfiletype() local selection = editor:GetSelText() if filetype == "pdf" and selection ~= 0 then local n, m for i=1,#patterns do n, m = match(selection,patterns[i]) if n and m then break end end n = tonumber(n) m = tonumber(m) if n and m then show_pdf_object(n) end end end function search_pdf_object() local filetype = getfiletype() local selection = editor:GetSelText() if filetype == "pdf" and selection ~= 0 then local onstrip = OnStrip function OnStrip(control,change) if control == 2 then local n = tonumber(scite.StripValue(1)) if n then show_pdf_object(n) end OnStrip = onstrip scite.StripShow("") end end scite.StripShow("!'Object Number:'{}(&Search)\n") end end end do local valid = { xml = true, tex = true, } function document_text() local filetype = getfiletype() if valid[filetype or ""] then local startposition = editor.SelectionStart local endposition = editor.SelectionEnd if startposition ~= endposition then startposition = extend_to_start() endposition = extend_to_end() editor:SetSel(startposition,endposition) local replacement = '' for i = editor:LineFromPosition(startposition), editor:LineFromPosition(endposition) do local str = editor:GetLine(i) if filetype == 'xml' then if find(str,"^<%!%-%- .* %-%->%s*$") then replacement = replacement .. gsub(str,"^<%!%-%- (.*) %-%->(%s*)$","%1\n") elseif find(str,"%S") then replacement = replacement .. '\n" else replacement = replacement .. str end else if find(str,"^%%D%s+$") then replacement = replacement .. "\n" elseif find(str,"^%%D ") then replacement = replacement .. gsub(str,"^%%D ",'') else replacement = replacement .. '%D ' .. str end end end replacement = gsub(replacement,"[\n\r]$",'') editor:ReplaceSel(replacement) end end end end do local data = { xml = { quote = { left = "", right = "", }, quotation = { left = "", right = "", }, }, tex = { quote = { left = "\\quote {", right = "}", }, quotation = { left = "\\quotation {", right = "}", }, }, } function quote_text() local filetype = getfiletype() local filedata = data[filetype] local selection = editor:GetSelText() if filedata and selection ~= "" then selection = gsub(selection,[["(.-)"]], filedata.quotation.left .. "%1" .. filedata.quotation.right) selection = gsub(selection,[['(.-)']], filedata.quote .left .. "%1" .. filedata.quote .right) editor:ReplaceSel(selection) end end function quote_text_s() local filetype = getfiletype() local filedata = data[filetype] local selection = editor:GetSelText() if filedata and selection ~= "" then selection = filedata.quote.left .. selection .. filedata.quote.right editor:ReplaceSel(selection) end end function quote_text_d() local filetype = getfiletype() local filedata = data[filetype] local selection = editor:GetSelText() if filedata and selection ~= "" then selection = filedata.quotation.left .. selection .. filedata.quotation.right editor:ReplaceSel(selection) end end end do local data = { xml = { pattern = [[(>[^<%-][^<%-]+)([-/])(%w%w+)]], replacement = [[%1%3]], }, tex = { pattern = [[([^|])([-/]+)([^|])]], replacement = [[%1|%2|%3]], }, } function compound_text() local filetype = getfiletype() local filedata = data[filetype] local selection = editor:GetSelText() if filedata and selection ~= "" then selection = gsub(selection,filedata.pattern,filedata.replacement) editor:ReplaceSel(selection) end end end -- There used to be some spell checking code here usign regular Scite -- mechanisms but that has been moved to the lexer code already a while -- ago so I removed the (pre 2005) code here. (See archive.) do function add_text() local startposition = editor.SelectionStart local endposition = editor.SelectionEnd if startposition == endposition then return end local selection = gsub(editor:GetSelText(), "%s*$", '') local n, sum = 0, 0 for s in gmatch(selection,"[%-%+]?[%d%.%,]+") do -- todo: proper lpeg s = gsub(s,",",".") local m = tonumber(s) if m then n = n + 1 sum = sum + m report("%4i : %s",n,m) end end if n > 0 then report() report("sum : %s",sum) else report("no numbers selected") end end end local dirty = { } do local bidi = nil local mapping = { l = 0, -- "Left-to-Right", lre = 7, -- "Left-to-Right Embedding", lro = 7, -- "Left-to-Right Override", r = 2, -- "Right-to-Left", al = 3, -- "Right-to-Left Arabic", rle = 7, -- "Right-to-Left Embedding", rlo = 7, -- "Right-to-Left Override", pdf = 7, -- "Pop Directional Format", en = 4, -- "European Number", es = 4, -- "European Number Separator", et = 4, -- "European Number Terminator", an = 5, -- "Arabic Number", cs = 6, -- "Common Number Separator", nsm = 6, -- "Non-Spacing Mark", bn = 7, -- "Boundary Neutral", b = 0, -- "Paragraph Separator", s = 7, -- "Segment Separator", ws = 0, -- "Whitespace", on = 7, -- "Other Neutrals", } -- todo: take from scite-context-theme.lua local colors = { -- b g r [0] = 0x000000, -- black [1] = 0x00007F, -- red [2] = 0x007F00, -- green [3] = 0x7F0000, -- blue [4] = 0x7F7F00, -- cyan [5] = 0x7F007F, -- magenta [6] = 0x007F7F, -- yellow [7] = 0x007FB0, -- orange [8] = 0x4F4F4F, -- dark } -- in principle, when we could inject some funny symbol that is not part of the -- stream and/or use a different extra styling for each snippet then selection -- would work and rendering would look better too ... one problem is that a font -- rendering can collapse characters due to font features function show_bidi() cat = editor.CharAt editor.CodePage = SC_CP_UTF8 for i=1,#colors do -- 0,#colors editor.StyleFore[i] = colors[i] -- crashes end if not bidi then bidi = require("context.scite-ctx-bidi") end local len = editor.TextLength local str = editor:textrange(0,len-1) local t = { } local a = { } local n = 0 local i = 0 local v while i < len do n = n + 1 v, s = toutfcode(i) t[n] = v a[n] = s i = i + s end local t = bidi.process(t) editor:StartStyling(0,31) local defaultcolor = mapping.l local mirrorcolor = 1 if false then for i=1,n do local direction = t[i].direction local color = direction and (mapping[direction] or 0) or defaultcolor editor:SetStyling(a[i],color) end else local lastcolor = -1 local runlength = 0 for i=1,n do local ti = t[i] local direction = ti.direction local mirror = t[i].mirror local color = (mirror and mirrorcolor) or (direction and mapping[direction]) or defaultcolor if color == lastcolor then runlength = runlength + a[i] else if runlength > 0 then editor:SetStyling(runlength,lastcolor) end lastcolor = color runlength = a[i] end end if runlength > 0 then editor:SetStyling(runlength,lastcolor) end end editor:SetStyling(2,31) dirty[props.FileNameExt] = true end end -- menu local menuactions = { } local menufunctions = { } local menuentries = { } function UserListShow(menutrigger, menulist) if type(menulist) == "string" then menuentries = { } menuactions = { } for item in gmatch(menulist,"[^%|]+") do if item ~= "" then -- why not just a split for key, value in gmatch(item,"%s*(.+)=(.+)%s*") do menuentries[#menuentries+1] = key menuactions[key] = value end end end else menuentries = menulist menuactions = false end local menustring = concat(menuentries,'|') if menustring == "" then report("there are no (further) options defined for this file type") else editor.AutoCSeparator = byte('|') editor:UserListShow(menutrigger,menustring) editor.AutoCSeparator = byte(' ') end end function OnUserListSelection(trigger,choice) if menufunctions[trigger] then return menufunctions[trigger](menuactions and menuactions[choice] or choice) else return false end end -- main menu do local menutrigger = 12 function show_menu(menulist) UserListShow(menutrigger, menulist) end function process_menu(action) if not find(action,"%(%)$") then assert(load(action .. "()"))() else assert(load(action))() end end menufunctions[12] = process_menu end -- The template code is old but used so we cannot drop it. I will cook up a better -- system some day, using Lua tables instead. do -- local templatetrigger = 13 local ctx_template_file = "scite-ctx-templates.lua" local ctx_template_list = { } local ctx_template_menu = { } -- function ctx_list_loaded(path) -- return ctx_path_list[path] and #ctx_path_list[path] > 0 -- end local patterns = { xml = "<%?context%-directive job ctxtemplate (.-) %?>" } local function loadtemplate(name) local temp = gsub(name,"\\","/") local okay = loadtable(temp) if okay then print("template loaded: " .. name) end return okay end local function loadtemplatefrompaths(path,name) return loadtemplate(path .. "/" .. name) or loadtemplate(path .. "/../" .. name) or loadtemplate(path .. "/../../" .. name) end function insert_template(templatelist) local path = props["FileDir"] local suffix = props["FileExt"] local list = ctx_template_list[path] if list == nil then local pattern = patterns[suffix] local okay = false if pattern then for i=0,9 do local line = editor:GetLine(i) or "" local name = match(line,pattern) if name then okay = loadtemplatefrompaths(path,name) if not okay then name = resultof("mtxrun --find-file " .. name) if name then name = gsub(name,"\n","") okay = loadtemplate(name) end end break end end end if not okay then okay = loadtemplatefrompaths(path,ctx_template_file) end if not okay then okay = loadtemplate(props["SciteDefaultHome"] .. "/context/" .. ctx_template_file) end if okay then list = okay else list = false print("no template file found") end ctx_template_list[path] = list end ctx_template_menu = { } if list then local okay = list[suffix] if okay then local menu = { } for i=1,#okay do local o = okay[i] local n = o.name menu[#menu+1] = n ctx_template_menu[n] = o end UserListShow(templatetrigger, menu, true) end end end function inject_template(action) if ctx_template_menu then local a = ctx_template_menu[action] if a then local template = a.template local nature = a.nature if template then local margin = props['SelectionStartColumn'] - 1 -- template = gsub(template,"\\n","\n") template = gsub(template,"%?%?","_____") local pos = find(template,"%?") template = gsub(template,"%?","") template = gsub(template,"_____","?") if nature == "display" then local spaces = rep(" ",margin) if not find(template,"\n$") then template = template .. "\n" end template = gsub(template,"\n",function(s) return "\n" .. spaces end) pos = pos + margin -- todo: check for first line end editor:insert(editor.CurrentPos,template) if pos then editor.CurrentPos = editor.CurrentPos + pos - 1 editor.SelectionStart = editor.CurrentPos editor.SelectionEnd = editor.CurrentPos editor:GotoPos(editor.CurrentPos) end end end end end menufunctions[13] = inject_template end do -- These will become external and taken from sort-lan.lua in the -- ConTeXt distribution. local textlists = { en = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", }, nl = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", }, fr = { "a", "æ", "b", "c", "ç", "d", "e", "è", "é", "ê", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "Æ", "B", "C", "Ç", "D", "E", "È", "É", "Ê", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", }, de = { "a", "ä", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "ö", "p", "q", "r", "s", "ß", "t", "u", "ü", "v", "w", "x", "y", "z", "A", "Ä", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "Ö", "P", "Q", "R", "S", "SS", "T", "U", "Ü", "V", "W", "X", "Y", "Z", }, fi = { -- finish "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "å", "ä", "ö", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Å", "Ä", "Ö", }, sl = { -- slovenian "a", "b", "c", "č", "ć", "d", "đ", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "š", "t", "u", "v", "w", "x", "y", "z", "ž", "A", "B", "C", "Č", "Ć", "D", "Đ", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "Š", "T", "U", "V", "W", "X", "Y", "Z", "Ž", }, ru = { -- rusian "а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "і", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "ѣ", "э", "ю", "я", "ѳ", "ѵ", "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И", "І", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Ѣ", "Э", "Ю", "Я", "Ѳ", "Ѵ", }, uk = { -- ukraninuan "а", "б", "в", "г", "ґ", "д", "е", "є", "ж", "з", "и", "і", "ї", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ь", "ю", "я", "А", "Б", "В", "Г", "Ґ", "Д", "Е", "Є", "Ж", "З", "И", "І", "Ї", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ь", "Ю", "Я", }, be = { -- belarusia "а", "б", "в", "г", "д", "е", "ё", "ж", "з", "і", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ў", "ф", "х", "ц", "ч", "ш", "ы", "ь", "э", "ю", "я", "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "І", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ў", "Ф", "Х", "Ц", "Ч", "Ш", "Ы", "Ь", "Э", "Ю", "Я", }, bg = { -- bulgarian "а", "б", "в", "г", "д", "е", "ж", "з","и", "й", "к", "a", "л", "a", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ь", "ю", "я", "А", "Б", "В", "Г", "Д", "Е", "Ж", "З","И", "Й", "К", "A", "Л", "A", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ь", "Ю", "Я", }, pl = { -- polish "a", "ą", "b", "c", "ć", "d", "e", "ę", "f", "g", "h", "i", "j", "k", "l", "ł", "m", "n", "ń", "o", "ó", "p", "q", "r", "s", "ś", "t", "u", "v", "w", "x", "y", "z", "ź", "ż", "A", "Ą", "B", "C", "Ć", "D", "E", "Ę", "F", "G", "H", "I", "J", "K", "L", "Ł", "M", "N", "Ń", "O", "Ó", "P", "Q", "R", "S", "Ś", "T", "U", "V", "W", "X", "Y", "Z", "Ź", "Ż", }, cz = { -- czech "a", "á", "b", "c", "č", "d", "ď", "e", "é", "ě", "f", "g", "h", "i", "í", "j", "k", "l", "m", "n", "ň", "o", "ó", "p", "q", "r", "ř", "s", "š", "t", "ť", "u", "ú", "ů", "v", "w", "x", "y", "ý", "z", "ž", "A", "Á", "B", "C", "Č", "D", "Ď", "E", "É", "Ě", "F", "G", "H", "I", "Í", "J", "K", "L", "M", "N", "Ň", "O", "Ó", "P", "Q", "R", "Ř", "S", "Š", "T", "Ť", "U", "Ú", "Ů", "V", "W", "X", "Y", "Ý", "Z", "Ž", }, sk = { -- slovak "a", "á", "ä", "b", "c", "č", "d", "ď", "e", "é", "f", "g", "h", ch, "i", "í", "j", "k", "l", "ĺ", "ľ", "m", "n", "ň", "o", "ó", "ô", "p", "q", "r", "ŕ", "s", "š", "t", "ť", "u", "ú", "v", "w", "x", "y", "ý", "z", "ž", "A", "Á", "Ä", "B", "C", "Č", "D", "Ď", "E", "É", "F", "G", "H", "I", "Í", "J", "K", "L", "Ĺ", "Ľ", "M", "N", "Ň", "O", "Ó", "Ô", "P", "Q", "R", "Ŕ", "S", "Š", "T", "Ť", "U", "Ú", "V", "W", "X", "Y", "Ý", "Z", "Ž", }, hr = { -- croatian "a", "b", "c", "č", "ć", "d", "đ", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "š", "t", "u", "v", "z", "ž", "A", "B", "C", "Č", "Ć", "D", "Đ", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "R", "S", "Š", "T", "U", "V", "Z", "Ž", }, sr = { -- serbian "а", "б", "в", "г", "д", "ђ", "е", "ж", "з", "и", "ј", "к", "л", "љ", "м", "н", "њ", "о", "п", "р", "с", "т", "ћ", "у", "ф", "х", "ц", "ч", "џ", "ш", "А", "Б", "В", "Г", "Д", "Ђ", "Е", "Ж", "З", "И", "Ј", "К", "Л", "Љ", "М", "Н", "Њ", "О", "П", "Р", "С", "Т", "Ћ", "У", "Ф", "Х", "Ц", "Ч", "Џ", "Ш", }, no = { -- norwegian "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "æ", "ø", "å", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Æ", "Ø", "Å", }, da = { --danish "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "æ", "ø", "å", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Æ", "Ø", "Å", }, sv = { -- swedish "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "å", "ä", "ö", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Å", "Ä", "Ö", }, is = { -- islandic "a", "á", "b", "d", "ð", "e", "é", "f", "g", "h", "i", "í", "j", "k", "l", "m", "n", "o", "ó", "p", "r", "s", "t", "u", "ú", "v", "x", "y", "ý", "þ", "æ", "ö", "A", "Á", "B", "D", "Ð", "E", "É", "F", "G", "H", "I", "Í", "J", "K", "L", "M", "N", "O", "Ó", "P", "R", "S", "T", "U", "Ú", "V", "X", "Y", "Ý", "Þ", "Æ", "Ö", }, -- gr = { -- greek -- "α", "ά", "ὰ", "ᾶ", "ᾳ", "ἀ", "ἁ", "ἄ", "ἂ", "ἆ", -- "ἁ", "ἅ", "ἃ", "ἇ", "ᾁ", "ᾴ", "ᾲ", "ᾷ", "ᾄ", "ᾂ", -- "ᾅ", "ᾃ", "ᾆ", "ᾇ", "β", "γ", "δ", "ε", "έ", "ὲ", -- "ἐ", "ἔ", "ἒ", "ἑ", "ἕ", "ἓ", "ζ", "η", "η", "ή", -- "ὴ", "ῆ", "ῃ", "ἠ", "ἤ", "ἢ", "ἦ", "ᾐ", "ἡ", "ἥ", -- "ἣ", "ἧ", "ᾑ", "ῄ", "ῂ", "ῇ", "ᾔ", "ᾒ", "ᾕ", "ᾓ", -- "ᾖ", "ᾗ", "θ", "ι", "ί", "ὶ", "ῖ", "ἰ", "ἴ", "ἲ", -- "ἶ", "ἱ", "ἵ", "ἳ", "ἷ", "ϊ", "ΐ", "ῒ", "ῗ", "κ", -- "λ", "μ", "ν", "ξ", "ο", "ό", "ὸ", "ὀ", "ὄ", "ὂ", -- "ὁ", "ὅ", "ὃ", "π", "ρ", "ῤ", "ῥ", "σ", "ς", "τ", -- "υ", "ύ", "ὺ", "ῦ", "ὐ", "ὔ", "ὒ", "ὖ", "ὑ", "ὕ", -- "ὓ", "ὗ", "ϋ", "ΰ", "ῢ", "ῧ", "φ", "χ", "ψ", "ω", -- "ώ", "ὼ", "ῶ", "ῳ", "ὠ", "ὤ", "ὢ", "ὦ", "ᾠ", "ὡ", -- "ὥ", "ὣ", "ὧ", "ᾡ", "ῴ", "ῲ", "ῷ", "ᾤ", "ᾢ", "ᾥ", -- "ᾣ", "ᾦ", "ᾧ", -- -- "Α", "Ά", "Ὰ", "Α͂", "Ἀ", "Ἁ", "Ἄ", "Ἂ", "Ἆ", -- "Ἁ", "Ἅ", "Ἃ", "Ἇ", -- "Β", "Γ", "Δ", "Ε", "Έ", "Ὲ", -- "Ἐ", "Ἔ", "Ἒ", "Ἑ", "Ἕ", "Ἓ", "Ζ", "Η", "Η", "Ή", -- "Ὴ", "Η͂", "Ἠ", "Ἤ", "Ἢ", "Ἦ", "Ἡ", "Ἥ", -- "Ἣ", "Ἧ", -- "Θ", "Ι", "Ί", "Ὶ", "Ι͂", "Ἰ", "Ἴ", "Ἲ", -- "Ἶ", "Ἱ", "Ἵ", "Ἳ", "Ἷ", "Ϊ", "Ϊ́", "Ϊ̀", "Ϊ͂", "Κ", -- "Λ", "Μ", "Ν", "Ξ", "Ο", "Ό", "Ὸ", "Ὀ", "Ὄ", "Ὂ", -- "Ὁ", "Ὅ", "Ὃ", "Π", "Ρ", "Ρ̓", "Ῥ", "Σ", "Σ", "Τ", -- "Υ", "Ύ", "Ὺ", "Υ͂", "Υ̓", "Υ̓́", "Υ̓̀", "Υ̓͂", "Ὑ", "Ὕ", -- "Ὓ", "Ὗ", "Ϋ", "Ϋ́", "Ϋ̀", "Ϋ͂", "Φ", "Χ", "Ψ", "Ω", -- "Ώ", "Ὼ", "Ω͂", "Ὠ", "Ὤ", "Ὢ", "Ὦ", "Ὡ", -- "Ὥ", "Ὣ", "Ὧ", -- }, gr = { -- greek "α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "ς", "τ", "υ", "φ", "χ", "ψ", "ω", "Α", "Β", "Γ", "Δ", "Ε", "Ζ", "Η", "Θ", "Ι", "Κ", "Λ", "Μ", "Ν", "Ξ", "Ο", "Π", "Ρ", "Σ", "Τ", "Υ", "Χ", "Ψ", "Ω", }, la = { -- latin "a", "ā", "ă", "b", "c", "d", "e", "ē", "ĕ", "f", "g", "h", "i", "ī", "ĭ", "j", "k", "l", "m", "n", "o", "ō", "ŏ", "p", "q", "r", "s", "t", "u", "ū", "ŭ", "v", "w", "x", "y", "ȳ", "y̆", "z", "æ", "A", "Ā", "Ă", "B", "C", "D", "E", "Ē", "Ĕ", "F", "G", "H", "I", "Ī", "Ĭ", "J", "K", "L", "M", "N", "O", "Ō", "Ŏ", "P", "Q", "R", "S", "T", "U", "Ū", "Ŭ", "V", "W", "X", "Y", "Ȳ", "Y̆", "Z", "Æ", }, it = { -- italian "a", "á", "b", "c", "d", "e", "é", "è", "f", "g", "h", "i", "í", "ì", "j", "k", "l", "m", "n", "o", "ó", "ò", "p", "q", "r", "s", "t", "u", "ú", "ù", "v", "w", "x", "y", "z", "A", "Á", "B", "C", "D", "E", "É", "È", "F", "G", "H", "I", "Í", "Ì", "J", "K", "L", "M", "N", "O", "Ó", "Ò", "P", "Q", "R", "S", "T", "U", "Ú", "Ù", "V", "W", "X", "Y", "Z", }, ro = { -- romanian "a", "ă", "â", "b", "c", "d", "e", "f", "g", "h", "i", "î", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "ș", "t", "ț", "u", "v", "w", "x", "y", "z", "A", "Ă", "Â", "B", "C", "D", "E", "F", "G", "H", "I", "Î", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "Ș", "T", "Ț", "U", "V", "W", "X", "Y", "Z", }, es = { -- spanish "a", "á", "b", "c", "d", "e", "é", "f", "g", "h", "i", "í", "j", "k", "l", "m", "n", "ñ", "o", "ó", "p", "q", "r", "s", "t", "u", "ú", "ü", "v", "w", "x", "y", "z", "A", "Á", "B", "C", "D", "E", "É", "F", "G", "H", "I", "Í", "J", "K", "L", "M", "N", "Ñ", "O", "Ó", "P", "Q", "R", "S", "T", "U", "Ú", "Ü", "V", "W", "X", "Y", "Z", }, pt = { -- portuguese "a", "á", "â", "ã", "à", "b", "c", "ç", "d", "e", "é", "ê", "f", "g", "h", "i", "í", "j", "k", "l", "m", "n", "o", "ó", "ô", "õ", "p", "q", "r", "s", "t", "u", "ú", "ü", "v", "w", "x", "y", "z", "A", "Á", "Â", "Ã", "À", "B", "C", "Ç", "D", "E", "É", "Ê", "F", "G", "H", "I", "Í", "J", "K", "L", "M", "N", "O", "Ó", "Ô", "Õ", "P", "Q", "R", "S", "T", "U", "Ú", "Ü", "V", "W", "X", "Y", "Z", }, lt = { -- lithuanian "a", "ą", "b", "c", "ch", "č", "d", "e", "ę", "ė", "f", "g", "h", "i", "į", "y", "j", "k", "l", "m", "n", "o", "p", "r", "s", "š", "t", "u", "ų", "ū", "v", "z", "ž", "A", "Ą", "B", "C", "CH", "Č", "D", "E", "Ę", "Ė", "F", "G", "H", "I", "Į", "Y", "J", "K", "L", "M", "N", "O", "P", "R", "S", "Š", "T", "U", "Ų", "Ū", "V", "Z", "Ž", }, lv = { -- latvian "a", "ā", "b", "c", "č", "d", "e", "ē", "f", "g", "ģ", "h", "i", "ī", "j", "k", "ķ", "l", "ļ", "m", "n", "ņ", "o", "ō", "p", "r", "ŗ", "s", "š", "t", "u", "ū", "v", "z", "ž", "A", "Ā", "B", "C", "Č", "D", "E", "Ē", "F", "G", "Ģ", "H", "I", "Ī", "J", "K", "Ķ", "L", "Ļ", "M", "N", "Ņ", "O", "Ō", "P", "R", "Ŗ", "S", "Š", "T", "U", "Ū", "V", "Z", "Ž", }, hu = { -- hungarian "a", "á", "b", "c", "d", "e", "é", "f", "g", "h", "i", "í", "j", "k", "l", "m", "n", "o", "ó", "ö", "ő", "p", "q", "r", "s", "t", "u", "ú", "ü", "ű", "v", "w", "x", "y", "z", "A", "Á", "B", "C", "D", "E", "É", "F", "G", "H", "I", "Í", "J", "K", "L", "M", "N", "O", "Ó", "Ö", "Ő", "P", "Q", "R", "S", "T", "U", "Ú", "Ü", "Ű", "V", "W", "X", "Y", "Z", }, et = { -- estonian "a", "b", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "š", "z", "ž", "t", "u", "v", "w", "õ", "ä", "ö", "ü", "x", "y", "A", "B", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "R", "S", "Š", "Z", "Ž", "T", "U", "V", "W", "Õ", "Ä", "Ö", "Ü", "X", "Y", }, -- jp = { -- japanese -- "あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ", -- "さ", "し", "す", "せ", "そ", "た", "ち", "つ", "て", "と", -- "な", "に", "ぬ", "ね", "の", "は", "ひ", "ふ", "へ", "ほ", -- "ま", "み", "む", "め", "も", "や", "ゆ", "よ", -- "ら", "り", "る", "れ", "ろ", "わ", "ゐ", "ゑ", "を", "ん", -- }, } local textselector = { } for k, v in next, textlists do textselector[#textselector+1] = k end table.sort(textselector) -- We can populate these with the utf converter but it looks nicer here to -- see what we actually get. And it also tests how SciTE displays these -- special characters. local mathsets = { { "tf", { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, }, { "bf", { "𝐛", "𝐜", "𝐝", "𝐞", "𝐟", "𝐠", "𝐡", "𝐢", "𝐣", "𝐤", "𝐥", "𝐦", "𝐧", "𝐨", "𝐩", "𝐪", "𝐫", "𝐬", "𝐭", "𝐮", "𝐯", "𝐰", "𝐱", "𝐲", "𝐳", "𝐀", "𝐁", "𝐂", "𝐃", "𝐄", "𝐅", "𝐆", "𝐇", "𝐈", "𝐉", "𝐊", "𝐋", "𝐌", "𝐍", "𝐎", "𝐏", "𝐐", "𝐑", "𝐒", "𝐓", "𝐔", "𝐕", "𝐖", "𝐗", "𝐘", "𝐙", "𝐚", "𝟎", "𝟏", "𝟐", "𝟑", "𝟒", "𝟓", "𝟔", "𝟕", "𝟖", "𝟗" }, }, { "it", { "𝑎", "𝑏", "𝑐", "𝑑", "𝑒", "𝑓", "𝑔", "ℎ", "𝑖", "𝑗", "𝑘", "𝑙", "𝑚", "𝑛", "𝑜", "𝑝", "𝑞", "𝑟", "𝑠", "𝑡", "𝑢", "𝑣", "𝑤", "𝑥", "𝑦", "𝑧", "𝐴", "𝐵", "𝐶", "𝐷", "𝐸", "𝐹", "𝐺", "𝐻", "𝐼", "𝐽", "𝐾", "𝐿", "𝑀", "𝑁", "𝑂", "𝑃", "𝑄", "𝑅", "𝑆", "𝑇", "𝑈", "𝑉", "𝑊", "𝑋", "𝑌", "𝑍", }, }, { "bi", { "𝒂", "𝒃", "𝒄", "𝒅", "𝒆", "𝒇", "𝒈", "𝒉", "𝒊", "𝒋", "𝒌", "𝒍", "𝒎", "𝒏", "𝒐", "𝒑", "𝒒", "𝒓", "𝒔", "𝒕", "𝒖", "𝒗", "𝒘", "𝒙", "𝒚", "𝒛", "𝑨", "𝑩", "𝑪", "𝑫", "𝑬", "𝑭", "𝑮", "𝑯", "𝑰", "𝑱", "𝑲", "𝑳", "𝑴", "𝑵", "𝑶", "𝑷", "𝑸", "𝑹", "𝑺", "𝑻", "𝑼", "𝑽", "𝑾", "𝑿", "𝒀", "𝒁", }, }, { "sc", { "𝒵", "𝒶", "𝒷", "𝒸", "𝒹", "ℯ", "𝒻", "ℊ", "𝒽", "𝒾", "𝒿", "𝓀", "𝓁", "𝓂", "𝓃", "ℴ", "𝓅", "𝓆", "𝓇", "𝓈", "𝓉", "𝓊", "𝓋", "𝓌", "𝓍", "𝓎", "𝓏", "𝒜", "ℬ", "𝒞", "𝒟", "ℰ", "ℱ", "𝒢", "ℋ", "ℐ", "𝒥", "𝒦", "ℒ", "ℳ", "𝒩", "𝒪", "𝒫", "𝒬", "ℛ", "𝒮", "𝒯", "𝒰", "𝒱", "𝒲", "𝒳", "𝒴", }, }, { "sc bf", { "𝓪", "𝓫", "𝓬", "𝓭", "𝓮", "𝓯", "𝓰", "𝓱", "𝓲", "𝓳", "𝓴", "𝓵", "𝓶", "𝓷", "𝓸", "𝓹", "𝓺", "𝓻", "𝓼", "𝓽", "𝓾", "𝓿", "𝔀", "𝔁", "𝔂", "𝔃", "𝓐", "𝓑", "𝓒", "𝓓", "𝓔", "𝓕", "𝓖", "𝓗", "𝓘", "𝓙", "𝓚", "𝓛", "𝓜", "𝓝", "𝓞", "𝓟", "𝓠", "𝓡", "𝓢", "𝓣", "𝓤", "𝓥", "𝓦", "𝓧", "𝓨", "𝓩", }, }, { "fr", { "𝔞", "𝔟", "𝔠", "𝔡", "𝔢", "𝔣", "𝔤", "𝔥", "𝔦", "𝔧", "𝔨", "𝔩", "𝔪", "𝔫", "𝔬", "𝔭", "𝔮", "𝔯", "𝔰", "𝔱", "𝔲", "𝔳", "𝔴", "𝔵", "𝔶", "𝔷", "𝔄", "𝔅", "ℭ", "𝔇", "𝔈", "𝔉", "𝔊", "ℌ", "ℑ", "𝔍", "𝔎", "𝔏", "𝔐", "𝔑", "𝔒", "𝔓", "𝔔", "ℜ", "𝔖", "𝔗", "𝔘", "𝔙", "𝔚", "𝔛", "𝔜", "ℨ", }, }, { "ds", { "𝕓", "𝕔", "𝕕", "𝕖", "𝕗", "𝕘", "𝕙", "𝕚", "𝕛", "𝕜", "𝕝", "𝕞", "𝕟", "𝕠", "𝕡", "𝕢", "𝕣", "𝕤", "𝕥", "𝕦", "𝕧", "𝕨", "𝕩", "𝕪", "𝕫", "𝔸", "𝔹", "ℂ", "𝔻", "𝔼", "𝔽", "𝔾", "ℍ", "𝕀", "𝕁", "𝕂", "𝕃", "𝕄", "ℕ", "𝕆", "ℙ", "ℚ", "ℝ", "𝕊", "𝕋", "𝕌", "𝕍", "𝕎", "𝕏", "𝕐", "ℤ", "𝕒", "𝟘", "𝟙", "𝟚", "𝟛", "𝟜", "𝟝", "𝟞", "𝟟", "𝟠", "𝟡" }, }, { "fr bf", { "𝕬", "𝕭", "𝕮", "𝕯", "𝕰", "𝕱", "𝕲", "𝕳", "𝕴", "𝕵", "𝕶", "𝕷", "𝕸", "𝕹", "𝕺", "𝕻", "𝕼", "𝕽", "𝕾", "𝕿", "𝖀", "𝖁", "𝖂", "𝖃", "𝖄", "𝖅", "𝖆", "𝖇", "𝖈", "𝖉", "𝖊", "𝖋", "𝖌", "𝖍", "𝖎", "𝖏", "𝖐", "𝖑", "𝖒", "𝖓", "𝖔", "𝖕", "𝖖", "𝖗", "𝖘", "𝖙", "𝖚", "𝖛", "𝖜", "𝖝", "𝖞", "𝖟" }, }, { "ss tf", { "𝖺", "𝖻", "𝖼", "𝖽", "𝖾", "𝖿", "𝗀", "𝗁", "𝗂", "𝗃", "𝗄", "𝗅", "𝗆", "𝗇", "𝗈", "𝗉", "𝗊", "𝗋", "𝗌", "𝗍", "𝗎", "𝗏", "𝗐", "𝗑", "𝗒", "𝗓", "𝖠", "𝖡", "𝖢", "𝖣", "𝖤", "𝖥", "𝖦", "𝖧", "𝖨", "𝖩", "𝖪", "𝖫", "𝖬", "𝖭", "𝖮", "𝖯", "𝖰", "𝖱", "𝖲", "𝖳", "𝖴", "𝖵", "𝖶", "𝖷", "𝖸", "𝖹", "𝟢", "𝟣", "𝟤", "𝟥", "𝟦", "𝟧", "𝟨", "𝟩", "𝟪", "𝟫" }, }, { "ss bf", { "𝗮", "𝗯", "𝗰", "𝗱", "𝗲", "𝗳", "𝗴", "𝗵", "𝗶", "𝗷", "𝗸", "𝗹", "𝗺", "𝗻", "𝗼", "𝗽", "𝗾", "𝗿", "𝘀", "𝘁", "𝘂", "𝘃", "𝘄", "𝘅", "𝘆", "𝘇", "𝗔", "𝗕", "𝗖", "𝗗", "𝗘", "𝗙", "𝗚", "𝗛", "𝗜", "𝗝", "𝗞", "𝗟", "𝗠", "𝗡", "𝗢", "𝗣", "𝗤", "𝗥", "𝗦", "𝗧", "𝗨", "𝗩", "𝗪", "𝗫", "𝗬", "𝗭", "𝟬", "𝟭", "𝟮", "𝟯", "𝟰", "𝟱", "𝟲", "𝟳", "𝟴", "𝟵", }, }, { "ss it", { "𝘢", "𝘣", "𝘤", "𝘥", "𝘦", "𝘧", "𝘨", "𝘩", "𝘪", "𝘫", "𝘬", "𝘭", "𝘮", "𝘯", "𝘰", "𝘱", "𝘲", "𝘳", "𝘴", "𝘵", "𝘶", "𝘷", "𝘸", "𝘹", "𝘺", "𝘻", "𝘈", "𝘉", "𝘊", "𝘋", "𝘌", "𝘍", "𝘎", "𝘏", "𝘐", "𝘑", "𝘒", "𝘓", "𝘔", "𝘕", "𝘖", "𝘗", "𝘘", "𝘙", "𝘚", "𝘛", "𝘜", "𝘝", "𝘞", "𝘟", "𝘠", "𝘡", }, }, { "ss bi", { "𝙖", "𝙗", "𝙘", "𝙙", "𝙚", "𝙛", "𝙜", "𝙝", "𝙞", "𝙟", "𝙠", "𝙡", "𝙢", "𝙣", "𝙤", "𝙥", "𝙦", "𝙧", "𝙨", "𝙩", "𝙪", "𝙫", "𝙬", "𝙭", "𝙮", "𝙯", "𝘼", "𝘽", "𝘾", "𝘿", "𝙀", "𝙁", "𝙂", "𝙃", "𝙄", "𝙅", "𝙆", "𝙇", "𝙈", "𝙉", "𝙊", "𝙋", "𝙌", "𝙍", "𝙎", "𝙏", "𝙐", "𝙑", "𝙒", "𝙓", "𝙔", "𝙕", }, }, { "tt", { "𝚊", "𝚋", "𝚌", "𝚍", "𝚎", "𝚏", "𝚐", "𝚑", "𝚒", "𝚓", "𝚔", "𝚕", "𝚖", "𝚗", "𝚘", "𝚙", "𝚚", "𝚛", "𝚜", "𝚝", "𝚞", "𝚟", "𝚠", "𝚡", "𝚢", "𝚣", "𝙰", "𝙱", "𝙲", "𝙳", "𝙴", "𝙵", "𝙶", "𝙷", "𝙸", "𝙹", "𝙺", "𝙻", "𝙼", "𝙽", "𝙾", "𝙿", "𝚀", "𝚁", "𝚂", "𝚃", "𝚄", "𝚅", "𝚆", "𝚇", "𝚈", "𝚉", "𝟶", "𝟷", "𝟸", "𝟹", "𝟺", "𝟻", "𝟼", "𝟽", "𝟾", "𝟿" }, }, { "gr tf", { "α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "ς", "σ", "τ", "υ", "φ", "χ", "ψ", "ω", "Α", "Β", "Γ", "Δ", "Ε", "Ζ", "Η", "Θ", "Ι", "Κ", "Λ", "Μ", "Ν", "Ξ", "Ο", "Π", "Ρ", "΢", "Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω", }, }, { "gr bf", { "𝛂", "𝛃", "𝛄", "𝛅", "𝛆", "𝛇", "𝛈", "𝛉", "𝛊", "𝛋", "𝛌", "𝛍", "𝛎", "𝛏", "𝛐", "𝛑", "𝛒", "𝛓", "𝛔", "𝛕", "𝛖", "𝛗", "𝛘", "𝛙", "𝛚", "𝚨", "𝚩", "𝚪", "𝚫", "𝚬", "𝚭", "𝚮", "𝚯", "𝚰", "𝚱", "𝚲", "𝚳", "𝚴", "𝚵", "𝚶", "𝚷", "𝚸", "𝚹", "𝚺", "𝚻", "𝚼", "𝚽", "𝚾", "𝚿", "𝛀", }, }, { "gr it", { "𝛼", "𝛽", "𝛾", "𝛿", "𝜀", "𝜁", "𝜂", "𝜃", "𝜄", "𝜅", "𝜆", "𝜇", "𝜈", "𝜉", "𝜊", "𝜋", "𝜌", "𝜍", "𝜎", "𝜏", "𝜐", "𝜑", "𝜒", "𝜓", "𝜔", "𝛢", "𝛣", "𝛤", "𝛥", "𝛦", "𝛧", "𝛨", "𝛩", "𝛪", "𝛫", "𝛬", "𝛭", "𝛮", "𝛯", "𝛰", "𝛱", "𝛲", "𝛳", "𝛴", "𝛵", "𝛶", "𝛷", "𝛸", "𝛹", "𝛺", }, }, { "gr bi", { "𝜶", "𝜷", "𝜸", "𝜹", "𝜺", "𝜻", "𝜼", "𝜽", "𝜾", "𝜿", "𝝀", "𝝁", "𝝂", "𝝃", "𝝄", "𝝅", "𝝆", "𝝇", "𝝈", "𝝉", "𝝊", "𝝋", "𝝌", "𝝍", "𝝎", "𝜜", "𝜝", "𝜞", "𝜟", "𝜠", "𝜡", "𝜢", "𝜣", "𝜤", "𝜥", "𝜦", "𝜧", "𝜨", "𝜩", "𝜪", "𝜫", "𝜬", "𝜭", "𝜮", "𝜯", "𝜰", "𝜱", "𝜲", "𝜳", "𝜴", }, }, { "gr ss bf", { "𝝰", "𝝱", "𝝲", "𝝳", "𝝴", "𝝵", "𝝶", "𝝷", "𝝸", "𝝹", "𝝺", "𝝻", "𝝼", "𝝽", "𝝾", "𝝿", "𝞀", "𝞁", "𝞂", "𝞃", "𝞄", "𝞅", "𝞆", "𝞇", "𝞈", "𝝖", "𝝗", "𝝘", "𝝙", "𝝚", "𝝛", "𝝜", "𝝝", "𝝞", "𝝟", "𝝠", "𝝡", "𝝢", "𝝣", "𝝤", "𝝥", "𝝦", "𝝧", "𝝨", "𝝩", "𝝪", "𝝫", "𝝬", "𝝭", "𝝮", }, }, { "gr ss bi", { "𝞪", "𝞫", "𝞬", "𝞭", "𝞮", "𝞯", "𝞰", "𝞱", "𝞲", "𝞳", "𝞴", "𝞵", "𝞶", "𝞷", "𝞸", "𝞹", "𝞺", "𝞻", "𝞼", "𝞽", "𝞾", "𝞿", "𝟀", "𝟁", "𝟂", "𝞐", "𝞑", "𝞒", "𝞓", "𝞔", "𝞕", "𝞖", "𝞗", "𝞘", "𝞙", "𝞚", "𝞛", "𝞜", "𝞝", "𝞞", "𝞟", "𝞠", "𝞡", "𝞢", "𝞣", "𝞤", "𝞥", "𝞦", "𝞧", "𝞨", }, }, { "op", { }, }, { "sy a", { }, }, { "sy b", { }, }, { "sy c", { }, }, } local mathlists = { } local mathselector = { } for i=1,#mathsets do local mathset = mathsets[i] mathselector[#mathselector+1] = mathset[1] mathlists[mathset[1]] = mathset[2] end local enabled = 0 local usedlists = { { name = "text", current = "en", lists = textlists, selector = textselector }, { name = "math", current = "tf", lists = mathlists, selector = mathselector }, } local function make_strip() local used = usedlists[enabled] local lists = used.lists local alphabet = lists[used.current] local selector = "(hide)(" .. concat(used.selector,")(") .. ")" local alphabet = "(" .. used.current .. ":)(" .. concat(alphabet,")(") .. ")" scite.StripShow(selector .. "\n" .. alphabet) end local function hide_strip() scite.StripShow("") end local function process_strip(control) local value = scite.StripValue(control) if value == "hide" then hide_strip() return elseif find(value,".+:") then return end local used = usedlists[enabled] if used.lists[value] then used.current = value make_strip() else editor:insert(editor.CurrentPos,value) end end local function ignore_strip() end function toggle_strip(name) enabled = enabled + 1 if usedlists[enabled] then make_strip() OnStrip = process_strip else enabled = 0 hide_strip() OnStrip = ignore_strip end end end -- Last time I checked the source the output pane errorlist lexer was still -- hardcoded and could not be turned off ... alas. -- output.Lexer = 0 -- SCI_SETBIDIRECTIONAL = SC_BIDIRECTIONAL_R2L -- Because SCITE messes around with package.loaded a regular require doesn't work, so -- we overload it. We also add some paths. do package.path = props.SciteDefaultHome .. "/context/lexers/?.lua;" .. package.path package.path = props.SciteDefaultHome .. "/context/lexers/themes/?.lua;" .. package.path package.path = props.SciteDefaultHome .. "/context/lexers/data/?.lua;" .. package.path local required = require local loaded = { } require = function(name) local data = loaded[name] if not data then data = required(name) loaded[name] = data end return data end end -- It makes not much sense to trace back over whitespace and start lexing because in -- our use case we can have nested lexers that themselve need a trace back. Also, in -- large documents we seldom add at the end and therefore can as well parse the -- whole document. Lua 5.4 is faster anyway. -- -- The 'editor' object is not useable because (1) it is null terminating which is -- bad for the PDF lexer. The 'styler' on the other hand is utf based and does not -- work well for the byte based LPEG lexers. And, because 'OnStyle' creates a large -- userdata blob anyway, we added a few methods to it. -- -- Because this file will be reloaded after a change, and in the process messes with -- some global properties (like package.loaded) we have some require hackery in the -- lexer files. -- function OnStyle(styler) -- local S_DEFAULT = 0 -- local S_IDENTIFIER = 1 -- local S_KEYWORD = 2 -- local S_UNICODECOMMENT = 3 -- local identifierCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -- styler:StartStyling(styler.startPos, styler.lengthDoc, styler.initStyle) -- while styler:More() do -- if styler:State() == S_IDENTIFIER then -- if not identifierCharacters:find(styler:Current(), 1, true) then -- local identifier = styler:Token() -- if identifier == "if" or identifier == "end" then -- styler:ChangeState(S_KEYWORD) -- end -- styler:SetState(S_DEFAULT) -- end -- elseif styler:State() == S_UNICODECOMMENT then -- if styler:Match("»") then -- styler:ForwardSetState(S_DEFAULT) -- end -- end -- if styler:State() == S_DEFAULT then -- if styler:Match("«") then -- styler:SetState(S_UNICODECOMMENT) -- elseif identifierCharacters:find(styler:Current(), 1, true) then -- styler:SetState(S_IDENTIFIER) -- end -- end -- styler:Forward() -- end -- styler:EndStyling() -- end -- function OnStyle(styler) -- local lineStart = editor:LineFromPosition(styler.startPos) -- local lineEnd = editor:LineFromPosition(styler.startPos + styler.lengthDoc) -- editor:StartStyling(styler.startPos, 31) -- for line=lineStart,lineEnd,1 do -- local lengthLine = editor:PositionFromLine(line+1) - editor:PositionFromLine(line) -- local lineText = editor:GetLine(line) -- local first = string.sub(lineText,1,1) -- local style = 0 -- if first == "+" then -- style = 1 -- elseif first == " " or first == "\t" then -- style = 2 -- end -- editor:SetStyling(lengthLine, style) -- end -- end do local lexers = nil local properties = props local partial = false local partial = true local trace = false -- local trace = true local loadedlexers = setmetatable ( { }, { __index = function(t,k) local language = match(k,"^script_(.*)$") or k if not lexers then lexers = require("scite-context-lexer") lexers.loadtheme(require("scite-context-theme")) end local name = "scite-context-lexer-" .. language local v = lexers.load(name) if v then lexers.registertheme(properties,language) else v = false end t[name] = v t[k] = v t[language] = v return v end } ) local function update(language,size,start,stop) if language then local syntax = loadedlexers[language] if syntax then lexers.scite_onstyle(syntax,editor,partial,language,props.FileNameExt,size,start,stop,trace) end end end function Initialise() check_output_pane() end function OnStyle(styler) -- for the moment here: editor.StyleClearAll(output) -- we have no way to nil the output lexer update(styler.language,editor.TextLength,styler.startPos,styler.lengthDoc) end function OnOpen(filename) if trace then report("opening '%s' of %i bytes, language '%s'",filename,editor.TextLength,props.Language) end update(props.Language,editor.TextLength,0,editor.TextLength) check_output_pane() end function OnSwitchFile(filename) if dirty[props.FileNameExt] then if trace then report("switching '%s' of %i bytes, language '%s'",filename,editor.TextLength,props.Language) end update(props.Language,editor.TextLength,0,editor.TextLength) dirty[props.FileNameExt] = false end check_output_pane() end function OnChar() if not editor:AutoCActive() then local syntax = loadedlexers[props.Language] if syntax and syntax.completion then local stop = editor.CurrentPos local start = editor:WordStartPosition(stop,true) local length = stop - start if length >= 2 then local snippet = editor:textrange(start,stop) local list = syntax.completion(snippet) if list then editor.AutoCMaxHeight = 30 editor.AutoCSeparator = 32 editor:AutoCShow(length,list) end end end end end end -- function OnKey(a,b,c) -- print("key",a,b,c) -- end