athena-python-docx 0.7.0__tar.gz → 0.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 (311) hide show
  1. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/CLAUDE.md +27 -2
  2. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/PKG-INFO +1 -1
  3. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/__init__.py +1 -1
  4. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/_http_doc.py +58 -5
  5. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/commands.py +9 -2
  6. athena_python_docx-0.8.0/docx/errors.py +88 -0
  7. athena_python_docx-0.8.0/docx/oxml/__init__.py +148 -0
  8. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/table.py +90 -19
  9. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/pyproject.toml +1 -1
  10. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/101_table_cells_flat_iteration.json +0 -6
  11. athena_python_docx-0.8.0/tests/fidelity/op_snapshots/17_table_basic.json +4 -0
  12. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/18_table_cell_text.json +0 -6
  13. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/22_table_cell_paragraphs_iteration.json +2 -1
  14. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/23_nested_table.json +0 -1
  15. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/24_table_add_row_column.json +0 -1
  16. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/35_full_report.json +12 -10
  17. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/40_large_table_10x10.json +0 -100
  18. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/45_cell_text_round_trip.json +0 -1
  19. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/49_resume_layout.json +0 -4
  20. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/51_nested_tables_deep.json +0 -1
  21. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/56_everything_in_one.json +0 -13
  22. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/61_cell_paragraph_with_runs.json +2 -1
  23. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/62_many_cell_paragraphs.json +3 -1
  24. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/63_table_style_round_trip.json +0 -1
  25. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/65_20x20_table_formatted.json +800 -401
  26. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/68_invoice.json +0 -19
  27. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/69_newsletter.json +0 -1
  28. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/72_legal_contract.json +0 -3
  29. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/73_form_with_many_tables.json +0 -30
  30. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/79_bulk_cell_formatting.json +18 -10
  31. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/88_mixed_content_iteration.json +0 -10
  32. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/91_many_small_tables.json +0 -100
  33. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex01_five_levels_deep_tables.json +0 -1
  34. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex02_unicode_everywhere.json +0 -4
  35. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex04_50x50_table.json +0 -50
  36. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex05_long_text_in_cell.json +0 -2
  37. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex10_complex_bom.json +90 -66
  38. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex11_banded_rows_formatting.json +240 -81
  39. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex13_cell_with_10_paragraphs.json +0 -1
  40. athena_python_docx-0.8.0/tests/fidelity/op_snapshots/ex14_styled_report_table.json +211 -0
  41. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex20_kitchen_sink_v2.json +120 -90
  42. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega01_book_chapter.json +18 -15
  43. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega02_research_proposal.json +18 -19
  44. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega03_financial_statement.json +28 -23
  45. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega05_user_manual.json +32 -21
  46. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega07_budget_spreadsheet.json +40 -31
  47. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega09_signed_contract.json +8 -7
  48. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega10_api_documentation.json +64 -32
  49. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw01_official_quickstart.json +0 -12
  50. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw06_meeting_minutes.json +0 -13
  51. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw08_table_merged_header.json +0 -8
  52. athena_python_docx-0.7.0/tests/fidelity/op_snapshots/ex14_styled_report_table.json → athena_python_docx-0.8.0/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +58 -47
  53. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw14_nested_cell_table.json +0 -2
  54. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/baseline_gaps.json +1 -1
  55. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/compare.py +16 -1
  56. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/reports/GAP_ANALYSIS.md +3 -4
  57. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/reports/gap_report.json +3 -12
  58. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/snapshots/athena_latest.json +124 -59
  59. athena_python_docx-0.8.0/tests/test_block_not_found_error.py +246 -0
  60. athena_python_docx-0.8.0/tests/test_cell_text_plain_fastpath.py +60 -0
  61. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_command_dataclasses.py +10 -1
  62. athena_python_docx-0.8.0/tests/test_insert_deferred.py +138 -0
  63. athena_python_docx-0.8.0/tests/test_oxml_shim.py +123 -0
  64. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/uv.lock +1 -1
  65. athena_python_docx-0.7.0/docx/errors.py +0 -45
  66. athena_python_docx-0.7.0/tests/fidelity/op_snapshots/17_table_basic.json +0 -5
  67. athena_python_docx-0.7.0/tests/fidelity/op_snapshots/rw10_colored_grid_table.json +0 -181
  68. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/.gitignore +0 -0
  69. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/README.md +0 -0
  70. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/_batching.py +0 -0
  71. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/_buffer.py +0 -0
  72. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/_http.py +0 -0
  73. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/_image_utils.py +0 -0
  74. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/_ptc.py +0 -0
  75. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/api.py +0 -0
  76. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/client.py +0 -0
  77. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/comments.py +0 -0
  78. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/document.py +0 -0
  79. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/enum/__init__.py +0 -0
  80. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/enum/section.py +0 -0
  81. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/enum/style.py +0 -0
  82. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/enum/table.py +0 -0
  83. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/enum/text.py +0 -0
  84. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/exceptions.py +0 -0
  85. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/opc/__init__.py +0 -0
  86. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/opc/coreprops.py +0 -0
  87. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/revisions.py +0 -0
  88. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/section.py +0 -0
  89. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/settings.py +0 -0
  90. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/shape.py +0 -0
  91. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/shared.py +0 -0
  92. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/styles/__init__.py +0 -0
  93. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/styles/style.py +0 -0
  94. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/styles/styles.py +0 -0
  95. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/text/__init__.py +0 -0
  96. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/text/font.py +0 -0
  97. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/text/hyperlink.py +0 -0
  98. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/text/pagebreak.py +0 -0
  99. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/text/paragraph.py +0 -0
  100. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/text/parfmt.py +0 -0
  101. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/text/run.py +0 -0
  102. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/text/tabstops.py +0 -0
  103. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/docx/typing.py +0 -0
  104. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/scripts/publish.sh +0 -0
  105. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/scripts/release.sh +0 -0
  106. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/scripts/round_trip_smoke.py +0 -0
  107. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/__init__.py +0 -0
  108. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/conftest.py +0 -0
  109. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/METHODOLOGY.md +0 -0
  110. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/README.md +0 -0
  111. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/__init__.py +0 -0
  112. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/ab_probe_cases.py +0 -0
  113. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/ab_probe_runner.py +0 -0
  114. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/auto_gen_cases.py +0 -0
  115. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/binary_round_trip.py +0 -0
  116. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/cases.py +0 -0
  117. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/complex_cases.py +0 -0
  118. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/coverage_report.py +0 -0
  119. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/extract.py +0 -0
  120. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/extreme_cases.py +0 -0
  121. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/fake_session.py +0 -0
  122. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/local_runner.py +0 -0
  123. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/mega_cases.py +0 -0
  124. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshot.py +0 -0
  125. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/01_basic_paragraph.json +0 -0
  126. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/02_multiple_headings.json +0 -0
  127. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/03_runs_with_formatting.json +0 -0
  128. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/04_font_name_and_size.json +0 -0
  129. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/05_font_color_rgb.json +0 -0
  130. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/06_font_character_properties.json +0 -0
  131. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/07_font_subscript_superscript.json +0 -0
  132. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/08_font_highlight.json +0 -0
  133. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/09_paragraph_alignment.json +0 -0
  134. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/100_table_negative_indexing.json +0 -0
  135. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/102_text_with_embedded_special_chars.json +0 -0
  136. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/103_cell_tables_enumeration.json +0 -0
  137. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/104_core_properties_datetime.json +0 -0
  138. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/105_default_one_section.json +0 -0
  139. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/106_heading_paragraph_format.json +0 -0
  140. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/107_varying_row_heights.json +0 -0
  141. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/10_paragraph_indents.json +0 -0
  142. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/11_paragraph_spacing.json +0 -0
  143. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/12_paragraph_keep_options.json +0 -0
  144. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/13_paragraph_tab_stops.json +0 -0
  145. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/14_run_add_tab_and_break.json +0 -0
  146. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/15_run_add_break_page.json +0 -0
  147. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/16_paragraph_clear_and_insert_before.json +0 -0
  148. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/19_table_row_column_sizing.json +0 -0
  149. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/20_table_cell_vertical_alignment.json +0 -0
  150. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/21_table_alignment_and_autofit.json +0 -0
  151. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/25_table_merge_cells.json +0 -0
  152. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/26_section_page_setup.json +0 -0
  153. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/27_section_margins.json +0 -0
  154. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/28_section_add_new.json +0 -0
  155. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/29_section_headers_linked.json +0 -0
  156. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/30_styles_iteration.json +0 -0
  157. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/31_styles_lookup_and_default.json +0 -0
  158. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/32_styles_add_paragraph_style.json +0 -0
  159. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/33_core_properties_set_and_get.json +0 -0
  160. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/34_inline_shapes_iterate_empty.json +0 -0
  161. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/36_replace_text_in_paragraph.json +0 -0
  162. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/37_iterate_runs_and_format_all_bold.json +0 -0
  163. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/38_font_all_properties.json +0 -0
  164. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/39_large_body_100_paragraphs.json +0 -0
  165. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/41_unicode_and_emoji.json +0 -0
  166. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/42_very_long_paragraph.json +0 -0
  167. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/43_paragraph_text_round_trip.json +0 -0
  168. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/44_paragraph_alignment_round_trip.json +0 -0
  169. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/46_run_text_setter_round_trip.json +0 -0
  170. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/47_font_size_round_trip.json +0 -0
  171. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/48_font_color_round_trip.json +0 -0
  172. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/50_multi_section_doc.json +0 -0
  173. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/52_iterate_everything.json +0 -0
  174. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/53_apply_style_to_paragraphs.json +0 -0
  175. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/54_empty_everything.json +0 -0
  176. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/55_single_character_runs.json +0 -0
  177. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/57_runs_after_multiple_text_appends.json +0 -0
  178. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/58_modify_runs_in_place.json +0 -0
  179. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/59_indent_round_trip.json +0 -0
  180. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/60_space_round_trip.json +0 -0
  181. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/64_many_sections.json +0 -0
  182. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/66_toc_like_structure.json +0 -0
  183. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/67_paragraph_insert_before_chain.json +0 -0
  184. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/70_add_and_iterate_back.json +0 -0
  185. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/71_academic_paper.json +0 -0
  186. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/74_paragraph_with_10_runs.json +0 -0
  187. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/75_paragraph_negative_first_line_indent.json +0 -0
  188. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/76_rgbcolor_from_string.json +0 -0
  189. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/77_length_unit_conversions.json +0 -0
  190. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/78_paragraph_copy_style.json +0 -0
  191. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/80_apply_style_after_add_run.json +0 -0
  192. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/81_multi_page_with_breaks.json +0 -0
  193. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/82_add_text_on_existing_run.json +0 -0
  194. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/83_clear_then_repopulate_paragraph.json +0 -0
  195. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/84_table_reread_row_count.json +0 -0
  196. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/85_header_footer_access.json +0 -0
  197. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/86_font_read_unset_returns_none.json +0 -0
  198. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/87_500_paragraph_doc.json +0 -0
  199. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/89_alignment_clear_via_none.json +0 -0
  200. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/90_cell_add_paragraph_styled.json +0 -0
  201. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/92_margins_every_section.json +0 -0
  202. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/93_font_bool_reads_after_set.json +0 -0
  203. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/94_page_break_before_paragraph.json +0 -0
  204. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/95_paragraph_hyperlinks_empty.json +0 -0
  205. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/96_paragraph_contains_page_break.json +0 -0
  206. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/97_document_styles_by_key.json +0 -0
  207. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/98_style_contains_check.json +0 -0
  208. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/99_run_add_picture_from_bytes.json +0 -0
  209. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex03_1000_paragraphs.json +0 -0
  210. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex06_hundred_tiny_runs.json +0 -0
  211. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex07_every_font_boolean.json +0 -0
  212. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex08_many_continuous_sections.json +0 -0
  213. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex09_many_tab_stops.json +0 -0
  214. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex12_section_reconfigure.json +0 -0
  215. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex15_paragraph_all_format_props.json +0 -0
  216. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex16_runs_interleaved_with_breaks.json +0 -0
  217. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex17_all_break_kinds.json +0 -0
  218. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex18_read_back_large_doc.json +0 -0
  219. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/ex19_mutate_all_runs.json +0 -0
  220. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega04_recipe_card.json +0 -0
  221. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega06_complex_newsletter.json +0 -0
  222. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/mega08_product_catalog.json +0 -0
  223. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw02_paragraph_style_list.json +0 -0
  224. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw03_character_formatting.json +0 -0
  225. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw04_section_page_setup.json +0 -0
  226. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw05_toc_pattern.json +0 -0
  227. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw07_dense_formatting_demo.json +0 -0
  228. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw09_bulk_run_iteration.json +0 -0
  229. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw11_header_text.json +0 -0
  230. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw12_first_page_footer.json +0 -0
  231. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw13_even_page_header.json +0 -0
  232. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/op_snapshots/rw15_paragraph_style_instance.json +0 -0
  233. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/ours_spec.json +0 -0
  234. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/parity_crawl.py +0 -0
  235. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/parity_diff.json +0 -0
  236. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/real_world_cases.py +0 -0
  237. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/round_trip_tests.py +0 -0
  238. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/runner.py +0 -0
  239. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/stock_spec.json +0 -0
  240. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/fidelity/test_e2e_against_staging.py +0 -0
  241. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/README.md +0 -0
  242. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/__init__.py +0 -0
  243. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/intentional_deviations.json +0 -0
  244. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/introspect.py +0 -0
  245. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/run_parity.py +0 -0
  246. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/snapshots/upstream_python_docx_1.2.0.json +0 -0
  247. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/parity/test_parity_gap.py +0 -0
  248. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_batching_perf.py +0 -0
  249. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_buffer.py +0 -0
  250. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_collapsed_range_format.py +0 -0
  251. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_commands.py +0 -0
  252. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_comments.py +0 -0
  253. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_document_create.py +0 -0
  254. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_http_transport.py +0 -0
  255. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_hyperlink_coalescing.py +0 -0
  256. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_iter_inner_content.py +0 -0
  257. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_list_styles.py +0 -0
  258. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_merged_cells.py +0 -0
  259. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_paragraph_text_len_cache.py +0 -0
  260. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_parity_misc.py +0 -0
  261. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_parity_round2.py +0 -0
  262. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_phase_a_behavior.py +0 -0
  263. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_phase_b_headers_footers.py +0 -0
  264. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_phase_c_tables.py +0 -0
  265. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_pr19766_review_fixes.py +0 -0
  266. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_ptc.py +0 -0
  267. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_python_docx_api_parity.py +0 -0
  268. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_revisions.py +0 -0
  269. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_add_paragraph_style.py +0 -0
  270. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_add_picture.py +0 -0
  271. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_add_run.py +0 -0
  272. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_cell_add_paragraph.py +0 -0
  273. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_comments_add_comment.py +0 -0
  274. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_comments_get.py +0 -0
  275. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_document_audit.py +0 -0
  276. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_document_element.py +0 -0
  277. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_enum_section.py +0 -0
  278. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_font_audit.py +0 -0
  279. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_header_footer.py +0 -0
  280. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_hyperlink.py +0 -0
  281. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_inline_shape.py +0 -0
  282. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_insert_paragraph_before.py +0 -0
  283. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_misc.py +0 -0
  284. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_paragraph_strict.py +0 -0
  285. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_paragraph_style.py +0 -0
  286. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_paragraph_style_strict.py +0 -0
  287. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_parfmt.py +0 -0
  288. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_row_col_cell.py +0 -0
  289. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_run_add_break.py +0 -0
  290. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_run_bool_setters.py +0 -0
  291. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_run_style.py +0 -0
  292. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_run_style_strict.py +0 -0
  293. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_run_text.py +0 -0
  294. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_run_underline.py +0 -0
  295. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_section_audit.py +0 -0
  296. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_section_dimensions.py +0 -0
  297. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_section_onoff.py +0 -0
  298. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_settings.py +0 -0
  299. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_shared_audit.py +0 -0
  300. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_style.py +0 -0
  301. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_styles.py +0 -0
  302. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_table_audit.py +0 -0
  303. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_table_cell.py +0 -0
  304. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_table_dimensions.py +0 -0
  305. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_silent_stub_table_layout.py +0 -0
  306. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_smoke_integration.py +0 -0
  307. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_style_acceptance.py +0 -0
  308. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_style_font.py +0 -0
  309. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_style_setters_contract.py +0 -0
  310. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_wire_contract.py +0 -0
  311. {athena_python_docx-0.7.0 → athena_python_docx-0.8.0}/tests/test_zod_wire_contract.py +0 -0
