python-hwpx 6.6.0__tar.gz → 6.8.0__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 (461) hide show
  1. {python_hwpx-6.6.0/src/python_hwpx.egg-info → python_hwpx-6.8.0}/PKG-INFO +7 -22
  2. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/README.md +6 -21
  3. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/pyproject.toml +7 -1
  4. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/__init__.py +95 -34
  5. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/_legacy.py +2 -2
  6. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/fields.py +288 -24
  7. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/layout.py +64 -8
  8. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/media.py +38 -45
  9. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/memos.py +32 -12
  10. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/fields.py +39 -3
  11. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/media.py +16 -2
  12. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/notes.py +2 -2
  13. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/parts.py +31 -0
  14. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/shapes.py +96 -9
  15. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/styles.py +23 -5
  16. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/persistence.py +22 -69
  17. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/shapes.py +96 -7
  18. python_hwpx-6.8.0/src/hwpx/_moved_modules.py +118 -0
  19. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/data/contract_docs/known-traps.md +25 -1
  20. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/data/contract_docs/mutation-semantics.md +7 -4
  21. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/data/contract_docs/support-matrix.md +5 -5
  22. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/document.py +46 -7
  23. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/equation/authoring.py +30 -20
  24. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/equation/eqedit.py +66 -4
  25. python_hwpx-6.8.0/src/hwpx/equation/measure.py +518 -0
  26. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/equation/tokens.py +14 -1
  27. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/errors.py +41 -1
  28. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/experimental.py +8 -0
  29. python_hwpx-6.8.0/src/hwpx/form_fit/_glyph_table.py +3765 -0
  30. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/form_fit/apply.py +7 -1
  31. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/form_fit/engine.py +15 -66
  32. python_hwpx-6.8.0/src/hwpx/form_fit/measure.py +2111 -0
  33. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/form_fit/policy.py +7 -1
  34. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/errors.py +12 -22
  35. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/ingest/hwpx_converter.py +2 -1
  36. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/layout/lint.py +228 -27
  37. python_hwpx-6.8.0/src/hwpx/layout/pages.py +3523 -0
  38. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/objects/__init__.py +2 -1
  39. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/objects/form_field.py +51 -38
  40. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/opc/relationships.py +72 -1
  41. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/_document_primitives.py +19 -24
  42. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/_paragraph_text_edit.py +27 -0
  43. python_hwpx-6.8.0/src/hwpx/oxml/curves.py +231 -0
  44. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/document_parts.py +6 -3
  45. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/drop_cap.py +22 -17
  46. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/dutmal_compose.py +19 -10
  47. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/field_marks.py +38 -7
  48. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/header.py +39 -33
  49. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/header_fonts.py +37 -6
  50. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/header_part.py +21 -25
  51. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/master_page_authoring.py +67 -5
  52. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/memo.py +181 -3
  53. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/note_authoring.py +1 -1
  54. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/numbering_kinds.py +35 -1
  55. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/objects.py +44 -27
  56. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/paragraph.py +20 -13
  57. python_hwpx-6.8.0/src/hwpx/oxml/paragraph_heading.py +70 -0
  58. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/section.py +23 -5
  59. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/section_format.py +25 -6
  60. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/section_story.py +13 -1
  61. python_hwpx-6.8.0/src/hwpx/oxml/shape_position.py +282 -0
  62. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/table.py +36 -28
  63. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/table_sizes.py +126 -11
  64. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/utils.py +18 -1
  65. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/quality/save_pipeline.py +4 -1
  66. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/table_patch.py +32 -8
  67. python_hwpx-6.8.0/src/hwpx/tools/__init__.py +277 -0
  68. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/document_merge.py +4 -1
  69. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/exporter.py +136 -17
  70. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/id_integrity.py +22 -35
  71. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/layout_preview.py +5 -2
  72. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/package_validator.py +334 -24
  73. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/repair.py +38 -2
  74. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/template_analyzer.py +9 -6
  75. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/toc_author.py +8 -6
  76. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/validator.py +53 -0
  77. {python_hwpx-6.6.0 → python_hwpx-6.8.0/src/python_hwpx.egg-info}/PKG-INFO +7 -22
  78. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/python_hwpx.egg-info/SOURCES.txt +28 -0
  79. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_add_control.py +17 -5
  80. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_add_heading.py +74 -8
  81. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_cell_fields.py +47 -0
  82. python_hwpx-6.8.0/tests/test_cell_margins.py +311 -0
  83. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_cell_text_rewrite_semantics.py +10 -11
  84. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_container_authoring.py +60 -29
  85. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_coverage_ledger.py +12 -0
  86. python_hwpx-6.8.0/tests/test_curve_connector_authoring.py +160 -0
  87. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_document_formatting.py +94 -8
  88. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_document_merge.py +4 -1
  89. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_documentation_code_fences.py +23 -2
  90. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_drop_cap_authoring.py +34 -5
  91. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_dutmal_compose_authoring.py +34 -5
  92. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_engine_surface_6_0.py +14 -0
  93. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_equation_authoring.py +47 -2
  94. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_equation_converter.py +65 -0
  95. python_hwpx-6.8.0/tests/test_equation_measure_hancom_saved.py +99 -0
  96. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_equation_render.py +24 -0
  97. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_equation_size.py +14 -2
  98. python_hwpx-6.8.0/tests/test_equation_width_hancom_boxes.py +73 -0
  99. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_existing_document_format_editing.py +31 -0
  100. python_hwpx-6.8.0/tests/test_export_notes.py +202 -0
  101. python_hwpx-6.8.0/tests/test_field_type_ids.py +120 -0
  102. python_hwpx-6.8.0/tests/test_form_fields.py +372 -0
  103. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_form_fit.py +201 -18
  104. python_hwpx-6.8.0/tests/test_form_fit_hancom_rules.py +946 -0
  105. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_gap_closure_tools.py +36 -16
  106. python_hwpx-6.8.0/tests/test_header_control_before_field.py +78 -0
  107. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_hwp5_save.py +58 -5
  108. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_image_object_workflow.py +64 -3
  109. python_hwpx-6.8.0/tests/test_instid_attribute_case.py +126 -0
  110. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_integration_hwpx_compatibility.py +1 -1
  111. python_hwpx-6.8.0/tests/test_layer_leak_guard.py +181 -0
  112. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_layout_cache_scope.py +48 -0
  113. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_layout_lint.py +190 -2
  114. python_hwpx-6.8.0/tests/test_layout_page_estimate.py +1593 -0
  115. python_hwpx-6.8.0/tests/test_lazy_hwp5_import.py +87 -0
  116. python_hwpx-6.8.0/tests/test_lazy_tools_import.py +91 -0
  117. python_hwpx-6.8.0/tests/test_lazy_tools_submodules.py +149 -0
  118. python_hwpx-6.8.0/tests/test_list_continue.py +112 -0
  119. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_master_page_authoring.py +11 -0
  120. python_hwpx-6.8.0/tests/test_master_page_pages_taken.py +181 -0
  121. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_memo_and_style_editing.py +65 -0
  122. python_hwpx-6.8.0/tests/test_memo_fields.py +93 -0
  123. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_merge_cells_keeps_contents.py +4 -3
  124. python_hwpx-6.8.0/tests/test_moved_module_imports.py +105 -0
  125. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_native_edit_contract.py +6 -6
  126. python_hwpx-6.8.0/tests/test_ns_shapes.py +198 -0
  127. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_opc_package.py +7 -7
  128. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_oxml_modularization.py +4 -3
  129. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_package_hygiene.py +93 -2
  130. python_hwpx-6.8.0/tests/test_paragraph_property_lookup.py +51 -0
  131. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_product_boundary.py +9 -1
  132. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_public_artifact_hygiene.py +14 -0
  133. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_recover_broken_zip.py +1 -1
  134. python_hwpx-6.8.0/tests/test_remove_unused_charts.py +104 -0
  135. python_hwpx-6.8.0/tests/test_remove_unused_images.py +84 -0
  136. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_repair_repack.py +4 -4
  137. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_save_pipeline.py +16 -0
  138. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_shape_open_safety_risk_check.py +41 -33
  139. python_hwpx-6.8.0/tests/test_shape_original_size.py +167 -0
  140. python_hwpx-6.8.0/tests/test_size_ratchet.py +102 -0
  141. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_stable_surface.py +3 -2
  142. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_style_font_border_reads.py +78 -2
  143. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_style_resolution.py +53 -0
  144. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_tab_definition_version_switch.py +67 -26
  145. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_patch.py +1 -1
  146. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_template_analyzer_enrichment.py +1 -0
  147. python_hwpx-6.8.0/tests/test_text_box_fields.py +87 -0
  148. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_toc_author.py +9 -1
  149. python_hwpx-6.8.0/tests/test_validator_form_parameters.py +96 -0
  150. python_hwpx-6.8.0/tests/test_validator_hancom_open_rules.py +313 -0
  151. python_hwpx-6.8.0/tests/test_validator_section_ids.py +141 -0
  152. python_hwpx-6.6.0/src/hwpx/equation/measure.py +0 -371
  153. python_hwpx-6.6.0/src/hwpx/form_fit/measure.py +0 -854
  154. python_hwpx-6.6.0/src/hwpx/oxml/shape_position.py +0 -128
  155. python_hwpx-6.6.0/src/hwpx/tools/__init__.py +0 -131
  156. python_hwpx-6.6.0/tests/test_cell_margins.py +0 -168
  157. python_hwpx-6.6.0/tests/test_form_fields.py +0 -101
  158. python_hwpx-6.6.0/tests/test_form_fit_hancom_rules.py +0 -191
  159. python_hwpx-6.6.0/tests/test_instid_attribute_case.py +0 -100
  160. python_hwpx-6.6.0/tests/test_master_page_pages_taken.py +0 -83
  161. python_hwpx-6.6.0/tests/test_ns_shapes.py +0 -79
  162. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/LICENSE +0 -0
  163. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/NOTICE +0 -0
  164. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/setup.cfg +0 -0
  165. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/__init__.py +0 -0
  166. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/_resolve.py +0 -0
  167. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/_units.py +0 -0
  168. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/headings.py +0 -0
  169. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/highlight.py +0 -0
  170. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/__init__.py +0 -0
  171. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/_base.py +0 -0
  172. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/page.py +0 -0
  173. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/refs.py +0 -0
  174. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/tables.py +0 -0
  175. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/text.py +0 -0
  176. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/ns/tracking.py +0 -0
  177. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/_document/tracked.py +0 -0
  178. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/body_patch.py +0 -0
  179. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/capabilities.py +0 -0
  180. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/data/Skeleton.hwpx +0 -0
  181. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/data/contract_docs/recipes-traversal.md +0 -0
  182. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/equation/__init__.py +0 -0
  183. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/equation/mathml.py +0 -0
  184. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/equation/render.py +0 -0
  185. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/form_fit/__init__.py +0 -0
  186. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/form_fit/report.py +0 -0
  187. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/__init__.py +0 -0
  188. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/binary.py +0 -0
  189. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/bodytext.py +0 -0
  190. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/cfb.py +0 -0
  191. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/controls.py +0 -0
  192. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/docinfo.py +0 -0
  193. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/docinfo_writer.py +0 -0
  194. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/fileheader.py +0 -0
  195. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/header_xml.py +0 -0
  196. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/owpml.py +0 -0
  197. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/package.py +0 -0
  198. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/reader.py +0 -0
  199. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/records.py +0 -0
  200. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/section_common.py +0 -0
  201. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/section_writer.py +0 -0
  202. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/section_xml.py +0 -0
  203. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/shape_xml.py +0 -0
  204. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/shapes.py +0 -0
  205. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/summary.py +0 -0
  206. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/hwp5/writer.py +0 -0
  207. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/ingest/__init__.py +0 -0
  208. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/ingest/base.py +0 -0
  209. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/layout/__init__.py +0 -0
  210. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/layout/report.py +0 -0
  211. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/model.py +0 -0
  212. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/mutation_report.py +0 -0
  213. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/objects/binary_item.py +0 -0
  214. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/objects/checkbox.py +0 -0
  215. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/objects/highlight.py +0 -0
  216. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/objects/results.py +0 -0
  217. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/objects/tracked.py +0 -0
  218. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/opc/package.py +0 -0
  219. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/opc/security.py +0 -0
  220. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/opc/xml_utils.py +0 -0
  221. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/__init__.py +0 -0
  222. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/_document_impl.py +0 -0
  223. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/body.py +0 -0
  224. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/canonical_defaults.py +0 -0
  225. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/color.py +0 -0
  226. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/common.py +0 -0
  227. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/document.py +0 -0
  228. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/document_metadata.py +0 -0
  229. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/header_compat.py +0 -0
  230. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/history_part.py +0 -0
  231. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/hyperlink_form.py +0 -0
  232. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/master_page.py +0 -0
  233. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/namespaces.py +0 -0
  234. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/numbering.py +0 -0
  235. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/parser.py +0 -0
  236. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/run.py +0 -0
  237. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/schema.py +0 -0
  238. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/section_layout.py +0 -0
  239. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/settings.py +0 -0
  240. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/simple_parts.py +0 -0
  241. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/table_merge.py +0 -0
  242. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/oxml/version_part.py +0 -0
  243. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/package.py +0 -0
  244. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/patch.py +0 -0
  245. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/plan/__init__.py +0 -0
  246. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/plan/_execute.py +0 -0
  247. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/plan/_model.py +0 -0
  248. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/plan/_schema.py +0 -0
  249. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/plan/_validate.py +0 -0
  250. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/py.typed +0 -0
  251. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/quality/__init__.py +0 -0
  252. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/quality/ledger.py +0 -0
  253. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/quality/policy.py +0 -0
  254. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/quality/rendering.py +0 -0
  255. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/quality/report.py +0 -0
  256. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/templates.py +0 -0
  257. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/_schemas/header.xsd +0 -0
  258. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/_schemas/owpml-body.xsd +0 -0
  259. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/_schemas/owpml-core.xsd +0 -0
  260. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/_schemas/owpml-header.xsd +0 -0
  261. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/_schemas/owpml-paralist.xsd +0 -0
  262. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/_schemas/owpml-xml.xsd +0 -0
  263. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/_schemas/section.xsd +0 -0
  264. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/archive_cli.py +0 -0
  265. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/doc_diff.py +0 -0
  266. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/document_viewer.py +0 -0
  267. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/generic_inventory.py +0 -0
  268. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/idempotence.py +0 -0
  269. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/ir_equality.py +0 -0
  270. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/mail_merge.py +0 -0
  271. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/markdown_export.py +0 -0
  272. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/object_finder.py +0 -0
  273. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/package_reconcile.py +0 -0
  274. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/page_guard.py +0 -0
  275. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/read_fidelity.py +0 -0
  276. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/recover.py +0 -0
  277. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/redline.py +0 -0
  278. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/report_utils.py +0 -0
  279. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/roundtrip_diff.py +0 -0
  280. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/table_cleanup.py +0 -0
  281. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/table_navigation.py +0 -0
  282. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/text_extract_cli.py +0 -0
  283. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/text_extractor.py +0 -0
  284. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/hwpx/tools/toc_fidelity.py +0 -0
  285. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/python_hwpx.egg-info/dependency_links.txt +0 -0
  286. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/python_hwpx.egg-info/entry_points.txt +0 -0
  287. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/python_hwpx.egg-info/requires.txt +0 -0
  288. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/src/python_hwpx.egg-info/top_level.txt +0 -0
  289. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_adoption_metrics_snapshot.py +0 -0
  290. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_arc_authoring.py +0 -0
  291. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_authoring_defaults.py +0 -0
  292. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_authoring_quality_corpus.py +0 -0
  293. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_blind_eval_fixture.py +0 -0
  294. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_body_patch.py +0 -0
  295. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_border_fill_image_gradient.py +0 -0
  296. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_border_line_types.py +0 -0
  297. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_build_element_census.py +0 -0
  298. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_byte_patch_identity.py +0 -0
  299. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_capabilities_surface.py +0 -0
  300. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_cell_border_neighbors.py +0 -0
  301. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_cell_line_spacing.py +0 -0
  302. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_char_pr_child_order.py +0 -0
  303. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_character_width_ratio.py +0 -0
  304. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_chart_authoring.py +0 -0
  305. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_check_box_authoring.py +0 -0
  306. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_color_arguments.py +0 -0
  307. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_column_break.py +0 -0
  308. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_comment_node_robustness.py +0 -0
  309. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_contract_docs_sync.py +0 -0
  310. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_corpus_read_fidelity.py +0 -0
  311. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_coverage_promotion.py +0 -0
  312. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_coverage_targets.py +0 -0
  313. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_deviations_registry.py +0 -0
  314. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_doc_diff.py +0 -0
  315. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_document_context_manager.py +0 -0
  316. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_document_facade_surface.py +0 -0
  317. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_document_metadata.py +0 -0
  318. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_document_ops_runtime_boundary.py +0 -0
  319. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_document_save_api.py +0 -0
  320. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_document_viewer.py +0 -0
  321. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_edit_fidelity_corpus.py +0 -0
  322. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_edit_plan.py +0 -0
  323. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_editor_surface_inventory.py +0 -0
  324. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_equalize_widths_per_row.py +0 -0
  325. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_error_contract.py +0 -0
  326. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_error_messages.py +0 -0
  327. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_evalplan_core_primitives.py +0 -0
  328. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_export_captions_dutmal.py +0 -0
  329. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_export_cell_text_spaces.py +0 -0
  330. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_export_list_labels.py +0 -0
  331. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_export_text_boxes.py +0 -0
  332. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_exporter_table_text.py +0 -0
  333. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_field_marks.py +0 -0
  334. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_fill_image_hancom_modes.py +0 -0
  335. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_form_field_authoring.py +0 -0
  336. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_form_fill_core_primitives.py +0 -0
  337. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_form_fit_integration.py +0 -0
  338. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_fuzz_catalog_derive_expected.py +0 -0
  339. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_fuzz_loop.py +0 -0
  340. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_fuzz_regressions.py +0 -0
  341. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_golden_api.py +0 -0
  342. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_header_compat_authoring.py +0 -0
  343. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_heading_style_shapes.py +0 -0
  344. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_highlight_authoring.py +0 -0
  345. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_hp_tab_support.py +0 -0
  346. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_hwp5_container.py +0 -0
  347. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_hwp5_hancom_files.py +0 -0
  348. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_hwp5_open.py +0 -0
  349. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_hwpxlib_corpus_read.py +0 -0
  350. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_hyperlink_hancom_form.py +0 -0
  351. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_id_generator_range.py +0 -0
  352. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_id_integrity.py +0 -0
  353. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_index_mark.py +0 -0
  354. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_ingest.py +0 -0
  355. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_inline_models.py +0 -0
  356. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_insert_row_merged_cells.py +0 -0
  357. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_integration_roundtrip.py +0 -0
  358. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_internal_calls_skip_moved_names.py +0 -0
  359. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_layout_preview.py +0 -0
  360. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_library_boundary_closure.py +0 -0
  361. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_line_width_arguments.py +0 -0
  362. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_list_defaults_vs_hancom.py +0 -0
  363. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_llms_txt.py +0 -0
  364. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_mail_merge_xlsx.py +0 -0
  365. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_manifest_resolve_once.py +0 -0
  366. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_markdown_export.py +0 -0
  367. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_markdown_export_shape_text.py +0 -0
  368. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_memo_shape_authoring.py +0 -0
  369. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_merge_cells_hancom_files.py +0 -0
  370. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_moved_surface_hints.py +0 -0
  371. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_mutation_report.py +0 -0
  372. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_namespace_handling.py +0 -0
  373. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_namespace_hygiene.py +0 -0
  374. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_namespace_normalization.py +0 -0
  375. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_new_features.py +0 -0
  376. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_note_authoring_contract.py +0 -0
  377. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_ns_fields.py +0 -0
  378. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_ns_media.py +0 -0
  379. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_ns_notes.py +0 -0
  380. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_ns_page.py +0 -0
  381. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_ns_refs.py +0 -0
  382. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_ns_tables.py +0 -0
  383. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_ns_tracking.py +0 -0
  384. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_number_formats.py +0 -0
  385. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_open_safety_corpus.py +0 -0
  386. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_outline_numbering.py +0 -0
  387. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_oxml_parsing.py +0 -0
  388. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_packaging_license_metadata.py +0 -0
  389. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_packaging_py_typed.py +0 -0
  390. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_page_number_control.py +0 -0
  391. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_page_number_format.py +0 -0
  392. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_page_orientation.py +0 -0
  393. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_para_pr_dedup.py +0 -0
  394. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_align_distribute_space.py +0 -0
  395. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_border.py +0 -0
  396. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_format_targets.py +0 -0
  397. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_hyperlink_style.py +0 -0
  398. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_keep_together.py +0 -0
  399. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_margin_default_scale.py +0 -0
  400. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_property_version_switch.py +0 -0
  401. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_remove_in_containers.py +0 -0
  402. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_paragraph_section_management.py +0 -0
  403. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_part_hierarchy_read_models.py +0 -0
  404. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_polygon_authoring.py +0 -0
  405. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_public_runtime_boundary.py +0 -0
  406. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_read_fidelity.py +0 -0
  407. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_redline_authoring.py +0 -0
  408. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_redline_verify.py +0 -0
  409. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_release_workflow_safety.py +0 -0
  410. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_replace_text_barriers.py +0 -0
  411. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_report_utils.py +0 -0
  412. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_repr_snapshots.py +0 -0
  413. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_return_contract.py +0 -0
  414. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_roundtrip_fidelity.py +0 -0
  415. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_roundtrip_fidelity_corpus.py +0 -0
  416. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_row_heights.py +0 -0
  417. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_run_choice_atom_authoring.py +0 -0
  418. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_run_content_kinds.py +0 -0
  419. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_run_font_refs.py +0 -0
  420. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_run_style_base.py +0 -0
  421. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_safe_edit_example.py +0 -0
  422. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_save_keeps_inline_text_caches.py +0 -0
  423. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_save_verifies_once.py +0 -0
  424. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_section_clear_body.py +0 -0
  425. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_section_columns.py +0 -0
  426. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_section_headers.py +0 -0
  427. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_section_ids_order.py +0 -0
  428. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_section_properties_real_roundtrip.py +0 -0
  429. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_set_column_widths_uniform_split.py +0 -0
  430. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_set_paragraph_format_keep.py +0 -0
  431. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_shape_geometry_contract.py +0 -0
  432. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_shape_position_frames.py +0 -0
  433. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_skeleton_template_ids.py +0 -0
  434. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_split_cell.py +0 -0
  435. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_split_merged_cell.py +0 -0
  436. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_stale_layout_cache_sweep.py +0 -0
  437. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_story_edits_reach_control_copy.py +0 -0
  438. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_tab_character_writing.py +0 -0
  439. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_cell_equalize.py +0 -0
  440. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_cleanup.py +0 -0
  441. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_label.py +0 -0
  442. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_navigation.py +0 -0
  443. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_page_flow.py +0 -0
  444. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_patch_dryrun.py +0 -0
  445. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_patch_m105.py +0 -0
  446. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_patch_structure_fixes.py +0 -0
  447. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_table_split_merge.py +0 -0
  448. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_tables_default_border.py +0 -0
  449. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_text_extractor_annotations.py +0 -0
  450. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_text_extractor_nested_once.py +0 -0
  451. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_text_extractor_run_choice_atoms.py +0 -0
  452. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_text_inline_elements.py +0 -0
  453. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_text_replace_everywhere.py +0 -0
  454. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_title_mark.py +0 -0
  455. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_toc_fidelity.py +0 -0
  456. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_tracked_overlap_render_smoke.py +0 -0
  457. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_tracked_paragraph_delete_break.py +0 -0
  458. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_validation_severity.py +0 -0
  459. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_validator_comment_nodes.py +0 -0
  460. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_validator_full_schema.py +0 -0
  461. {python_hwpx-6.6.0 → python_hwpx-6.8.0}/tests/test_version_metadata.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-hwpx
