Beispiel #1
0
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))
Beispiel #2
0
    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']
Beispiel #3
0
    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']
Beispiel #4
0
    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
Beispiel #5
0
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
Beispiel #7
0
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']
Beispiel #8
0
    #
    # 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)
Beispiel #9
0
    def html_description(self):
        if self.description is None:
            return None

        return core.publish_parts(self.description,
                                  writer=html4css1.Writer())['html_body']