@@ -39,6 +39,18 @@ These standard python-docx members don't apply to a Superdoc-backed SDK:
39
39
  `Comment.tables` — SuperDoc models a comment as a single text body,
40
40
  not a `BlockItemContainer`. Use `Comment.text` instead. The
41
41
  paragraph/table-bearing surface raises `CommentsNotImplementedError`.
42
+ - **`docx.oxml.*`** — the entire raw-OOXML module tree (``ns.qn``,
43
+ ``OxmlElement``, ``CT_*`` classes, etc.) is unavailable because the
44
+ SDK is HTTP-only against a SuperDoc Y.Doc; there is no local lxml
45
+ tree to manipulate. As of 0.8.0, ``docx.oxml`` is a real stub
46
+ package that raises a typed
47
+ :class:`docx.oxml.OxmlNotAvailableError` (subclass of
48
+ ``ImportError``) on any attribute access, with an inline pointer at
49
+ the high-level API (``Document.add_paragraph``, ``Run.bold``,
50
+ ``_Cell.text``, …) or the typed command surface in
51
+ ``docx.commands``. Pre-0.8.0 this used to fail with the stdlib's
52
+ generic ``ModuleNotFoundError: No module named 'docx.oxml'`` and
53
+ agents had to retry to discover the gap.
42
54
 
