Tolerate Sphinx extensions
Opened this issue · 2 comments
First off, rstfmt looks great and we'd like to use it in our project! CC @sk1p
In a first test, handling the formatting for Sphinx extensions like https://www.sphinx-doc.org/en/master/usage/extensions/doctest.html was a stumbling point.
How to reproduce
Format a document that uses the Sphinx doctest extension:
Reproducer
==========
.. testsetup:: *
import numpy as np
What happens
(libertem) C:\Users\dwebe\Documents\src\LiberTEM>rstfmt prototypes\reproducers\rstfmt.rst
:4: (ERROR/3) Unknown directive type "testsetup".
.. testsetup:: *
import numpy as np
Traceback (most recent call last):
File "c:\users\dwebe\.conda\envs\libertem\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\users\dwebe\.conda\envs\libertem\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\dwebe\.conda\envs\libertem\Scripts\rstfmt.exe\__main__.py", line 7, in <module>
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\rstfmt\__main__.py", line 46, in main
doc = rstfmt.parse_string(inp)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\rstfmt\rstfmt.py", line 750, in parse_string
parser.parse(s, doc)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\__init__.py", line 191, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 170, in run
results = StateMachineWS.run(self, input_lines, input_offset,
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\statemachine.py", line 241, in run
context, next_state, result = self.check_line(
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\statemachine.py", line 459, in check_line
return method(match, context, next_state)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\statemachine.py", line 241, in run
context, next_state, result = self.check_line(
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\statemachine.py", line 459, in check_line
return method(match, context, next_state)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 2099, in directive
return self.unknown_directive(type_name)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\parsers\rst\states.py", line 2280, in unknown_directive
error = self.reporter.error(
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\utils\__init__.py", line 231, in error
return self.system_message(self.ERROR_LEVEL, *args, **kwargs)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\rstfmt\rstfmt.py", line 274, in system_message
msg = super().system_message(level, message, *children, **kwargs)
File "c:\users\dwebe\.conda\envs\libertem\lib\site-packages\docutils\utils\__init__.py", line 197, in system_message
raise SystemMessage(msg, level)
docutils.utils.SystemMessage: :4: (ERROR/3) Unknown directive type "testsetup".
.. testsetup:: *
import numpy as np
What should happen
Blocks with unknown directives are ignored. Possibly, they can trigger a warning. Possibly, there could be an interface to write formatters for new directives that could be installed as part of an extension that implements them in Sphinx.
One could take this a step further and allow piping the code into language-specific auto-formatters, like black for Python.
Seems like this kind of approach could be used as a short-term fix: https://github.com/OCA/pylint-odoo/pull/66/files