1 {-# LANGUAGE OverloadedStrings #-}
2 {-# LANGUAGE RecordWildCards #-}
3 {-# LANGUAGE ViewPatterns #-}
4 {-# OPTIONS_GHC -fno-warn-orphans #-}
5 -- | Render a TCT file in DTC.
6 module Language.TCT.Write.DTC where
8 import Control.Applicative (Applicative(..))
9 import Control.Monad (Monad(..), forM_, mapM, when)
11 import Data.Eq (Eq(..))
12 import Data.Foldable (Foldable(..))
13 import Data.Function (($), (.), flip)
14 import Data.Functor ((<$>))
16 import Data.Maybe (Maybe(..))
17 import Data.Monoid (Monoid(..))
18 import Data.Ord (Ord(..))
19 import Data.Semigroup (Semigroup(..))
20 import Data.Sequence (Seq, ViewL(..))
21 import Data.String (String, IsString(..))
22 import Data.Text (Text)
23 import Prelude (Num(..), undefined)
24 import Text.Blaze ((!))
25 import Text.Blaze.Html (Html)
26 import Text.Show (Show(..))
27 import qualified Control.Monad.Trans.State as S
28 import qualified Data.List as L
29 import qualified Data.Sequence as Seq
30 import qualified Data.Text as Text
31 import qualified Text.Blaze as B
32 import qualified Text.Blaze.Internal as B
33 import qualified Data.Text.Lazy as TL
35 import Language.TCT.Tree
36 import Language.TCT.Token
37 import Language.TCT.Elem hiding (trac,dbg)
38 import qualified Language.TCT.Write.Text as Write
39 import Text.Blaze.Utils
40 import Text.Blaze.DTC (DTC)
41 import qualified Text.Blaze.DTC as D
42 import qualified Text.Blaze.DTC.Attributes as DA
44 import Debug.Trace (trace)
45 trac :: String -> a -> a
48 dbg :: Show a => String -> a -> a
49 dbg m x = trac (m <> ": " <> show x) x
51 dtc :: Trees (Cell Key) (Cell Token) -> DTC
54 D.xmlModel "./schema/dtc.rnc"
55 D.xmlStylesheet $ "./xsl/document.html5."<>lang<>".xsl"
56 D.html5Stylesheet $ "./xsl/document.html5."<>lang<>".xsl"
57 D.atomStylesheet $ "./xsl/document.atom."<>lang<>".xsl"
59 forM_ tct $ d_TreeCell []
61 d_TreeCell :: [Key] -> Tree (Cell Key) (Cell Token) -> DTC
62 d_TreeCell path (TreeN (unCell -> key@KeySection{}) ts) =
63 let (attrs,children) = partitionAttributesChildren ts in
65 forM_ (case Seq.viewl children of {Tree0{} :< ts' -> ts'; _ -> children}) $
66 d_TreeCell (key:path) in
67 (\acc -> foldr (\(n,v) -> B.AddCustomAttribute (B.Text n) (B.Text v)) acc attrs) $
68 case Seq.viewl children of
69 Tree0 (Cell _posTitle _ (TokenPlain title)) :< _ ->
70 case Text.splitOn "\n" title of
72 D.section ! DA.name (attrValue t0) $ do
73 let st = Text.intercalate "\n" t1
74 when (not (Text.null st)) $
75 D.name $ B.toMarkup st
78 D.section ! DA.name (attrValue title) $
80 Tree0 (Cell _posTitle _ title) :< _ ->
82 D.name $ d_Token (key:path) title
84 _ -> D.section d_content
85 d_TreeCell path (Tree0 cell) = d_CellToken path cell
86 d_TreeCell path (TreeN cell@(unCell -> KeyColon{}) ts) =
87 let (attrs,children) = partitionAttributesChildren ts in
88 foldr (\(n,v) -> B.AddCustomAttribute (B.Text n) (B.Text v))
89 (d_CellKey path cell children)
91 d_TreeCell path (TreeN cell ts) = d_CellKey path cell ts
93 partitionAttributesChildren :: Seq (Tree (Cell Key) (Cell Token)) -> ([(Name,Text)],Seq (Tree (Cell Key) (Cell Token)))
94 partitionAttributesChildren ts = (attrs,children)
96 attrs :: [(Name,Text)]
101 TreeN (unCell -> KeyEqual n _wh) a -> (n,v):acc
104 Write.text Write.config_text{Write.config_text_escape = False} $
105 Write.treeRackUpLeft <$> a
108 children = Seq.filter (\t ->
111 TreeN (unCell -> KeyEqual{}) _cs -> False
116 d_CellKey :: [Key] -> Cell Key -> Trees (Cell Key) (Cell Token) -> DTC
117 d_CellKey path (Cell _pos _posEnd key) cells = do
119 KeyColon n _wh -> d_Key n
120 KeyGreat n _wh -> d_Key n
121 KeyEqual n _wh -> d_Key n
122 KeyBar n _wh -> d_Key n
124 B.toMarkup ("- "::Text)
125 forM_ cells $ d_TreeCell (key:path)
127 KeyLower name attrs -> do
128 B.Content $ "<"<>B.toMarkup name
130 forM_ cells $ d_TreeCell path
134 d_Key name | null cells =
135 B.CustomLeaf (B.Text name) True mempty
137 B.CustomParent (B.Text name) $
138 forM_ cells $ d_TreeCell (key:path)
140 d_CellToken :: [Key] -> Cell Token -> DTC
141 d_CellToken path (Cell _pos _posEnd tok) =
142 -- case L.find (\case KeySection{} -> True; _ -> False) $ dbg "d_CellToken: path:" path of
143 case dbg "d_CellToken: path" path of
146 TokenPair PairElem{} _t -> d_Token path tok
147 _ -> D.para $ d_Token path tok
148 _ -> d_Token path tok
150 d_Token :: [Key] -> Token -> DTC
151 d_Token path tok = go tok
153 -- indent = Text.replicate (columnPos pos - 1) " "
155 go (TokenPlain txt) = B.toMarkup txt
156 go (TokenTag v) = D.ref mempty ! DA.to (attrValue v)
157 go (TokenEscape c) = B.toMarkup c
158 go (TokenLink lnk) = D.eref (B.toMarkup lnk) ! DA.to (attrValue lnk)
159 go (TokenPair PairSlash t) = D.i $ go t
160 go (TokenPair PairBackquote t) = D.code $ go t
161 go (TokenPair PairFrenchquote t) = D.q $ go t
162 go (TokenPair PairHash (TokenPlain t)) =
163 D.ref mempty ! DA.to (attrValue t)
164 go (TokenPair (PairElem name attrs) t) =
167 Tokens ts | Seq.null ts ->
168 B.CustomLeaf (B.Text name) True mempty
169 _ -> B.CustomParent (B.Text name) $ go t
170 go (TokenPair p t) = do
171 let (o,c) = pairBorders p t
175 go (Tokens ts) = foldMap go ts
177 d_Attrs :: Attrs -> DTC -> DTC
178 d_Attrs = flip $ foldl' d_Attr
180 d_Attr :: DTC -> (Text,Attr) -> DTC
181 d_Attr acc (_,Attr{..}) =