nitdoc: move `DocComposite::is_toc_hidden` to `doc_base`
[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 import modelize
20
21 # StructurePhase populates the DocPage content with section and article.
22 #
23 # This phase only applies structure.
24 # The content of the structure is choosen by the rendering phases.
25 class StructurePhase
26 super DocPhase
27
28 # Used to sort ConcernsTree by rank.
29 private var concerns_sorter = new MConcernRankSorter
30
31 # Used to sort ConcernsTree by name.
32 private var name_sorter = new MEntityNameSorter
33
34 # Populates the given DocModel.
35 redef fun apply do
36 for page in doc.pages.values do page.apply_structure(self, doc)
37 end
38 end
39
40 redef class DocPage
41
42 # Populates `self` with structure elements like DocComposite ones.
43 #
44 # See `StructurePhase`.
45 fun apply_structure(v: StructurePhase, doc: DocModel) do end
46 end
47
48 redef class OverviewPage
49 redef fun apply_structure(v, doc) do
50 var article = new HomeArticle("home.article", "Home")
51 root.add_child article
52 # Projects list
53 var mprojects = doc.model.mprojects.to_a
54 var sorter = new MConcernRankSorter
55 sorter.sort mprojects
56 var section = new ProjectsSection("projects.section", "Projects")
57 for mproject in mprojects do
58 section.add_child new DefinitionArticle("{mproject.nitdoc_id}.definition", mproject)
59 end
60 article.add_child section
61 end
62 end
63
64 redef class SearchPage
65 redef fun apply_structure(v, doc) do
66 var mmodules = doc.mmodules.to_a
67 v.name_sorter.sort(mmodules)
68 var mclasses = doc.mclasses.to_a
69 v.name_sorter.sort(mclasses)
70 var mprops = doc.mproperties.to_a
71 v.name_sorter.sort(mprops)
72 root.add_child new IndexArticle("index.article", mmodules, mclasses, mprops)
73 end
74 end
75
76 redef class MGroupPage
77 redef fun apply_structure(v, doc) do
78 var section = new MEntitySection("{mentity.nitdoc_name}.section", mentity)
79 root.add_child section
80 if mentity.is_root then
81 section.add_child new IntroArticle("{mentity.mproject.nitdoc_id}.intro", mentity.mproject)
82 else
83 section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", mentity)
84 end
85 var concerns = self.concerns
86 if concerns == null or concerns.is_empty then return
87 # FIXME avoid diff
88 mentity.mproject.booster_rank = -1000
89 mentity.booster_rank = -1000
90 concerns.sort_with(v.concerns_sorter)
91 mentity.mproject.booster_rank = 0
92 mentity.booster_rank = 0
93 section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", mentity, concerns)
94 for mentity in concerns do
95 var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", mentity)
96 if mentity isa MModule then
97 ssection.add_child new DefinitionArticle("{mentity.nitdoc_id}.definition", mentity)
98 end
99 section.add_child ssection
100 end
101 end
102 end
103
104 redef class MModulePage
105 redef fun apply_structure(v, doc) do
106 var section = new MEntitySection("{mentity.nitdoc_name}.section", mentity)
107 root.add_child section
108 section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", mentity)
109 var concerns = self.concerns
110 if concerns == null or concerns.is_empty then return
111 # FIXME avoid diff
112 mentity.mgroup.mproject.booster_rank = -1000
113 mentity.mgroup.booster_rank = -1000
114 mentity.booster_rank = -1000
115 concerns.sort_with(v.concerns_sorter)
116 mentity.mgroup.mproject.booster_rank = 0
117 mentity.mgroup.booster_rank = 0
118 mentity.booster_rank = 0
119 section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", mentity, concerns)
120 # reference list
121 for mentity in concerns do
122 var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", mentity)
123 if mentity isa MModule then
124 var mclasses = mclasses_for_mmodule(mentity).to_a
125 v.name_sorter.sort(mclasses)
126 for mclass in mclasses do
127 var article = new DefinitionListArticle(
128 "{mclass.intro.nitdoc_id}.definition-list", mclass)
129 var mclassdefs = mclassdefs_for(mclass).to_a
130 if not mclassdefs.has(mclass.intro) then
131 article.add_child(new DefinitionArticle(
132 "{mclass.intro.nitdoc_id}.definition", mclass.intro))
133 end
134 doc.mainmodule.linearize_mclassdefs(mclassdefs)
135 for mclassdef in mclassdefs do
136 article.add_child(new DefinitionArticle(
137 "{mclassdef.nitdoc_id}.definition", mclassdef))
138 end
139 ssection.add_child article
140 end
141 end
142 section.add_child ssection
143 end
144 end
145
146 # Filters `self.mclassses` by intro `mmodule`.
147 private fun mclasses_for_mmodule(mmodule: MModule): Set[MClass] do
148 var mclasses = new HashSet[MClass]
149 for mclass in self.mclasses do
150 if mclass.intro.mmodule == mmodule then
151 mclasses.add mclass
152 end
153 end
154 return mclasses
155 end
156
157 # Filters `self.mclassdefs` by `mclass`.
158 private fun mclassdefs_for(mclass: MClass): Set[MClassDef] do
159 var mclassdefs = new HashSet[MClassDef]
160 for mclassdef in self.mclassdefs do
161 if mclassdef.mclass == mclass then
162 mclassdefs.add mclassdef
163 end
164 end
165 return mclassdefs
166 end
167 end
168
169 redef class MClassPage
170 redef fun apply_structure(v, doc) do
171 var section = new MEntitySection("{mentity.nitdoc_name}.section", mentity)
172 root.add_child section
173 section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", mentity)
174 var concerns = self.concerns
175 if concerns == null or concerns.is_empty then return
176 # FIXME diff hack
177 mentity.intro_mmodule.mgroup.mproject.booster_rank = -1000
178 mentity.intro_mmodule.mgroup.booster_rank = -1000
179 mentity.intro_mmodule.booster_rank = -1000
180 concerns.sort_with(v.concerns_sorter)
181 mentity.intro_mmodule.mgroup.mproject.booster_rank = 0
182 mentity.intro_mmodule.mgroup.booster_rank = 0
183 mentity.intro_mmodule.booster_rank = 0
184 var constructors = new ConstructorsSection(
185 "{mentity.nitdoc_id}.constructors", mentity)
186 var minit = mentity.root_init
187 if minit != null then
188 constructors.add_child new DefinitionArticle("{minit.nitdoc_id}.definition", minit)
189 end
190 section.add_child constructors
191 section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", mentity, concerns)
192 for mentity in concerns do
193 var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", mentity)
194 if mentity isa MModule then
195 var mprops = mproperties_for(mentity)
196 var by_kind = new PropertiesByKind.with_elements(mprops)
197 for group in by_kind.groups do
198 v.name_sorter.sort(group)
199 for mprop in group do
200 for mpropdef in mpropdefs_for(mprop, mentity) do
201 if mpropdef isa MMethodDef and mpropdef.mproperty.is_init then
202 if mpropdef == minit then continue
203 constructors.add_child new DefinitionArticle(
204 "{mpropdef.nitdoc_id}.definition", mpropdef)
205 else
206 ssection.add_child new DefinitionArticle(
207 "{mpropdef.nitdoc_id}.definition", mpropdef)
208 end
209 end
210 end
211 end
212 end
213 section.add_child ssection
214 end
215 end
216
217 # Filters `self.mpropdefs` by `mmodule`.
218 #
219 # FIXME diff hack
220 private fun mproperties_for(mmodule: MModule): Set[MProperty] do
221 var mprops = new HashSet[MProperty]
222 for mpropdef in self.mpropdefs do
223 if mpropdef.mclassdef.mmodule == mmodule then
224 mprops.add mpropdef.mproperty
225 end
226 end
227 return mprops
228 end
229
230 # Filters `self.mpropdefs` by `mproperty`.
231 #
232 # FIXME diff hack
233 private fun mpropdefs_for(mproperty: MProperty, mmodule: MModule): Set[MPropDef] do
234 var mpropdefs = new HashSet[MPropDef]
235 for mpropdef in self.mpropdefs do
236 if mpropdef.mproperty == mproperty and
237 mpropdef.mclassdef.mmodule == mmodule then
238 mpropdefs.add mpropdef
239 end
240 end
241 return mpropdefs
242 end
243 end
244
245 redef class MPropertyPage
246 redef fun apply_structure(v, doc) do
247 var section = new MEntitySection("{mentity.nitdoc_name}.section", mentity)
248 root.add_child section
249 section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", mentity)
250 var concerns = self.concerns
251 if concerns == null or concerns.is_empty then return
252 # FIXME diff hack
253 mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = -1000
254 mentity.intro.mclassdef.mmodule.mgroup.booster_rank = -1000
255 mentity.intro.mclassdef.mmodule.booster_rank = -1000
256 concerns.sort_with(v.concerns_sorter)
257 mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = 0
258 mentity.intro.mclassdef.mmodule.mgroup.booster_rank = 0
259 mentity.intro.mclassdef.mmodule.booster_rank = 0
260 section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", mentity, concerns)
261 for mentity in concerns do
262 var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", mentity)
263 if mentity isa MModule then
264 # Add mproperties
265 var mpropdefs = mpropdefs_for(mentity).to_a
266 v.name_sorter.sort(mpropdefs)
267 for mpropdef in mpropdefs do
268 ssection.add_child new DefinitionArticle(
269 "{mpropdef.nitdoc_id}.definition", mpropdef)
270 end
271 end
272 section.add_child ssection
273 end
274 end
275
276 # Filters `self.mpropdefs` by `mmodule`.
277 private fun mpropdefs_for(mmodule: MModule): Set[MPropDef] do
278 var mpropdefs = new HashSet[MPropDef]
279 for mpropdef in self.mpropdefs do
280 if mpropdef.mclassdef.mmodule == mmodule then
281 mpropdefs.add mpropdef
282 end
283 end
284 return mpropdefs
285 end
286 end
287
288 # A group of sections that can be displayed together in a tab.
289 #
290 # Display the first child and hide less relevant data in other panels.
291 class TabbedGroup
292 super DocSection
293 end
294
295 # A group of sections that can be displayed together in a tab panel.
296 class PanelGroup
297 super DocSection
298 end
299
300 # A DocComposite element about a MEntity.
301 class MEntityComposite
302 super DocComposite
303
304 redef fun title do return mentity.nitdoc_name
305
306 # MEntity documented by this page element.
307 var mentity: MEntity
308 end
309
310 # A list of constructors.
311 class ConstructorsSection
312 super MEntitySection
313 end
314
315 # A Section about a Concern.
316 #
317 # Those sections are used to build the page summary.
318 class ConcernSection
319 super MEntityComposite
320 super DocSection
321
322 redef fun is_toc_hidden do return is_hidden
323 end
324
325 # An article about a Mentity.
326 #
327 # Used to display textual content about a MEntity.
328 abstract class MEntityArticle
329 super MEntityComposite
330 super DocArticle
331 end
332
333 # A section about a Mentity.
334 #
335 # Used to regroup content about a MEntity.
336 class MEntitySection
337 super MEntityComposite
338 super DocSection
339 end
340
341 # An introduction article about a MEntity.
342 #
343 # Used at the top of a documentation page to introduce the documented MEntity.
344 class IntroArticle
345 super MEntityComposite
346 super DocArticle
347
348 redef var is_hidden = false
349 redef var is_toc_hidden = true
350 end
351
352 # An article that display a ConcernsTreee as a list.
353 class ConcernsArticle
354 super MEntityArticle
355
356 # Concerns to list in this article.
357 var concerns: ConcernsTree
358
359 redef fun is_hidden do return concerns.is_empty
360 end
361
362 # An article that displaus a list of definition belonging to a MEntity.
363 class DefinitionListArticle
364 super TabbedGroup
365 super MEntityArticle
366 end
367
368 # An article that display the definition text of a MEntity.
369 class DefinitionArticle
370 super MEntityArticle
371
372 redef var is_hidden = false
373 end
374
375 # The main project article.
376 class HomeArticle
377 super DocArticle
378 end
379
380 # The project list.
381 class ProjectsSection
382 super DocArticle
383 end
384
385 # An article that display an index of mmodules, mclasses and mproperties.
386 class IndexArticle
387 super DocArticle
388
389 # List of mmodules to display.
390 var mmodules: Array[MModule]
391
392 # List of mclasses to display.
393 var mclasses: Array[MClass]
394
395 # List of mproperties to display.
396 var mprops: Array[MProperty]
397
398 redef fun is_hidden do
399 return mmodules.is_empty and mclasses.is_empty and mprops.is_empty
400 end
401 end