File: environment.py

package info (click to toggle)
sphinx-needs 5.1.0%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 12,108 kB
  • sloc: python: 21,148; javascript: 187; makefile: 95; sh: 29; xml: 10
file content (138 lines) | stat: -rw-r--r-- 4,749 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from __future__ import annotations

from pathlib import Path

from jinja2 import Environment, PackageLoader, select_autoescape
from sphinx import version_info as sphinx_version
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
from sphinx.util.fileutil import copy_asset, copy_asset_file

from sphinx_needs.config import NeedsSphinxConfig
from sphinx_needs.logging import log_warning
from sphinx_needs.utils import logger

_STATIC_DIR_NAME = "_static"


def _add_css_file(app: Sphinx, rel_path: Path) -> None:
    # note this deduplication is already done in Sphinx v7.2.1+
    # https://github.com/sphinx-doc/sphinx/commit/0c22d9c9ff4a0a6b3ce2f0aa6bc591b4525b4163
    rel_str = rel_path.as_posix()
    if sphinx_version < (7, 2) and f"_static/{rel_str}" in getattr(
        app.builder, "css_files", []
    ):
        return
    app.add_css_file(rel_str)


def _add_js_file(app: Sphinx, rel_path: Path) -> None:
    # note this deduplication is already done in Sphinx v7.2.1+
    # https://github.com/sphinx-doc/sphinx/commit/0c22d9c9ff4a0a6b3ce2f0aa6bc591b4525b4163
    rel_str = rel_path.as_posix()
    if sphinx_version < (7, 2) and f"_static/{rel_str}" in getattr(
        app.builder, "script_files", []
    ):
        return
    app.add_js_file(rel_str)


def install_styles_static_files(app: Sphinx, env: BuildEnvironment) -> None:
    builder = app.builder
    # Do not copy static_files for our "needs" builder
    if builder.name == "needs":
        return

    logger.info("Copying static style files for sphinx-needs")

    config = NeedsSphinxConfig(app.config)

    statics_dir = Path(builder.outdir) / _STATIC_DIR_NAME
    dest_dir = statics_dir / "sphinx-needs"
    css_root = Path(__file__).parent / "css"

    # Add common css files
    copy_asset(
        str(css_root.joinpath("common")),
        str(dest_dir.joinpath("common_css")),
        lambda path: not path.endswith(".css"),
    )
    for common_path in sorted(dest_dir.joinpath("common_css").glob("*.css")):
        _add_css_file(app, common_path.relative_to(statics_dir))

    # Add theme css file
    if config.css in [f.name for f in sorted(css_root.joinpath("themes").glob("*.css"))]:
        copy_asset_file(str(css_root.joinpath("themes", config.css)), str(dest_dir))
        _add_css_file(app, dest_dir.joinpath(config.css).relative_to(statics_dir))
    elif Path(config.css).is_file():
        copy_asset_file(config.css, str(dest_dir))
        _add_css_file(
            app, dest_dir.joinpath(Path(config.css).name).relative_to(statics_dir)
        )
    else:
        log_warning(
            logger,
            f"needs_css not an existing file: {config.css}",
            "config",
            None,
        )


def install_lib_static_files(app: Sphinx, env: BuildEnvironment) -> None:
    """
    Copies css and js files from needed js/css libs
    :param app:
    :param env:
    :return:
    """
    builder = app.builder
    # Do not copy static_files for our "needs" builder
    if builder.name == "needs":
        return

    logger.info("Copying static files for sphinx-needs datatables support")

    statics_dir = Path(builder.outdir) / _STATIC_DIR_NAME
    source_dir = Path(__file__).parent / "libs" / "html"
    destination_dir = statics_dir / "sphinx-needs" / "libs" / "html"

    # "Copying static files for sphinx-needs datatables support..."
    copy_asset(str(source_dir), str(destination_dir))

    # Add the needed datatables js and css file
    lib_path = Path("sphinx-needs") / "libs" / "html"
    _add_js_file(app, lib_path.joinpath("datatables.min.js"))
    _add_js_file(app, lib_path.joinpath("datatables_loader.js"))
    _add_css_file(app, lib_path.joinpath("datatables.min.css"))
    _add_js_file(app, lib_path.joinpath("sphinx_needs_collapse.js"))


def install_permalink_file(app: Sphinx, env: BuildEnvironment) -> None:
    """
    Creates permalink.html in build dir
    :param app:
    :param env:
    :return:
    """
    builder = app.builder
    # Do not copy static_files for our "needs" builder
    if builder.name == "needs":
        return

    # load jinja template
    jinja_env = Environment(
        loader=PackageLoader("sphinx_needs"), autoescape=select_autoescape()
    )
    template = jinja_env.get_template("permalink.html")

    # save file to build dir
    sphinx_config = NeedsSphinxConfig(env.config)
    out_file = Path(builder.outdir) / Path(sphinx_config.permalink_file).name
    with open(out_file, "w", encoding="utf-8") as f:
        f.write(
            template.render(
                permalink_file=sphinx_config.permalink_file,
                needs_file=sphinx_config.permalink_data,
                **sphinx_config.render_context,
            )
        )