使用 Pygments 对 Vimwiki 进行代码高亮

Fri 27 December 2013

Vimwiki 推荐的代码高亮机制是通过一个 JavaScript 插件来完成的, 那样需要加载很多 js, 所以不想使用, 比较倾向使用 Pygments 在 Vimwiki 生成 HTML 的时候对代码进行高亮.

尝试

使用 custom_wiki2html 选项

仔细的看了 Vimwiki 的帮助文档, 发现有一个 custom_wiki2html (:h vimwiki-option-custom_wiki2html) 的选项可以指定自己 的脚本来处理 wiki2html, 尝试了一下, 发现这个脚本是在生成 HTML 之前调用, 而且如果对 wiki 文件处理之后无法替换回原来的内容(后来发现这个仅仅是对使用 Markdown 语法作为 Wiki 语法设定的), 所以放弃了.

Fork 仓库, 更改代码

后来想想既然原生的没有解决办法, 所以就干脆在 github 上 fork 了仓库 clone 到本地进行修改, 通过直接 hack 代码在 Vimwiki 处理之前对代码进行高亮.

思路

粗略的看了下代码, Vimwiki 是将文件读入, 然后逐行处理, 看来只能在文件读取之后 对内容做一些操作.

Vimscript 的 readfile 返回一个列表, 每一个元素代表一行, 编写一个函数处理这个 列表, 并返回, 在 autoload/vimwiki/html.vim 里的 第 1350 行找到 vimwiki#html#CustomWiki2HTML 函数, 并在其上面添加一个函数

function! s:highlight_code_with_pygments(lsource) "{{{
  if !has('python')
    return a:lsource
  endif
  let s:lsource = deepcopy(a:lsource)
  let s:content = ''
python <<EOF
def handle():
  import vim

  import re
  import os

  try:
    import pygments
  except ImportError:
    vim.command("echoerr 'Cannot import pygments library, please install it.'")
    return

  from pygments.lexers import get_lexer_by_name
  from pygments.formatters import HtmlFormatter
  from pygments import highlight
  from pygments.util import ClassNotFound

  CODE_RE = re.compile(r'\n({{{(\w*?)\s(.*?)\s}}})', re.M|re.U|re.S)

  data = vim.eval("s:lsource")
  content = "\n".join(data)
  new = False
  css_class = vim.eval("VimwikiGet('pygments_class')")
  for source, lang_type, code in CODE_RE.findall(content):
    lang_type = lang_type or "text"
    try:
      lexer = get_lexer_by_name(lang_type)
    except ClassNotFound:
      lexer = get_lexer_by_name("text")

    formatter = HtmlFormatter(encoding="utf8", cssclass=css_class,
                              noclasses=False, style="default",
                              linenos = None, nowrap = True)

    hcode = highlight(code, lexer, formatter)
    content = content.replace(source, hcode)
    if new is False:
      new = True

  if new:
    vim.command("let s:content='%s'" % content.replace("'", "\'"))

handle()

EOF

  if s:content != ''
    let s:lsource = split(s:content, '\n')
  endif

  return s:lsource
endfunction "}}}

然后在 vimwiki#html#Wiki2HTML 函数内读取文件的下面调用此函数

...
    let lsource = readfile(wikifile)

    let lsource = s:highlight_code_with_pygments(lsource)
...

当然需要还需要拷贝 css 文件, 修改模板等, 这里不一一详述

结果

好吧, 确实工作了, 但是新的问题出来了, 高亮后替换成HTML的内容会被 Vimwiki 第二次处理 所以 HTML 的格式全乱了, CSS 样式也肯定不行了. 找了一下没有办法能避免 Vimwiki 不 处理一段内容(为什么已经是 HTMl 了 Vimwiki 还要处理呢)

上述方法不行, 那只能再想想办法了

使用特殊的注释: %nowiki

为了解决上面重复处理已转化成 HTML 内容的问题, 我添加 %nowiki 语法, 以 %nowiki 这个开头的行将不处理. 然后将高亮的代码替换成 %nowiki 开始的行, 将上面 Python 相关代码加上如下内容:

...
hcode = highlight(code, lexer, formatter)

# 添加以下语句
hcode = "%nowiki" + '\n%nowiki'.join(hcode.split("\n"))

content = content.replace(source, hcode)
..

