src/doc: rename `DocComposite::add` into `add_child` to avoid conflict with `Template...
[nit.git] / src / doc / doc_phases / doc_structure.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Composes the DocComposite tree of a DocPage and organizes its content.
16 module doc_structure
17
18 import doc_concerns
19
20 # StructurePhase populates the DocPage content with section and article.
21 #
22 # This phase only applies structure.
23 # The content of the structure is choosen by the rendering phases.
24 class StructurePhase
25 super DocPhase
26
27 # Used to sort ConcernsTree by rank.
28 private var concerns_sorter = new MConcernRankSorter
29
30 # Used to sort ConcernsTree by name.
31 private var name_sorter = new MEntityNameSorter
32
33 # Populates the given DocModel.
34 redef fun apply do
35 for page in doc.pages do
36 if page isa MEntityPage then page.apply_structure(self, doc)
37 end
38 end
39
40 # TODO index and search page should also be structured here
41 end
42
43 redef class MEntityPage
44
45 # Populates `self` with structure elements like DocComposite ones.
46 #
47 # See `StructurePhase`.
48 fun apply_structure(v: StructurePhase, doc: DocModel) do end
49 end
50
51 redef class MGroupPage
52 redef fun apply_structure(v, doc) do
53 if mentity.is_root then
54 root.add_child new IntroArticle(mentity.mproject)
55 else
56 root.add_child new IntroArticle(mentity)
57 end
58 var concerns = self.concerns
59 if concerns == null or concerns.is_empty then return
60 # FIXME avoid diff
61 mentity.mproject.booster_rank = -1000
62 mentity.booster_rank = -1000
63 concerns.sort_with(v.concerns_sorter)
64 mentity.mproject.booster_rank = 0
65 mentity.booster_rank = 0
66 root.add_child new ConcernsArticle(mentity, concerns)
67 for mentity in concerns do
68 if mentity isa MModule then
69 root.add_child new DefinitionArticle(mentity)
70 else
71 root.add_child new ConcernSection(mentity)
72 end
73 end
74 end
75 end
76
77 redef class MModulePage
78 redef fun apply_structure(v, doc) do
79 root.add_child new IntroArticle(mentity)
80 var concerns = self.concerns
81 if concerns == null or concerns.is_empty then return
82 # FIXME avoid diff
83 mentity.mgroup.mproject.booster_rank = -1000
84 mentity.mgroup.booster_rank = -1000
85 mentity.booster_rank = -1000
86 concerns.sort_with(v.concerns_sorter)
87 mentity.mgroup.mproject.booster_rank = 0
88 mentity.mgroup.booster_rank = 0
89 mentity.booster_rank = 0
90 root.add_child new ConcernsArticle(mentity, concerns)
91 # reference list
92 for mentity in concerns do
93 var section = new ConcernSection(mentity)
94 if mentity isa MModule then
95 var mclasses = mclasses_for_mmodule(mentity).to_a
96 v.name_sorter.sort(mclasses)
97 for mclass in mclasses do
98 var article = new DefinitionArticle(mclass)
99 var mclassdefs = mclassdefs_for(mclass).to_a
100 if not mclassdefs.has(mclass.intro) then
101 article.add_child(new DefinitionArticle(mclass.intro))
102 end
103 doc.mainmodule.linearize_mclassdefs(mclassdefs)
104 for mclassdef in mclassdefs do
105 article.add_child(new DefinitionArticle(mclassdef))
106 end
107 section.add_child article
108 end
109 end
110 root.add_child section
111 end
112 end
113
114 # Filters `self.mclassses` by intro `mmodule`.
115 private fun mclasses_for_mmodule(mmodule: MModule): Set[MClass] do
116 var mclasses = new HashSet[MClass]
117 for mclass in self.mclasses do
118 if mclass.intro.mmodule == mmodule then
119 mclasses.add mclass
120 end
121 end
122 return mclasses
123 end
124
125 # Filters `self.mclassdefs` by `mclass`.
126 private fun mclassdefs_for(mclass: MClass): Set[MClassDef] do
127 var mclassdefs = new HashSet[MClassDef]
128 for mclassdef in self.mclassdefs do
129 if mclassdef.mclass == mclass then
130 mclassdefs.add mclassdef
131 end
132 end
133 return mclassdefs
134 end
135 end
136
137 redef class MClassPage
138 redef fun apply_structure(v, doc) do
139 root.add_child new IntroArticle(mentity)
140 var concerns = self.concerns
141 if concerns == null or concerns.is_empty then return
142 # FIXME diff hack
143 mentity.intro_mmodule.mgroup.mproject.booster_rank = -1000
144 mentity.intro_mmodule.mgroup.booster_rank = -1000
145 mentity.intro_mmodule.booster_rank = -1000
146 concerns.sort_with(v.concerns_sorter)
147 mentity.intro_mmodule.mgroup.mproject.booster_rank = 0
148 mentity.intro_mmodule.mgroup.booster_rank = 0
149 mentity.intro_mmodule.booster_rank = 0
150 root.add_child new ConcernsArticle(mentity, concerns)
151 for mentity in concerns do
152 var section = new ConcernSection(mentity)
153 if mentity isa MModule then
154 var mprops = mproperties_for(mentity)
155 var by_kind = new PropertiesByKind.with_elements(mprops)
156 for group in by_kind.groups do
157 v.name_sorter.sort(group)
158 for mprop in group do
159 for mpropdef in mpropdefs_for(mprop, mentity) do
160 section.add_child new DefinitionArticle(mpropdef)
161 end
162 end
163 end
164 end
165 root.add_child section
166 end
167 end
168
169 # Filters `self.mpropdefs` by `mmodule`.
170 #
171 # FIXME diff hack
172 private fun mproperties_for(mmodule: MModule): Set[MProperty] do
173 var mprops = new HashSet[MProperty]
174 for mpropdef in self.mpropdefs do
175 if mpropdef.mclassdef.mmodule == mmodule then
176 mprops.add mpropdef.mproperty
177 end
178 end
179 return mprops
180 end
181
182 # Filters `self.mpropdefs` by `mproperty`.
183 #
184 # FIXME diff hack
185 private fun mpropdefs_for(mproperty: MProperty, mmodule: MModule): Set[MPropDef] do
186 var mpropdefs = new HashSet[MPropDef]
187 for mpropdef in self.mpropdefs do
188 if mpropdef.mproperty == mproperty and
189 mpropdef.mclassdef.mmodule == mmodule then
190 mpropdefs.add mpropdef
191 end
192 end
193 return mpropdefs
194 end
195 end
196
197 redef class MPropertyPage
198 redef fun apply_structure(v, doc) do
199 root.add_child new IntroArticle(mentity)
200 var concerns = self.concerns
201 if concerns == null or concerns.is_empty then return
202 # FIXME diff hack
203 mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = -1000
204 mentity.intro.mclassdef.mmodule.mgroup.booster_rank = -1000
205 mentity.intro.mclassdef.mmodule.booster_rank = -1000
206 concerns.sort_with(v.concerns_sorter)
207 mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = 0
208 mentity.intro.mclassdef.mmodule.mgroup.booster_rank = 0
209 mentity.intro.mclassdef.mmodule.booster_rank = 0
210 root.add_child new ConcernsArticle(mentity, concerns)
211 for mentity in concerns do
212 var section = new ConcernSection(mentity)
213 if mentity isa MModule then
214 # Add mproperties
215 var mpropdefs = mpropdefs_for(mentity).to_a
216 v.name_sorter.sort(mpropdefs)
217 for mpropdef in mpropdefs do
218 section.add_child new DefinitionArticle(mpropdef)
219 end
220 end
221 root.add_child section
222 end
223 end
224
225 # Filters `self.mpropdefs` by `mmodule`.
226 private fun mpropdefs_for(mmodule: MModule): Set[MPropDef] do
227 var mpropdefs = new HashSet[MPropDef]
228 for mpropdef in self.mpropdefs do
229 if mpropdef.mclassdef.mmodule == mmodule then
230 mpropdefs.add mpropdef
231 end
232 end
233 return mpropdefs
234 end
235 end
236
237 # A DocComposite element about a MEntity.
238 class MEntityComposite
239 super DocComposite
240
241 # MEntity documented by this page element.
242 var mentity: MEntity
243 end
244
245 # A Section about a Concern.
246 #
247 # Those sections are used to build the page summary.
248 class ConcernSection
249 super MEntityComposite
250 super DocSection
251 end
252
253 # An article about a Mentity.
254 #
255 # Used to display textual content about a MEntity.
256 abstract class MEntityArticle
257 super MEntityComposite
258 super DocArticle
259 end
260
261 # An introduction article about a MEntity.
262 #
263 # Used at the top of a documentation page to introduce the documented MEntity.
264 class IntroArticle
265 super MEntityComposite
266 super DocArticle
267 end
268
269 # An article that display a ConcernsTreee as a list.
270 class ConcernsArticle
271 super MEntityArticle
272
273 # Concerns to list in this article.
274 var concerns: ConcernsTree
275 end
276
277 # An article that display the definition text of a MEntity.
278 class DefinitionArticle
279 super MEntityArticle
280 end