def rst_to_html(s): """Convert a blob of reStructuredText to HTML""" log = logging.getLogger("docutils") if docutils_core is None: raise Exception( "Attempted to use rst_to_html but docutils unavailable.") class FakeStream(object): def write(self, str): if len(str) > 0 and not str.isspace(): log.warn(str) settings_overrides = { "embed_stylesheet": False, "template": os.path.join(os.path.dirname(__file__), "docutils_template.txt"), "warning_stream": FakeStream(), "doctitle_xform": False, # without option, very different rendering depending on # number of sections in help content. } return unicodify( docutils_core.publish_string(s, writer=docutils_html4css1.Writer(), settings_overrides=settings_overrides))
def render(self, context, mimetype, content, filename=None, rev=None): # Minimize visual impact of errors from docutils.writers import html4css1 class TracHTMLTranslator(html4css1.HTMLTranslator): """Specialized translator with unobtrusive error reporting""" def visit_system_message(self, node): paragraph = node.children.pop(0) message = escape(paragraph.astext()) if paragraph else '' backrefs = node['backrefs'] if backrefs: span = ('<span class="system-message">%s</span>' % (''.join('<a href="#%s" title="%s">?</a>' % (backref, message) for backref in backrefs))) else: span = ('<span class="system-message" title="%s">?</span>' % message) self.body.append(span) def depart_system_message(self, node): pass writer = html4css1.Writer() writer.translator_class = TracHTMLTranslator inliner = rst.states.Inliner() inliner.trac = (self.env, context) parser = rst.Parser(inliner=inliner) content = content_to_unicode(self.env, content, mimetype) parts = publish_parts(content, writer=writer, parser=parser, settings_overrides={'halt_level': 6, 'warning_stream': False, 'file_insertion_enabled': 0, 'raw_enabled': 0, 'warning_stream': False}) return parts['html_body']
def render(self, context, mimetype, content, filename=None, rev=None): # Minimize visual impact of errors class TracHTMLTranslator(html4css1.HTMLTranslator): """Specialized translator with unobtrusive error reporting and some extra security features""" def __init__(self, *args, **kwargs): self._render_unsafe_content = wikisys.render_unsafe_content self._safe_schemes = set(wikisys.safe_schemes) html4css1.HTMLTranslator.__init__(self, *args, **kwargs) def visit_system_message(self, node): paragraph = node.children.pop(0) message = escape(paragraph.astext()) if paragraph else '' backrefs = node['backrefs'] if backrefs: span = ('<span class="system-message">%s</span>' % (''.join('<a href="#%s" title="%s">?</a>' % (backref, message) for backref in backrefs))) else: span = ('<span class="system-message" title="%s">?</span>' % message) self.body.append(span) def depart_system_message(self, node): pass def visit_image(self, node): html4css1.HTMLTranslator.visit_image(self, node) uri = node.attributes.get('uri') if not wikisys.is_safe_origin(uri, context.req): self.body[-1] = self.body[-1].replace( '<img ', '<img crossorigin="anonymous" ') def visit_reference(self, node): if self._is_safe_uri(node.get('refuri')): html4css1.HTMLTranslator.visit_reference(self, node) def depart_reference(self, node): if self._is_safe_uri(node.get('refuri')): html4css1.HTMLTranslator.depart_reference(self, node) def _is_safe_uri(self, uri): if self._render_unsafe_content or not uri: return True else: pos = uri.find(':') return pos < 0 or uri[0:pos] in self._safe_schemes wikisys = WikiSystem(self.env) writer = html4css1.Writer() writer.translator_class = TracHTMLTranslator inliner = rst.states.Inliner() inliner.trac = (self.env, context) parser = rst.Parser(inliner=inliner) content = content_to_unicode(self.env, content, mimetype) # The default Reader is explicitly passed as a workaround for #11248 parts = publish_parts(content, writer=writer, parser=parser, reader=standalone.Reader(parser), settings_overrides={'halt_level': 6, 'file_insertion_enabled': 0, 'raw_enabled': 0, 'warning_stream': False}) return parts['html_body']
def _publish_parts(self, text): # Creating a new Writer instance is cheap operation, since # its initialization is almost empty. writer = html4css1.Writer() # We need custom translator in order to override translation # behaviour. For instance, we don't want to have <div> wrappers # around sections. writer.translator_class = _HtmlTranslator # Party on, dude! Let's get converted data. parts = publish_parts(source=text, writer=writer, settings_overrides=dict(self._conf['docutils'])) return parts
def rst2html(rst): """Render reStructured Text into HTML. Disable dangerous things, like file inclusion and raw HTML. """ # Keep authors from spilling the contents of local files into the post # or abusing raw HTML: secure_settings = { 'file_insertion_enabled': 0, 'raw_enabled': 0, 'initial_header_level': 2, '_disable_config': 1 } return mark_safe( publish_parts(rst, writer=html4css1.Writer(), settings_overrides=secure_settings)['html_body'])
def _get_publisher(self): output, pub = publish_programmatically( source=self.source, source_path=None, source_class=docutils.io.StringInput, destination_class=docutils.io.StringOutput, destination=None, destination_path=None, reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', writer=html4css1.Writer(), writer_name='pseudoxml', settings=None, settings_spec=None, settings_overrides=RST_SETTINGS, config_section=None, enable_exit_status=False) return pub
def compile_rst(text, request, part=None, line_numbers=False): """Compiles the given ReStructuredText into HTML. Returns only the actual content of the generated HTML document, without headers or footers. :param text: The ReST to compile :type text: `unicode` :param line_numbers: Whether to generate a "data-source-ln" attribute with source line-numbers (default: ``false``) :type line_numbers: ``boolean`` :return: The body content of the generated HTML :return_type: `unicode` """ settings = deepcopy(SETTINGS) settings['pyramid_request'] = request settings['wte_part'] = part writer = html4css1.Writer() if line_numbers: writer.translator_class = HTMLLineNumbersTranslator parts = core.publish_parts(source=text, writer=writer, settings_overrides=settings) return parts['body']
# # This is a bit gross to patch because all this is built up at load time. Body.pats['optname'] = r'[a-zA-Z0-9][a-zA-Z0-9._-]*' Body.pats['longopt'] = r'(--|/)%(optname)s([ =]%(optarg)s)?' % Body.pats Body.pats['option'] = r'(%(shortopt)s|%(longopt)s)' % Body.pats Body.patterns['option_marker'] = r'%(option)s(, %(option)s)*( +| ?$)' % Body.pats description = ('Generates (X)HTML documents from standalone reStructuredText ' 'sources. ' + default_description) # workaround for bug with <xxx id="tags" name="tags"> in IE from docutils.writers import html4css1 class IESafeHtmlTranslator(html4css1.HTMLTranslator): def starttag(self, node, tagname, suffix='\n', empty=0, **attributes): x = html4css1.HTMLTranslator.starttag(self, node, tagname, suffix, empty, **attributes) y = x.replace('id="tags"', 'id="tags_"') y = y.replace('name="tags"', 'name="tags_"') y = y.replace('href="#tags"', 'href="#tags_"') return y mywriter = html4css1.Writer() mywriter.translator_class = IESafeHtmlTranslator publish_cmdline(writer=mywriter, description=description)
def html_description(self): if self.description is None: return None return core.publish_parts(self.description, writer=html4css1.Writer())['html_body']