Coverage for hdl_registers/generator/html/page.py: 100%
42 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 20:51 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 20:51 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the hdl-registers project, an HDL register generator fast enough to run
5# in real time.
6# https://hdl-registers.com
7# https://github.com/hdl-registers/hdl-registers
8# --------------------------------------------------------------------------------------------------
10# Standard libraries
11from pathlib import Path
12from typing import Any, Optional
14# First party libraries
15from hdl_registers.register_modes import REGISTER_MODES
17# Local folder libraries
18from .constant_table import HtmlConstantTableGenerator
19from .html_generator_common import HtmlGeneratorCommon
20from .register_table import HtmlRegisterTableGenerator
23class HtmlPageGenerator(HtmlGeneratorCommon):
24 """
25 Generate a HTML page with register and constant information.
26 See the :ref:`generator_html` article for usage details.
27 """
29 __version__ = "1.0.0"
31 SHORT_DESCRIPTION = "HTML page"
33 @property
34 def output_file(self) -> Path:
35 """
36 Result will be placed in this file.
37 """
38 return self.output_folder / f"{self.name}_regs.html"
40 def get_code(self, **kwargs: Any) -> str:
41 """
42 Get a complete HTML page with register and constant information.
43 """
44 title = f"Documentation of {self.name} registers"
45 html = f"""\
46<!DOCTYPE html>
47<html>
48<head>
49 <title>{title}</title>
50 <!-- Include the style both inline and as a link to a separate CSS file. -->
51 <!-- Some tools, e.g. Jenkins, will not render with an inline stylesheet. -->
52 <!-- For other tools, e.g. page inclusion in sphinx, the style must be in the file. -->
53 <link rel="stylesheet" href="regs_style.css">
54 <style>
55 {self.get_page_style()}
56 </style>
57</head>
58<body>
59 <h1>{title}</h1>
60 <p>This document is a specification for the register interface of the FPGA module \
61<b>{self.name}</b>.</p>
62 <p>{' '.join(self.generated_source_info)}</p>
63 <h2>Register modes</h2>
64 <p>The following register modes are available.</p>
65{self._get_mode_descriptions()}
66"""
68 html += " <h2>Registers</h2>\n"
69 if self.register_list.register_objects:
70 register_table_generator = HtmlRegisterTableGenerator(
71 register_list=self.register_list, output_folder=self.output_folder
72 )
73 html += f"""
74 <p>The following registers make up the register list.</p>
75{register_table_generator.get_code()}
76"""
77 else:
78 html += " <p>This module does not have any registers.</p>"
80 html += " <h2>Constants</h2>\n"
81 if self.register_list.constants:
82 constant_table_generator = HtmlConstantTableGenerator(
83 register_list=self.register_list, output_folder=self.output_folder
84 )
85 html += f"""
86 <p>The following constants are part of the register interface.</p>
87{constant_table_generator.get_code()}"""
88 else:
89 html += " <p>This module does not have any constants.</p>"
91 html += """
92</body>
93</html>"""
95 return html
97 @staticmethod
98 def get_page_style(
99 table_style: Optional[str] = None, font_style: Optional[str] = None, extra_style: str = ""
100 ) -> str:
101 """
102 Get a CSS style for the register pages. Shall be saved to a file called ``regs_style.css``.
104 Return:
105 str: CSS code.
106 """
107 if font_style is None:
108 font_style = """
109html * {
110 font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
111}"""
113 if table_style is None:
114 table_style = """
115table {
116 border-collapse: collapse;
117}
118td, th {
119 border-width: 1px;
120 border-style: solid;
121 border-color: #ddd;
122 padding: 8px;
123}
124td.array_header {
125 border-top-width: 10px;
126 border-top-color: #4cacaf;
127}
128td.array_footer {
129 border-bottom-width: 10px;
130 border-bottom-color: #4cacaf;
131}
132tr:nth-child(even) {
133 background-color: #f2f2f2;
134}
135th {
136 padding-top: 12px;
137 padding-bottom: 12px;
138 text-align: left;
139 background-color: #4CAF50;
140 color: white;
141}"""
143 style = f"""
144{font_style}
145{table_style}
146{extra_style}"""
147 return style
149 @staticmethod
150 def _get_mode_descriptions() -> str:
151 html = """
152<table>
153<thead>
154 <tr>
155 <th>Mode</th>
156 <th>Description</th>
157 </tr>
158</thead>
159<tbody>"""
161 for mode in REGISTER_MODES.values():
162 html += f"""
163<tr>
164 <td>{mode.name}</td>
165 <td>{mode.description}</td>
166</tr>
167"""
168 html += """
169</tbody>
170</table>"""
171 return html