1 {-# LANGUAGE NoMonomorphismRestriction #-}
2 {-# LANGUAGE DuplicateRecordFields #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 module Hdoc.DTC.Sym where
6 import Control.Applicative (Applicative(..), (<$>), (<$))
7 import Control.Monad (void)
8 import Data.Default.Class (Default(..))
9 import Data.Foldable (Foldable(..), concat)
10 import Data.Function (($), (.))
11 import Data.Maybe (Maybe(..), maybe)
12 import Data.TreeSeq.Strict (Tree(..), tree0)
13 import qualified Control.Applicative as Alt
14 import qualified Data.Sequence as Seq
15 import qualified Data.Text.Lazy as TL
18 import Hdoc.RNC.Sym as RNC
19 import Hdoc.DTC.Anchor (wordify)
20 import qualified Hdoc.DTC.Document as DTC
21 import qualified Hdoc.RNC.Write as RNC
24 -- | Use a symantic (tagless final) class to encode
25 -- both the parsing and the schema of DTC,
26 -- when repr is respectively instanciated
27 -- on 'DTC.Parser' or 'RNC.RuleWriter'.
28 class RNC.Sym_RNC repr => Sym_DTC repr where
29 position :: repr DTC.Pos
30 document :: repr DTC.Document
33 about :: repr DTC.About
34 header :: repr DTC.Header
36 author :: repr DTC.Entity
37 editor :: repr DTC.Entity
39 entity :: repr DTC.Entity
41 serie :: repr DTC.Serie
42 alias :: repr DTC.Alias
45 include :: repr DTC.Include
47 block :: repr DTC.Block
48 blockBreak :: repr DTC.Block
49 blockToC :: repr DTC.Block
50 blockToF :: repr DTC.Block
51 blockIndex :: repr DTC.Block
52 blockFigure :: repr DTC.Block
53 blockReferences :: repr DTC.Block
54 reference :: repr DTC.Reference
57 paraItem :: repr DTC.ParaItem
58 paraItems :: repr DTC.Para
60 plain :: repr DTC.Plain
61 plainNode :: repr (Tree DTC.PlainNode)
63 commonAttrs :: repr DTC.CommonAttrs
65 title :: repr DTC.Title
76 <$?> (def, Just <$> id)
77 <|?> (def, rule "class" $ attribute "class" $ TL.words <$> text)
79 document = rule "document" $
85 <$> optional (rule "about" $ element "about" about)
91 [ element "section" $ Tree <$> section <*> body
92 , tree0 . DTC.BodyBlock <$> block
101 title = rule "title" $ DTC.Title <$> element "title" plain
102 name = rule "name" $ attribute "name" text
103 url = rule "url" $ URL <$> text
104 path = rule "path" $ Path <$> text
105 ident = rule "ident" $ Ident <$> text
106 to = rule "to" $ attribute "to" ident
107 id = rule "id" $ attribute "id" ident
112 <$?> (0, attribute "year" int)
113 <|?> (Nothing, Just <$> attribute "month" nat1)
114 <|?> (Nothing, Just <$> attribute "day" nat1)
120 <$?> (def, attribute "href" path)
121 block = rule "block" $
123 [ DTC.BlockPara <$> para
131 , anyElem $ \n@XmlName{..} ->
136 blockBreak = rule "break" $
146 <*> optional (attribute "depth" nat)
171 (wordify <$>) . TL.lines <$> text)
178 <*> attribute "type" text
182 rule "blockReferences" $
183 element "references" $
189 para = rule "para" $ paraItems <|> DTC.ParaItem <$> paraItem
193 [ element "ol" $ DTC.ParaOL <$> many (element "li" $ DTC.ListItem <$> attribute "name" text <*> many para)
194 , element "ul" $ DTC.ParaUL <$> many (element "li" $ many para)
195 , element "artwork" $ DTC.ParaArtwork <$> attribute "type" text <*> text
196 , element "quote" $ DTC.ParaQuote <$> attribute "type" text <*> many para
197 , DTC.ParaPlain . Seq.fromList <$> some plainNode
198 , DTC.ParaComment <$> comment
207 plain = rule "plain" $ (Seq.fromList <$>) $ many plainNode
211 [ tree0 . DTC.PlainText <$> text
212 , element "br" $ tree0 DTC.PlainBreak <$ none
213 , element "b" $ Tree DTC.PlainB <$> plain
214 , element "code" $ Tree DTC.PlainCode <$> plain
215 , element "del" $ Tree DTC.PlainDel <$> plain
216 , element "i" $ Tree DTC.PlainI <$> plain
217 , element "q" $ Tree DTC.PlainQ <$> plain
218 , element "sc" $ Tree DTC.PlainSC <$> plain
219 , element "span" $ Tree . DTC.PlainSpan <$> commonAttrs <*> plain
220 , element "sub" $ Tree DTC.PlainSub <$> plain
221 , element "sup" $ Tree DTC.PlainSup <$> plain
222 , element "u" $ Tree DTC.PlainU <$> plain
223 , element "note" $ tree0 . DTC.PlainNote Nothing <$> many para
224 , element "iref" $ Tree . DTC.PlainIref Nothing . wordify <$> attribute "to" text <*> plain
225 , element "eref" $ Tree . DTC.PlainEref <$> attribute "to" url <*> plain
226 , element "ref" $ Tree . DTC.PlainRef <$> to <*> plain
227 , element "rref" $ Tree . DTC.PlainRref Nothing <$> to <*> plain
229 tag = rule "tag" $ element "tag" text
231 (foldr ($) def <$>) $
233 [ (\a acc -> acc{DTC.titles=a:DTC.titles acc}) <$> title
234 , (\a acc -> (acc::DTC.About){DTC.url=Just a}) <$> attribute "url" url
235 , (\a acc -> acc{DTC.authors=a:DTC.authors acc}) <$> author
236 , (\a acc -> acc{DTC.editor=DTC.editor acc Alt.<|> Just a}) <$> editor
237 , (\a acc -> acc{DTC.date=DTC.date acc Alt.<|> Just a}) <$> date
238 , (\a acc -> acc{DTC.tags=a:DTC.tags acc}) <$> tag
239 , (\a acc -> acc{DTC.links=a:DTC.links acc}) <$> link
240 , (\a acc -> acc{DTC.series=a:DTC.series acc}) <$> serie
241 , (\a acc -> acc{DTC.headers=a:DTC.headers acc}) <$> header
246 DTC.Header (xmlNameLocal n)
248 author = rule "author" $ element "author" entity
249 editor = rule "editor" $ element "editor" entity
250 entity = rule "entity" $
254 <|?> (def, attribute "street" text)
255 <|?> (def, attribute "zipcode" text)
256 <|?> (def, attribute "city" text)
257 <|?> (def, attribute "region" text)
258 <|?> (def, attribute "country" text)
259 <|?> (def, attribute "email" text)
260 <|?> (def, attribute "tel" text)
261 <|?> (def, attribute "fax" text)
262 <|?> (def, Just <$> attribute "url" url)
263 <|?> (def, Just <$> element "org" entity)
264 serie = rule "serie" $
269 <|?> (def, attribute "id" text)
273 (\n h r t p -> DTC.Link n h r t (Seq.fromList p))
275 <|?> (def, attribute "href" url)
276 <|?> (def, attribute "rel" text)
277 <|?> (def, Just <$> attribute "type" text)
279 alias = rule "alias" $
284 reference = rule "reference" $
285 element "reference" $
290 instance Sym_DTC RNC.Writer where
291 position = RNC.writeText ""
292 instance Sym_DTC RNC.RuleWriter where
293 position = RNC.RuleWriter position
295 -- | RNC schema for DTC
296 schema :: [RNC.RuleWriter ()]
301 , void $ rule "about" $ element "about" about
320 , void $ blockReferences