How to get inline code ending with spaces with docutils/sphinx? - python-sphinx

The following rST directive doesn't support trailing spaces:
:code:`foo `
Example:
>>> from docutils import core
>>> whole = core.publish_parts(""":code:`x `""")['whole']
<string>:1: (WARNING/2) Inline interpreted text or phrase reference start-string without end-string.
Is there a way to get rid of this warning?

No. According to the docutils documentation of Inline markup recognition rules:
Inline markup end-strings must be immediately preceded by non-whitespace.

Related

Disable stripping of trailing newlines from code blocks

I'm creating an Asciidoctor document with some code blocks. I'm using pygments as syntax highlighter.
In the output, trailing empty lines in a code block are removed. Normally that's fine, but in some specific case I want to include an empty line after the code in the output.
This should be possible with pygments, since the documentation states:
Currently, all lexers support these options:
stripnl: Strip leading and trailing newlines from the input (default: True)
Is it possible to change this option (i.e. to set stripnl=False) for a code block in an Asciidoctor document? If so, how?
A work-around is acceptable if there's no clean way to achieve this.
I've considered inserting invisible Unicode characters so the line is not empty, but this seems to cause problems in my IDE (AsciidocFX does not seem to like some Unicode characters) and/or in one of the output formats (HTML and PDF), resulting in garbled output.
example.adoc:
:source-highlighter: pygments
:pygments-style: manni
:pygments-linenums-mode: inline
Some code block here:
```c
void example(void)
{
printf("hello, world\n");
}
```
When compiled using asciidoctor example.adoc -o example.html, the output is rendered (roughly) like:
Some code block here:
void example(void)
{
printf("hello, world\n");
}
I'd like to have the code block rendered as
void example(void)
{
printf("hello, world\n");
}
// including this empty line here!
NB: I added the ruby tag, because Asciidoctor and Pygments are written in ruby, and it seems that the configuration of Pygments is done using ruby files as well. I have a strong feeling that the solution requires some Ruby scripts, but I'm not familiar with Ruby myself, so this is far from trivial for me.
In case it's relevant: I'm using Windows 10, Asciidoctor 2.0.17, ruby 3.0.2p107, and pygments.rb 2.3.0.
Asciidoctor and Pygments are both stripping the trailing whitespace.
When Pygments is specified as the syntax highlighter, Asciidoctor appears to stop its whitespace removal. That means that you can use a pass-through macro to add a space, provided that you use Asciidoc code blocks:
:source-highlighter: pygments
:pygments-style: manni
:pygments-linenums-mode: inline
Some code block here:
[source, c, subs="macros+"]
----
void example(void)
{
printf("hello, world\n");
}
pass:v[ ]
----
The solution with pass:v[] did not work for me either using the IntelliJ Asciidoctor plugin. What worked is that I inserted a
\u200F\u200F\u200E \u200E
^
| space here
unicode character set to the end of the last line.

Preserve tabs in Sphinx Makefile code-block's

I use Sphinx with reStructuredText input and HTML output to document different pieces of the infrastructure. The idea is that a user who reads the documentation can copy examples and past them into her file. How can that be done for Makefile examples? Makefiles need tab characters at certain places, but Sphinx converts tabs into spaces.
Example: The command line must start with a tab in the final HTML. Here it is written with three spaces for indent and a tab:
.. code-block:: Makefile
target: dependency
command -i $< -o $#
code-block does not have an option to control tab expansion.
A web search with sphinx code-block makefile tab has answers for tab expansion in included code (I prefer to have it inline) or how the Sphinx Makefile can be edited, but nothing that soles my problem.
Tab expansion happens very early stage of parsing RST, so you have to customize parser itself to disable it. I hope this works.
from typing import Union
from docutils.nodes import document
from docutils.statemachine import StringList
from sphinx.parsers import RSTParser
class NoTabExpansionRSTParser(RSTParser):
def parse(self, inputstring: Union[str, StringList], document: document) -> None:
if isinstance(inputstring, str):
lines = inputstring.splitlines()
inputstring = StringList(lines, document.current_source)
super().parse(inputstring, document)
def setup(app):
app.add_source_parser(NoTabExpansionRSTParser, override=True)
FYI, here's where tab expansion happens, which is bypassed by the above code.
In sphinx.parsers.RSTParser#parse
lines = docutils.statemachine.string2lines(
inputstring, tab_width=document.settings.tab_width,
convert_whitespace=True)
↓
In docutils.statemachine.string2lines
return [s.expandtabs(tab_width).rstrip() for s in astring.splitlines()]

Pandoc - is tex output with dollar sign math possible?

Is it possible to have .tex files output from pandoc have math mode with dollar signs ($)? The manual says:
LaTeX: It will appear verbatim surrounded by \(...\) (for inline math) or \[...\] (for display math).
I also found this Github issue from 2016 where the author says it could be selectable. Is there now a pandoc argument or another way of having the .tex output use dollar signs?
You can do this using a pandoc filter. E.g.:
-- Do nothing unless we are targeting TeX.
if not FORMAT:match('tex$') then return {} end
function Math (m)
local delimiter = m.mathtype == 'InlineMath' and '$' or '$$'
return pandoc.RawInline('tex', delimiter .. m.text .. delimiter)
end
Save to file dollar-math.lua, and pass it to pandoc via --lua-filter=dollar-math.lua.

Multi-line in a sequence in YAML

I would like to have multiple lines in a sequence in YAML. This is how I do it, but I have issues with parsing it in python:
Element: |
- multiple lines
come here
Doing it this way, when I parse it with Python, I still see the - in the parsed data. It seems that YAML does not understand this is a list.
Your input is not a list, YAML only knows about mappings (constructed as a Python dict and sequences (constructed as a Python list).
Normally - is the block sequence entry indicator, But since you start a block style literal on the first line as the value for the key Element, because of the |, everything following it that is indented is part of this scalar (constructed as a Python string).
What you want to do is bring the indicator outside of the literal scalar:
Element:
- |
multiple lines
come here
If you load that in Python in a variable data then data['Element'][0] will be the string 'multiple lines\ncome here\n'. That is: every newline in your literal scalar will be a newline in your string, and there will be a single final newline on that string independent of how many empty lines follow (this is clipping). If you want the end to have no newline, then use |- (stripping), and if you want all newlines until outdenting then use |+ (keeping). Those additions to the | are called chomping indicators.
If you have the above in a file called input.yaml:
import sys
from pathlib import Path
import ruamel.yaml
input = Path('input.yaml')
yaml = ruamel.yaml.YAML(typ='safe')
data = yaml.load(input)
print(f'{data["Element"][0]!r}') # print the representation, so you can see where the newlines are
which gives:
'multiple lines\ncome here\n'
Use this syntax (for the yaml Python package, at least)
stuff:
- 'this is a multiline
string'
In other words quote the string and unindent its continuation.

How to use inline code with a trailing whitespace?

When I use
``# ``
in my Sphinx documentation I get the following warning:
WARNING: Inline literal start-string without end-string.
Trying
:samp:`# `
leads to
WARNING: Inline interpreted text or phrase reference start-string without end-string.
The problem seems to be the trailing whitespace however I couldn't figure out a way of getting around this problem. Escaping the whitespace with a backslash (\) doesn't help either (for the first example the warning persists and for the second example the whitespace is omitted in the generated docs).
This answer doesn't work because the inline code section interprets the |space| as a literal string.
Experienced with Sphinx 1.6.2.
A workaround is to use a no-break space character (U+00A0) instead of a regular space (U+0020) for the trailing whitespace.
There are several ways to insert a literal no-break space character. See https://en.wikipedia.org/wiki/Non-breaking_space#Keyboard_entry_methods.
Use a "literal" role__ with an escaped space after the intended trailing space::
:literal:`# \ `
__https://docutils.sourceforge.io/docs/ref/rst/roles.html#literal

Resources