然后找到 s:parse_line 函数, 在处理 toc 的下面添加

  " toc -- placeholder "{{{
  if !processed
    if line =~ '^\s*%toc'
      let processed = 1
      let param = matchstr(line, '^\s*%toc\s\zs.*')
      let state.placeholder = ['toc', param]
    endif
  endif
  "}}}

  " 添加处理 nowiki
  " nowiki "{{{
  if !processed
    if line=~ '^\s*%nowiki'
      let processed = 1
      call add(res_lines, substitute(line, '^\s*%nowiki', '', ''))
    endif
  endif "}}}

然后找到 s:safe_html 函数, 添加如下语句

function! s:safe_html(line) "{{{
  " 不处理 %nowiki 
  if a:line=~ '^\s*%nowiki'
    return a:line
  endif

  ...
endfunction

大功告成, 这样就可以正常的使用 pygments 进行高亮代码

成果

修改后的代码放在了 github 上, 在 这里, 有需要的可以安装, 但这个更改仅仅是对我个人使用, 可能不会跟随主线程版本的更新.

当然我添加了一些选项来开启/关闭使用pygments, 安装后在 Vim 中执行 :h vimwiki-option-use_pygments

大家通过代码也看到了, 要使用改变之后的插件 Vim 需要编译 +python 并且需要安装 pygments Python 库.

Category: Vim Tagged: vim vimwiki pygments python highlight

comments


使用 Vimwiki + git 做知识管理

Thu 26 December 2013

一直在找一个合适的知识管理工具, 用过 Evernote, 但是不支持 Markdown, 用了一段时间也放弃了. 最近 python-cn 列表里也在讨论这个问题, 看到有人使用 Vimwiki, 所以就尝试了一下.

安装后,试着写了点东西, 发现很方便做知识管理和记录笔记, 可以生成HTML, 可以定制模板, 这里不讨论如何使用, Vimwiki 的文档介绍的很详细,

我使用bootstrap和 jquery 对模板进行了一些定制:

  • 添加导航
  • 将toc移动到左侧

下面将介绍我是如何做的, 并在最后附上如何部署的

指定模板

首先需要更改默认模板

    let g:vimwiki_list = [{'path': '~/vimwiki',
    \    'path_html': '~/vimwiki_html',
    \    'template_path': '~/vimwiki/template',
    \    'template_default': "default.tpl"}]

并将默认的模板作为模板进行修改

mkdir -p ~/vimwiki/template
cp …

Category: Vim Tagged: vim vimwiki wiki 知识 管理 git

comments

Read More

推荐几款最近发现非常酷的Vim插件

Fri 18 October 2013

最近看一个github上的Vim配置, 发现了几款非常酷而且非常有用的Vim插件:

  • delimitMate 用于补全括号和引号
  • vim-surround 用于快速切换括号/引号或者标签
  • GitGutter 实时显示git更改
  • Gitv 查看Git详细提交日志(类似gitk)
  • vim-commentary Vim批量注释工具, 可以注释多行和去除多行注释
  • indentLine 更加美观的显示缩进对齐线

先放上录屏:

安装

上面插件可以通过 Vundle 来安装 (了解Vundle猛击 这里), 下面是 .vimrc 的配置

Bundle "Yggdroot/indentLine"
Bundle "airblade/vim-gitgutter"
Bundle "gregsexton/gitv"
Bundle "tpope/vim-commentary"
Bundle "tpope/vim-surround"
Bundle "Raimondi/delimitMate"

然后重新打开 Vim, 执行 :BundleIntall 等待安装完成 …

Category: Vim Tagged: Vim 插件 缩进对齐线 Git surround delimitMate

comments

Read More

Vim 相对行号

Wed 09 October 2013

大家在用Vim时是否会遇到想复制多行或者想快速向下/向上移动多行时而不知道行数的情况, 相对行号将帮助你轻易的完成类似的任务

Category: Vim Tagged: Vim 相对 行号

comments

Read More

Vim 代码补全和检查: YouCompleteMe & syntastic

Wed 14 August 2013

Vim 7.4 发布, 最近升级了Vim, 并安装了YouCompleteMe和Syntastic插件, 这里记录下过程

升级Vim

YouCompleteMe 需要Vim 7.3.584+的支持, 并且开启 +python , 可以通过:version查看 升级Vim需要先卸载原有的Vim

sudo apt-get remove vim vim-tiny vim-common vim-runtime gvim vim-gui-common

并安装以下依赖

sudo apt-get install libncurses5-dev libgnome2-dev libgnomeui-dev \
    libgtk2.0-dev libatk1.0-dev libbonoboui2-dev \
    libcairo2-dev libx11-dev libxpm-dev libxt-dev \
    python-dev ruby-dev mercurial checkinstall

下载最新的Vim源码 …

Category: Vim Tagged: Vim 补全 7.4 升级 检查 C语言 YouCompleteMe syntastic

comments

Read More

Vim配置系列(二) —- 好看的statusline

Sat 05 January 2013

Vim是一款文本编辑器,但是这并不影响它有一个好看的外观,大家都知道Vim可以通过配色方案来改变Vim的外观,满足一些"好色之徒",之前大家可能也主意到截图中一个非常漂亮的statusline,这是通过Vim的一个Powerline的插件实现的.之前我们配置了Vundle的插件管理(传送门)我们可以用Vundle安装Powerline,在.vimrc(Windows可能是_vimrc)中添加:

Bundle "Lokaltog/vim-powerline"

然后重新打开vim执行

:BundleInstall

如果你和github畅通的话就会顺利安装插件,然后在.vimrc里添加

set laststatus=2
let g:Powerline_symbols='unicode'

如果gvim打开需要使用/path/to/your/bundle/vim-powerline/fontpatcher/fontpatcher给当前gvim使用的字体打上补丁(依赖需要fontforge和python)

然后重新打开vim你就会发现一个漂亮的statusline

好看的statusline

Category: Vim Tagged: 配置 系列 漂亮 插件 vim statusline Powerline

comments

Read More

Vim 结合Python编写的翻译插件

Fri 04 January 2013

最近重写了一下之前用Python写的一个终端翻译工具,想着Vim7.3 支持Python于是想将这个功能写为一个插件让Vim也支持翻译功能,现在英汉翻译比较完善, t会翻译光标下单词,选中的翻译还不完善,仅仅是个半成品,在此抛砖引玉.将下面代码复制保存为translate.vim 放到~/.vim/plugin目录下即可,代码如下:

"   Author  :   cold
"   E-mail  :   wh_linux@126.com
"   Date    :   2012/12/20 16:23
"   Desc    :   英汉/汉英翻译插件
"   Useage  :
"                  <Leader> t 翻译当前光标下内容 //XXX 中文不行
"                  <Leader> lt 翻译当前行
"                  <Leader> vt 翻译选中的内容

function GetCursorWord()
    let column = get(getpos('.'), 2, 0 …

Category: Vim Tagged: 翻译 插件 vim python

comments

Read More

Vim配置系列(一) ---- 插件管理

Fri 14 December 2012

最近对Vim进行了一番较大的配置变动,所以就想写出一个系列来将配置过程分享下来,供需要的朋友参考.我们之前配置Vim插件是一大助力,可以帮助我们做一些比较cool或这比较实用的功能,但是我之前都是直接搜索插件然后下载下来,手动拷贝到相应的插件,这种感觉肯定是不爽,不管是Linux还是Python/Ruby都有一套自己的包管理器,可以比较智能的搜索/安装/升级/卸载包.Vim也有类似功能的插件Vundle,他是一款Vim插件管理器,依赖于git,git是一款非常棒的VCS这里不做介绍,有兴趣的可以了解一下.Vundle可以根据配置文件的github或其他git的路径自行安装/升级插件.下面我们来介绍如何安装: 首先在你的~/.vim下或者$VIM/vimfiles($VIM是vim的安装路径)创建bundle目录

mkdir ~/.vim/bundle

然后使用git克隆Vundle项目:

git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

然后在你的.vimrc里添加下面内容:

set nocompatible
filetype off                              " 先关闭文件类型 …

Category: Vim Tagged: 配置 系列 管理 插件 Vundle vim Bundle

comments

Read More

Vim打开Python源码自动添加#!行和编码行 升级版

Thu 13 December 2012

之前给大家分享过一个打开Python源代码时自动添加#!行和编码行来避免一些重复的工作,那个是因为需要大量编写时临时的解决方案,后来使用中会出现一些问题,比如查看别人源码时也会更改一些东西,从而造成git不必要的更新和手动删除的额外动作,所以又写了一个,只是在文件是新打开文件时或者空文件才自动添加的方法,同时再打开python源文件将这个方法绑定要F4上可以手动添加,并会判断是否有这两行,如果有则不执行动作,同时也添加了一些辅助性注释, 比如 作者/邮箱/创建日期和描述,代码实现如下:

"Python 注释
function InsertPythonComment()
    exe 'normal'.1.'G'
    let line = getline('.')
    if line =~ '^#!.*$' || line =~ '^#.*coding:.*$'
        return
    endif
    normal O
    call setline('.', '#!/usr/bin/env python')
    normal o
    call setline('.', '# -*- coding:utf-8 -*-')
    normal o …

Category: Vim Tagged: 自动 编码信息 添加 vim shbang line python

comments

Read More

用Vim为Python源码自动添加#!行和编码行

Sat 29 September 2012

每次开始写Python打开文件第一件事就是写上#!/usr/bin/env python和编码之类的东西,

太多了,写烦就,写了一个打开Python自动填充的函数,将下面内容添加到~/.vimrc下即可每次打开如果没有上述行则会自动填充:

function InsertPythonHeader()
    let l1 = getline(1)
    let l2 = getline(2)
    if  match('\#!/', l1) == 0
        exec 1
        normal O
        call setline(1,'#!/usr/bin/env python')
    endif
    if match("\#", l2) == 0 && (match("-", l2)  != 2 ¦¦ (match("code", l2) != 2))
        exec …

Category: Vim Tagged: 自动 编码信息 添加 vim shbang line python

comments

Read More
Page 1 of 2

Next »