nitdoc: introduce StructurePhase
[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 new IntroArticle(mentity.mproject)
55 else
56 root.add 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 new ConcernsArticle(mentity, concerns)
67 for mentity in concerns do
68 if mentity isa MModule then
69 root.add new DefinitionArticle(mentity)
70 else
71 root.add 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 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 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(new DefinitionArticle(mclass.intro))
102 end
103 doc.mainmodule.linearize_mclassdefs(mclassdefs)
104 for mclassdef in mclassdefs do
105 article.add(new DefinitionArticle(mclassdef))
106 end
107 section.add article
108 end
109 end
110 root.add 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 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 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 new DefinitionArticle(mpropdef)
161 end
162 end
163 end
164 end
165 root.add 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 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 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 new DefinitionArticle(mpropdef)
219 end
220 end
221 root.add 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