table-layout-1.0.0.0: src/Text/Layout/Table/Pandoc.hs
-- | Render tables that can be used in <https://pandoc.org/ Pandoc>. In
-- particular, this supports the
-- <https://pandoc.org/MANUAL.html#tables pipe_tables> extension.
module Text.Layout.Table.Pandoc
( PandocSeparator
, pandocPipeTableLines
) where
import Data.List
import Data.Default.Class
import Text.Layout.Table.Cell
import Text.Layout.Table.Primitives.ColumnModifier
import Text.Layout.Table.Primitives.Header
import Text.Layout.Table.Spec.ColSpec
import Text.Layout.Table.Spec.HeaderSpec
import Text.Layout.Table.Spec.Position
import Text.Layout.Table.Spec.Util
-- | The separator to be used for 'HeaderSpec'. The only supported value is
-- 'def'. Typically, it is not necessary to use this.
data PandocSeparator
-- The value is not actually used anywhere. It exists with the sole
-- purpose to limit user input to the single supported character.
= PandocSeparator
instance Default PandocSeparator where
-- | A single line represented by @-@ and @|@.
def = PandocSeparator
-- | Generate a table that is readable but also serves as input to pandoc.
--
-- >>> mapM_ putStrLn $ pandocPipeTableLines [defColSpec, numCol] (titlesH ["text", "numeric value"]) [["a", "1.5"], ["b", "6.60000"]]
-- |text|numberic value|
-- |:---|-------------:|
-- |a | 1.5 |
-- |b | 6.60000|
pandocPipeTableLines
:: Cell c
=> [ColSpec]
-> HeaderSpec PandocSeparator c
-> [Row String]
-> [String]
pandocPipeTableLines specs h tab =
fmap (intercalate "|" . ("" :) . (++ [""])) $ consHeaderRow . (vSeparators :) $ zipWith ($) cmfs <$> tab
where
cmfs = zipWith (\spec cmi -> columnModifier (position spec) (cutMark spec) cmi) specs cmis
cmis = zipWith (ensureWidthCMI 2) posSpecs $ fitHeaderIntoCMIs $ deriveColModInfosFromGrid specs tab
posSpecs = fmap position specs
(fitHeaderIntoCMIs, consHeaderRow) = case h of
NoneHS _ -> (id, id)
_ ->
( fitTitlesCMI titles posSpecs
, (zipWith4 headerCellModifier headerSpecs (cutMark <$> specs) cmis titles :)
)
where
(headerSpecs, titles) = unzip $ headerContents h
vSeparators = zipWith (\pos cmi -> applyPandocPositionMarker pos $ replicate (widthCMI cmi) '-') posSpecs cmis
applyPandocPositionMarker :: Position H -> String -> String
applyPandocPositionMarker p = case p of
Start -> markLeft
Center -> markRight . markLeft
End -> markRight
where
markLeft = (':' :) . drop 1
markRight = reverse . (':' :) . drop 1 . reverse