src/doc: introduce `html_comment` and `html_short_comment` services
[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
107 # Returns the comment of this MEntity formatted as HTML.
108 var html_comment: nullable Writable is lazy do
109 var mdoc = mdoc_or_fallback
110 if mdoc == null then return null
111 return mdoc.tpl_comment
112 end
113
114 # Returns the comment of this MEntity formatted as HTML.
115 var html_short_comment: nullable Writable is lazy do
116 var mdoc = mdoc_or_fallback
117 if mdoc == null then return null
118 return mdoc.tpl_short_comment
119 end
120 end
121
122 redef class MProject
123 redef var nitdoc_id = name.to_cmangle is lazy
124 redef fun nitdoc_url do return root.nitdoc_url
125 redef var html_modifiers = ["project"]
126 redef fun html_namespace do return html_link
127 end
128
129 redef class MGroup
130 redef var nitdoc_id is lazy do
131 if parent != null then
132 return "{parent.nitdoc_id}__{name.to_cmangle}"
133 end
134 return name.to_cmangle
135 end
136
137 redef fun nitdoc_url do return "group_{nitdoc_id}.html"
138 redef var html_modifiers = ["group"]
139
140 # Depends if `self` is root or not.
141 #
142 # * If root `mproject`.
143 # * Else `mproject::self`.
144 redef fun html_namespace do
145 var tpl = new Template
146 tpl.add mproject.html_namespace
147 if mproject.root != self then
148 tpl.add "::"
149 tpl.add html_link
150 end
151 return tpl
152 end
153 end
154
155 redef class MModule
156 redef var nitdoc_id is lazy do
157 if mgroup != null then
158 if mgroup.mmodules.length == 1 then
159 return "{mgroup.nitdoc_id}-"
160 else
161 return "{mgroup.nitdoc_id}__{name.to_cmangle}"
162 end
163 end
164 return name.to_cmangle
165 end
166
167 redef fun nitdoc_url do return "module_{nitdoc_id}.html"
168 redef var html_modifiers = ["module"]
169
170 # Depends if `self` belongs to a MGroup.
171 #
172 # * If mgroup `mgroup::self`.
173 # * Else `self`.
174 redef fun html_namespace do
175 var tpl = new Template
176 if mgroup != null then
177 tpl.add mgroup.html_namespace
178 tpl.add "::"
179 end
180 tpl.add html_link
181 return tpl
182 end
183 end
184
185 redef class MClass
186 redef var nitdoc_id = "{intro_mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
187 redef fun nitdoc_url do return "class_{nitdoc_id}.html"
188 redef fun mdoc_or_fallback do return intro.mdoc
189
190 # Format: `Foo[E]`
191 redef var html_name is lazy do
192 var tpl = new Template
193 tpl.add name.html_escape
194 if arity > 0 then
195 tpl.add "["
196 var parameter_names = new Array[String]
197 for p in mparameters do
198 parameter_names.add(p.html_name)
199 end
200 tpl.add parameter_names.join(", ")
201 tpl.add "]"
202 end
203 return tpl.write_to_string
204 end
205
206 redef fun html_modifiers do return intro.html_modifiers
207 redef fun html_declaration do return intro.html_declaration
208
209 # Returns `mproject::self`.
210 redef fun html_namespace do
211 var tpl = new Template
212 tpl.add intro_mmodule.mgroup.mproject.html_namespace
213 tpl.add "::<span>"
214 tpl.add html_link
215 tpl.add "</span>"
216 return tpl
217 end
218
219 # Returns `intro.html_short_signature`.
220 fun html_short_signature: Template do return intro.html_short_signature
221
222 # Returns `intro.html_signature`.
223 fun html_signature: Template do return intro.html_signature
224 end
225
226 redef class MClassDef
227 redef var nitdoc_id = "{mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
228 redef fun nitdoc_url do return "{mclass.nitdoc_url}#{nitdoc_id}"
229 redef fun mdoc_or_fallback do return mdoc or else mclass.mdoc_or_fallback
230
231 # Depends if `self` is an intro or not.
232 #
233 # * If intro contains the visibility and kind.
234 # * If redef contains the `redef` keyword and kind.
235 redef fun html_modifiers do
236 var res = new Array[String]
237 if not is_intro then
238 res.add "redef"
239 else
240 if mclass.visibility != public_visibility then
241 res.add mclass.visibility.to_s
242 end
243 end
244 res.add mclass.kind.to_s
245 return res
246 end
247
248 # Depends if `self` is an intro or not.
249 #
250 # For intro: `private abstract class Foo[E: Object]`
251 # For redef: `redef class Foo[E]`
252 # TODO change the implementation to correspond to the comment.
253 redef fun html_declaration do
254 var tpl = new Template
255 tpl.add "<span>"
256 tpl.add html_modifiers.join(" ")
257 tpl.add " "
258 tpl.add html_link
259 tpl.add html_signature
260 tpl.add "</span>"
261 return tpl
262 end
263
264 # Returns `mmodule::self`
265 redef fun html_namespace do
266 var tpl = new Template
267 tpl.add mmodule.html_namespace
268 tpl.add "::<span>"
269 tpl.add mclass.html_link
270 tpl.add "</span>"
271 return tpl
272 end
273
274 # Returns the MClassDef generic signature without static bounds.
275 fun html_short_signature: Template do
276 var tpl = new Template
277 var mparameters = mclass.mparameters
278 if not mparameters.is_empty then
279 tpl.add "["
280 for i in [0..mparameters.length[ do
281 tpl.add mparameters[i].html_name
282 if i < mparameters.length - 1 then tpl.add ", "
283 end
284 tpl.add "]"
285 end
286 return tpl
287 end
288
289 # Returns the MClassDef generic signature with static bounds.
290 fun html_signature: Template do
291 var tpl = new Template
292 var mparameters = mclass.mparameters
293 if not mparameters.is_empty then
294 tpl.add "["
295 for i in [0..mparameters.length[ do
296 tpl.add "{mparameters[i].html_name}: "
297 tpl.add bound_mtype.arguments[i].html_signature
298 if i < mparameters.length - 1 then tpl.add ", "
299 end
300 tpl.add "]"
301 end
302 return tpl
303 end
304 end
305
306 redef class MProperty
307 redef var nitdoc_id = "{intro_mclassdef.mclass.nitdoc_id}__{name.to_cmangle}" is lazy
308 redef fun nitdoc_url do return "property_{nitdoc_id}.html"
309 redef fun mdoc_or_fallback do return intro.mdoc
310 redef fun html_modifiers do return intro.html_modifiers
311 redef fun html_declaration do return intro.html_declaration
312
313 # Returns `mclass::self`.
314 redef fun html_namespace do
315 var tpl = new Template
316 tpl.add intro_mclassdef.mclass.html_namespace
317 tpl.add "::<span>"
318 tpl.add intro.html_link
319 tpl.add "</span>"
320 return tpl
321 end
322
323 # Returns `intro.html_short_signature`.
324 fun html_short_signature: Template do return intro.html_short_signature
325
326 # Returns `intro.html_signature`.
327 fun html_signature: Template do return intro.html_signature
328 end
329
330 redef class MPropDef
331 redef var nitdoc_id = "{mclassdef.nitdoc_id}__{name.to_cmangle}" is lazy
332 redef fun nitdoc_url do return "{mproperty.nitdoc_url}#{nitdoc_id}"
333 redef fun mdoc_or_fallback do return mdoc or else mproperty.mdoc_or_fallback
334
335 # Depends if `self` is an intro or not.
336 #
337 # * If intro contains the visibility and kind.
338 # * If redef contains the `redef` keyword and kind.
339 redef fun html_modifiers do
340 var res = new Array[String]
341 if not is_intro then
342 res.add "redef"
343 else
344 if mproperty.visibility != public_visibility then
345 res.add mproperty.visibility.to_s
346 end
347 end
348 return res
349 end
350
351 # Depends if `self` is an intro or not.
352 #
353 # For intro: `private fun foo(e: Object): Bar is abstract`
354 # For redef: `redef fun foo(e) is cached`
355 # TODO change the implementation to correspond to the comment.
356 redef fun html_declaration do
357 var tpl = new Template
358 tpl.add "<span>"
359 tpl.add html_modifiers.join(" ")
360 tpl.add " "
361 tpl.add html_link
362 tpl.add html_signature
363 tpl.add "</span>"
364 return tpl
365 end
366
367 # Returns `mclassdef::self`
368 redef fun html_namespace do
369 var tpl = new Template
370 tpl.add mclassdef.html_namespace
371 tpl.add "::"
372 tpl.add html_link
373 return tpl
374 end
375
376 # Returns the MPropdDef signature without static types.
377 fun html_short_signature: Template is abstract
378
379 # Returns the MPropDef signature with static types.
380 fun html_signature: Template is abstract
381 end
382
383 redef class MAttributeDef
384
385 redef fun html_modifiers do
386 var res = super
387 res.add "var"
388 return res
389 end
390
391 redef fun html_short_signature do return new Template
392
393 redef fun html_signature do
394 var tpl = new Template
395 if static_mtype != null then
396 tpl.add ": "
397 tpl.add static_mtype.html_signature
398 end
399 return tpl
400 end
401 end
402
403 redef class MMethodDef
404
405 # FIXME annotation should be handled in their own way
406 redef fun html_modifiers do
407 var res = super
408 if is_abstract then
409 res.add "abstract"
410 else if is_intern then
411 res.add "intern"
412 end
413 if mproperty.is_init then
414 res.add "init"
415 else
416 res.add "fun"
417 end
418 return res
419 end
420
421 redef fun html_short_signature do return msignature.html_short_signature
422 redef fun html_signature do return msignature.html_signature
423 end
424
425 redef class MVirtualTypeProp
426 redef fun html_link do return mvirtualtype.html_link
427 end
428
429 redef class MVirtualTypeDef
430
431 redef fun html_modifiers do
432 var res = super
433 res.add "type"
434 return res
435 end
436
437 redef fun html_short_signature do return new Template
438
439 redef fun html_signature do
440 var tpl = new Template
441 if bound == null then return tpl
442 tpl.add ": "
443 tpl.add bound.html_signature
444 return tpl
445 end
446 end
447
448 redef class MType
449 # Returns the signature of this type whithout bounds.
450 fun html_short_signature: Template is abstract
451
452 # Returns the signature of this type.
453 fun html_signature: Template is abstract
454 end
455
456 redef class MClassType
457 redef fun html_link do return mclass.html_link
458 redef fun html_short_signature do return html_link
459 redef fun html_signature do return html_link
460 end
461
462 redef class MNullableType
463
464 redef fun html_short_signature do
465 var tpl = new Template
466 tpl.add "nullable "
467 tpl.add mtype.html_short_signature
468 return tpl
469 end
470
471 redef fun html_signature do
472 var tpl = new Template
473 tpl.add "nullable "
474 tpl.add mtype.html_signature
475 return tpl
476 end
477 end
478
479 redef class MGenericType
480 redef fun html_short_signature do
481 var lnk = html_link
482 var tpl = new Template
483 tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
484 tpl.add "["
485 for i in [0..arguments.length[ do
486 tpl.add arguments[i].html_short_signature
487 if i < arguments.length - 1 then tpl.add ", "
488 end
489 tpl.add "]"
490 return tpl
491 end
492
493 redef fun html_signature do
494 var lnk = html_link
495 var tpl = new Template
496 tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
497 tpl.add "["
498 for i in [0..arguments.length[ do
499 tpl.add arguments[i].html_signature
500 if i < arguments.length - 1 then tpl.add ", "
501 end
502 tpl.add "]"
503 return tpl
504 end
505 end
506
507 redef class MParameterType
508 redef fun html_link do
509 return new Link.with_title("{mclass.nitdoc_url}#FT_{name.to_cmangle}", name, "formal type")
510 end
511
512 redef fun html_short_signature do return html_link
513 redef fun html_signature do return html_link
514 end
515
516 redef class MVirtualType
517 redef fun html_link do return mproperty.intro.html_link
518 redef fun html_signature do return html_link
519 end
520
521 redef class MSignature
522
523 redef fun html_short_signature do
524 var tpl = new Template
525 if not mparameters.is_empty then
526 tpl.add "("
527 for i in [0..mparameters.length[ do
528 tpl.add mparameters[i].html_short_signature
529 if i < mparameters.length - 1 then tpl.add ", "
530 end
531 tpl.add ")"
532 end
533 return tpl
534 end
535
536 redef fun html_signature do
537 var tpl = new Template
538 if not mparameters.is_empty then
539 tpl.add "("
540 for i in [0..mparameters.length[ do
541 tpl.add mparameters[i].html_signature
542 if i < mparameters.length - 1 then tpl.add ", "
543 end
544 tpl.add ")"
545 end
546 if return_mtype != null then
547 tpl.add ": "
548 tpl.add return_mtype.html_signature
549 end
550 return tpl
551 end
552 end
553
554 redef class MParameter
555
556 # Returns `self` name and ellipsys if any.
557 fun html_short_signature: Template do
558 var tpl = new Template
559 tpl.add name
560 if is_vararg then tpl.add "..."
561 return tpl
562 end
563
564 # Returns `self` name with it's static type and ellipsys if any.
565 fun html_signature: Template do
566 var tpl = new Template
567 tpl.add "{name}: "
568 tpl.add mtype.html_signature
569 if is_vararg then tpl.add "..."
570 return tpl
571 end
572 end
573
574 ################################################################################
575 # Additions to `model_ext`.
576
577 redef class MRawType
578 redef fun html_signature do
579 var tpl = new Template
580
581 for part in parts do
582 if part.target != null then
583 tpl.add part.target.as(not null).html_link
584 else
585 tpl.add part.text.html_escape
586 end
587 end
588 return tpl
589 end
590 end
591
592 redef class MInnerClass
593 redef fun nitdoc_url do return inner.nitdoc_url
594 redef fun html_signature do return inner.html_signature
595 end
596
597 redef class MInnerClassDef
598 redef fun nitdoc_url do return inner.nitdoc_url
599
600 redef fun html_link_to_anchor do return inner.html_link_to_anchor
601 redef fun html_link do return inner.html_link
602 redef fun html_signature do return inner.html_signature
603 end