{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
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
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"
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
"@{}")
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"
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
"}"]
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
(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