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 TS
24 import qualified Hjugement as MJ
25 import qualified Data.Tree as Tree
27 -- import Hdoc.Utils ()
28 import Hdoc.DTC.Document as DTC
29 import qualified Hdoc.XML as XML
32 -- | Collect 'Block's by mapping them by their 'XmlPos' or 'Ident'.
34 { all_index :: Map XML.Pos Terms
35 , all_figure :: Map TL.Text (Map XML.Pos (Maybe Title))
36 , all_reference :: HM.HashMap Ident (Seq Reference)
37 , all_section :: HM.HashMap Title (Seq (Either Head Section))
38 , all_judges :: HM.HashMap Ident Judges
39 , all_grades :: HM.HashMap Ident [Grade]
40 , all_judgments :: HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])]
42 instance Default All where
52 instance Semigroup All where
54 { all_index = Map.union (all_index x) (all_index y)
55 , all_figure = Map.unionWith (<>) (all_figure x) (all_figure y)
56 , all_section = HM.unionWith (<>) (all_section x) (all_section y)
57 , all_reference = HM.unionWith (<>) (all_reference x) (all_reference y)
58 , all_judges = HM.union (all_judges x) (all_judges y)
59 , all_grades = HM.union (all_grades x) (all_grades y)
60 , all_judgments = HM.unionWith (<>) (all_judgments x) (all_judgments y)
62 instance Monoid All where
69 instance Collect Document where
70 collect Document{head=head@Head{about=About{titles}, judgments=js}, body} =
71 def{ all_section = HM.fromListWith (<>) $ (\t -> (t, pure $ Left head)) <$> titles } <>
72 (foldMap collect body)
74 choicesBySectionByJudgment HM.empty $
75 TS.Tree (choicesByJudgment js) $
76 choicesByJudgmentBySection body
78 instance Collect (Tree BodyNode) where
81 BodyBlock b -> collect b
82 BodySection s@Section{..} ->
83 def{ all_section = HM.fromListWith (<>) $
84 (\(Alias t) -> (t, pure $ Right s))
85 <$> (Alias section_title : section_aliases)
88 instance Collect DTC.Block where
90 BlockPara _p -> def -- collect p
94 BlockAside{..} -> foldMap collect blocks
95 BlockIndex{..} -> def{all_index = Map.singleton posXML terms}
98 Map.singleton type_ (Map.singleton posXML mayTitle)}
99 -- <> foldMap collect paras
100 BlockReferences{..} ->
102 HM.fromListWith (<>) $ (<$> refs) $ \ref@DTC.Reference{..} -> (reference_id, pure ref)
104 BlockGrades{attrs=CommonAttrs{id=i}, ..} ->
105 def{all_grades = HM.singleton (fromMaybe "" i) scale}
106 BlockJudges judges@Judges{judges_attrs=CommonAttrs{id=i}, ..} ->
107 def{all_judges = HM.singleton (fromMaybe "" i) judges}
109 instance Collect Judgment where
110 collect Judgment{..} = def
113 (judges,grades,question)
114 (Tree.Node choices [])
116 -- <> foldMap collect choices
117 instance Collect Para where
119 ParaItem item -> collect item
120 ParaItems{..} -> foldMap collect items
121 instance Collect ParaItem where
125 ParaQuote{..} -> foldMap collect paras
127 ParaOL items -> foldMap collect items
128 ParaUL items -> foldMap (foldMap collect) items
129 ParaJudgment{} -> def
130 instance Collect ListItem where
131 collect ListItem{..} = foldMap collect paras
132 instance Collect Choice where
134 foldMap collect title <>
135 foldMap collect opinions
136 instance Collect Opinion where
137 collect Opinion{..} =
138 foldMap collect comment
139 instance Collect Title where
140 collect (Title t) = collect t
141 instance Collect Plain where
142 collect = foldMap collect
143 instance Collect (Tree PlainNode) where
144 collect (Tree n ts) =
148 PlainGroup -> collect ts
150 PlainCode -> collect ts
151 PlainDel -> collect ts
153 PlainSpan{} -> collect ts
154 PlainSub -> collect ts
155 PlainSup -> collect ts
156 PlainSC -> collect ts
158 PlainNote{..} -> foldMap collect note
160 PlainEref{} -> collect ts
161 PlainIref{} -> collect ts
162 PlainTag{} -> collect ts
163 PlainRref{..} -> collect ts
166 choicesByJudgment :: [Judgment] -> HM.HashMap Judgment (Maybe MJ.Share, [Choice])
167 choicesByJudgment js =
168 HM.fromList $ (<$> js) $ \j@Judgment{..} ->
169 (j,(judgment_importance, judgment_choices))
171 choicesByJudgmentBySection :: Body -> TS.Trees (HM.HashMap Judgment (Maybe MJ.Share, [Choice]))
172 choicesByJudgmentBySection bod = bod >>= \(Tree b bs) ->
174 BodyBlock{} -> mempty
175 BodySection Section{..} ->
177 let choicesJ = choicesByJudgment section_judgments in
179 -- NOTE: if the 'BodySection' has a child which
180 -- is not a 'BodySection' itself, then add "phantom" 'Judgment's
181 -- which will inherit from this 'BodySection'.
182 -- This enables judges to express something on material not in a sub 'BodySection'.
183 let childrenBlocksJudgments =
185 Tree BodyBlock{} _ -> True
187 then Seq.singleton $ Tree ((Nothing,[]) <$ choicesJ) Seq.empty
189 childrenBlocksJudgments <>
190 choicesByJudgmentBySection bs
192 choicesBySectionByJudgment ::
193 HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])] ->
194 TS.Tree (HM.HashMap Judgment (Maybe MJ.Share, [Choice])) ->
195 HM.HashMap Judgment [Tree.Tree (Maybe MJ.Share, [Choice])]
196 choicesBySectionByJudgment inh (TS.Tree selfJ childrenJS) =
199 (<$> selfS) $ \(Tree.Node choices old) ->
200 Tree.Node choices (old<>childrenS))
204 selfSJ = (\cs -> [Tree.Node cs []]) <$> selfJ
208 HM.unionWith (<>) accJ $
209 choicesBySectionByJudgment
210 (([Tree.Node (Nothing,[]) []] <$ selfJ) <> inh)