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