Files
John MacFarlane 098c48d79f RTF reader: fix tables parsed as deeply nested tables.
Closes #11682.

Fixes two bugs that caused a simple table to be read as a cascade of
nested tables:

* `\plain` reset the entire property record (including the in-table
  flag) via `const def`.  When a cell paragraph used `\plain` after
  `\intbl`, the in-table flag was cleared, so the next `\cell` closed
  the partially-built table and embedded it inside a new cell.  Per the
  RTF spec, `\plain` should reset only character formatting, so it now
  preserves paragraph/context properties (in-table, list level, outline
  level, hyperlink, anchor).

* `\row` was ignored and only `\trowd` started a new row.  Real-world
  RTF often emits a single `\trowd` and separates rows with `\row`, so
  every cell ended up in one row.  Both `\trowd` and `\row` now begin a
  fresh row (only when the current one has cells), and empty trailing
  rows are dropped when closing the table.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-03 16:36:29 +02:00

2.2 KiB

Cell paragraphs that use \plain after \intbl, together with a single \trowd and \row row terminators, should produce a flat table rather than deeply nested tables.

% pandoc -f rtf -t native
{\rtf1\ansi\deff0
{\fonttbl{\f0 Times;}{\f1 Times;}{\f2 Times;}}
\trowd\trgaph60\trleft0
\clvertalt\cellx3245
\clvertalt\cellx6490
\clvertalt\cellx9735
\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 A\plain\f1\fs22\cell
\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 B\plain\f1\fs22\cell
\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 C\plain\f1\fs22\cell
\intbl\row
\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 1\plain\f1\fs22\cell
\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 2\plain\f1\fs22\cell
\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 3\plain\f1\fs22\cell
\intbl\row
}
^D
[ Table
    ( "" , [] , [] )
    (Caption Nothing [])
    [ ( AlignDefault , ColWidthDefault )
    , ( AlignDefault , ColWidthDefault )
    , ( AlignDefault , ColWidthDefault )
    ]
    (TableHead ( "" , [] , [] ) [])
    [ TableBody
        ( "" , [] , [] )
        (RowHeadColumns 0)
        []
        [ Row
            ( "" , [] , [] )
            [ Cell
                ( "" , [] , [] )
                AlignDefault
                (RowSpan 1)
                (ColSpan 1)
                [ Para [ Str "A" ] ]
            , Cell
                ( "" , [] , [] )
                AlignDefault
                (RowSpan 1)
                (ColSpan 1)
                [ Para [ Str "B" ] ]
            , Cell
                ( "" , [] , [] )
                AlignDefault
                (RowSpan 1)
                (ColSpan 1)
                [ Para [ Str "C" ] ]
            ]
        , Row
            ( "" , [] , [] )
            [ Cell
                ( "" , [] , [] )
                AlignDefault
                (RowSpan 1)
                (ColSpan 1)
                [ Para [ Str "1" ] ]
            , Cell
                ( "" , [] , [] )
                AlignDefault
                (RowSpan 1)
                (ColSpan 1)
                [ Para [ Str "2" ] ]
            , Cell
                ( "" , [] , [] )
                AlignDefault
                (RowSpan 1)
                (ColSpan 1)
                [ Para [ Str "3" ] ]
            ]
        ]
    ]
    (TableFoot ( "" , [] , [] ) [])
]