From 816ca8480dd0887f39294f91a38e66bda33bbd2d Mon Sep 17 00:00:00 2001 From: Tuong Nguyen Manh Date: Sat, 9 Aug 2025 13:48:32 +0200 Subject: [PATCH] ODT Reader: Add table-header-rows --- src/Text/Pandoc/Readers/ODT/ContentReader.hs | 27 ++-- test/Tests/Readers/ODT.hs | 2 + test/odt/native/simpleTable.native | 2 +- test/odt/native/simpleTableWithCaption.native | 2 +- test/odt/native/simpleTableWithHeader.native | 79 +++++++++++ .../simpleTableWithMultipleHeaderRows.native | 125 ++++++++++++++++++ test/odt/native/tableWithContents.native | 2 +- test/odt/odt/simpleTableWithHeader.odt | Bin 0 -> 10377 bytes .../odt/simpleTableWithMultipleHeaderRows.odt | Bin 0 -> 10173 bytes 9 files changed, 228 insertions(+), 11 deletions(-) create mode 100644 test/odt/native/simpleTableWithHeader.native create mode 100644 test/odt/native/simpleTableWithMultipleHeaderRows.native create mode 100644 test/odt/odt/simpleTableWithHeader.odt create mode 100644 test/odt/odt/simpleTableWithMultipleHeaderRows.odt diff --git a/src/Text/Pandoc/Readers/ODT/ContentReader.hs b/src/Text/Pandoc/Readers/ODT/ContentReader.hs index 2d4b98949..b9778bdd3 100644 --- a/src/Text/Pandoc/Readers/ODT/ContentReader.hs +++ b/src/Text/Pandoc/Readers/ODT/ContentReader.hs @@ -795,15 +795,26 @@ read_citation = matchingElement NsText "bibliography-mark" read_table :: BlockMatcher read_table = matchingElement NsTable "table" $ liftA simpleTable' - $ matchChildContent' [ read_table_row - ] + $ (matchChildContent' [read_table_header]) &&& + (matchChildContent' [read_table_row]) --- | A simple table without a caption or headers --- | Infers the number of headers from rows -simpleTable' :: [[Blocks]] -> Blocks -simpleTable' [] = simpleTable [] [] -simpleTable' (x : rest) = simpleTable (fmap (const defaults) x) (x : rest) - where defaults = fromList [] +-- | A simple table without a caption. +simpleTable' :: ([[Blocks]], [[Blocks]]) -> Blocks +simpleTable' (headers, rows) = + table emptyCaption (replicate numcols defaults) th [tb] tf + where + defaults = (AlignDefault, ColWidthDefault) + numcols = maximum $ map length $ headers ++ rows + toRow = Row nullAttr . map simpleCell + th = TableHead nullAttr $ map toRow headers + tb = TableBody nullAttr 0 [] $ map toRow rows + tf = TableFoot nullAttr [] + +-- +read_table_header :: ElementMatcher [[Blocks]] +read_table_header = matchingElement NsTable "table-header-rows" + $ matchChildContent' [ read_table_row + ] -- read_table_row :: ElementMatcher [[Blocks]] diff --git a/test/Tests/Readers/ODT.hs b/test/Tests/Readers/ODT.hs index c226259bb..a5e2dc009 100644 --- a/test/Tests/Readers/ODT.hs +++ b/test/Tests/Readers/ODT.hs @@ -180,6 +180,8 @@ namesOfTestsComparingToNative = [ "blockquote" , "referenceToText" , "simpleTable" , "simpleTableWithCaption" + , "simpleTableWithHeader" + , "simpleTableWithMultipleHeaderRows" , "tab" -- , "table" , "textMixedStyles" diff --git a/test/odt/native/simpleTable.native b/test/odt/native/simpleTable.native index 937ce3cdd..d3281181b 100644 --- a/test/odt/native/simpleTable.native +++ b/test/odt/native/simpleTable.native @@ -1 +1 @@ -[Table ("",[],[]) (Caption Nothing []) [(AlignDefault,ColWidthDefault),(AlignDefault,ColWidthDefault)] (TableHead ("",[],[]) [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) []]]) [TableBody ("",[],[]) (RowHeadColumns 0) [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Content"]],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "More",Space,Str "content"]]]]] (TableFoot ("",[],[]) []),Para []] \ No newline at end of file +[Table ("",[],[]) (Caption Nothing []) [(AlignDefault,ColWidthDefault),(AlignDefault,ColWidthDefault)] (TableHead ("",[],[]) []) [TableBody ("",[],[]) (RowHeadColumns 0) [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Content"]],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "More",Space,Str "content"]]]]] (TableFoot ("",[],[]) []),Para []] diff --git a/test/odt/native/simpleTableWithCaption.native b/test/odt/native/simpleTableWithCaption.native index 14d0cedbc..ebc704339 100644 --- a/test/odt/native/simpleTableWithCaption.native +++ b/test/odt/native/simpleTableWithCaption.native @@ -1 +1 @@ -[Table ("",[],[]) (Caption Nothing [Para [Str "Table",Space,Str "1:",Space,Str "Some",Space,Str "caption",Space,Str "for",Space,Str "a",Space,Str "table"]]) [(AlignDefault,ColWidthDefault),(AlignDefault,ColWidthDefault)] (TableHead ("",[],[]) [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) []]]) [TableBody ("",[],[]) (RowHeadColumns 0) [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Content"]],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "More",Space,Str "content"]]]]] (TableFoot ("",[],[]) []),Para []] \ No newline at end of file +[Table ("",[],[]) (Caption Nothing [Para [Str "Table",Space,Str "1:",Space,Str "Some",Space,Str "caption",Space,Str "for",Space,Str "a",Space,Str "table"]]) [(AlignDefault,ColWidthDefault),(AlignDefault,ColWidthDefault)] (TableHead ("",[],[]) []) [TableBody ("",[],[]) (RowHeadColumns 0) [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Content"]],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "More",Space,Str "content"]]]]] (TableFoot ("",[],[]) []),Para []] diff --git a/test/odt/native/simpleTableWithHeader.native b/test/odt/native/simpleTableWithHeader.native new file mode 100644 index 000000000..a0432f764 --- /dev/null +++ b/test/odt/native/simpleTableWithHeader.native @@ -0,0 +1,79 @@ +[ Table + ( "" , [] , [] ) + (Caption Nothing []) + [ ( AlignDefault , ColWidthDefault ) + , ( AlignDefault , ColWidthDefault ) + , ( AlignDefault , ColWidthDefault ) + ] + (TableHead + ( "" , [] , [] ) + [ Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "A" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "B" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "C" ] ] + ] + ]) + [ TableBody + ( "" , [] , [] ) + (RowHeadColumns 0) + [] + [ Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "1" ] ] + , Cell + ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) [ Plain [] ] + , Cell + ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) [ Plain [] ] + ] + , Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "2" ] ] + , Cell + ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) [ Plain [] ] + , Cell + ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) [ Plain [] ] + ] + , Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "3" ] ] + , Cell + ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) [ Plain [] ] + , Cell + ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) [ Plain [] ] + ] + ] + ] + (TableFoot ( "" , [] , [] ) []) +, Para [] +] diff --git a/test/odt/native/simpleTableWithMultipleHeaderRows.native b/test/odt/native/simpleTableWithMultipleHeaderRows.native new file mode 100644 index 000000000..949fd289a --- /dev/null +++ b/test/odt/native/simpleTableWithMultipleHeaderRows.native @@ -0,0 +1,125 @@ +[ Table + ( "" , [] , [] ) + (Caption Nothing []) + [ ( AlignDefault , ColWidthDefault ) + , ( AlignDefault , ColWidthDefault ) + , ( AlignDefault , ColWidthDefault ) + ] + (TableHead + ( "" , [] , [] ) + [ Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "A" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "B" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "C" ] ] + ] + , Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "I" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "II" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "II" ] ] + ] + ]) + [ TableBody + ( "" , [] , [] ) + (RowHeadColumns 0) + [] + [ Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "1" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [] ] + ] + , Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "2" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [] ] + ] + , Row + ( "" , [] , [] ) + [ Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [ Str "3" ] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [] ] + , Cell + ( "" , [] , [] ) + AlignDefault + (RowSpan 1) + (ColSpan 1) + [ Plain [] ] + ] + ] + ] + (TableFoot ( "" , [] , [] ) []) +, Para [] +] + diff --git a/test/odt/native/tableWithContents.native b/test/odt/native/tableWithContents.native index d2e044f66..38c3fe6bf 100644 --- a/test/odt/native/tableWithContents.native +++ b/test/odt/native/tableWithContents.native @@ -1 +1 @@ -[Table ("",[],[]) (Caption Nothing []) [(AlignDefault,ColWidthDefault),(AlignDefault,ColWidthDefault)] (TableHead ("",[],[]) [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) []]]) [TableBody ("",[],[]) (RowHeadColumns 0) [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "A"]],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "B"]]],Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "C"]],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "D"]]]]] (TableFoot ("",[],[]) []),Para []] \ No newline at end of file +[Table ("",[],[]) (Caption Nothing []) [(AlignDefault,ColWidthDefault),(AlignDefault,ColWidthDefault)] (TableHead ("",[],[]) []) [TableBody ("",[],[]) (RowHeadColumns 0) [] [Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "A"]],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "B"]]],Row ("",[],[]) [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "C"]],Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "D"]]]]] (TableFoot ("",[],[]) []),Para []] diff --git a/test/odt/odt/simpleTableWithHeader.odt b/test/odt/odt/simpleTableWithHeader.odt new file mode 100644 index 0000000000000000000000000000000000000000..09be801ba5189dba138f694f7d71aaac35177454 GIT binary patch literal 10377 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 Hk5~T#KK&PC literal 0 HcmV?d00001