1 {-# LANGUAGE FlexibleInstances #-}
2 {-# LANGUAGE OverloadedStrings #-}
3 module Hdoc.DTC.Collect where
4 import Control.Applicative (Applicative(..))
7 import Data.Default.Class (Default(..))
8 import Data.Foldable (Foldable(..), any)
9 import Data.Function (($))
10 import Data.Functor ((<$>), (<$))
11 import Data.Map.Strict (Map)
12 import Data.Maybe (Maybe(..), fromMaybe)
13 import Data.Monoid (Monoid(..))
14 import Data.Semigroup (Semigroup(..))
15 import Data.TreeSeq.Strict (Tree(..))
16 import Text.Show (Show(..))
17 import qualified Data.HashMap.Strict as HM
18 import qualified Data.Map.Strict as Map
19 import qualified Data.Sequence as Seq
20 import qualified Data.Text.Lazy as TL
21 import qualified Data.TreeSeq.Strict as TreeSeq
22 import qualified Hjugement as MJ
23 import qualified Data.Tree as Tree
26 import Hdoc.DTC.Document as DTC
27 import qualified Hdoc.DTC.Index as Index
28 import qualified Hdoc.DTC.Check as Check
31 -- | Collect 'Block's by mapping them by their 'Pos' or 'Ident'.
33 { all_index :: Map Pos Terms
34 , all_figure :: Map TL.Text (Map Pos (Maybe Title))
35 , all_reference :: Map Ident About
36 , all_judges :: HM.HashMap Ident [Judge]
37 , all_grades :: HM.HashMap Ident [Grade]
38 , all_judgments :: HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])]
40 instance Default All where
49 instance Semigroup All where
51 { all_index = Map.union (all_index x) (all_index y)
52 , all_figure = Map.unionWith (<>) (all_figure x) (all_figure y)
53 , all_reference = Map.union (all_reference x) (all_reference y)
54 , all_judges = HM.union (all_judges x) (all_judges y)
55 , all_grades = HM.union (all_grades x) (all_grades y)
56 , all_judgments = HM.unionWith (<>) (all_judgments x) (all_judgments y)
58 instance Monoid All where
65 instance Collect Document where
66 collect Document{head=Head{judgments=js}, body} =
67 (foldMap collect body)
69 choicesBySectionByJudgment HM.empty $
70 TreeSeq.Tree (choicesByJudgment js) $
71 choicesByJudgmentBySection body
73 choicesByJudgment :: [Judgment] -> HM.HashMap Judgment (Maybe MJ.Share, [Choice])
74 choicesByJudgment js =
75 HM.fromList $ (<$> js) $ \j@Judgment{..} ->
76 (j,(importance, choices))
77 choicesByJudgmentBySection :: Body -> TreeSeq.Trees (HM.HashMap Judgment (Maybe MJ.Share, [Choice]))
78 choicesByJudgmentBySection bod = bod >>= \(Tree b bs) ->
81 BodySection{judgments} ->
83 let choicesJ = choicesByJudgment judgments in
85 -- NOTE: if the 'BodySection' has a child which
86 -- is not a 'BodySection' itself, then add "phantom" 'Judgment's
87 -- which will inherit from this 'BodySection'.
88 -- This enables judges to express something on material not in a sub 'BodySection'.
89 let childrenBlocksJudgments =
91 Tree BodyBlock{} _ -> True
93 then Seq.singleton $ Tree ((Nothing,[]) <$ choicesJ) Seq.empty
95 childrenBlocksJudgments <>
96 choicesByJudgmentBySection bs
97 choicesBySectionByJudgment ::
98 HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])] ->
99 TreeSeq.Tree (HM.HashMap Judgment (Maybe MJ.Share, [Choice])) ->
100 HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])]
101 choicesBySectionByJudgment inh (TreeSeq.Tree selfJ childrenJS) =
104 (<$> selfS) $ \(Tree.Node choices old) ->
105 Tree.Node choices (old<>childrenS))
109 selfSJ = (\cs -> [Tree.Node cs []]) <$> selfJ
113 HM.unionWith (<>) accJ $
114 choicesBySectionByJudgment
115 (([Tree.Node (Nothing,[]) []] <$ selfJ) <> inh)
120 instance Collect (Tree BodyNode) where
121 collect (Tree n ts) =
123 BodyBlock b -> collect b
124 BodySection{} -> foldMap collect ts
125 instance Collect DTC.Block where
127 BlockPara _p -> def -- collect p
131 BlockAside{..} -> foldMap collect blocks
132 BlockIndex{..} -> def{all_index = Map.singleton pos terms}
135 Map.singleton type_ (Map.singleton pos mayTitle)}
136 -- <> foldMap collect paras
137 BlockReferences{..} ->
139 Map.fromList $ (<$> refs) $ \DTC.Reference{id=id', ..} -> (id', about)
141 BlockGrades{attrs=CommonAttrs{id=i}, ..} ->
142 def{all_grades = HM.singleton (fromMaybe "" i) scale}
143 BlockJudges{attrs=CommonAttrs{id=i}, ..} ->
144 def{all_judges = HM.singleton (fromMaybe "" i) jury}
146 instance Collect Judgment where
147 collect Judgment{..} = def
150 (judges,grades,question)
151 (Tree.Node choices [])
153 -- <> foldMap collect choices
154 instance Collect Para where
156 ParaItem item -> collect item
157 ParaItems{..} -> foldMap collect items
158 instance Collect ParaItem where
162 ParaQuote{..} -> foldMap collect paras
164 ParaOL items -> foldMap collect items
165 ParaUL items -> foldMap (foldMap collect) items
166 ParaJudgment{} -> def
167 instance Collect ListItem where
168 collect ListItem{..} = foldMap collect paras
169 instance Collect Choice where
171 foldMap collect title <>
172 foldMap collect opinions
173 instance Collect Opinion where
174 collect Opinion{..} =
175 foldMap collect comment
176 instance Collect Title where
177 collect (Title t) = collect t
178 instance Collect Plain where
179 collect = foldMap collect
180 instance Collect (Tree PlainNode) where
181 collect (Tree n ts) =
185 PlainGroup -> collect ts
187 PlainCode -> collect ts
188 PlainDel -> collect ts
190 PlainSpan{} -> collect ts
191 PlainSub -> collect ts
192 PlainSup -> collect ts
193 PlainSC -> collect ts
195 PlainNote{..} -> foldMap collect note
197 PlainEref{} -> collect ts
198 PlainIref{} -> collect ts
199 PlainRef{} -> collect ts
200 PlainRref{..} -> collect ts