Sphinx: Use reStructuredText's `code` directive

Created on 4 Dec 2015  ·  5Comments  ·  Source: sphinx-doc/sphinx

Since docutils 0.9, reStructuredText supports code directive, but Sphinx, unfortunately, can't handle this. By design, code directive supports syntax highlighting, but Sphinx ignores this due to visit_literal_block reimplementation in custom HTMLTranslator.

So basically:

  • Sphinx handles code directive as literal block.
  • There's no syntax highlighting in produced block (it's supposed to be generated by docutils, and it does, but as children nodes) due to HTMLTranslator limitations.

Well, I see two possible ways to solve this issue:

  1. Use Sphinx's CodeBlock implementation for code directive:

python directives.register_directive('code', CodeBlock)

Pros:

  • easy to implement
  • features/options similar code-block / sourcecode

Cons:

  • doesn't compatible with docutils implementation

    1. Use docutils' (native) implementation for code directive.

Pros:

  • backward compatible, since standard (native) implementation is used

Cons:

  • requires changes in many places, since we need:

    • distinguish Sphinx's code blocks from docutils' one on HTMLTranslator level (could be solved by injecting some marker from Sphinx's implementation)

    • use default visit_literal_block implementation for non-Sphinx code blocks

    • pass short Pygments CSS notation to docutils (long is default)

  • user will lack of Sphinx-specific code-block options

Folks, could you please share your opinion on this?

@birkenfeld It'd be nice to see your input.

bug markup

Most helpful comment

Docutils uses code-block and sourcecode as aliases for code directive. Taking into account that Sphinx provides own implementation for both of them, I think it would make sense to reimplement code directive either.

All 5 comments

I think neither option is great. In the first case, Sphinx would have a half-compatible code directive that will confuse users later on when they want to use the Docutils line number option; in the second case there is Pygments highlighting but it doesn't take into account the options from conf.py.

I think option 3 might be better: to acknowledge that Sphinx RST is a slightly different language than Docutils RST (library-wise, _not_ syntax-wise), and to only support .. code:: unofficially with no highlighting, as we do at the moment. This will keep the Sphinx codebase cleaner and easier to support, and people who want documents that are both Sphinx and Docutils RST will not be terribly inconvenienced.

Docutils uses code-block and sourcecode as aliases for code directive. Taking into account that Sphinx provides own implementation for both of them, I think it would make sense to reimplement code directive either.

I was wondering why my attempts to get syntax highlighting of inline code were not working, and it looks like this is maybe the problem. I have this role defined:

.. role:: python(code)
   :language: python

and in my document I use :python:`print("hi")`, and while I see monospaced (code) text, I don't see syntax highlighting. Inspecting the HTML, I see this:

<code class="code python docutils literal notranslate">
  <span class="keyword"><span class="pre">print</span></span>
  <span class="punctuation"><span class="pre">(</span></span>
  <span class="literal string double"><span class="pre">“hi”</span></span>
  <span class="punctuation"><span class="pre">)</span></span>
</code>

I have a pygments.css asset loaded, but it uses different class names, e.g.:

.highlight .k { color: #007020; font-weight: bold } /* Keyword */

All I need to do is add the relevant selectors to the appropriate definitions:

.highlight .k, .code .keyword { color: #007020; font-weight: bold } /* Keyword */

It seems like it would be relatively easy to distribute such a custom CSS file until a proper solution is found, but maybe there are other complexities I'm not considering?

This issue was filed about the code directive, you are talking about the code role.
I've filed #5157 as a separate issue, since there is a way to do highlighting of code blocks (using code-block), but not highlighting of inline code.
Perhaps https://pypi.org/project/sphinxcontrib-inlinesyntaxhighlight/ will work for you. It does not contain code to support building with LaTeX.

I just posted a PR #6132 for latter idea.

Personally, I prefer former one. Because I'd not like to distinguish two style of "code block" directives. I suspect they will confuse users. So it would be better to start discussion about integration of them.

My opinion is adding docutils originated options to code-block directive. And then let code directive be overridden with code-block directive. It will bring upper compatibility to Sphinx.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shimizukawa picture shimizukawa  ·  3Comments

samweisgamdschie picture samweisgamdschie  ·  3Comments

shimizukawa picture shimizukawa  ·  3Comments

jessetan picture jessetan  ·  3Comments

miketheman picture miketheman  ·  3Comments