43
55
  ### Phase-3b upstream-blocked surface
44
56
 
@@ -149,13 +161,26 @@ This is a **thin HTTP client** that mimics the sync python-docx API.
149
161
  the context-manager exit drain explicitly; `docx.flush_all()` is
150
162
  the Daytona-prelude hook that flushes every live buffer in the
151
163
  process.
152
- - Other response-bearing ops without a client id (`Insert`,
153
- `ListsCreate`, `ListsAttach`, `CommentsCreate`, `CommentsPatch`,
164
+ - **Insert deferral (0.8.0+):** `Insert` was removed from the
165
+ response-bearing set because every in-tree caller
166
+ (`Paragraph._insert_run_text_segments`, `Run.add_text`, `_Cell.text`)
167
+ ignores the response — the Run proxy wraps a known client-side range
168
+ and doesn't need the server's echoed node id. Net result: a styled
169
+ run (one `add_run` + 6 format setters) ships as 1 HTTP request
170
+ instead of 2. The remaining response-bearing ops without a client id
171
+ (`ListsCreate`, `ListsAttach`, `CommentsCreate`, `CommentsPatch`,
154
172
  `TrackChangesDecide`) keep their eager-flush semantics so callers
155
173
  reading back ids still see real data. A `Document.add_paragraph`
156
174
  with `style="List Bullet"` flushes the queued CreateParagraph in
157
175
  the same batch as the follow-up `ListsCreate` — still one HTTP
158
176
  request per logical operation.
177
+ - **Plain-text cell fast path (0.8.0+):** `_Cell.text = value` skips
178
+ the eager `doc.markdownToFragment` query when ``value`` contains no
179
+ markdown control characters (the dominant case for tabular data —
180
+ numbers, labels, currency strings). The fragment is built locally
181
+ and the follow-up `doc.insert` is buffered, so plain cell
182
+ assignments are 0 HTTP requests until the next flush. See
183
+ ``docx.table._is_plain_text`` for the trigger predicate.
159
184
  - The path-proxy in `_http_doc.py` is an internal translation layer:
160
185
  call sites that look like `await self._session.doc.create.paragraph(p)`
161
186
  resolve to `CommandBuffer.call(CreateParagraph(**p))`. Rewriting call
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: athena-python-docx
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: Drop-in replacement for python-docx that connects to Athena's Superdoc/Keryx collaborative document stack
5
5
  Project-URL: Homepage, https://athenaintelligence.ai
6
6
  Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
@@ -6,7 +6,7 @@ See CLAUDE.md for the API parity contract.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- __version__ = "0.7.0"
9
+ __version__ = "0.8.0"
10
10
 
11
11
  from docx.api import Document
12
12
  from docx._buffer import flush_all
@@ -112,6 +112,7 @@ from docx.commands import (
112
112
  )
113
113
  from docx.errors import (
114
114
  AuthenticationError,
115
+ BlockNotFoundError,
115
116
  DocxError,
116
117
  NotFoundError,
117
118
  SessionError,
@@ -134,6 +135,39 @@ _NOT_FOUND_ERROR_NAMES: frozenset[str] = frozenset(
134
135
  )
135
136
 
136
137
 
138
+ def _looks_like_block_not_found(err_obj: dict) -> bool:
139
+ """Detect SuperDoc's ``Block "<type>:<id>" was not found`` shape.
140
+
141
+ Triggers the typed :class:`BlockNotFoundError` so agent code can
142
+ distinguish a missing-block miss (cell-inner-paragraph addressing
143
+ bug, stale id from a different session) from a generic transport
144
+ or validation error.
145
+ """
146
+ msg = err_obj.get("message")
147
+ if not isinstance(msg, str):
148
+ return False
149
+ lower = msg.lower()
150
+ if "not found" not in lower:
151
+ return False
152
+ # Be conservative: require either ``block "`` (the SuperDoc CLI's
153
+ # quoted-id format) or ``block <id>`` followed by ``not found``.
154
+ return 'block "' in lower or ('block ' in lower and ' was not found' in lower)
155
+
156
+
157
+ _CELL_PARAGRAPH_HINT: str = (
158
+ "\n\nHint: SuperDoc 1.8.1 cannot format paragraphs nested inside "
159
+ "table cells via SetParagraphAlignment / SetParagraphStyle / "
160
+ "SetParagraphIndentation / SetParagraphSpacing or doc.insert with "
161
+ "a paragraph-block target. The cell's inner paragraph id is "
162
+ "returned by cell.getNodeById but isn't a top-level addressable "
163
+ "block. Materialize the cell's paragraph first via "
164
+ '``cell.text = "value"``, then re-read ``cell.paragraphs[0]`` and '
165
+ "apply format ops to that post-materialization Paragraph proxy. "
166
+ "Tracked upstream at docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md "
167
+ "§ 'cell-inner paragraph addressing'."
168
+ )
169
+
170
+
137
171
  def _looks_like_not_found(parsed: dict) -> bool:
138
172
  """Inspect a docx-studio partial-failure dict and decide whether it
139
173
  describes a "no such entity" miss (vs. a real transport / validation
@@ -285,11 +319,30 @@ def _http_post_json(
285
319
  # sites (``Comments.get``) can coerce it to ``None`` without
286
320
  # swallowing real transport / validation failures.
287
321
  err_obj = parsed.get("error") if isinstance(parsed, dict) else None
288
- if isinstance(err_obj, dict) and _looks_like_not_found(err_obj):
289
- raise NotFoundError(
290
- f"docx-studio batch reported a partial failure: {parsed!r}",
291
- payload=err_obj,
292
- )
322
+ if isinstance(err_obj, dict):
323
+ base_msg = f"docx-studio batch reported a partial failure: {parsed!r}"
324
+ # ``BlockNotFoundError`` is the narrower miss — caller is most
325
+ # likely targeting a cell-inner paragraph or stale-session
326
+ # block id. Surface the typed exception plus an agent-readable
327
+ # workaround so the next attempt doesn't repeat the same
328
+ # mistake. The cell-paragraph hint only applies when the
329
+ # missing id has the ``paragraph:`` prefix (SuperDoc's quoted-
330
+ # id error format) — stale list-item / table-row / image ids
331
+ # would benefit from a different hint or none at all, and a
332
+ # red-herring "use cell.text" pointer would just waste the
333
+ # next retry.
334
+ if _looks_like_block_not_found(err_obj):
335
+ msg_str = err_obj.get("message")
336
+ paragraph_block = (
337
+ isinstance(msg_str, str)
338
+ and "paragraph:" in msg_str.lower()
339
+ )
340
+ raise BlockNotFoundError(
341
+ base_msg + (_CELL_PARAGRAPH_HINT if paragraph_block else ""),
342
+ payload=err_obj,
343
+ )
344
+ if _looks_like_not_found(err_obj):
345
+ raise NotFoundError(base_msg, payload=err_obj)
293
346
  raise DocxError(
294
347
  f"docx-studio batch reported a partial failure: {parsed!r}",
295
348
  )
@@ -814,8 +814,15 @@ _RESPONSE_BEARING_TYPES: frozenset[str] = frozenset(
814
814
  # CreateImage returns {image: {nodeId}}; SetImageSize and the
815
815
  # InlineShape proxy both need that nodeId, so it must flush.
816
816
  "CreateImage",
817
- # Insert sometimes returns an id; treat as response-bearing for safety.
818
- "Insert",
817
+ # Insert is INTENTIONALLY not here as of 0.8.0. All in-tree
818
+ # callers (``Paragraph._insert_run_text_segments``, ``Run.add_text``,
819
+ # ``_Cell.text``) wrap a known client-side range/cell target and
820
+ # never read Insert's response; deferring it lets a styled
821
+ # ``add_run`` flow ship its text-insert in the same HTTP batch
822
+ # as the format setters that follow it. If a future caller needs
823
+ # the Insert response, route it through ``CommandBuffer._eager_flush_with``
824
+ # at the call site rather than re-adding Insert here, so the
825
+ # batched path isn't penalized for the one outlier.
819
826
  # CreateSectionBreak intentionally NOT here — it returns no node id;
820
827
  # the caller resolves the new section via sections.list afterwards.
821
828
  # CommentsCreate returns the new comment's entityId — caller wraps
@@ -0,0 +1,88 @@
1
+ """Exception types for athena-python-docx."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ class DocxError(Exception):
7
+ """Base class for all athena-python-docx errors."""
8
+
9
+
10
+ class SessionError(DocxError):
11
+ """Raised when the Superdoc SDK session cannot be established or used."""
12
+
13
+
14
+ class AuthenticationError(SessionError):
15
+ """Raised when Keryx rejects the collab token."""
16
+
17
+
18
+ class UnsupportedProviderError(SessionError):
19
+ """Raised when the asset is on ysweet instead of yhub.
20
+
21
+ Phase 1 only supports yhub; ysweet-routed assets must be migrated first.
22
+ """
23
+
24
+
25
+ class DocumentClosedError(DocxError):
26
+ """Raised when operating on a closed Document."""
27
+
28
+
29
+ class ValidationError(DocxError):
30
+ """Raised when SDK-level validation fails (bad args, out-of-range indices)."""
31
+
32
+
33
+ class NotFoundError(DocxError):
34
+ """Raised when a server-side lookup determines that the addressed
35
+ entity does not exist (comment id, node id, …).
36
+
37
+ Distinct from :class:`DocxError` so callers can speculatively read
38
+ (``Comments.get``, future ``find_by_id`` patterns) and coerce a
39
+ typed miss to ``None`` without swallowing real transport/auth
40
+ failures.
41
+ """
42
+
43
+ def __init__(self, message: str, payload: dict | None = None) -> None:
44
+ super().__init__(message)
45
+ self.payload: dict = payload or {}
46
+
47
+
48
+ class BlockNotFoundError(NotFoundError):
49
+ """Raised when SuperDoc reports ``Block "<type>:<id>" was not found``.
50
+
51
+ Most commonly fires when paragraph-format operations target a
52
+ paragraph node nested inside a table cell. SuperDoc 1.8.1's
53
+ ``format.paragraph.setAlignment`` / ``setStyle`` / ``setIndentation``
54
+ / ``setSpacing`` and ``doc.insert``-into-block-target ops don't
55
+ traverse into table cells: the inner paragraph's id is returned by
56
+ ``cell.getNodeById`` but isn't a valid top-level addressable block.
57
+
58
+ The agent-facing workaround is:
59
+
60
+ cell.text = "value" # materializes the cell's paragraph as
61
+ # a real block once content lands.
62
+ p = cell.paragraphs[0] # the *post-materialization* paragraph
63
+ p.alignment = ... # now resolves.
64
+
65
+ See ``docx-studio/SUPERDOC_UPSTREAM_REQUESTS.md`` § "cell-inner
66
+ paragraph addressing" for the upstream ask.
67
+ """
68
+
69
+ @property
70
+ def block_id(self) -> str | None:
71
+ """Best-effort extraction of the missing block id from the SuperDoc
72
+ error message. Returns ``None`` when the prefix can't be parsed.
73
+ """
74
+ msg = self.payload.get("message")
75
+ if not isinstance(msg, str):
76
+ return None
77
+ # SuperDoc formats the message as ``Block "<type>:<uuid>" was not
78
+ # found.`` (or ``Block "<uuid>" not found.`` for some shapes) —
79
+ # extract whatever sits between the quotes, then strip an optional
80
+ # ``<type>:`` prefix so callers can compare against bare ids.
81
+ start = msg.find('"')
82
+ end = msg.find('"', start + 1) if start >= 0 else -1
83
+ if start < 0 or end <= start:
84
+ return None
85
+ quoted = msg[start + 1 : end]
86
+ if ":" in quoted:
87
+ return quoted.split(":", 1)[1]
88
+ return quoted
@@ -0,0 +1,148 @@
1
+ """Stub package — ``docx.oxml`` is intentionally unavailable in
2
+ athena-python-docx.
3
+
4
+ python-docx upstream exposes raw OOXML element classes (``OxmlElement``,
5
+ ``CT_*``, ``qn``, ``nsmap``, …) for advanced users who manipulate
6
+ Word's XML directly. athena-python-docx is backed by a SuperDoc Y.Doc
7
+ + Keryx pipeline, not a local OOXML tree, so there is no XML element
8
+ to manipulate.
9
+
10
+ Before 0.8.0 attempts to ``from docx.oxml.ns import qn`` failed with
11
+ the stdlib's generic ``ModuleNotFoundError: No module named
12
+ 'docx.oxml'`` — agent code had to discover the gap by retry. As of
13
+ 0.8.0 this package is a typed stub: every import path resolves, but
14
+ every attribute access raises :class:`OxmlNotAvailableError` with a
15
+ single actionable message pointing at the high-level python-docx
16
+ surface (``Document.add_paragraph``, ``Run.bold``, ``_Cell.text``, …)
17
+ or the typed command bus (``docx.commands``).
18
+
19
+ The gap is documented in ``docx-studio/python-sdk/CLAUDE.md`` § "Intentionally
20
+ omitted" and locked into the parity matrix via
21
+ ``tests/parity/intentional_deviations.json`` (``docx.oxml**``).
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import sys
27
+ import types
28
+ from typing import Any
29
+
30
+
31
+ class OxmlNotAvailableError(ImportError):
32
+ """Raised on any access to ``docx.oxml.*`` symbols.
33
+
34
+ Inherits :class:`ImportError` so callers using
35
+ ``try: from docx.oxml import X / except ImportError`` still match,
36
+ while ``except OxmlNotAvailableError`` lets newer code distinguish
37
+ a "no oxml surface" miss from a real import-resolution failure.
38
+ """
39
+
40
+
41
+ _MESSAGE: str = (
42
+ "docx.oxml is not available in athena-python-docx — the SuperDoc "
43
+ "backend doesn't expose raw OOXML elements. Use the high-level "
44
+ "python-docx API (Document.add_paragraph, Run.bold, _Cell.text, …) "
45
+ "or the typed command surface in docx.commands for any mutation "
46
+ "the high-level API doesn't cover. "
47
+ "See docx-studio/python-sdk/CLAUDE.md § 'Intentionally omitted' for "
48
+ "the parity rationale."
49
+ )
50
+
51
+
52
+ class _OxmlStubModule(types.ModuleType):
53
+ """ModuleType subclass that raises :class:`OxmlNotAvailableError`
54
+ on every attribute access.
55
+
56
+ Installed into :data:`sys.modules` at package-init time so
57
+ qualified imports like ``from docx.oxml.ns import qn`` find a real
58
+ module object (avoiding ``ModuleNotFoundError``) and raise the
59
+ typed exception when the symbol is dereferenced.
60
+
61
+ No ``__slots__`` — ``types.ModuleType`` itself carries a
62
+ ``__dict__``, so a slots declaration on a subclass is a no-op and
63
+ doesn't prevent ``docx.oxml.ns.qn = something`` from silently
64
+ bypassing :meth:`__getattr__` on the next read. If a future caller
65
+ needs to block that bypass we'd need a ``__setattr__`` guard that
66
+ rejects user-attribute writes while still letting the import
67
+ machinery install dunders (``__loader__``, ``__spec__``, …) on the
68
+ stub at package-init time.
69
+ """
70
+
71
+ def __getattr__(self, name: str) -> Any: # noqa: ANN401
72
+ if name.startswith("__") and name.endswith("__"):
73
+ # Dunder access (e.g. ``__path__`` during submodule import)
74
+ # must fall through to AttributeError so Python's import
75
+ # machinery can probe without triggering our typed error.
76
+ raise AttributeError(name)
77
+ path = self.__name__
78
+ raise OxmlNotAvailableError(f"{path}.{name} — {_MESSAGE}")
79
+
80
+
81
+ # Common upstream submodule paths. Listed explicitly rather than wild-
82
+ # carded so adding a new one is a visible diff. Every entry maps to a
83
+ # single sentinel module; no per-submodule state.
84
+ _SUBMODULES: tuple[str, ...] = (
85
+ "ns",
86
+ "parser",
87
+ "element",
88
+ "xmlchemy",
89
+ "exceptions",
90
+ "ooxml",
91
+ "coreprops",
92
+ "document",
93
+ "text",
94
+ "table",
95
+ "comments",
96
+ "header_footer",
97
+ "footnote",
98
+ "endnote",
99
+ "shared",
100
+ "shape",
101
+ "section",
102
+ "settings",
103
+ "styles",
104
+ "numbering",
105
+ )
106
+
107
+
108
+ def _install_stub_submodules() -> None:
109
+ """Pre-populate :data:`sys.modules` with stub entries for every
110
+ well-known ``docx.oxml.*`` submodule.
111
+
112
+ Idempotent — re-running is a no-op for entries already installed
113
+ (covers the rare case of a test that reloads the package).
114
+ """
115
+ for short in _SUBMODULES:
116
+ full = f"docx.oxml.{short}"
117
+ if full in sys.modules:
118
+ continue
119
+ sys.modules[full] = _OxmlStubModule(full)
120
+
121
+
122
+ _install_stub_submodules()
123
+
124
+
125
+ def __getattr__(name: str) -> Any: # noqa: ANN401
126
+ """PEP 562 attribute hook for ``from docx.oxml import X``.
127
+
128
+ Submodule names (handled via :data:`sys.modules` injection in
129
+ :func:`_install_stub_submodules`) and dunder names fall through to
130
+ the default ``AttributeError`` so Python's import machinery
131
+ behaves normally. Everything else raises the typed error.
132
+ """
133
+ if name.startswith("__") and name.endswith("__"):
134
+ raise AttributeError(name)
135
+ if name in _SUBMODULES:
136
+ # Should already be present in sys.modules; defensive fallback
137
+ # so we never leak ModuleNotFoundError if the caller reloaded
138
+ # the package between calls.
139
+ full = f"docx.oxml.{name}"
140
+ mod = sys.modules.get(full)
141
+ if mod is None:
142
+ mod = _OxmlStubModule(full)
143
+ sys.modules[full] = mod
144
+ return mod
145
+ raise OxmlNotAvailableError(f"docx.oxml.{name} — {_MESSAGE}")
146
+
147
+
148
+ __all__ = ["OxmlNotAvailableError"]
@@ -54,6 +54,33 @@ def _log_warn(msg: str) -> None:
54
54
  print(f"[docx-sdk] WARN: {msg}", file=sys.stderr)
55
55
 
56
56
 
57
+ # Characters that, when present, force ``_Cell.text``'s setter to round-
58
+ # trip through the server-side ``doc.markdownToFragment`` op so any
59
+ # inline markdown gets rendered into structural runs. Plain-text values
60
+ # (the common case for tabular data — numbers, labels, names) skip the
61
+ # query entirely and build the fragment locally, saving one HTTP
62
+ # round-trip per cell assignment. The set is conservative on purpose:
63
+ # ``-``, ``.``, ``,``, parentheses, currency symbols, and percent are
64
+ # considered plain so that ``cell.text = "$1,234.56 (-3.4%)"`` doesn't
65
+ # eat a round-trip.
66
+ _MARKDOWN_SPECIAL_CHARS: frozenset[str] = frozenset(
67
+ "*_~`#>[]<|\\"
68
+ )
69
+
70
+
71
+ def _is_plain_text(value: str) -> bool:
72
+ """Return True iff ``value`` contains no markdown control characters.
73
+
74
+ Used by ``_Cell.text`` to decide whether to construct the SuperDoc
75
+ paragraph fragment locally (plain text) or to defer to the
76
+ server-side ``doc.markdownToFragment`` op (anything that might
77
+ contain bold/italic/code/header/list/link/blockquote/html syntax).
78
+ """
79
+ if not value:
80
+ return True
81
+ return not any(ch in _MARKDOWN_SPECIAL_CHARS for ch in value)
82
+
83
+
57
84
  def _find_first_paragraph_id(obj: object) -> str:
58
85
  """Walk a getNodeById result to find the first paragraph nodeId."""
59
86
  if isinstance(obj, dict):
@@ -1010,10 +1037,18 @@ class _Cell:
1010
1037
  }
1011
1038
  # Superdoc only accepts block-typed fragments at the top level
1012
1039
  # (paragraph/heading/table/image/list/sectionBreak/sdt/tableOfContents).
1013
- # We convert the plain-text value through `doc.markdownToFragment`
1014
- # to get a guaranteed-valid `{kind:"paragraph", paragraph:{inlines:[...]}}`
1015
- # shape, then doc.insert appends its inline runs into the cell's
1016
- # existing paragraph (rather than adding a sibling paragraph).
1040
+ # We need to materialize ``value`` into a
1041
+ # ``{kind:"paragraph", paragraph:{inlines:[...]}}`` fragment.
1042
+ #
1043
+ # As of 0.8.0 we build the fragment locally when ``value`` has no
1044
+ # markdown-special characters — that's the dominant cell-content
1045
+ # case in practice (numeric cells, plain labels) and skipping
1046
+ # the ``doc.markdownToFragment`` query removes one eager HTTP
1047
+ # round-trip per ``cell.text = …``. Combined with
1048
+ # ``Insert`` no longer being response-bearing (0.8.0), a 30-cell
1049
+ # table assignment now ships in a single ``doc.insert`` batch
1050
+ # instead of 60 sequential round-trips. See
1051
+ # ``docx-studio/PERFORMANCE_BATCHING_ANALYSIS.md``.
1017
1052
  #
1018
1053
  # Confirmed against real staging Superdoc. This is the ONLY shape
1019
1054
  # that actually lands text inside a tableCell:
@@ -1022,17 +1057,8 @@ class _Cell:
1022
1057
  # - doc.replace + tableCell target → replaces the cell itself,
1023
1058
  # destroying the table structure
1024
1059
  try:
1025
- frag_result: object = run_sync(
1026
- session.doc.markdown_to_fragment({"markdown": value or ""}),
1027
- )
1028
- fragment: object = (
1029
- frag_result.get("fragment")
1030
- if isinstance(frag_result, dict)
1031
- else None
1032
- )
1033
- # Fall back to a hand-built fragment with Superdoc's native
1034
- # shape if markdownToFragment is unavailable.
1035
- if not isinstance(fragment, dict):
1060
+ fragment: dict
1061
+ if _is_plain_text(value):
1036
1062
  fragment = {
1037
1063
  "kind": "paragraph",
1038
1064
  "paragraph": {
@@ -1043,6 +1069,29 @@ class _Cell:
1043
1069
  ),
1044
1070
  },
1045
1071
  }
1072
+ else:
1073
+ frag_result: object = run_sync(
1074
+ session.doc.markdown_to_fragment({"markdown": value}),
1075
+ )
1076
+ resolved: object = (
1077
+ frag_result.get("fragment")
1078
+ if isinstance(frag_result, dict)
1079
+ else None
1080
+ )
1081
+ if isinstance(resolved, dict):
1082
+ fragment = resolved
1083
+ else:
1084
+ # Server didn't return a fragment — fall back to the
1085
+ # hand-built shape so we still land text rather than
1086
+ # raising.
1087
+ fragment = {
1088
+ "kind": "paragraph",
1089
+ "paragraph": {
1090
+ "inlines": [
1091
+ {"kind": "run", "run": {"text": value}},
1092
+ ],
1093
+ },
1094
+ }
1046
1095
  run_sync(
1047
1096
  session.doc.insert(
1048
1097
  {
@@ -1063,14 +1112,36 @@ class _Cell:
1063
1112
  def paragraphs(self) -> list["Paragraph"]:
1064
1113
  from docx.text.paragraph import Paragraph
1065
1114
 
1066
- return [
1067
- Paragraph(
1115
+ # Mark each Paragraph proxy as cell-inner so downstream format
1116
+ # ops that hit a SuperDoc ``Block not found`` miss can correlate
1117
+ # back to the well-known cell-paragraph addressing gap (see
1118
+ # ``BlockNotFoundError`` and ``SUPERDOC_UPSTREAM_REQUESTS.md``).
1119
+ # The flag is informational — no setter changes behavior based
1120
+ # on it yet — but it makes the connection inspectable from a
1121
+ # debugger and gives ``_apply_inline`` and friends something
1122
+ # stable to consult when we eventually add a materialization
1123
+ # fallback at the SDK layer.
1124
+ pids = self._inner_paragraph_ids()
1125
+ # Resolve the cell address ONCE and re-use it for every
1126
+ # paragraph; the original draft called ``self._cell_address()``
1127
+ # inside the loop, which hits ``_cell_id`` → ``_cell_info`` →
1128
+ # ``tables.get_cells`` per iteration. A 10-paragraph cell would
1129
+ # have eaten 10 redundant ``tables.get_cells`` round-trips just
1130
+ # to stamp identical metadata — defeats the whole point of the
1131
+ # 0.8.0 round-trip-reduction work. ``addr`` is ``None`` for an
1132
+ # empty cell so we don't issue a no-op address query in that case.
1133
+ addr = self._cell_address() if pids else None
1134
+ out: list[Paragraph] = []
1135
+ for pid in pids:
1136
+ p = Paragraph(
1068
1137
  session=self._table._session,
1069
1138
  node_id=pid,
1070
1139
  node_type="paragraph",
1071
1140
  )
1072
- for pid in self._inner_paragraph_ids()
1073
- ]
1141
+ p._cell_inner = True # type: ignore[attr-defined]
1142
+ p._cell_address = addr # type: ignore[attr-defined]
1143
+ out.append(p)
1144
+ return out
1074
1145
 
1075
1146
  @property
1076
1147
  def tables(self) -> list[Table]:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "athena-python-docx"
7
- version = "0.7.0"
7
+ version = "0.8.0"
8
8
  description = "Drop-in replacement for python-docx that connects to Athena's Superdoc/Keryx collaborative document stack"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -5,26 +5,20 @@
5
5
  "tables.get",
6
6
  "tables.get",
7
7
  "tables.getCells",
8
- "markdownToFragment",
9
8
  "insert",
10
9
  "tables.get",
11
10
  "tables.getCells",
12
- "markdownToFragment",
13
11
  "insert",
14
12
  "tables.get",
15
13
  "tables.getCells",
16
- "markdownToFragment",
17
14
  "insert",
18
15
  "tables.get",
19
16
  "tables.getCells",
20
- "markdownToFragment",
21
17
  "insert",
22
18
  "tables.get",
23
19
  "tables.getCells",
24
- "markdownToFragment",
25
20
  "insert",
26
21
  "tables.get",
27
22
  "tables.getCells",
28
- "markdownToFragment",
29
23
  "insert"
30
24
  ]
@@ -0,0 +1,4 @@
1
+ [
2
+ "create.table",
3
+ "tables.setStyle"
4
+ ]
@@ -3,31 +3,25 @@
3
3
  "tables.get",
4
4
  "tables.get",
5
5
  "tables.getCells",
6
- "markdownToFragment",
7
6
  "insert",
8
7
  "tables.get",
9
8
  "tables.get",
10
9
  "tables.getCells",
11
- "markdownToFragment",
12
10
  "insert",
13
11
  "tables.get",
14
12
  "tables.get",
15
13
  "tables.getCells",
16
- "markdownToFragment",
17
14
  "insert",
18
15
  "tables.get",
19
16
  "tables.get",
20
17
  "tables.getCells",
21
- "markdownToFragment",
22
18
  "insert",
23
19
  "tables.get",
24
20
  "tables.get",
25
21
  "tables.getCells",
26
- "markdownToFragment",
27
22
  "insert",
28
23
  "tables.get",
29
24
  "tables.get",
30
25
  "tables.getCells",
31
- "markdownToFragment",
32
26
  "insert"
33
27
  ]
@@ -3,7 +3,6 @@
3
3
  "tables.get",
4
4
  "tables.get",
5
5
  "tables.getCells",
6
- "markdownToFragment",
7
6
  "insert",
8
7
  "tables.get",
9
8
  "tables.getCells",
@@ -12,5 +11,7 @@
12
11
  "tables.get",
13
12
  "tables.getCells",
14
13
  "getNodeById",
14
+ "tables.get",
15
+ "tables.getCells",
15
16
  "getNodeById"
16
17
  ]
@@ -8,6 +8,5 @@
8
8
  "tables.get",
9
9
  "tables.get",
10
10
  "tables.getCells",
11
- "markdownToFragment",
12
11
  "insert"
13
12
  ]
@@ -6,7 +6,6 @@
6
6
  "tables.get",
7
7
  "tables.get",
8
8
  "tables.getCells",
9
- "markdownToFragment",
10
9
  "insert",
11
10
  "tables.get",
12
11
  "tables.get",