-- | Block output similar to default org reporting. This is stub -- version which is to be improved later. module OrgStat.Outputs.Block ( genBlockOutput ) where import Universum import qualified Data.List as L import qualified Data.Text as T import Text.PrettyPrint.Boxes (center1, hsep, left, render, right, text, vcat) import OrgStat.Ast (Org, filterHasClock, orgSubtrees, orgTitle, orgTotalDuration) import OrgStat.Outputs.Types (BlockOutput(..), BlockParams(..)) import OrgStat.Util (dropEnd, timeF) data BlockFrames = BlockFrames { bfAngle1 :: Text , bfAngle2 :: Text , bfHorizontal :: Text , bfVertical :: Text } deriving Show unicodeBlockFrames,asciiBlockFrames :: BlockFrames unicodeBlockFrames = BlockFrames "├" "└" "─" "│" asciiBlockFrames = BlockFrames "|" "\\" "-" "|" -- | Generate block output (emacs table-like). genBlockOutput :: BlockParams -> Org -> BlockOutput genBlockOutput BlockParams{..} (filterHasClock -> o0) = do BlockOutput $ fromString $ render $ hsep 2 center1 [vsep,col1,vsep,col2,vsep] where BlockFrames{..} = if _bpUnicode then unicodeBlockFrames else asciiBlockFrames text' = text . toString elems' = withDepth (0::Int) o0 col1 = vcat left $ map (text' . trimTitle . fst) elems' col2 = vcat right $ map (text' . snd) elems' vsep = vcat center1 $ replicate (length elems') (text $ toString bfVertical) trimTitle t | T.length t > _bpMaxLength = T.take (_bpMaxLength - 3) t <> "..." | otherwise = t formatter o = let dur = orgTotalDuration o titleRaw = T.take _bpMaxLength $ o ^. orgTitle in (titleRaw, timeF dur) withDepth :: Int -> Org -> [(Text,Text)] withDepth i o = do let (name,dur) = formatter o let children = map (withDepth (i+1)) (o ^. orgSubtrees) let processChild,processLastChild :: [(Text,Text)] -> [(Text,Text)] processChild [] = [] processChild (pair0:pairs) = first ((bfAngle1 <> bfHorizontal <> " ") <>) pair0 : map (first ((bfVertical <> " ") <>)) pairs processLastChild [] = [] processLastChild (pair0:pairs) = first ((bfAngle2 <> bfHorizontal <> " ") <>) pair0 : map (first (" " <>)) pairs let childrenProcessed | null children = [] | otherwise = concat $ map processChild (dropEnd 1 children) ++ [processLastChild (L.last children)] (name,dur) : childrenProcessed