1 {-# LANGUAGE ConstraintKinds #-}
2 {-# LANGUAGE ExistentialQuantification #-}
3 {-# LANGUAGE FlexibleContexts #-}
4 {-# LANGUAGE FlexibleInstances #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE OverloadedStrings #-}
7 {-# LANGUAGE ScopedTypeVariables #-}
8 {-# OPTIONS_GHC -fno-warn-orphans #-}
9 module Hdoc.DTC.Write.Plain where
11 import Control.Applicative (Applicative(..), liftA2)
12 import Control.Category
15 import Data.Default.Class (Default(..))
16 import Data.Eq (Eq(..))
17 import Data.Foldable (Foldable(..), concat)
18 import Data.Function (($))
20 import Data.Maybe (Maybe(..), maybe)
21 import Data.Monoid (Monoid(..))
22 import Data.Semigroup (Semigroup(..))
23 import Data.Text (Text)
24 import Data.TreeSeq.Strict (Tree(..))
25 import Data.Tuple (fst, snd)
26 import Data.String (String, IsString(..))
28 import Text.Show (Show(..))
29 import qualified Control.Monad.Trans.State as S
30 import qualified Data.List as List
31 import qualified Data.Text.Lazy as TL
32 import qualified Data.Text.Lazy.Builder as TLB
34 import Data.Locale hiding (Index)
36 import Hdoc.DTC.Write.XML ()
37 import Hdoc.DTC.Document as DTC hiding (Plain)
38 import qualified Hdoc.DTC.Document as DTC
41 type Plain = S.State State TLB.Builder
43 runPlain :: Plain -> State -> (TL.Text, State)
45 let (b,s') = S.runState p s in
46 (TLB.toLazyText b, s')
48 text :: Plainify a => State -> a -> TL.Text
49 text st a = fst $ runPlain (plainify a) st
51 instance IsString Plain where
52 fromString = return . fromString
53 instance Semigroup Plain where
55 instance Monoid Plain where
62 { state_l10n :: Loqualization (L10n Plain)
63 , state_italic :: Bool
66 instance Default State where
68 { state_l10n = Loqualization EN_US
69 , state_italic = False
74 class Plainify a where
75 plainify :: a -> Plain
76 instance Plainify String where
77 plainify = return . TLB.fromString
78 instance Plainify Text where
79 plainify = return . TLB.fromText
80 instance Plainify TL.Text where
81 plainify = return . TLB.fromLazyText
83 instance Plainify Para where
85 ParaItem{..} -> plainify item
86 ParaItems{..} -> plainify items
88 instance Plainify DTC.Plain where
89 plainify = foldMap plainify
90 instance Plainify (Tree PlainNode) where
91 plainify (Tree n ls) =
94 PlainText txt -> plainify txt
95 PlainGroup -> plainify ls
96 PlainB -> "*"<>plainify ls<>"*"
97 PlainCode -> "`"<>plainify ls<>"`"
98 PlainDel -> "-"<>plainify ls<>"-"
99 PlainI -> "/"<>plainify ls<>"/"
100 PlainNote{..} -> "" -- TODO: to be coded, with a switch on/off in State
102 State{state_l10n=Loqualization loc} <- S.get
103 l10n_Quote (plainify ls) loc
104 PlainSC -> plainify ls
105 PlainSpan{..} -> plainify ls
106 PlainSub -> plainify ls
107 PlainSup -> plainify ls
108 PlainU -> "_"<>plainify ls<>"_"
109 PlainEref{..} -> plainify ls
110 PlainIref{..} -> plainify ls
111 PlainRef{..} -> plainify ls
112 PlainRref{..} -> plainify ls
113 instance Plainify Title where
114 plainify (Title t) = plainify t
115 instance Plainify PosPath where
118 snd . foldl' (\(nParent,acc) (n,c) ->
120 (if TL.null acc then acc else acc <> ".") <>
122 then TL.pack (show c)
123 else TL.pack (show n)<>TL.pack (show c))
127 instance Plainify XmlName where
128 plainify = plainify . show
129 instance Plainify Int where
130 plainify = plainify . show
131 instance Plainify Nat where
132 plainify (Nat n) = plainify n
133 instance Plainify Nat1 where
134 plainify (Nat1 n) = plainify n
137 class L10n msg lang where
138 l10n_Colon :: FullLocale lang -> msg
139 l10n_Table_of_Contents :: FullLocale lang -> msg
140 l10n_Quote :: msg -> FullLocale lang -> msg
141 l10n_Date :: Date -> FullLocale lang -> msg
143 instance L10n TL.Text FR where
144 l10n_Colon _loc = " : "
145 l10n_Table_of_Contents _loc = "Sommaire"
146 l10n_Quote msg _loc = "« "<>msg<>" »"
147 l10n_Date Date{..} _loc =
150 List.intersperse " " $
152 [ maybe [] (pure . show) day
165 9 -> pure "septembre"
167 11 -> pure "novembre"
168 12 -> pure "décembre"
172 instance L10n TL.Text EN where
173 l10n_Colon _loc = ": "
174 l10n_Table_of_Contents _loc = "Table of Contents"
175 l10n_Quote msg _loc = "“"<>msg<>"”"
176 l10n_Date Date{..} _loc =
179 List.intersperse " " $
181 [ maybe [] (pure . show) day
194 9 -> pure "September"
196 11 -> pure "November"
197 12 -> pure "December"
202 instance L10n Plain FR where
203 l10n_Colon loc = plainify (l10n_Colon loc::TL.Text)
204 l10n_Table_of_Contents loc = plainify (l10n_Table_of_Contents loc::TL.Text)
205 l10n_Quote msg _loc = do
206 depth <- S.gets state_quote
208 case unNat depth `mod` 3 of
212 S.modify' $ \s -> s{state_quote=succNat depth}
214 S.modify' $ \s -> s{state_quote=depth}
216 l10n_Date date loc = plainify (l10n_Date date loc::TL.Text)
217 instance L10n Plain EN where
218 l10n_Colon loc = plainify (l10n_Colon loc::TL.Text)
219 l10n_Table_of_Contents loc = plainify (l10n_Table_of_Contents loc::TL.Text)
220 l10n_Quote msg _loc = do
221 depth <- S.gets state_quote
223 case unNat depth `mod` 3 of
227 S.modify' $ \s -> s{state_quote=succNat depth}
229 S.modify' $ \s -> s{state_quote=depth}
231 l10n_Date date loc = plainify (l10n_Date date loc::TL.Text)
234 -- ** Type 'L10nPlain'
235 -- | Useful newtype to just use 'plainify', instead of 'state_l10n'.
236 newtype L10nPlain = L10nPlain (forall l. L10n l Plain => FullLocale l -> Plain)
237 instance Plainify L10nPlain where
238 plainify (L10nPlain l10n) = do
239 State{state_l10n} <- S.get