diff --git a/docs/strictdoc_20_L1_Open_Requirements_Tool.sdoc b/docs/strictdoc_20_L1_Open_Requirements_Tool.sdoc index cd468abed..874d601e2 100644 --- a/docs/strictdoc_20_L1_Open_Requirements_Tool.sdoc +++ b/docs/strictdoc_20_L1_Open_Requirements_Tool.sdoc @@ -1121,6 +1121,18 @@ This section captures the requirements related to "Requirements exchange" as out The Requirements Tool should fundamentally support the exchange of documentation and requirements with other tools. Importing data into this tool and exporting data from it to other tools should be straightforward. The key focus of this section's requirements is on enabling seamless access to requirements and documentation data. <<< +[REQUIREMENT] +MID: 086eb992322d4c43ad91a40f6c9f9952 +UID: SDOC-SSS-96 +STATUS: Active +TITLE: PDF export +STATEMENT: >>> +The Requirements Tool shall support exporting documentation content to PDF, both individual documents and complete documentation trees. +<<< +RATIONALE: >>> +PDF is one of the most common formats for reviewing documentation. +<<< + [REQUIREMENT] MID: 73e70548c2cf415f94adbf1066d5fe4b UID: SDOC-SSS-58 diff --git a/docs/strictdoc_21_L2_StrictDoc_Requirements.sdoc b/docs/strictdoc_21_L2_StrictDoc_Requirements.sdoc index 71114d4b2..f38e3c71d 100644 --- a/docs/strictdoc_21_L2_StrictDoc_Requirements.sdoc +++ b/docs/strictdoc_21_L2_StrictDoc_Requirements.sdoc @@ -741,13 +741,18 @@ RELATIONS: MID: f2fd90ad8a2946e7b085233a9c7a8a75 UID: SDOC-SRS-51 STATUS: Active -TITLE: Export to printable HTML pages (HTML2PDF) +TITLE: Export to HTML content to PDF (HTML2PDF) STATEMENT: >>> -StrictDoc shall provide export to printable HTML pages. +StrictDoc shall allow exporting documents and entire documentation trees to PDF. +<<< +RATIONALE: >>> +As required by the parent requirement, PDF is one of the most common documentation formats. <<< RELATIONS: - TYPE: Parent VALUE: DO178-5 +- TYPE: Parent + VALUE: SDOC-SSS-96 [REQUIREMENT] MID: 8811f0ef33de4365bc66a602a8c184f6 diff --git a/docs_extra/DO178_requirements.sdoc b/docs_extra/DO178_requirements.sdoc index 0c766cbf0..adf4243aa 100644 --- a/docs_extra/DO178_requirements.sdoc +++ b/docs_extra/DO178_requirements.sdoc @@ -173,9 +173,6 @@ TITLE: PDF and HTML publishing STATEMENT: >>> StrictDoc shall support publication of documents to HTML and PDF formats. <<< -COMMENT: >>> -N: Sphinx is nice for release. -<<< [REQUIREMENT] MID: 8b73ce9efcc840b2be272d5aaef08e70 diff --git a/strictdoc/core/actions/export_action.py b/strictdoc/core/actions/export_action.py index 9df4a460f..86abe4fa3 100644 --- a/strictdoc/core/actions/export_action.py +++ b/strictdoc/core/actions/export_action.py @@ -105,6 +105,7 @@ def export(self) -> None: specific_documents=(DocumentType.DOCUMENT,), ) + # @relation(SDOC-SRS-51, scope=range_start) if "html2pdf" in self.project_config.export_formats: output_html2pdf_root = os.path.join( self.project_config.output_dir, "html2pdf" @@ -128,6 +129,7 @@ def export(self) -> None: output_html2pdf_root, flat_assets=True, ) + # @relation(SDOC-SRS-51, scope=range_end) if "rst" in self.project_config.export_formats: output_rst_root = os.path.join( diff --git a/strictdoc/core/traceability_index.py b/strictdoc/core/traceability_index.py index f4b11b200..c1191cac1 100644 --- a/strictdoc/core/traceability_index.py +++ b/strictdoc/core/traceability_index.py @@ -989,6 +989,8 @@ def clone_to_bundle_document( - The bundle is generated to the root of the output folder (level=0). - Some variables do not contribute (yet) to the final result, so they are marked as NOT_RELEVANT. + + @relation(SDOC-SRS-51, scope=function) """ traceability_index_copy = deepcopy(self) bundle_document = SDocDocument( diff --git a/strictdoc/export/html/renderers/link_renderer.py b/strictdoc/export/html/renderers/link_renderer.py index 3f868482d..c90f0c17a 100644 --- a/strictdoc/export/html/renderers/link_renderer.py +++ b/strictdoc/export/html/renderers/link_renderer.py @@ -114,6 +114,13 @@ def render_node_link( assert isinstance(node, (SDocNode, Anchor)), node assert isinstance(document_type, DocumentType), type(document_type) local_link = self.render_local_anchor(node) + + # If the context document is a bundle, all contained documents are + # merged into this bundle document. In this case, all links are local, + # so there is no need to resolve links to external documents. + if context_document is not None and context_document.is_bundle_document: + return f"#{local_link}" + including_document = node.get_including_document() if ( including_document is not None diff --git a/tests/integration/features/html2pdf/01_empty_document/test.itest b/tests/integration/features/html2pdf/01_empty_document/test.itest index 346ab1477..15be501bc 100644 --- a/tests/integration/features/html2pdf/01_empty_document/test.itest +++ b/tests/integration/features/html2pdf/01_empty_document/test.itest @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + REQUIRES: TEST_HTML2PDF RUN: %strictdoc export %S --formats=html2pdf --output-dir %T | filecheck %s --dump-input=fail diff --git a/tests/integration/features/html2pdf/01_empty_document/test_pdf.py b/tests/integration/features/html2pdf/01_empty_document/test_pdf.py index 7d4d94da1..8693e9e89 100644 --- a/tests/integration/features/html2pdf/01_empty_document/test_pdf.py +++ b/tests/integration/features/html2pdf/01_empty_document/test_pdf.py @@ -1,3 +1,7 @@ +""" +@relation(SDOC-SRS-51, scope=file) +""" + from pypdf import PdfReader reader = PdfReader("Output/html2pdf/pdf/input.pdf") diff --git a/tests/integration/features/html2pdf/02_three_top_level_requirements/test.itest b/tests/integration/features/html2pdf/02_three_top_level_requirements/test.itest index fff103c2e..0220a9de3 100644 --- a/tests/integration/features/html2pdf/02_three_top_level_requirements/test.itest +++ b/tests/integration/features/html2pdf/02_three_top_level_requirements/test.itest @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + REQUIRES: TEST_HTML2PDF RUN: %strictdoc export %S --formats=html2pdf --output-dir %T | filecheck %s --dump-input=fail diff --git a/tests/integration/features/html2pdf/02_three_top_level_requirements/test_pdf.py b/tests/integration/features/html2pdf/02_three_top_level_requirements/test_pdf.py index 34c553a58..c3fcafc6b 100644 --- a/tests/integration/features/html2pdf/02_three_top_level_requirements/test_pdf.py +++ b/tests/integration/features/html2pdf/02_three_top_level_requirements/test_pdf.py @@ -1,3 +1,7 @@ +""" +@relation(SDOC-SRS-51, scope=file) +""" + from pypdf import PdfReader reader = PdfReader("Output/html2pdf/pdf/input.pdf") diff --git a/tests/integration/features/html2pdf/03_three_documents_with_assets/test.itest b/tests/integration/features/html2pdf/03_three_documents_with_assets/test.itest index 083765c19..f16d7fb4b 100644 --- a/tests/integration/features/html2pdf/03_three_documents_with_assets/test.itest +++ b/tests/integration/features/html2pdf/03_three_documents_with_assets/test.itest @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + REQUIRES: TEST_HTML2PDF RUN: %strictdoc export %S --formats=html2pdf --output-dir %T | filecheck %s --dump-input=fail diff --git a/tests/integration/features/html2pdf/03_three_documents_with_assets/test_pdf.py b/tests/integration/features/html2pdf/03_three_documents_with_assets/test_pdf.py index 5dc7e56f1..8b36b0c38 100644 --- a/tests/integration/features/html2pdf/03_three_documents_with_assets/test_pdf.py +++ b/tests/integration/features/html2pdf/03_three_documents_with_assets/test_pdf.py @@ -1,3 +1,7 @@ +""" +@relation(SDOC-SRS-51, scope=file) +""" + from pypdf import PdfReader reader = PdfReader("Output/html2pdf/pdf/input.pdf") diff --git a/tests/integration/features/html2pdf/04_composable_document_with_assets/test.itest b/tests/integration/features/html2pdf/04_composable_document_with_assets/test.itest index e2f33ebd9..f246804a3 100644 --- a/tests/integration/features/html2pdf/04_composable_document_with_assets/test.itest +++ b/tests/integration/features/html2pdf/04_composable_document_with_assets/test.itest @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + REQUIRES: TEST_HTML2PDF RUN: %strictdoc export %S --formats=html2pdf --included-documents --output-dir %T | filecheck %s --dump-input=fail diff --git a/tests/integration/features/html2pdf/04_composable_document_with_assets/test_bundle_pdf.py b/tests/integration/features/html2pdf/04_composable_document_with_assets/test_bundle_pdf.py index d10b0966f..686355c4e 100644 --- a/tests/integration/features/html2pdf/04_composable_document_with_assets/test_bundle_pdf.py +++ b/tests/integration/features/html2pdf/04_composable_document_with_assets/test_bundle_pdf.py @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + from pypdf import PdfReader reader = PdfReader("Output/html2pdf/pdf/bundle.pdf") diff --git a/tests/integration/features/html2pdf/04_composable_document_with_assets/test_pdf.py b/tests/integration/features/html2pdf/04_composable_document_with_assets/test_pdf.py index c7ffa4153..207aefef1 100644 --- a/tests/integration/features/html2pdf/04_composable_document_with_assets/test_pdf.py +++ b/tests/integration/features/html2pdf/04_composable_document_with_assets/test_pdf.py @@ -1,3 +1,7 @@ +""" +@relation(SDOC-SRS-51, scope=file) +""" + from pypdf import PdfReader reader = PdfReader("Output/html2pdf/pdf/input.pdf") diff --git a/tests/integration/features/html2pdf/05_generate_bundle_document/test.itest b/tests/integration/features/html2pdf/05_generate_bundle_document/test.itest index b5e41d898..809377e5a 100644 --- a/tests/integration/features/html2pdf/05_generate_bundle_document/test.itest +++ b/tests/integration/features/html2pdf/05_generate_bundle_document/test.itest @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + REQUIRES: TEST_HTML2PDF RUN: %strictdoc export %S --formats=html2pdf --generate-bundle-document --output-dir %T | filecheck %s --dump-input=fail diff --git a/tests/integration/features/html2pdf/05_generate_bundle_document/test_pdf.py b/tests/integration/features/html2pdf/05_generate_bundle_document/test_pdf.py index d10b0966f..025edf940 100644 --- a/tests/integration/features/html2pdf/05_generate_bundle_document/test_pdf.py +++ b/tests/integration/features/html2pdf/05_generate_bundle_document/test_pdf.py @@ -1,3 +1,7 @@ +""" +@relation(SDOC-SRS-51, scope=file) +""" + from pypdf import PdfReader reader = PdfReader("Output/html2pdf/pdf/bundle.pdf") diff --git a/tests/integration/features/html2pdf/06_system_chromedriver/test.itest b/tests/integration/features/html2pdf/06_system_chromedriver/test.itest index baf5ecd0a..353e8d725 100644 --- a/tests/integration/features/html2pdf/06_system_chromedriver/test.itest +++ b/tests/integration/features/html2pdf/06_system_chromedriver/test.itest @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + REQUIRES: TEST_HTML2PDF REQUIRES: SYSTEM_CHROMEDRIVER diff --git a/tests/integration/features/html2pdf/06_system_chromedriver/test_pdf.py b/tests/integration/features/html2pdf/06_system_chromedriver/test_pdf.py index 7d4d94da1..8693e9e89 100644 --- a/tests/integration/features/html2pdf/06_system_chromedriver/test_pdf.py +++ b/tests/integration/features/html2pdf/06_system_chromedriver/test_pdf.py @@ -1,3 +1,7 @@ +""" +@relation(SDOC-SRS-51, scope=file) +""" + from pypdf import PdfReader reader = PdfReader("Output/html2pdf/pdf/input.pdf") diff --git a/tests/integration/features/html2pdf/07_composable_document_with_relations/test.itest b/tests/integration/features/html2pdf/07_composable_document_with_relations/test.itest index 046ed3a06..05a91bb62 100644 --- a/tests/integration/features/html2pdf/07_composable_document_with_relations/test.itest +++ b/tests/integration/features/html2pdf/07_composable_document_with_relations/test.itest @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + REQUIRES: TEST_HTML2PDF RUN: %strictdoc export %S --formats=html2pdf --included-documents --output-dir %T | filecheck %s --dump-input=fail @@ -9,10 +11,11 @@ RUN: %check_exists --file %T/html2pdf/pdf/input.pdf RUN: %cat %T/html2pdf/html/%THIS_TEST_FOLDER/input-PDF.html | filecheck %s --dump-input=fail --check-prefix CHECK-INPUT-PDF CHECK-INPUT-PDF:

