strictdoc 0.0.43a3__tar.gz → 0.0.43a4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/PKG-INFO +1 -1
  2. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/__init__.py +1 -1
  3. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/error_handling.py +6 -0
  4. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/grammar/grammar.py +23 -2
  5. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/grammar/type_system.py +2 -2
  6. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/writer.py +5 -1
  7. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/commands/section.py +61 -43
  8. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/commands/update_document_config.py +31 -21
  9. strictdoc-0.0.43a4/strictdoc/export/dot/document_dot_generator.py +301 -0
  10. strictdoc-0.0.43a4/strictdoc/export/dot/templates/profile1/document.dot +12 -0
  11. strictdoc-0.0.43a4/strictdoc/export/dot/templates/profile1/folder.dot +15 -0
  12. strictdoc-0.0.43a4/strictdoc/export/dot/templates/profile1/legend.dot +69 -0
  13. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/dot/templates/profile1/requirement.dot +7 -3
  14. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/dot/templates/profile1/top_level.dot +8 -1
  15. strictdoc-0.0.43a4/strictdoc/export/dot/templates/profile2/document.dot +4 -0
  16. strictdoc-0.0.43a4/strictdoc/export/dot/templates/profile2/folder.dot +3 -0
  17. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/anchor_controller.js +7 -8
  18. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/element.css +18 -8
  19. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/renderers/markup_renderer.py +1 -4
  20. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/multiline/index.jinja +1 -1
  21. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/_shared/frame_toc.jinja +8 -6
  22. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/rst/rst_to_html_fragment_writer.py +1 -0
  23. strictdoc-0.0.43a3/strictdoc/export/dot/document_dot_generator.py +0 -157
  24. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/.gitignore +0 -0
  25. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/CHANGELOG.md +0 -0
  26. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/CONTRIBUTING.md +0 -0
  27. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/Dockerfile +0 -0
  28. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/LICENSE +0 -0
  29. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/NOTICE +0 -0
  30. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/README.md +0 -0
  31. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/drafts/strictdoc_low_level_requirements.sdoc +0 -0
  32. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/favicon.ico +0 -0
  33. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/mypy.ini +0 -0
  34. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/pyproject.toml +0 -0
  35. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/requirements.check.txt +0 -0
  36. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/ruff.toml +0 -0
  37. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/__init__.py +0 -0
  38. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/excel/__init__.py +0 -0
  39. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/excel/excel_import.py +0 -0
  40. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/excel/export/__init__.py +0 -0
  41. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/excel/export/excel_generator.py +0 -0
  42. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/excel/import_/__init__.py +0 -0
  43. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/excel/import_/excel_to_sdoc_converter.py +0 -0
  44. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/__init__.py +0 -0
  45. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/export/__init__.py +0 -0
  46. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/export/sdoc_to_reqif_converter.py +0 -0
  47. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/import_/__init__.py +0 -0
  48. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/import_/reqif_to_sdoc_converter.py +0 -0
  49. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/p11_polarion/__init__.py +0 -0
  50. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/p11_polarion/reqif_to_sdoc_converter.py +0 -0
  51. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/reqif_export.py +0 -0
  52. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/reqif_import.py +0 -0
  53. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/reqif/sdoc_reqif_fields.py +0 -0
  54. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/__init__.py +0 -0
  55. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/document_reference.py +0 -0
  56. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/errors/__init__.py +0 -0
  57. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/errors/document_tree_error.py +0 -0
  58. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/free_text_reader.py +0 -0
  59. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/grammar/__init__.py +0 -0
  60. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/grammar/grammar_builder.py +0 -0
  61. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/include_reader.py +0 -0
  62. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/__init__.py +0 -0
  63. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/anchor.py +0 -0
  64. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/constants.py +0 -0
  65. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/document.py +0 -0
  66. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/document_config.py +0 -0
  67. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/document_grammar.py +0 -0
  68. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/fragment.py +0 -0
  69. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/fragment_from_file.py +0 -0
  70. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/free_text.py +0 -0
  71. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/inline_link.py +0 -0
  72. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/node.py +0 -0
  73. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/object_factory.py +0 -0
  74. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/reference.py +0 -0
  75. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/requirement.py +0 -0
  76. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/section.py +0 -0
  77. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/models/type_system.py +0 -0
  78. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/processor.py +0 -0
  79. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/reader.py +0 -0
  80. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/validations/__init__.py +0 -0
  81. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc/validations/requirement.py +0 -0
  82. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc_source_code/__init__.py +0 -0
  83. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc_source_code/grammar.py +0 -0
  84. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc_source_code/models/__init__.py +0 -0
  85. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc_source_code/models/range_pragma.py +0 -0
  86. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc_source_code/models/source_file_info.py +0 -0
  87. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/backend/sdoc_source_code/reader.py +0 -0
  88. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/cli/__init__.py +0 -0
  89. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/cli/argument_int_range.py +0 -0
  90. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/cli/cli_arg_parser.py +0 -0
  91. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/cli/command_parser_builder.py +0 -0
  92. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/cli/main.py +0 -0
  93. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/commands/__init__.py +0 -0
  94. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/commands/about_command.py +0 -0
  95. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/commands/dump_grammar_command.py +0 -0
  96. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/commands/manage_autouid_command.py +0 -0
  97. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/commands/version_command.py +0 -0
  98. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/__init__.py +0 -0
  99. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/actions/__init__.py +0 -0
  100. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/actions/export_action.py +0 -0
  101. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/actions/import_action.py +0 -0
  102. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/actions/passthrough_action.py +0 -0
  103. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/commands/constants.py +0 -0
  104. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/commands/delete_section.py +0 -0
  105. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/commands/validation_error.py +0 -0
  106. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/document_finder.py +0 -0
  107. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/document_iterator.py +0 -0
  108. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/document_meta.py +0 -0
  109. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/document_tree.py +0 -0
  110. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/document_tree_iterator.py +0 -0
  111. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/environment.py +0 -0
  112. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/file_traceability_index.py +0 -0
  113. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/file_tree.py +0 -0
  114. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/finders/__init__.py +0 -0
  115. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/finders/source_files_finder.py +0 -0
  116. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/graph/validations.py +0 -0
  117. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/graph_database.py +0 -0
  118. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/level_counter.py +0 -0
  119. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/project_config.py +0 -0
  120. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/source_tree.py +0 -0
  121. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/traceability_index.py +0 -0
  122. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/traceability_index_builder.py +0 -0
  123. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/core/tree_cycle_detector.py +0 -0
  124. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/__init__.py +0 -0
  125. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/dot/dot_templates.py +0 -0
  126. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/dot/templates/profile1/section.dot +0 -0
  127. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/dot/templates/profile2/requirement.dot +0 -0
  128. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/dot/templates/profile2/section.dot +0 -0
  129. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/dot/templates/profile2/top_level.dot +0 -0
  130. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/__init__.py +0 -0
  131. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/base.css +0 -0
  132. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/content.css +0 -0
  133. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/collapsible_list_controller.js +0 -0
  134. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/deletable_field_controller.js +0 -0
  135. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/draggable_list_controller.js +0 -0
  136. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/dropdown_menu_controller.js +0 -0
  137. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/editable_field_controller.js +0 -0
  138. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/modal_controller.js +0 -0
  139. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/movable_field_controller.js +0 -0
  140. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/controllers/scroll_into_view_controller.js +0 -0
  141. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/favicon.ico +0 -0
  142. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/form.css +0 -0
  143. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/layout.css +0 -0
  144. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/node.css +0 -0
  145. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/pan_with_space.js +0 -0
  146. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/requirement-tree.css +0 -0
  147. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/requirement.css +0 -0
  148. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/requirement__temporary.css +0 -0
  149. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/requirements-coverage.js +0 -0
  150. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/resizable_bar.js +0 -0
  151. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/source-code-coverage.js +0 -0
  152. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/source.css +0 -0
  153. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/stimulus.js +0 -0
  154. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/tree.css +0 -0
  155. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/turbo.js +0 -0
  156. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static/viewtype_menu.js +0 -0
  157. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/LICENSE-MATHJAX +0 -0
  158. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/tex.js +0 -0
  159. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_AMS-Regular.woff +0 -0
  160. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Bold.woff +0 -0
  161. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Regular.woff +0 -0
  162. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Bold.woff +0 -0
  163. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Regular.woff +0 -0
  164. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Bold.woff +0 -0
  165. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Italic.woff +0 -0
  166. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Regular.woff +0 -0
  167. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-BoldItalic.woff +0 -0
  168. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-Italic.woff +0 -0
  169. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-Regular.woff +0 -0
  170. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Bold.woff +0 -0
  171. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Italic.woff +0 -0
  172. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Regular.woff +0 -0
  173. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Script-Regular.woff +0 -0
  174. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Size1-Regular.woff +0 -0
  175. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Size2-Regular.woff +0 -0
  176. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Size3-Regular.woff +0 -0
  177. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Size4-Regular.woff +0 -0
  178. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Typewriter-Regular.woff +0 -0
  179. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Vector-Bold.woff +0 -0
  180. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Vector-Regular.woff +0 -0
  181. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/output/chtml/fonts/woff-v2/MathJax_Zero.woff +0 -0
  182. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/_static_extra/mathjax/tex-mml-chtml.js +0 -0
  183. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/document_type.py +0 -0
  184. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/form_objects/document_config_form_object.py +0 -0
  185. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/form_objects/document_grammar_form_object.py +0 -0
  186. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/form_objects/requirement_form_object.py +0 -0
  187. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/form_objects/section_form_object.py +0 -0
  188. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/__init__.py +0 -0
  189. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/document.py +0 -0
  190. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/document_deep_trace.py +0 -0
  191. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/document_table.py +0 -0
  192. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/document_trace.py +0 -0
  193. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/document_tree.py +0 -0
  194. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/requirements_coverage.py +0 -0
  195. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/source_file_coverage.py +0 -0
  196. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/generators/source_file_view_generator.py +0 -0
  197. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/html_generator.py +0 -0
  198. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/html_templates.py +0 -0
  199. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/renderers/__init__.py +0 -0
  200. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/renderers/html_fragment_writer.py +0 -0
  201. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/renderers/link_renderer.py +0 -0
  202. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/renderers/text_to_html_writer.py +0 -0
  203. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg__separator.jinja.html +0 -0
  204. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_add.jinja.html +0 -0
  205. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_anchor.jinja +0 -0
  206. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_back.jinja.html +0 -0
  207. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_book.jinja.html +0 -0
  208. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_close.jinja +0 -0
  209. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_code.jinja.html +0 -0
  210. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_delete.jinja.html +0 -0
  211. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_document.jinja.html +0 -0
  212. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_edit.jinja.html +0 -0
  213. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_expand.jinja.html +0 -0
  214. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_folder.jinja +0 -0
  215. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_folder_sm.jinja +0 -0
  216. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_gear.jinja.html +0 -0
  217. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_index.jinja.html +0 -0
  218. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_list.jinja.html +0 -0
  219. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_maximize.jinja +0 -0
  220. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_minimize.jinja +0 -0
  221. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_minusminus.jinja.html +0 -0
  222. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_move_down.jinja.html +0 -0
  223. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_move_up.jinja.html +0 -0
  224. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_plusplus.jinja.html +0 -0
  225. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_project.jinja.html +0 -0
  226. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_requirement.jinja.html +0 -0
  227. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_source.jinja.html +0 -0
  228. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_toc.jinja.html +0 -0
  229. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_res/svg_ico16_tree.jinja +0 -0
  230. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_shared/nav.jinja.html +0 -0
  231. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_shared/requirement_block/files_tree.jinja.html +0 -0
  232. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_shared/requirement_block/uid_and_title.jinja.html +0 -0
  233. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_shared/requirement_tree_left.jinja.html +0 -0
  234. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_shared/requirement_tree_right.jinja.html +0 -0
  235. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/_shared/tags.jinja.html +0 -0
  236. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/deep_trace/show_full_requirement/stream_show_full_requirement.jinja +0 -0
  237. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/_shared/stream_refresh_document.jinja.html +0 -0
  238. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/_shared/stream_updated_toc.jinja.html +0 -0
  239. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/add_requirement_comment/stream_add_requirement_comment.jinja.html +0 -0
  240. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/add_requirement_parent_link/stream_add_requirement_parent_link.jinja.html +0 -0
  241. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/create_requirement/stream_cancel_new_requirement.jinja.html +0 -0
  242. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/create_requirement/stream_created_requirement.jinja.html +0 -0
  243. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/create_requirement/stream_new_requirement.jinja.html +0 -0
  244. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/create_section/stream_cancel_new_section.jinja.html +0 -0
  245. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/create_section/stream_created_section.jinja.html +0 -0
  246. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/create_section/stream_new_section.jinja.html +0 -0
  247. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/delete_requirement/stream_confirm_delete_requirement.jinja +0 -0
  248. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/delete_requirement/stream_delete_requirement.jinja.html +0 -0
  249. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/delete_section/stream_confirm_delete_section.jinja +0 -0
  250. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/delete_section/stream_delete_section.jinja.html +0 -0
  251. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_document_config/stream_cancel_edit_document_config.jinja.html +0 -0
  252. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_document_config/stream_edit_document_config.jinja.html +0 -0
  253. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_document_config/stream_save_document_config.jinja.html +0 -0
  254. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_document_grammar/stream_add_grammar_field.jinja.html +0 -0
  255. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_document_grammar/stream_edit_document_grammar.jinja.html +0 -0
  256. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_document_grammar/stream_save_document_grammar.jinja.html +0 -0
  257. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_requirement/stream_edit_requirement.jinja.html +0 -0
  258. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_requirement/stream_update_requirement.jinja.html +0 -0
  259. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_section/stream_edit_section.jinja.html +0 -0
  260. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/edit_section/stream_updated_section.jinja.html +0 -0
  261. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/document/move_node/stream_update_document_content.jinja +0 -0
  262. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/project_index/import_reqif_document/stream_form_import_reqif_document.jinja.html +0 -0
  263. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/project_index/import_reqif_document/stream_refresh_with_imported_reqif_document.jinja.html +0 -0
  264. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/project_index/stream_create_document.jinja.html +0 -0
  265. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/actions/project_index/stream_new_document.jinja.html +0 -0
  266. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/base.jinja.html +0 -0
  267. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/abstract/index.jinja +0 -0
  268. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/anchor/index.jinja +0 -0
  269. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/button/cancel.jinja +0 -0
  270. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/button/confirm.jinja +0 -0
  271. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/button/delete.jinja +0 -0
  272. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/button/submit.jinja +0 -0
  273. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/confirm/_usage_example.jinja +0 -0
  274. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/confirm/index.jinja +0 -0
  275. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/form/field/file/index.jinja +0 -0
  276. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/form/field/text/index.jinja +0 -0
  277. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/header/_usage_example.jinja +0 -0
  278. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/header/header_pagetype.jinja +0 -0
  279. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/header/index.jinja +0 -0
  280. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/modal/_usage_example.jinja +0 -0
  281. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/modal/form.jinja +0 -0
  282. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/modal/index.jinja +0 -0
  283. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/node/card.jinja +0 -0
  284. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/node/index.jinja +0 -0
  285. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/node/node_controls/index.jinja +0 -0
  286. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/node/root.jinja +0 -0
  287. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/card.jinja +0 -0
  288. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/card_extends_card.jinja +0 -0
  289. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/comments/index.jinja +0 -0
  290. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/files/index.jinja +0 -0
  291. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/index.jinja +0 -0
  292. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/index_extends_node.jinja +0 -0
  293. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/links/index.jinja +0 -0
  294. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/meta/index.jinja +0 -0
  295. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/rationale/index.jinja +0 -0
  296. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/statement/index.jinja +0 -0
  297. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/tiny.jinja +0 -0
  298. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/tiny_extends_card.jinja +0 -0
  299. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/title/index.jinja +0 -0
  300. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/requirement/uid/index.jinja +0 -0
  301. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/resizable_bar/index.jinja +0 -0
  302. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/card.jinja +0 -0
  303. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/card_extends_card.jinja +0 -0
  304. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/h/index.jinja +0 -0
  305. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/index.jinja +0 -0
  306. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/index_extends_node.jinja +0 -0
  307. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/text/index.jinja +0 -0
  308. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/tiny.jinja +0 -0
  309. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/tiny_extends_card.jinja +0 -0
  310. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/components/section/title/index.jinja +0 -0
  311. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/_shared/frame_header_document_title.jinja +0 -0
  312. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/_shared/project_tree.jinja +0 -0
  313. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/_shared/resizable_bar_with_project_tree.jinja +0 -0
  314. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/_shared/resizable_bar_with_toc.jinja +0 -0
  315. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/_shared/viewtype_menu.jinja +0 -0
  316. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/actions.jinja +0 -0
  317. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_document_config.jinja.html +0 -0
  318. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_document_config_edit.jinja.html +0 -0
  319. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_document_content.jinja.html +0 -0
  320. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_document_grammar_edit.jinja.html +0 -0
  321. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_document_grammar_edit_custom_field.jinja.html +0 -0
  322. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_requirement_edit.jinja +0 -0
  323. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_requirement_edit_field_comment.jinja +0 -0
  324. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_requirement_edit_field_parent_link.jinja +0 -0
  325. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/frame_section_edit.jinja +0 -0
  326. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/index.jinja +0 -0
  327. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/document/main.jinja +0 -0
  328. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/table/index.jinja +0 -0
  329. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/table/main.jinja +0 -0
  330. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/traceability/index.jinja +0 -0
  331. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/traceability/main.jinja +0 -0
  332. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/traceability_deep/frame_show_full_requirement.jinja +0 -0
  333. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/traceability_deep/index.jinja +0 -0
  334. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/document/traceability_deep/main.jinja +0 -0
  335. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/project_index/actions.jinja +0 -0
  336. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/project_index/frame_form_import_reqif.jinja.html +0 -0
  337. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/project_index/frame_form_new_document.jinja.html +0 -0
  338. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/project_index/frame_project_tree.jinja.html +0 -0
  339. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/project_index/index.jinja +0 -0
  340. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/project_index/main.jinja +0 -0
  341. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/requirements_coverage/index.jinja +0 -0
  342. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/requirements_coverage/main.jinja +0 -0
  343. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/requirements_coverage/project_tree_flat_anchor_list.jinja +0 -0
  344. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/requirements_coverage/requirement.jinja.html +0 -0
  345. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/requirements_coverage/resizable_bar_with_project_tree.jinja +0 -0
  346. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/source_file_coverage/index.jinja +0 -0
  347. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/source_file_coverage/main.jinja +0 -0
  348. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/source_file_view/aside.jinja +0 -0
  349. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/source_file_view/header__source_file_name.jinja +0 -0
  350. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/source_file_view/index.jinja +0 -0
  351. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/source_file_view/main.jinja +0 -0
  352. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/screens/source_file_view/requirement.jinja +0 -0
  353. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/templates/websocket.jinja.html +0 -0
  354. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/tools/__init__.py +0 -0
  355. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/html/tools/html_embedded.py +0 -0
  356. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/rst/__init__.py +0 -0
  357. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/rst/directives/raw_html_role.py +0 -0
  358. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/rst/directives/wildcard_enhanced_image.py +0 -0
  359. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/rst/document_rst_generator.py +0 -0
  360. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/rst/rst_templates.py +0 -0
  361. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/rst/templates/requirement.jinja.rst +0 -0
  362. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/export/rst/writer.py +0 -0
  363. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/__init__.py +0 -0
  364. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/auto_described.py +0 -0
  365. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/cast.py +0 -0
  366. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/exception.py +0 -0
  367. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/file_modification_time.py +0 -0
  368. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/file_system.py +0 -0
  369. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/math.py +0 -0
  370. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/parallelizer.py +0 -0
  371. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/path_filter.py +0 -0
  372. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/pickle.py +0 -0
  373. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/rst.py +0 -0
  374. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/sorting.py +0 -0
  375. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/string.py +0 -0
  376. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/textx.py +0 -0
  377. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/timing.py +0 -0
  378. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/helpers/uuid.py +0 -0
  379. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/server/__init__.py +0 -0
  380. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/server/app.py +0 -0
  381. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/server/config.py +0 -0
  382. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/server/error_object.py +0 -0
  383. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/server/main.py +0 -0
  384. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/server/routers/main_router.py +0 -0
  385. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc/server/server.py +0 -0
  386. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/strictdoc.toml +0 -0
  387. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/tasks.py +0 -0
  388. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/tasks_wine.py +0 -0
  389. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/tools/confluence_html_table_import.py +0 -0
  390. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/tools/link_health.py +0 -0
  391. {strictdoc-0.0.43a3 → strictdoc-0.0.43a4}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strictdoc
