# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.## This program is Free Software; you can redistribute it and/or# modify it under the terms of the GNU General Public License# as published by the Free Software Foundation; either version 2# of the License, or (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."""Helpers and utilities for Sphinx rendering of CLI based on Click Extra... danger:: This module is quite janky but does the job. Still, it would benefits from a total clean rewrite. This would require a better understanding of Sphinx, Click and MyST internals. And as a side effect will eliminate the dependency on ``pallets_sphinx_themes``. If you're up to the task, you can try to refactor it. I'll probably start by moving the whole ``pallets_sphinx_themes.themes.click.domain`` code here, merge it with the local collection of monkey-patches below, then clean the whole code to make it more readable and maintainable. And finally, address all the todo-list below... todo:: Add support for plain MyST directives to remove the need of wrapping rST into an ``{eval-rst}`` block. Ideally, this would allow for the following simpler syntax in MyST: .. code-block:: markdown ```{click-example} from click_extra import echo, extra_command, option, style @extra_command @option("--name", prompt="Your name", help="The person to greet.") def hello_world(name): "Simple program that greets NAME." echo(f"Hello, {style(name, fg='red')}!") ``` .. code-block:: markdown ```{click-run} invoke(hello_world, args=["--help"]) ```.. todo:: Fix the need to have both ``.. click:example::`` and ``.. click:run::`` directives in the same ``{eval-rst}`` block in MyST. This is required to have both directives shares states and context."""from__future__importannotationstry:importsphinx# noqa: F401exceptImportError:raiseImportError("You need to install click_extra[sphinx] extra dependencies to use this module.")fromtypingimportAnyfromdocutils.statemachineimportViewListfromsphinx.highlightingimportPygmentsBridgefrom.pygmentsimportAnsiHtmlFormatterfrom.testingimportExtraCliRunner
[docs]classPatchedViewList(ViewList):"""Force the rendering of ANSI shell session. Replaces the ``.. sourcecode:: shell-session`` code block produced by ``.. click:run::`` directive with an ANSI Shell Session: ``.. code-block:: ansi-shell-session``. ``.. sourcecode:: shell-session`` has been `released in Pallets-Sphinx-Themes 2.1.0 <https://github.com/pallets/pallets-sphinx-themes/pull/62>`_. """
[docs]defappend(self,*args,**kwargs)->None:"""Search the default code block and replace it with our own version."""default_code_block=".. sourcecode:: shell-session"new_code_block=".. code-block:: ansi-shell-session"ifdefault_code_blockinargs:new_args=list(args)index=args.index(default_code_block)new_args[index]=new_code_blockargs=tuple(new_args)returnsuper().append(*args,**kwargs)
[docs]defsetup(app:Any)->None:"""Register new directives, augmented with ANSI coloring. New directives: - ``.. click:example::`` - ``.. click:run::`` .. danger:: This function activates lots of monkey-patches: - ``sphinx.highlighting.PygmentsBridge`` is updated to set its default HTML formatter to an ANSI capable one for the whole Sphinx app. - ``pallets_sphinx_themes.themes.click.domain.ViewList`` is `patched to force an ANSI lexer on the rST code block <#click_extra.sphinx.PatchedViewList>`_. - ``pallets_sphinx_themes.themes.click.domain.ExampleRunner`` is replaced with ``click_extra.testing.ExtraCliRunner`` to have full control of contextual color settings by the way of the ``color`` parameter. It also produce unfiltered ANSI codes so that the other ``PatchedViewList`` monkey-patch can do its job and render colors in the HTML output. """# Set Sphinx's default HTML formatter to an ANSI capable one.PygmentsBridge.html_formatter=AnsiHtmlFormatterfrompallets_sphinx_themes.themes.clickimportdomaindomain.ViewList=PatchedViewList# Brutal, but effective.# Alternative patching methods: https://stackoverflow.com/a/38928265domain.ExampleRunner.__bases__=(ExtraCliRunner,)# Force color rendering in ``invoke`` calls.domain.ExampleRunner.force_color=True# Register directives to Sphinx.domain.setup(app)