3
2
2012
6

为 Chito 修改 Markdown

本文来自依云's Blog,转载请注明。

我使用 Markdown 写博客已经有段时间了,但是一直以来有个小小的问题:对于代码块,markdown 生成的是一个<pre>标签里套一个<code>标签。缩进四个空格还好,用 Vim 的列编辑就行了(>操作不行,因为空行不会被缩进),可是删除这些<code>标签并加上相应的语言标识很烦。于是有了以下 Python 代码,使用的是 Python 版的 markdown,支持使用~~~~作为代码分隔符,如:

~~~~python|这是 Python 代码
print('Hello Python!')
~~~~

将会被翻译为

<pre class="brush: python;" title="这是 Python 代码">print('Hello Python!')
</pre>

程序如下:

#!/usr/bin/env python3
# vim:fileencoding=utf-8

import sys
from itertools import takewhile

import markdown
from lxml.html import fromstring, tostring

def parseAttr(s):
  a = s.split('|')
  if len(a) > 3:
    raise ValueError('Too many attributes')
  a = list(map(str.strip, a))
  if len(a) == 3:
    a[2] = bool(a[2])
  elif len(a) == 2:
    a.append(False)
  elif len(a) == 1:
    a.extend(['', False])
  else:
    a = ['plain', '', False]
  if not a[0]:
    a[0] = 'plain'
  return a

def analyseAttrs(text):
  '''Attributes are defined like this:

  ~~~~lang|title|collapse

  In place of ``collapse``, anything not empty is considered true.
  '''
  incode = False
  lines = []
  attrs = []
  istilda = lambda ch: ch == '~'
  for l in text.split('\n'):
    if l.startswith('~~~~'):
      if not incode:
        incode = len(tuple(takewhile(istilda, l)))
        attr = parseAttr(l.lstrip('~'))
        attrs.append(attr)
        l = tildas = '~' * incode
      else:
        if l.find(tildas) == 0:
          incode = False
    lines.append(l)
  return '\n'.join(lines), attrs

def applyAttrs(html, attrs):
  doc = fromstring(html)
  for i, code in enumerate(doc.xpath('//pre/code')):
    pre = code.getparent()
    text = pre[0].text
    del pre[:]
    pre.text = text
    attr = attrs[i]
    c = 'brush: %s;' % attr[0]
    if attr[2]:
      c += ' collapse: true;'
    pre.set('class', c)
    if attr[1]:
      pre.set('title', attr[1])
  return tostring(doc, encoding=str)[5:-6] + '\n'

def main():
  text = sys.stdin.read()
  text, attrs = analyseAttrs(text)
  out = markdown.markdown(text, ['fenced_code'])
  out = applyAttrs(out, attrs)
  sys.stdout.write(out)

if __name__ == '__main__':
  main()
Category: python | Tags: chito markdown python | Read Count: 6081
Avatar_small
Fermat618 说:
Mar 03, 2012 09:29:39 AM

你是把程序提交到is-programmer.com上面再直接提交的markdown么。

Avatar_small
Fermat618 说:
Mar 03, 2012 10:17:19 AM

把波浪线~叫tilda,,,,,,你怎么不叫它 tildo 呢

jiazhoulvke 说:
Mar 06, 2012 01:59:55 PM

看了文章后想试试在vim里用markdown写文章,于是搜了一下,结果发现vimrepress是支持markdown的!天啊,我居然才知道,这已经不是用“孤陋寡闻”所能形容的了。话说用markdown写东西真的很爽。

lazymonkey 说:
Apr 18, 2012 06:15:29 PM

一直都是用VimWiki转换成HTML后发表的,但有一个问题,"xmlrpc"貌似会忽略HTML中的注释,像"<!--more-->"标签就无法插入咯!

Avatar_small
依云 说:
Apr 18, 2012 06:31:40 PM

啊,我既没有用过 xmlrpc,也没用过 <!--more-->。。。。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com