Coverage for src/mkdocs_iframe/plugin.py: 0.00%
73 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-05 09:22 -0400
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-05 09:22 -0400
1"""This module contains the `mkdocs_iframe` plugin."""
3from __future__ import annotations
5import re
6import shutil
7import textwrap
8from pathlib import Path
9from tempfile import mkdtemp
10from typing import TYPE_CHECKING, Any, Sequence
12from mkdocs.config.config_options import Type as MkType
13from mkdocs.plugins import BasePlugin
14from mkdocs.structure.files import File, Files
16from mkdocs_iframe.loggers import get_logger
18if TYPE_CHECKING:
19 from mkdocs.config import Config
21log = get_logger(__name__)
24class Report:
25 def __init__(self, name: str, path: str | None = None, index: str = "index.html"):
26 self.name = name
27 self.path = path or f"html{name}"
28 self.index = index
29 self.page_name = f"{name}.md"
30 self.id = f"{name}iframe"
32 def index_file(self, use_directory_urls: bool) -> str:
33 report_index = self.index
34 if report_index == "index.html":
35 report_index = f"{self.name}index.html"
37 if use_directory_urls:
38 return report_index
39 return f"{self.name}/{report_index}"
41 def index_page(self, use_directory_urls: bool) -> str:
42 index = self.index_file(use_directory_urls)
44 style = textwrap.dedent(
45 """
46 <style>
47 article h1, article > a, .md-sidebar--secondary {
48 display: none !important;
49 }
50 </style>
51 """,
52 )
54 iframe = textwrap.dedent(
55 f"""
56 <iframe
57 id="{self.id}"
58 src="{index}"
59 frameborder="0"
60 scrolling="no"
61 onload="resizeIframe();"
62 width="100%">
63 </iframe>
64 """,
65 )
67 script = textwrap.dedent(
68 f"""
69 <script>
70 var {self.id} = document.getElementById("{self.id}");
72 function resizeIframe() {{
73 {self.id}.style.height = {self.id}.contentWindow.document.documentElement.offsetHeight + 'px';
74 }}
76 testiframe.contentWindow.document.body.onclick = function() {{
77 {self.id}.contentWindow.location.reload();
78 }}
79 </script>
81 """,
82 )
83 page_contents = style + iframe + script
84 return page_contents
87class MkDocsIframePlugin(BasePlugin):
88 """The MkDocs plugin to integrate the HTML reports in the site."""
90 config_scheme: Sequence[tuple[str, MkType]] = (
91 ("reports", MkType(list, default=[])),
92 )
94 def reports(self) -> list[Report]:
95 return [Report(**report) for report in self.config.reports]
97 def on_files(self, files: Files, config: Config, **kwargs: Any) -> Files: # noqa: ARG002
98 """Add the html report to the navigation.
100 Hook for the [`on_files` event](https://www.mkdocs.org/user-guide/plugins/#on_files).
102 Arguments:
103 files: The files collection.
104 config: The MkDocs config object.
105 **kwargs: Additional arguments passed by MkDocs.
107 Returns:
108 The modified files collection.
110 """
111 site_dir = Path(config["site_dir"])
112 use_directory_urls = config["use_directory_urls"]
113 for report in self.reports():
114 page_contents = report.index_page(use_directory_urls)
115 tempdir = mkdtemp()
116 tempfile = Path(tempdir) / report.page_name
117 with tempfile.open("w") as fp:
118 fp.write(page_contents)
120 files.append(
121 File(
122 report.page_name,
123 str(tempfile.parent),
124 str(site_dir),
125 use_directory_urls,
126 )
127 )
129 return files
131 def on_post_build(self, config: Config, **kwargs: Any) -> None: # noqa: ARG002
132 """Copy the HTML reports into the site directory.
134 Hook for the [`on_post_build` event](https://www.mkdocs.org/user-guide/plugins/#on_post_build).
136 Arguments:
137 config: The MkDocs config object.
138 **kwargs: Additional arguments passed by MkDocs.
140 """
141 site_dir = Path(config["site_dir"])
142 use_directory_urls = config["use_directory_urls"]
144 for report in self.reports():
145 report_dir = site_dir / report.name
146 tmp_index = site_dir / f".{report.name}-tmp.html"
148 if report.index == "index.html":
149 if config["use_directory_urls"]:
150 shutil.move(report_dir / "index.html", tmp_index)
151 else:
152 shutil.move(report_dir.with_suffix(".html"), tmp_index)
154 shutil.rmtree(str(report_dir), ignore_errors=True)
155 try:
156 shutil.copytree(report.path, str(report_dir))
157 except FileNotFoundError:
158 log.warning(f"No such HTML report directory: {report_dir}")
159 return
161 if report.index == "index.html":
162 report_index = report.index_file(use_directory_urls)
164 shutil.move(report_dir / "index.html", report_dir / report_index)
165 if use_directory_urls:
166 shutil.move(str(tmp_index), report_dir / "index.html")
167 else:
168 shutil.move(str(tmp_index), report_dir.with_suffix(".html"))
170 for html_file in report_dir.iterdir():
171 if html_file.suffix == ".html" and html_file.name != "index.html":
172 html_file.write_text(re.sub(r'href="index\.html"', f'href="{report_index}"', html_file.read_text()))