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.Either (Either(..))
9 import Data.Foldable (Foldable(..), any)
10 import Data.Function (($))
11 import Data.Functor ((<$>), (<$))
12 import Data.Map.Strict (Map)
13 import Data.Maybe (Maybe(..), fromMaybe)
14 import Data.Monoid (Monoid(..))
15 import Data.Sequence (Seq)
16 import Data.Semigroup (Semigroup(..))
17 import Data.TreeSeq.Strict (Tree(..))
18 import Text.Show (Show(..))
19 import qualified Data.HashMap.Strict as HM
20 import qualified Data.Map.Strict as Map
21 import qualified Data.Sequence as Seq
22 import qualified Data.Text.Lazy as TL
23 import qualified Data.TreeSeq.Strict as TreeSeq
24 import qualified Hjugement as MJ
25 import qualified Data.Tree as Tree
27 -- import Hdoc.Utils ()
28 import Hdoc.DTC.Document as DTC
31 -- | Collect 'Block's by mapping them by their 'XmlPos' or 'Ident'.
33 { all_index :: Map XmlPos Terms
34 , all_figure :: Map TL.Text (Map XmlPos (Maybe Title))
35 , all_reference :: HM.HashMap Ident (Seq Reference)
36 , all_section :: HM.HashMap Title (Seq (Either Head Section))
37 , all_judges :: HM.HashMap Ident [Judge]
38 , all_grades :: HM.HashMap Ident [Grade]
39 , all_judgments :: HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])]
41 instance Default All where
51 instance Semigroup All where
53 { all_index = Map.union (all_index x) (all_index y)
54 , all_figure = Map.unionWith (<>) (all_figure x) (all_figure y)
55 , all_section = HM.unionWith (<>) (all_section x) (all_section y)
56 , all_reference = HM.unionWith (<>) (all_reference x) (all_reference y)
57 , all_judges = HM.union (all_judges x) (all_judges y)
58 , all_grades = HM.union (all_grades x) (all_grades y)
59 , all_judgments = HM.unionWith (<>) (all_judgments x) (all_judgments y)
61 instance Monoid All where
68 instance Collect Document where
69 collect Document{head=head@Head{about=About{titles}, judgments=js}, body} =
70 def{ all_section = HM.fromListWith (<>) $ (\t -> (t, pure $ Left head)) <$> titles } <>
71 (foldMap collect body)
73 choicesBySectionByJudgment HM.empty $
74 TreeSeq.Tree (choicesByJudgment js) $
75 choicesByJudgmentBySection body
77 instance Collect (Tree BodyNode) where
80 BodyBlock b -> collect b
81 BodySection s@Section{title, aliases} ->
82 def{ all_section = HM.fromListWith (<>) $ (\(Alias t) -> (t, pure $ Right s)) <$> (Alias title : aliases) } <>
84 instance Collect DTC.Block where
86 BlockPara _p -> def -- collect p
90 BlockAside{..} -> foldMap collect blocks
91 BlockIndex{..} -> def{all_index = Map.singleton xmlPos terms}
94 Map.singleton type_ (Map.singleton xmlPos mayTitle)}
95 -- <> foldMap collect paras
96 BlockReferences{..} ->
98 HM.fromListWith (<>) $ (<$> refs) $ \ref@DTC.Reference{id} -> (id, pure ref)
100 BlockGrades{attrs=CommonAttrs{id=i}, ..} ->
101 def{all_grades = HM.singleton (fromMaybe "" i) scale}
102 BlockJudges{attrs=CommonAttrs{id=i}, ..} ->
103 def{all_judges = HM.singleton (fromMaybe "" i) jury}
105 instance Collect Judgment where
106 collect Judgment{..} = def
109 (judges,grades,question)
110 (Tree.Node choices [])
112 -- <> foldMap collect choices
113 instance Collect Para where
115 ParaItem item -> collect item
116 ParaItems{..} -> foldMap collect items
117 instance Collect ParaItem where
121 ParaQuote{..} -> foldMap collect paras
123 ParaOL items -> foldMap collect items
124 ParaUL items -> foldMap (foldMap collect) items
125 ParaJudgment{} -> def
126 instance Collect ListItem where
127 collect ListItem{..} = foldMap collect paras
128 instance Collect Choice where
130 foldMap collect title <>
131 foldMap collect opinions
132 instance Collect Opinion where
133 collect Opinion{..} =
134 foldMap collect comment
135 instance Collect Title where
136 collect (Title t) = collect t
137 instance Collect Plain where
138 collect = foldMap collect
139 instance Collect (Tree PlainNode) where
140 collect (Tree n ts) =
144 PlainGroup -> collect ts
146 PlainCode -> collect ts
147 PlainDel -> collect ts
149 PlainSpan{} -> collect ts
150 PlainSub -> collect ts
151 PlainSup -> collect ts
152 PlainSC -> collect ts
154 PlainNote{..} -> foldMap collect note
156 PlainEref{} -> collect ts
157 PlainIref{} -> collect ts
158 PlainTag{} -> collect ts
159 PlainRref{..} -> collect ts
162 choicesByJudgment :: [Judgment] -> HM.HashMap Judgment (Maybe MJ.Share, [Choice])
163 choicesByJudgment js =
164 HM.fromList $ (<$> js) $ \j@Judgment{..} ->
165 (j,(importance, choices))
166 choicesByJudgmentBySection :: Body -> TreeSeq.Trees (HM.HashMap Judgment (Maybe MJ.Share, [Choice]))
167 choicesByJudgmentBySection bod = bod >>= \(Tree b bs) ->
169 BodyBlock{} -> mempty
170 BodySection Section{judgments} ->
172 let choicesJ = choicesByJudgment judgments in
174 -- NOTE: if the 'BodySection' has a child which
175 -- is not a 'BodySection' itself, then add "phantom" 'Judgment's
176 -- which will inherit from this 'BodySection'.
177 -- This enables judges to express something on material not in a sub 'BodySection'.
178 let childrenBlocksJudgments =
180 Tree BodyBlock{} _ -> True
182 then Seq.singleton $ Tree ((Nothing,[]) <$ choicesJ) Seq.empty
184 childrenBlocksJudgments <>
185 choicesByJudgmentBySection bs
186 choicesBySectionByJudgment ::
187 HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])] ->
188 TreeSeq.Tree (HM.HashMap Judgment (Maybe MJ.Share, [Choice])) ->
189 HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])]
190 choicesBySectionByJudgment inh (TreeSeq.Tree selfJ childrenJS) =
193 (<$> selfS) $ \(Tree.Node choices old) ->
194 Tree.Node choices (old<>childrenS))
198 selfSJ = (\cs -> [Tree.Node cs []]) <$> selfJ
202 HM.unionWith (<>) accJ $
203 choicesBySectionByJudgment
204 (([Tree.Node (Nothing,[]) []] <$ selfJ) <> inh)