1 {-# LANGUAGE NoMonomorphismRestriction #-}
2 {-# LANGUAGE DuplicateRecordFields #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 module Hdoc.DTC.Sym where
6 import Control.Applicative (Applicative(..), (<$>), (<$))
7 import Control.Arrow (second)
8 import Control.Monad (void)
9 import Data.Bool (Bool(..))
10 import Data.Default.Class (Default(..))
11 import Data.Foldable (concat)
12 import Data.Monoid (mconcat)
13 import Data.Function (($), (.), flip)
14 import Data.Maybe (Maybe(..))
15 import Data.Semigroup (Semigroup(..))
16 import Data.TreeSeq.Strict (Tree(..), tree0)
17 import qualified Data.HashMap.Strict as HM
18 import qualified Data.Sequence as Seq
19 import qualified Data.Text.Lazy as TL
22 import Hdoc.RNC.Sym as RNC
23 import qualified Hdoc.DTC.Analyze.Index as Index
24 import qualified Hdoc.DTC.Document as DTC
25 import qualified Hdoc.RNC.Write as RNC
26 import qualified Hdoc.TCT.Cell as TCT
27 import qualified Hdoc.XML as XML
30 -- | Use a symantic (tagless final) class to encode
31 -- both the parsing and the schema of DTC,
32 -- when repr is respectively instanciated
33 -- on 'DTC.Parser' or 'RNC.RuleWriter'.
34 class RNC.Sym_RNC repr => Sym_DTC repr where
35 positionXML :: repr XML.Pos
36 locationTCT :: repr TCT.Location
37 document :: repr DTC.Document
39 about :: repr DTC.About
43 section :: repr DTC.Section
44 include :: repr DTC.Include
46 block :: repr DTC.Block
47 blockBreak :: repr DTC.Block
48 blockToC :: repr DTC.Block
49 blockToF :: repr DTC.Block
50 blockIndex :: repr DTC.Block
51 blockAside :: repr DTC.Block
52 blockFigure :: repr DTC.Block
53 blockReferences :: repr DTC.Block
54 blockJudges :: repr DTC.Block
55 blockGrades :: repr DTC.Block
56 reference :: repr DTC.Reference
59 paraItem :: repr DTC.ParaItem
60 paraItems :: repr DTC.Para
62 plain :: repr DTC.Plain
63 plainNode :: repr (Tree DTC.PlainNode)
65 commonAttrs :: repr DTC.CommonAttrs
67 title :: repr DTC.Title
70 path :: repr DTC.FilePath
73 class_ :: repr [TL.Text]
77 author :: repr DTC.Entity
79 entity :: repr DTC.Entity
81 serie :: repr DTC.Serie
82 alias :: repr DTC.Alias
83 judgment :: repr DTC.Judgment
84 choice_ :: repr DTC.Choice
85 opinion :: repr DTC.Opinion
86 judges :: repr DTC.Judges
87 judge :: repr DTC.Judge
88 grade :: repr DTC.Grade
90 document = rule "document" $
103 [ element "section" $ Tree . DTC.BodySection <$> section <*> body
104 , tree0 . DTC.BodyBlock <$> block
106 section = rule "section" $
108 (\section_posXML section_locTCT section_attrs abouts ->
109 DTC.Section{section_about=mconcat abouts, ..})
114 about = rule "about" $
122 <|*> element "tag" text
125 <|*> element "description" para
127 title = rule "title" $ DTC.Title <$> element "title" plain
128 name = rule "name" $ DTC.Name <$> text
129 url = rule "url" $ URL <$> text
130 path = rule "path" $ TL.unpack <$> text
131 ident = rule "ident" $ Ident <$> text
132 to = rule "to" $ attribute "to" ident
137 <$?> (def, Just <$> id)
139 id = rule "id" $ attribute "id" ident
140 class_ = rule "class" $ attribute "class" $ TL.words <$> text
141 rel = rule "rel" $ attribute "rel" name
142 role = rule "role" $ attribute "role" name
150 <||> attribute "year" int
151 <|?> (def, Just <$> attribute "month" nat1)
152 <|?> (def, Just <$> attribute "day" nat1)
158 <$?> (def, attribute "href" path)
159 block = rule "block" $
161 [ DTC.BlockPara <$> para
172 , anyElem $ \n@XmlName{..} ->
177 blockBreak = rule "break" $
187 <*> optional (attribute "depth" nat)
216 (Index.wordify <$>) . TL.lines <$> text
233 <*> attribute "type" text
238 rule "blockReferences" $
239 element "references" $
244 blockJudges = rule "blockJudges" $ DTC.BlockJudges <$> judges
257 <*> attribute "name" name
258 <*> attribute "color" text
259 <*> option False (True <$ attribute "default" text)
263 paraItems <|> -- within a <para>
264 DTC.ParaItem <$> paraItem -- without a <para>
268 [ element "ol" $ DTC.ParaOL <$> many (element "li" $ DTC.ListItem <$> attribute "name" name <*> many para)
269 , element "ul" $ DTC.ParaUL <$> many (element "li" $ many para)
270 , element "artwork" $ DTC.ParaArtwork <$> attribute "type" text <*> text
271 , element "quote" $ DTC.ParaQuote <$> attribute "type" text <*> many para
272 , DTC.ParaPlain . Seq.fromList <$> some plainNode
273 , DTC.ParaComment <$> comment
274 , DTC.ParaJudgment <$> judgment
283 plain = rule "plain" $ (Seq.fromList <$>) $ many plainNode
287 [ tree0 . DTC.PlainText <$> text
288 , element "br" $ tree0 DTC.PlainBreak <$ none
289 , element "b" $ Tree DTC.PlainB <$> plain
290 , element "code" $ Tree DTC.PlainCode <$> plain
291 , element "del" $ Tree DTC.PlainDel <$> plain
292 , element "i" $ Tree DTC.PlainI <$> plain
293 , element "q" $ Tree DTC.PlainQ <$> plain
294 , element "sc" $ Tree DTC.PlainSC <$> plain
295 , element "span" $ Tree . DTC.PlainSpan <$> commonAttrs <*> plain
296 , element "sub" $ Tree DTC.PlainSub <$> plain
297 , element "sup" $ Tree DTC.PlainSup <$> plain
298 , element "u" $ Tree DTC.PlainU <$> plain
299 , element "note" $ tree0 . DTC.PlainNote <$> many para
300 , element "iref" $ Tree . DTC.PlainIref . Index.wordify <$> attribute "to" text <*> plain
301 , element "eref" $ Tree . DTC.PlainEref <$> attribute "to" url <*> plain
302 , element "tag" $ tree0 <$> (DTC.PlainTag <$> locationTCT <*> positionXML <*> to <*> pure False)
303 , element "tag-back" $ tree0 <$> (DTC.PlainTag <$> locationTCT <*> positionXML <*> to <*> pure True )
304 , element "at" $ tree0 <$> (DTC.PlainAt <$> locationTCT <*> positionXML <*> to <*> pure False)
305 , element "at-back" $ tree0 <$> (DTC.PlainAt <$> locationTCT <*> positionXML <*> to <*> pure True )
306 , element "ref" $ Tree <$> (DTC.PlainRef <$> locationTCT <*> positionXML <*> to) <*> plain
312 DTC.Header (XML.nameLocal n)
315 author = rule "author" $ element "author" entity
316 entity = rule "entity" $
321 <|?> (def, attribute "name" text)
322 <|?> (def, attribute "street" text)
323 <|?> (def, attribute "zipcode" text)
324 <|?> (def, attribute "city" text)
325 <|?> (def, attribute "region" text)
326 <|?> (def, attribute "country" text)
327 <|?> (def, attribute "email" text)
328 <|?> (def, attribute "tel" text)
329 <|?> (def, attribute "fax" text)
330 <|?> (def, Just <$> attribute "url" url)
331 <|*> element "org" entity
332 serie = rule "serie" $
336 <$?> (def, attribute "name" name)
337 <|?> (def, attribute "id" text)
344 <|?> (def, attribute "url" url)
345 <|?> (def, Seq.fromList <$> some plainNode)
346 alias = rule "alias" $
351 reference = rule "reference" $
352 element "reference" $
367 DTC.Judgment def -- def def
370 <||> attribute "judges" ident
371 <||> attribute "grades" ident
372 <|?> (def, Just <$> attribute "importance" rationalPositive)
373 <|?> (def, Just <$> attribute "hide" bool)
374 -- <|?> (def, Just <$> attribute "importance" (pure 0))
375 <|?> (def, Just <$> title)
387 (interleaved $ DTC.Opinion
390 <|?> (def, attribute "judge" name)
391 <|?> (def, attribute "grade" name)
392 <|?> (def, Just <$> attribute "default" name)
393 <|?> (def, Just <$> attribute "importance" rationalPositive))
394 -- <|?> (def, Just <$> attribute "importance" (pure 0)))
406 HM.fromListWith (flip (<>)) .
407 ((\j@DTC.Judge{..} -> (judge_name, pure j)) <$>)
415 <*> attribute "name" name
420 HM.fromListWith (flip (<>)) .
422 <$> many defaultGrade
427 <$> attribute "grades" ident
428 <*> attribute "grade" (DTC.Name <$> text)
430 instance Sym_DTC RNC.Writer where
431 positionXML = RNC.writeText ""
432 locationTCT = RNC.writeText ""
433 instance Sym_DTC RNC.RuleWriter where
434 positionXML = RNC.RuleWriter positionXML
435 locationTCT = RNC.RuleWriter locationTCT
437 -- | RNC schema for DTC
438 schema :: [RNC.RuleWriter ()]
465 , void $ blockReferences