Use ReStructuredText for pretty source code listin

2019-05-07 09:00发布

As is asked and answered in this post, one can use SyntaxHighlighter for pretty code listing.

With ReStructuredText, I can use raw directive as follows.

.. raw:: html

    <script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js"></script>
    <script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js"></script>
    <link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shCoreDefault.css"/>
    <script type="text/javascript">SyntaxHighlighter.all();</script>

I could use `SyntaxHighlighter <http://alexgorbatchev.com/SyntaxHighlighter/>`_ for highlighting source code. 

.. raw:: html

    <pre class="brush: js;">
    function helloSyntaxHighlighter()
    {
        return "hi!";
    }
    </pre>

However, I need to have code directive that I can use.

.. code:: 

    function helloSyntaxHighlighter()
    {
        return "hi!";
    }

How can I translate code directive into the following HTML code?

<pre class="brush: js;">
function helloSyntaxHighlighter()
{
    return "hi!";
}
</pre>

2条回答
我想做一个坏孩纸
2楼-- · 2019-05-07 09:20

There is a way I have used:

  • Install rst2pdf and pygments.

  • Then make a copy of rst2html, call it myrst2html or whatever you want.

  • In the copy, add this after the imports:

    from docutils.parsers.rst import directives 
    import rst2pdf.pygments_code_block_directive 
    directives.register_directive('code-block',
        rst2pdf.pygments_code_block_directive.code_block_directive) 
    

And that's it, you now have the code-block directives.

查看更多
祖国的老花朵
3楼-- · 2019-05-07 09:42

I could make it work as follows :

  1. To generate <pre>..</pre>, I needed to modify ParsedLiteral, so I copied the ParsedLiteral class into Code as follows. Changing the line 5 self.options['class'] = ['brush: js;'] # <-- is the main idea.

    class Code(Directive):

    option_spec = {'class': directives.class_option}
    has_content = True
    
    def run(self):
        self.options['class'] = ['brush: js;'] # <--
        set_classes(self.options)
        self.assert_has_content()
        text = '\n'.join(self.content)
        text_nodes, messages = self.state.inline_text(text, self.lineno)
        node = nodes.literal_block(text, '', *text_nodes, **self.options)
        node.line = self.content_offset + 1
        return [node] + messages
    
  2. Add one line in init.py as follows.

    _directive_registry = { 'code' : ('body', 'Code'),

Now, you can use the following code

.. code::

   print "Hello world!"  # *tricky* code

To get this HTML code

<pre class="brush: js; literal-block">
print &quot;Hello world!&quot;  # <em>tricky</em> code
</pre>

Possible Easy Solution?

I could use ParsedLiteral if I find a way to pass the parameter of 'bruch: js;'. However, when I tried the code

.. parsed-literal::
   :class: "brunch: js;"

   print "Hello world!"  # *tricky* code

The tag becomes <pre class="brunch ja">.

查看更多
登录 后发表回答