{-# LANGUAGE LambdaCase        #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Writers.LaTeX.Table
   Copyright   : Copyright (C) 2006-2020 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable

Output LaTeX formatted tables.
-}
module Text.Pandoc.Writers.LaTeX.Table
  ( tableToLaTeX
  ) where
import Control.Monad.State.Strict
import Data.List (intersperse)
import Data.Text (Text)
import qualified Data.Text as T
import Text.Pandoc.Class.PandocMonad (PandocMonad)
import Text.Pandoc.Definition
import Text.DocLayout
  ( Doc, braces, cr, empty, hcat, hsep, isEmpty, literal, nest
  , text, vcat, ($$) )
import Text.Pandoc.Shared (splitBy)
import Text.Pandoc.Walk (walk)
import Text.Pandoc.Writers.Shared (toLegacyTable)
import Text.Pandoc.Writers.LaTeX.Caption (getCaption)
import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)
import Text.Pandoc.Writers.LaTeX.Types
  ( LW, WriterState (stBeamer, stExternalNotes, stInMinipage, stNotes, stTable) )
import Text.Printf (printf)

tableToLaTeX :: PandocMonad m
             => ([Inline] -> LW m (Doc Text))
             -> ([Block]  -> LW m (Doc Text))
             -> Caption -> [ColSpec] -> TableHead -> [TableBody] -> TableFoot
             -> LW m (Doc Text)
tableToLaTeX :: ([Inline] -> LW m (Doc Text))
-> ([Block] -> LW m (Doc Text))
-> Caption
-> [ColSpec]
-> TableHead
-> [TableBody]
-> TableFoot
-> LW m (Doc Text)
tableToLaTeX [Inline] -> LW m (Doc Text)
inlnsToLaTeX [Block] -> LW m (Doc Text)
blksToLaTeX Caption
blkCapt [ColSpec]
specs TableHead
thead [TableBody]
tbody TableFoot
tfoot = do
  let ([Inline]
caption, [Alignment]
aligns, [Double]
widths, [[Block]]
heads, [[[Block]]]
rows) =
        Caption
-> [ColSpec]
-> TableHead
-> [TableBody]
-> TableFoot
-> ([Inline], [Alignment], [Double], [[Block]], [[[Block]]])
toLegacyTable Caption
blkCapt [ColSpec]
specs TableHead
thead [TableBody]
tbody TableFoot
tfoot
  -- simple tables have to have simple cells:
  let isSimple :: [Block] -> Bool
isSimple = \case
        [Plain [Inline]
_] -> Bool
True
        [Para  [Inline]
_] -> Bool
True
        []        -> Bool
True
        [Block]
_         -> Bool
False
  let widths' :: [Double]
widths' = if (Double -> Bool) -> [Double] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0) [Double]
widths Bool -> Bool -> Bool
&& Bool -> Bool
not (([[Block]] -> Bool) -> [[[Block]]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (([Block] -> Bool) -> [[Block]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
isSimple) [[[Block]]]
rows)
                   then Int -> Double -> [Double]
forall a. Int -> a -> [a]
replicate ([Alignment] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Alignment]
aligns)
                          (Double
1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Alignment] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Alignment]
aligns))
                   else [Double]
widths
  (Doc Text
captionText, Doc Text
captForLof, Doc Text
captNotes) <- ([Inline] -> LW m (Doc Text))
-> Bool -> [Inline] -> LW m (Doc Text, Doc Text, Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> Bool -> [Inline] -> LW m (Doc Text, Doc Text, Doc Text)
getCaption [Inline] -> LW m (Doc Text)
inlnsToLaTeX Bool
False [Inline]
caption
  let toHeaders :: [[Block]] -> LW m (Doc Text)
toHeaders [[Block]]
hs = do Doc Text
contents <- ([Block] -> LW m (Doc Text))
-> Bool -> [Alignment] -> [[Block]] -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Block] -> LW m (Doc Text))
-> Bool -> [Alignment] -> [[Block]] -> LW m (Doc Text)
tableRowToLaTeX [Block] -> LW m (Doc Text)
blksToLaTeX Bool
True [Alignment]
aligns [[Block]]
hs
                        Doc Text -> LW m (Doc Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text
"\\toprule" Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
contents Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"\\midrule")
  let removeNote :: Inline -> Inline
removeNote (Note [Block]
_) = Attr -> [Inline] -> Inline
Span (Text
"", [], []) []
      removeNote Inline
x        = Inline
x
  Doc Text
firsthead <- if Doc Text -> Bool
forall a. Doc a -> Bool
isEmpty Doc Text
captionText Bool -> Bool -> Bool
|| ([Block] -> Bool) -> [[Block]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Block]]
heads
                  then Doc Text -> LW m (Doc Text)
forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
forall a. Doc a
empty
                  else (Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ String -> Doc Text
forall a. HasChars a => String -> Doc a
text String
"\\endfirsthead") (Doc Text -> Doc Text) -> LW m (Doc Text) -> LW m (Doc Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [[Block]] -> LW m (Doc Text)
toHeaders [[Block]]
heads
  Doc Text
head' <- if ([Block] -> Bool) -> [[Block]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Block]]
heads
              then Doc Text -> LW m (Doc Text)
forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
"\\toprule"
              -- avoid duplicate notes in head and firsthead:
              else [[Block]] -> LW m (Doc Text)
toHeaders (if Doc Text -> Bool
forall a. Doc a -> Bool
isEmpty Doc Text
firsthead
                                 then [[Block]]
heads
                                 else (Inline -> Inline) -> [[Block]] -> [[Block]]
forall a b. Walkable a b => (a -> a) -> b -> b
walk Inline -> Inline
removeNote [[Block]]
heads)
  let capt :: Doc Text
capt = if Doc Text -> Bool
forall a. Doc a -> Bool
isEmpty Doc Text
captionText
                then Doc Text
forall a. Doc a
empty
                else Doc Text
"\\caption" Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
captForLof Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text -> Doc Text
forall a. HasChars a => Doc a -> Doc a
braces Doc Text
captionText
                         Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
"\\tabularnewline"
  [Doc Text]
rows' <- ([[Block]] -> LW m (Doc Text))
-> [[[Block]]] -> StateT WriterState m [Doc Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (([Block] -> LW m (Doc Text))
-> Bool -> [Alignment] -> [[Block]] -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Block] -> LW m (Doc Text))
-> Bool -> [Alignment] -> [[Block]] -> LW m (Doc Text)
tableRowToLaTeX [Block] -> LW m (Doc Text)
blksToLaTeX Bool
False [Alignment]
aligns) [[[Block]]]
rows
  let colDescriptors :: Doc Text
colDescriptors =
         (if (Double -> Bool) -> [Double] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0) [Double]
widths'
             then [Doc Text] -> Doc Text
