diff options
| author | John MacFarlane <[email protected]> | 2025-01-10 22:45:19 -0800 |
|---|---|---|
| committer | John MacFarlane <[email protected]> | 2025-01-10 22:50:17 -0800 |
| commit | cbe67b9602a736976ef6921aefbbc60d51c6755a (patch) | |
| tree | d50ac8fb2a85cb4b4270d1ffca58e7cf8d53e11f /src | |
| parent | 6051d62e56f4c64857ac5d6b2d6fab9390f6ea5a (diff) | |
Docx reader and writer: support row heads.
Reader: When `w:tblLook` has `w:firstColumn` set (or an equivalent bit
mask), we set row heads = 1 in the AST.
Writer: set `w:firstColumn` in `w:tblLook` when there are row
heads. (Word only allows one, so this is triggered by any number
of row heads > 0.)
Closes #9495.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Text/Pandoc/Readers/Docx.hs | 4 | ||||
| -rw-r--r-- | src/Text/Pandoc/Readers/Docx/Parse.hs | 24 | ||||
| -rw-r--r-- | src/Text/Pandoc/Writers/Docx/Table.hs | 8 |
3 files changed, 26 insertions, 10 deletions
diff --git a/src/Text/Pandoc/Readers/Docx.hs b/src/Text/Pandoc/Readers/Docx.hs index efe104af7..3222e81b6 100644 --- a/src/Text/Pandoc/Readers/Docx.hs +++ b/src/Text/Pandoc/Readers/Docx.hs @@ -815,6 +815,8 @@ bodyPartToBlocks (Tbl mbsty cap grid look parts) = do cap' = caption shortCaption fullCaption (hdr, rows) = splitHeaderRows (firstRowFormatting look) parts + let rowHeadCols = if firstColumnFormatting look then 1 else 0 + let width = maybe 0 maximum $ nonEmpty $ map rowLength parts rowLength :: Docx.Row -> Int rowLength (Docx.Row _ c) = sum (fmap (\(Docx.Cell _ gridSpan _ _) -> fromIntegral gridSpan) c) @@ -838,7 +840,7 @@ bodyPartToBlocks (Tbl mbsty cap grid look parts) = do return $ tableWith attr cap' (zip alignments widths) (TableHead nullAttr headerCells) - [TableBody nullAttr 0 [] bodyCells] + [TableBody nullAttr (RowHeadColumns rowHeadCols) [] bodyCells] (TableFoot nullAttr []) bodyPartToBlocks HRule = pure Pandoc.horizontalRule diff --git a/src/Text/Pandoc/Readers/Docx/Parse.hs b/src/Text/Pandoc/Readers/Docx/Parse.hs index 99ffcaf09..43adf7930 100644 --- a/src/Text/Pandoc/Readers/Docx/Parse.hs +++ b/src/Text/Pandoc/Readers/Docx/Parse.hs @@ -294,11 +294,15 @@ data BodyPart = Paragraph ParagraphStyle [ParPart] type TblGrid = [Integer] -newtype TblLook = TblLook {firstRowFormatting::Bool} +data TblLook = TblLook { firstRowFormatting ::Bool + , firstColumnFormatting :: Bool + } deriving Show defaultTblLook :: TblLook -defaultTblLook = TblLook{firstRowFormatting = False} +defaultTblLook = TblLook{ firstRowFormatting = False + , firstColumnFormatting = False + } data Row = Row TblHeader [Cell] deriving Show @@ -691,17 +695,25 @@ elemToTblGrid _ _ = throwError WrongElem elemToTblLook :: NameSpaces -> Element -> D TblLook elemToTblLook ns element | isElem ns "w" "tblLook" element = - let firstRow = findAttrByName ns "w" "firstRow" element - val = findAttrByName ns "w" "val" element + let val = findAttrByName ns "w" "val" element firstRowFmt = - case firstRow of + case findAttrByName ns "w" "firstRow" element of Just "1" -> True Just _ -> False Nothing -> case val of Just bitMask -> testBitMask bitMask 0x020 Nothing -> False + firstColFmt = + case findAttrByName ns "w" "firstColumn" element of + Just "1" -> True + Just _ -> False + Nothing -> case val of + Just bitMask -> testBitMask bitMask 0x080 + Nothing -> False in - return TblLook{firstRowFormatting = firstRowFmt} + return TblLook{ firstRowFormatting = firstRowFmt + , firstColumnFormatting = firstColFmt + } elemToTblLook _ _ = throwError WrongElem elemToRow :: NameSpaces -> Element -> D Row diff --git a/src/Text/Pandoc/Writers/Docx/Table.hs b/src/Text/Pandoc/Writers/Docx/Table.hs index 0caab7cd5..6dcb3f027 100644 --- a/src/Text/Pandoc/Writers/Docx/Table.hs +++ b/src/Text/Pandoc/Writers/Docx/Table.hs @@ -63,6 +63,7 @@ import Text.Pandoc.XML.Light.Types import qualified Data.Text as T import qualified Text.Pandoc.Translations as Term import qualified Text.Pandoc.Writers.GridTable as Grid +import Data.Bits ((.|.)) tableToOpenXML :: PandocMonad m => WriterOptions @@ -71,7 +72,7 @@ tableToOpenXML :: PandocMonad m -> WS m [Content] tableToOpenXML opts blocksToOpenXML gridTable = do setFirstPara - let (Grid.Table (ident,_,tableAttr) caption colspecs _rowheads thead tbodies tfoot) = + let (Grid.Table (ident,_,tableAttr) caption colspecs rowheads thead tbodies tfoot) = gridTable let (Caption _maybeShortCaption captionBlocks) = caption tablenum <- gets stNextTableNum @@ -106,7 +107,8 @@ tableToOpenXML opts blocksToOpenXML gridTable = do -- 0×0100 Apply last column conditional formatting -- 0×0200 Do not apply row banding conditional formatting -- 0×0400 Do not apply column banding conditional formattin - let tblLookVal = if hasHeader then (0x20 :: Int) else 0 + let tblLookVal = (if hasHeader then (0x20 :: Int) else 0) .|. + (if rowheads > 0 then (0x80 :: Int) else 0) let (gridCols, tblWattr) = tableLayout (elems colspecs) listLevel <- asks envListLevel let tblStyle = fromMaybe "Table" (lookup "custom-style" tableAttr) @@ -122,7 +124,7 @@ tableToOpenXML opts blocksToOpenXML gridTable = do [ mknode "w:tblLayout" [("w:type", "fixed")] () | hasWidths ] ++ [ mknode "w:tblLook" [("w:firstRow",if hasHeader then "1" else "0") ,("w:lastRow",if hasFooter then "1" else "0") - ,("w:firstColumn","0") + ,("w:firstColumn",if rowheads > 0 then "1" else "0") ,("w:lastColumn","0") ,("w:noHBand","0") ,("w:noVBand","0") |
