diff options
| author | Nils Carlson <nils@nilscarlson.se> | 2020-09-24 16:31:47 +0000 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-24 09:31:47 -0700 | 
| commit | 4f13c0e25e7c97c0590944718a65147cf2c5d07a (patch) | |
| tree | 1b061410bcf94d277bc1fdf648eacad4deb3d552 | |
| parent | 1f707da40fa2a916fe6f8f86720494eadfc5ae9e (diff) | |
| download | pandoc-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.hs | 82 | ||||
| -rw-r--r-- | test/command/table-with-column-span.md | 157 | 
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> +``` | 
