ans42

assert(random() == 0x2a)

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1 动机

Html作为一种文档格式其实还是比较好的,支持图片,超链接。 一般只要不使用过于复杂的JavaScript,兼容性也不成问题。 最主要的一点,有很多工具可以生成Html,比如asciidoc, txt2tags, emacs/org-mode.

但是如果Html引用了外部图片或css,则在拷贝html文档时要注意把图片也带上,不太方便。 解决这种问题有三种办法:

  1. 使用IE转为mht
  2. 使用acrobat转为pdf
  3. 使用data uri schema将图片嵌入html。

方法3如果可行,显然更好。在网上没找到相关工具,于是自己写了一个。

2 代码

#!/usr/bin/env python2
'''
Convert external referenced img/css to be inlined using data uri schema
snippet as:
 <img src="a.png" alt="a.png"/>
will converted to:
 <img src="data:image/png;base64,iVBORw0KGgoAAAA" alt="a.png"/>
Usage:
inline.py src-html to-html
'''
import sys
import os
import re

def read(path, mode='r'):
    try:
        with open(path, mode) as f:
            return f.read()
    except IOError:
            return ''

def write(path, content):
    with open(path, 'w') as f:
        f.write(content)

def get_ext(name):
    index = name.rfind('.')
    if index == -1: return ""
    return name[index+1:].lower()

def mime(url):
    mime_types  = dict(png='image/png', svg='image/svg+xml', jpg='image/jpeg', jpeg='image/jpeg', css='text/css')
    return mime_types.get(get_ext(url), 'image/unknown')

def multi_sub(pats, repl, content):
    for p in pats:
        content = re.sub(p, repl, content)
    return content

def inline(content, base_dir='.'):
    def data_uri(url):
        print 'data_uri(%s)'%(repr(url))
        content = read(os.path.join(base_dir, url), 'rb')
        if not content:
            return url
        else:
            return 'data:%s;base64,%s' %(mime(url), content.encode("base64").replace("\n", ""))
    img_pat = '(<img\s+src\s*=\s*")(.*?)(".*?/>)'
    css_pat = '(<link\s+rel="stylesheet"\s+type="text/css"\s+href=")(.*?)(".*?/>)'
    return multi_sub([img_pat, css_pat], lambda m: '%s%s%s'%(m.group(1), data_uri(m.group(2)), m.group(3)), content)

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print __doc__
        sys.exit(1)
    write(sys.argv[2], inline(read(sys.argv[1]), os.path.dirname(sys.argv[1])))

3 使用方法:

./inline.py src.html inlined.html
posted on 2011-12-13 22:34  ans42  阅读(732)  评论(0编辑  收藏  举报