Skip to content

fix(docx-markdoc): import rejects comparison redlines whose footnote reference sits in both a w:del and a w:ins run #962

Description

@stevenobiajulu

Summary

Post-merge smoke for #950 tried the most realistic brownfield source available in-repo: the redline that compareDocuments produces from the two ILPA fixtures. importDocxToMarkdoc refuses it with ANNOTATION_IMPORT_UNSUPPORTEDFootnote 24 must have exactly one reference (referenceCount: 2) — before any annotation work can begin, so the annotation-only path admitted by #950 is unreachable on this class of document.

Privacy-safe reproduction

Both inputs are committed public model documents:

import { compareDocuments } from '@usejunior/docx-compare';
import { importDocxToMarkdoc } from '@usejunior/docx-markdoc';
const redline = (await compareDocuments(
  readFileSync('tests/test_documents/redline/ILPA-Model-Limited-Parnership-Agreement-Deal-By-Deal_v1.docx'),
  readFileSync('tests/test_documents/redline/ILPA-Model-Limited-Partnership-Agreement-WOF_v2.docx'),
  { author: 'Jane Doe', date: new Date('2026-08-15T12:00:00Z') },
)).document;
await importDocxToMarkdoc(redline); // throws ANNOTATION_IMPORT_UNSUPPORTED footnote:24 referenceCount 2

(~107 s for the comparison; 1,784 w:ins/w:del elements in the output.)

Analysis

When a paragraph carrying a footnote reference is rewritten, the comparison emits the w:footnoteReference run once inside w:del and once inside w:ins, both pointing at the same footnote id. That is the normal Word representation of a moved/re-typed reference, and accept/reject resolve it to exactly one. The import invariant "exactly one reference per footnote" counts raw references and does not see through revision containers.

Expected behavior

Import should count footnote references after collapsing revision containers (one visible reference per footnote in each of the accept and reject projections), or resolve the canonical anchor from the surviving reference and treat the deleted twin as revision content. Failing that, the diagnostic should say the duplicate is revision-induced so the user knows accept/reject is not required.

Refs #949, #950.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions