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 Hdoc.DTC.Index (wordify)
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 (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 Nothing <$> many para
275 , element "iref" $ Tree . DTC.PlainIref Nothing . wordify <$> attribute "to" text <*> plain
276 , element "eref" $ Tree . DTC.PlainEref <$> attribute "to" url <*> plain
277 , element "tag" $ Tree . DTC.PlainTag def <$> locationTCT <*> plain
278 , element "rref" $ Tree <$> (DTC.PlainRref Nothing Nothing <$> locationTCT <*> to) <*> plain
280 tag = rule "tag" $ element "tag" text
282 (foldr ($) def <$>) $
284 [ (\a acc -> acc{DTC.titles=a:DTC.titles acc}) <$> title
285 , (\a acc -> (acc::DTC.About){DTC.url=Just a}) <$> attribute "url" url
286 , (\a acc -> acc{DTC.authors=a:DTC.authors acc}) <$> author
287 , (\a acc -> acc{DTC.editor=DTC.editor acc Alt.<|> Just a}) <$> editor
288 , (\a acc -> acc{DTC.date=DTC.date acc Alt.<|> Just a}) <$> date
289 , (\a acc -> acc{DTC.tags=a:DTC.tags acc}) <$> tag
290 , (\a acc -> acc{DTC.links=a:DTC.links acc}) <$> link
291 , (\a acc -> acc{DTC.series=a:DTC.series acc}) <$> serie
292 , (\a acc -> acc{DTC.headers=a:DTC.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" $
336 DTC.Reference Nothing
350 DTC.Judgment def def def
353 <||> attribute "judges" ident
354 <||> attribute "grades" ident
355 <|?> (def, Just <$> attribute "importance" rationalPositive)
356 <|?> (def, Just <$> title)
368 (interleaved $ DTC.Opinion
371 <|?> (def, attribute "judge" name)
372 <|?> (def, attribute "grade" name)
373 <|?> (def, Just <$> attribute "importance" rationalPositive))
385 HM.fromListWith (flip (<>)) .
386 ((\j@DTC.Judge{..} -> (judge_name, pure j)) <$>)
394 <*> attribute "name" name
399 HM.fromListWith (flip (<>)) .
401 <$> many defaultGrade
406 <$> attribute "grades" ident
407 <*> attribute "grade" (DTC.Name <$> text)
409 instance Sym_DTC RNC.Writer where
410 positionXML = RNC.writeText ""
411 locationTCT = RNC.writeText ""
412 instance Sym_DTC RNC.RuleWriter where
413 positionXML = RNC.RuleWriter positionXML
414 locationTCT = RNC.RuleWriter locationTCT
416 -- | RNC schema for DTC
417 schema :: [RNC.RuleWriter ()]
422 , void $ rule "about" $ element "about" about
447 , void $ blockReferences