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.Function (($), (.), flip)
13 import Data.Maybe (Maybe(..))
14 import Data.Semigroup (Semigroup(..))
15 import Data.TreeSeq.Strict (Tree(..), tree0)
16 import qualified Data.HashMap.Strict as HM
17 import qualified Data.Sequence as Seq
18 import qualified Data.Text.Lazy as TL
21 import Hdoc.RNC.Sym as RNC
22 import qualified Hdoc.DTC.Analyze.Index as Index
23 import qualified Hdoc.DTC.Document as DTC
24 import qualified Hdoc.RNC.Write as RNC
25 import qualified Hdoc.TCT.Cell as TCT
26 import qualified Hdoc.XML as XML
29 -- | Use a symantic (tagless final) class to encode
30 -- both the parsing and the schema of DTC,
31 -- when repr is respectively instanciated
32 -- on 'DTC.Parser' or 'RNC.RuleWriter'.
33 class RNC.Sym_RNC repr => Sym_DTC repr where
34 positionXML :: repr XML.Pos
35 locationTCT :: repr TCT.Location
36 document :: repr DTC.Document
39 about :: repr DTC.About
40 header :: repr DTC.Header
43 include :: repr DTC.Include
45 block :: repr DTC.Block
46 blockBreak :: repr DTC.Block
47 blockToC :: repr DTC.Block
48 blockToF :: repr DTC.Block
49 blockIndex :: repr DTC.Block
50 blockAside :: repr DTC.Block
51 blockFigure :: repr DTC.Block
52 blockReferences :: repr DTC.Block
53 blockJudges :: repr DTC.Block
54 blockGrades :: repr DTC.Block
55 reference :: repr DTC.Reference
58 paraItem :: repr DTC.ParaItem
59 paraItems :: repr DTC.Para
61 plain :: repr DTC.Plain
62 plainNode :: repr (Tree DTC.PlainNode)
64 commonAttrs :: repr DTC.CommonAttrs
66 title :: repr DTC.Title
69 path :: repr DTC.FilePath
72 class_ :: repr [TL.Text]
74 author :: repr DTC.Entity
75 editor :: repr DTC.Entity
77 entity :: repr DTC.Entity
79 serie :: repr DTC.Serie
80 alias :: repr DTC.Alias
81 judgment :: repr DTC.Judgment
82 choice_ :: repr DTC.Choice
83 opinion :: repr DTC.Opinion
84 judges :: repr DTC.Judges
85 judge :: repr DTC.Judge
86 grade :: repr DTC.Grade
88 document = rule "document" $
95 <$?> (def, rule "about" $ element "about" about)
102 [ element "section" $ Tree . DTC.BodySection <$> section <*> body
103 , tree0 . DTC.BodyBlock <$> block
113 title = rule "title" $ DTC.Title <$> element "title" plain
114 name = rule "name" $ DTC.Name <$> text
115 url = rule "url" $ URL <$> text
116 path = rule "path" $ TL.unpack <$> text
117 ident = rule "ident" $ Ident <$> text
118 to = rule "to" $ attribute "to" ident
123 <$?> (def, Just <$> id)
125 id = rule "id" $ attribute "id" ident
126 class_ = rule "class" $ attribute "class" $ TL.words <$> text
131 <$?> (0, attribute "year" int)
132 <|?> (Nothing, Just <$> attribute "month" nat1)
133 <|?> (Nothing, Just <$> attribute "day" nat1)
139 <$?> (def, attribute "href" path)
140 block = rule "block" $
142 [ DTC.BlockPara <$> para
153 , anyElem $ \n@XmlName{..} ->
158 blockBreak = rule "break" $
168 <*> optional (attribute "depth" nat)
193 (Index.wordify <$>) . TL.lines <$> text)
206 <*> attribute "type" text
211 rule "blockReferences" $
212 element "references" $
217 blockJudges = rule "blockJudges" $ DTC.BlockJudges <$> judges
230 <*> attribute "name" name
231 <*> attribute "color" text
232 <*> option False (True <$ attribute "default" text)
236 paraItems <|> -- within a <para>
237 DTC.ParaItem <$> paraItem -- without a <para>
241 [ element "ol" $ DTC.ParaOL <$> many (element "li" $ DTC.ListItem <$> attribute "name" name <*> many para)
242 , element "ul" $ DTC.ParaUL <$> many (element "li" $ many para)
243 , element "artwork" $ DTC.ParaArtwork <$> attribute "type" text <*> text
244 , element "quote" $ DTC.ParaQuote <$> attribute "type" text <*> many para
245 , DTC.ParaPlain . Seq.fromList <$> some plainNode
246 , DTC.ParaComment <$> comment
247 , DTC.ParaJudgment <$> judgment
256 plain = rule "plain" $ (Seq.fromList <$>) $ many plainNode
260 [ tree0 . DTC.PlainText <$> text
261 , element "br" $ tree0 DTC.PlainBreak <$ none
262 , element "b" $ Tree DTC.PlainB <$> plain
263 , element "code" $ Tree DTC.PlainCode <$> plain
264 , element "del" $ Tree DTC.PlainDel <$> plain
265 , element "i" $ Tree DTC.PlainI <$> plain
266 , element "q" $ Tree DTC.PlainQ <$> plain
267 , element "sc" $ Tree DTC.PlainSC <$> plain
268 , element "span" $ Tree . DTC.PlainSpan <$> commonAttrs <*> plain
269 , element "sub" $ Tree DTC.PlainSub <$> plain
270 , element "sup" $ Tree DTC.PlainSup <$> plain
271 , element "u" $ Tree DTC.PlainU <$> plain
272 , element "note" $ tree0 . DTC.PlainNote <$> many para
273 , element "iref" $ Tree . DTC.PlainIref . Index.wordify <$> attribute "to" text <*> plain
274 , element "eref" $ Tree . DTC.PlainEref <$> attribute "to" url <*> plain
275 , element "tag" $ tree0 <$> (DTC.PlainTag <$> locationTCT <*> positionXML <*> to <*> pure False)
276 , element "tag-back" $ tree0 <$> (DTC.PlainTag <$> locationTCT <*> positionXML <*> to <*> pure True )
277 , element "at" $ tree0 <$> (DTC.PlainAt <$> locationTCT <*> positionXML <*> to <*> pure False)
278 , element "at-back" $ tree0 <$> (DTC.PlainAt <$> locationTCT <*> positionXML <*> to <*> pure True )
279 , element "ref" $ Tree <$> (DTC.PlainRef <$> locationTCT <*> positionXML <*> to) <*> plain
289 <|?> (def, Just <$> attribute "url" url)
291 <|?> (def, Just <$> editor)
292 <|?> (def, Just <$> date)
293 <|*> element "tag" text
296 <|?> (def, Just <$> element "description" para)
300 DTC.Header (XML.nameLocal n)
302 author = rule "author" $ element "author" entity
303 editor = rule "editor" $ element "editor" entity
304 entity = rule "entity" $
307 <$?> (def, attribute "name" text)
308 <|?> (def, attribute "street" text)
309 <|?> (def, attribute "zipcode" text)
310 <|?> (def, attribute "city" text)
311 <|?> (def, attribute "region" text)
312 <|?> (def, attribute "country" text)
313 <|?> (def, attribute "email" text)
314 <|?> (def, attribute "tel" text)
315 <|?> (def, attribute "fax" text)
316 <|?> (def, Just <$> attribute "url" url)
317 <|?> (def, Just <$> element "org" entity)
318 serie = rule "serie" $
322 <$?> (def, attribute "name" name)
323 <|?> (def, attribute "id" text)
327 (\n h r t p -> DTC.Link n h r t (Seq.fromList p))
328 <$?> (def, attribute "name" name)
329 <|?> (def, attribute "href" url)
330 <|?> (def, attribute "rel" text)
331 <|?> (def, Just <$> attribute "type" text)
333 alias = rule "alias" $
338 reference = rule "reference" $
339 element "reference" $
354 DTC.Judgment def def def
357 <||> attribute "judges" ident
358 <||> attribute "grades" ident
359 <|?> (def, Just <$> attribute "importance" rationalPositive)
360 -- <|?> (def, Just <$> attribute "importance" (pure 0))
361 <|?> (def, Just <$> title)
373 (interleaved $ DTC.Opinion
376 <|?> (def, attribute "judge" name)
377 <|?> (def, attribute "grade" name)
378 <|?> (def, Just <$> attribute "importance" rationalPositive))
379 -- <|?> (def, Just <$> attribute "importance" (pure 0)))
391 HM.fromListWith (flip (<>)) .
392 ((\j@DTC.Judge{..} -> (judge_name, pure j)) <$>)
400 <*> attribute "name" name
405 HM.fromListWith (flip (<>)) .
407 <$> many defaultGrade
412 <$> attribute "grades" ident
413 <*> attribute "grade" (DTC.Name <$> text)
415 instance Sym_DTC RNC.Writer where
416 positionXML = RNC.writeText ""
417 locationTCT = RNC.writeText ""
418 instance Sym_DTC RNC.RuleWriter where
419 positionXML = RNC.RuleWriter positionXML
420 locationTCT = RNC.RuleWriter locationTCT
422 -- | RNC schema for DTC
423 schema :: [RNC.RuleWriter ()]
428 , void $ rule "about" $ element "about" about
452 , void $ blockReferences