3
- Version: 6.6.0
3
+ Version: 6.8.0
4
4
  Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 문서 라이브러리
5
5
  Author: python-hwpx Maintainers
6
6
  License-Expression: Apache-2.0
@@ -68,7 +68,7 @@ Dynamic: license-file
68
68
 
69
69
  한컴오피스가 없어도 됩니다. HWPX는 ZIP+XML(OWPML) 포맷이라 순수 파이썬만으로
70
70
  읽고, 고치고, 새로 만들 수 있습니다 — Windows·macOS·Linux·CI, 그리고
71
- **파이썬이 도는 ChatGPT 채팅 안에서도** 그대로 동작합니다. 기존 문서의 저장은 요청한 보존 등급과 실제 검증 결과를 영수증으로 남깁니다.
71
+ **파이썬이 도는 ChatGPT 채팅 안에서도** 그대로 동작합니다.
72
72
  새 문서의 한컴 호환성은 아래에 날짜·버전을 명시한 코퍼스로 측정합니다.
73
73
 
74
74
  <p align="center">
@@ -109,7 +109,7 @@ from hwpx import HwpxDocument
109
109
 
110
110
  doc = HwpxDocument.new()
111
111
  doc.add_heading("2026 운영계획", level=1)
112
- doc.add_paragraph("가. 추진 배경", style="개요 2")
112
+ doc.add_paragraph("추진 배경", style="개요 2") # 한/글이 "가." 번호를 붙인다
113
113
  doc.save_to_path("계획.hwpx")
