1 {-# LANGUAGE OverloadedStrings #-}
2 {-# LANGUAGE RecordWildCards #-}
3 {-# LANGUAGE ViewPatterns #-}
4 {-# OPTIONS_GHC -fno-warn-orphans #-}
5 -- | Render a TCT file in plain Text.
6 module Language.TCT.Text where
8 import Control.Monad (Monad(..), mapM)
10 import Data.Eq (Eq(..))
11 import Data.Foldable (Foldable(..))
12 import Data.Function (($), (.))
13 import Data.Functor ((<$>))
15 import Data.Int (Int64)
16 import Data.Monoid (Monoid(..))
17 import Data.Ord (Ord(..))
18 import Data.Semigroup (Semigroup(..))
19 import Data.Sequence (ViewL(..))
20 import Data.String (String)
21 import Data.Text (Text)
22 import Prelude (Num(..), undefined, Integral(..))
23 import Text.Show (Show(..))
24 import qualified Control.Monad.Trans.State as S
25 import qualified Data.List as L
26 import qualified Data.Sequence as Seq
27 import qualified Data.Text as Text
28 import qualified Data.Text.Lazy as TL
30 import Language.TCT.Tree
31 import Language.TCT.Token
32 import Language.TCT.Elem hiding (trac,dbg)
34 import Debug.Trace (trace)
35 trac :: String -> a -> a
38 dbg :: Show a => String -> a -> a
39 dbg m x = trac (m <> ": " <> show x) x
44 text :: Trees (Cell Key) (Cell Token) -> TL.Text
45 text tct = foldMap t_TreeCell (treePosLastCell tct)
47 t_Value :: Text -> TL.Text
50 int64 :: Integral i => i -> Int64
51 int64 = fromInteger . toInteger
53 t_TreeCell :: Tree (Pos,Cell Key) (Pos,Cell Token) -> TL.Text
54 t_TreeCell (TreeN c@(_, unCell -> KeySection lvl) ts) =
56 TL.replicate (int64 lvl) "#" <> " " <>
58 Tree0 (_,Cell posTitle _ title) :< _ -> t_IndentToken posTitle title
60 foldMap t_TreeCell (case Seq.viewl ts of {Tree0{} :< ts' -> ts'; _ -> ts})
61 t_TreeCell (Tree0 c@(_,cell)) =
64 t_TreeCell (TreeN c@(_,cell) cs) =
68 t_IndentCell :: (Pos,Cell a) -> TL.Text
69 t_IndentCell ((lineLast,colLast),posCell -> (line,col))
71 TL.replicate (int64 $ line - (lineLast+1)) "\n" <>
72 TL.replicate (int64 $ col - 1) " "
74 && colLast <= col = TL.replicate (int64 $ col - colLast) " "
75 | otherwise = undefined
77 t_CellKey :: Cell Key -> Trees (Pos,Cell Key) (Pos,Cell Token) -> TL.Text
78 t_CellKey (Cell _pos _posEnd key) cells = do
80 KeyColon n wh -> t_Key n wh ":"
81 KeyGreat n wh -> t_Key n wh ">"
82 KeyEqual n wh -> t_Key n wh "="
83 KeyBar n wh -> t_Key n wh "|"
84 KeyDash -> "- " <> foldMap t_TreeCell cells
85 KeyLower name attrs ->
86 "<" <> tl name <> t_Attrs attrs <>
87 foldMap t_TreeCell cells
89 t_Key :: Text -> White -> TL.Text -> TL.Text
90 t_Key name wh mark = tl name <> tl wh <> mark <> foldMap t_TreeCell cells
92 t_CellToken :: Cell Token -> TL.Text
93 t_CellToken (Cell pos _posEnd tok) =
96 t_Token :: Token -> TL.Text
97 t_Token (TokenPlain txt) = tl txt
98 t_Token (TokenTag v) = "#"<>tl v
99 t_Token (TokenEscape c) = tl $ Text.pack ['\\',c]
100 t_Token (TokenLink lnk) = tl lnk
101 t_Token (TokenPair grp t) = tl o<>t_Token t<>tl c
102 where (o,c) = pairBorders grp t
103 t_Token (Tokens ts) = foldMap t_Token ts
105 t_IndentToken :: Pos -> Token -> TL.Text
106 t_IndentToken pos tok = go tok `S.evalState` linePos pos
108 indent = TL.replicate (int64 $ columnPos pos - 1) " "
109 go :: Token -> S.State Int TL.Text
110 go (TokenPlain txt) = do
112 let lines = Text.splitOn "\n" txt
113 let lnums = tl : -- TODO: fmap
114 [ \line -> "\n"<>indent<>tl line
117 S.put (lin - 1 + L.length lines)
118 return $ mconcat $ L.zipWith ($) lnums lines
119 go (TokenTag v) = return $ "#"<>tl v
120 go (TokenEscape c) = return $ tl $ Text.pack ['\\',c]
121 go (TokenLink lnk) = return $ tl lnk
122 go (TokenPair grp t) = do
124 return $ tl o<>t'<>tl c
125 where (o,c) = pairBorders grp t
128 return $ foldr (<>) mempty ts'
130 t_Attrs :: Attrs -> TL.Text
131 t_Attrs = foldMap t_Attr
133 t_Attr :: (Text,Attr) -> TL.Text
134 t_Attr (attr_white,Attr{..}) =
143 treePosLastCell :: Trees (Cell k) (Cell a) -> Trees (Pos,Cell k) (Pos,Cell a)
144 treePosLastCell t = S.evalState (go`mapM`t) (1,1)
146 go :: Tree (Cell k) (Cell a) ->
147 S.State (Int, Int) (Tree (Pos, Cell k) (Pos, Cell a))
150 S.put $ posEndCell cell
151 return $ Tree0 (lastPos,cell)
152 go (TreeN cell ts) = do
154 S.put $ posEndCell cell
156 return $ TreeN (lastPos,cell) ts'