Hatena::ブログ(Diary)

podhmoの日記

 | 

2011-04-09

moinmoin,blockdiag

| 18:47

memo memo

## blockdiag_directive.py

# -*- coding: utf-8 -*-

from docutils import nodes

from blockdiag.diagparser import tokenize, parse
from blockdiag.DiagramDraw import DiagramDraw
from blockdiag.blockdiag import ScreenNodeBuilder
from blockdiag.elements import DiagramNode, DiagramEdge, NodeGroup
import funcparserlib.parser as parser

def with_diag_cleaning(fn):
    def _with_diag_cleaning(*args, **kw):
        DiagramNode.clear()
        DiagramEdge.clear()
        NodeGroup.clear()
        return fn(*args, **kw)
    return _with_diag_cleaning

def with_cache(fn):
    cache = {}
    def _with_cache(k, *args, **kw):
        if k in cache:
            return cache[k]
        else:
            result = fn(k, *args, **kw)
            cache[k] = result
            return result
    return _with_cache

def svg_to_svg_fragment(svg, width, height):
    import re
    params = [(u"<\?xml.*\?>\n", u"",), 
              (u"<!DOCTYPE svg PUBLIC .*>\n", u"",), 
              (u"<svg viewBox.*>", u"<svg width=%s height=%s>" % (width, height)),]
    for pat, rep, in params:
        svg = re.sub(pat, rep, svg)
    return svg

## global settings
font = "/usr/share/fonts/truetype/takao/TakaoGothic.ttf"

@with_cache
@with_diag_cleaning
def text_to_svg_fragment(text, width=None, height=None, antialias=True): 
    try:
        tree =  parse(tokenize(text))
        diagram = ScreenNodeBuilder.build(tree)
        draw = DiagramDraw("SVG", diagram, None, font=font, antialias=antialias, nodoctype=True)
        draw.draw()

        if width is None or height is None:
            xy = draw.pagesize()
            if width is None: width = xy.x
            if height is None: height = xy.y

        svg = unicode(draw.save(None), "utf-8")
        return u"<pre>%s</pre>" % svg_to_svg_fragment(svg, width, height)
    except Exception, e:
        message = u"%s: %s" % (e.__class__, str(e))
        return u"<pre>%s</pre>" % message


def blockdiag_directive(name, arguments, options, content, lineno, 
                        content_offset, block_text, state, state_machine):
    text = unicode("\n".join(content.data))
    svg = text_to_svg_fragment(text) #width, height
    return [nodes.raw("", svg, format="html")]

memo memo まだwidth,height,antialiasとかオプションで取れない

VARIANTS = {}
import blockdiag_directive
blockdiag_directive.font = "/usr/share/fonts/truetype/takao/TakaoMincho.ttf"
from blockdiag_directive import blockdiag_directive

blockdiag_directive.arguments = (0, 0, False)
blockdiag_directive.content = 1
blockdiag_directive.options = dict([(key, directives.flag) for key in VARIANTS])

directives.register_directive("blockdiag", blockdiag_directive)

podhmopodhmo 2011/04/12 00:11 これは、出力されるhtmlがfont-familyを絶対パスで表示するので危険。中が見えないようにbasenameに置換する処理を加えた方が良い。

トラックバック - http://d.hatena.ne.jp/podhmo/20110409/1302342454
 |