114
114
  ```
115
115
 
@@ -130,7 +130,7 @@ doc.save_to_path("계획.hwpx")
130
130
  - **편집** — 문단·표·이미지·머리글/바닥글·메모·각주, 줄간격·여백·쪽번호 같은 서식
131
131
  - **양식 채우기** — 라벨로 셀을 찾아 값만 채우기, 행·열 조정 같은 구조 편집도 바이트 보존으로
132
132
  - **생성·일괄 처리** — 새 문서 저작, 목차·상호참조, mail merge, 텍스트 diff, 변경추적(redline)
133
- - **검증·안전** — 패키지 구조 검증 CLI, 열림 안전 게이트, 모든 저장에 영수증(`MutationReport`)
133
+ - **검증·안전** — 패키지 구조 검증 CLI, 열림 안전 게이트, 저장 결과 보고(`return_report=True`)
134
134
 
135
135
  자세한 내용: [5분 퀵스타트](docs/quickstart.md) · [사용 가이드](docs/usage.md) · [API 레퍼런스](https://airmang.github.io/python-hwpx/) · [예제](docs/examples.md)
136
136
 
@@ -152,20 +152,6 @@ report = doc.save_to_path("신청서-작성완료.hwpx", mode="patch", fallback=
152
152
  바이트 보존을 요구합니다. 수정 파트 내부의 보존과 시각적 배치는 별도 확인이
153
153
  필요합니다. 출력 재개봉과 내용 확인까지 포함한 경로는 [안전한 쓰기 계약](docs/safe-write-contract.md)을 따르세요.
154
154
 
155
- ### 저장에는 영수증이 따라옵니다
156
-
157
- ```python
158
- report = doc.save_to_path("결과.hwpx", return_report=True)
159
- print(report.actual_mode) # "patch" 또는 "rebuild" — 실제 저장 등급
160
- print(report.preservation.untouched_part_payloads.to_dict())
161
- # {"verified": 17, "changed": 0}
162
- ```
163
-
164
- `mode="patch", fallback="error"`는 보존 등급 미달 시 출력하지 않습니다.
165
- 기본 `auto`는 달성 가능한 등급을 선택합니다. `report.ok`는 요청 반영이나 시각
166
- 검증 완료를 뜻하지 않습니다.
167
- 전체 규칙: [안전한 쓰기 계약](docs/safe-write-contract.md).
168
-
169
155
  *예제 중 **독립 실행 예제** 표시가 없는 블록은 여러분의 기존 문서를 입력으로
170
156
  쓰는 조각입니다. 예제별 Python 블록 판정은
171
157
  [실행 ledger](docs/python-example-ledger.json)에 동결돼 있습니다.*
@@ -175,10 +161,9 @@ print(report.preservation.untouched_part_payloads.to_dict())
175
161
  만든 파일이 실제 한컴오피스에서 열리는지 재서 그대로 공개합니다. 측정마다
176
162
  스택과 날짜를 병기합니다:
177
163
 
178
- - **한컴 열림 120/120 · 렌더 검증 120/120** — 현행 스택(5.7.0 · 실한컴
179
- 12.0.0.3288 · 2026-08-03)의 축소 측정: 기준 스트라텀 + 신규 저작 표면
180
- 6종(각주·누름틀·수식·차트·체크박스·편집 계획). 영수증은 행마다 bucket이
181
- 있어 `jq` 한 줄로 재현됩니다
164
+ - **한컴 열림 120/120 · 렌더 검증 120/120** — 기준 문서군 + 저작 기능
165
+ 6종(각주·누름틀·수식·차트·체크박스·편집 계획) 축소 측정
166
+ (5.7.0 · 실한컴 12.0.0.3288 · 2026-08-03)
182
167
  - **한컴 열림 476/476** — 전수 동결 코퍼스(N=497) 측정
183
168
  (3.4.1 · 실한컴 12.0.0.3288 · 2026-07-19)
184
169
  - **미수정 영역 바이트 보존 497/497** · 개인정보 유출 0
@@ -17,7 +17,7 @@
17
17
 
18
18
  한컴오피스가 없어도 됩니다. HWPX는 ZIP+XML(OWPML) 포맷이라 순수 파이썬만으로
19
19
  읽고, 고치고, 새로 만들 수 있습니다 — Windows·macOS·Linux·CI, 그리고
20
- **파이썬이 도는 ChatGPT 채팅 안에서도** 그대로 동작합니다. 기존 문서의 저장은 요청한 보존 등급과 실제 검증 결과를 영수증으로 남깁니다.
20
+ **파이썬이 도는 ChatGPT 채팅 안에서도** 그대로 동작합니다.
21
21
  새 문서의 한컴 호환성은 아래에 날짜·버전을 명시한 코퍼스로 측정합니다.
22
22
 
23
23
  <p align="center">
@@ -58,7 +58,7 @@ from hwpx import HwpxDocument
58
58
 
59
59
  doc = HwpxDocument.new()
60
60
  doc.add_heading("2026 운영계획", level=1)
61
- doc.add_paragraph("가. 추진 배경", style="개요 2")
61
+ doc.add_paragraph("추진 배경", style="개요 2") # 한/글이 "가." 번호를 붙인다
62
62
  doc.save_to_path("계획.hwpx")
63
63
  ```
