neo_doxygen: Add an API to process description markup.
[nit.git] / contrib / neo_doxygen / src / doxml / doc_listener.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 # Documentation reading.
16 module doxml::doc_listener
17
18 import listener
19 import html
20
21 # Processes documentation.
22 class DocListener
23 super TextListener
24
25 # The read documentation.
26 var doc = new Documentation is writable
27
28 # Mapping between the type of a Doxygen element and the corresponding
29 # factory.
30 private var factories = new HashMap[String, HtmlElementFactory]
31
32 private var element_stack = new Array[HTMLTag]
33
34 # Does the next block have to be added to the detailed description?
35 private var in_detailed_description = false
36
37 redef fun listen_until(uri, local_name) do
38 super
39 if local_name == "briefdescription" then
40 in_detailed_description = false
41 else
42 in_detailed_description = true
43 end
44 end
45
46 redef fun start_dox_element(local_name, atts) do
47 super
48 var factory = factories.get_or_null(local_name)
49 if factory == null then return
50 element_stack.push(factory.create_element(local_name, atts))
51 end
52
53 redef fun end_dox_element(local_name) do
54 super
55 if not factories.has_key(local_name) then return
56 if element_stack.is_empty then return
57 var current_element = element_stack.pop
58 current_element.append(flush_buffer.trim)
59 if element_stack.is_empty then add_block(current_element.write_to_string)
60 end
61
62 redef fun end_listening do
63 super
64 if not element_stack.is_empty then
65 var current_element = element_stack.first.write_to_string
66 add_block(current_element)
67 end
68 add_block(flush_buffer.trim)
69 element_stack.clear
70 end
71
72 private fun add_block(block: String) do
73 if block.is_empty then return
74 if in_detailed_description then
75 doc.add(block)
76 else
77 doc.brief_description = block
78 in_detailed_description = true
79 end
80 end
81 end
82
83 # Provides a mean to create a certain kind of HTML elements.
84 private abstract class HtmlElementFactory
85 # Create a new empty HTML element.
86 #
87 # Parameters:
88 #
89 # * `local_name`: Type of the Doxygen element that will be represented by
90 # the HTML element.
91 # * `attributes`: Attributes of the Doxygen element that will be
92 # represented by the HTML element.
93 fun create_element(local_name: String, attributes: Attributes): HTMLTag is abstract
94 end