From 86fa5500996d8e0194d1473a2b8a92b113a46cb3 Mon Sep 17 00:00:00 2001 From: Kazuya Takei Date: Sat, 11 Nov 2023 20:20:37 +0900 Subject: [PATCH] feat: Generate roles to render color-text with style attribute --- pyproject.toml | 1 + src/atsphinx/color_text.py | 75 ++++++++++++++++++++++++++++++++++++++ tests/test-root/index.rst | 2 + tests/test_it.py | 6 +++ 4 files changed, 84 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 200e764..ea89aa3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ dynamic = ["version", "description"] [project.optional-dependencies] doc = [] test = [ + "BeautifulSoup4", "pytest ==7.*", ] diff --git a/src/atsphinx/color_text.py b/src/atsphinx/color_text.py index 121897d..89c7e0f 100644 --- a/src/atsphinx/color_text.py +++ b/src/atsphinx/color_text.py @@ -1,10 +1,85 @@ """Text color changer for Sphinx.""" +from typing import List, Optional + +from docutils import nodes +from docutils.parsers.rst import roles +from docutils.parsers.rst.states import Inliner +from docutils.writers import Writer from sphinx.application import Sphinx +from sphinx.config import Config __version__ = "0.0.0" +COLORS = { + "black": "#000000", + "silver": "#c0c0c0", + "gray": "#808080", + "white": "#ffffff", + "maroon": "#800000", + "red": "#ff0000", + "purple": "#800080", + "fuchsia": "#ff00ff", + "green": "#008000", + "lime": "#00ff00", + "olive": "#808000", + "yellow": "#ffff00", + "navy": "#000080", + "blue": "#0000ff", + "teal": "#008080", + "aqua": "#00ffff", +} +"""Major named-colors. + +Use "Standard colors" from + `MDN `_. +""" + + +class ColorText(nodes.Inline, nodes.TextElement): # noqa: D101 + pass + + +def visit_color_text(self: Writer, node: ColorText): # noqa: D103 + self.body.append(self.starttag(node, "span", "", style=node["style"])) + + +def depart_color_text(self: Writer, node: ColorText): # noqa: D103 + self.body.append("") + + +def create_color_role(code): + """Generate role function from color-code(RGB).""" + + def _color_role( + role: str, + rawtext: str, + text: str, + lineno: int, + inliner: Inliner, + options: Optional[dict] = None, + content: Optional[List[str]] = None, + ): # noqa: D103 + options = roles.normalized_role_options(options) + messages = [] + node = ColorText(rawtext, text) + node["style"] = f"color: {code}" + return [node], messages + + return _color_role + + +def register_colors(app: Sphinx, config: Config): + """Grenerate and register role for color-text. + + This func refs ``COLORS`` and conf.py to generate. + """ + for name, code in COLORS.items(): + roles.register_canonical_role(f"color:{name}", create_color_role(code)) + def setup(app: Sphinx): # noqa: D103 + app.connect("config-inited", register_colors) + app.add_node(ColorText, html=(visit_color_text, depart_color_text)) return { "version": __version__, "env_version": 1, diff --git a/tests/test-root/index.rst b/tests/test-root/index.rst index ea7ca69..ec42c91 100644 --- a/tests/test-root/index.rst +++ b/tests/test-root/index.rst @@ -1,2 +1,4 @@ Test doc for atsphinx-color-text ================================ + +sphinx-revealjs is presentation library for Pythonista using reStructuredText and :color:red:`Sphinx`. diff --git a/tests/test_it.py b/tests/test_it.py index 350afbc..0175abd 100644 --- a/tests/test_it.py +++ b/tests/test_it.py @@ -2,9 +2,15 @@ from io import StringIO import pytest +from bs4 import BeautifulSoup from sphinx.testing.util import SphinxTestApp @pytest.mark.sphinx("html") def test__it(app: SphinxTestApp, status: StringIO, warning: StringIO): """Test to pass.""" + app.build() + html = app.outdir / "index.html" + soup = BeautifulSoup(html.read_text(), "html.parser") + span = soup.span + assert "style" in span.attrs