1 package org.apache.maven.doxia.macro.toc;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.StringReader;
23
24 import org.apache.maven.doxia.index.IndexEntry;
25 import org.apache.maven.doxia.index.IndexingSink;
26 import org.apache.maven.doxia.macro.AbstractMacro;
27 import org.apache.maven.doxia.macro.Macro;
28 import org.apache.maven.doxia.macro.MacroExecutionException;
29 import org.apache.maven.doxia.macro.MacroRequest;
30 import org.apache.maven.doxia.util.HtmlTools;
31 import org.apache.maven.doxia.parser.ParseException;
32 import org.apache.maven.doxia.parser.Parser;
33 import org.apache.maven.doxia.sink.Sink;
34
35 import org.codehaus.plexus.component.annotations.Component;
36 import org.codehaus.plexus.util.StringUtils;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 @Component( role = Macro.class, hint = "toc" )
81 public class TocMacro
82 extends AbstractMacro
83 {
84
85 private int section;
86
87
88 private int fromDepth;
89
90
91 private int toDepth;
92
93
94 private static final int DEFAULT_DEPTH = 5;
95
96
97 public void execute( Sink sink, MacroRequest request )
98 throws MacroExecutionException
99 {
100 String source = (String) request.getParameter( "sourceContent" );
101 Parser parser = (Parser) request.getParameter( "parser" );
102
103 section = getInt( request, "section", 0 );
104 fromDepth = getInt( request, "fromDepth", 0 );
105 toDepth = getInt( request, "toDepth", DEFAULT_DEPTH );
106
107 if ( fromDepth > toDepth )
108 {
109 return;
110 }
111
112 IndexEntry index = new IndexEntry( "index" );
113 IndexingSink tocSink = new IndexingSink( index );
114
115 try
116 {
117 parser.parse( new StringReader( source ), tocSink );
118 }
119 catch ( ParseException e )
120 {
121 throw new MacroExecutionException( "ParseException: " + e.getMessage(), e );
122 }
123
124 if ( index.getChildEntries().size() > 0 )
125 {
126 sink.list( getAttributesFromMap( request.getParameters() ) );
127
128 int i = 1;
129
130 for ( IndexEntry sectionIndex : index.getChildEntries() )
131 {
132 if ( ( i == section ) || ( section == 0 ) )
133 {
134 writeSubSectionN( sink, sectionIndex, 1 );
135 }
136
137 i++;
138 }
139
140 sink.list_();
141 }
142 }
143
144
145
146
147
148
149 private void writeSubSectionN( Sink sink, IndexEntry sectionIndex, int n )
150 {
151 if ( fromDepth <= n )
152 {
153 sink.listItem();
154 sink.link( "#" + HtmlTools.encodeId( sectionIndex.getId() ) );
155 sink.text( sectionIndex.getTitle() );
156 sink.link_();
157 }
158
159 if ( toDepth > n )
160 {
161 if ( sectionIndex.getChildEntries().size() > 0 )
162 {
163 if ( fromDepth <= n )
164 {
165 sink.list();
166 }
167
168 for ( IndexEntry subsectionIndex : sectionIndex.getChildEntries() )
169 {
170 if ( n == toDepth - 1 )
171 {
172 sink.listItem();
173 sink.link( "#" + HtmlTools.encodeId( subsectionIndex.getId() ) );
174 sink.text( subsectionIndex.getTitle() );
175 sink.link_();
176 sink.listItem_();
177 }
178 else
179 {
180 writeSubSectionN( sink, subsectionIndex, n + 1 );
181 }
182 }
183
184 if ( fromDepth <= n )
185 {
186 sink.list_();
187 }
188 }
189 }
190
191 if ( fromDepth <= n )
192 {
193 sink.listItem_();
194 }
195 }
196
197
198
199
200
201
202
203
204 private static int getInt( MacroRequest request, String parameter, int defaultValue )
205 throws MacroExecutionException
206 {
207 String value = (String) request.getParameter( parameter );
208
209 if ( StringUtils.isEmpty( value ) )
210 {
211 return defaultValue;
212 }
213
214 int i;
215
216 try
217 {
218 i = Integer.parseInt( value );
219 }
220 catch ( NumberFormatException e )
221 {
222 return defaultValue;
223 }
224
225 if ( i < 0 )
226 {
227 throw new MacroExecutionException( "The " + parameter + "=" + i + " should be positive." );
228 }
229
230 return i;
231 }
232 }