authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-09-12 15:01:41-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-09-12 17:00:32-07:00
log23f0f23fc7064901d2942eb0d0ff5c4adea3afd6
tree995e5c9e952f234bbef5d231b7cb29caf50ccde7
parentebed33c87eab2e83fb48269388f22950d118ea53
signature Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU

feat: edit cell shading and indents and nest tables through the page model

Shading and indents change in place on a stored cell: the writer sets or removes the documented CellShadingColor and the indent array on the cell object. OneNote 2010 stores the shading property but neither renders it nor accepts it through its COM schema (corpus/m6/cell-shading-control-01 already records both), so the property is written as documented without a native rendering claim. Cell layout still stays fixed, as OneNote sizes cells itself. A table inside a cell paragraph needed no new lowering: the placement and structure passes already recurse through cells. corpus/table-edit/nested is the native gate, a one-column table written into a cell of the native tree fixture and cold-read by OneNote 2010 with both tables; tools/test_table_edit.py checks it without a VM. Assisted-by: claude-fable-5.1

32 files changed, 462 insertions(+), 9 deletions(-)

corpus/table-edit/README.md+11-4
...@@ -16,13 +16,20 @@ of three cells. `edited/cold` is its cold read: the native columns keep their...@@ -16,13 +16,20 @@ of three cells. `edited/cold` is its cold read: the native columns keep their
16widths and locks, OneNote sizes the unlocked column to its content, and the16widths and locks, OneNote sizes the unlocked column to its content, and the
17new row and cells read back with their text.17new row and cells read back with their text.
1818
19`nested/candidate` is the writer's output for
20`a_table_nests_inside_a_cell_and_is_removed_again` on the same tree fixture:
21the second cell of the native table gains a paragraph holding a one-column,
22two-row table with locked 72 pt column and visible borders. `nested/cold` is
23its cold read with both tables.
24
19Native rows and cells are plain containers; the writer creates them with the25Native rows and cells are plain containers; the writer creates them with the
20modification time, the indent array copied from a sibling cell, and the flags26modification time, the indent array copied from a sibling cell, and the flags
21every native cell carries, rebuilds each table's row and cell order to the27every native cell carries, rebuilds each table's row and cell order to the
22model's, and writes the column count, widths, locks and border flag. New28model's, and writes the column count, widths, locks and border flag. New
23tables start as an empty paragraph whose content the structure pass replaces.29tables start as an empty paragraph whose content the structure pass replaces.
24An emptied cell keeps a replacement paragraph, as the tree writer provides.30An emptied cell keeps a replacement paragraph, as the tree writer provides.
25`tools/test_table_edit.py` checks both captures without a VM. Regenerate with31`tools/test_table_edit.py` checks all three captures without a VM. Regenerate
26`ONESTORE_TABLE_EXPORT` and `ONESTORE_TABLE_EDIT_EXPORT` set to new absolute32with `ONESTORE_TABLE_EXPORT`, `ONESTORE_TABLE_EDIT_EXPORT` and
27directories while running the tests, then cold-open them with33`ONESTORE_NESTED_TABLE_EXPORT` set to new absolute directories while running
28`tools/native_runner.py OUTPUT COLD --expected-pages 1|12 --collect-notebook`.34the tests, then cold-open them with `tools/native_runner.py OUTPUT COLD
35--expected-pages 1|12 --collect-notebook`.
corpus/table-edit/nested/candidate/Open Notebook.onetoc2 created
Binary files /dev/null and b/corpus/table-edit/nested/candidate/Open Notebook.onetoc2 differ
corpus/table-edit/nested/candidate/synthetic.one created
Binary files /dev/null and b/corpus/table-edit/nested/candidate/synthetic.one differ
corpus/table-edit/nested/cold/commands.jsonl created+3
...@@ -0,0 +1,3 @@
1{"command": "powershell -NoProfile -Command \"Expand-Archive -LiteralPath C:\\one-tests\\transfer.zip -DestinationPath C:\\one-tests\\runs\\capture\\notebook\"", "exit": 0, "stdout": "", "stderr": "", "error": null}
2{"command": "powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File C:\\one-tests\\read-current.ps1 -Root C:\\one-tests\\runs\\capture -CloneHost ONE-M6-8E63A852 -ExpectedPages 12", "exit": 0, "stdout": "Read 1 sections and 12 pages.\r\n", "stderr": "", "error": null}
3{"command": "powershell -NoProfile -Command \"Compress-Archive -Force -Path C:\\one-tests\\runs\\capture\\* -DestinationPath C:\\one-tests\\captured.zip\"", "exit": 0, "stdout": "", "stderr": "", "error": null}
corpus/table-edit/nested/cold/machine.json created+1
...@@ -0,0 +1 @@
1{"name": "m6-8e63a852", "hostname": "ONE-M6-8E63A852"}
corpus/table-edit/nested/cold/notebook/Open Notebook.onetoc2 created
Binary files /dev/null and b/corpus/table-edit/nested/cold/notebook/Open Notebook.onetoc2 differ
corpus/table-edit/nested/cold/notebook/synthetic.one created
Binary files /dev/null and b/corpus/table-edit/nested/cold/notebook/synthetic.one differ
corpus/table-edit/nested/cold/read/environment.json created+7
...@@ -0,0 +1,7 @@
1{
2 "powershell": "5.1.14409.1005",
3 "schema": "xs2010",
4 "hostname": "ONE-M6-8E63A852",
5 "cold": true,
6 "onenote": "14.0.4763.1000"
7}
corpus/table-edit/nested/cold/read/hierarchy.xml created+2
...@@ -0,0 +1,2 @@
1<?xml version="1.0"?>
2<one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{D5C61ACD-0C18-47AB-9BB7-EA0453092F1A}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-12T21:55:30.000Z" color="#B49EDE"><one:Section name="synthetic" ID="{DCA72CDB-70D0-04AA-3F56-92B886A9FA01}{1}{B0}" path="C:\one-tests\runs\capture\notebook\synthetic.one" lastModifiedTime="2026-09-12T21:55:30.000Z" color="#8AA8E4"><one:Page ID="{F0EEDF5D-F91B-47BB-B831-3A297A91E61E}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{C131A2C2-2BC5-4502-8CFF-F5FCAC5673F9}{1}{B0}" name="Indent first subtree" dateTime="2026-09-08T19:25:53.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{80C90902-0F49-4C7B-8E7F-596216EE4379}{1}{B0}" name="Outdent first group" dateTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{B78DF4E7-9F1A-454E-BE5B-F35A57E182C9}{1}{B0}" name="Delete only grouped subtree" dateTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{F0F484B0-2100-4784-B9E5-4A8B81EF98E2}{1}{B0}" name="Delete unindented sibling after group" dateTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{56E30880-7E3F-485A-BAC8-09FC9BA6B44B}{1}{B0}" name="Delete cell subtree" dateTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{D1132B3D-E3A6-4819-8341-86F33DC7D2E2}{1}{B0}" name="Delete sole cell paragraph" dateTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{676EECC9-3E35-4A9E-AF43-A9882BDDAC59}{1}{B0}" name="Move numbered subtree down" dateTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{E63E6C84-AAC4-4272-82DB-0820DBFF5E89}{1}{B0}" name="Delete numbered subtree" dateTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{8C93E36A-F0C0-4425-A30B-B2B8A0719684}{1}{B0}" name="Indent bullet subtree" dateTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{789DA77C-5409-4002-B4AC-695817E35153}{1}{B0}" name="Outdent child across indentation gap" dateTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/><one:Page ID="{A04B2BEA-D010-4C40-BAAC-F5BDB53D09E0}{1}{B0}" name="Move cell subtree down" dateTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1"/></one:Section></one:Notebook>
corpus/table-edit/nested/cold/read/page-000.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{56E30880-7E3F-485A-BAC8-09FC9BA6B44B}{1}{B0}" name="Delete cell subtree" dateTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Delete cell subtree]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="428.1300048828125" height="62.30315780639648"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{40}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{41}{B0}"><one:Columns><one:Column index="0" width="240.0" isLocked="true"/><one:Column index="1" width="180.0" isLocked="true"/></one:Columns><one:Row objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{42}{B0}" lastModifiedTime="2026-09-12T21:53:40.000Z"><one:Cell lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{43}{B0}" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{46}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{55}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{61}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{66}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Cell tail]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{71}{B0}" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{74}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other cell]]></one:T></one:OE><one:OE author="Table author" lastModifiedBy="Table author" creationTime="2026-09-12T21:53:40.000Z" lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{DFC0C49E-E046-0AFB-1BF8-ABC555E425B9}{0}{B0}" alignment="left" style="font-family:Calibri;font-size:11.0pt"><one:Table bordersVisible="true" lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{89987300-2101-0CE3-210D-9562C6C4ADB1}{0}{B0}"><one:Columns><one:Column index="0" width="72.0" isLocked="true"/></one:Columns><one:Row objectID="{CF32A2C1-04E7-0743-39C0-9C765A8E44CC}{0}{B0}" lastModifiedTime="2026-09-12T21:53:40.000Z"><one:Cell lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{1BAB3712-BACF-009D-0E46-EBA95350D396}{0}{B0}"><one:OEChildren><one:OE creationTime="2026-09-12T21:53:40.000Z" lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{82BC0B4C-FCA6-0778-2A66-7B5A5496D0A5}{0}{B0}" alignment="left"><one:T><![CDATA[Inner one]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row><one:Row objectID="{A337C7AB-1858-0A2B-34E0-881F2933D0FB}{0}{B0}" lastModifiedTime="2026-09-12T21:53:40.000Z"><one:Cell lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{6E7D1347-DF88-06E2-392D-6543DAD4FBFE}{0}{B0}"><one:OEChildren><one:OE creationTime="2026-09-12T21:53:40.000Z" lastModifiedTime="2026-09-12T21:53:40.000Z" objectID="{5E489B68-01D9-0719-0234-7A5E46894E1A}{0}{B0}" alignment="left"><one:T><![CDATA[Inner two]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{79}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{C8D3C6B7-FB34-46C1-B4B5-3FE5439E350E}{80}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-001.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{676EECC9-3E35-4A9E-AF43-A9882BDDAC59}{1}{B0}" name="Move numbered subtree down" dateTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Move numbered subtree down]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="142.6107788085937" height="67.13858032226562"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{40}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="I."/></one:List><one:T><![CDATA[Anchor]]></one:T></one:OE><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{46}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="II."/></one:List><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{55}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{61}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{67}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{73}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0D5508DA-3F74-4EFD-8A2C-68449D01A988}{74}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-002.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{789DA77C-5409-4002-B4AC-695817E35153}{1}{B0}" name="Outdent child across indentation gap" dateTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Outdent child across indentation gap]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="196.6107788085937" height="80.56629943847656"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Anchor]]></one:T><one:OEChildren indent="2"><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{45}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{54}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{60}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{65}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{70}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{76}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{5DAD8763-3535-46F5-8981-F32E9714936D}{77}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-003.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{80C90902-0F49-4C7B-8E7F-596216EE4379}{1}{B0}" name="Outdent first group" dateTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{1BBE628F-87A8-4B93-B54E-9137D9FD93C3}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Outdent first group]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{1BBE628F-87A8-4B93-B54E-9137D9FD93C3}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="169.6107788085937" height="53.71086883544922"/><one:OEChildren indent="2"><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{1BBE628F-87A8-4B93-B54E-9137D9FD93C3}{40}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{1BBE628F-87A8-4B93-B54E-9137D9FD93C3}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{1BBE628F-87A8-4B93-B54E-9137D9FD93C3}{55}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE></one:OEChildren><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{1BBE628F-87A8-4B93-B54E-9137D9FD93C3}{60}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{1BBE628F-87A8-4B93-B54E-9137D9FD93C3}{66}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{1BBE628F-87A8-4B93-B54E-9137D9FD93C3}{67}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-004.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{8C93E36A-F0C0-4425-A30B-B2B8A0719684}{1}{B0}" name="Indent bullet subtree" dateTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Indent bullet subtree]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="142.6107788085937" height="67.13858032226562"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{40}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[Anchor]]></one:T></one:OE><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{46}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{55}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{61}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{67}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{73}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{B5B89198-15DB-4C07-BF58-7E58B020F589}{74}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-005.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{A04B2BEA-D010-4C40-BAAC-F5BDB53D09E0}{1}{B0}" name="Move cell subtree down" dateTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Move cell subtree down]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="428.1300048828125" height="62.23086929321289"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{40}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{41}{B0}"><one:Columns><one:Column index="0" width="240.0" isLocked="true"/><one:Column index="1" width="180.0" isLocked="true"/></one:Columns><one:Row objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{42}{B0}" lastModifiedTime="2026-09-08T19:26:01.000Z"><one:Cell lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{43}{B0}" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{46}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{55}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{61}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{66}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Cell tail]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{71}{B0}" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{74}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other cell]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{79}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{CB7E7F98-8FDF-4EC8-948F-FD54A192325F}{80}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-006.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{B78DF4E7-9F1A-454E-BE5B-F35A57E182C9}{1}{B0}" name="Delete only grouped subtree" dateTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{A8913014-4EC8-484A-88B2-8A57E3AC8A3D}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Delete only grouped subtree]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{A8913014-4EC8-484A-88B2-8A57E3AC8A3D}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="169.6107788085937" height="53.71086883544922"/><one:OEChildren indent="2"><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{A8913014-4EC8-484A-88B2-8A57E3AC8A3D}{40}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{A8913014-4EC8-484A-88B2-8A57E3AC8A3D}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{A8913014-4EC8-484A-88B2-8A57E3AC8A3D}{55}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE></one:OEChildren><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{A8913014-4EC8-484A-88B2-8A57E3AC8A3D}{60}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{A8913014-4EC8-484A-88B2-8A57E3AC8A3D}{66}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{A8913014-4EC8-484A-88B2-8A57E3AC8A3D}{67}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-007.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{C131A2C2-2BC5-4502-8CFF-F5FCAC5673F9}{1}{B0}" name="Indent first subtree" dateTime="2026-09-08T19:25:53.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{0E6415D5-ECAA-442C-AED2-B0701782A11F}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Indent first subtree]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0E6415D5-ECAA-442C-AED2-B0701782A11F}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="142.6107788085937" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:54.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{0E6415D5-ECAA-442C-AED2-B0701782A11F}{40}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{0E6415D5-ECAA-442C-AED2-B0701782A11F}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{0E6415D5-ECAA-442C-AED2-B0701782A11F}{55}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{0E6415D5-ECAA-442C-AED2-B0701782A11F}{60}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{0E6415D5-ECAA-442C-AED2-B0701782A11F}{65}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-08T19:25:55.000Z" objectID="{0E6415D5-ECAA-442C-AED2-B0701782A11F}{66}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-008.xml created+4
...@@ -0,0 +1,4 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{D1132B3D-E3A6-4819-8341-86F33DC7D2E2}{1}{B0}" name="Delete sole cell paragraph" dateTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{17}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Delete sole cell paragraph]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{23}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="428.1300048828125" height="21.94771385192871"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{24}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{25}{B0}"><one:Columns><one:Column index="0" width="240.0" isLocked="true"/><one:Column index="1" width="180.0" isLocked="true"/></one:Columns><one:Row objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{26}{B0}" lastModifiedTime="2026-09-08T19:26:01.000Z"><one:Cell lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{27}{B0}" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{30}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{39}{B0}" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{42}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other cell]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{47}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{3A6D0DF0-19C6-4437-A72B-CD2D5D8EDAB7}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-009.xml created+5
...@@ -0,0 +1,5 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{E63E6C84-AAC4-4272-82DB-0820DBFF5E89}{1}{B0}" name="Delete numbered subtree" dateTime="2026-09-08T19:25:57.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Delete numbered subtree]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="142.6107788085937" height="67.13858032226562"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{40}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="I."/></one:List><one:T><![CDATA[Anchor]]></one:T></one:OE><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{46}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="II."/></one:List><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{55}{B0}" alignment="left" quickStyleIndex="0"><one:T style="font-family:Calibri;font-size:11.0pt"><![CDATA[<span
5style='font-style:italic'>Child</span>]]></one:T><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{61}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Grandchild]]></one:T></one:OE></one:OEChildren></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{67}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[Trailing sibling]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:26:01.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{73}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:58.000Z" lastModifiedTime="2026-09-08T19:25:58.000Z" objectID="{D89C2513-8081-4B38-ADDB-D4796BE57B6D}{74}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-010.xml created+20
...@@ -0,0 +1,20 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{F0EEDF5D-F91B-47BB-B831-3A297A91E61E}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Rich author" lastModifiedBy="Rich author" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{972277E1-B26E-440D-B7C3-B6F2850D037F}{10}{B0}"><one:Position x="36.0" y="14.40000057220459" z="0"/><one:Size width="127.5136947631836" height="42.90299224853515"/><one:OEChildren><one:OE creationTime="2026-09-08T04:47:24.000Z" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{9047DF16-4113-0F07-0797-75F84E667189}{1}{B0}" alignment="left"><one:T><![CDATA[<span style='font-weight:bold;
3text-decoration:underline;font-family:Calibri;font-size:11.0pt'>Bold</span><span
4style='font-family:Calibri;font-size:11.0pt'> </span><span style='font-family:
5Arial;font-size:13.5pt'>&#129408;</span><span style='font-family:Calibri;
6font-size:11.0pt'> </span><span style='font-style:italic;text-decoration:line-through;
7font-family:Calibri;font-size:11.0pt'>italic</span><span style='font-family:
8Calibri;font-size:11.0pt'> </span><span style='vertical-align:super;font-family:
9Calibri;font-size:11.0pt'>é</span><span style='font-family:Calibri;font-size:
1011.0pt'> </span><span style='font-family:Calibri;font-size:11.0pt;color:#0C2238;
11background:yellow;mso-highlight:yellow'>color</span><span style='font-family:
12Calibri;font-size:11.0pt'> </span><span style='vertical-align:sub;font-family:
13Calibri;font-size:11.0pt'>東京</span><span style='font-family:Calibri;font-size:
1411.0pt'><br>
15End</span>]]></one:T></one:OE><one:OE author="snow" authorInitials="S" lastModifiedBy="snow" lastModifiedByInitials="S" creationTime="2026-09-05T05:06:55.000Z" lastModifiedTime="2026-09-05T05:06:56.000Z" objectID="{972277E1-B26E-440D-B7C3-B6F2850D037F}{11}{B0}" alignment="left" quickStyleIndex="0" style="font-size:11.0pt;color:#1F4E79"><one:T><![CDATA[<span
16style='font-weight:bold;font-family:Calibri' lang=en-US>Fictitious: café, </span><span
17style='font-weight:bold;font-family:SimSun' lang=en-US>東京</span><span
18style='font-weight:bold;font-family:Calibri' lang=en-US>, </span><span
19style='font-weight:bold;font-family:Arial;direction:rtl;unicode-bidi:embed'
20lang=ar-SA>مرحبا</span>]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/page-011.xml created+4
...@@ -0,0 +1,4 @@
1<?xml version="1.0"?>
2<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{F0F484B0-2100-4784-B9E5-4A8B81EF98E2}{1}{B0}" name="Delete unindented sibling after group" dateTime="2026-09-08T19:25:55.000Z" lastModifiedTime="2026-09-12T21:55:19.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Preserved task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{81A62340-0F2E-42B2-9749-B51DDC107DBD}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Delete unindented sibling after group]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{81A62340-0F2E-42B2-9749-B51DDC107DBD}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="129.6621246337891" height="26.85543441772461"/><one:OEChildren indent="2"><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{81A62340-0F2E-42B2-9749-B51DDC107DBD}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Anchor]]></one:T></one:OE></one:OEChildren><one:OEChildren><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{81A62340-0F2E-42B2-9749-B51DDC107DBD}{45}{B0}" alignment="left" quickStyleIndex="0"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span
3style='font-weight:bold' lang=en-US>Target &#129408; é</span><span lang=en-US> </span><a
4href="https://example.invalid/tree"><span lang=x-none>Link label</span></a>]]></one:T></one:OE></one:OEChildren></one:Outline><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T19:25:57.000Z" objectID="{81A62340-0F2E-42B2-9749-B51DDC107DBD}{55}{B0}"><one:Position x="540.0" y="108.0" z="1"/><one:Size width="99.85796356201171" height="13.42771339416504"/><one:OEChildren><one:OE creationTime="2026-09-08T19:25:56.000Z" lastModifiedTime="2026-09-08T19:25:56.000Z" objectID="{81A62340-0F2E-42B2-9749-B51DDC107DBD}{56}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Other outline]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page>
corpus/table-edit/nested/cold/read/payloads.json created+3
...@@ -0,0 +1,3 @@
1[
2
3]
\ No newline at end of file
corpus/table-edit/nested/cold/run.json created+18
...@@ -0,0 +1,18 @@
1{
2 "notebook": "/private/tmp/m4/nested",
3 "expected_pages": 12,
4 "author": null,
5 "author_timeout_seconds": 600,
6 "inspect": false,
7 "collect_notebook": true,
8 "base": {
9 "file": "win7-office-base.qcow2",
10 "format": "qcow2",
11 "sha256": "a1a4f8fab782ee14885ff801ca2f6347c208fdcfc3513637096f314315c89346",
12 "virtual_size": 68719476736
13 },
14 "scripts": {
15 "cold.ps1": "c177fc72ae6c2634d186f5671a880de20b09f9716532c37c69cb13aa15c7e331",
16 "read.ps1": "04013bfcccee40a17e2a225f9b9e96f40a3a8daad9e350609654f8eda3ccbb41"
17 }
18}
corpus/table-edit/nested/cold/scripts/cold.ps1 created+27
...@@ -0,0 +1,27 @@
1param([Parameter(Mandatory=$true)][string]$Root, [string]$CloneHost = '')
2Set-StrictMode -Version Latest
3$ErrorActionPreference = 'Stop'
4$root = [IO.Path]::GetFullPath($Root).TrimEnd('\')
5if ([IO.Path]::GetDirectoryName($root) -ne 'C:\one-tests\runs') {
6 throw 'Choose a run directly below C:\one-tests\runs.'
7}
8if (Get-Process ONENOTE -ErrorAction SilentlyContinue) { throw 'Close OneNote before resetting its test cache.' }
9$key = 'HKCU:\Software\Microsoft\Office\14.0\OneNote'
10if ($CloneHost) {
11 if ($CloneHost -notmatch '^ONE-[A-Z0-9-]+$' -or [Environment]::MachineName -ne $CloneHost) {
12 throw 'The disposable clone hostname does not match this machine.'
13 }
14 New-Item "$key\Options\Paths" -Force | Out-Null
15 New-ItemProperty "$key\Options\Paths" -Name UnfiledNotesSection -PropertyType ExpandString -Value 'C:\one-tests\Loose.one' -Force | Out-Null
16} elseif ((Get-ItemProperty "$key\Options\Paths").UnfiledNotesSection -ne 'C:\one-tests\Loose.one' -or
17 -not (Test-Path 'C:\one-tests\profile-original-cache')) {
18 throw 'Park the personal OneNote profile before resetting the test cache.'
19}
20$cache = Join-Path $env:LOCALAPPDATA 'Microsoft\OneNote\14.0'
21$parked = Join-Path 'C:\one-tests\caches' ([IO.Path]::GetFileName($root))
22if (Test-Path $parked) { throw 'Choose a new run; its parked cache already exists.' }
23New-Item -ItemType Directory -Path 'C:\one-tests\caches' -Force | Out-Null
24if (Test-Path $cache) { Move-Item -LiteralPath $cache -Destination $parked }
25if (Test-Path "$key\OpenNotebooks") { Remove-Item "$key\OpenNotebooks" -Recurse }
26New-Item "$key\OpenNotebooks" | Out-Null
27New-ItemProperty "$key\OpenNotebooks" -Name '1' -PropertyType String -Value "$root\notebook" | Out-Null
corpus/table-edit/nested/cold/scripts/read.ps1 created+142
...@@ -0,0 +1,142 @@
1param(
2 [Parameter(Mandatory=$true)][string]$Root,
3 [int]$ExpectedPages = -1,
4 [switch]$UseCurrentCache,
5 [switch]$Pdf,
6 [switch]$KeepOpen,
7 [string]$CloneHost = ''
8)
9Set-StrictMode -Version Latest
10$ErrorActionPreference = 'Stop'
11$root = [IO.Path]::GetFullPath($Root).TrimEnd('\')
12if ([IO.Path]::GetDirectoryName($root) -ne 'C:\one-tests\runs') {
13 throw 'Choose a run directly below C:\one-tests\runs.'
14}
15$notebook = Join-Path $root 'notebook'
16$output = Join-Path $root 'read'
17if (Test-Path $output) { throw 'Choose a new read destination.' }
18if ($UseCurrentCache) {
19 if ((Get-ItemProperty 'HKCU:\Software\Microsoft\Office\14.0\OneNote\Options\Paths').UnfiledNotesSection -ne 'C:\one-tests\Loose.one') {
20 throw 'Park the personal OneNote profile before reading test notebooks.'
21 }
22} else {
23 & "$PSScriptRoot\cold-current.ps1" -Root $root -CloneHost $CloneHost
24}
25New-Item -ItemType Directory -Path $output | Out-Null
26$app = New-Object -ComObject OneNote.Application
27$notebookId = ''
28$failure = $null
29try {
30 $app.OpenHierarchy($notebook, '', [ref]$notebookId, 0)
31 $process = Get-Process ONENOTE
32 @{ hostname = [Environment]::MachineName; onenote = $process.MainModule.FileVersionInfo.FileVersion;
33 powershell = $PSVersionTable.PSVersion.ToString(); schema = 'xs2010'; cold = (-not $UseCurrentCache.IsPresent) } |
34 ConvertTo-Json | Set-Content (Join-Path $output 'environment.json') -Encoding UTF8
35 $sections = @()
36 foreach ($file in @(Get-ChildItem $notebook -Recurse | Where-Object { $_.Extension -eq '.one' })) {
37 $id = ''
38 $app.OpenHierarchy($file.FullName, '', [ref]$id, 0)
39 $sections += $id
40 }
41 $deadline = [DateTime]::UtcNow.AddSeconds(300)
42 $previous = ''
43 $lastChange = ''
44 $stableSince = [DateTime]::UtcNow
45 $settled = $false
46 do {
47 $pages = @{}
48 foreach ($section in $sections) {
49 $hierarchy = ''
50 $app.GetHierarchy($section, 4, [ref]$hierarchy, 1)
51 [xml]$xml = $hierarchy
52 foreach ($node in $xml.SelectNodes('//*[@path]')) {
53 if (-not $node.GetAttribute('path').StartsWith("$notebook\", [StringComparison]::OrdinalIgnoreCase)) {
54 throw 'OneNote opened a section outside the copied notebook.'
55 }
56 }
57 foreach ($node in $xml.SelectNodes('//*[local-name()="Page"]')) {
58 $id = $node.GetAttribute('ID')
59 $content = ''
60 $app.GetPageContent($id, [ref]$content, 1, 1)
61 $pages[$id] = $content
62 }
63 }
64 $signature = [String]::Join('|', @($pages.Keys | Sort-Object | ForEach-Object { $_ + $pages[$_] }))
65 if ($signature -ne $previous) {
66 $lastChange = $previous
67 $previous = $signature
68 $stableSince = [DateTime]::UtcNow
69 }
70 if ((($ExpectedPages -ge 0 -and $pages.Count -eq $ExpectedPages) -or
71 ($ExpectedPages -lt 0 -and $pages.Count -gt 0)) -and
72 ([DateTime]::UtcNow - $stableSince).TotalSeconds -ge 2) { $settled = $true; break }
73 Start-Sleep -Milliseconds 250
74 } while ([DateTime]::UtcNow -lt $deadline)
75 if (-not $settled -or ($ExpectedPages -ge 0 -and $pages.Count -ne $ExpectedPages) -or ($ExpectedPages -lt 0 -and $pages.Count -eq 0)) {
76 [IO.File]::WriteAllText((Join-Path $output 'previous-signature.txt'), $lastChange, [Text.Encoding]::UTF8)
77 $index = 0
78 foreach ($id in @($pages.Keys | Sort-Object)) {
79 [IO.File]::WriteAllText((Join-Path $output ('unsettled-{0:d3}.xml' -f $index)), $pages[$id], [Text.Encoding]::UTF8)
80 $index++
81 }
82 $hierarchy = ''
83 $app.GetHierarchy($notebookId, 4, [ref]$hierarchy, 1)
84 [IO.File]::WriteAllText((Join-Path $output 'unsettled-hierarchy.xml'), $hierarchy, [Text.Encoding]::UTF8)
85 throw "Expected $ExpectedPages stable pages; OneNote returned $($pages.Count), settled=$settled."
86 }
87 $index = 0
88 $payloads = @()
89 foreach ($id in @($pages.Keys | Sort-Object)) {
90 [IO.File]::WriteAllText((Join-Path $output ('page-{0:d3}.xml' -f $index)), $pages[$id], [Text.Encoding]::UTF8)
91 if ($Pdf) {
92 $pdfPath = Join-Path $output ('page-{0:d3}.pdf' -f $index)
93 $app.NavigateTo($id, '', $false)
94 $app.Publish($id, $pdfPath, 3, '')
95 if (-not (Test-Path $pdfPath) -or (Get-Item $pdfPath).Length -eq 0) { throw 'OneNote did not publish the page PDF.' }
96 }
97 [xml]$page = $pages[$id]
98 foreach ($file in $page.SelectNodes('//*[local-name()="InsertedFile" or local-name()="MediaFile"]')) {
99 $bytes = [IO.File]::ReadAllBytes($file.GetAttribute('pathCache'))
100 $hash = [BitConverter]::ToString([Security.Cryptography.SHA256]::Create().ComputeHash($bytes)).Replace('-', '').ToLowerInvariant()
101 [IO.File]::WriteAllBytes((Join-Path $output ($hash + '.attachment')), $bytes)
102 $payloads += @{ page = $id; object = $file.ParentNode.GetAttribute('objectID');
103 kind = $file.LocalName; name = $file.GetAttribute('preferredName');
104 sha256 = $hash; bytes = $bytes.Length }
105 }
106 $index++
107 }
108 [IO.File]::WriteAllText((Join-Path $output 'payloads.json'), (ConvertTo-Json -InputObject $payloads -Depth 4), [Text.Encoding]::UTF8)
109 $all = ''
110 $app.GetHierarchy($notebookId, 4, [ref]$all, 1)
111 [xml]$finalTree = $all
112 $finalIds = @($finalTree.SelectNodes('//*[local-name()="Page"]') | ForEach-Object { $_.GetAttribute('ID') } | Sort-Object -Unique)
113 if ($finalIds.Count -ne $pages.Count -or @($finalIds | Where-Object { -not $pages.ContainsKey($_) }).Count -ne 0) {
114 throw 'The notebook hierarchy changed while collecting page evidence; repeat the cold read.'
115 }
116 [IO.File]::WriteAllText((Join-Path $output 'hierarchy.xml'), $all, [Text.Encoding]::UTF8)
117 Write-Output "Read $($sections.Count) sections and $($pages.Count) pages."
118} catch {
119 $failure = $_
120 [IO.File]::WriteAllText((Join-Path $output 'failure.txt'), ($_ | Out-String), [Text.Encoding]::UTF8)
121 throw
122} finally {
123 try {
124 try {
125 if ($notebookId -and $CloneHost) { $app.SyncHierarchy($notebookId) }
126 if ($notebookId -and -not $KeepOpen -and (-not $UseCurrentCache -or $CloneHost)) {
127 $app.CloseNotebook($notebookId, $false)
128 }
129 } catch {
130 if ($null -eq $failure) { throw }
131 [IO.File]::WriteAllText((Join-Path $output 'cleanup-failure.txt'), ($_ | Out-String), [Text.Encoding]::UTF8)
132 }
133 } finally {
134 [void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($app)
135 }
136 $app = $null
137 [GC]::Collect()
138 [GC]::WaitForPendingFinalizers()
139 if (-not $UseCurrentCache -and -not $CloneHost) {
140 Get-Process ONENOTE -ErrorAction SilentlyContinue | Wait-Process -Timeout 10
141 }
142}
corpus/table-edit/nested/cold/source.json created+14
...@@ -0,0 +1,14 @@
1[
2 {
3 "path": "Open Notebook.onetoc2",
4 "bytes": 1612,
5 "sha256": "1c7c0e30cc2c2f029f87e20bba0981f0bf8a7f2f6643ad67a24e80834f539991",
6 "mtime_ns": 1789250020753460025
7 },
8 {
9 "path": "synthetic.one",
10 "bytes": 91192,
11 "sha256": "6f3b8737c318834e2958368ed9fd9bc2ff4c7490bbd4a29907fa76e472355b43",
12 "mtime_ns": 1789250020752551397
13 }
14]
corpus/table-edit/nested/cold/teardown.json created+1
...@@ -0,0 +1 @@
1{"absent": true}
crates/notebook/README.md+1-1
...@@ -14,7 +14,7 @@ diffs the supplied model against the page stored in the supplied local snapshot,...@@ -14,7 +14,7 @@ diffs the supplied model against the page stored in the supplied local snapshot,
14writes the difference into the working image and queues one14writes the difference into the working image and queues one
15`Operation::Page(PageIntent { before, after, author })`; `before` is the page the15`Operation::Page(PageIntent { before, after, author })`; `before` is the page the
16edit started from and is the precondition reconciliation checks. Text, styles,16edit started from and is the precondition reconciliation checks. Text, styles,
17paragraph formatting, hyperlinks, bullets, numbering, note tags, table rows and columns, pictures (insertion in paragraphs or on the page, position, size, description) and attachments, paragraph structure,17paragraph formatting, hyperlinks, bullets, numbering, note tags, table rows, columns, cell shading, nested tables, pictures (insertion in paragraphs or on the page, position, size, description) and attachments, paragraph structure,
18outline layout, insertions and deletions are all differences between `before` and18outline layout, insertions and deletions are all differences between `before` and
19`after`; the library never sees editor operations.19`after`; the library never sees editor operations.
2020
crates/onestore/README.md+1-1
...@@ -57,7 +57,7 @@ harness also accepts `--client-profile release`....@@ -57,7 +57,7 @@ harness also accepts `--client-profile release`.
57| `ParagraphJoin`, `PreparedEdit::join` | Join adjacent ordinary text while preserving inherited character styles and native text-identity rules |57| `ParagraphJoin`, `PreparedEdit::join` | Join adjacent ordinary text while preserving inherited character styles and native text-identity rules |
58| `TextAttribute`, `PreparedEdit::format` | Change character formatting over a UTF-16 range while sharing immutable styles; preserve unselected runs |58| `TextAttribute`, `PreparedEdit::format` | Change character formatting over a UTF-16 range while sharing immutable styles; preserve unselected runs |
59| `OutlineEdit`, `PreparedEdit::outline` | Change ordinary outline position/width or a paragraph's saved expansion default, preserving identities and content |59| `OutlineEdit`, `PreparedEdit::outline` | Change ordinary outline position/width or a paragraph's saved expansion default, preserving identities and content |
60| `PreparedEdit::page` | Publish an edited `page::Page` as one revision per changed space: text, character and paragraph formatting, hyperlinks, bullets and numbering, note tags, table rows and columns, inserted pictures (in paragraphs or on the page) and attachments, picture position, size and description, paragraph insertion/split/join/move/deletion, outline insertion/deletion/position/width and saved collapse state, lowered onto the typed writers with the model's identities |60| `PreparedEdit::page` | Publish an edited `page::Page` as one revision per changed space: text, character and paragraph formatting, hyperlinks, bullets and numbering, note tags, table rows, columns, cell shading and indents, nested tables, inserted pictures (in paragraphs or on the page) and attachments, picture position, size and description, paragraph insertion/split/join/move/deletion, outline insertion/deletion/position/width and saved collapse state, lowered onto the typed writers with the model's identities |
61| `TreeEdit`, `PreparedEdit::tree` | Move or delete a subtree on one page, normalize surviving containers, and replace an emptied table cell's paragraph atomically |61| `TreeEdit`, `PreparedEdit::tree` | Move or delete a subtree on one page, normalize surviving containers, and replace an emptied table cell's paragraph atomically |
62| `PreparedEdit::commit`, `PreparedEdit::commit_file` | Publish the exact prepared image under caller-held exclusion or the conservative filesystem adapter |62| `PreparedEdit::commit`, `PreparedEdit::commit_file` | Publish the exact prepared image under caller-held exclusion or the conservative filesystem adapter |
63| `read_file` | Read a snapshot under whole-file exclusion |63| `read_file` | Read a snapshot under whole-file exclusion |
crates/onestore/src/page/write.rs+66-3
...@@ -438,13 +438,11 @@ impl Lowering<'_> {...@@ -438,13 +438,11 @@ impl Lowering<'_> {
438 .find(|before| before.id == cell.id)438 .find(|before| before.id == cell.id)
439 .is_none_or(|before| {439 .is_none_or(|before| {
440 cell.layout == before.layout440 cell.layout == before.layout
441 && cell.indents == before.indents
442 && cell.shading == before.shading
443 && cell.unsupported == before.unsupported441 && cell.unsupported == before.unsupported
444 })442 })
445 });443 });
446 if !unchanged_cells {444 if !unchanged_cells {
447 return Err(invalid("Cell layout, indents and shading cannot be edited"));445 return Err(invalid("Cell layout cannot be edited"));
448 }446 }
449 }447 }
450 (ParagraphContent::Unsupported(a), ParagraphContent::Unsupported(b)) if a == b => {}448 (ParagraphContent::Unsupported(a), ParagraphContent::Unsupported(b)) if a == b => {}
...@@ -690,6 +688,7 @@ impl Lowering<'_> {...@@ -690,6 +688,7 @@ impl Lowering<'_> {
690 });688 });
691 self.place_containers(old, new, placed, &existing)?;689 self.place_containers(old, new, placed, &existing)?;
692 self.edit_table_structure(old, new)?;690 self.edit_table_structure(old, new)?;
691 self.edit_cells(old, new)?;
693 self.edit_images(old, new)?;692 self.edit_images(old, new)?;
694 self.edit_attachments(old, new)?;693 self.edit_attachments(old, new)?;
695 self.place_containers(old, new, placed, &deferred)?;694 self.place_containers(old, new, placed, &deferred)?;
...@@ -1052,6 +1051,70 @@ impl Lowering<'_> {...@@ -1052,6 +1051,70 @@ impl Lowering<'_> {
1052 /// order to the model's, and writes the column widths, locks and border flag. Native1051 /// order to the model's, and writes the column widths, locks and border flag. Native
1053 /// rows and cells are plain containers; a cell carries its indent array and the flags1052 /// rows and cells are plain containers; a cell carries its indent array and the flags
1054 /// every native cell has.1053 /// every native cell has.
1054 /// Shading (the documented `CellShadingColor`, which OneNote 2010 stores but neither
1055 /// renders nor accepts through its COM schema) and indents change in place on a cell.
1056 fn edit_cells(&mut self, old: &View<'_>, new: &View<'_>) -> Result<(), Error> {
1057 let stored: BTreeMap<ExGuid, &super::TableCell> = old
1058 .paragraphs
1059 .values()
1060 .filter_map(|paragraph| match &paragraph.content {
1061 ParagraphContent::Table(table) => Some(table),
1062 _ => None,
1063 })
1064 .flat_map(|table| table.rows.iter().flat_map(|row| &row.cells))
1065 .map(|cell| (cell.id, cell))
1066 .collect();
1067 for paragraph in new.paragraphs.values() {
1068 let ParagraphContent::Table(table) = &paragraph.content else {
1069 continue;
1070 };
1071 for cell in table.rows.iter().flat_map(|row| &row.cells) {
1072 let Some(previous) = stored.get(&cell.id) else {
1073 continue;
1074 };
1075 if (cell.shading, &cell.indents) == (previous.shading, &previous.indents) {
1076 continue;
1077 }
1078 let mut values: Values = vec![(
1079 0x14001d7a,
1080 crate::create::current_timestamps()?
1081 .0
1082 .to_le_bytes()
1083 .to_vec(),
1084 )];
1085 let mut removed = Vec::new();
1086 if cell.shading != previous.shading {
1087 match cell.shading {
1088 Some(shading) => values.push((0x14001e26, shading.to_le_bytes().to_vec())),
1089 None => removed.push(0x14001e26),
1090 }
1091 }
1092 if cell.indents != previous.indents {
1093 if cell.indents.is_empty() {
1094 removed.push(0x1c001c12);
1095 } else {
1096 values.push((0x1c001c12, measurement_bytes(&cell.indents, 4)?));
1097 }
1098 }
1099 let (space, object) = (self.space, self.id(cell.id));
1100 self.apply(|current| {
1101 crate::write::write_revision(current, space, |raw| {
1102 let mut object_properties =
1103 PropertyObject::from_object(&raw.objects[&object])?;
1104 object_properties.remove(&removed)?;
1105 let values: Vec<(u32, &[u8])> = values
1106 .iter()
1107 .map(|(id, bytes)| (*id, bytes.as_slice()))
1108 .collect();
1109 object_properties.set(&values)?;
1110 Ok(BTreeMap::from([(object, object_properties)]))
1111 })
1112 })?;
1113 }
1114 }
1115 Ok(())
1116 }
1117
1055 fn edit_table_structure(&mut self, old: &View<'_>, new: &View<'_>) -> Result<(), Error> {1118 fn edit_table_structure(&mut self, old: &View<'_>, new: &View<'_>) -> Result<(), Error> {
1056 let old_tables: BTreeMap<ExGuid, &Table> = old1119 let old_tables: BTreeMap<ExGuid, &Table> = old
1057 .paragraphs1120 .paragraphs
crates/onestore/tests/page_tables.rs+86
...@@ -214,6 +214,92 @@ fn column_widths_locks_and_borders_change_in_place() {...@@ -214,6 +214,92 @@ fn column_widths_locks_and_borders_change_in_place() {
214 assert_same(written.as_bytes(), space, &after);214 assert_same(written.as_bytes(), space, &after);
215}215}
216216
217#[test]
218fn cell_shading_and_indents_change_in_place() {
219 let (space, before) = page_by_title(TREES, "Delete cell subtree");
220 let mut after = before.clone();
221 let table = table_mut(&mut after);
222 let cell = &mut table.rows[0].cells[0];
223 assert_eq!(cell.shading, None);
224 cell.shading = Some(0x0000ffff);
225 let original_indents = cell.indents.clone();
226 cell.indents = vec![18.0, 0.0, 27.0, 27.0];
227 let written = PreparedEdit::page(TREES, space, &after, AUTHOR).unwrap();
228 let stored = assert_same(written.as_bytes(), space, &after);
229 let mut reset = stored.clone();
230 let cell = &mut table_mut(&mut reset).rows[0].cells[0];
231 cell.shading = None;
232 cell.indents = original_indents;
233 let again = PreparedEdit::page(written.as_bytes(), space, &reset, AUTHOR).unwrap();
234 assert_eq!(assert_same(again.as_bytes(), space, &reset), before);
235}
236
237/// `ONESTORE_NESTED_TABLE_EXPORT` names a new directory receiving the candidate for a cold reopen.
238#[test]
239fn a_table_nests_inside_a_cell_and_is_removed_again() {
240 let (space, before) = page_by_title(TREES, "Delete cell subtree");
241 let mut after = before.clone();
242 let template = table_mut(&mut after).rows[0].cells[0].paragraphs[0].clone();
243 let cell = |text: &str| TableCell {
244 id: new_id().unwrap(),
245 layout: Default::default(),
246 indents: Vec::new(),
247 shading: None,
248 paragraphs: vec![cell_paragraph(&template, text)],
249 unsupported: Vec::new(),
250 };
251 let nested = Table {
252 id: new_id().unwrap(),
253 columns: vec![TableColumn {
254 width: 72.0,
255 locked: true,
256 }],
257 rows: vec![
258 TableRow {
259 id: new_id().unwrap(),
260 cells: vec![cell("Inner one")],
261 },
262 TableRow {
263 id: new_id().unwrap(),
264 cells: vec![cell("Inner two")],
265 },
266 ],
267 borders: Some(true),
268 layout: Default::default(),
269 tags: Vec::new(),
270 };
271 let mut holder = cell_paragraph(&template, "");
272 holder.content = ParagraphContent::Table(nested);
273 holder.format = Format::default();
274 let holder_id = holder.id;
275 table_mut(&mut after).rows[0].cells[1]
276 .paragraphs
277 .push(holder);
278 let written = PreparedEdit::page(TREES, space, &after, AUTHOR).unwrap();
279 let stored = assert_same(written.as_bytes(), space, &after);
280 if let Some(directory) = std::env::var_os("ONESTORE_NESTED_TABLE_EXPORT") {
281 let directory = std::path::PathBuf::from(directory);
282 std::fs::create_dir(&directory).unwrap();
283 std::fs::write(directory.join("synthetic.one"), written.as_bytes()).unwrap();
284 let written_store = Store::parse(written.as_bytes()).unwrap();
285 std::fs::write(
286 directory.join("Open Notebook.onetoc2"),
287 onestore::create_table_of_contents(
288 "Open Notebook.onetoc2",
289 &[("synthetic.one", written_store.header.file_id)],
290 )
291 .unwrap(),
292 )
293 .unwrap();
294 }
295 let mut removed = stored.clone();
296 table_mut(&mut removed).rows[0].cells[1]
297 .paragraphs
298 .retain(|paragraph| paragraph.id != holder_id);
299 let again = PreparedEdit::page(written.as_bytes(), space, &removed, AUTHOR).unwrap();
300 assert_eq!(assert_same(again.as_bytes(), space, &removed), before);
301}
302
217#[test]303#[test]
218fn inconsistent_tables_are_refused() {304fn inconsistent_tables_are_refused() {
219 let (space, before) = page_by_title(TREES, "Delete cell subtree");305 let (space, before) = page_by_title(TREES, "Delete cell subtree");
tools/test_table_edit.py+6
...@@ -53,6 +53,12 @@ class TableEditTest(unittest.TestCase):...@@ -53,6 +53,12 @@ class TableEditTest(unittest.TestCase):
53 self.assertEqual(rows[0][2], ['Third column'])53 self.assertEqual(rows[0][2], ['Third column'])
54 self.assertEqual(rows[1], [['Second row'], ['Second row, second column'], ['Second row, third column']])54 self.assertEqual(rows[1], [['Second row'], ['Second row, second column'], ['Second row, third column']])
5555
56 def test_a_table_nested_in_a_native_cell_renders_natively(self):
57 self.check('nested')
58 outer, inner = tables(FIXTURE / 'nested/cold/read', 'Delete cell subtree')
59 self.assertEqual(inner, ('true', [('72.0', 'true')], [[['Inner one']], [['Inner two']]]))
60 self.assertEqual(outer[2][0][1], ['Other cell', 'Inner one', 'Inner two'])
61
5662
57if __name__ == '__main__':63if __name__ == '__main__':
58 unittest.main()64 unittest.main()