StrictDoc Documentation
strictdoc/features/html2pdf/html2pdf_generator.py
Source file coverage
Path:
strictdoc/features/html2pdf/html2pdf_generator.py
Lines:
139
Non-empty lines:
119
Non-empty lines covered with requirements:
119 / 119 (100.0%)
Functions:
2
Functions covered by requirements:
2 / 2 (100.0%)
1
"""
2
@relation(SDOC-SRS-51, scope=file)
3
"""
4
 
5
import os
6
from pathlib import Path
7
from typing import List, Tuple
8
 
9
from strictdoc.core.project_config import ProjectConfig
10
from strictdoc.core.traceability_index import TraceabilityIndex
11
from strictdoc.export.html.html_generator import HTMLGenerator
12
from strictdoc.export.html.html_templates import HTMLTemplates
13
from strictdoc.export.html.renderers.link_renderer import LinkRenderer
14
from strictdoc.export.html.renderers.markup_renderer import MarkupRenderer
15
from strictdoc.features.html2pdf.generator import (
16
    DocumentHTML2PDFGenerator,
17
)
18
from strictdoc.features.html2pdf.pdf_print_driver import PDFPrintDriver
19
from strictdoc.helpers.exception import StrictDocException
20
from strictdoc.helpers.git_client import GitClient
21
from strictdoc.helpers.timing import measure_performance
22
 
23
 
24
class HTML2PDFGenerator:
25
    @staticmethod
26
    def export_tree(
27
        project_config: ProjectConfig,
28
        traceability_index: TraceabilityIndex,
29
        html_templates: HTMLTemplates,
30
        output_html2pdf_root: str,
31
        flat_assets: bool = False,
32
    ) -> None:
33
        if not project_config.is_activated_html2pdf():
34
            raise StrictDocException("HTML2PDF feature is not enabled")
35
 
36
        git_client: GitClient = GitClient()
37
 
38
        path_to_output_pdf_html_dir = os.path.join(output_html2pdf_root, "html")
39
        path_to_output_pdf_pdf_dir = os.path.join(output_html2pdf_root, "pdf")
40
 
41
        HTMLGenerator.export_assets(
42
            traceability_index=traceability_index,
43
            project_config=project_config,
44
            html_templates=html_templates,
45
            export_output_html_root=path_to_output_pdf_html_dir,
46
            flat_assets=flat_assets,
47
        )
48
 
49
        paths_to_print: List[Tuple[str, str]] = []
50
 
51
        for document_ in traceability_index.document_tree.document_list:
52
            assert document_.meta is not None
53
 
54
            # Skip generating the included documents, unless the option is provided.
55
            if not project_config.export_included_documents:
56
                if document_.document_is_included():
57
                    continue
58
 
59
            root_path = document_.meta.get_root_path_prefix()
60
 
61
            link_renderer = LinkRenderer(
62
                root_path=root_path,
63
                static_path=project_config.dir_for_sdoc_assets,
64
            )
65
            # The document meta's output_document_dir_full_path points to the
66
            # regular HTML output directory, but html2pdf copies assets to a
67
            # separate html2pdf/html/ tree. Pass the correct directory so that
68
            # RST wildcard image resolution (image.*) finds assets at the right
69
            # location. For the bundle (flat_assets=True) all assets sit at the
70
            # root of path_to_output_pdf_html_dir; for individual documents they
71
            # sit inside each document's own subdirectory.
72
            if flat_assets:
73
                rst_reference_path = path_to_output_pdf_html_dir
74
            else:
75
                rst_reference_path = os.path.join(
76
                    path_to_output_pdf_html_dir,
77
                    document_.meta.output_document_dir_rel_path.relative_path,
78
                )
79
            markup_renderer = MarkupRenderer.create(
80
                document_.config.get_markup(),
81
                traceability_index,
82
                link_renderer,
83
                html_templates,
84
                project_config,
85
                document_,
86
                flat_assets=flat_assets,
87
                reference_path_override=rst_reference_path,
88
            )
89
 
90
            with measure_performance("Generating printable HTML document"):
91
                document_content = DocumentHTML2PDFGenerator.export(
92
                    project_config,
93
                    document_,
94
                    traceability_index,
95
                    markup_renderer,
96
                    link_renderer,
97
                    git_client=git_client,
98
                    html_templates=html_templates,
99
                )
100
 
101
            path_to_output_html_doc_dir = os.path.join(
102
                path_to_output_pdf_html_dir,
103
                document_.meta.output_document_dir_rel_path.relative_path,
104
            )
105
            Path(path_to_output_html_doc_dir).mkdir(parents=True, exist_ok=True)
106
            Path(path_to_output_pdf_pdf_dir).mkdir(parents=True, exist_ok=True)
107
 
108
            path_to_output_html_doc = os.path.join(
109
                path_to_output_html_doc_dir,
110
                document_.meta.document_filename_base + "-PDF.html",
111
            )
112
 
113
            with open(
114
                path_to_output_html_doc, "w", encoding="utf8"
115
            ) as output_html_doc_file_:
116
                output_html_doc_file_.write(document_content)
117
 
118
            path_to_output_pdf_dir = os.path.join(
119
                path_to_output_pdf_pdf_dir,
120
                document_.meta.input_doc_dir_rel_path.relative_path,
121
            )
122
            Path(path_to_output_pdf_dir).mkdir(parents=True, exist_ok=True)
123
 
124
            path_to_output_pdf = os.path.join(
125
                path_to_output_pdf_dir,
126
                document_.meta.document_filename_base + ".pdf",
127
            )
128
 
129
            paths_to_print.append((path_to_output_html_doc, path_to_output_pdf))
130
 
131
        pdf_print_driver = PDFPrintDriver()
132
        try:
133
            pdf_print_driver.get_pdf_from_html(
134
                project_config,
135
                paths_to_print,
136
                path_to_output_pdf_html_dir,
137
            )
138
        except TimeoutError:
139
            print("error: HTML2PDF: timeout error.")  # noqa: T201