forall a. [Doc a] -> Doc a
hcat ([Doc Text] -> Doc Text)
-> ([Text] -> [Doc Text]) -> [Text] -> Doc Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Doc Text) -> [Text] -> [Doc Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Doc Text
forall a. HasChars a => a -> Doc a
literal
             else (\[Text]
xs -> Doc Text
forall a. Doc a
cr Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Int -> Doc Text -> Doc Text
forall a. IsString a => Int -> Doc a -> Doc a
nest Int
2 ([Doc Text] -> Doc Text
forall a. [Doc a] -> Doc a
vcat ([Doc Text] -> Doc Text) -> [Doc Text] -> Doc Text
forall a b. (a -> b) -> a -> b
$ (Text -> Doc Text) -> [Text] -> [Doc Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Doc Text
forall a. HasChars a => a -> Doc a
literal [Text]
xs))) ([Text] -> Doc Text) -> [Text] -> Doc Text
forall a b. (a -> b) -> a -> b
$
         (Alignment -> Double -> Text) -> [Alignment] -> [Double] -> [Text]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Int -> Alignment -> Double -> Text
toColDescriptor ([Double] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
widths')) [Alignment]
aligns [Double]
widths'
  (WriterState -> WriterState) -> StateT WriterState m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((WriterState -> WriterState) -> StateT WriterState m ())
-> (WriterState -> WriterState) -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ \WriterState
s -> WriterState
s{ stTable :: Bool
stTable = Bool
True }
  Doc Text
notes <- [Doc Text] -> Doc Text
notesToLaTeX ([Doc Text] -> Doc Text)
-> StateT WriterState m [Doc Text] -> LW m (Doc Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (WriterState -> [Doc Text]) -> StateT WriterState m [Doc Text]
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> [Doc Text]
stNotes
  Doc Text -> LW m (Doc Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ Doc Text
"\\begin{longtable}[]" Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<>
              Doc Text -> Doc Text
forall a. HasChars a => Doc a -> Doc a
braces (Doc Text
"@{}" Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
colDescriptors Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
"@{}")
              -- the @{} removes extra space at beginning and end
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
capt
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
firsthead
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
head'
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"\\endhead"
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ [Doc Text] -> Doc Text
forall a. [Doc a] -> Doc a
vcat [Doc Text]
rows'
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"\\bottomrule"
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"\\end{longtable}"
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
captNotes
         Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
notes

toColDescriptor :: Int -> Alignment -> Double -> Text
toColDescriptor :: Int -> Alignment -> Double -> Text
toColDescriptor Int
_numcols Alignment
align Double
0 =
  case Alignment
align of
         Alignment
AlignLeft    -> Text
"l"
         Alignment
AlignRight   -> Text
"r"
         Alignment
AlignCenter  -> Text
"c"
         Alignment
AlignDefault -> Text
"l"
toColDescriptor Int
numcols Alignment
align Double
width =
  String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String -> String -> Int -> Double -> String
forall r. PrintfType r => String -> r
printf
     String
">{%s\\arraybackslash}p{(\\columnwidth - %d\\tabcolsep) * \\real{%0.2f}}"
     String
align'
     ((Int
numcols Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)
     Double
width
 where
   align' :: String
   align' :: String
align' = case Alignment
align of
              Alignment
AlignLeft    -> String
"\\raggedright"
              Alignment
AlignRight   -> String
"\\raggedleft"
              Alignment
AlignCenter  -> String
"\\centering"
              Alignment
AlignDefault -> String
"\\raggedright"

tableRowToLaTeX :: PandocMonad m
                => ([Block] -> LW m (Doc Text))
                -> Bool
                -> [Alignment]
                -> [[Block]]
                -> LW m (Doc Text)
tableRowToLaTeX :: ([Block] -> LW m (Doc Text))
-> Bool -> [Alignment] -> [[Block]] -> LW m (Doc Text)
tableRowToLaTeX [Block] -> LW m (Doc Text)
blockListToLaTeX Bool
header [Alignment]
aligns [[Block]]
cols = do
  [Doc Text]
cells <- ((Alignment, [Block]) -> LW m (Doc Text))
-> [(Alignment, [Block])] -> StateT WriterState m [Doc Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (([Block] -> LW m (Doc Text))
-> Bool -> (Alignment, [Block]) -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Block] -> LW m (Doc Text))
-> Bool -> (Alignment, [Block]) -> LW m (Doc Text)
tableCellToLaTeX [Block] -> LW m (Doc Text)
blockListToLaTeX Bool
header) ([(Alignment, [Block])] -> StateT WriterState m [Doc Text])
-> [(Alignment, [Block])] -> StateT WriterState m [Doc Text]
forall a b. (a -> b) -> a -> b
$ [Alignment] -> [[Block]] -> [(Alignment, [Block])]
forall a b. [a] -> [b] -> [(a, b)]
zip [Alignment]
aligns [[Block]]
cols
  Doc Text -> LW m (Doc Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ [Doc Text] -> Doc Text
forall a. [Doc a] -> Doc a
hsep (Doc Text -> [Doc Text] -> [Doc Text]
forall a. a -> [a] -> [a]
intersperse Doc Text
"&" [Doc Text]
cells) Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
" \\\\ \\addlinespace"

-- For simple latex tables (without minipages or parboxes),
-- we need to go to some lengths to get line breaks working:
-- as LineBreak bs = \vtop{\hbox{\strut as}\hbox{\strut bs}}.
fixLineBreaks :: Block -> Block
fixLineBreaks :: Block -> Block
fixLineBreaks (Para [Inline]
ils)  = [Inline] -> Block
Para ([Inline] -> Block) -> [Inline] -> Block
forall a b. (a -> b) -> a -> b
$ [Inline] -> [Inline]
fixLineBreaks' [Inline]
ils
fixLineBreaks (Plain [Inline]
ils) = [Inline] -> Block
Plain ([Inline] -> Block) -> [Inline] -> Block
forall a b. (a -> b) -> a -> b
$ [Inline] -> [Inline]
fixLineBreaks' [Inline]
ils
fixLineBreaks Block
x           = Block
x

fixLineBreaks' :: [Inline] -> [Inline]
fixLineBreaks' :: [Inline] -> [Inline]
fixLineBreaks' [Inline]
ils = case (Inline -> Bool) -> [Inline] -> [[Inline]]
forall a. (a -> Bool) -> [a] -> [[a]]
splitBy (Inline -> Inline -> Bool
forall a. Eq a => a -> a -> Bool
== Inline
LineBreak) [Inline]
ils of
                       []     -> []
                       [[Inline]
xs]   -> [Inline]
xs
                       [[Inline]]
chunks -> Format -> Text -> Inline
RawInline Format
"tex" Text
"\\vtop{" Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:
                                 ([Inline] -> [Inline]) -> [[Inline]] -> [Inline]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [Inline] -> [Inline]
tohbox [[Inline]]
chunks [Inline] -> [Inline] -> [Inline]
forall a. Semigroup a => a -> a -> a
<>
                                 [Format -> Text -> Inline
RawInline Format
"tex" Text
"}"]
  where tohbox :: [Inline] -> [Inline]
tohbox [Inline]
ys = Format -> Text -> Inline
RawInline Format
"tex" Text
"\\hbox{\\strut " Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: [Inline]
ys [Inline] -> [Inline] -> [Inline]
forall a. Semigroup a => a -> a -> a
<>
                    [Format -> Text -> Inline
RawInline Format
"tex" Text
"}"]

-- We also change display math to inline math, since display
-- math breaks in simple tables.
displayMathToInline :: Inline -> Inline
displayMathToInline :: Inline -> Inline
displayMathToInline (Math MathType
DisplayMath Text
x) = MathType -> Text -> Inline
Math MathType
InlineMath Text
x
displayMathToInline Inline
x                    = Inline
x

tableCellToLaTeX :: PandocMonad m
                 => ([Block] -> LW m (Doc Text))
                 -> Bool -> (Alignment, [Block])
                 -> LW m (Doc Text)
tableCellToLaTeX :: ([Block] -> LW m (Doc Text))
-> Bool -> (Alignment, [Block]) -> LW m (Doc Text)
tableCellToLaTeX [Block] -> LW m (Doc Text)
blockListToLaTeX Bool
header (Alignment
align, [Block]
blocks) = do
  Bool
beamer <- (WriterState -> Bool) -> StateT WriterState m Bool
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
stBeamer
  Bool
externalNotes <- (WriterState -> Bool) -> StateT WriterState m Bool
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
stExternalNotes
  Bool
inMinipage <- (WriterState -> Bool) -> StateT WriterState m Bool
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
stInMinipage
  -- See #5367 -- footnotehyper/footnote don't work in beamer,
  -- so we need to produce the notes outside the table...
  (WriterState -> WriterState) -> StateT WriterState m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((WriterState -> WriterState) -> StateT WriterState m ())
-> (WriterState -> WriterState) -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ stExternalNotes :: Bool
stExternalNotes = Bool
beamer }
  let isPlainOrPara :: Block -> Bool
isPlainOrPara = \case
        Para{}  -> Bool
True
        Plain{} -> Bool
True
        Block
_       -> Bool
False
  Doc Text
result <-
    if (Block -> Bool) -> [Block] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Block -> Bool
isPlainOrPara [Block]
blocks
       then
         [Block] -> LW m (Doc Text)
blockListToLaTeX ([Block] -> LW m (Doc Text)) -> [Block] -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ (Block -> Block) -> [Block] -> [Block]
forall a b. Walkable a b => (a -> a) -> b -> b
walk Block -> Block
fixLineBreaks ([Block] -> [Block]) -> [Block] -> [Block]
forall a b. (a -> b) -> a -> b
$ (Inline -> Inline) -> [Block] -> [Block]
forall a b. Walkable a b => (a -> a) -> b -> b
walk Inline -> Inline
displayMathToInline [Block]
blocks
       else do
         (WriterState -> WriterState) -> StateT WriterState m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((WriterState -> WriterState) -> StateT WriterState m ())
-> (WriterState -> WriterState) -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ stInMinipage :: Bool
stInMinipage = Bool
True }
         Doc Text
cellContents <- [Block] -> LW m (Doc Text)
blockListToLaTeX [Block]
blocks
         (WriterState -> WriterState) -> StateT WriterState m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((WriterState -> WriterState) -> StateT WriterState m ())
-> (WriterState -> WriterState) -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ stInMinipage :: Bool
stInMinipage = Bool
inMinipage }
         let valign :: Doc Text
valign = String -> Doc Text
forall a. HasChars a => String -> Doc a
text (String -> Doc Text) -> String -> Doc Text
forall a b. (a -> b) -> a -> b
$ if Bool
header then String
"[b]" else String
"[t]"
         let halign :: Doc Text
halign = case Alignment
align of
                        Alignment
AlignLeft    -> Doc Text
"\\raggedright"
                        Alignment
AlignRight   -> Doc Text
"\\raggedleft"
                        Alignment
AlignCenter  -> Doc Text
"\\centering"
                        Alignment
AlignDefault -> Doc Text
"\\raggedright"
         Doc Text -> LW m (Doc Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ Doc Text
"\\begin{minipage}" Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
valign Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<>
                  Doc Text -> Doc Text
forall a. HasChars a => Doc a -> Doc a
braces Doc Text
"\\linewidth" Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
halign Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
forall a. Doc a
cr Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<>
                  Doc Text
cellContents Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
forall a. Doc a
cr Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<>
                  Doc Text
"\\end{minipage}"
  (WriterState -> WriterState) -> StateT WriterState m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((WriterState -> WriterState) -> StateT WriterState m ())
-> (WriterState -> WriterState) -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ stExternalNotes :: Bool
stExternalNotes = Bool
externalNotes }
  Doc Text -> LW m (Doc Text)
forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
result