Repository navigation
Read task Notes when opening a .mpp (#455) - #519
Merged
Merged
Conversation
Current-layout .mpp files keep a task's notes as RichEdit RTF under VarMeta key 0x000F. var_fields now decodes that block to the plain text Project's MSPDI export writes (a new dependency-free RTF reader), and import_tasks carries it into Task.notes, so an opened .mpp saved as .yppx/.xml keeps its notes. The oracle comparison checks Notes on every current-layout pair. The other #417 task elements stay unread: no corpus case shows where Project stores them. Committed by the planner on the implementer's behalf: its sandbox denies writes to .git. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…#455 r1) Picture, object and other non-text destinations are hidden and \binN payloads are skipped, so embedded images no longer leak hex into Notes or refuse the file. Escaped bytes are decoded through the selected font's \fcharset or the document's \ansicpg, with tables for Windows code pages 1250-1258, instead of always as cp1252. \uc fallbacks skip control words and stop at a brace, and backslash-newline is a paragraph mark. The notes test uses add_var; the corpus README and PROJECT.md record the Notes key. Committed by the planner on the implementer's behalf: its sandbox denies writes to .git. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
RichEdit bullet markers (pntext/listtext) are hidden and Symbol-charset escapes map to U+F000+byte, so a bulleted note no longer refuses the file. \fcharset0 is cp1252 and \fcharset1 follows \ansicpg; a font's \cpgN wins over its charset; \plain restores the \deff font. Unknown control symbols are ignored. The code-page tables are regenerated from MultiByteToWideChar by the new corpus/tools/gen_rtf_codepages.py. The header must be \rtfN, and parse and fallback skipping share one lexer with strict hex digits. Committed by the planner on the implementer's behalf: its sandbox denies writes to .git. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Code page 874 joins the generated tables and \fcharset222 maps to it, so a Thai note no longer refuses the file. Unescaped high-bit bytes are decoded through the current font's code page like \'hh escapes, and a font's \fcharset/\cpg is taken only at its definition's own depth, not from a nested \fontfile. Committed by the planner on the implementer's behalf: its sandbox denies writes to .git. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The r3 depth gate only accepted \fcharset/\cpg one group below \fonttbl, so a font table written without per-entry braces lost its charsets and decoded under \ansicpg. One in_font_entry helper now accepts the fonttbl group and one level below it, still excluding a nested \fontfile. Committed by the planner on the implementer's behalf: its sandbox denies writes to .git. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…notes (#455 r5) A hidden or \* destination opened inside the font table no longer counts as a font entry, so a nested \fontfile\cpg cannot override a brace-less entry's \fcharset. A decoded note holding a character outside XML 1.0 Char (C0 controls other than TAB/CR/LF, U+FFFE, U+FFFF) is refused like a task name with control characters, since saving it would write ill-formed MSPDI. Committed by the planner on the implementer's behalf: its sandbox denies writes to .git. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Conflict in mppread/src/lib.rs: both sides added private modules (rtf/rtf_codepage here, rscdecode/tabledecode on main); kept all four. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Owner
Author
|
Merged automatically (auto-merge and full autonomy are on for this checkout):
Follow-ups:
|
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.
What and why
Opening a
.mppdropped task Notes, one of the task elements #417 madeTaskkeep, so a.mppopened and saved as.yppx/.xmllost them.Current-layout
.mppfiles store a task's notes as RichEdit RTF under Var2Data key0x000F(found by diffing corpus steps 06 → 07; the block is the RTF followed by\r\nand a NUL). This PR:taskdecode::var_fieldsintoMppTaskFields.notes, andimport_taskscopies it intoTask.notes;mppread/src/rtf.rs, a dependency-free RTF → plain-text reader producing exactly the text Project's MSPDI export writes (final\pardropped, CRLF paragraphs). It hides non-text destinations (font/colour tables, pictures, objects,\binpayloads, bulletpntext, fields, headers…), honours\uc/\u, and decodes\'hhand raw 8-bit text through the current font's\cpg/\fcharsetor\ansicpg;mppread/src/rtf_codepage.rs, the Windows single-byte code pages 874 and 1250–1258, generated fromMultiByteToWideCharbycorpus/tools/gen_rtf_codepages.py; Symbol-charset bytes map to U+F000+byte;0x000Fincorpus/mpp/README.mdand adds Notes to PROJECT.md's list of fields that survive an import.Not in this PR (no corpus case shows where Project stores them — tracked in a follow-up issue): Contact, WBSLevel, SubprojectName, PreLeveledStart/Finish, StatusManager, CommitmentStart/Finish, IsPublished (every snapshot row matches
!summary && active, so no bit can be told apart from a summary/active marker without a Publish toggle case), non-default DisplayAsSummary/CommitmentType, and Notes on the legacy/MPP12 decode path.Closes #455
Tests
oracle_corpus:same!(notes)— every current-layout.mpppair's decoded and imported Notes equal Project's MSPDI export (incl. step 07'sFirst line.\r\nSecond line — unicode ✓ and «quotes».).taskdecode: the verbatim 314-byte corpus note decodes, imports, and surviveswrite_mspdi→read_mspdi; corrupt RTF refuses with the UID.rtf.rsunit tests: RichEdit notes, bullets, pictures/objects/\bin, code pages and charsets (incl. brace-less font tables and nested\fontfile),\ucfallbacks, control symbols, malformed and XML-illegal input.overalloc::tests::project_assignment_and_resource_offsetsis skipped locally: with only the fetchedsnapshots/corpus present it finds 47 < 50 Project pairs — pre-existing and unrelated (follow-up filed); CI has no corpus, where it returns early.Review record
Plan agreed with Codex at v2 (v1 dropped IsPublished decoding for lack of a toggle case, and pinned the note block's
\r\n\0tail). Five revmux rounds:\binpayloads leaked or refused,\fcharsetignored, non-1252 locales refused the file), 4 Minor (fallback skipping, backslash-newline, test helper, docs) — all fixed.\fcharset0used\ansicpg), 4 Minor (\plain, unknown control symbols, Python vs Windows code-page tables, README escape), 3 Immaterial (\cpg, header check, duplicated lexer) — all fixed.\fontfile\cpg) — all fixed.\fontfilein a brace-less entry, XML-illegal characters) — fixed and verified by the planner's direct diff read.No finding was disputed or deferred.