Avoid using 'error' for unassigned table cells.

Instead, throw a regular pandoc error.  This is not necessarily
a programming error, as it can be triggered by inserting a
cell with ColSpan 0 in the AST.  Unfortunately the types
don't prevent that.

Closes #8468.
This commit is contained in:
John MacFarlane
2022-12-02 14:47:29 -08:00
parent 8b01e200f0
commit c5beb1db45
2 changed files with 34 additions and 30 deletions
+32 -29
View File
@@ -14,7 +14,8 @@ module Text.Pandoc.Writers.Docx.Table
) where
import Control.Monad.State.Strict ( modify, gets )
import Control.Monad ( unless )
import Control.Monad ( unless , zipWithM )
import Control.Monad.Except ( throwError )
import Data.Array ( elems, (!), assocs, indices )
import Data.Text (Text)
import Text.Pandoc.Definition
@@ -42,6 +43,7 @@ import Control.Monad.Reader (asks)
import Text.Pandoc.Shared ( tshow, stringify )
import Text.Pandoc.Options (WriterOptions, isEnabled)
import Text.Pandoc.Extensions (Extension(Ext_native_numbering))
import Text.Pandoc.Error (PandocError(PandocSomeError))
import Text.Printf (printf)
import Text.Pandoc.Writers.GridTable
( rowArray,
@@ -180,8 +182,8 @@ cellGridToOpenXML :: PandocMonad m
cellGridToOpenXML blocksToOpenXML rowType aligns part@(Part _ cellArray _) =
if null (elems cellArray)
then return mempty
else mapM (rowToOpenXML blocksToOpenXML) $
partToRows rowType aligns part
else partToRows rowType aligns part >>=
mapM (rowToOpenXML blocksToOpenXML)
data OOXMLCell
= OOXMLCell Attr Alignment RowSpan ColSpan [Block]
@@ -189,32 +191,33 @@ data OOXMLCell
data OOXMLRow = OOXMLRow RowType Attr [OOXMLCell]
partToRows :: RowType -> [Alignment] -> Part -> [OOXMLRow]
partToRows rowType aligns part =
let
toOOXMLCell :: Alignment -> RowIndex -> ColIndex -> GridCell -> [OOXMLCell]
toOOXMLCell columnAlign ridx cidx = \case
ContentCell attr align rowspan colspan blocks ->
-- Respect non-default, cell specific alignment.
let align' = case align of
AlignDefault -> columnAlign
_ -> align
in [OOXMLCell attr align' rowspan colspan blocks]
ContinuationCell idx'@(ridx',cidx') | ridx /= ridx', cidx == cidx' ->
case (partCellArray part)!idx' of
(ContentCell _ _ _ colspan _) -> [OOXMLCellMerge colspan]
x -> error $ "Content cell expected, got, " ++ show x ++
" at index " ++ show idx'
_ -> mempty
mkRow :: (RowIndex, Attr) -> OOXMLRow
mkRow (ridx, attr) = OOXMLRow rowType attr
. mconcat
. zipWith (\align -> uncurry $ toOOXMLCell align ridx)
aligns
. assocs
. rowArray ridx
$ partCellArray part
in map mkRow $ assocs (partRowAttrs part)
partToRows :: PandocMonad m
=> RowType -> [Alignment] -> Part -> WS m [OOXMLRow]
partToRows rowType aligns part = do
let toOOXMLCell :: PandocMonad m =>
Alignment -> RowIndex -> ColIndex -> GridCell -> WS m [OOXMLCell]
toOOXMLCell columnAlign ridx cidx = \case
UnassignedCell ->
throwError $ PandocSomeError "Encountered unassigned table cell"
ContentCell attr align rowspan colspan blocks -> do
-- Respect non-default, cell specific alignment.
let align' = case align of
AlignDefault -> columnAlign
_ -> align
return [OOXMLCell attr align' rowspan colspan blocks]
ContinuationCell idx'@(ridx',cidx') | ridx /= ridx', cidx == cidx' -> do
case (partCellArray part)!idx' of
(ContentCell _ _ _ colspan _) -> return [OOXMLCellMerge colspan]
x -> error $ "Content cell expected, got, " ++ show x ++
" at index " ++ show idx'
_ -> return mempty
let mkRow :: PandocMonad m => (RowIndex, Attr) -> WS m OOXMLRow
mkRow (ridx, attr) = do
cs <- zipWithM (\align -> uncurry $ toOOXMLCell align ridx)
aligns
(assocs . rowArray ridx $ partCellArray part)
return $ OOXMLRow rowType attr . mconcat $ cs
mapM mkRow $ assocs (partRowAttrs part)
rowToOpenXML :: PandocMonad m
=> ([Block] -> WS m [Content])
+2 -1
View File
@@ -45,6 +45,7 @@ import qualified Text.Pandoc.Builder as B
data GridCell
= ContentCell Attr Alignment RowSpan ColSpan [Block]
| ContinuationCell CellIndex
| UnassignedCell
deriving (Show)
-- | Row index in a table part.
@@ -103,7 +104,7 @@ data BuilderCell
fromBuilderCell :: BuilderCell -> GridCell
fromBuilderCell = \case
FilledCell c -> c
FreeCell -> error "Found an unassigned cell. Please report this as a bug!"
FreeCell -> UnassignedCell
rowsToPart :: Attr -> [B.Row] -> Part
rowsToPart attr = \case