64
64
 
@@ -79,7 +79,7 @@ doc.save_to_path("계획.hwpx")
79
79
  - **편집** — 문단·표·이미지·머리글/바닥글·메모·각주, 줄간격·여백·쪽번호 같은 서식
80
80
  - **양식 채우기** — 라벨로 셀을 찾아 값만 채우기, 행·열 조정 같은 구조 편집도 바이트 보존으로
81
81
  - **생성·일괄 처리** — 새 문서 저작, 목차·상호참조, mail merge, 텍스트 diff, 변경추적(redline)
82
- - **검증·안전** — 패키지 구조 검증 CLI, 열림 안전 게이트, 모든 저장에 영수증(`MutationReport`)
82
+ - **검증·안전** — 패키지 구조 검증 CLI, 열림 안전 게이트, 저장 결과 보고(`return_report=True`)
83
83
 
84
84
  자세한 내용: [5분 퀵스타트](docs/quickstart.md) · [사용 가이드](docs/usage.md) · [API 레퍼런스](https://airmang.github.io/python-hwpx/) · [예제](docs/examples.md)
85
85
 
@@ -101,20 +101,6 @@ report = doc.save_to_path("신청서-작성완료.hwpx", mode="patch", fallback=
101
101
  바이트 보존을 요구합니다. 수정 파트 내부의 보존과 시각적 배치는 별도 확인이
102
102
  필요합니다. 출력 재개봉과 내용 확인까지 포함한 경로는 [안전한 쓰기 계약](docs/safe-write-contract.md)을 따르세요.
103
103
 
104
- ### 저장에는 영수증이 따라옵니다
105
-
106
- ```python
107
- report = doc.save_to_path("결과.hwpx", return_report=True)
108
- print(report.actual_mode) # "patch" 또는 "rebuild" — 실제 저장 등급
109
- print(report.preservation.untouched_part_payloads.to_dict())
110
- # {"verified": 17, "changed": 0}
111
- ```
112
-
113
- `mode="patch", fallback="error"`는 보존 등급 미달 시 출력하지 않습니다.
114
- 기본 `auto`는 달성 가능한 등급을 선택합니다. `report.ok`는 요청 반영이나 시각
115
- 검증 완료를 뜻하지 않습니다.
116
- 전체 규칙: [안전한 쓰기 계약](docs/safe-write-contract.md).
117
-
118
104
  *예제 중 **독립 실행 예제** 표시가 없는 블록은 여러분의 기존 문서를 입력으로
119
105
  쓰는 조각입니다. 예제별 Python 블록 판정은
120
106
  [실행 ledger](docs/python-example-ledger.json)에 동결돼 있습니다.*
@@ -124,10 +110,9 @@ print(report.preservation.untouched_part_payloads.to_dict())
124
110
  만든 파일이 실제 한컴오피스에서 열리는지 재서 그대로 공개합니다. 측정마다
125
111
  스택과 날짜를 병기합니다:
126
112
 
127
- - **한컴 열림 120/120 · 렌더 검증 120/120** — 현행 스택(5.7.0 · 실한컴
128
- 12.0.0.3288 · 2026-08-03)의 축소 측정: 기준 스트라텀 + 신규 저작 표면
129
- 6종(각주·누름틀·수식·차트·체크박스·편집 계획). 영수증은 행마다 bucket이
130
- 있어 `jq` 한 줄로 재현됩니다
113
+ - **한컴 열림 120/120 · 렌더 검증 120/120** — 기준 문서군 + 저작 기능
114
+ 6종(각주·누름틀·수식·차트·체크박스·편집 계획) 축소 측정
115
+ (5.7.0 · 실한컴 12.0.0.3288 · 2026-08-03)
131
116
  - **한컴 열림 476/476** — 전수 동결 코퍼스(N=497) 측정
132
117
  (3.4.1 · 실한컴 12.0.0.3288 · 2026-07-19)
133
118
  - **미수정 영역 바이트 보존 497/497** · 개인정보 유출 0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-hwpx"
7
- version = "6.6.0"
7
+ version = "6.8.0"
8
8
  description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 문서 라이브러리"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  license = "Apache-2.0"
@@ -295,6 +295,9 @@ files = [
295
295
  # Table width/height distribution (distribute cell width row by row) moved out
296
296
  # of table.py -- born in the gate, per the WP-A rule.
297
297
  "src/hwpx/oxml/table_sizes.py",
298
+ # A paragraph shape's heading (outline levels 8 to 10 in Hancom's hp:switch form),
299
+ # written and read in one place -- born in the gate, per the WP-A rule.
300
+ "src/hwpx/oxml/paragraph_heading.py",
298
301
  # Floating-shape reference frames (set_position) and shape-text
299
302
  # vertical alignment -- objects.py's overflow module (1600-line cap),
300
303
  # born in the gate, per the WP-A rule.
@@ -501,6 +504,9 @@ include = [
501
504
  # Table width/height distribution (distribute cell width row by row) moved out
502
505
  # of table.py -- born in the gate, per the WP-A rule.
503
506
  "src/hwpx/oxml/table_sizes.py",
507
+ # A paragraph shape's heading (outline levels 8 to 10 in Hancom's hp:switch form),
508
+ # written and read in one place -- born in the gate, per the WP-A rule.
509
+ "src/hwpx/oxml/paragraph_heading.py",
504
510
  # Floating-shape reference frames (set_position) and shape-text
505
511
  # vertical alignment -- objects.py's overflow module (1600-line cap),
506
512
  # born in the gate, per the WP-A rule.
@@ -14,7 +14,7 @@
14
14
  import importlib
15
15
  import warnings
16
16
  from dataclasses import dataclass
17
- from typing import Literal
17
+ from typing import TYPE_CHECKING, Literal
18
18
 
19
19
 
20
20
  def _resolve_version() -> str:
@@ -28,9 +28,9 @@ def _resolve_version() -> str:
28
28
 
29
29
  # --- experimental / deprecated 최상위 표면 (지연 접근, 접근 시 경고) ---------------
30
30
  #
31
- # stable 이름은 아래에서 eager import 되어 모듈 전역에 존재하므로 ``__getattr__``이
32
- # 호출되지 않습니다(=경고 없음). 여기 등록된 이름만 지연 해석되어 경고를 냅니다.
33
- # 4.0.0에서 제거되는 이름은 0개 — 모두 계속 import 가능합니다.
31
+ # stable 이름은 경고 없이 해석됩니다. 대부분 아래에서 eager import 되고, ``hwpx.tools``의
32
+ # 이름은 ``_TOOLS_STABLE_EXPORTS``가 지연 해석합니다. 여기 등록된 이름만 지연 해석되어
33
+ # 경고를 냅니다. 4.0.0에서 제거되는 이름은 0개 — 모두 계속 import 가능합니다.
34
34
 
35
35
  _EXPERIMENTAL_EXPORTS = {
36
36
  # 문서 ingestion 프레임워크(임의 포맷 -> HWPX). 계약 유동.
@@ -45,6 +45,10 @@ _EXPERIMENTAL_EXPORTS = {
45
45
  "LayoutPreview": "hwpx.tools.layout_preview",
46
46
  "PreviewPage": "hwpx.tools.layout_preview",
47
47
  "render_layout_preview": "hwpx.tools.layout_preview",
48
+ # 쪽 수 추정(한/글 없이, 줄마다 쪽·단·세로 위치). 계약 유동.
49
+ "EstimatedLine": "hwpx.layout.pages",
50
+ "PageEstimate": "hwpx.layout.pages",
51
+ "estimate_pages": "hwpx.layout.pages",
48
52
  # 문서 프리뷰 뷰어(3.8.0 신규). 계약 유동.
49
53
  "DocumentViewer": "hwpx.tools.document_viewer",
50
54
  "render_document_viewer": "hwpx.tools.document_viewer",
@@ -289,8 +293,8 @@ class RetiredSurface(ImportError):
289
293
  def __getattr__(name: str) -> object:
290
294
  """Resolve dynamic module attributes.
291
295
 
292
- ``__version__``은 경고 없이 지연 해석하고, experimental/deprecated 이름은
293
- 해석 시 ``DeprecationWarning``을 냅니다.
296
+ ``__version__``과 ``hwpx.tools``의 stable 이름은 경고 없이 지연 해석하고,
297
+ experimental/deprecated 이름은 해석 시 ``DeprecationWarning``을 냅니다.
294
298
  """
295
299
 
296
300
  if name == "__version__":
@@ -314,6 +318,17 @@ def __getattr__(name: str) -> object:
314
318
  warnings.warn(_deprecated_message(name), DeprecationWarning, stacklevel=2)
315
319
  return getattr(importlib.import_module(module_name), name)
316
320
 
321
+ if name in _TOOLS_STABLE_EXPORTS or name == "tools":
322
+ # Not ``from . import tools``: that asks this module for ``tools`` first and
323
+ # re-enters this function.
324
+ import hwpx.tools as tools
325
+
326
+ if name == "tools":
327
+ return tools
328
+ value = getattr(tools, name)
329
+ globals()[name] = value
330
+ return value
331
+
317
332
  moved = _MOVED_TO_COMPANION.get(name)
318
333
  if moved is not None:
319
334
  statement = moved.import_statement(name)
@@ -342,41 +357,87 @@ def __dir__() -> list[str]:
342
357
  return sorted(
343
358
  set(globals())
344
359
  | set(__all__)
360
+ | {"tools"}
345
361
  | set(_EXPERIMENTAL_EXPORTS)
346
362
  | set(_DEPRECATED_EXPORTS)
347
363
  )
348
364
 
349
365
 
350
- # --- stable 최상위 표면 (eager import) ------------------------------------------
351
- from .tools.text_extractor import (
352
- DEFAULT_NAMESPACES,
353
- ParagraphInfo,
354
- SectionInfo,
355
- TextExtractor,
356
- )
357
- from .tools.object_finder import FoundElement, ObjectFinder
358
- from .tools.doc_diff import (
359
- DOC_DIFF_REPORT_VERSION,
360
- REFERENCE_CONSISTENCY_REPORT_VERSION,
361
- diff_paragraphs,
362
- doc_diff,
363
- inspect_reference_consistency,
364
- )
365
- from .tools.mail_merge import (
366
- MAIL_MERGE_REPORT_VERSION,
367
- inspect_mail_merge_placeholders,
368
- load_mail_merge_rows,
369
- merge_template_rows,
370
- )
371
- from .tools.package_validator import (
372
- EditorOpenSafetyReport,
373
- PackageValidationReport,
374
- validate_editor_open_safety,
375
- validate_package,
366
+ # --- 지연 stable 최상위 표면 (첫 접근 때 해석, 경고 없음) ---------------------------
367
+ #
368
+ # ``hwpx.tools``에 사는 stable 이름은 첫 접근 때 ``__getattr__``이 그 모듈을 읽어
369
+ # 같은 객체를 돌려주고 모듈 전역에 둡니다(경고 없음). ``import hwpx``가 도구 모듈
370
+ # 전부(내보내기·비교·검증 등)를 읽지 않게 하려는 것입니다. ``__all__``·``dir()``·
371
+ # ``from hwpx import *``에는 그대로 있습니다.
372
+
373
+ #: ``hwpx.tools``의 하위 모듈이 정의하고 ``hwpx.tools``가 다시 내보내는 stable 이름(텍스트 추출·개체
374
+ #: 찾기·문서 비교·메일 머지·패키지 검증). 정적 import로 해석하므로 동적 import 지점은
375
+ #: 늘지 않는다.
376
+ _TOOLS_STABLE_EXPORTS = frozenset(
377
+ {
378
+ "DEFAULT_NAMESPACES",
379
+ "ParagraphInfo",
380
+ "SectionInfo",
381
+ "TextExtractor",
382
+ "FoundElement",
383
+ "ObjectFinder",
384
+ "DOC_DIFF_REPORT_VERSION",
385
+ "REFERENCE_CONSISTENCY_REPORT_VERSION",
386
+ "diff_paragraphs",
387
+ "doc_diff",
388
+ "inspect_reference_consistency",
389
+ "MAIL_MERGE_REPORT_VERSION",
390
+ "inspect_mail_merge_placeholders",
391
+ "load_mail_merge_rows",
392
+ "merge_template_rows",
393
+ "EditorOpenSafetyReport",
394
+ "PackageValidationReport",
395
+ "validate_editor_open_safety",
396
+ "validate_package",
397
+ }
376
398
  )
399
+
400
+
401
+ if TYPE_CHECKING: # type checkers see the real objects; at runtime they load lazily
402
+ from .tools.doc_diff import (
403
+ DOC_DIFF_REPORT_VERSION,
404
+ REFERENCE_CONSISTENCY_REPORT_VERSION,
405
+ diff_paragraphs,
406
+ doc_diff,
407
+ inspect_reference_consistency,
408
+ )
409
+ from .tools.mail_merge import (
410
+ MAIL_MERGE_REPORT_VERSION,
411
+ inspect_mail_merge_placeholders,
412
+ load_mail_merge_rows,
413
+ merge_template_rows,
414
+ )
415
+ from .tools.object_finder import FoundElement, ObjectFinder
416
+ from .tools.package_validator import (
417
+ EditorOpenSafetyReport,
418
+ PackageValidationReport,
419
+ validate_editor_open_safety,
420
+ validate_package,
421
+ )
422
+ from .tools.text_extractor import (
423
+ DEFAULT_NAMESPACES,
424
+ ParagraphInfo,
425
+ SectionInfo,
426
+ TextExtractor,
427
+ )
428
+
429
+
430
+ # ``import hwpx.builder`` goes through the import system, not ``__getattr__``,
431
+ # so the moved module names get their destination from a finder instead.
432
+ from . import _moved_modules
433
+
434
+ _moved_modules.install(_MOVED_TO_COMPANION)
435
+
436
+
437
+ # --- stable 최상위 표면 (eager import) ------------------------------------------
438
+ # ``hwpx.tools``의 stable 이름은 위 ``_TOOLS_STABLE_EXPORTS``가 지연 해석한다.
377
439
  from .ingest import HwpxMarkdownConverter
378
- from .errors import HwpxError
379
- from .hwp5.errors import Hwp5ConversionWarning, Hwp5Error
440
+ from .errors import Hwp5ConversionWarning, Hwp5Error, HwpxError
380
441
  from .mutation_report import (
381
442
  MutationReport,
382
443
  PreservationDowngradeError,
@@ -615,7 +615,7 @@ class _LegacyFacade:
615
615
  field_id: str | None = None,
616
616
  author: str | None = None,
617
617
  created: datetime | str | None = None,
618
- number: int = 1,
618
+ number: int | None = None,
619
619
  anchor_char_pr_id_ref: str | int | None = None,
620
620
  ) -> tuple[HwpxOxmlMemo, HwpxOxmlParagraph, str]:
621
621
  """Create a memo and ensure it is visible by anchoring a MEMO field."""
@@ -801,7 +801,7 @@ class _LegacyFacade:
801
801
  field_id: str | None = None,
802
802
  author: str | None = None,
803
803
  created: datetime | str | None = None,
804
- number: int = 1,
804
+ number: int | None = None,
805
805
  char_pr_id_ref: str | int | None = None,
806
806
  ) -> str:
807
807
  """Attach a MEMO field control to *paragraph* so Hangul shows *memo*."""