用 vimwiki 搭建你自己的维基世界
为什么要使用 vimwiki
众所周知,维基语法的作用有三点。1. 使条目更规范。通过一定转换,wiki 能输出为拥有约定俗成格式的HTML;2. 节约编辑时间。 显然,你不用写出完整的HTML标签,也不用在可视化编辑器中点来点去;3. 充分的可读性。使用维基语法书写的文档,即使未被转为HTML,内容的语义也是一目了然,甚至表格也能清晰地阅读。相较而言,UBB什么的简直就是扯淡嘛。
使用 vimwiki ,当然是为了享受维基语法的这些优点。但 vimwiki 提供的不仅这些,它还可以帮你维护 TODO-LIST 和个人日记。它生成的HTML文件可以轻松自定义,只要你愿意,你完全能把它打造成个人网站,甚至是拥有评论系统的博客。正如我和闲耘这样。
安装 vimwiki
vimwiki 的安装同其他vim插件一样,把下载回来的东西解压到 vimfiles 里就好了。有 zip 包和 vba 包两种格式。其中 vba 是 Vim 独有的插件安装包。推荐使用 vba 安装,因为它能保存你的安装信息,不高兴了还可以卸载(详细说明请:h vba
)。要使用这种安装方式,需要有 vimball 插件。Windows 下的 gvim 已经自带。如果你还没有这东西,可以先到 vim.org 自行下载。
使用 Vim 打开 vimwiki.vba ,然后执行 :so %
,就这么简单。
如果你选择了 zip 包,解压完成后你可能还需要重建帮助文件索引。请执行 :helptags $VIMFILES/doc
。其中
$VIMFILES 就是您的 vimfiles 目录。这是需要在 vimrc 中定义的系统变量, Windows 下应该是 $VIM/vimfiles
, Linux 下是 ~/.vim/
。请检查您的 vimrc 里是否有这样的代码:
if has("win32") let $VIMFILES = $VIM.'/vimfiles' else let $VIMFILES = $HOME.'/.vim' endif
如果还没有,就赶快加上吧。
如果你正在使用 MRU ,并且设置了 MRU_Include_Files
,记得把 .wiki 也包括进去。
装好之后,您可以马上使用 :h vimwiki
查看帮助。相信我,查看帮助文档绝对是最管用的学习方式(虽然耗时更久,但学得更全面,省去许多将来求助搜索引擎的时间)。当然,如果你英文不好,看不太懂,本文的存在就是为了帮助你,别急,慢慢来。
开始使用 vimwiki
使用快捷键 <leader>ww
开始编辑您的第一个 vimwiki 吧! 首次使用 vimwiki 时, 它默认会在操作系统用户目录(即 ~/
)建立一个 vimwiki 文件夹,保存所有你的 wiki 条目。如果你调用 :Vimwiki2HTML 命令把 wiki 条目转为 html 页面,它会创建一个名为 vimwiki_html 的文件夹保存所有生成的 html 文件。
基本的 Wiki 语法
= 一级标题 = == 二级标题 == === 三级标题 === 此次类推。 当标题前面有空白时,标题文本居中对齐。 = 我是居中的标题 = *粗体* _斜体_ ~~删除线~~ `Some Code 代码
` 注意 这几个针对文本格式的标签,都要求左右留有空白。 请注意你的代码高亮,一般来说,有了相应的高亮,你用的wiki标签才生效。 ^上^标 ,,下,,标 四个空格缩进的内容会被转成blockquote {{{ class="brush:php" 这中间的内容会被放到一个 pre 里,适合贴代码。 上面的 class 是可选的,一般用来安排代码高亮。 事实上,这一块代码展示就是放在了一个 pre 里。 请无视下面一行的反斜杠 }}}WikiItem
大写开头的驼峰英文会被自动当作一个维基词条,并添加链接[[Wiki Item]]
这是手动建立维基词条的方式[[wiki item|description]]
输出HTML时显示description,链到 wiki itemhttp://ktmud.com/
外部URL会被自动转换成链接[http://ktmud.com Ktmud]
带文字的外链[images/hello.jpg]
输出 <img src="images/hello.jpg" />[[images/hello.jpg]]
输出图片,并链向图片地址 * 无序列表 条目一 * 无序列表 条目二 - 子列表 条目一 - 自列表 条目二 # 有序列表 条目一 # 有序列表 条目二 * 和 - 是等价的,后面必须跟一个空格
您可以查看本文的wiki源文件加深理解。
参考 :h vimwiki-syntax
特殊占位符
在wiki条目中使用以下占位符,能对生成的HTML文件做一些特殊的处理。
-
%toc
自动生成的目录 -
%title
指定HTML文档的title,建议放到文档最末尾。如果不指定,title 就是文件名 -
%nohtml
告诉 vimwiki 不为某条目生成HTML文件。即使你在该条目打开时为它单独执行:Vimwiki2HTML
,也不会生成。
生成HTML
使用 :Vimwiki2HTML
可以为当前维基条目生成HTML文件,使用 :VimwikiAll2HTML
可以为所有条目生成HTML。您可以为每个维基项目指定 auto_export
选项,这样在wiki文件保存时就会自动生成HTML。个人不建议这样做,因为当条目很大,保存就相当费时。
定义下面的快捷键映射即可:
map <S-F4> :VimwikiAll2HTML<cr>
map <F4> :Vimwiki2HTML<cr>
键操作
快捷键总览
-
<leader>ww
在当前窗口打开维基首页 -
<leader>wt
在新tab打开维基首页 -
<leader>w<leader>w
打开/新建当天日记 -
<leader>w<keader>t
在新tab打开/新建当天日记 -
<leader>ws
选择维基项目(详见下面的“多个维基项目”一节)
编辑时的按键
- 尚未建立的词条会被显示为红色(或其他你的 Vim 语法高亮定义的错误颜色),在词条上敲回车键,可以编辑这个词条。点击 Shift-回车,在新的分割窗口编辑该词条。编辑好以后点击退格(Backspace)键,可以返回链入页
- 使用 Tab 键,可以跳到下一个维基词条或链接,使用 Shift-Tab 跳到上一个
-
插入模式下使用Shift-Enter,插入
<br>
并换行 - 在标题上点击 - 和 = (也就是 - 和 + ),可以分表提升和降低标题层级
另有条目管理相关的快捷键 <leader>wd
和 <leader>wr
,分表代表删除和重命名当前条目。其中重命名条目很强大,还能更改所有其他条目内引用了该条目的链接。
重命名之后别忘了重新生成所有条目的HTML。
进阶操作
日记功能
使用快捷键 <leader>w<leader>w
可以快速编辑当天的日记。还可以配合 Calendar 插件 轻松管理你的日记。
请马上下载并安装 calendar.vim。 安装后,定义一下快捷键吧:
" calendar
map <F8> :Calendar<cr>
按 F8
调出日历窗口,按 q
退出。
在日期上点回车,就可以编辑当天的日记了!
PS: 按左右键在前后一个月里跳转,按上下键在前后一年跳转。按 t
回到当天。当然,Vim 默认的上下左右 hjkl 也是能用的。
多个维基项目
您可以配置 g:vimwiki_list
,指定多个维基项目,它们各自拥有单独的文件夹。这就允许你把工作维基和生活的琐事记录完全分开。
请打开 vimrc ,加入以下内容:
let g:vimwiki_list = [{'path': 'E:/path/to/vimwiki-1/vimwiki/', \ 'path_html': 'E:/My Dropbox/vimwiki_html/' \ 'html_header': 'E:/My Dropbox/Public/vimwiki_template/header.htm', \ 'html_footer': 'E:/My Dropbox/Public/vimwiki_template/footer.htm', \ 'diary_link_count': 5}, \{'path': 'Z:/path/to/vimwiki-2/vimwiki/'}]
这里其实定义了两个维基项目。 path
是必须的,说明你想要把 wiki 条目存在哪个目录。其他选项各有默认值。生成的HTML存放在 path_html
下默认是与 path
同目录下的 WIKIFOLDER_html
,其中 WIKIFOLER 是你存放维基条目的文件夹名。你可以分别为每个 wiki 项目指定 html 头部和尾部模板,建议把模板文件后缀采用 htm ,既和生成的 html 有所区分,又能保证语法高亮和各种 ftplugin 可用。 diary_link_count
是指 diary.wiki 里每行放多少个日志链接。
定义好之后,你可以使用 <leader>ws
选择当前活动的维基项目。使用 <leader>ws
会弹出一个维基项目的列表,并带有编号,使用这个编号加上“快捷键总览”部分的快捷键,就可以打开相应项目的首页、日记等。如 2<leader>w<leader>w
就是在当前窗口打开列表中第二个项目的日记。
更多选项请参考 :h viwmiki-local-options
任务管理 TODO-list
Loading...
编辑表格
Loading...
调教你的 vimwiki
更改一点默认配置
目前我的 vimrc 里有这些内容:
" vimwiki " 是否在词条文件保存时就输出html 这个会让保存大词条比较慢 所以我默认没有启用 有需要的话就把这一行复制到下面去 " \ 'auto_export': 1, " 多个维基项目的配置 let g:vimwiki_list = [{'path': 'E:/My Dropbox/vimwiki/', \ 'html_header': 'E:/My Dropbox/Public/vimwiki_template/header.htm', \ 'html_footer': 'E:/My Dropbox/Public/vimwiki_template/footer.htm', \ 'diary_link_count': 5}, \{'path': 'Z:\demo\qiuchi\wiki'}] " 对中文用户来说,我们并不怎么需要驼峰英文成为维基词条 let g:vimwiki_camel_case = 0 " 标记为完成的 checklist 项目会有特别的颜色 let g:vimwiki_hl_cb_checked = 1 " 我的 vim 是没有菜单的,加一个 vimwiki 菜单项也没有意义 let g:vimwiki_menu = '' " 是否开启按语法折叠 会让文件比较慢 "let g:vimwiki_folding = 1 " 是否在计算字串长度时用特别考虑中文字符 let g:vimwiki_CJK_length = 1 " 详见下文... let g:vimwiki_valid_html_tags='b,i,s,u,sub,sup,kbd,del,br,hr,div,code,h1'
警告! 以下为高级内容,虽然我手把手在教,但毕竟折腾耗时。 而且您的操作可能因为 vimwiki 将来的版本升级而失效。 请评估自己的时间成本!
做一个你自己的模板
vimwiki 生成的HTML会都会链接相应vimwiki_html目录下的style.css。如果你不自己指定,它会自动生成一个默认的。CSS禅意花园的境界是什么来着,仅仅修改 style.css 就能拥有风格完全不同的页面。通过简单修改 style.css ,你完全可以创造自己风格的维基站。加上自定义文档头部和尾部的功能,折腾出一个个人网站来绰绰有余。当然,如果你还在想新闻列表,feed订阅什么的,请赶快走开。毕竟, vimwiki 不是 CMS 。
可惜的是,并不能指定一个 style.css 的模板,如果你还折腾了一些 JavaScript 增强,就更麻烦了。需要的话请自行把相关文件复制过去吧。当然,你也可以直接把本页面另存为,使用我的模板!具体实现请自己折腾。
HTML 模板增强
使footer也可以引用 %root_path%
修改 $VIMFILES/autoload/vimwiki_html.vim ,第 1169 行
call extend(ldest, s:get_html_footer())
换为
call extend(ldest, s:get_html_footer(subdir))
相应的, s:get_html_footer 这个函数也要改一下。第 136 行,函数定义的部分:
function! s:get_html_footer()
改为
function! s:get_html_footer(subdir)
再从 s:get_html_header 里把处理 %root_path% 的部分拷过去。第 104 行:
call map(lines, 'substitute(v:val, "%root_path%", "'. \ s:root_path(a:subdir) .'", "g")')
复制到第 141 行 let lines = readfile(expand(VimwikiGet('html_footer')))
之后
在wiki里使用更多的HTML标签
vimwiki 有一个 g:vimwiki_valid_html_tags 值,可以指定允许写在 wiki 中的HTML标签。 g:vimwiki_valid_html_tags 的默认值是 'b,i,s,u,sub,sup,kbd,br,hr'
,也就是说,当你在 wiki 中输入:
<b>Hello</b> <strong>Hello</stong>
输出的HTML会显示为:
Hello <strong>Hello</stong>
标签 b
被当作可用的HTML标签,而 strong
则输出为文本。
但有时候我们需要建立更强大的维基页面,不只用到这几个标签。比如本站首页的“有什么特别的”部分,就是一个有特定 class
和 id
的 div
。于是在 vimrc 中定义:
let g:vimwiki_valid_html_tags='b,i,s,u,sub,sup,kbd,br,hr,div,del,code'
在这里我添加了 div
, del
, code
三个标签。
但是,非常不幸,当我们需要在维基里贴HTML代码,即使我们把代码放到了 {{{ }}}
包裹的 pre 里,这几个标签还是会被输出为实际的HTML标签,而不是文本。
解决办法还是修改 vimwiki_html.vim 这个文件。
找到 " WIKI2HTML "{{{
所在行,也就是开始转换HTML的地方。
在前面添加一个函数:
function s:parse_tag_keeper(line) let line = substitute(a:line,'\\<', \'\<', 'g') let line = substitute(line,'\\>', \'\>', 'g') return line endfunction
然后在之后的 s:parse_line(line, state)
函数内,插入这个函数的调用:
... let line = s:safe_html(a:line) let line = s:parse_tag_keeper(line)
这样如果我们用 <tag> 的形式输入 valid_html_tags 包括的标签,输出的HTML就会把它们当成文本处理了。
在写本文时,我需要输出 {{{ }}}
,而这对标记被作为了 wiki 里 pre
区块的 pattern 。于是就还要再写一个函数:
function s:parse_pre_keeper(line) let line = substitute(a:line,'\\{\\{\\{', \'{{{', 'g') let line = substitute(line,'\\}\\}\\}', \'}}}', 'g') return line endfunction
就把它定义在 s:parse_tag_keeper
之后吧。但调用的时候怎么办呢?肯定要放在 vimwiki_html.vim 处理了 pre 区块之后。思来想去,只能放在刚好要输出HTML文件的时候。但是 vim 的 writefile
函数,接受的参数是一个 list (相当于数组),而不是字串。既然如此,我们就把输出结果给合并了再替换,然后再包装成 list 。
找到这句:
call writefile(ldest, path.wwFileNameOnly.'.html')
稍微修改一下:
let output = join(ldest, "\n\r") let output = s:parse_pre_keeper(output) let outputlist = split(output, "\n\r") call writefile(outputlist, path.wwFileNameOnly.'.html')
之所以还要再split,是因为writefile写入的 NL 是无法用字符模拟的。这样当然会造成性能问题,如果有知道更好解决方案的,请留言告诉我。