athena-python-docx 0.32.0__tar.gz → 0.34.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.
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/AGENTS.md +133 -29
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/PKG-INFO +1 -1
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/__init__.py +1 -1
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_capabilities.py +10 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_http_doc.py +8 -2
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_postproc.py +10 -1
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_run_order.py +31 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/commands.py +66 -2
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/enum/base.py +28 -1
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/section.py +9 -24
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/styles/_table.py +6 -4
- athena_python_docx-0.34.0/docx/styles/latent.py +337 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/styles/style.py +269 -66
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/styles/styles.py +10 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/table.py +70 -13
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/text/hyperlink.py +7 -4
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/text/pagebreak.py +65 -18
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/text/paragraph.py +82 -17
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/text/parfmt.py +70 -41
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/text/run.py +201 -30
- athena_python_docx-0.34.0/docx/text/tabstops.py +461 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/pyproject.toml +1 -1
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/ab_probe_cases.py +88 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/fake_session.py +4 -1
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +1 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +1 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +1 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +1 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw18_header_table_properties.json +1 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fixtures/field_reads.json +1 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/live/baseline.json +10 -59
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/live/fixture_scripts.py +50 -0
- athena_python_docx-0.34.0/tests/test_alignment_values.py +90 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_field_runs.py +159 -3
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_http_transport.py +1 -1
- athena_python_docx-0.34.0/tests/test_latent_style_writes.py +166 -0
- athena_python_docx-0.34.0/tests/test_line_clear_break.py +83 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_paragraph_delete.py +1 -0
- athena_python_docx-0.34.0/tests/test_parfmt_clears.py +144 -0
- athena_python_docx-0.34.0/tests/test_rendered_page_breaks.py +229 -0
- athena_python_docx-0.34.0/tests/test_run_page_number_blocks.py +157 -0
- athena_python_docx-0.34.0/tests/test_run_unmodeled_toggles.py +86 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_parfmt.py +10 -8
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_row_col_cell.py +3 -11
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_section_onoff.py +11 -23
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_table_layout.py +8 -6
- athena_python_docx-0.34.0/tests/test_style_delete.py +150 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_style_formatting_writes.py +25 -2
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_style_metadata_writes.py +138 -1
- athena_python_docx-0.34.0/tests/test_style_tab_stops.py +207 -0
- athena_python_docx-0.34.0/tests/test_tab_stop_writes.py +324 -0
- athena_python_docx-0.34.0/tests/test_table_clears.py +128 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_wire_contract.py +8 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/uv.lock +1 -1
- athena_python_docx-0.32.0/docx/styles/latent.py +0 -220
- athena_python_docx-0.32.0/docx/text/tabstops.py +0 -232
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/.gitignore +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/CLAUDE.md +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/DOCX_EXEC_LAB.md +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/README.md +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_athena_extension.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_batching.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_buffer.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_citations.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_execution.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_http.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_image_utils.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_ptc.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_references.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_table_styles.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_timeouts.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/_tracked.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/api.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/blkcntnr.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/bookmarks.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/charts.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/client.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/comments.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/document.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/drawing/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/enum/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/enum/dml.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/enum/section.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/enum/shape.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/enum/style.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/enum/table.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/enum/text.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/errors.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/exceptions.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/fields.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/footnotes.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/image/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/image/exceptions.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/image/image.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/math.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/opc/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/opc/coreprops.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/oxml/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/revisions.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/sdt.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/session.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/settings.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/shape.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/shared.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/styles/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/text/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/text/font.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/toc.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/docx/typing.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/docx_exec_lab.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/docx_exec_lab_examples/fast_table_fill.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/docx_exec_lab_examples/find_replace_literal.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/dump_wire_fixtures.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/release.sh +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/round_trip_smoke.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/smoke_test_block_not_found.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/scripts/validate_find_replace_asset.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/conftest.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/METHODOLOGY.md +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/README.md +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/ab_probe_runner.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/auto_gen_cases.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/binary_round_trip.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/cases.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/complex_cases.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/coverage_report.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/extract.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/extreme_cases.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/firm_templates/README.md +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/firm_templates/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/firm_templates/_runner.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/firm_templates/extractor.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/firm_templates/test_pw_corpus.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/firm_templates/test_pw_research_digest.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/local_runner.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/mega_cases.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshot.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/17_table_basic.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/35_full_report.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex14_styled_report_table.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw16_header_footer_tables.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw17_header_letterhead_filled.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw19_header_table_rows_columns.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/op_snapshots/rw20_header_table_merges.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/ours_spec.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/parity_crawl.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/parity_diff.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/real_world_cases.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/round_trip_tests.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/stock_spec.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fixtures/note_reference_reads.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fixtures/ruby_reads.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/fixtures/symbol_reads.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/live/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/live/reader.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/live/runner.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/live/sdk_driver.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/live/stock_driver.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/live/test_live_runner.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/README.md +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/__init__.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/baseline_gaps.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/compare.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/intentional_deviations.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/introspect.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/reports/GAP_ANALYSIS.md +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/reports/gap_report.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/run_parity.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/snapshots/athena_latest.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/parity/test_parity_gap.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_add_section.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_add_section_extract_items.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_athena_extension_creates_session_open.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_athena_extensions_contract.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_athena_extensions_registry.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_batch_chunking.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_batching_perf.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_block_not_found_error.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_buffer.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_add_paragraph_wire_shape.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_add_table_not_supported.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_borders_spec.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_fastpath_runs.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_inner_add_hyperlink_stash.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_inner_add_run_via_cell_insert.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_inner_format_stash.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_inner_run_format_stash.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_inner_run_guard.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_merge.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_nested_tables.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_paragraphs_listed.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_text_plain_fastpath.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_cell_text_replace_semantics.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_citations.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_collapsed_range_format.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_color_format_theme.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_command_dataclasses.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_commands.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_comment_paragraphs.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_comments.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_comments_first_read.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_content_control_value.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_core_properties.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_document_asset_id_property.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_document_clear.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_document_create.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_document_create_from_template.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_document_factory_validation.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_docx_exec_lab.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_docx_exec_lab_server.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_drawing_image.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_e2e_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_empty_hyperlinks.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_enum_parity.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_execution_scope.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_export_docx_clean.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_export_rescue_anchors.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_field_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_field_refresh.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_find_replace_session_open.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_flushed_write_failures.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_hyperlink_coalescing.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_image_url_data_uri.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_inline_page_break.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_inline_shape_alt_text.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_inline_shape_size.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_inline_shape_type.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_inline_shapes_floating.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_insert_deferred.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_iter_inner_content.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_list_styles.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_merged_cell_secondary_slot.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_merged_cells.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_missing_modules.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_nested_table_refused.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_note_reference_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_oxml_shim.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_page_break.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_paragraph_runs_hyperlinks.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_paragraph_text_len_cache.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_parity_misc.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_parity_round2.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_partial_failure_cascade.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_pdf_export_and_page_renders.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_phase_a_behavior.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_phase_b_headers_footers.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_phase_c_tables.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_positional_cell_id.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_postproc_cell_format_rewrite.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_postproc_cell_run_format_rewrite.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_postproc_ref_restore.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_pr19766_review_fixes.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_ptc.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_python_docx_api_parity.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_read_run_ranges.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_repeated_node_read.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_restart_numbering.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_revisions.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_round_trip_smoke_script.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_ruby_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_add_picture_anchor.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_break_inner_content.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_edges.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_formatting_wire.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_identity.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_later_runs.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_mark_inheritance.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_table_style_objects.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_text_python_docx.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_run_text_refreshes_paragraph.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_sdk_reads_served.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_section_read_lengths.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_add_picture.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_add_run.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_comments_get.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_document_audit.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_document_element.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_enum_section.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_font_audit.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_header_footer.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_hyperlink.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_inline_shape.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_misc.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_paragraph_strict.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_paragraph_style.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_run_add_break.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_run_style.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_run_style_strict.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_run_text.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_run_underline.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_section_audit.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_section_dimensions.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_settings.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_shared_audit.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_style.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_styles.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_table_audit.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_table_cell.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_silent_stub_table_dimensions.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_smoke_integration.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_style_acceptance.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_style_font.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_style_names.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_style_setters_contract.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_style_tab_stops_read.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_symbol_reads_python_docx_parity.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_table_anchors.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_table_direction.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_table_read_reuse.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_table_set_cell_perf.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_table_style_id_resolution.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_temporarily_unavailable.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_text_control_characters.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_tracked_revisions_offsets.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_uv_lock_version.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_validate_find_replace_asset_script.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_xml_attr_guard.py +0 -0
- {athena_python_docx-0.32.0 → athena_python_docx-0.34.0}/tests/test_zod_wire_contract.py +0 -0
|
@@ -85,16 +85,30 @@ pinned by focused tests and documented in
|
|
|
85
85
|
`quick_style`, `unhide_when_used`, `base_style`,
|
|
86
86
|
`next_paragraph_style`) write the style's definition
|
|
87
87
|
(`SetStyleMetadata`), `Styles.add_style` adds one (`CreateStyle`), and
|
|
88
|
-
a paragraph or
|
|
89
|
-
`style.paragraph_format
|
|
88
|
+
a paragraph, character or table style's formatting (`style.font.*`,
|
|
89
|
+
`style.paragraph_format.*`; a table style's on a docx-studio that reports
|
|
90
|
+
`tableStyleFormatting`, which a room imported before its cells resolved
|
|
91
|
+
table styles does not) is written too (`SetStyleFormatting`); each
|
|
90
92
|
reads back from the style table, whose `metadata` / `font` /
|
|
91
93
|
`paragraphFormat` entries are the capability signal
|
|
92
94
|
(`tests/test_style_metadata_writes.py`,
|
|
93
|
-
`tests/test_style_formatting_writes.py`)
|
|
94
|
-
|
|
95
|
-
a docx-studio
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
`tests/test_style_formatting_writes.py`), a paragraph style's
|
|
96
|
+
`tab_stops` (each mutation sends the style's whole `w:tabs` as python-docx's
|
|
97
|
+
`TabStops` leaves it, on a docx-studio that reports `styleTabStops`; each
|
|
98
|
+
tab stop object is its place in that list, which a write to another moves,
|
|
99
|
+
so of two equal stops each writes itself, and one removed writes nothing;
|
|
100
|
+
`tests/test_style_tab_stops.py`). `delete()` removes a paragraph
|
|
101
|
+
or character style's definition (`DeleteStyle`, on a docx-studio that
|
|
102
|
+
reports `deleteStyle`; `tests/test_style_delete.py`): its content keeps the
|
|
103
|
+
style's name and shows the default style, as in Word. A table style's
|
|
104
|
+
`delete()`, `base_style` and `style_id` are sent where docx-studio also
|
|
105
|
+
reports `tableStyleRestyles` (it draws the style's tables again), and its
|
|
106
|
+
font and paragraph format where it reports `tableStyleFormatting`; a room
|
|
107
|
+
imported before its cells resolved table styles reports neither. A
|
|
108
|
+
numbering style's `style_id` and deletion, and every style write on a
|
|
109
|
+
docx-studio without that signal emit
|
|
110
|
+
`PendingStyleMutationWarning` (or its delete / paragraph-format / registry
|
|
111
|
+
variant) and stash on `_overrides` (`tests/test_style_setters_contract.py`).
|
|
98
112
|
- **A picture is a run, and `Run.iter_inner_content()` yields its
|
|
99
113
|
`docx.drawing.Drawing`.** As python-docx reads a `w:r` holding a
|
|
100
114
|
`w:drawing`, `Paragraph.runs` and `iter_inner_content()` hold a run with
|
|
@@ -116,10 +130,15 @@ pinned by focused tests and documented in
|
|
|
116
130
|
- **`Styles.latent_styles`** (`docx.styles.latent.LatentStyles`) reads
|
|
117
131
|
the document's `<w:latentStyles>` (defaults and each `w:lsdException`)
|
|
118
132
|
from docx-studio's `Info` (`includeStyles` → `latentStyles`), as python-docx
|
|
119
|
-
reads them
|
|
120
|
-
and `_LatentStyle.delete`
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
reads them, and writes them as python-docx does: each setter,
|
|
134
|
+
`add_latent_style` and `_LatentStyle.delete` sends one `EditLatentStyles`
|
|
135
|
+
to a docx-studio that reports `latentStyleWrites`
|
|
136
|
+
(`tests/test_latent_style_writes.py`); an older one keeps the value, with
|
|
137
|
+
`PendingLatentStylesWriteWarning`. A `_LatentStyle` addresses its exception
|
|
138
|
+
by name and `occurrence` (which of that name's exceptions it is), moved
|
|
139
|
+
when an earlier one is deleted, so one `add_latent_style` returns beside an
|
|
140
|
+
exception of the same name writes to itself, as python-docx's element does. A docx-studio that predates the read (or
|
|
141
|
+
a document without a source copy) reads as empty, with
|
|
123
142
|
`PendingLatentStylesReadWarning`.
|
|
124
143
|
|
|
125
144
|
### Intentional deviations (additions / different semantics)
|
|
@@ -169,6 +188,22 @@ not file-backed. Each is documented in the relevant docstring.
|
|
|
169
188
|
cells stay. ``table.style = None`` removes an existing table's style as
|
|
170
189
|
python-docx does (``DOCX_STUDIO_LIMITATIONS.md`` § 25).
|
|
171
190
|
|
|
191
|
+
- **Table, row and cell properties set to None, and row height parts**, as
|
|
192
|
+
python-docx 1.2.0 writes them on a docx-studio that reports
|
|
193
|
+
``tableClears`` (``tests/test_table_clears.py``): ``Table.alignment =
|
|
194
|
+
None`` removes ``w:jc`` (a header or footer table's too),
|
|
195
|
+
``_Cell.vertical_alignment = None`` removes
|
|
196
|
+
``w:vAlign``, and ``_Row.height`` / ``_Row.height_rule`` each write their
|
|
197
|
+
own part of ``w:trHeight``, None removing it (``<w:trHeight
|
|
198
|
+
w:hRule="exact"/>``); a height set without a rule is the value alone.
|
|
199
|
+
``_Cell.width = None`` raises ``TypeError`` and ``Table.autofit = None``
|
|
200
|
+
changes nothing, as in python-docx. An older docx-studio keeps the
|
|
201
|
+
``PendingTableClearWarning`` and sends a rule (at least) with each height.
|
|
202
|
+
``_Column.width = None`` still warns: a ``w:gridCol`` without a width
|
|
203
|
+
needs the layout to size the column from its cells. An invalid height or
|
|
204
|
+
rule is refused before the capability read, whose ``Info`` would send the
|
|
205
|
+
edits still buffered.
|
|
206
|
+
|
|
172
207
|
- **`Document.create(name=, base_url=, api_key=, parent_folder_id=, workspace_id=, docx=, agora_base_url=)`**
|
|
173
208
|
classmethod. Stock python-docx returns a blank in-memory document
|
|
174
209
|
for `Document(None)`; we can't fabricate a Word document asset
|
|
@@ -921,10 +956,26 @@ architecture or a DOCX Studio constraint:
|
|
|
921
956
|
string DOCX Studio's commands carry for a member (`"center"`, `"wavy"`,
|
|
922
957
|
the `w:` XML value, …) where upstream rejects strings. The SDK sends
|
|
923
958
|
`member.to_docx_studio()` and reads with `from_docx_studio()`, never
|
|
924
|
-
`.value`.
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
`
|
|
959
|
+
`.value`. A paragraph's alignment and tab stops go as python-docx writes
|
|
960
|
+
them (distributed / kashida / Thai justification, `LIST`/`CLEAR`/`END`/
|
|
961
|
+
`NUM`/`START` tabs) to a DOCX Studio that reports `alignmentValues`
|
|
962
|
+
(`tests/test_alignment_values.py`); to an older one, as their closest
|
|
963
|
+
value (`"justify"`, `"left"`) with `PendingEnumCoercionWarning`.
|
|
964
|
+
`TabStops.add_tab_stop` keeps a stop already at its position and goes in
|
|
965
|
+
after it, as python-docx's `insert_tab_in_order` puts it
|
|
966
|
+
(`SetParagraphTabStop` with `insert`, sent to a DOCX Studio that reports
|
|
967
|
+
`tabStopInserts`; an older one replaces that stop). A stop's `alignment`
|
|
968
|
+
and `leader` change it in place, and its `position` moves it where
|
|
969
|
+
python-docx moves its `w:tab` (`tests/test_tab_stop_writes.py`). A
|
|
970
|
+
`TabStop` is its place in the paragraph's list, which a write through any
|
|
971
|
+
other moves (the live stops of each paragraph are held weakly per
|
|
972
|
+
session), as python-docx's proxy holds its `w:tab`: two stops at one
|
|
973
|
+
position are each their own, and two objects of one stop both write it.
|
|
974
|
+
One the paragraph no longer holds takes a value and writes nothing; its
|
|
975
|
+
`position` raises `AttributeError`, except for one `clear_all` took out,
|
|
976
|
+
as python-docx's do. An add reads nothing unless a stop of the paragraph
|
|
977
|
+
holds a place: the next read finds where it went.
|
|
978
|
+
`WD_ALIGN_VERTICAL.BOTH` goes as `"center"`. `INHERITED`
|
|
928
979
|
raises `ValueError` ("has no XML representation") as upstream's
|
|
929
980
|
`to_xml` does, and a bool is its int value (`True` is the member valued
|
|
930
981
|
1), as upstream reads it. `Table.alignment`
|
|
@@ -1009,7 +1060,10 @@ architecture or a DOCX Studio constraint:
|
|
|
1009
1060
|
docx-studio finds the table by those paragraphs, so a table an edit moved (a
|
|
1010
1061
|
row added above a table nested in a cell, a table added before it, a merge
|
|
1011
1062
|
moving a nested table into the merged cell) is still the one read and
|
|
1012
|
-
written, as python-docx's proxies follow the elements they hold.
|
|
1063
|
+
written, as python-docx's proxies follow the elements they hold. A write
|
|
1064
|
+
that replaces one of those paragraphs (`cell.text = …` on the first or last
|
|
1065
|
+
cell) leaves its paraId on the table as an alias (`anchorAliases`), so the
|
|
1066
|
+
proxy reaches the table in later batches on any docx-studio replica. When no
|
|
1013
1067
|
table holds them (the table was deleted, or the cell holding it had its
|
|
1014
1068
|
text replaced, which removes the tables it held), docx-studio refuses the
|
|
1015
1069
|
batch and the SDK raises `StaleTableError`: "the table this proxy named is
|
|
@@ -1069,11 +1123,16 @@ architecture or a DOCX Studio constraint:
|
|
|
1069
1123
|
exported paragraph as `annotation text`. Owner decision, 2026-10-12.
|
|
1070
1124
|
Recorded in `tests/parity/intentional_deviations.json` (`live_deviations`).
|
|
1071
1125
|
|
|
1072
|
-
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
`
|
|
1076
|
-
|
|
1126
|
+
- **A `ParagraphFormat` setter given `None` clears that property alone**, as
|
|
1127
|
+
upstream does, on a docx-studio that reports `paragraphFormatClears`:
|
|
1128
|
+
`space_before`, `space_after`, `line_spacing` (the line with its rule) and
|
|
1129
|
+
`line_spacing_rule` (the rule alone) send `ClearParagraphSpacing.only`;
|
|
1130
|
+
`left_indent`, `right_indent` and `first_line_indent` send
|
|
1131
|
+
`ClearParagraphIndentation.only`; `keep_with_next`, `keep_together` and
|
|
1132
|
+
`widow_control` send `SetParagraphKeepOptions.clear…`. On an older one a
|
|
1133
|
+
spacing or indent `None` clears all of the paragraph's spacing or indents,
|
|
1134
|
+
as before, and the keep options and `line_spacing_rule` warn
|
|
1135
|
+
(`PendingParfmtClearWarning`) and keep the value. The `Section` dimension setters
|
|
1077
1136
|
remove the attribute for `None`, as upstream does (`null` on the wire),
|
|
1078
1137
|
on a docx-studio whose section read reports `clearsDimensions`; on an
|
|
1079
1138
|
older one they warn (`PendingSectionDimensionClearWarning`) and keep the
|
|
@@ -1156,18 +1215,37 @@ architecture or a DOCX Studio constraint:
|
|
|
1156
1215
|
field's result changed (through another read's run, or by a
|
|
1157
1216
|
collaborator) raises `FieldRunWriteError` rather than write over that
|
|
1158
1217
|
change, where python-docx's run is live;
|
|
1159
|
-
- formatting a result run formats the field's whole result
|
|
1160
|
-
with a `field` target), from its source formatting,
|
|
1161
|
-
formats that run
|
|
1218
|
+
- formatting a field's one result run formats the field's whole result
|
|
1219
|
+
(`FormatApply` with a `field` target), from its source formatting, as
|
|
1220
|
+
python-docx formats that run, and in a body paragraph docx-studio writes
|
|
1221
|
+
the run's own `w:rPr` with it (a caption's number keeps its `w:noProof`
|
|
1222
|
+
and takes nothing of the Caption style); of a result of several runs, it formats that
|
|
1223
|
+
run alone, as python-docx does, against a docx-studio that reports
|
|
1224
|
+
`capabilities.fieldRunFormats` (an older one formats the whole result).
|
|
1225
|
+
The SDK names that run by its place among the result's runs and the text
|
|
1226
|
+
it was read with, and renumbers the result runs a read holds when a write
|
|
1227
|
+
through one of them empties it (docx-studio writes no emptied result
|
|
1228
|
+
run): a run that no longer has a place, or holds other text, is not
|
|
1229
|
+
formatted alone. The SDK warns (`PendingFieldRunFormatWarning`), or
|
|
1230
|
+
docx-studio refuses the format, so it never lands on another run;
|
|
1162
1231
|
- `.text` (and `clear()`) on a field character or field code run raises
|
|
1163
1232
|
`docx.errors.FieldRunWriteError` naming the field: python-docx replaces
|
|
1164
1233
|
the run's `w:fldChar` or `w:instrText` with the text, which breaks the
|
|
1165
1234
|
field;
|
|
1166
|
-
- formatting set on a field character or field code run
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1235
|
+
- formatting set on a field character or field code run, a table of
|
|
1236
|
+
contents' own runs among them, is written to that run's `w:rPr` as
|
|
1237
|
+
python-docx writes it, so `for run in p.runs: run.bold = True` formats
|
|
1238
|
+
every run, against a docx-studio that reports
|
|
1239
|
+
`capabilities.fieldRunFormats` (the SDK names the run: its `part`, with its
|
|
1240
|
+
field's index and which run of that part it is, or which of the
|
|
1241
|
+
paragraph's field runs no field node stands for it is). It is refused and
|
|
1242
|
+
warns (`DocxUnsupportedCommandWarning`) for a run of a field `add_field`
|
|
1243
|
+
added since the import, whose runs docx-studio writes from its node, and
|
|
1244
|
+
of a paragraph a field was added to or taken out of since; a tracked
|
|
1245
|
+
format raises naming `TrackedChangesUnsupported`. An older docx-studio has
|
|
1246
|
+
no command that writes those runs' `w:rPr`: there the setter changes
|
|
1247
|
+
nothing and emits `PendingFieldRunFormatWarning`
|
|
1248
|
+
(`tests/test_field_runs.py`, `DOCX_STUDIO_LIMITATIONS.md` § 27);
|
|
1171
1249
|
- `add_text`, `add_tab`, `add_break`, `add_picture`, `add_field`,
|
|
1172
1250
|
`add_footnote`, `add_endnote`, `add_math` and `add_cross_reference` on
|
|
1173
1251
|
any of a field's runs raise `FieldRunWriteError`; python-docx appends to
|
|
@@ -1177,6 +1255,32 @@ architecture or a DOCX Studio constraint:
|
|
|
1177
1255
|
exported file. Against a docx-studio that predates `fieldRun` reads, a
|
|
1178
1256
|
field reads as no runs and no text, as before (`tests/test_field_runs.py`).
|
|
1179
1257
|
|
|
1258
|
+
- **A run that holds a page number block refuses two whole-run formats.** A
|
|
1259
|
+
page number block (`w:pgNum`) reads as a run with no text, and a run that
|
|
1260
|
+
holds text and blocks (or two blocks) reads as python-docx's one run. A
|
|
1261
|
+
whole-run format (`run.bold = True`, `run.font.*`, a format of a block's
|
|
1262
|
+
run) formats every piece of it, as python-docx formats its `w:rPr`. Two
|
|
1263
|
+
formats are refused while a block of the run has a node. A link's block
|
|
1264
|
+
has none, and takes both as the run's text does. The first is a tracked
|
|
1265
|
+
format (`track_revisions`), which raises `DocxError` naming
|
|
1266
|
+
`TrackedChangesUnsupported`, because docx-studio records no tracked change
|
|
1267
|
+
on a block. The second is the on/off properties no editor mark holds
|
|
1268
|
+
(`font.no_proof`, `snap_to_grid`, `web_hidden`, `spec_vanish`, `math`,
|
|
1269
|
+
`complex_script`, `cs_bold`, `cs_italic`), in any format that reaches a
|
|
1270
|
+
block, which warn (`DocxUnsupportedCommandWarning`), because a block keeps
|
|
1271
|
+
its source run's.
|
|
1272
|
+
python-docx writes both into the run's `w:rPr`. Made on the run's text
|
|
1273
|
+
alone, either would leave the run half formatted and split it in two
|
|
1274
|
+
(`DOCX_STUDIO_LIMITATIONS.md` § 27). `run.text = …` and `clear()` replace
|
|
1275
|
+
all of such a run, its blocks too, as upstream does: the SDK declares
|
|
1276
|
+
`wholeRunPieces`, and renumbers the field runs it holds of the paragraph,
|
|
1277
|
+
since each field after the blocks is numbered one lower for each
|
|
1278
|
+
(`tests/test_run_page_number_blocks.py`). Two text writes are refused and
|
|
1279
|
+
warn (`DocxUnsupportedCommandWarning`), where upstream replaces the
|
|
1280
|
+
blocks: text written to a block's run (a run of blocks alone, or a lone
|
|
1281
|
+
block), which would move the text offsets the SDK keeps, and the text of a
|
|
1282
|
+
link's run that holds a block, which has no node to take out.
|
|
1283
|
+
|
|
1180
1284
|
- **`Font.name = "…"` also clears the theme fonts of the two slots it
|
|
1181
1285
|
sets.** python-docx writes the name to `w:rFonts`' `w:ascii` and `w:hAnsi`
|
|
1182
1286
|
and leaves a `w:asciiTheme` / `w:hAnsiTheme` beside them; Word reads a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: athena-python-docx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.34.0
|
|
4
4
|
Summary: Drop-in replacement for python-docx that connects to Athena's DOCX Studio collaborative document stack
|
|
5
5
|
Project-URL: Homepage, https://athenaintelligence.ai
|
|
6
6
|
Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
|
|
@@ -22,6 +22,16 @@ from docx._batching import run_sync
|
|
|
22
22
|
# An older docx-studio gives none, so the SDK needs no check.
|
|
23
23
|
TABLE_ANCHORS_CLIENT_CAPABILITY = "tableAnchors"
|
|
24
24
|
|
|
25
|
+
# What this SDK declares in ``client.capabilities``: it renumbers the field
|
|
26
|
+
# runs it holds once a whole run's text write (``run.text = …``, ``clear()``)
|
|
27
|
+
# took out the page number blocks (``w:pgNum``) of a run docx-studio cut at
|
|
28
|
+
# them, whose read lists their field indices (``pageNumberBlocks``). Such a
|
|
29
|
+
# write then replaces all of the run, its blocks too, as python-docx replaces
|
|
30
|
+
# its ``w:r``'s content, and each field after the blocks is numbered one lower
|
|
31
|
+
# for each. An older docx-studio lists no blocks and keeps them, so the SDK
|
|
32
|
+
# renumbers nothing.
|
|
33
|
+
WHOLE_RUN_PIECES_CLIENT_CAPABILITY = "wholeRunPieces"
|
|
34
|
+
|
|
25
35
|
# Session -> the capabilities its server reported, read once.
|
|
26
36
|
_capabilities: "weakref.WeakKeyDictionary[Any, dict[str, Any]]" = weakref.WeakKeyDictionary()
|
|
27
37
|
|
|
@@ -44,7 +44,7 @@ from urllib3.util.retry import Retry
|
|
|
44
44
|
from docx._batching import call_abandoned, note_progress
|
|
45
45
|
from docx._buffer import CommandBuffer, keep_reported_message
|
|
46
46
|
from docx._tracked import TRACKED_AUTHORING_CAPABILITY, TRACKED_MINIMAL_PARAGRAPH_TEXT_CAPABILITY
|
|
47
|
-
from docx._capabilities import TABLE_ANCHORS_CLIENT_CAPABILITY
|
|
47
|
+
from docx._capabilities import TABLE_ANCHORS_CLIENT_CAPABILITY, WHOLE_RUN_PIECES_CLIENT_CAPABILITY
|
|
48
48
|
from docx._timeouts import (
|
|
49
49
|
DEFAULT_OP_TIMEOUT_SECONDS,
|
|
50
50
|
LONG_RUNNING_COMMAND_TIMEOUT_SECONDS,
|
|
@@ -87,6 +87,8 @@ from docx.commands import (
|
|
|
87
87
|
CreateParagraph,
|
|
88
88
|
CreateSectionBreak,
|
|
89
89
|
CreateStyle,
|
|
90
|
+
EditLatentStyles,
|
|
91
|
+
DeleteStyle,
|
|
90
92
|
CreateTable,
|
|
91
93
|
CreateTOC,
|
|
92
94
|
CreateWatermark,
|
|
@@ -1209,11 +1211,13 @@ class HttpClient:
|
|
|
1209
1211
|
"version": _sdk_version(),
|
|
1210
1212
|
# Keeps its offsets as a tracked edit moves them, and reads a
|
|
1211
1213
|
# paragraph's length back after a tracked ``paragraph.text``
|
|
1212
|
-
# (``docx._tracked``); holds anchored table ids (``docx.table``)
|
|
1214
|
+
# (``docx._tracked``); holds anchored table ids (``docx.table``);
|
|
1215
|
+
# renumbers its field runs after a cut run's whole write (``docx._run_order``).
|
|
1213
1216
|
"capabilities": [
|
|
1214
1217
|
TRACKED_AUTHORING_CAPABILITY,
|
|
1215
1218
|
TRACKED_MINIMAL_PARAGRAPH_TEXT_CAPABILITY,
|
|
1216
1219
|
TABLE_ANCHORS_CLIENT_CAPABILITY,
|
|
1220
|
+
WHOLE_RUN_PIECES_CLIENT_CAPABILITY,
|
|
1217
1221
|
],
|
|
1218
1222
|
},
|
|
1219
1223
|
"commands": [
|
|
@@ -1374,6 +1378,8 @@ _OP_TO_COMMAND: dict[str, type[Command]] = {
|
|
|
1374
1378
|
"styles.set_formatting": SetStyleFormatting,
|
|
1375
1379
|
"styles.set_metadata": SetStyleMetadata,
|
|
1376
1380
|
"styles.create": CreateStyle,
|
|
1381
|
+
"styles.edit_latent": EditLatentStyles,
|
|
1382
|
+
"styles.delete": DeleteStyle,
|
|
1377
1383
|
"core_properties.set": SetCoreProperties,
|
|
1378
1384
|
# Sections
|
|
1379
1385
|
"sections.set_page_margins": SetSectionPageMargins,
|
|
@@ -2897,6 +2897,15 @@ def _replace_flag(
|
|
|
2897
2897
|
elem.set(f"{W_NS}val", "0")
|
|
2898
2898
|
|
|
2899
2899
|
|
|
2900
|
+
# The other ``w:jc`` justifications python-docx writes, by their lower case.
|
|
2901
|
+
_JUSTIFICATIONS_BY_LOWER = {
|
|
2902
|
+
"mediumkashida": "mediumKashida",
|
|
2903
|
+
"highkashida": "highKashida",
|
|
2904
|
+
"lowkashida": "lowKashida",
|
|
2905
|
+
"thaidistribute": "thaiDistribute",
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2908
|
+
|
|
2900
2909
|
def normalize_alignment(value: Any) -> str | None:
|
|
2901
2910
|
"""Convert a python-docx ``WD_ALIGN_PARAGRAPH`` value (or string) to
|
|
2902
2911
|
the OOXML ``w:jc`` value (``left`` / ``center`` / ``right`` /
|
|
@@ -2919,7 +2928,7 @@ def normalize_alignment(value: Any) -> str | None:
|
|
|
2919
2928
|
return "both"
|
|
2920
2929
|
if s in {"distribute"}:
|
|
2921
2930
|
return "distribute"
|
|
2922
|
-
return
|
|
2931
|
+
return _JUSTIFICATIONS_BY_LOWER.get(s)
|
|
2923
2932
|
|
|
2924
2933
|
# WD_ALIGN_PARAGRAPH enum values (int-like).
|
|
2925
2934
|
name = getattr(value, "name", None)
|
|
@@ -29,6 +29,7 @@ document stores none of it.
|
|
|
29
29
|
|
|
30
30
|
from __future__ import annotations
|
|
31
31
|
|
|
32
|
+
import bisect
|
|
32
33
|
import itertools
|
|
33
34
|
import weakref
|
|
34
35
|
from dataclasses import dataclass, field
|
|
@@ -105,6 +106,36 @@ def _live_runs(run: "Run") -> list["Run"]:
|
|
|
105
106
|
return [proxy for block_id in ids for proxy in list(blocks.get(block_id, ()))]
|
|
106
107
|
|
|
107
108
|
|
|
109
|
+
def page_number_blocks_gone(run: "Run", gone: list[int], *, taken_out: bool) -> None:
|
|
110
|
+
"""The page number blocks ``gone`` (their field indices) are no run's of
|
|
111
|
+
``run``'s paragraph now: a whole run's text write took them out
|
|
112
|
+
(``taken_out``), or, with tracking on, deleted them, where they keep
|
|
113
|
+
their place and their numbers.
|
|
114
|
+
|
|
115
|
+
No live run proxy of the paragraph, read or created, lists them
|
|
116
|
+
(``pageNumberBlocks``). Taken out, each field after them is numbered one
|
|
117
|
+
lower for each, as docx-studio numbers them, so every proxy names its
|
|
118
|
+
field (``fieldIndex``) and the blocks it holds by the new numbers.
|
|
119
|
+
"""
|
|
120
|
+
removed = sorted(set(gone))
|
|
121
|
+
|
|
122
|
+
def renumbered(index: int) -> int:
|
|
123
|
+
return index - bisect.bisect_left(removed, index) if taken_out else index
|
|
124
|
+
|
|
125
|
+
for proxy in _live_runs(run):
|
|
126
|
+
snapshot: object = getattr(proxy, "_inline_snapshot", None)
|
|
127
|
+
if not isinstance(snapshot, dict):
|
|
128
|
+
continue
|
|
129
|
+
index: object = snapshot.get("fieldIndex")
|
|
130
|
+
if isinstance(index, int) and not isinstance(index, bool):
|
|
131
|
+
snapshot["fieldIndex"] = renumbered(index)
|
|
132
|
+
blocks: object = snapshot.get("pageNumberBlocks")
|
|
133
|
+
if isinstance(blocks, list):
|
|
134
|
+
snapshot["pageNumberBlocks"] = [
|
|
135
|
+
renumbered(block) for block in blocks if isinstance(block, int) and block not in removed
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
|
|
108
139
|
def _move_live_runs(
|
|
109
140
|
run: "Run",
|
|
110
141
|
old_span: tuple[int, int],
|
|
@@ -248,6 +248,12 @@ class InsertLineBreak(Command):
|
|
|
248
248
|
# in it, as python-docx writes it. Sent only to a docx-studio reporting
|
|
249
249
|
# ``capabilities.inlineColumnBreak``; an older one ignores it.
|
|
250
250
|
inline: bool | None = None
|
|
251
|
+
# ``"left"``, ``"right"`` or ``"all"``: a clearing line break
|
|
252
|
+
# (``Run.add_break(WD_BREAK.LINE_CLEAR_LEFT)`` and the rest), written as
|
|
253
|
+
# ``<w:br w:type="textWrapping" w:clear="…"/>``. Sent only to a
|
|
254
|
+
# docx-studio reporting ``capabilities.lineBreakClear``; an older one
|
|
255
|
+
# ignores it and inserts a line break.
|
|
256
|
+
clear: str | None = None
|
|
251
257
|
|
|
252
258
|
|
|
253
259
|
@dataclass
|
|
@@ -304,6 +310,12 @@ class SetParagraphIndentation(Command):
|
|
|
304
310
|
@dataclass
|
|
305
311
|
class ClearParagraphIndentation(Command):
|
|
306
312
|
target: dict[str, Any]
|
|
313
|
+
# Only these of the paragraph's own indents ("left", "right", "firstLine":
|
|
314
|
+
# the first-line or hanging indent), as python-docx's ``left_indent`` /
|
|
315
|
+
# ``right_indent`` / ``first_line_indent = None`` each clear their own.
|
|
316
|
+
# Without it, all of them. Sent only to a docx-studio reporting
|
|
317
|
+
# ``paragraphFormatClears``; an older one drops it and clears all.
|
|
318
|
+
only: list[str] | None = None
|
|
307
319
|
|
|
308
320
|
|
|
309
321
|
@dataclass
|
|
@@ -318,6 +330,12 @@ class SetParagraphSpacing(Command):
|
|
|
318
330
|
@dataclass
|
|
319
331
|
class ClearParagraphSpacing(Command):
|
|
320
332
|
target: dict[str, Any]
|
|
333
|
+
# Only these of the paragraph's own spacing ("before", "after", "line":
|
|
334
|
+
# the line spacing with its rule, "lineRule": the rule alone), as
|
|
335
|
+
# python-docx's ``space_before`` / ``space_after`` / ``line_spacing`` /
|
|
336
|
+
# ``line_spacing_rule = None`` each clear their own. Without it, all of
|
|
337
|
+
# them. Sent only to a docx-studio reporting ``paragraphFormatClears``.
|
|
338
|
+
only: list[str] | None = None
|
|
321
339
|
|
|
322
340
|
|
|
323
341
|
@dataclass
|
|
@@ -326,6 +344,12 @@ class SetParagraphKeepOptions(Command):
|
|
|
326
344
|
keep_next: bool | None = None
|
|
327
345
|
keep_lines: bool | None = None
|
|
328
346
|
widow_control: bool | None = None
|
|
347
|
+
# ``keep_with_next`` / ``keep_together`` / ``widow_control = None``: the
|
|
348
|
+
# paragraph's own value goes, and it takes its style's again. Sent only to
|
|
349
|
+
# a docx-studio reporting ``paragraphFormatClears``.
|
|
350
|
+
clear_keep_next: bool | None = None
|
|
351
|
+
clear_keep_lines: bool | None = None
|
|
352
|
+
clear_widow_control: bool | None = None
|
|
329
353
|
|
|
330
354
|
|
|
331
355
|
@dataclass
|
|
@@ -347,6 +371,10 @@ class SetParagraphTabStop(Command):
|
|
|
347
371
|
position: float
|
|
348
372
|
alignment: str | None = None
|
|
349
373
|
leader: str | None = None
|
|
374
|
+
# python-docx's ``add_tab_stop``: the stop goes in after any at its
|
|
375
|
+
# position, which stays (``insert_tab_in_order``). An older docx-studio
|
|
376
|
+
# drops the key and replaces that stop.
|
|
377
|
+
insert: bool | None = None
|
|
350
378
|
|
|
351
379
|
|
|
352
380
|
@dataclass
|
|
@@ -381,6 +409,30 @@ class CreateStyle(Command):
|
|
|
381
409
|
builtin: bool | None = None
|
|
382
410
|
|
|
383
411
|
|
|
412
|
+
@dataclass
|
|
413
|
+
class EditLatentStyles(Command):
|
|
414
|
+
"""One python-docx write to ``styles.xml``'s ``w:latentStyles``:
|
|
415
|
+
``defaults`` (``LatentStyles`` setters), ``add`` (``add_latent_style``,
|
|
416
|
+
the styles.xml name) or ``exception`` (``{"name", "attrs"}`` for a
|
|
417
|
+
``_LatentStyle`` setter, ``{"name", "delete": True}`` for ``delete()``).
|
|
418
|
+
Sent only to a docx-studio reporting ``latentStyleWrites``."""
|
|
419
|
+
|
|
420
|
+
defaults: dict[str, Any] | None = None
|
|
421
|
+
add: str | None = None
|
|
422
|
+
exception: dict[str, Any] | None = None
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
@dataclass
|
|
426
|
+
class DeleteStyle(Command):
|
|
427
|
+
"""A style's ``w:style`` removed from ``styles.xml``, as python-docx's
|
|
428
|
+
``BaseStyle.delete()`` removes it: ``style_id`` names it, as for
|
|
429
|
+
``SetStyleMetadata``. Sent only to a docx-studio reporting
|
|
430
|
+
``deleteStyle``."""
|
|
431
|
+
|
|
432
|
+
style_id: str
|
|
433
|
+
style_type: str | None = None
|
|
434
|
+
|
|
435
|
+
|
|
384
436
|
@dataclass
|
|
385
437
|
class SetStyleMetadata(Command):
|
|
386
438
|
"""A style's metadata in ``styles.xml``, as python-docx's ``BaseStyle``
|
|
@@ -599,10 +651,15 @@ class TablesSetColumnWidth(Command):
|
|
|
599
651
|
|
|
600
652
|
@dataclass
|
|
601
653
|
class TablesSetRowHeight(Command):
|
|
654
|
+
"""A row's ``w:trHeight``: ``height_pt`` its value and ``rule`` its
|
|
655
|
+
``w:hRule`` (``"auto"`` | ``"exact"`` | ``"atLeast"``), each left as it is
|
|
656
|
+
when not given; ``NULL`` removes it, on a docx-studio that reports
|
|
657
|
+
``tableClears``."""
|
|
658
|
+
|
|
602
659
|
node_id: str
|
|
603
660
|
row_index: int
|
|
604
|
-
height_pt: float
|
|
605
|
-
rule: str | None = None
|
|
661
|
+
height_pt: float | None = None
|
|
662
|
+
rule: str | None = None
|
|
606
663
|
|
|
607
664
|
|
|
608
665
|
@dataclass
|
|
@@ -2051,6 +2108,11 @@ def is_response_bearing(cmd: Command) -> bool:
|
|
|
2051
2108
|
if isinstance(cmd, CreateSectionBreak):
|
|
2052
2109
|
# ``Document.add_section`` returns the section the answer names.
|
|
2053
2110
|
return cmd.new_section is True
|
|
2111
|
+
if isinstance(cmd, SetStyleMetadata):
|
|
2112
|
+
# ``BaseStyle.style_id = …`` takes the new id once docx-studio renamed
|
|
2113
|
+
# the style: a refused rename raises at the call, and the style keeps
|
|
2114
|
+
# the id the document holds.
|
|
2115
|
+
return "id" in (cmd.metadata or {})
|
|
2054
2116
|
return cmd.type in _RESPONSE_BEARING_TYPES
|
|
2055
2117
|
|
|
2056
2118
|
|
|
@@ -2188,6 +2250,8 @@ __all__ = [
|
|
|
2188
2250
|
"ClearParagraphTabStops",
|
|
2189
2251
|
"SetStyleFormatting",
|
|
2190
2252
|
"CreateStyle",
|
|
2253
|
+
"EditLatentStyles",
|
|
2254
|
+
"DeleteStyle",
|
|
2191
2255
|
"SetStyleMetadata",
|
|
2192
2256
|
"SetCoreProperties",
|
|
2193
2257
|
# Sections
|
|
@@ -62,6 +62,33 @@ class _DocxStudioWire:
|
|
|
62
62
|
"""``value`` as ``owner`` sends it: ``TypeError`` for a non-int,
|
|
63
63
|
non-str value and ``ValueError`` for one naming no member, before
|
|
64
64
|
anything reaches the wire."""
|
|
65
|
+
return cls._member_for(value, owner).to_docx_studio()
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def _wire_for(cls, value: object, owner: str, session: Any, capability: str) -> str:
|
|
69
|
+
"""``value`` as ``owner`` sends it to ``session``'s docx-studio: the
|
|
70
|
+
member's own string where an older docx-studio takes it too, or where
|
|
71
|
+
this one reports ``capability``; else :meth:`_wire`'s closest value,
|
|
72
|
+
with its warning. Only a value an older docx-studio collapses asks
|
|
73
|
+
docx-studio what it takes."""
|
|
74
|
+
import warnings
|
|
75
|
+
|
|
76
|
+
member = cls._member_for(value, owner)
|
|
77
|
+
exact = _wire_value(member)
|
|
78
|
+
with warnings.catch_warnings():
|
|
79
|
+
warnings.simplefilter("ignore")
|
|
80
|
+
collapsed = member.to_docx_studio()
|
|
81
|
+
if exact is None or exact == collapsed:
|
|
82
|
+
return collapsed
|
|
83
|
+
from docx._capabilities import server_takes
|
|
84
|
+
|
|
85
|
+
if session is not None and server_takes(session, capability):
|
|
86
|
+
return exact
|
|
87
|
+
return member.to_docx_studio()
|
|
88
|
+
|
|
89
|
+
@classmethod
|
|
90
|
+
def _member_for(cls, value: object, owner: str) -> Any:
|
|
91
|
+
"""The member ``value`` names for ``owner``, validated as :meth:`_wire` says."""
|
|
65
92
|
if not isinstance(value, (int, str)):
|
|
66
93
|
raise TypeError(
|
|
67
94
|
f"{owner} requires {cls.__name__}, int, or str; "
|
|
@@ -75,7 +102,7 @@ class _DocxStudioWire:
|
|
|
75
102
|
f"{owner} = {value!r}: not a valid {cls.__name__}. "
|
|
76
103
|
f"Expected a member or one of {[m.value for m in members]}."
|
|
77
104
|
) from exc
|
|
78
|
-
return member
|
|
105
|
+
return member
|
|
79
106
|
|
|
80
107
|
|
|
81
108
|
class BaseEnum(_DocxStudioWire, int, enum.Enum):
|
|
@@ -242,28 +242,12 @@ def _warn_section_dimension_clear(prop: str) -> None:
|
|
|
242
242
|
|
|
243
243
|
|
|
244
244
|
class PendingSectionOnOffClearWarning(UserWarning):
|
|
245
|
-
"""
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
``<w:titlePg/>`` element back to inherited. DOCX Studio 1.8's
|
|
249
|
-
``sections.set_title_page`` only accepts ``enabled: bool`` — the
|
|
250
|
-
wire can't represent the clear-intent. The warning surfaces
|
|
251
|
-
silent-divergence. Tracked in
|
|
252
|
-
``docx-studio/DOCX_STUDIO_LIMITATIONS.md``.
|
|
245
|
+
"""No longer emitted: ``Section.different_first_page_header_footer =
|
|
246
|
+
None`` removes ``<w:titlePg/>`` as ``False`` does, as python-docx 1.x
|
|
247
|
+
does. Kept so code that filters or imports it keeps working.
|
|
253
248
|
"""
|
|
254
249
|
|
|
255
250
|
|
|
256
|
-
def _warn_section_onoff_clear(prop: str) -> None:
|
|
257
|
-
warnings.warn(
|
|
258
|
-
f"Section.{prop} = None was IGNORED — DOCX Studio 1.8 has no "
|
|
259
|
-
f"clear-op for this OnOff property. The section keeps its "
|
|
260
|
-
f"previous value. Tracked in "
|
|
261
|
-
f"docx-studio/DOCX_STUDIO_LIMITATIONS.md.",
|
|
262
|
-
PendingSectionOnOffClearWarning,
|
|
263
|
-
stacklevel=3,
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
|
|
267
251
|
def _require_section_bool(prop: str, value: object) -> bool:
|
|
268
252
|
"""Reject non-bool input on Section OnOff setters.
|
|
269
253
|
|
|
@@ -592,11 +576,12 @@ class Section:
|
|
|
592
576
|
|
|
593
577
|
@different_first_page_header_footer.setter
|
|
594
578
|
def different_first_page_header_footer(self, value: bool | None) -> None:
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
579
|
+
# python-docx removes ``w:titlePg`` for ``None`` as for ``False``
|
|
580
|
+
# (``CT_SectPr.titlePg_val``), and so does docx-studio for ``False``.
|
|
581
|
+
enabled = (
|
|
582
|
+
False
|
|
583
|
+
if value is None
|
|
584
|
+
else _require_section_bool("different_first_page_header_footer", value)
|
|
600
585
|
)
|
|
601
586
|
run_sync(
|
|
602
587
|
self._session.doc.sections.set_title_page(
|
|
@@ -204,11 +204,13 @@ def style_table(session: Any) -> tuple[StyleRecord, ...] | None:
|
|
|
204
204
|
# same session): what an earlier read reported is no longer current.
|
|
205
205
|
_latent.pop(session, None)
|
|
206
206
|
_stale.discard(session)
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
# A server that showed it writes styles still does once deletes leave its
|
|
208
|
+
# table without the entries that told: the signal holds for the session.
|
|
209
|
+
_writes_style_formatting[session] = _writes_style_formatting.get(session, False) or (
|
|
210
|
+
bool(table) and any(record.font is not None for record in table)
|
|
209
211
|
)
|
|
210
|
-
_writes_style_metadata[session] =
|
|
211
|
-
record.metadata is not None for record in table
|
|
212
|
+
_writes_style_metadata[session] = _writes_style_metadata.get(session, False) or (
|
|
213
|
+
bool(table) and any(record.metadata is not None for record in table)
|
|
212
214
|
)
|
|
213
215
|
return table
|
|
214
216
|
|