3
- Version: 0.0.43a3
3
+ Version: 0.0.43a4
4
4
  Summary: StrictDoc is open-source software for technical documentation and requirements management.
5
5
  Project-URL: Changelog, https://github.com/strictdoc-project/strictdoc/blob/main/CHANGELOG.md
6
6
  Project-URL: Homepage, https://strictdoc.readthedocs.io/en/stable/
@@ -1,6 +1,6 @@
1
1
  from strictdoc.core.environment import SDocRuntimeEnvironment
2
2
 
3
- __version__ = "0.0.43a3"
3
+ __version__ = "0.0.43a4"
4
4
 
5
5
 
6
6
  environment = SDocRuntimeEnvironment(__file__)
@@ -1,3 +1,5 @@
1
+ from textx import TextXSyntaxError
2
+
1
3
  from strictdoc.backend.sdoc.models.document_grammar import (
2
4
  DocumentGrammar,
3
5
  GrammarElementField,
@@ -9,6 +11,10 @@ from strictdoc.backend.sdoc.models.requirement import (
9
11
  )
10
12
 
11
13
 
14
+ def get_textx_syntax_error_message(exception: TextXSyntaxError):
15
+ return f"SDoc markup error: {exception.context}."
16
+
17
+
12
18
  class StrictDocSemanticError(Exception):
13
19
  def __init__( # pylint: disable=too-many-arguments
14
20
  self, title, hint, example, line=None, col=None, filename=None
@@ -1,6 +1,6 @@
1
1
  TEXT_TYPES_GRAMMAR = r"""
2
2
  TextPart[noskipws]:
3
- (InlineLink | Anchor | NormalString)
3
+ (Anchor | InlineLink | NormalString)
4
4
  ;
5
5
 
6
6
  NormalString[noskipws]:
@@ -17,10 +17,31 @@ InlineLink[noskipws]:
17
17
  InlineLinkStart value = /[^\]]*/ ']'
18
18
  ;
19
19
 
20
- AnchorStart: '[ANCHOR: ';
20
+ AnchorStart[noskipws]:
21
+ // Make sure that an anchor cannot follow right after a text string.
22
+ /(?<!\S\n)^/ '[ANCHOR: '
23
+ ;
21
24
 
22
25
  Anchor[noskipws]:
23
26
  AnchorStart value = /[^\],]*/ (', ' title = /\w+[\s\w+]*/)? ']'
27
+ // We expect either:
28
+ // - An anchor has a newline character after it, if this anchor is the last
29
+ // part in the free text.
30
+ // - An anchor has two newline symbols, if this anchor is not the last part in
31
+ // the free text.
32
+ // Furthermore, there are two cases of parsing free text with ANCHORs:
33
+ // 1) The full [FREETEXT] blocks inside SDoc files.
34
+ // 2) The inner free text blocks when only a single section is edited in UI.
35
+ // The resulting regex magic has three cases:
36
+ // 1) The ANCHOR has two newlines after it and something else follows it.
37
+ // 2) The ANCHOR has one newline and nothing else after it in an inner free
38
+ // text block (\Z). A variation of this case is when there is no newline,
39
+ // but only the end of the string (\Z).
40
+ // 3) The ANCHOR has one newline and then immediately the [/FREETEXT] ending
41
+ // block follows. (positive lookahead towards closing [/FREETEXT])
42
+ // '\\n' /(\\n|\Z)/
43
+ /\Z|(\n(\n|\Z|(?=\[\/FREETEXT\])))/
44
+
24
45
  ;
25
46
 
26
47
  FreeTextEnd: /^/ '[/FREETEXT]' '\n';
@@ -5,7 +5,7 @@ FieldName[noskipws]:
5
5
 
6
6
  // According to the Strict Grammar Rule #3, both SingleLineString and
7
7
  // MultiLineString can never be empty strings.
8
- // Both must start with a non-space character.
8
+ // Both must eventualy start with a non-space character.
9
9
  SingleLineString:
10
10
  (!MultiLineStringStart /\S/) (!MultiLineStringStart /./)* /$/
11
11
  ;
@@ -20,7 +20,7 @@ MultiLineStringEnd[noskipws]:
20
20
 
21
21
  MultiLineString[noskipws]:
22
22
  MultiLineStringStart-
23
- (!MultiLineStringEnd /\S/) (!MultiLineStringEnd /(?ms)./)+
23
+ (!MultiLineStringEnd /\W*\S/) (!MultiLineStringEnd /(?ms)./)+
24
24
  MultiLineStringEnd-
25
25
  ;
26
26
 
@@ -318,7 +318,8 @@ class SDWriter:
318
318
  def print_free_text_content(free_text):
319
319
  assert isinstance(free_text, FreeText)
320
320
  output = ""
321
- for part in free_text.parts:
321
+
322
+ for part_idx, part in enumerate(free_text.parts):
322
323
  if isinstance(part, str):
323
324
  output += part
324
325
  elif isinstance(part, InlineLink):
@@ -332,6 +333,9 @@ class SDWriter:
332
333
  output += ", "
333
334
  output += part.title
334
335
  output += "]"
336
+ output += "\n"
337
+ if part_idx != (len(free_text.parts) - 1):
338
+ output += "\n"
335
339
  else:
336
340
  raise NotImplementedError(part)
337
341
  return output
@@ -1,7 +1,10 @@
1
1
  from collections import defaultdict
2
2
  from typing import Dict, List, Optional, Union
3
3
 
4
+ from textx import TextXSyntaxError
5
+
4
6
  from strictdoc.backend.sdoc.document_reference import DocumentReference
7
+ from strictdoc.backend.sdoc.error_handling import get_textx_syntax_error_message
5
8
  from strictdoc.backend.sdoc.free_text_reader import SDFreeTextReader
6
9
  from strictdoc.backend.sdoc.models.anchor import Anchor
7
10
  from strictdoc.backend.sdoc.models.document import Document
@@ -58,30 +61,38 @@ class UpdateSectionCommand:
58
61
  ) = RstToHtmlFragmentWriter(
59
62
  context_document=section.document
60
63
  ).write_with_validation(form_object.section_statement_unescaped)
64
+
61
65
  if parsed_html is None:
62
66
  errors["section_statement"].append(rst_error)
63
67
  else:
64
- free_text_container = SDFreeTextReader.read(
65
- form_object.section_statement_unescaped
66
- )
67
- anchors: List[Anchor] = []
68
- for part in free_text_container.parts:
69
- if isinstance(part, InlineLink):
70
- # FIXME: Add validations.
71
- pass
72
- elif isinstance(part, Anchor):
73
- anchors.append(part)
74
- else:
75
- pass
76
- if anchors is not None:
77
- try:
78
- traceability_index.validate_node_against_anchors(
79
- node=section, new_anchors=anchors
80
- )
81
- except SingleValidationError as anchors_validation_error:
82
- errors["section_statement"].append(
83
- anchors_validation_error.args[0]
84
- )
68
+ try:
69
+ free_text_container = SDFreeTextReader.read(
70
+ form_object.section_statement_unescaped
71
+ )
72
+ anchors: List[Anchor] = []
73
+ for part in free_text_container.parts:
74
+ if isinstance(part, InlineLink):
75
+ # FIXME: Add validations.
76
+ pass
77
+ elif isinstance(part, Anchor):
78
+ anchors.append(part)
79
+ else:
80
+ pass
81
+ if anchors is not None:
82
+ try:
83
+ traceability_index.validate_node_against_anchors(
84
+ node=section, new_anchors=anchors
85
+ )
86
+ except (
87
+ SingleValidationError
88
+ ) as anchors_validation_error:
89
+ errors["section_statement"].append(
90
+ anchors_validation_error.args[0]
91
+ )
92
+ except TextXSyntaxError as exception:
93
+ errors["section_statement"].append(
94
+ get_textx_syntax_error_message(exception)
95
+ )
85
96
  else:
86
97
  # If there is no free text, we need to check the anchors that may
87
98
  # have been in the existing free text.
@@ -93,6 +104,7 @@ class UpdateSectionCommand:
93
104
  errors["section_statement"].append(
94
105
  anchors_validation_error.args[0]
95
106
  )
107
+
96
108
  if len(errors) > 0:
97
109
  raise validation_error
98
110
 
@@ -204,28 +216,34 @@ class CreateSectionCommand:
204
216
  if parsed_html is None:
205
217
  errors["section_statement"].append(rst_error)
206
218
  else:
207
- free_text_container = SDFreeTextReader.read(
208
- form_object.section_statement_unescaped
209
- )
210
- anchors: List[Anchor] = []
211
- for part in free_text_container.parts:
212
- if isinstance(part, InlineLink):
213
- # FIXME: Add validations.
214
- pass
215
- elif isinstance(part, Anchor):
216
- anchors.append(part)
217
- else:
218
- pass
219
- if anchors is not None:
220
- try:
221
- traceability_index.validate_node_against_anchors(
222
- node=None, new_anchors=anchors
223
- )
224
- except SingleValidationError as anchors_validation_error:
225
- errors["section_statement"].append(
226
- anchors_validation_error.args[0]
227
- )
228
-
219
+ try:
220
+ free_text_container = SDFreeTextReader.read(
221
+ form_object.section_statement_unescaped
222
+ )
223
+ anchors: List[Anchor] = []
224
+ for part in free_text_container.parts:
225
+ if isinstance(part, InlineLink):
226
+ # FIXME: Add validations.
227
+ pass
228
+ elif isinstance(part, Anchor):
229
+ anchors.append(part)
230
+ else:
231
+ pass
232
+ if anchors is not None:
233
+ try:
234
+ traceability_index.validate_node_against_anchors(
235
+ node=None, new_anchors=anchors
236
+ )
237
+ except (
238
+ SingleValidationError
239
+ ) as anchors_validation_error:
240
+ errors["section_statement"].append(
241
+ anchors_validation_error.args[0]
242
+ )
243
+ except TextXSyntaxError as exception:
244
+ errors["section_statement"].append(
245
+ get_textx_syntax_error_message(exception)
246
+ )
229
247
  if len(errors) > 0:
230
248
  raise validation_error
231
249
 
@@ -1,6 +1,9 @@
1
1
  from collections import defaultdict
2
2
  from typing import Dict, List, Optional
3
3
 
4
+ from textx import TextXSyntaxError
5
+
6
+ from strictdoc.backend.sdoc.error_handling import get_textx_syntax_error_message
4
7
  from strictdoc.backend.sdoc.free_text_reader import SDFreeTextReader
5
8
  from strictdoc.backend.sdoc.models.anchor import Anchor
6
9
  from strictdoc.backend.sdoc.models.document import Document
@@ -127,27 +130,34 @@ class UpdateDocumentConfigCommand:
127
130
  if parsed_html is None:
128
131
  errors["FREETEXT"].append(rst_error)
129
132
  else:
130
- free_text_container = SDFreeTextReader.read(
131
- form_object.document_freetext_unescaped
132
- )
133
- anchors: List[Anchor] = []
134
- for part in free_text_container.parts:
135
- if isinstance(part, InlineLink):
136
- # FIXME: Add validations.
137
- pass
138
- elif isinstance(part, Anchor):
139
- anchors.append(part)
140
- else:
141
- pass
142
- if anchors is not None:
143
- try:
144
- traceability_index.validate_node_against_anchors(
145
- node=document, new_anchors=anchors
146
- )
147
- except SingleValidationError as anchors_validation_error:
148
- errors["FREETEXT"].append(
149
- anchors_validation_error.args[0]
150
- )
133
+ try:
134
+ free_text_container = SDFreeTextReader.read(
135
+ form_object.document_freetext_unescaped
136
+ )
137
+ anchors: List[Anchor] = []
138
+ for part in free_text_container.parts:
139
+ if isinstance(part, InlineLink):
140
+ # FIXME: Add validations.
141
+ pass
142
+ elif isinstance(part, Anchor):
143
+ anchors.append(part)
144
+ else:
145
+ pass
146
+ if anchors is not None:
147
+ try:
148
+ traceability_index.validate_node_against_anchors(
149
+ node=document, new_anchors=anchors
150
+ )
151
+ except (
152
+ SingleValidationError
153
+ ) as anchors_validation_error:
154
+ errors["FREETEXT"].append(
155
+ anchors_validation_error.args[0]
156
+ )
157
+ except TextXSyntaxError as exception:
158
+ errors["FREETEXT"].append(
159
+ get_textx_syntax_error_message(exception)
160
+ )
151
161
  else:
152
162
  # If there is no free text, we need to check the anchors that may
153
163
  # have been in the existing free text.
@@ -0,0 +1,301 @@
1
+ import os
2
+ import random
3
+ from collections import defaultdict
4
+ from pathlib import Path
5
+ from typing import List, Optional, Union
6
+
7
+ import graphviz
8
+
9
+ from strictdoc.backend.sdoc.models.document import Document
10
+ from strictdoc.backend.sdoc.models.requirement import Requirement
11
+ from strictdoc.backend.sdoc.models.section import Section
12
+ from strictdoc.core.document_iterator import DocumentCachingIterator
13
+ from strictdoc.core.traceability_index import TraceabilityIndex
14
+ from strictdoc.export.dot.dot_templates import DotTemplates
15
+
16
+
17
+ def get_path_components(folder_path):
18
+ path = os.path.normpath(folder_path)
19
+ return path.split(os.sep)
20
+
21
+
22
+ class DocumentDotGenerator:
23
+ def __init__(self, profile: str):
24
+ assert profile in ("profile1", "profile2"), profile
25
+ self.profile: str = profile
26
+ self.index_template = DotTemplates.jinja_environment.get_template(
27
+ f"{profile}/top_level.dot"
28
+ )
29
+ self.template_folder = DotTemplates.jinja_environment.get_template(
30
+ f"{profile}/folder.dot"
31
+ )
32
+ self.template_document = DotTemplates.jinja_environment.get_template(
33
+ f"{profile}/document.dot"
34
+ )
35
+ self.template_section = DotTemplates.jinja_environment.get_template(
36
+ f"{profile}/section.dot"
37
+ )
38
+ self.template_requirement = DotTemplates.jinja_environment.get_template(
39
+ f"{profile}/requirement.dot"
40
+ )
41
+
42
+ def export_tree(
43
+ self, traceability_index: TraceabilityIndex, output_dot_root
44
+ ):
45
+ Path(output_dot_root).mkdir(parents=True, exist_ok=True)
46
+
47
+ project_tree_content = ""
48
+
49
+ documents_by_folder = defaultdict(list)
50
+ for document in traceability_index.document_tree.document_list:
51
+ if not document.has_any_requirements():
52
+ continue
53
+ documents_by_folder[
54
+ document.meta.output_document_dir_rel_path
55
+ ].append(document)
56
+
57
+ accumulated_links = []
58
+ accumulated_section_siblings = []
59
+ document_flat_requirements = []
60
+ document: Document
61
+ for document_folder_idx, document_folder in enumerate(
62
+ documents_by_folder.keys()
63
+ ):
64
+ folder_documents = documents_by_folder[document_folder]
65
+ document_content = self._print_folder_documents(
66
+ document_folder,
67
+ document_folder_idx,
68
+ folder_documents,
69
+ accumulated_links,
70
+ accumulated_section_siblings,
71
+ document_flat_requirements,
72
+ )
73
+ project_tree_content += document_content
74
+ project_tree_content += "\n\n"
75
+
76
+ folders_idx = range(len(documents_by_folder))
77
+ folder_cluster_ids = list(
78
+ map(lambda f: f'"cluster_folder_anchor_{f}"', folders_idx)
79
+ )
80
+ folders_link_string = " -> ".join(folder_cluster_ids)
81
+
82
+ def random_color():
83
+ # https://graphviz.org/doc/info/colors.html
84
+ return random.choice(
85
+ [
86
+ "red",
87
+ "forestgreen",
88
+ "green",
89
+ "blue",
90
+ "gray10",
91
+ "turquoise",
92
+ "sienna",
93
+ "indigo",
94
+ "lightseagreen",
95
+ "olive",
96
+ "teal",
97
+ "webpurple",
98
+ "webmaroon",
99
+ "slateblue1",
100
+ ]
101
+ )
102
+
103
+ dot_output = self.index_template.render(
104
+ project_tree_content=project_tree_content,
105
+ accumulated_links=accumulated_links,
106
+ accumulated_section_siblings=accumulated_section_siblings,
107
+ document_flat_requirements=document_flat_requirements,
108
+ random_color=random_color,
109
+ folders_link_string=folders_link_string,
110
+ )
111
+
112
+ output_path = os.path.join(
113
+ output_dot_root, f"output.{self.profile}.dot"
114
+ )
115
+ with open(output_path, "w", encoding="utf8") as file:
116
+ file.write(dot_output)
117
+
118
+ dot = graphviz.Source.from_file(output_path)
119
+ # view=True makes the output PDF be opened in a default viewer program.
120
+ dot.render(output_path, view=False)
121
+
122
+ def _print_folder_documents(
123
+ self,
124
+ folder_name,
125
+ folder_idx,
126
+ folder_documents: List[Document],
127
+ accumulated_links,
128
+ accumulated_section_siblings,
129
+ document_flat_requirements,
130
+ ):
131
+ def get_bottom_most_section(document: Document) -> Optional[Section]:
132
+ current_node: Union[Document, Section] = document
133
+ candidate_section: Optional[Section] = None
134
+ while len(current_node.section_contents) > 0:
135
+ for subnode in reversed(current_node.section_contents):
136
+ if isinstance(subnode, Section):
137
+ candidate_section = subnode
138
+ current_node = subnode
139
+ break
140
+ else:
141
+ break
142
+ return candidate_section
143
+
144
+ folder_documents_content = ""
145
+ for document_idx, document in enumerate(folder_documents):
146
+ assert document.has_any_requirements()
147
+
148
+ document_content = self._print_document(
149
+ document,
150
+ folder_idx,
151
+ document_idx,
152
+ accumulated_links,
153
+ accumulated_section_siblings,
154
+ document_flat_requirements,
155
+ )
156
+ folder_documents_content += document_content
157
+ folder_documents_content += "\n\n"
158
+
159
+ if document_idx > 0:
160
+ prev_document = folder_documents[document_idx - 1]
161
+ prev_document_last_section = get_bottom_most_section(
162
+ prev_document
163
+ )
164
+ if prev_document_last_section is None:
165
+ continue
166
+
167
+ lhs_node_id = document.section_contents[0].node_id
168
+ if not isinstance(document.section_contents[0], Section):
169
+ lhs_node_id = document.node_id
170
+
171
+ rhs_node_id = prev_document_last_section.node_id
172
+
173
+ accumulated_section_siblings.append((lhs_node_id, rhs_node_id))
174
+
175
+ dot_output = self.template_folder.render(
176
+ folder_name=folder_name,
177
+ folder_idx=folder_idx,
178
+ folder_documents_content=folder_documents_content,
179
+ )
180
+ return dot_output
181
+
182
+ def _print_document(
183
+ self,
184
+ document: Document,
185
+ folder_idx,
186
+ document_idx,
187
+ accumulated_links,
188
+ accumulated_section_siblings,
189
+ document_flat_requirements,
190
+ ) -> str:
191
+ document_content = self._print_node(
192
+ document, accumulated_links, accumulated_section_siblings
193
+ )
194
+
195
+ this_document_flat_requirements = []
196
+
197
+ iterator = DocumentCachingIterator(document)
198
+ for node in iterator.all_content():
199
+ if isinstance(node, Requirement):
200
+ uuid = self.get_requirement_uuid(node)
201
+
202
+ this_document_flat_requirements.append(f'"value_{uuid}"')
203
+
204
+ this_document_flat_requirements_str = (
205
+ " -> ".join(this_document_flat_requirements)
206
+ if len(this_document_flat_requirements) > 1
207
+ else None
208
+ )
209
+ document_flat_requirements.append(this_document_flat_requirements_str)
210
+
211
+ return self.template_document.render(
212
+ document=document,
213
+ document_idx=document_idx,
214
+ folder_idx=folder_idx,
215
+ document_content=document_content,
216
+ )
217
+
218
+ def _print_node(
219
+ self,
220
+ node: Union[Document, Section],
221
+ accumulated_links,
222
+ accumulated_section_siblings,
223
+ ) -> str:
224
+ def get_uuid(node_):
225
+ return node_.node_id
226
+
227
+ def get_upper_sibling_section(node_: Section):
228
+ parent: Union[Document, Section] = node_.parent
229
+ node_index = parent.section_contents.index(node_)
230
+ if node_index > 0:
231
+ candidate_upper_sibling = parent.section_contents[
232
+ node_index - 1
233
+ ]
234
+ if isinstance(candidate_upper_sibling, Section):
235
+ return candidate_upper_sibling
236
+ return None
237
+
238
+ node_content = ""
239
+ for subnode in node.section_contents:
240
+ if isinstance(subnode, Section):
241
+ node_content += self._print_node(
242
+ subnode, accumulated_links, accumulated_section_siblings
243
+ )
244
+ node_content += "\n"
245
+
246
+ upper_sibling_section = get_upper_sibling_section(subnode)
247
+ if upper_sibling_section is not None:
248
+ accumulated_section_siblings.append(
249
+ (get_uuid(subnode), get_uuid(upper_sibling_section))
250
+ )
251
+ elif isinstance(subnode, Requirement):
252
+ node_content += self._print_requirement_fields(
253
+ subnode, accumulated_links
254
+ )
255
+ node_content += "\n"
256
+ output = self.template_section.render(
257
+ section=node,
258
+ uuid=get_uuid(node),
259
+ node_content=node_content,
260
+ font_size=32 - node.ng_level * 4,
261
+ context_title=f"{node.context.title_number_string} {node.title}"
262
+ if isinstance(node, Section)
263
+ else node.title,
264
+ )
265
+ return output
266
+
267
+ def _print_requirement_fields(
268
+ self, requirement: Requirement, accumulated_links
269
+ ):
270
+ def get_color_from_status(requirement_: Requirement):
271
+ if requirement_.reserved_status is None:
272
+ return "#87CEEB", "filled,rounded,dashed", "box", "\\l"
273
+ if requirement_.reserved_status == "Draft":
274
+ return "gray", "filled", "diamond", ""
275
+ if requirement_.reserved_status == "Backlog":
276
+ return "lightgray", "filled,rounded,dashed", "box", "\\l"
277
+ if requirement_.reserved_status == "Progress":
278
+ return "yellow", "filled,rounded,solid", "box", "\\l"
279
+ if requirement_.reserved_status in ("Active", "Implemented"):
280
+ return "white", "filled,rounded,solid", "box", "\\l"
281
+ raise NotImplementedError(requirement.reserved_status)
282
+
283
+ uuid = self.get_requirement_uuid(requirement)
284
+ for parent_uid in requirement.get_parent_requirement_reference_uids():
285
+ accumulated_links.append((uuid, parent_uid))
286
+
287
+ output = self.template_requirement.render(
288
+ requirement=requirement,
289
+ uuid=uuid,
290
+ requirement_color=get_color_from_status(requirement),
291
+ )
292
+ return output
293
+
294
+ @staticmethod
295
+ def get_requirement_uuid(requirement: Requirement):
296
+ assert isinstance(requirement, Requirement)
297
+ return (
298
+ requirement.reserved_uid
299
+ if requirement.reserved_uid is not None
300
+ else requirement.node_id
301
+ )
@@ -0,0 +1,12 @@
1
+ subgraph "cluster_{{folder_idx}}_document_{{document_idx}}" {
2
+ label = "";
3
+ penwidth=0;
4
+
5
+ // This is currently only used to orient: Legend -> First Document.
6
+ "anchor_cluster_{{folder_idx}}_document_{{document_idx}}" [shape="point", width=1, height=1, fillcolor=red, style=invis];
7
+
8
+ {% filter indent(width=2) %}
9
+ {{document_content}}
10
+ {% endfilter %}
11
+
12
+ }
@@ -0,0 +1,15 @@
1
+ subgraph "cluster_folder_{{folder_idx}}" {
2
+ label = "{{folder_name}}";
3
+ fontsize = 32;
4
+ fontname="Arial-bold";
5
+ penwidth=1;
6
+ style="rounded";
7
+
8
+ "cluster_folder_anchor_{{folder_idx}}" [shape="point", width=1, height=1, style="invis"];
9
+
10
+ {% filter indent(width=2) %}
11
+ {{folder_documents_content}}
12
+ {% endfilter %}
13
+
14
+ }
15
+