nitdoc: replace `article:` prefix id by `.article` suffix
[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")
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")
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("concern:{mentity.nitdoc_id}", 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("concern:{mentity.nitdoc_id}", 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("concern:{mentity.nitdoc_id}", 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("concern:{mentity.nitdoc_id}", 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
299 # The title of this group.
300 var group_title: String
301 end
302
303 # A DocComposite element about a MEntity.
304 class MEntityComposite
305 super DocComposite
306
307 # MEntity documented by this page element.
308 var mentity: MEntity
309 end
310
311 # A list of constructors.
312 class ConstructorsSection
313 super MEntitySection
314 end
315
316 # A Section about a Concern.
317 #
318 # Those sections are used to build the page summary.
319 class ConcernSection
320 super MEntityComposite
321 super DocSection
322 end
323
324 # An article about a Mentity.
325 #
326 # Used to display textual content about a MEntity.
327 abstract class MEntityArticle
328 super MEntityComposite
329 super DocArticle
330 end
331
332 # A section about a Mentity.
333 #
334 # Used to regroup content about a MEntity.
335 class MEntitySection
336 super MEntityComposite
337 super DocSection
338 end
339
340 # An introduction article about a MEntity.
341 #
342 # Used at the top of a documentation page to introduce the documented MEntity.
343 class IntroArticle
344 super MEntityComposite
345 super DocArticle
346 end
347
348 # An article that display a ConcernsTreee as a list.
349 class ConcernsArticle
350 super MEntityArticle
351
352 # Concerns to list in this article.
353 var concerns: ConcernsTree
354 end
355
356 # An article that displaus a list of definition belonging to a MEntity.
357 class DefinitionListArticle
358 super TabbedGroup
359 super MEntityArticle
360 end
361
362 # An article that display the definition text of a MEntity.
363 class DefinitionArticle
364 super MEntityArticle
365 end
366
367 # The main project article.
368 class HomeArticle
369 super DocArticle
370 end
371
372 # The project list.
373 class ProjectsSection
374 super DocArticle
375 end
376
377 # An article that display an index of mmodules, mclasses and mproperties.
378 class IndexArticle
379 super DocArticle
380
381 # List of mmodules to display.
382 var mmodules: Array[MModule]
383
384 # List of mclasses to display.
385 var mclasses: Array[MClass]
386
387 # List of mproperties to display.
388 var mprops: Array[MProperty]
389 end