Repository navigation
Conversation
apply_table_ops could insert rows (insert_row_by_clone) but no columns. insert_column_by_clone inserts count columns right of grid column ref_col (left of it with side "left"), cloning it: - each new column is as wide as ref_col, and the table grows by it; - each new cell takes the format of the cell of the same row in ref_col, and its text unless blank is set, which leaves one empty paragraph as Hangul does; - a cell merged across the new columns grows its colSpan and width, next to a merged cell ending (on the left, starting) at ref_col each new column gets an empty cell of its format and rows, and a cell merged down ref_col is cloned with its rows; - cell zones move with their columns. Eighteen Hangul-saved files: 3x3 tables made by Hangul and the same tables after Hangul inserted columns (right, left, three, right of a wider column, merged cells across, ending at and down the column, formats per row, a table as wide as the text). With blank the inserted tables match Hangul's cell for cell, but for the stored width of a cell merged across the new column, which Hangul leaves as it was and draws by the grid. The row insertion shares its paragraph id helper (_fresh_ids). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tables written by other programs can hold hp:tc elements with their paragraphs straight inside, without hp:subList, hp:cellAddr, hp:cellSpan or hp:cellSz. Deleting a row or a column, inserting rows or columns, setting or fitting column widths and splitting the table stopped on an AssertionError there, and inserting a row or reordering rows refused it for an unrelated reason. _guard_flat, which every one of these edits calls first, now refuses such a table as it refuses one holding a table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
delete_column on the only column of a one-column table, or on every column, stopped on a ZeroDivisionError sharing out the freed width among no columns left. delete_row on every row left a table without rows and refused it only for the grid it left. Hangul does not delete the last row or column either; both now refuse and point to delete_table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
insert_row_by_clone inserted rows below ref_row only, keeping the text of the cells it clones. It now takes side "above" to insert before the row, and blank to leave each new cell one empty paragraph of its format as Hangul does: - each new row is as high as ref_row, and each new cell takes the format of the cell of the same column in ref_row, a cell merged across columns there included; - above the row, a cell merged across the new rows grows its rowSpan over them, and over a merged cell starting at ref_row each new row gets an empty cell of its format, as below the row for one ending there; - cell zones now move with their rows, below the row too. Twenty Hangul-saved files: 3x3 tables made by Hangul and the same tables after Hangul inserted rows (below, above, three, next to a taller row, merged cells across, ending at and starting at the row, a cell merged across columns, formats per column). With blank the inserted tables match Hangul's cell for cell; Hangul also stores the table's laid-out height anew, which python-hwpx leaves as it was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
delete_row and delete_column left the table's hp:cellzone entries where they were, so a zone drew its border fill on the cells that moved into its rows or columns. A zone now keeps the lines it covers that stay, moved back over the deleted ones before it, and goes when none stays; the zone list goes with its last zone, as OWPML wants one in it. A row the column deletion leaves without cells folds its zones into its neighbours, as a cell merge folds such a line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
apply_table_ops could split a cell merged down several rows back into stacked cells (split_cell_vertical), but not split a cell into columns or a single row into several. split_cell takes the cell's row and col and rows and/or cols (2..63): - into columns the cell's width is shared out evenly, the last part taking what is left over; new grid lines go where the parts end, and every other cell keeps its width over the grid columns it now covers; - into rows the parts take the rows the cell covers when they divide evenly, else one row each and as many new rows after its last as it lacks, which the cells beside that row grow over; the parts share out the cell's stored height evenly; - the content stays in the first part, and the others hold one empty paragraph of the cell's format; cell zones keep the area they cover. Nineteen Hangul-saved files: 3x3 tables made by Hangul and the same tables after Hangul split a cell (into two and three columns and rows, both, in a wider column and a taller row, merged across columns and down rows, a formatted cell). Column splits and the even split of a taller row match Hangul's cell for cell. For rows lower than their content Hangul stores heights from the content (0 or less for the last part) and lays the cells out to their content either way. _drop_line_caches is split out of _blank_cell_text for the first part. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e table object The table object had merge_cells and split_merged_cell but no row or column insertion or deletion and no cell split; those were only on the byte path (apply_table_ops). HwpxOxmlTable (hwpx.model.Table) now has insert_rows (below or above), insert_columns (right or left), delete_rows, delete_columns and split_cell, and doc.tables the same names taking the table first. Each runs the matching edit of apply_table_ops on the table's XML (_restructure_table, which apply_table_ops now uses as well) and puts the result back into the table element, so both paths follow one set of rules: those of Hangul's own row and column insertion and deletion and cell split. New paragraphs take ids unused anywhere in the document. The paragraph holding the table loses its line cache, and cells taken from the table before an edit no longer belong to it. The methods live in oxml/table_structure.py (TableStructureEdits, a mixin of HwpxOxmlTable), as table.py sits at its line cap; the module is registered in module-ownership.json and born in the type gate. The model surface lock lists the five as stable members of Table (docs/stable-api.md counts them), and the import breadth bound rises to 98: HwpxOxmlTable inherits the mixin, so its module loads with the table module, while the edits themselves (table_patch) load on first use. Tests run the edits through the object model on the Hangul-saved tables of the byte-path tests and against apply_table_ops itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
바뀐 점
표 객체(
hwpx.model.Table, 곧HwpxOxmlTable)에는 칸 합치기(merge_cells)와 합친 칸 풀기(split_merged_cell)만 있었다. 행·열을 넣거나 지우는 것과 칸 나누기는 바이트 경로(apply_table_ops)에만 있었다. 이제 표 객체에도 다섯 메서드가 있다.apply_table_ops의 같은 편집과 같다(insert_row_by_clone,insert_column_by_clone,delete_row,delete_column,split_cell). 한/글의 줄/칸 추가하기·지우기, 셀 나누기를 따른다.blank=True면 한/글처럼 그 서식의 빈 문단 하나만 둔다.hp:cellzone)도 함께 옮긴다.TableStructureError를 내고 표를 그대로 둔다.코드
oxml/table_structure.py(새 모듈)TableStructureEdits:HwpxOxmlTable의 믹스인.apply_table_ops의 편집을 적용하고, 결과를 표 요소에 제자리로 돌려놓는다.table.py가 줄 수 상한에 닿아 새 모듈로 뺐다.docs/architecture/module-ownership.json에 등록하고, 형식 검사 범위(pyproject.toml)에 넣었다.oxml/table.py:class HwpxOxmlTable(TableStructureEdits)(+1줄).table_patch.py:_restructure_table(표 하나에 구조 편집 하나를 적용하고 격자를 검사).apply_table_ops도 이것을 쓴다._document/ns/tables.py:doc.tables의 다섯 위임 메서드.capabilities.py: 표 구조 영역의 진입점에hwpx.model:Table.docs/api_reference.md, 지원 표(두 벌), 변경 로그.tests/test_product_boundary.py(분류 모듈 수 181),tests/test_namespace_hygiene.py(doc.tables동사).tests/data/model_surface.json: 다섯 메서드를Table의 안정(stable) 멤버로 넣었다.docs/stable-api.md의 멤버 수는 198이 되고, 설명 한 단락을 더했다.tests/data/import_breadth.json:import hwpx가 읽는 hwpx 모듈 상한을 97 → 98로 올렸다.table_patch)는 처음 편집할 때 읽는다.table.py에 둘 수 없는 이유는 줄 수 상한이다.테스트
tests/test_table_structure_edits.py를 더한다.apply_table_ops와의 대조(7판): 합친 칸이 있는 표에서 두 경로의 결과 칸이 같은지 본다.doc.tables메서드, 다시 연 문서.이 PR은 #432 위에 쌓았다(#430 → #431 → #432). 앞 PR이 병합되면 그 커밋들은 이 PR의 diff에서 빠진다.
🤖 Generated with Claude Code