Package common :: Module rst_xhtml_generator
[hide private]
[frames] | no frames]

Source Code for Module common.rst_xhtml_generator

  1  # -*- coding:utf-8 -*- 
  2  ## src/common/rst_xhtml_generator.py 
  3  ## 
  4  ## Copyright (C) 2006 Santiago Gala 
  5  ##                    Nikos Kouremenos <kourem AT gmail.com> 
  6  ## Copyright (C) 2006-2010 Yann Leboulanger <asterix AT lagaule.org> 
  7  ## Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org> 
  8  ## 
  9  ## This file is part of Gajim. 
 10  ## 
 11  ## Gajim is free software; you can redistribute it and/or modify 
 12  ## it under the terms of the GNU General Public License as published 
 13  ## by the Free Software Foundation; version 3 only. 
 14  ## 
 15  ## Gajim is distributed in the hope that it will be useful, 
 16  ## but WITHOUT ANY WARRANTY; without even the implied warranty of 
 17  ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 18  ## GNU General Public License for more details. 
 19  ## 
 20  ## You should have received a copy of the GNU General Public License 
 21  ## along with Gajim. If not, see <http://www.gnu.org/licenses/>. 
 22  ## 
 23   
 24  try: 
 25      from docutils import io 
 26      from docutils.core import Publisher 
 27      from docutils.parsers.rst import roles 
 28      from docutils import nodes, utils 
 29      from docutils.parsers.rst.roles import set_classes 
 30  except ImportError: 
 31      print "Requires docutils 0.4 for set_classes to be available" 
32 - def create_xhtml(text):
33 return None
34 else:
35 - def pos_int_validator(text):
36 """ 37 Validates that text can be evaluated as a positive integer 38 """ 39 result = int(text) 40 if result < 0: 41 raise ValueError("Error: value '%(text)s' " 42 "must be a positive integer") 43 return result
44
45 - def generate_uri_role( role_name, aliases, anchor_text, base_url, 46 interpret_url, validator):
47 """ 48 Create and register a uri based "interpreted role" 49 50 Those are similar to the RFC, and PEP ones, and take 51 role_name: 52 name that will be registered 53 aliases: 54 list of alternate names 55 anchor_text: 56 text that will be used, together with the role 57 base_url: 58 base url for the link 59 interpret_url: 60 this, modulo the validated text, will be added to it 61 validator: 62 should return the validated text, or raise ValueError 63 """ 64 def uri_reference_role(role, rawtext, text, lineno, inliner, 65 options={}, content=[]): 66 try: 67 valid_text = validator(text) 68 except ValueError, e: 69 msg = inliner.reporter.error( e.message % dict(text=text), line=lineno) 70 prb = inliner.problematic(rawtext, rawtext, msg) 71 return [prb], [msg] 72 ref = base_url + interpret_url % valid_text 73 set_classes(options) 74 node = nodes.reference(rawtext, anchor_text + utils.unescape(text), refuri=ref, 75 **options) 76 return [node], []
77 78 uri_reference_role.__doc__ = """Role to make handy references to URIs. 79 80 Use as :%(role_name)s:`71` (or any of %(aliases)s). 81 It will use %(base_url)s+%(interpret_url)s 82 validator should throw a ValueError, containing optionally 83 a %%(text)s format, if the interpreted text is not valid. 84 """ % locals() 85 roles.register_canonical_role(role_name, uri_reference_role) 86 from docutils.parsers.rst.languages import en 87 en.roles[role_name] = role_name 88 for alias in aliases: 89 en.roles[alias] = role_name 90 91 generate_uri_role('xep-reference', ('jep', 'xep'), 92 'XEP #', 'http://www.xmpp.org/extensions/', 'xep-%04d.html', 93 pos_int_validator) 94 generate_uri_role('gajim-ticket-reference', ('ticket', 'gtrack'), 95 'Gajim Ticket #', 'http://trac.gajim.org/ticket/', '%d', 96 pos_int_validator) 97
98 - class HTMLGenerator:
99 """ 100 Really simple HTMLGenerator starting from publish_parts 101 102 It reuses the docutils.core.Publisher class, which means it is *not* 103 threadsafe. 104 """
105 - def __init__(self, settings_spec=None, 106 settings_overrides=dict(report_level=5, halt_level=5), 107 config_section='general'):
108 self.pub = Publisher(reader=None, parser=None, writer=None, 109 settings=None, 110 source_class=io.StringInput, 111 destination_class=io.StringOutput) 112 self.pub.set_components(reader_name='standalone', 113 parser_name='restructuredtext', 114 writer_name='html') 115 # hack: JEP-0071 does not allow HTML char entities, so we hack our way 116 # out of it. 117 # &mdash; == u"\u2014" 118 # a setting to only emit charater entities in the writer would be nice 119 # FIXME: several &nbsp; are emitted, and they are explicitly forbidden 120 # in the JEP 121 # &nbsp; == u"\u00a0" 122 self.pub.writer.translator_class.attribution_formats['dash'] = ( 123 u'\u2014', '') 124 self.pub.process_programmatic_settings(settings_spec, 125 settings_overrides, 126 config_section)
127 128
129 - def create_xhtml(self, text, destination=None, destination_path=None, 130 enable_exit_status=None):
131 """ 132 Create xhtml for a fragment of IM dialog. We can use the source_name 133 to store info about the message 134 """ 135 self.pub.set_source(text, None) 136 self.pub.set_destination(destination, destination_path) 137 output = self.pub.publish(enable_exit_status=enable_exit_status) 138 # kludge until we can get docutils to stop generating (rare) &nbsp; 139 # entities 140 return u'\u00a0'.join(self.pub.writer.parts['fragment'].strip().split( 141 '&nbsp;'))
142 143 Generator = HTMLGenerator() 144
145 - def create_xhtml(text):
146 return Generator.create_xhtml(text)
147 148 149 if __name__ == '__main__': 150 print "test 1\n", Generator.create_xhtml(""" 151 test:: 152 153 >>> print 1 154 1 155 156 *I* like it. It is for :JEP:`71` 157 158 this `` should trigger`` should trigger the &nbsp; problem. 159 160 """) 161 print "test 2\n", Generator.create_xhtml(""" 162 *test1 163 164 test2_ 165 """) 166 print "test 3\n", Generator.create_xhtml(""":ticket:`316` implements :xep:`71`""") 167