Post syntax highlighted code in Drupal

You may have seen that I sometimes post code here. Wouldn't it be nice if all the code are syntax highlighted, like what we see in a text editor? Well, with the help of Vim, it's easy. Vim is bundled with a "2html" script, that can turn whatever shown in Vim into a HTML file, with all it's color and format. To invoke this command, simply issue ":so \$VIMRUNTIME/syntax/2html.vim" command in Vim to run the script, or more simply ":TOhtml". No, you don't have to type this many characters, autocompletion should do most of the typing for you. Vim will then open up a window that contains the newly converted HTML file.

(Update: for newer version of vim, need to :let g:html_use_css=0 first)

If I want to post it to Drupal, I simply remove the unnecessary tags such as "html", "body" and "head", etc. and save the file. When I write the blog entry, I read back the file and insert it where I want it. Also, I enclose the code with

<div class="codeblock">
code here
</div>

so the default Drupal style sheet renders the code within a nice box and on a light gray background.

This approach is much better than installing some syntax highlighting modules written in PHP on Drupal. Now the supported syntax highlighting file formats are practically unlimited, only bound by Vim's syntax highlighting repertoire, which includes pretty much every imaginable text file format. What's more, Vim's color theme applies here! So you can have all kinds of colorful code. Below are some examples.

This is my ~/.vimrc, displayed with xterm16 allblue color theme, which I use in terminal:


" vim behavior
set nocompatible

" set 256 color scheme for terminial use
set term=xterm-256color
"colors desert256
"let xterm16_brightness = 'default'     " Change if needed
let xterm16_colormap = 'allblue'       " Change if needed
"let xterm16_colormap = 'soft'       " Change if needed
colors xterm16
"colors pyte

" REQUIRED. This makes vim invoke latex-suite when you open a tex file.
filetype plugin on

" IMPORTANT: win32 users will need to have 'shellslash' set so that latex
" can be called correctly.
set shellslash

" IMPORTANT: grep will sometimes skip displaying the file name if you
" search in a singe file. This will confuse latex-suite. Set your grep
" program to alway generate a file-name.
set grepprg=grep\ -nH\ \$*

" OPTIONAL: This enables automatic indentation as you type.
filetype indent on

" TIP: if you write your \label's as \label{fig:something}, then if you
" type in \ref{fig: and press <C-n> you will automatically cycle through
" all the figure labels. Very useful!
set iskeyword+=:

" so .tex file will always be recognized as Latex.
let g:tex_flavor = "latex"

" this is mostly a matter of taste. but LaTeX looks good with just a bit
" of indentation.
set tabstop=2
set shiftwidth=2
set expandtab 

set autoindent
set smartindent

" matching brackets
set showmatch

" show cursor position
set ruler

" minibufexpl setting
let BufExplMapWindowNavVim = 1
let g:miniBufExplMapWindowNavArrows = 1
let g:miniBufExplMapCTabSwitchBufs = 1
let g:miniBufExplModSelTarget = 1

"set paste Mode On/Off
map <F11> :call Paste_on_off()<CR>
set pastetoggle=<F11>
let paste_mode = 0 " 0 = normal, 1 = paste
func! Paste_on_off()
  if g:paste_mode == 0
    set paste
    let g:paste_mode = 1
  else
    set nopaste
    let g:paste_mode = 0
  endif
  return
endfunc

" spell checking on/off
map <F10> :call Spell_on_off()<CR>
let spell_mode = 0
func! Spell_on_off()
  if g:spell_mode == 0
    setlocal spell spelllang=en_us
    let g:spell_mode = 1
  else 
    setlocal nospell
    let g:spell_mode = 0
  endif
  return
endfunc

" post blog entry to my Drupal site
" Use :e blog/nodeID_which_is_digits to open an existing entry for editting;
"     For example :e blog/12
" Use :e blog/anything_other_than_digits to open a new entry for editing
"     For example :e blog/blah
" Use :w to post it.
" Use :w blog/anything to post a file as a new blog entry

python << EOF

strUserName = 'secret'
strPassword = 'secret'
strDrupal = 'http://yyhh.org'

import vim
import xmlrpclib
import re

def PostBlog():

  #
  # If first line contains a blog entry ID then edit existing post,
  # otherwise write a new one.
  #
  nFirstLine = 0
  strID = vim.current.buffer[0]
  if not re.match( '^\d+\$', strID):
    strID = ''
  else:
    nFirstLine = 1

  strTitle = vim.current.buffer[nFirstLine]
  strText = "\n".join( vim.current.buffer[nFirstLine+1:])

  oDrupal = xmlrpclib.ServerProxy( strDrupal + '/xmlrpc.php')

  oPost = { 'title': strTitle, 'description': strText}

  if strID == '':
    strID = oDrupal.metaWeblog.newPost( 'blog', strUserName, strPassword, oPost, True)
  else:
    bSuccess = oDrupal.metaWeblog.editPost( strID, strUserName, strPassword, oPost, True)

  print "Posted entry %s" % strID

  #
  # Don't intend to write posts to disk so unmodify the buffer and
  # allow easy quit from VIM.
  #
  vim.command( 'set nomodified')

def ReadBlog( strID ):
  
  #
  # So html plugin is automatically enabled for editing the post
  # with auto-completion and syntax highlighting
  #
  vim.command('setfiletype html')

  if not strID.isdigit():
    print "New blog entry"
    return

  oDrupal = xmlrpclib.ServerProxy( strDrupal + '/xmlrpc.php')

  oBlog = oDrupal.metaWeblog.getPost( strID, strUserName, strPassword )

  vim.current.buffer[:] = []
  vim.current.buffer[0] = strID
  vim.current.buffer.append( oBlog['title'])
  vim.current.buffer.append( '')
  for strLine in oBlog['description'].split('\n'):
    vim.current.buffer.append( strLine)

EOF

:au BufWriteCmd blog/* py PostBlog() 
:au BufReadCmd blog/* py ReadBlog(vim.eval("expand('<afile>:t')"))

syntax on

On Drupal's side, I needed to enable full HTML input format, or these colorful HTML code will be removed by Drupal. Oh, another thing, do not use TinyMCE rich text editor to edit the post, because it will mess up the HTML code. Well, TinyMCE was installed here per Yunyao's request, I don't use it anyway, I use vim to edit my post:-)

Comments

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <div> <h1><h2><h3><sub><sup><b><i><u><font><img>
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Lines and paragraphs break automatically.

More information about formatting options

To prevent automated spam submissions leave this field empty.
Nice place