Advertisement
Guest User

markup test

a guest
Oct 28th, 2014
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.97 KB | None | 0 0
  1. local MD_MARK_ITAL = '_' -- italic
  2. local MD_MARK_BOLD = '**' -- bold
  3. local MD_MARK_LINK = '$$$' -- link description start
  4. local MD_MARK_LINZ = '$$$' -- link description end
  5. local MD_MARK_LINA = '&&&' -- link URL start
  6. local MD_MARK_LINT = '&&&' -- link URL end
  7. local MD_MARK_HEAD = '#' -- header
  8. local MD_MARK_CODE = '`' -- code
  9. local MD_MARK_BOXD = '|||' -- highlight
  10. local MD_MARK_MARK = ' ' -- separator
  11. local markup = {
  12.   [MD_MARK_BOXD] = {st=25, fg={127,0,127}, b=true},
  13.   [MD_MARK_CODE] = {st=26, fg={127,127,127}, fs=10},
  14.   [MD_MARK_HEAD] = {st=27, fn="Lucida Console", b=true},
  15.   [MD_MARK_LINK] = {st=28, u=true, hs={32,32,127}},
  16.   [MD_MARK_BOLD] = {st=29, b=true},
  17.   [MD_MARK_ITAL] = {st=30, i=true},
  18.   [MD_MARK_MARK] = {st=31, v=false},
  19. }
  20. local q = EscapeMagic
  21. local MD_MARK_PTRN = ''  -- combination of all markup marks that can start styling
  22. for key in pairs(markup) do
  23.   if key ~= MD_MARK_MARK then MD_MARK_PTRN = MD_MARK_PTRN .. q(key) end
  24. end
  25.  
  26. local function ismarkup (tx)
  27.   local start = 1
  28.   local marksep = "[%s!%?%.,;:%(%)]"
  29.   while true do
  30.     -- find a separator first
  31.     local st,_,sep,more = string.find(tx, "(["..MD_MARK_PTRN.."])(.)", start)
  32.     if not st then return end
  33.  
  34.     -- check if this is a first character of a multi-character separator
  35.     if not markup[sep] then sep = sep .. (more or '') end
  36.  
  37.     local s,e,cap
  38.     local qsep = q(sep)
  39.     local nonsep = ("[^%s]"):format(qsep)
  40.     local nonspace = ("[^%s]"):format(qsep.."%s")
  41.     if sep == MD_MARK_HEAD then
  42.       -- always search from the start of the line
  43.       -- [%w%p] set is needed to avoid continuing this markup to the next line
  44.       s,e,cap = string.find(tx,"^("..q(MD_MARK_HEAD)..".+[%w%p])")
  45.     elseif sep == MD_MARK_LINK then
  46.       -- allow everything based on balanced link separators
  47.       s,e,cap = string.find(tx,
  48.         "^(%b"..MD_MARK_LINK..MD_MARK_LINZ
  49.         .."%b"..MD_MARK_LINA..MD_MARK_LINT..")", st)
  50.     elseif markup[sep] then
  51.       -- try 2+ characters between separators first
  52.       -- if not found, try a single character
  53.       s,e,cap = string.find(tx,"^("..qsep..nonspace..nonsep.."-"..nonspace..qsep..")", st)
  54.       if not s then s,e,cap = string.find(tx,"^("..qsep..nonspace..qsep..")", st) end
  55.     end
  56.     if s and -- selected markup is surrounded by spaces or punctuation marks
  57.       (s == 1   or tx:sub(s-1, s-1):match(marksep)) and
  58.       (e == #tx or tx:sub(e+1, e+1):match(marksep))
  59.       then return s,e,cap,sep end
  60.     start = st+1
  61.   end
  62. end
  63.  
  64. local ts_style = function (editor, lines, linee)
  65.   local lines = lines or 0
  66.   if (lines < 0) then return end
  67.  
  68.   -- always style to the end as there may be comments that need re-styling
  69.   -- technically, this should be GetLineCount()-1, but we want to style
  70.   -- beyond the last line to make sure it is styled correctly
  71.   local linec = editor:GetLineCount()
  72.   local linee = linee or linec
  73.  
  74.   local es = editor:GetEndStyled()
  75.   local needfix = false
  76.  
  77.   for line=lines,linee do
  78.     local tx = editor:GetLine(line)
  79.     local ls = editor:PositionFromLine(line)
  80.  
  81.     local from = 1
  82.     local off = -1
  83.  
  84.     -- doing WrapCount(line) when line == linec (which may be beyond
  85.     -- the last line) occasionally crashes the application on OSX.
  86.     local wrapped = line < linec and editor:WrapCount(line) or 0
  87.  
  88.     while from do
  89.       tx = string.sub(tx,from)
  90.       local f,t,w,mark = ismarkup(tx)
  91.       print(f)
  92.      
  93.       if (f) then
  94.         local p = ls+f+off
  95.         local s = bit.band(editor:GetStyleAt(p), 31)
  96.         local smark = #mark
  97.         local emark = #mark -- assumes end mark is the same length as start mark
  98.         if mark == MD_MARK_HEAD then
  99.           -- grab multiple MD_MARK_HEAD if present
  100.           local _,_,full = string.find(w,"^("..q(MD_MARK_HEAD).."+)")
  101.           smark,emark = #full,0
  102.         elseif mark == MD_MARK_LINK then
  103.           local lsep = w:find(q(MD_MARK_LINZ)..q(MD_MARK_LINA))
  104.           if lsep then emark = #w-lsep+#MD_MARK_LINT end
  105.         end
  106.         editor:StartStyling(p, 31)
  107.         editor:SetStyling(smark, markup[MD_MARK_MARK].st)
  108.         editor:SetStyling(t-f+1-smark-emark, markup[mark].st or markup[MD_MARK_MARK].st)
  109.         editor:SetStyling(emark, markup[MD_MARK_MARK].st)
  110.  
  111.         off = off + t
  112.       end
  113.       from = t and (t+1)
  114.     end
  115.  
  116.     -- has this line changed its wrapping because of invisible styling?
  117.     if wrapped > 1 and editor:WrapCount(line) < wrapped then needfix = true end
  118.   end
  119.   editor:StartStyling(es, 31)
  120.  
  121.   -- if any wrapped lines have changed, then reset WrapMode to fix the drawing
  122.   if needfix then
  123.     -- this fixes an issue with duplicate lines in Scintilla when
  124.     -- invisible styles hide some of the content that would be wrapped.
  125.     local wrapmode = editor:GetWrapMode()
  126.     if wrapmode ~= wxstc.wxSTC_WRAP_NONE then editor:SetWrapMode(wrapmode) end
  127.     -- if some of the lines have folded, this can make not styled lines visible
  128.     ts_style(editor, linee+1) -- style to the end in this case
  129.   end
  130. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement