1 {-# LANGUAGE PolyKinds #-}
2 {-# LANGUAGE ViewPatterns #-}
3 module Language.Symantic.Document.Sym where
5 import Data.Char (Char)
6 import Data.Eq (Eq(..))
7 import Data.Foldable (Foldable(..))
8 import Data.Maybe (Maybe(..))
9 import Data.Function ((.))
10 import Data.Functor (Functor(..))
12 import Data.Semigroup (Semigroup(..))
13 import Data.String (String, IsString)
14 import Data.Text (Text)
15 import Prelude (Integer)
16 import qualified Data.List as L
17 import qualified Data.Text as T
18 import qualified Data.Text.Lazy as TL
21 class (IsString d, Semigroup d) => Doc_Text d where
27 integer :: Integer -> d
32 charH :: Char -> d -- XXX: MUST NOT be '\n'
33 stringH :: String -> d -- XXX: MUST NOT contain '\n'
34 textH :: Text -> d -- XXX: MUST NOT contain '\n'
35 ltextH :: TL.Text -> d -- XXX: MUST NOT contain '\n'
36 catH :: Foldable f => f d -> d
37 catV :: Foldable f => f d -> d
41 default spaces :: Doc_Text (ReprOf d) => Trans d => Int -> d
42 default int :: Doc_Text (ReprOf d) => Trans d => Int -> d
43 default integer :: Doc_Text (ReprOf d) => Trans d => Integer -> d
44 default charH :: Doc_Text (ReprOf d) => Trans d => Char -> d
45 default stringH :: Doc_Text (ReprOf d) => Trans d => String -> d
46 default textH :: Doc_Text (ReprOf d) => Trans d => Text -> d
47 default ltextH :: Doc_Text (ReprOf d) => Trans d => TL.Text -> d
48 -- default catH :: Doc_Text (ReprOf d) => Trans d => Foldable f => Functor f => f d -> d
49 -- default catV :: Doc_Text (ReprOf d) => Trans d => Foldable f => Functor f => f d -> d
53 spaces = trans . spaces
55 integer = trans . integer
56 char = \case '\n' -> eol; c -> charH c
57 string = catV . fmap stringH . lines
58 text = catV . fmap textH . lines
59 ltext = catV . fmap ltextH . lines
61 stringH = trans . stringH
63 ltextH = trans . ltextH
64 -- catH l = trans (catH (fmap unTrans l))
65 catH = foldr (<>) empty
66 -- catV l = trans (catV (fmap unTrans l))
67 catV l | null l = empty
68 catV l = foldr1 (\a acc -> a <> eol <> acc) l
69 dquote d = "\"" <> d <> "\""
70 fquote d = "« " <> d <> " »"
71 squote d = "'" <> d <> "'"
73 -- * Class 'Doc_Color'
74 class Doc_Color d where
115 onMagentaer :: d -> d
119 default reverse :: Doc_Color (ReprOf d) => Trans d => d -> d
120 default black :: Doc_Color (ReprOf d) => Trans d => d -> d
121 default red :: Doc_Color (ReprOf d) => Trans d => d -> d
122 default green :: Doc_Color (ReprOf d) => Trans d => d -> d
123 default yellow :: Doc_Color (ReprOf d) => Trans d => d -> d
124 default blue :: Doc_Color (ReprOf d) => Trans d => d -> d
125 default magenta :: Doc_Color (ReprOf d) => Trans d => d -> d
126 default cyan :: Doc_Color (ReprOf d) => Trans d => d -> d
127 default white :: Doc_Color (ReprOf d) => Trans d => d -> d
128 default blacker :: Doc_Color (ReprOf d) => Trans d => d -> d
129 default redder :: Doc_Color (ReprOf d) => Trans d => d -> d
130 default greener :: Doc_Color (ReprOf d) => Trans d => d -> d
131 default yellower :: Doc_Color (ReprOf d) => Trans d => d -> d
132 default bluer :: Doc_Color (ReprOf d) => Trans d => d -> d
133 default magentaer :: Doc_Color (ReprOf d) => Trans d => d -> d
134 default cyaner :: Doc_Color (ReprOf d) => Trans d => d -> d
135 default whiter :: Doc_Color (ReprOf d) => Trans d => d -> d
136 default onBlack :: Doc_Color (ReprOf d) => Trans d => d -> d
137 default onRed :: Doc_Color (ReprOf d) => Trans d => d -> d
138 default onGreen :: Doc_Color (ReprOf d) => Trans d => d -> d
139 default onYellow :: Doc_Color (ReprOf d) => Trans d => d -> d
140 default onBlue :: Doc_Color (ReprOf d) => Trans d => d -> d
141 default onMagenta :: Doc_Color (ReprOf d) => Trans d => d -> d
142 default onCyan :: Doc_Color (ReprOf d) => Trans d => d -> d
143 default onWhite :: Doc_Color (ReprOf d) => Trans d => d -> d
144 default onBlacker :: Doc_Color (ReprOf d) => Trans d => d -> d
145 default onRedder :: Doc_Color (ReprOf d) => Trans d => d -> d
146 default onGreener :: Doc_Color (ReprOf d) => Trans d => d -> d
147 default onYellower :: Doc_Color (ReprOf d) => Trans d => d -> d
148 default onBluer :: Doc_Color (ReprOf d) => Trans d => d -> d
149 default onMagentaer :: Doc_Color (ReprOf d) => Trans d => d -> d
150 default onCyaner :: Doc_Color (ReprOf d) => Trans d => d -> d
151 default onWhiter :: Doc_Color (ReprOf d) => Trans d => d -> d
153 reverse = trans1 reverse
157 yellow = trans1 yellow
159 magenta = trans1 magenta
162 blacker = trans1 blacker
163 redder = trans1 redder
164 greener = trans1 greener
165 yellower = trans1 yellower
167 magentaer = trans1 magentaer
168 cyaner = trans1 cyaner
169 whiter = trans1 whiter
170 onBlack = trans1 onBlack
172 onGreen = trans1 onGreen
173 onYellow = trans1 onYellow
174 onBlue = trans1 onBlue
175 onMagenta = trans1 onMagenta
176 onCyan = trans1 onCyan
177 onWhite = trans1 onWhite
178 onBlacker = trans1 onBlacker
179 onRedder = trans1 onRedder
180 onGreener = trans1 onGreener
181 onYellower = trans1 onYellower
182 onBluer = trans1 onBluer
183 onMagentaer = trans1 onMagentaer
184 onCyaner = trans1 onCyaner
185 onWhiter = trans1 onWhiter
187 -- * Class 'Doc_Decoration'
188 class Doc_Decoration d where
192 default bold :: Doc_Decoration (ReprOf d) => Trans d => d -> d
193 default underline :: Doc_Decoration (ReprOf d) => Trans d => d -> d
194 default italic :: Doc_Decoration (ReprOf d) => Trans d => d -> d
196 underline = trans1 underline
197 italic = trans1 italic
201 -- | Return the underlying @tr@ of the transformer.
204 -- | Lift a tr to the transformer's.
205 trans :: ReprOf tr -> tr
206 -- | Unlift a tr from the transformer's.
207 unTrans :: tr -> ReprOf tr
209 -- | Identity transformation for a unary symantic method.
210 trans1 :: (ReprOf tr -> ReprOf tr) -> (tr -> tr)
211 trans1 f = trans . f . unTrans
213 -- | Identity transformation for a binary symantic method.
215 :: (ReprOf tr -> ReprOf tr -> ReprOf tr)
217 trans2 f t1 t2 = trans (f (unTrans t1) (unTrans t2))
219 -- | Identity transformation for a ternary symantic method.
221 :: (ReprOf tr -> ReprOf tr -> ReprOf tr -> ReprOf tr)
222 -> (tr -> tr -> tr -> tr)
223 trans3 f t1 t2 t3 = trans (f (unTrans t1) (unTrans t2) (unTrans t3))
226 -- * Class 'SplitOnCharWithEmpty'
227 class SplitOnCharWithEmpty t where
228 splitOnCharWithEmpty :: Char -> t -> [t]
229 instance SplitOnCharWithEmpty Text where
230 splitOnCharWithEmpty sep t =
231 case T.break (== sep) t of
232 (chunk, T.uncons -> Just (_, rest)) -> chunk : splitOnCharWithEmpty sep rest
233 (chunk, _) -> [chunk]
234 instance SplitOnCharWithEmpty TL.Text where
235 splitOnCharWithEmpty sep t =
236 case TL.break (== sep) t of
237 (chunk, TL.uncons -> Just (_, rest)) -> chunk : splitOnCharWithEmpty sep rest
238 (chunk, _) -> [chunk]
239 instance SplitOnCharWithEmpty String where
240 splitOnCharWithEmpty sep t =
241 case L.break (== sep) t of
242 (chunk, _:rest) -> chunk : splitOnCharWithEmpty sep rest
243 (chunk, []) -> [chunk]
245 lines :: SplitOnCharWithEmpty t => t -> [t]
246 lines = splitOnCharWithEmpty '\n'
252 -- * Class 'SplitOnChar'
254 class SplitOnChar t where
255 splitOnChar :: Char -> t -> [t]
256 instance SplitOnChar Text where
258 case Text.uncons t of
262 then splitOnChar sep xs
264 let (chunk, rest) = Text.break (== sep) t in
265 chunk:splitOnChar sep rest
266 instance SplitOnChar String where
272 then splitOnChar sep xs
274 let (chunk, rest) = List.break (== sep) t in
275 chunk:splitOnChar sep rest