Add styling rules in pandoc tables for odt/docx output (table borders)

前端 未结 6 1487
一整个雨季
一整个雨季 2020-12-24 02:42

I\'m generating some odt/docx reports via markdown using knitr and pandoc and am now wondering how you\'d go about formating tables. Primarily I\'m interested in adding rule

6条回答
  •  有刺的猬
    2020-12-24 03:21

    Here's how I searched how to do this:

    The way to add a table in Docx is to use the tag. So I searched for this in the github repository, and found it in this file (called Writers/Docx.hs, so it's not a big surprise)

    blockToOpenXML opts (Table caption aligns widths headers rows) = do
      let captionStr = stringify caption
      caption' <- if null caption
                     then return []
                     else withParaProp (pStyle "TableCaption")
                          $ blockToOpenXML opts (Para caption)
      let alignmentFor al = mknode "w:jc" [("w:val",alignmentToString al)] ()
      let cellToOpenXML (al, cell) = withParaProp (alignmentFor al)
                                        $ blocksToOpenXML opts cell
      headers' <- mapM cellToOpenXML $ zip aligns headers
      rows' <- mapM (\cells -> mapM cellToOpenXML $ zip aligns cells)
               $ rows
      let borderProps = mknode "w:tcPr" []
                        [ mknode "w:tcBorders" []
                          $ mknode "w:bottom" [("w:val","single")] ()
                        , mknode "w:vAlign" [("w:val","bottom")] () ]
      let mkcell border contents = mknode "w:tc" []
                                $ [ borderProps | border ] ++
                                if null contents
                                   then [mknode "w:p" [] ()]
                                   else contents
      let mkrow border cells = mknode "w:tr" [] $ map (mkcell border) cells
      let textwidth = 7920  -- 5.5 in in twips, 1/20 pt
      let mkgridcol w = mknode "w:gridCol"
                           [("w:w", show $ (floor (textwidth * w) :: Integer))] ()
      return $
        [ mknode "w:tbl" []
          ( mknode "w:tblPr" []
            ( [ mknode "w:tblStyle" [("w:val","TableNormal")] () ] ++
              [ mknode "w:tblCaption" [("w:val", captionStr)] ()
              | not (null caption) ] )
          : mknode "w:tblGrid" []
            (if all (==0) widths
                then []
                else map mkgridcol widths)
          : [ mkrow True headers' | not (all null headers) ] ++
          map (mkrow False) rows'
          )
        ] ++ caption'
    

    I'm not familiar at all with Haskell, but I can see that the border-style is hardcoded, since there is no variable in it:

    let borderProps = mknode "w:tcPr" []
                        [ mknode "w:tcBorders" []
                          $ mknode "w:bottom" [("w:val","single")] ()
                        , mknode "w:vAlign" [("w:val","bottom")] () ]
    

    What does that mean ?

    That means that you can't change the style of the docx tables with the current version of PanDoc. Howewer, there's a way to get your own style.

    How to get your own style ?

    1. Create a Docx Document with the style you want on your table (by creating that table)
    2. Change the extension of that file and unzip it
    3. Open word/document.xml and search for the
    4. Try to find out how your style translates in XML and change the borderProps according to what you see.

    Here's a test with a border-style I created: Custom border style

    And here is the corresponding XML:

    
      
      
      
      
      
      
    
    

    What about odt ?

    I didn't have a look at it yet, ask if you don't find by yourself using a similar method.

    Hope this helps and don't hesitate to ask something more

提交回复
热议问题