src/doc: move components generation from `doc_model` to `doc_html` phase
[nit.git] / src / doc / html_templates / html_model.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 # HTML templates for Nit model MEntities.
16 module html_model
17
18 import doc_base
19 import doc_down
20 import html_components
21 import html::bootstrap
22 import ordered_tree
23
24 redef class MEntity
25 # ID used as a HTML unique ID and in file names.
26 #
27 # **Must** match the following (POSIX ERE) regular expression:
28 #
29 # ~~~POSIX ERE
30 # ^[A-Za-z_][A-Za-z0-9._-]*$
31 # ~~~
32 #
33 # That way, the ID is always a valid URI component and a valid XML name.
34 fun nitdoc_id: String is abstract
35
36 # URL of this entity’s Nitdoc page.
37 fun nitdoc_url: String is abstract
38
39 # Returns the mentity name without short signature.
40 #
41 # * MProject: `foo`
42 # * MGroup: `foo`
43 # * MModule: `foo`
44 # * MClass: `Foo[E]`
45 # * MClassDef: `Foo[E]`
46 # * MProperty: `foo(e)`
47 # * MPropdef: `foo(e)`
48 var html_name: String is lazy do return name.html_escape
49
50 # Returns a Link to the mentity `html_url`.
51 #
52 # Example: `<a href="html_url" title="mdoc.short_comment">html_short_name</a>
53 var html_link: Link is lazy do
54 var tpl = new Link(nitdoc_url, html_name)
55 var mdoc = mdoc_or_fallback
56 if mdoc != null then
57 tpl.title = mdoc.short_comment
58 end
59 return tpl
60 end
61
62 # Returns a Link to the mentity `nitdoc_id`.
63 #
64 # Example: `<a href="#nitdoc_id" title="mdoc.short_comment">html_short_name</a>
65 fun html_link_to_anchor: Link do
66 var tpl = new Link("#{nitdoc_id}", html_name)
67 var mdoc = mdoc_or_fallback
68 if mdoc != null then
69 tpl.title = mdoc.short_comment
70 end
71 return tpl
72 end
73
74 # Returns the list of keyword used in `self` declaration.
75 fun html_modifiers: Array[String] is abstract
76
77 # Returns the complete MEntity declaration decorated with HTML.
78 #
79 # * MProject: `project foo`
80 # * MGroup: `group foo`
81 # * MModule: `module foo`
82 # * MClass: `private abstract class Foo[E: Object]`
83 # * MClassDef: `redef class Foo[E]`
84 # * MProperty: `private fun foo(e: Object): Int`
85 # * MPropdef: `redef fun foo(e)`
86 fun html_declaration: Template do
87 var tpl = new Template
88 tpl.add "<span>"
89 tpl.add html_modifiers.join(" ")
90 tpl.add " "
91 tpl.add html_link
92 tpl.add "</span>"
93 return tpl
94 end
95
96 # Returns `self` namespace decorated with HTML links.
97 #
98 # * MProject: `mproject`
99 # * MGroup: `mproject(::group)`
100 # * MModule: `mgroup::mmodule`
101 # * MClass: `mproject::mclass`
102 # * MClassDef: `mmodule::mclassdef`
103 # * MProperty: `mclass::mprop`
104 # * MPropdef: `mclassdef:mpropdef`
105 fun html_namespace: Template is abstract
106 end
107
108 redef class MProject
109 redef var nitdoc_id = name.to_cmangle is lazy
110 redef fun nitdoc_url do return root.nitdoc_url
111 redef var html_modifiers = ["project"]
112 redef fun html_namespace do return html_link
113 end
114
115 redef class MGroup
116 redef var nitdoc_id is lazy do
117 if parent != null then
118 return "{parent.nitdoc_id}__{name.to_cmangle}"
119 end
120 return name.to_cmangle
121 end
122
123 redef fun nitdoc_url do return "group_{nitdoc_id}.html"
124 redef var html_modifiers = ["group"]
125
126 # Depends if `self` is root or not.
127 #
128 # * If root `mproject`.
129 # * Else `mproject::self`.
130 redef fun html_namespace do
131 var tpl = new Template
132 tpl.add mproject.html_namespace
133 if mproject.root != self then
134 tpl.add "::"
135 tpl.add html_link
136 end
137 return tpl
138 end
139 end
140
141 redef class MModule
142 redef var nitdoc_id is lazy do
143 if mgroup != null then
144 if mgroup.mmodules.length == 1 then
145 return "{mgroup.nitdoc_id}-"
146 else
147 return "{mgroup.nitdoc_id}__{name.to_cmangle}"
148 end
149 end
150 return name.to_cmangle
151 end
152
153 redef fun nitdoc_url do return "module_{nitdoc_id}.html"
154 redef var html_modifiers = ["module"]
155
156 # Depends if `self` belongs to a MGroup.
157 #
158 # * If mgroup `mgroup::self`.
159 # * Else `self`.
160 redef fun html_namespace do
161 var tpl = new Template
162 if mgroup != null then
163 tpl.add mgroup.html_namespace
164 tpl.add "::"
165 end
166 tpl.add html_link
167 return tpl
168 end
169 end
170
171 redef class MClass
172 redef var nitdoc_id = "{intro_mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
173 redef fun nitdoc_url do return "class_{nitdoc_id}.html"
174 redef fun mdoc_or_fallback do return intro.mdoc
175
176 # Format: `Foo[E]`
177 redef var html_name is lazy do
178 var tpl = new Template
179 tpl.add name.html_escape
180 if arity > 0 then
181 tpl.add "["
182 var parameter_names = new Array[String]
183 for p in mparameters do
184 parameter_names.add(p.html_name)
185 end
186 tpl.add parameter_names.join(", ")
187 tpl.add "]"
188 end
189 return tpl.write_to_string
190 end
191
192 redef fun html_modifiers do return intro.html_modifiers
193 redef fun html_declaration do return intro.html_declaration
194
195 # Returns `mproject::self`.
196 redef fun html_namespace do
197 var tpl = new Template
198 tpl.add intro_mmodule.mgroup.mproject.html_namespace
199 tpl.add "::<span>"
200 tpl.add html_link
201 tpl.add "</span>"
202 return tpl
203 end
204
205 # Returns `intro.html_short_signature`.
206 fun html_short_signature: Template do return intro.html_short_signature
207
208 # Returns `intro.html_signature`.
209 fun html_signature: Template do return intro.html_signature
210 end
211
212 redef class MClassDef
213 redef var nitdoc_id = "{mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
214 redef fun nitdoc_url do return "{mclass.nitdoc_url}#{nitdoc_id}"
215 redef fun mdoc_or_fallback do return mdoc or else mclass.mdoc_or_fallback
216
217 # Depends if `self` is an intro or not.
218 #
219 # * If intro contains the visibility and kind.
220 # * If redef contains the `redef` keyword and kind.
221 redef fun html_modifiers do
222 var res = new Array[String]
223 if not is_intro then
224 res.add "redef"
225 else
226 if mclass.visibility != public_visibility then
227 res.add mclass.visibility.to_s
228 end
229 end
230 res.add mclass.kind.to_s
231 return res
232 end
233
234 # Depends if `self` is an intro or not.
235 #
236 # For intro: `private abstract class Foo[E: Object]`
237 # For redef: `redef class Foo[E]`
238 # TODO change the implementation to correspond to the comment.
239 redef fun html_declaration do
240 var tpl = new Template
241 tpl.add "<span>"
242 tpl.add html_modifiers.join(" ")
243 tpl.add " "
244 tpl.add html_link
245 tpl.add html_signature
246 tpl.add "</span>"
247 return tpl
248 end
249
250 # Returns `mmodule::self`
251 redef fun html_namespace do
252 var tpl = new Template
253 tpl.add mmodule.html_namespace
254 tpl.add "::<span>"
255 tpl.add mclass.html_link
256 tpl.add "</span>"
257 return tpl
258 end
259
260 # Returns the MClassDef generic signature without static bounds.
261 fun html_short_signature: Template do
262 var tpl = new Template
263 var mparameters = mclass.mparameters
264 if not mparameters.is_empty then
265 tpl.add "["
266 for i in [0..mparameters.length[ do
267 tpl.add mparameters[i].html_name
268 if i < mparameters.length - 1 then tpl.add ", "
269 end
270 tpl.add "]"
271 end
272 return tpl
273 end
274
275 # Returns the MClassDef generic signature with static bounds.
276 fun html_signature: Template do
277 var tpl = new Template
278 var mparameters = mclass.mparameters
279 if not mparameters.is_empty then
280 tpl.add "["
281 for i in [0..mparameters.length[ do
282 tpl.add "{mparameters[i].html_name}: "
283 tpl.add bound_mtype.arguments[i].html_signature
284 if i < mparameters.length - 1 then tpl.add ", "
285 end
286 tpl.add "]"
287 end
288 return tpl
289 end
290 end
291
292 redef class MProperty
293 redef var nitdoc_id = "{intro_mclassdef.mclass.nitdoc_id}__{name.to_cmangle}" is lazy
294 redef fun nitdoc_url do return "property_{nitdoc_id}.html"
295 redef fun mdoc_or_fallback do return intro.mdoc
296 redef fun html_modifiers do return intro.html_modifiers
297 redef fun html_declaration do return intro.html_declaration
298
299 # Returns `mclass::self`.
300 redef fun html_namespace do
301 var tpl = new Template
302 tpl.add intro_mclassdef.mclass.html_namespace
303 tpl.add "::<span>"
304 tpl.add intro.html_link
305 tpl.add "</span>"
306 return tpl
307 end
308
309 # Returns `intro.html_short_signature`.
310 fun html_short_signature: Template do return intro.html_short_signature
311
312 # Returns `intro.html_signature`.
313 fun html_signature: Template do return intro.html_signature
314 end
315
316 redef class MPropDef
317 redef var nitdoc_id = "{mclassdef.nitdoc_id}__{name.to_cmangle}" is lazy
318 redef fun nitdoc_url do return "{mproperty.nitdoc_url}#{nitdoc_id}"
319 redef fun mdoc_or_fallback do return mdoc or else mproperty.mdoc_or_fallback
320
321 # Depends if `self` is an intro or not.
322 #
323 # * If intro contains the visibility and kind.
324 # * If redef contains the `redef` keyword and kind.
325 redef fun html_modifiers do
326 var res = new Array[String]
327 if not is_intro then
328 res.add "redef"
329 else
330 if mproperty.visibility != public_visibility then
331 res.add mproperty.visibility.to_s
332 end
333 end
334 return res
335 end
336
337 # Depends if `self` is an intro or not.
338 #
339 # For intro: `private fun foo(e: Object): Bar is abstract`
340 # For redef: `redef fun foo(e) is cached`
341 # TODO change the implementation to correspond to the comment.
342 redef fun html_declaration do
343 var tpl = new Template
344 tpl.add "<span>"
345 tpl.add html_modifiers.join(" ")
346 tpl.add " "
347 tpl.add html_link
348 tpl.add html_signature
349 tpl.add "</span>"
350 return tpl
351 end
352
353 # Returns `mclassdef::self`
354 redef fun html_namespace do
355 var tpl = new Template
356 tpl.add mclassdef.html_namespace
357 tpl.add "::"
358 tpl.add html_link
359 return tpl
360 end
361
362 # Returns the MPropdDef signature without static types.
363 fun html_short_signature: Template is abstract
364
365 # Returns the MPropDef signature with static types.
366 fun html_signature: Template is abstract
367 end
368
369 redef class MAttributeDef
370
371 redef fun html_modifiers do
372 var res = super
373 res.add "var"
374 return res
375 end
376
377 redef fun html_short_signature do return new Template
378
379 redef fun html_signature do
380 var tpl = new Template
381 if static_mtype != null then
382 tpl.add ": "
383 tpl.add static_mtype.html_signature
384 end
385 return tpl
386 end
387 end
388
389 redef class MMethodDef
390
391 # FIXME annotation should be handled in their own way
392 redef fun html_modifiers do
393 var res = super
394 if is_abstract then
395 res.add "abstract"
396 else if is_intern then
397 res.add "intern"
398 end
399 if mproperty.is_init then
400 res.add "init"
401 else
402 res.add "fun"
403 end
404 return res
405 end
406
407 redef fun html_short_signature do return msignature.html_short_signature
408 redef fun html_signature do return msignature.html_signature
409 end
410
411 redef class MVirtualTypeProp
412 redef fun html_link do return mvirtualtype.html_link
413 end
414
415 redef class MVirtualTypeDef
416
417 redef fun html_modifiers do
418 var res = super
419 res.add "type"
420 return res
421 end
422
423 redef fun html_short_signature do return new Template
424
425 redef fun html_signature do
426 var tpl = new Template
427 if bound == null then return tpl
428 tpl.add ": "
429 tpl.add bound.html_signature
430 return tpl
431 end
432 end
433
434 redef class MType
435 # Returns the signature of this type whithout bounds.
436 fun html_short_signature: Template is abstract
437
438 # Returns the signature of this type.
439 fun html_signature: Template is abstract
440 end
441
442 redef class MClassType
443 redef fun html_link do return mclass.html_link
444 redef fun html_short_signature do return html_link
445 redef fun html_signature do return html_link
446 end
447
448 redef class MNullableType
449
450 redef fun html_short_signature do
451 var tpl = new Template
452 tpl.add "nullable "
453 tpl.add mtype.html_short_signature
454 return tpl
455 end
456
457 redef fun html_signature do
458 var tpl = new Template
459 tpl.add "nullable "
460 tpl.add mtype.html_signature
461 return tpl
462 end
463 end
464
465 redef class MGenericType
466 redef fun html_short_signature do
467 var lnk = html_link
468 var tpl = new Template
469 tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
470 tpl.add "["
471 for i in [0..arguments.length[ do
472 tpl.add arguments[i].html_short_signature
473 if i < arguments.length - 1 then tpl.add ", "
474 end
475 tpl.add "]"
476 return tpl
477 end
478
479 redef fun html_signature do
480 var lnk = html_link
481 var tpl = new Template
482 tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
483 tpl.add "["
484 for i in [0..arguments.length[ do
485 tpl.add arguments[i].html_signature
486 if i < arguments.length - 1 then tpl.add ", "
487 end
488 tpl.add "]"
489 return tpl
490 end
491 end
492
493 redef class MParameterType
494 redef fun html_link do
495 return new Link.with_title("{mclass.nitdoc_url}#FT_{name.to_cmangle}", name, "formal type")
496 end
497
498 redef fun html_short_signature do return html_link
499 redef fun html_signature do return html_link
500 end
501
502 redef class MVirtualType
503 redef fun html_link do return mproperty.intro.html_link
504 redef fun html_signature do return html_link
505 end
506
507 redef class MSignature
508
509 redef fun html_short_signature do
510 var tpl = new Template
511 if not mparameters.is_empty then
512 tpl.add "("
513 for i in [0..mparameters.length[ do
514 tpl.add mparameters[i].html_short_signature
515 if i < mparameters.length - 1 then tpl.add ", "
516 end
517 tpl.add ")"
518 end
519 return tpl
520 end
521
522 redef fun html_signature do
523 var tpl = new Template
524 if not mparameters.is_empty then
525 tpl.add "("
526 for i in [0..mparameters.length[ do
527 tpl.add mparameters[i].html_signature
528 if i < mparameters.length - 1 then tpl.add ", "
529 end
530 tpl.add ")"
531 end
532 if return_mtype != null then
533 tpl.add ": "
534 tpl.add return_mtype.html_signature
535 end
536 return tpl
537 end
538 end
539
540 redef class MParameter
541
542 # Returns `self` name and ellipsys if any.
543 fun html_short_signature: Template do
544 var tpl = new Template
545 tpl.add name
546 if is_vararg then tpl.add "..."
547 return tpl
548 end
549
550 # Returns `self` name with it's static type and ellipsys if any.
551 fun html_signature: Template do
552 var tpl = new Template
553 tpl.add "{name}: "
554 tpl.add mtype.html_signature
555 if is_vararg then tpl.add "..."
556 return tpl
557 end
558 end
559
560 ################################################################################
561 # Additions to `model_ext`.
562
563 redef class MRawType
564 redef fun html_signature do
565 var tpl = new Template
566
567 for part in parts do
568 if part.target != null then
569 tpl.add part.target.as(not null).html_link
570 else
571 tpl.add part.text.html_escape
572 end
573 end
574 return tpl
575 end
576 end
577
578 redef class MInnerClass
579 redef fun nitdoc_url do return inner.nitdoc_url
580 redef fun html_signature do return inner.html_signature
581 end
582
583 redef class MInnerClassDef
584 redef fun nitdoc_url do return inner.nitdoc_url
585
586 redef fun html_link_to_anchor do return inner.html_link_to_anchor
587 redef fun html_link do return inner.html_link
588 redef fun html_signature do return inner.html_signature
589 end