@@ -42,11 +42,12 @@ tableToOpenXML blocksToOpenXML gridTable = do
4242 then return []
4343 else withParaPropM (pStyleM "Table Caption")
4444 $ blocksToOpenXML captionBlocks
45− head' <- cellGridToOpenXML blocksToOpenXML thead
46− bodies <- mapM (cellGridToOpenXML blocksToOpenXML) tbodies
47− foot' <- cellGridToOpenXML blocksToOpenXML tfoot
45+ head' <- cellGridToOpenXML blocksToOpenXML HeadRow thead
46+ bodies <- mapM (cellGridToOpenXML blocksToOpenXML BodyRow) tbodies
47+ foot' <- cellGridToOpenXML blocksToOpenXML FootRow tfoot
4848
4949 let hasHeader = not . null . indices . partRowAttrs $ thead
50+ let hasFooter = not . null . indices . partRowAttrs $ tfoot
5051 -- for compatibility with Word <= 2007, we include a val with a bitmask
5152 -- 0×0020 Apply first row conditional formatting
5253 -- 0×0040 Apply last row conditional formatting
@@ -61,7 +62,7 @@ tableToOpenXML blocksToOpenXML gridTable = do
6162 ( mknode "w:tblStyle" [("w:val","Table")] () :
6263 mknode "w:tblW" tblWattr () :
6364 mknode "w:tblLook" [("w:firstRow",if hasHeader then "1" else "0")
64− ,("w:lastRow","0")
65+ ,("w:lastRow",if hasFooter then "1" else "0")
6566 ,("w:firstColumn","0")
6667 ,("w:lastColumn","0")
6768 ,("w:noHBand","0")
@@ -77,6 +78,9 @@ tableToOpenXML blocksToOpenXML gridTable = do
7778 modify $ \s -> s { stInTable = False }
7879 return $ captionXml ++ [Elem tbl]
7980
81+-- | Parts of a table
82+data RowType = HeadRow | BodyRow | FootRow
83+
8084alignmentToString :: Alignment -> Text
8185alignmentToString = \case
8286 AlignLeft -> "left"
@@ -104,22 +108,23 @@ tableLayout specs =
104108 , [ ("w:type", "pct"), ("w:w", tshow rowwidth) ])
105109
106110cellGridToOpenXML :: PandocMonad m
107− => ([Block] -> WS m [Content])
108− -> Part
109− -> WS m [Element]
110−cellGridToOpenXML blocksToOpenXML part@(Part _ _ rowAttrs) =
111+ => ([Block] -> WS m [Content])
112+ -> RowType
113+ -> Part
114+ -> WS m [Element]
115+cellGridToOpenXML blocksToOpenXML rowType part@(Part _ _ rowAttrs) =
111116 if null (indices rowAttrs)
112117 then return mempty
113− else mapM (rowToOpenXML blocksToOpenXML) $ partToRows part
118+ else mapM (rowToOpenXML blocksToOpenXML) $ partToRows rowType part
114119
115120data OOXMLCell
116121 = OOXMLCell Attr Alignment RowSpan ColSpan [Block]
117122 | OOXMLCellMerge ColSpan
118123
119−data OOXMLRow = OOXMLRow Attr [OOXMLCell]
124+data OOXMLRow = OOXMLRow RowType Attr [OOXMLCell]
120125
121−partToRows :: Part -> [OOXMLRow]
122−partToRows part =
126+partToRows :: RowType -> Part -> [OOXMLRow]
127+partToRows rowType part =
123128 let
124129 toOOXMLCell :: RowIndex -> ColIndex -> GridCell -> [OOXMLCell]
125130 toOOXMLCell ridx cidx = \case
@@ -132,7 +137,7 @@ partToRows part =
132137 " at index " ++ show idx'
133138 _ -> mempty
134139 mkRow :: (RowIndex, Attr) -> OOXMLRow
135− mkRow (ridx, attr) = OOXMLRow attr
140+ mkRow (ridx, attr) = OOXMLRow rowType attr
136141 . concatMap (uncurry $ toOOXMLCell ridx)
137142 . assocs
138143 . rowArray ridx
@@ -143,12 +148,17 @@ rowToOpenXML :: PandocMonad m
143148 => ([Block] -> WS m [Content])
144149 -> OOXMLRow
145150 -> WS m Element
146−rowToOpenXML blocksToOpenXML (OOXMLRow _attr cells) = do
151+rowToOpenXML blocksToOpenXML (OOXMLRow rowType _attr cells) = do
147152 xmlcells <- mapM (ooxmlCellToOpenXML blocksToOpenXML) cells
153+ let addTrPr = case rowType of
154+ HeadRow -> (mknode "w:trPr" []
155+ [mknode "w:tblHeader" [("w:val", "true")] ()] :)
156+ BodyRow -> id
157+ FootRow -> id
148158 -- let align' = case align of
149159 -- AlignDefault -> colAlign
150160 -- _ -> align
151− return $ mknode "w:tr" [] xmlcells
161+ return $ mknode "w:tr" [] (addTrPr xmlcells)
152162
153163ooxmlCellToOpenXML :: PandocMonad m
154164 => ([Block] -> WS m [Content])
@@ -161,8 +171,6 @@ ooxmlCellToOpenXML blocksToOpenXML = \case
161171 , mknode "w:vMerge" [("w:val", "continue")] () ]
162172 , mknode "w:p" [] [mknode "w:pPr" [] ()]]
163173 OOXMLCell _attr align rowspan (ColSpan colspan) contents -> do
164− -- we handle rowspans via 'leftpad', so we can ignore those here
165−
166174 compactStyle <- pStyleM "Compact"
167175 es <- withParaProp (alignmentFor align) $ blocksToOpenXML contents
168176 -- Table cells require a <w:p> element, even an empty one!