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
282 (foldr ($) def <$>) $
284 [ (\a acc -> acc{DTC.about_titles = a:DTC.about_titles acc}) <$> title
285 , (\a acc -> acc{DTC.about_url = Just a}) <$> attribute "url" url
286 , (\a acc -> acc{DTC.about_authors = a:DTC.about_authors acc}) <$> author
287 , (\a acc -> acc{DTC.about_editor = DTC.about_editor acc Alt.<|> Just a}) <$> editor
288 , (\a acc -> acc{DTC.about_date = DTC.about_date acc Alt.<|> Just a}) <$> date
289 , (\a acc -> acc{DTC.about_tags = a:DTC.about_tags acc}) <$> tag
290 , (\a acc -> acc{DTC.about_links = a:DTC.about_links acc}) <$> link
291 , (\a acc -> acc{DTC.about_series = a:DTC.about_series acc}) <$> serie
292 , (\a acc -> acc{DTC.about_headers = a:DTC.about_headers acc}) <$> header
297 DTC.Header (XML.nameLocal n)
299 author = rule "author" $ element "author" entity
300 editor = rule "editor" $ element "editor" entity
301 entity = rule "entity" $
304 <$?> (def, attribute "name" text)
305 <|?> (def, attribute "street" text)
306 <|?> (def, attribute "zipcode" text)
307 <|?> (def, attribute "city" text)
308 <|?> (def, attribute "region" text)
309 <|?> (def, attribute "country" text)
310 <|?> (def, attribute "email" text)
311 <|?> (def, attribute "tel" text)
312 <|?> (def, attribute "fax" text)
313 <|?> (def, Just <$> attribute "url" url)
314 <|?> (def, Just <$> element "org" entity)
315 serie = rule "serie" $
319 <$?> (def, attribute "name" name)
320 <|?> (def, attribute "id" text)
324 (\n h r t p -> DTC.Link n h r t (Seq.fromList p))
325 <$?> (def, attribute "name" name)
326 <|?> (def, attribute "href" url)
327 <|?> (def, attribute "rel" text)
328 <|?> (def, Just <$> attribute "type" text)
330 alias = rule "alias" $
334 reference = rule "reference" $
335 element "reference" $
350 DTC.Judgment def def def
353 <||> attribute "judges" ident
354 <||> attribute "grades" ident
355 <|?> (def, Just <$> attribute "importance" rationalPositive)
356 -- <|?> (def, Just <$> attribute "importance" (pure 0))
357 <|?> (def, Just <$> title)
369 (interleaved $ DTC.Opinion
372 <|?> (def, attribute "judge" name)
373 <|?> (def, attribute "grade" name)
374 <|?> (def, Just <$> attribute "importance" rationalPositive))
375 -- <|?> (def, Just <$> attribute "importance" (pure 0)))
387 HM.fromListWith (flip (<>)) .
388 ((\j@DTC.Judge{..} -> (judge_name, pure j)) <$>)
396 <*> attribute "name" name
401 HM.fromListWith (flip (<>)) .
403 <$> many defaultGrade
408 <$> attribute "grades" ident
409 <*> attribute "grade" (DTC.Name <$> text)
411 instance Sym_DTC RNC.Writer where
412 positionXML = RNC.writeText ""
413 locationTCT = RNC.writeText ""
414 instance Sym_DTC RNC.RuleWriter where
415 positionXML = RNC.RuleWriter positionXML
416 locationTCT = RNC.RuleWriter locationTCT
418 -- | RNC schema for DTC
419 schema :: [RNC.RuleWriter ()]
424 , void $ rule "about" $ element "about" about
449 , void $ blockReferences