[NTG-context] An idea

Nikolai Weibull mailing-lists.context-users at rawuncut.elitemail.org
Sat Dec 3 20:45:57 CET 2005


Nikolai Weibull wrote:

> It would require very little programming.  syntax/2html.vim, which
> converts the buffer to a HTML document with syntax highlighting, is 526
> lines in the current CVS incarnation.  A syntax/2context.vim would be
> even shorter, perhaps 150 to 200 lines.  If I find the time I’ll write
> something this weekend.  I’m catching a could though, so I might not
> :-(.

A splitting headache notwithstanding, here’s a syntax/2context.vim that
weighs in at 170 lines.  There are still things to do, like figuring out
how to complement this on the ConTeXt side (i.e., defining \highlight)
and things will depend on how this is done.  Some sort of \type
environment would be nice, as it is better to not do escaping of special
characters on the Vim side.  Someone with better knowledge of how to do
this than I have is welcome to finish it.  The \highlight command should
be defined something like this (pseudo-tex-code):

\pdef\highlight[#1]{#2}%
  {\bgroup
   \setupcolorforgroup[#1]%
   \type{#2}%
   \egroup}

#1 is a group name, such as Statement, Operator, or Comment.  #2 may
contain multiple lines, and I don’t know how well this will work on the
TeX side.  It may also contain special characters like {, #, &, and so
on.  Suggestions?

        nikolai

-- 
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}
-------------- next part --------------
" Vim syntax support file
" Maintainer:       Nikolai Weibull <nikolai at bitwi.se>
" Latest Revision:  2005-12-03

function! s:Format(text, group)
  let formatted = strtrans(a:text)

  " TODO: Replace the reserved ConTeXt characters.

  return "\\highlight[" . a:group . ']{' . formatted . '}'
endfun

" Set up options.
let s:old_title = &title
let s:old_icon = &icon
let s:old_et = &l:et
let s:old_report = &report
let s:old_search = @/
set notitle noicon
setlocal et
set report=1000000

" Split window to create a buffer with the HTML file.
let s:org_bufnr = winbufnr(0)
if expand("%") == ""
  new untitled.tex
else
  new %.tex
endif
let s:new_win = winnr()
let s:org_win = bufwinnr(s:org_bufnr)

" Set up options in the new buffer.
set modifiable
%d
let s:old_paste = &paste
set paste
let s:old_magic = &magic
set magic

" Set up the buffer’s “header”.
exe "normal! a\\startlines\n\e"

" Switch to the original window.
exe s:org_win . 'wincmd w'

" Variables to keep track of the range to convert.
let s:lnum = 1
let s:end = line('$')

" Set up stuff for handling folding.
if has('folding') && !exists('context_ignore_folding')
  let s:foldfillchar = &fillchars[matchend(&fillchars, 'fold:')]
  if s:foldfillchar == ''
    let s:foldfillchar = '-'
  endif
endif

" Set up stuff for handling diffs.
let s:difffillchar = &fillchars[matchend(&fillchars, 'diff:')]
if s:difffillchar == ''
  let s:difffillchar = '-'
endif

" Now, loop over all lines in the range.
while s:lnum <= s:end
  " If there are filler lines for diff mode, show these above the line.
  let s:filler = diff_filler(s:lnum)
  if s:filler > 0
    let s:n = s:filler
    while s:n > 0
      let s:new = repeat(s:difffillchar, 3)

      if s:n > 2 && s:n < s:filler && !exists('context_whole_filler')
	let s:new = s:new . " " . s:filler . ' inserted lines '
	let s:n = 2
      endif

      let s:new = s:new . repeat(s:difffillchar, &columns - strlen(s:new))

      let s:new = s:Format(s:new, 'DiffDelete')
      exe s:new_win . 'wincmd w'
      exe 'normal! a' . s:new . "\n\e"
      exe s:org_win . 'wincmd w'

      let s:n -= 1
    endwhile
    unlet s:n
  endif
  unlet s:filler

  let s:new = ""
  if has('folding') && !exists('context_ignore_folding') && foldclosed(s:lnum) > -1
    let s:new = s:Format(s:new . foldtextresult(s:lnum), 'Folded')
    let s:lnum = foldclosedend(s:lnum)
  else
    let s:line = getline(s:lnum)
    let s:len = strlen(s:line)
    let s:diffattr = diff_hlID(s:lnum, 1)

    let s:col = 1
    while s:col <= s:len || (s:col == 1 && s:diffattr)
      let s:startcol = s:col " The start column for processing text.
      if s:diffattr
	let s:id = diff_hlID(s:lnum, s:col)
	let s:col += 1
	while s:col <= s:len && s:id == diff_hlID(s:lnum, s:col) | let s:col += 1 | endwhile
        if s:len < &columns
	  " Add spaces at the end to mark the changed line.
          let s:line = s:line . repeat(' ', &columns - s:len)
          let s:len = &columns
        endif
      else
	let s:id = synID(s:lnum, s:col, 1)
	let s:col += 1
	while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) | let s:col += 1 | endwhile
      endif

      " Expand tabs.
      let s:expanded = strpart(s:line, s:startcol - 1, s:col - s:startcol)
      let idx = stridx(s:expanded, "\t")
      while idx >= 0
        let i = &ts - (idx + s:startcol - 1) % &ts
        let s:expanded = substitute(s:expanded, '\t', repeat(' ', i), '')
        let idx = stridx(s:expanded, "\t")
      endwhile

      " Output the text with the same synID, with class set to {s:id_name}.
      let s:id = synIDtrans(s:id)
      let s:id_name = synIDattr(s:id, 'name')
      if s:expanded !~ '^\s*$'
        let s:new = s:new . s:Format(s:expanded, s:id_name)
      else
        let s:new = s:new . s:expanded
      endif
    endwhile
  endif

  exe s:new_win . 'wincmd w'
  exe 'normal! a' . s:new . "\n\e"
  exe s:org_win . 'wincmd w'
  let s:lnum = s:lnum + 1
endwhile

" Cleanup.
exe s:new_win . 'wincmd w'
exe "normal! a\\stoplines\n\e"
%s:\s\+$::e
$g/^$/d

" Restore old settings
let &report = s:old_report
let &title = s:old_title
let &icon = s:old_icon
let &paste = s:old_paste
let &magic = s:old_magic
let @/ = s:old_search
exe s:org_win . 'wincmd w'
let &l:et = s:old_et
exe s:new_win . 'wincmd w'

" Save a little bit of memory (worth doing?)
unlet s:old_et s:old_paste s:old_icon s:old_report s:old_title s:old_search
unlet s:lnum s:end s:old_magic
unlet! s:col s:id s:attr s:len s:line s:new s:expandedtab
unlet s:org_win s:new_win s:org_bufnr
if !v:profiling
  delfunc s:Format
endif
silent! unlet s:diffattr s:difffillchar s:foldfillchar


More information about the ntg-context mailing list