Source code for click_extra.sphinx.tables
# 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.
"""Keep the first column of a two-axis table on one line.
A table whose top-left cell names both of its axes, as
{func}`~click_extra.table.corner_header` spells them, is read down its first
column and across its headers. On a narrow screen, a browser wraps that first
column wherever it can, including after the hyphen of `click-extra` or of a
date, which splits every label over several lines. The labels of such a table
are short, so this module keeps each one whole: the table scrolls sideways
instead, inside the `table-wrapper` Furo puts around every table.
The extension marks every table whose first header cell holds
{data}`~click_extra.table.CORNER_GLYPH`, and ships the stylesheet the mark
hooks into. The stylesheet is written into the build rather than packaged as a
data file.
"""
from __future__ import annotations
from pathlib import Path
from docutils import nodes
from ..table import CORNER_GLYPH
TYPE_CHECKING = False
if TYPE_CHECKING:
from sphinx.application import Sphinx
CORNER_TABLE_CLASS = "corner-table"
"""HTML class of a table whose top-left cell names both of its axes."""
CORNER_TABLE_CSS = f"""\
table.{CORNER_TABLE_CLASS} th:first-child,
table.{CORNER_TABLE_CLASS} td:first-child {{
white-space: nowrap;
}}
"""
"""Stylesheet keeping the first column of a corner-labeled table on one line."""
STATIC_DIR = "_click_extra_static"
"""Folder of the output directory the stylesheet is written to.
Sphinx copies it into `_static` with the other static files, as it does for
every folder listed in `html_static_path`.
"""
STYLESHEET = "click-extra.css"
"""File name of the stylesheet, served from the `_static` folder."""
[docs]
def mark_corner_tables(app: Sphinx, doctree: nodes.document) -> None:
"""Add {data}`CORNER_TABLE_CLASS` to every table with a corner label."""
for table in doctree.findall(nodes.table):
header = next(table.findall(nodes.thead), None)
corner = next(header.findall(nodes.entry), None) if header else None
if corner is not None and CORNER_GLYPH in corner.astext():
table["classes"].append(CORNER_TABLE_CLASS)
[docs]
def add_stylesheet(app: Sphinx) -> None:
"""Write {data}`CORNER_TABLE_CSS` into the build and link it from each page.
Only an HTML builder serves stylesheets, so other builders skip it.
"""
if app.builder.format != "html":
return
static_dir = Path(app.outdir) / STATIC_DIR
static_dir.mkdir(parents=True, exist_ok=True)
(static_dir / STYLESHEET).write_text(CORNER_TABLE_CSS, encoding="UTF-8")
app.config.html_static_path.append(str(static_dir))
app.add_css_file(STYLESHEET)
[docs]
def setup(app: Sphinx) -> None:
"""Register the table marker and its stylesheet on `app`.
Called from {func}`click_extra.sphinx.setup` so projects only need to list
`"click_extra.sphinx"` in their `extensions`.
"""
app.connect("doctree-read", mark_corner_tables)
app.connect("builder-inited", add_stylesheet)