Skip to content

extradoc: inline <x-colbreak/> relocates to end of tab when surrounding paragraph text is edited #65

@sripathikrishnan

Description

@sripathikrishnan

Repro

Test doc: https://docs.google.com/document/d/1YKyqqH8wZa3kSnoBEdlwAumI94gRivSsZB1qvc9y4CA (title: sample3)

The doc has a "Columns" section where a single paragraph contains an inline <x-colbreak/> mid-paragraph, followed by a ## Columns heading:

...across to the next.<x-colbreak/>When columns are not created correctly...Obviously, that is not accessible.

The inline columnBreak element splits the paragraph into two columns in the rendered Google Doc.

Edit applied to the pulled markdown: change Obviously to Clearly (same paragraph, after the <x-colbreak/>). No other changes.

Push, then re-pull.

Expected

The inline <x-colbreak/> stays in its original position (mid-paragraph), the paragraph text reflects Clearly instead of Obviously, and the column layout is preserved.

Actual

After re-pull:

  • The mid-paragraph <x-colbreak/> is gone from its original position — the two halves of the paragraph joined into a single paragraph.
  • A standalone <x-colbreak/> appears at the end of the tab, after the final paragraph.
  • The document's two-column layout is broken.

Likely area

The reconciler / diffmerge path for paragraphs that contain special inline elements (columnBreak, pageBreak, etc.). A text edit inside a paragraph should be an in-place deleteContentRange+insertText that preserves sibling inline elements; instead, the paragraph appears to be rewritten in a way that loses the inline column break and then a synthetic one gets re-emitted at tab end.

Starting points for investigation:

  • extradoc/src/extradoc/serde/markdown/_from_markdown.py:131 (_X_COLBREAK_RE) and :1104 — where <x-colbreak/> is parsed into ParagraphElement(column_break=ColumnBreak()).
  • extradoc/src/extradoc/serde/markdown/_to_markdown.py:477 — serialization of columnBreak to <x-colbreak/>.
  • extradoc/src/extradoc/diffmerge/content_align.py and extradoc/src/extradoc/diffmerge/diff.py — alignment of paragraph elements across base / ancestor / mine. It is worth checking whether the content alignment treats columnBreak as a matchable element or discards it when the surrounding text changes.
  • extradoc/src/extradoc/reconcile_v3/lower.py:1875 — lowering of columnBreak / pageBreak / equation inline elements.

It is also worth checking whether the 3-way merge in diffmerge/apply_ops.py drops the columnBreak when the containing paragraph is classified as "changed" and whether a separate codepath re-appends any unmatched columnBreak to the end of the tab.

Environment

  • main @ f252136
  • Doc id: 1YKyqqH8wZa3kSnoBEdlwAumI94gRivSsZB1qvc9y4CA

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions