# -*- coding: iso-8859-1 -*- # Copyright (C) 2004-2006 Bastian Kleineidam # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. """docutils HTML writer with navigation placeholder and information""" from docutils import writers, nodes, languages, utils from docutils.writers import html4css1 from docutils.parsers.rst.directives.html import MetaBody import sys import os import re try: import Image # check for the Python Imaging Library except ImportError: Image = None class NavInfo (object): """store nav info""" def __init__ (self, name, level, visible=True, order=sys.maxint): self.name = name self.level = level self.visible = visible self.order = order def export (self): """return machine-parseable navigation information, suitable for config files""" return "\n".join([ "name = %r" % self.name, "level = %d" % self.level, "visible = %s" % self.visible, "order = %d" % self.order, ]) def __str__ (self): return "[%d]%r %s order=%d"%\ (self.level, self.name, (self.visible and "visible" or ""), self.order) class Writer (html4css1.Writer): """writer using custom nav class""" def __init__ (self): writers.Writer.__init__(self) self.translator_class = HTMLFileNavTranslator class FixedHTMLTranslator (html4css1.HTMLTranslator): def visit_image (self, node): """ Like super.visit_image(), but with align="middle" enforcement. """ atts = {} atts['src'] = node['uri'] if node.has_key('width'): atts['width'] = node['width'] if node.has_key('height'): atts['height'] = node['height'] if node.has_key('scale'): if Image and not (node.has_key('width') and node.has_key('height')): try: im = Image.open(str(atts['src'])) except (IOError, # Source image can't be found or opened UnicodeError): # PIL doesn't like Unicode paths. pass else: if not atts.has_key('width'): atts['width'] = str(im.size[0]) if not atts.has_key('height'): atts['height'] = str(im.size[1]) del im for att_name in 'width', 'height': if atts.has_key(att_name): match = re.match(r'([0-9.]+)(\S*)$', atts[att_name]) assert match atts[att_name] = '%s%s' % ( float(match.group(1)) * (float(node['scale']) / 100), match.group(2)) style = [] for att_name in 'width', 'height': if atts.has_key(att_name): if re.match(r'^[0-9.]+$', atts[att_name]): # Interpret unitless values as pixels. atts[att_name] += 'px' style.append('%s: %s;' % (att_name, atts[att_name])) del atts[att_name] if style: atts['style'] = ' '.join(style) atts['alt'] = node.get('alt', atts['src']) if (isinstance(node.parent, nodes.TextElement) or (isinstance(node.parent, nodes.reference) and not isinstance(node.parent.parent, nodes.TextElement))): # Inline context or surrounded by .... suffix = '' else: suffix = '\n' if node.has_key('align'): if node['align'] == 'center': if suffix: # "align" attribute is set in surrounding "div" element. self.body.append('