aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Carlson <nils@nilscarlson.se>2020-09-24 16:31:47 +0000
committerGitHub <noreply@github.com>2020-09-24 09:31:47 -0700
commit4f13c0e25e7c97c0590944718a65147cf2c5d07a (patch)
tree1b061410bcf94d277bc1fdf648eacad4deb3d552
parent1f707da40fa2a916fe6f8f86720494eadfc5ae9e (diff)
downloadpandoc-4f13c0e25e7c97c0590944718a65147cf2c5d07a.tar.gz
OpenDocument writer: New table cell support with row and column spans (#6682)
Unit tests only verify column spans at this point. Co-authored-by: Nils Carlson <nils.carlson@ludd.ltu.se>
-rw-r--r--src/Text/Pandoc/Writers/OpenDocument.hs82
-rw-r--r--test/command/table-with-column-span.md157
2 files changed, 213 insertions, 26 deletions
diff --git a/src/Text/Pandoc/Writers/OpenDocument.hs b/src/Text/Pandoc/Writers/OpenDocument.hs
index 731f98e75..c7ee839b5 100644
--- a/src/Text/Pandoc/Writers/OpenDocument.hs
+++ b/src/Text/Pandoc/Writers/OpenDocument.hs
@@ -32,11 +32,12 @@ import qualified Text.Pandoc.Builder as B
import Text.Pandoc.Logging
import Text.Pandoc.Options
import Text.DocLayout
-import Text.Pandoc.Shared (linesToPara, tshow)
+import Text.Pandoc.Shared (linesToPara, tshow, blocksToInlines)
import Text.Pandoc.Templates (renderTemplate)
import qualified Text.Pandoc.Translations as Term (Term(Figure, Table))
import Text.Pandoc.Writers.Math
import Text.Pandoc.Writers.Shared
+import qualified Text.Pandoc.Writers.AnnotatedTable as Ann
import Text.Pandoc.XML
import Text.Printf (printf)
@@ -371,9 +372,7 @@ blockToOpenDocument o bs
| BulletList b <- bs = setFirstPara >> bulletListToOpenDocument o b
| OrderedList a b <- bs = setFirstPara >> orderedList a b
| CodeBlock _ s <- bs = setFirstPara >> preformatted s
- | Table _ bc s th tb tf
- <- bs = let (c, a, w, h, r) = toLegacyTable bc s th tb tf
- in setFirstPara >> table c a w h r
+ | Table a bc s th tb tf <- bs = setFirstPara >> table (Ann.toTable a bc s th tb tf)
| HorizontalRule <- bs = setFirstPara >> return (selfClosingTag "text:p"
[ ("text:style-name", "Horizontal_20_Line") ])
| RawBlock f s <- bs = if f == Format "opendocument"
@@ -396,29 +395,32 @@ blockToOpenDocument o bs
orderedList a b = do (ln,pn) <- newOrderedListStyle (isTightList b) a
inTags True "text:list" [ ("text:style-name", "L" <> tshow ln)]
<$> orderedListToOpenDocument o pn b
- table c a w h r = do
+ table :: PandocMonad m => Ann.Table -> OD m (Doc Text)
+ table (Ann.Table _ (Caption _ c) colspecs thead tbodies _) = do
tn <- length <$> gets stTableStyles
pn <- length <$> gets stParaStyles
let genIds = map chr [65..]
name = "Table" <> tshow (tn + 1)
- columnIds = zip genIds w
+ (aligns, mwidths) = unzip colspecs
+ fromWidth (ColWidth w) | w > 0 = w
+ fromWidth _ = 0
+ widths = map fromWidth mwidths
+ columnIds = zip genIds widths
mkColumn n = selfClosingTag "table:table-column" [("table:style-name", name <> "." <> T.singleton (fst n))]
columns = map mkColumn columnIds
- paraHStyles = paraTableStyles "Heading" pn a
- paraStyles = paraTableStyles "Contents" (pn + length (newPara paraHStyles)) a
+ paraHStyles = paraTableStyles "Heading" pn aligns
+ paraStyles = paraTableStyles "Contents" (pn + length (newPara paraHStyles)) aligns
newPara = map snd . filter (not . isEmpty . snd)
addTableStyle $ tableStyle tn columnIds
mapM_ addParaStyle . newPara $ paraHStyles ++ paraStyles
captionDoc <- if null c
then return empty
- else inlinesToOpenDocument o c >>=
+ else inlinesToOpenDocument o (blocksToInlines c) >>=
if isEnabled Ext_native_numbering o
then numberedTableCaption
else unNumberedCaption "TableCaption"
- th <- if all null h
- then return empty
- else colHeadsToOpenDocument o (map fst paraHStyles) h
- tr <- mapM (tableRowToOpenDocument o (map fst paraStyles)) r
+ th <- colHeadsToOpenDocument o (map fst paraHStyles) thead
+ tr <- mapM (tableBodyToOpenDocument o (map fst paraStyles)) tbodies
let tableDoc = inTags True "table:table" [
("table:name" , name)
, ("table:style-name", name)
@@ -464,26 +466,54 @@ unNumberedCaption :: Monad m => Text -> Doc Text -> OD m (Doc Text)
unNumberedCaption style caption = return $ inParagraphTagsWithStyle style caption
colHeadsToOpenDocument :: PandocMonad m
- => WriterOptions -> [Text] -> [[Block]]
+ => WriterOptions -> [Text] -> Ann.TableHead
-> OD m (Doc Text)
-colHeadsToOpenDocument o ns hs =
- inTagsIndented "table:table-header-rows" . inTagsIndented "table:table-row" . vcat <$>
- mapM (tableItemToOpenDocument o "TableHeaderRowCell") (zip ns hs)
+colHeadsToOpenDocument o ns (Ann.TableHead _ hs) =
+ case hs of
+ [] -> return empty
+ (x:_) ->
+ let (Ann.HeaderRow _ _ c) = x
+ in inTagsIndented "table:table-header-rows" .
+ inTagsIndented "table:table-row" .
+ vcat <$> mapM (tableItemToOpenDocument o "TableHeaderRowCell") (zip ns c)
+
+tableBodyToOpenDocument:: PandocMonad m
+ => WriterOptions -> [Text] -> Ann.TableBody
+ -> OD m (Doc Text)
+tableBodyToOpenDocument o ns tb =
+ let (Ann.TableBody _ _ _ r) = tb
+ in vcat <$> mapM (tableRowToOpenDocument o ns) r
tableRowToOpenDocument :: PandocMonad m
- => WriterOptions -> [Text] -> [[Block]]
+ => WriterOptions -> [Text] -> Ann.BodyRow
-> OD m (Doc Text)
-tableRowToOpenDocument o ns cs =
- inTagsIndented "table:table-row" . vcat <$>
- mapM (tableItemToOpenDocument o "TableRowCell") (zip ns cs)
+tableRowToOpenDocument o ns r =
+ let (Ann.BodyRow _ _ _ c ) = r
+ in inTagsIndented "table:table-row" . vcat <$>
+ mapM (tableItemToOpenDocument o "TableRowCell") (zip ns c)
+
+
+colspanAttrib :: ColSpan -> [(Text, Text)]
+colspanAttrib cs =
+ case cs of
+ ColSpan 1 -> mempty
+ ColSpan n -> [("table:number-columns-spanned", tshow n)]
+
+rowspanAttrib :: RowSpan -> [(Text, Text)]
+rowspanAttrib rs =
+ case rs of
+ RowSpan 1 -> mempty
+ RowSpan n -> [("table:number-rows-spanned", tshow n)]
tableItemToOpenDocument :: PandocMonad m
- => WriterOptions -> Text -> (Text,[Block])
+ => WriterOptions -> Text -> (Text,Ann.Cell)
-> OD m (Doc Text)
-tableItemToOpenDocument o s (n,i) =
- let a = [ ("table:style-name" , s )
- , ("office:value-type", "string" )
- ]
+tableItemToOpenDocument o s (n,c) =
+ let (Ann.Cell _colspecs _colnum (Cell _ _ rs cs i) ) = c
+ csa = colspanAttrib cs
+ rsa = rowspanAttrib rs
+ a = [ ("table:style-name" , s )
+ , ("office:value-type", "string" ) ] ++ csa ++ rsa
in inTags True "table:table-cell" a <$>
withParagraphStyle o n (map plainToPara i)
diff --git a/test/command/table-with-column-span.md b/test/command/table-with-column-span.md
index 082233e5d..a0824b5a1 100644
--- a/test/command/table-with-column-span.md
+++ b/test/command/table-with-column-span.md
@@ -117,3 +117,160 @@
(TableFoot ("",[],[])
[])]
```
+```
+% pandoc -f native -t opendocument --quiet
+[Table ("",[],[]) (Caption Nothing
+ [])
+ [(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)
+ ,(AlignDefault,ColWidth 6.25e-2)]
+ (TableHead ("",[],[])
+ [])
+ [(TableBody ("",[],[]) (RowHeadColumns 0)
+ []
+ [Row ("",[],[])
+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 8)
+ [Para [Strong [Str "Octet",Space,Str "no.",Space,Str "1"]]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 8)
+ [Para [Strong [Str "Octet",Space,Str "no.",Space,Str "2"]]]]
+ ,Row ("",[],[])
+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "16"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "15"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "14"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "13"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "12"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "11"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "10"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "9"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "8"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "7"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "6"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "5"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "4"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "3"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "2"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
+ [Para [Str "1"]]]
+ ,Row ("",[],[])
+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 8)
+ [Para [Str "Code",Space,Str "A"]]
+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 8)
+ [Para [Str "Code",Space,Str "B"]]]])]
+ (TableFoot ("",[],[])
+ [])]
+^D
+<table:table table:name="Table1" table:style-name="Table1">
+ <table:table-column table:style-name="Table1.A" />
+ <table:table-column table:style-name="Table1.B" />
+ <table:table-column table:style-name="Table1.C" />
+ <table:table-column table:style-name="Table1.D" />
+ <table:table-column table:style-name="Table1.E" />
+ <table:table-column table:style-name="Table1.F" />
+ <table:table-column table:style-name="Table1.G" />
+ <table:table-column table:style-name="Table1.H" />
+ <table:table-column table:style-name="Table1.I" />
+ <table:table-column table:style-name="Table1.J" />
+ <table:table-column table:style-name="Table1.K" />
+ <table:table-column table:style-name="Table1.L" />
+ <table:table-column table:style-name="Table1.M" />
+ <table:table-column table:style-name="Table1.N" />
+ <table:table-column table:style-name="Table1.O" />
+ <table:table-column table:style-name="Table1.P" />
+ <table:table-row>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string" table:number-columns-spanned="8">
+ <text:p text:style-name="Table_20_Contents"><text:span text:style-name="T1">Octet
+ no. 1</text:span></text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string" table:number-columns-spanned="8">
+ <text:p text:style-name="Table_20_Contents"><text:span text:style-name="T1">Octet
+ no. 2</text:span></text:p>
+ </table:table-cell>
+ </table:table-row>
+ <table:table-row>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">16</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">15</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">14</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">13</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">12</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">11</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">10</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">9</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">8</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">7</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">6</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">5</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">4</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">3</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">2</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
+ <text:p text:style-name="Table_20_Contents">1</text:p>
+ </table:table-cell>
+ </table:table-row>
+ <table:table-row>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string" table:number-columns-spanned="8">
+ <text:p text:style-name="Table_20_Contents">Code A</text:p>
+ </table:table-cell>
+ <table:table-cell table:style-name="TableRowCell" office:value-type="string" table:number-columns-spanned="8">
+ <text:p text:style-name="Table_20_Contents">Code B</text:p>
+ </table:table-cell>
+ </table:table-row>
+</table:table>
+```