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 (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 Control.Applicative as Alt
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
40 about :: repr DTC.About
41 header :: repr DTC.Header
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 blockAside :: repr DTC.Block
53 blockFigure :: repr DTC.Block
54 blockReferences :: repr DTC.Block
55 blockJudges :: repr DTC.Block
56 blockGrades :: repr DTC.Block
57 reference :: repr DTC.Reference
60 paraItem :: repr DTC.ParaItem
61 paraItems :: repr DTC.Para
63 plain :: repr DTC.Plain
64 plainNode :: repr (Tree DTC.PlainNode)
66 commonAttrs :: repr DTC.CommonAttrs
68 title :: repr DTC.Title
71 path :: repr DTC.FilePath
74 class_ :: repr [TL.Text]
76 author :: repr DTC.Entity
77 editor :: 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" $
97 <$?> (def, rule "about" $ element "about" about)
104 [ element "section" $ Tree . DTC.BodySection <$> section <*> body
105 , tree0 . DTC.BodyBlock <$> block
115 title = rule "title" $ DTC.Title <$> element "title" plain
116 name = rule "name" $ DTC.Name <$> text
117 url = rule "url" $ URL <$> text
118 path = rule "path" $ TL.unpack <$> text
119 ident = rule "ident" $ Ident <$> text
120 to = rule "to" $ attribute "to" ident
125 <$?> (def, Just <$> id)
127 id = rule "id" $ attribute "id" ident
128 class_ = rule "class" $ attribute "class" $ TL.words <$> text
133 <$?> (0, attribute "year" int)
134 <|?> (Nothing, Just <$> attribute "month" nat1)
135 <|?> (Nothing, Just <$> attribute "day" nat1)
141 <$?> (def, attribute "href" path)
142 block = rule "block" $
144 [ DTC.BlockPara <$> para
155 , anyElem $ \n@XmlName{..} ->
160 blockBreak = rule "break" $
170 <*> optional (attribute "depth" nat)
195 (Index.wordify <$>) . TL.lines <$> text)
208 <*> attribute "type" text
213 rule "blockReferences" $
214 element "references" $
219 blockJudges = rule "blockJudges" $ DTC.BlockJudges <$> judges
232 <*> attribute "name" name
233 <*> attribute "color" text
234 <*> option False (True <$ attribute "default" text)
238 paraItems <|> -- within a <para>
239 DTC.ParaItem <$> paraItem -- without a <para>
243 [ element "ol" $ DTC.ParaOL <$> many (element "li" $ DTC.ListItem <$> attribute "name" name <*> many para)
244 , element "ul" $ DTC.ParaUL <$> many (element "li" $ many para)
245 , element "artwork" $ DTC.ParaArtwork <$> attribute "type" text <*> text
246 , element "quote" $ DTC.ParaQuote <$> attribute "type" text <*> many para
247 , DTC.ParaPlain . Seq.fromList <$> some plainNode
248 , DTC.ParaComment <$> comment
249 , DTC.ParaJudgment <$> judgment
258 plain = rule "plain" $ (Seq.fromList <$>) $ many plainNode
262 [ tree0 . DTC.PlainText <$> text
263 , element "br" $ tree0 DTC.PlainBreak <$ none
264 , element "b" $ Tree DTC.PlainB <$> plain
265 , element "code" $ Tree DTC.PlainCode <$> plain
266 , element "del" $ Tree DTC.PlainDel <$> plain
267 , element "i" $ Tree DTC.PlainI <$> plain
268 , element "q" $ Tree DTC.PlainQ <$> plain
269 , element "sc" $ Tree DTC.PlainSC <$> plain
270 , element "span" $ Tree . DTC.PlainSpan <$> commonAttrs <*> plain
271 , element "sub" $ Tree DTC.PlainSub <$> plain
272 , element "sup" $ Tree DTC.PlainSup <$> plain
273 , element "u" $ Tree DTC.PlainU <$> plain
274 , element "note" $ tree0 . DTC.PlainNote <$> many para
275 , element "iref" $ Tree . DTC.PlainIref . Index.wordify <$> attribute "to" text <*> plain
276 , element "eref" $ Tree . DTC.PlainEref <$> attribute "to" url <*> plain
277 , element "tag" $ Tree <$> (DTC.PlainTag <$> locationTCT <*> positionXML) <*> plain
278 , element "rref" $ Tree <$> (DTC.PlainRref <$> locationTCT <*> positionXML <*> to) <*> plain
280 tag = rule "tag" $ element "tag" text
289 <|?> (def, Just <$> attribute "url" url)
291 <|?> (def, Just <$> editor)
292 <|?> (def, Just <$> date)
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" $
337 reference = rule "reference" $
338 element "reference" $
353 DTC.Judgment def def def
356 <||> attribute "judges" ident
357 <||> attribute "grades" ident
358 <|?> (def, Just <$> attribute "importance" rationalPositive)
359 -- <|?> (def, Just <$> attribute "importance" (pure 0))
360 <|?> (def, Just <$> title)
372 (interleaved $ DTC.Opinion
375 <|?> (def, attribute "judge" name)
376 <|?> (def, attribute "grade" name)
377 <|?> (def, Just <$> attribute "importance" rationalPositive))
378 -- <|?> (def, Just <$> attribute "importance" (pure 0)))
390 HM.fromListWith (flip (<>)) .
391 ((\j@DTC.Judge{..} -> (judge_name, pure j)) <$>)
399 <*> attribute "name" name
404 HM.fromListWith (flip (<>)) .
406 <$> many defaultGrade
411 <$> attribute "grades" ident
412 <*> attribute "grade" (DTC.Name <$> text)
414 instance Sym_DTC RNC.Writer where
415 positionXML = RNC.writeText ""
416 locationTCT = RNC.writeText ""
417 instance Sym_DTC RNC.RuleWriter where
418 positionXML = RNC.RuleWriter positionXML
419 locationTCT = RNC.RuleWriter locationTCT
421 -- | RNC schema for DTC
422 schema :: [RNC.RuleWriter ()]
427 , void $ rule "about" $ element "about" about
452 , void $ blockReferences