@@ -39,13 +39,14 @@ module Text.Pandoc.Writers.Shared (
3939 , tagWithAttrs
4040 , fixDisplayMath
4141 , unsmartify
42+ , gridTable
4243 )
4344where
4445import Control.Monad (liftM)
4546import Data.Aeson (FromJSON (..), Result (..), ToJSON (..), Value (Object),
4647 encode, fromJSON)
4748import qualified Data.HashMap.Strict as H
48−import Data.List (groupBy)
49+import Data.List (groupBy, intersperse)
4950import qualified Data.Map as M
5051import Data.Maybe (isJust)
5152import qualified Data.Text as T
@@ -216,3 +217,43 @@ unsmartify opts ('\8212':xs)
216217unsmartify opts (x:xs) = x : unsmartify opts xs
217218unsmartify _ [] = []
218219
220+gridTable :: Monad m => Bool -> [Alignment] -> [Int]
221+ -> [Doc] -> [[Doc]] -> m Doc
222+gridTable headless aligns widthsInChars headers' rawRows = do
223+ let hpipeBlocks blocks = hcat [beg, middle, end]
224+ where h = maximum (1 : map height blocks)
225+ sep' = lblock 3 $ vcat (map text $ replicate h " | ")
226+ beg = lblock 2 $ vcat (map text $ replicate h "| ")
227+ end = lblock 2 $ vcat (map text $ replicate h " |")
228+ middle = chomp $ hcat $ intersperse sep' blocks
229+ let makeRow = hpipeBlocks . zipWith lblock widthsInChars
230+ let head' = makeRow headers'
231+ let rows' = map (makeRow . map chomp) rawRows
232+ let borderpart ch align widthInChars =
233+ let widthInChars' = if widthInChars < 1 then 1 else widthInChars
234+ in (if (align == AlignLeft || align == AlignCenter)
235+ then char ':'
236+ else char ch) <>
237+ text (replicate widthInChars' ch) <>
238+ (if (align == AlignRight || align == AlignCenter)
239+ then char ':'
240+ else char ch)
241+ let border ch aligns' widthsInChars' =
242+ char '+' <>
243+ hcat (intersperse (char '+') (zipWith (borderpart ch)
244+ aligns' widthsInChars')) <> char '+'
245+ let body = vcat $ intersperse (border '-' (repeat AlignDefault) widthsInChars)
246+ rows'
247+ let head'' = if headless
248+ then empty
249+ else head' $$ border '=' aligns widthsInChars
250+ if headless
251+ then return $
252+ border '-' aligns widthsInChars $$
253+ body $$
254+ border '-' (repeat AlignDefault) widthsInChars
255+ else return $
256+ border '-' (repeat AlignDefault) widthsInChars $$
257+ head'' $$
258+ body $$
259+ border '-' (repeat AlignDefault) widthsInChars