First statement links to second: 🔗 1.2. second one

-RUN: %strictdoc export %S --formats=html2pdf --included-documents --generate-bundle-document --output-dir %T | filecheck %s --dump-input=fail # With --generate-bundle-document, a bundle document is generated. +RUN: %strictdoc export %S --formats=html2pdf --included-documents --generate-bundle-document --output-dir %T | filecheck %s --dump-input=fail RUN: %check_exists --file %T/html2pdf/html/bundle-PDF.html RUN: %check_exists --file %T/html2pdf/pdf/bundle.pdf -FIXME: CHECK-INPUT-PDF-BUNDLE: Resolve the links correctly. - +RUN: %cat %T/html2pdf/html/bundle-PDF.html | filecheck %s --dump-input=fail --check-prefix CHECK-BUNDLE-PDF +# The link points to the same bundle document, not to its parent document. +CHECK-BUNDLE-PDF:

First statement links to second: 🔗 1.1.2. second one

diff --git a/tests/integration/features/html2pdf/90_strictdoc_smoke_test_html2pdf/test.itest b/tests/integration/features/html2pdf/90_strictdoc_smoke_test_html2pdf/test.itest index fa89d9c3f..0256b27d6 100644 --- a/tests/integration/features/html2pdf/90_strictdoc_smoke_test_html2pdf/test.itest +++ b/tests/integration/features/html2pdf/90_strictdoc_smoke_test_html2pdf/test.itest @@ -1,3 +1,5 @@ +# @relation(SDOC-SRS-51, scope=file) + REQUIRES: PLATFORM_IS_NOT_WINDOWS REQUIRES: TEST_HTML2PDF diff --git a/tools/html2pdf4doc_fuzzer.py b/tools/html2pdf4doc_fuzzer.py index 44e9f0896..b43c17764 100644 --- a/tools/html2pdf4doc_fuzzer.py +++ b/tools/html2pdf4doc_fuzzer.py @@ -1,3 +1,7 @@ +""" +@relation(SDOC-SRS-51, scope=file) +""" + import argparse import datetime import os.path