1 {-# LANGUAGE DuplicateRecordFields #-}
2 {-# LANGUAGE NoMonomorphismRestriction #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 {-# LANGUAGE RankNTypes #-}
5 module Textphile.DTC.Sym where
7 import Control.Applicative (Applicative(..), (<$>), (<$))
8 import Control.Arrow (second)
9 import Control.Monad (void)
10 import Data.Bool (Bool(..))
11 import Data.Default.Class (Default(..))
12 import Data.Foldable (concat)
13 import Data.Monoid (Monoid(..))
14 import Data.Function (($), (.), flip)
15 import Data.Maybe (Maybe(..))
16 import Data.Semigroup (Semigroup(..))
17 import Data.TreeSeq.Strict (Tree(..), tree0)
18 import Symantic.RNC hiding (element, attribute)
19 import Text.Blaze.DTC (xmlns_dtc)
20 import qualified Data.HashMap.Strict as HM
21 import qualified Data.Text.Lazy as TL
22 import qualified Symantic.RNC as RNC
23 import qualified Symantic.XML as XML
25 import Textphile.RNC as RNC
27 import qualified Textphile.DTC.Analyze.Index as Index
28 import qualified Textphile.DTC.Document as DTC
29 import qualified Textphile.TCT.Cell as TCT
30 import qualified Textphile.XML as XML
32 element :: RNC.Sym_RNC repr => XML.NCName -> repr a -> repr a
33 element = RNC.element . XML.QName xmlns_dtc
34 attribute :: RNC.Sym_RNC repr => XML.NCName -> repr a -> repr a
35 attribute = RNC.attribute . XML.QName ""
38 -- | Use a symantic (tagless final) class to encode
39 -- both the parsing and the schema of DTC,
40 -- when repr is respectively instanciated
41 -- on 'DTC.Parser', 'RNC.NS' or 'RNC.Writer'.
42 class (Sym_RNC repr, Sym_RNC_Extra repr) => Sym_DTC repr where
43 positionXML :: repr XML.Pos
44 locationTCT :: repr TCT.Location
45 document :: repr DTC.Document
49 section :: repr DTC.Section
50 about :: repr DTC.About
51 include :: repr DTC.Include
53 block :: repr DTC.Block
54 blockBreak :: repr DTC.Block
55 blockToC :: repr DTC.Block
56 blockToF :: repr DTC.Block
57 blockIndex :: repr DTC.Block
58 blockAside :: repr DTC.Block
59 blockFigure :: repr DTC.Block
60 blockReferences :: repr DTC.Block
61 blockJudges :: repr DTC.Block
62 blockGrades :: repr DTC.Block
63 reference :: repr DTC.Reference
66 paraItem :: repr DTC.ParaItem
67 paraItems :: repr DTC.Para
69 plain :: repr DTC.Plain
70 plainNode :: repr (Tree DTC.PlainNode)
72 commonAttrs :: repr DTC.CommonAttrs
74 title :: repr DTC.Title
77 path :: repr DTC.FilePath
80 class_ :: repr [TL.Text]
84 author :: repr DTC.Entity
86 entity :: repr DTC.Entity
88 serie :: repr DTC.Serie
89 alias :: repr DTC.Alias
90 judgment :: repr DTC.Judgment
91 choice_ :: repr DTC.Choice
92 opinion :: repr DTC.Opinion
93 judges :: repr DTC.Judges
94 judge :: repr DTC.Judge
95 grade :: repr DTC.Grade
97 document = rule "document" $
109 [ element "section" $ Tree . DTC.BodySection <$> section <*> body
110 , tree0 . DTC.BodyBlock <$> block
112 section = rule "section" $
114 (\section_posXML section_locTCT section_attrs abouts ->
115 DTC.Section{section_about=mconcat abouts, ..})
120 about = rule "about" $
128 <|*> element "tag" text
131 <|*> element "description" para
133 title = rule "title" $ DTC.Title <$> element "title" plain
134 name = rule "name" $ DTC.Name <$> text
135 url = rule "url" $ URL <$> text
136 path = rule "path" $ TL.unpack <$> text
137 ident = rule "ident" $ Ident <$> text
138 to = rule "to" $ attribute "to" ident
143 <$?> (def, Just <$> id)
145 id = rule "id" $ attribute "id" ident
146 class_ = rule "class" $ attribute "class" $ TL.words <$> text
147 rel = rule "rel" $ attribute "rel" name
148 role = rule "role" $ attribute "role" name
156 <||> attribute "year" int
157 <|?> (def, Just <$> attribute "month" nat1)
158 <|?> (def, Just <$> attribute "day" nat1)
164 <$?> (def, attribute "href" path)
165 block = rule "block" $
167 [ DTC.BlockPara <$> para
178 , anyElem $ \n@XmlName{..} ->
183 blockBreak = rule "break" $
193 <*> optional (attribute "depth" nat)
222 (Index.wordify <$>) . TL.lines <$> text
239 <*> attribute "type" text
244 rule "blockReferences" $
245 element "references" $
250 blockJudges = rule "blockJudges" $ DTC.BlockJudges <$> judges
263 <*> attribute "name" name
264 <*> attribute "color" text
265 <*> option False (True <$ attribute "default" text)
269 paraItems <|> -- within a <para>
270 DTC.ParaItem <$> paraItem -- without a <para>
274 [ element "ol" $ DTC.ParaOL <$> many (element "li" $ DTC.ListItem <$> attribute "name" name <*> many para)
275 , element "ul" $ DTC.ParaUL <$> many (element "li" $ many para)
276 , element "artwork" $ DTC.ParaArtwork <$> attribute "type" text <*> text
277 , element "quote" $ DTC.ParaQuote <$> attribute "type" text <*> many para
278 , DTC.ParaPlain <$> someSeq plainNode
279 , DTC.ParaComment <$> comment
280 , DTC.ParaJudgment <$> judgment
289 plain = rule "plain" $ manySeq plainNode
293 [ tree0 . DTC.PlainText <$> text
294 , element "br" $ tree0 DTC.PlainBreak <$ empty
295 , element "b" $ Tree DTC.PlainB <$> plain
296 , element "code" $ Tree DTC.PlainCode <$> plain
297 , element "del" $ Tree DTC.PlainDel <$> plain
298 , element "i" $ Tree DTC.PlainI <$> plain
299 , element "q" $ Tree DTC.PlainQ <$> plain
300 , element "sc" $ Tree DTC.PlainSC <$> plain
301 , element "span" $ Tree . DTC.PlainSpan <$> commonAttrs <*> plain
302 , element "sub" $ Tree DTC.PlainSub <$> plain
303 , element "sup" $ Tree DTC.PlainSup <$> plain
304 , element "u" $ Tree DTC.PlainU <$> plain
305 , element "note" $ tree0 . DTC.PlainNote <$> many para
306 , element "iref" $ Tree . DTC.PlainIref . Index.wordify <$> attribute "to" text <*> plain
307 , element "eref" $ Tree . DTC.PlainEref <$> attribute "to" url <*> plain
308 , element "tag" $ tree0 <$> (DTC.PlainTag <$> locationTCT <*> positionXML <*> to <*> pure False)
309 , element "tag-back" $ tree0 <$> (DTC.PlainTag <$> locationTCT <*> positionXML <*> to <*> pure True )
310 , element "at" $ tree0 <$> (DTC.PlainAt <$> locationTCT <*> positionXML <*> to <*> pure False)
311 , element "at-back" $ tree0 <$> (DTC.PlainAt <$> locationTCT <*> positionXML <*> to <*> pure True )
319 , element "page-ref" $
321 <$> (DTC.PlainPageRef
324 <*> attribute "to" text
325 <*> optional (attribute "at" ident)
332 DTC.Header (XML.nameLocal n)
335 author = rule "author" $ element "author" entity
336 entity = rule "entity" $
341 <|?> (def, attribute "name" text)
342 <|?> (def, attribute "street" text)
343 <|?> (def, attribute "zipcode" text)
344 <|?> (def, attribute "city" text)
345 <|?> (def, attribute "region" text)
346 <|?> (def, attribute "country" text)
347 <|?> (def, attribute "email" text)
348 <|?> (def, attribute "tel" text)
349 <|?> (def, attribute "fax" text)
350 <|?> (def, Just <$> attribute "url" url)
351 <|*> element "org" entity
352 serie = rule "serie" $
356 <$?> (def, attribute "name" name)
357 <|?> (def, attribute "id" text)
364 <|?> (def, attribute "url" url)
365 <|?> (def, someSeq plainNode)
366 alias = rule "alias" $
371 reference = rule "reference" $
372 element "reference" $
387 DTC.Judgment def -- def def
390 <||> attribute "judges" ident
391 <||> attribute "grades" ident
392 <|?> (def, Just <$> attribute "importance" rationalPositive)
393 <|?> (def, Just <$> attribute "hide" bool)
394 -- <|?> (def, Just <$> attribute "importance" (pure 0))
395 <|?> (def, Just <$> title)
407 (runPermutation $ DTC.Opinion
410 <|?> (def, attribute "judge" name)
411 <|?> (def, attribute "grade" name)
412 <|?> (def, Just <$> attribute "default" name)
413 <|?> (def, Just <$> attribute "importance" rationalPositive))
414 -- <|?> (def, Just <$> attribute "importance" (pure 0)))
426 HM.fromListWith (flip (<>)) .
427 ((\j@DTC.Judge{..} -> (judge_name, pure j)) <$>)
435 <*> attribute "name" name
440 HM.fromListWith (flip (<>)) .
442 <$> many defaultGrade
447 <$> attribute "grades" ident
448 <*> attribute "grade" (DTC.Name <$> text)
450 instance Sym_DTC RNC.NS where
453 instance Sym_DTC RNC.Writer where
454 positionXML = RNC.writeText ""
455 locationTCT = RNC.writeText ""
457 -- | RNC schema for DTC
458 schema :: forall repr. Sym_DTC repr => [repr ()]
460 [ void $ RNC.namespace Nothing xmlns_dtc
487 , void $ blockReferences