Coverage for hdl_registers/generator/html/page.py: 100%
42 statements
« prev ^ index » next coverage.py v7.6.8, created at 2024-12-01 20:50 +0000
« prev ^ index » next coverage.py v7.6.8, created at 2024-12-01 20:50 +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{self.header}
47<!DOCTYPE html>
48<html>
49<head>
50 <title>{title}</title>
51 <!-- Include the style both inline and as a link to a separate CSS file. -->
52 <!-- Some tools, e.g. Jenkins, will not render with an inline stylesheet. -->
53 <!-- For other tools, e.g. page inclusion in sphinx, the style must be in the file. -->
54 <link rel="stylesheet" href="regs_style.css">
55 <style>
56 {self.get_page_style()}
57 </style>
58</head>
59<body>
60 <h1>{title}</h1>
61 <p>This document is a specification for the register interface of the FPGA module \
62<b>{self.name}</b>.</p>
63 <p>{' '.join(self.generated_source_info)}</p>
64 <h2>Register modes</h2>
65 <p>The following register modes are available.</p>
66{self._get_mode_descriptions()}
67"""
69 html += " <h2>Registers</h2>\n"
70 if self.register_list.register_objects:
71 register_table_generator = HtmlRegisterTableGenerator(
72 register_list=self.register_list, output_folder=self.output_folder
73 )
74 html += f"""
75 <p>The following registers make up the register map.</p>
76{register_table_generator.get_code()}
77"""
78 else:
79 html += " <p>This module does not have any registers.</p>"
81 html += " <h2>Constants</h2>\n"
82 if self.register_list.constants:
83 constant_table_generator = HtmlConstantTableGenerator(
84 register_list=self.register_list, output_folder=self.output_folder
85 )
86 html += f"""
87 <p>The following constants are part of the register interface.</p>
88{constant_table_generator.get_code()}"""
89 else:
90 html += " <p>This module does not have any constants.</p>"
92 html += """
93</body>
94</html>"""
96 return html
98 @staticmethod
99 def get_page_style(
100 table_style: Optional[str] = None, font_style: Optional[str] = None, extra_style: str = ""
101 ) -> str:
102 """
103 Get a CSS style for the register pages. Shall be saved to a file called ``regs_style.css``.
105 Return:
106 str: CSS code.
107 """
108 if font_style is None:
109 font_style = """
110html * {
111 font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
112}"""
114 if table_style is None:
115 table_style = """
116table {
117 border-collapse: collapse;
118}
119td, th {
120 border-width: 1px;
121 border-style: solid;
122 border-color: #ddd;
123 padding: 8px;
124}
125td.array_header {
126 border-top-width: 10px;
127 border-top-color: #4cacaf;
128}
129td.array_footer {
130 border-bottom-width: 10px;
131 border-bottom-color: #4cacaf;
132}
133tr:nth-child(even) {
134 background-color: #f2f2f2;
135}
136th {
137 padding-top: 12px;
138 padding-bottom: 12px;
139 text-align: left;
140 background-color: #4CAF50;
141 color: white;
142}"""
144 style = f"""
145{font_style}
146{table_style}
147{extra_style}"""
148 return style
150 @staticmethod
151 def _get_mode_descriptions() -> str:
152 html = """
153<table>
154<thead>
155 <tr>
156 <th>Mode</th>
157 <th>Description</th>
158 </tr>
159</thead>
160<tbody>"""
162 for mode in REGISTER_MODES.values():
163 html += f"""
164<tr>
165 <td>{mode.name}</td>
166 <td>{mode.description}</td>
167</tr>
168"""
169 html += """
170</tbody>
171</table>"""
172 return html