| 1 | # Notebook structure |
| 2 | |
| 3 | `native-structure/` is OneNote 2010 building structure through the COM API on |
| 4 | a Rust-created notebook (`tools/native/notebook-structure.ps1`): it created |
| 5 | two sections and a section group with a section inside, renamed the notebook, |
| 6 | reopened it, and deleted a section; `structure-*.xml` are the hierarchy reads |
| 7 | after each step, `notebook-renamed/` the files before the delete. OneNote |
| 8 | keeps the documented table of contents (MS-ONE 2.2.14): one root object with |
| 9 | an entry array whose entries carry the file identity, order, filename and |
| 10 | colour (`0xffffffff` for sections, absent for groups); a section's colour |
| 11 | lives in its own metadata. Deleting moves the file into `OneNote_RecycleBin`, |
| 12 | a group with its own TOC that the root lists. OneNote also names every file |
| 13 | for its place in the header: `guidAncestor` is the parent TOC's file |
| 14 | identity and `crcName` the CRC of the section file name or the group folder |
| 15 | name. The Rust section `links.one`, created with a zero ancestor, was |
| 16 | re-identified on open and listed a second time under its new identity. |
| 17 | |
| 18 | `native-reorder/` is the COM API asked to move the last root section first |
| 19 | through `UpdateHierarchy` (`tools/native/notebook-reorder.ps1`): the |
| 20 | in-session read shows the new order, but after `SyncHierarchy`, close and |
| 21 | reopen the order is back and the TOC unchanged, so section order cannot be |
| 22 | authored through COM; the order rows below are proved by cold reads of Rust |
| 23 | candidates alone. Section display order is the entry's ordering number |
| 24 | ascending, sections before groups, which the owner's own notebook confirms |
| 25 | (array order there differs from the numbers, and OneNote lists by number). |
| 26 | |
| 27 | `structured/` is the notebook `crates/notebook/tests/structure.rs` builds |
| 28 | through `notebook::session::Notebook` (create sections and a group, rename |
| 29 | both, colour a section, order the root as group, renamed, first), placed the |
| 30 | same way; `deleted/` is the same notebook after deleting a section. Each |
| 31 | `cold/` is a fresh OneNote 2010 read: the hierarchy lists the entries in the |
| 32 | written order with the written colours, the recycle bin carries |
| 33 | `isRecycleBin`, and every file keeps the identity Rust wrote. |
| 34 | Every TOC revision the writer appends carries one global id table; with one |
| 35 | table per object group, as the section writer emits, OneNote applied a |
| 36 | reordered entry's value to the wrong entry. `tools/test_notebook_edit.py` |
| 37 | checks this without a VM. Regenerate with |
| 38 | `NOTEBOOK_STRUCTURE_EXPORT` and `NOTEBOOK_STRUCTURE_EXPORT_DELETED` set to |
| 39 | new directories while running the test, then cold-open each with |
| 40 | `tools/native_runner.py OUTPUT COLD --expected-pages -1 --collect-notebook`. |