Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local MD_MARK_ITAL = '_' -- italic
- local MD_MARK_BOLD = '**' -- bold
- local MD_MARK_LINK = '$$$' -- link description start
- local MD_MARK_LINZ = '$$$' -- link description end
- local MD_MARK_LINA = '&&&' -- link URL start
- local MD_MARK_LINT = '&&&' -- link URL end
- local MD_MARK_HEAD = '#' -- header
- local MD_MARK_CODE = '`' -- code
- local MD_MARK_BOXD = '|||' -- highlight
- local MD_MARK_MARK = ' ' -- separator
- local markup = {
- [MD_MARK_BOXD] = {st=25, fg={127,0,127}, b=true},
- [MD_MARK_CODE] = {st=26, fg={127,127,127}, fs=10},
- [MD_MARK_HEAD] = {st=27, fn="Lucida Console", b=true},
- [MD_MARK_LINK] = {st=28, u=true, hs={32,32,127}},
- [MD_MARK_BOLD] = {st=29, b=true},
- [MD_MARK_ITAL] = {st=30, i=true},
- [MD_MARK_MARK] = {st=31, v=false},
- }
- local q = EscapeMagic
- local MD_MARK_PTRN = '' -- combination of all markup marks that can start styling
- for key in pairs(markup) do
- if key ~= MD_MARK_MARK then MD_MARK_PTRN = MD_MARK_PTRN .. q(key) end
- end
- local function ismarkup (tx)
- local start = 1
- local marksep = "[%s!%?%.,;:%(%)]"
- while true do
- -- find a separator first
- local st,_,sep,more = string.find(tx, "(["..MD_MARK_PTRN.."])(.)", start)
- if not st then return end
- -- check if this is a first character of a multi-character separator
- if not markup[sep] then sep = sep .. (more or '') end
- local s,e,cap
- local qsep = q(sep)
- local nonsep = ("[^%s]"):format(qsep)
- local nonspace = ("[^%s]"):format(qsep.."%s")
- if sep == MD_MARK_HEAD then
- -- always search from the start of the line
- -- [%w%p] set is needed to avoid continuing this markup to the next line
- s,e,cap = string.find(tx,"^("..q(MD_MARK_HEAD)..".+[%w%p])")
- elseif sep == MD_MARK_LINK then
- -- allow everything based on balanced link separators
- s,e,cap = string.find(tx,
- "^(%b"..MD_MARK_LINK..MD_MARK_LINZ
- .."%b"..MD_MARK_LINA..MD_MARK_LINT..")", st)
- elseif markup[sep] then
- -- try 2+ characters between separators first
- -- if not found, try a single character
- s,e,cap = string.find(tx,"^("..qsep..nonspace..nonsep.."-"..nonspace..qsep..")", st)
- if not s then s,e,cap = string.find(tx,"^("..qsep..nonspace..qsep..")", st) end
- end
- if s and -- selected markup is surrounded by spaces or punctuation marks
- (s == 1 or tx:sub(s-1, s-1):match(marksep)) and
- (e == #tx or tx:sub(e+1, e+1):match(marksep))
- then return s,e,cap,sep end
- start = st+1
- end
- end
- local ts_style = function (editor, lines, linee)
- local lines = lines or 0
- if (lines < 0) then return end
- -- always style to the end as there may be comments that need re-styling
- -- technically, this should be GetLineCount()-1, but we want to style
- -- beyond the last line to make sure it is styled correctly
- local linec = editor:GetLineCount()
- local linee = linee or linec
- local es = editor:GetEndStyled()
- local needfix = false
- for line=lines,linee do
- local tx = editor:GetLine(line)
- local ls = editor:PositionFromLine(line)
- local from = 1
- local off = -1
- -- doing WrapCount(line) when line == linec (which may be beyond
- -- the last line) occasionally crashes the application on OSX.
- local wrapped = line < linec and editor:WrapCount(line) or 0
- while from do
- tx = string.sub(tx,from)
- local f,t,w,mark = ismarkup(tx)
- print(f)
- if (f) then
- local p = ls+f+off
- local s = bit.band(editor:GetStyleAt(p), 31)
- local smark = #mark
- local emark = #mark -- assumes end mark is the same length as start mark
- if mark == MD_MARK_HEAD then
- -- grab multiple MD_MARK_HEAD if present
- local _,_,full = string.find(w,"^("..q(MD_MARK_HEAD).."+)")
- smark,emark = #full,0
- elseif mark == MD_MARK_LINK then
- local lsep = w:find(q(MD_MARK_LINZ)..q(MD_MARK_LINA))
- if lsep then emark = #w-lsep+#MD_MARK_LINT end
- end
- editor:StartStyling(p, 31)
- editor:SetStyling(smark, markup[MD_MARK_MARK].st)
- editor:SetStyling(t-f+1-smark-emark, markup[mark].st or markup[MD_MARK_MARK].st)
- editor:SetStyling(emark, markup[MD_MARK_MARK].st)
- off = off + t
- end
- from = t and (t+1)
- end
- -- has this line changed its wrapping because of invisible styling?
- if wrapped > 1 and editor:WrapCount(line) < wrapped then needfix = true end
- end
- editor:StartStyling(es, 31)
- -- if any wrapped lines have changed, then reset WrapMode to fix the drawing
- if needfix then
- -- this fixes an issue with duplicate lines in Scintilla when
- -- invisible styles hide some of the content that would be wrapped.
- local wrapmode = editor:GetWrapMode()
- if wrapmode ~= wxstc.wxSTC_WRAP_NONE then editor:SetWrapMode(wrapmode) end
- -- if some of the lines have folded, this can make not styled lines visible
- ts_style(editor, linee+1) -- style to the end in this case
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement