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()]