View Javadoc
1   package org.apache.maven.doxia.module.xhtml5;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.StringWriter;
23  import java.io.Writer;
24  
25  import org.apache.maven.doxia.markup.HtmlMarkup;
26  import org.apache.maven.doxia.module.xhtml5.Xhtml5Sink;
27  import org.apache.maven.doxia.sink.Sink;
28  import org.apache.maven.doxia.sink.impl.AbstractSinkTest;
29  import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
30  
31  import static org.apache.maven.doxia.util.HtmlTools.escapeHTML;
32  
33  public class Xhtml5SinkTest
34      extends AbstractSinkTest
35  {
36      /** {@inheritDoc} */
37      protected String outputExtension()
38      {
39          return "html";
40      }
41  
42      /** {@inheritDoc} */
43      protected Sink createSink( Writer writer )
44      {
45          return new Xhtml5Sink( writer, "UTF-8" );
46      }
47  
48      /** {@inheritDoc} */
49      protected boolean isXmlSink()
50      {
51          return true;
52      }
53  
54      /**
55       * Test link generation.
56       *
57       * @throws java.lang.Exception if any.
58       */
59      public void testLinks()
60          throws Exception
61      {
62          Xhtml5Sink sink = null;
63          Writer writer =  new StringWriter();
64          try
65          {
66              sink = (Xhtml5Sink) createSink( writer );
67              sink.link( "http:/www.xdoc.com" );
68              sink.link_();
69              sink.link( "./index.html#anchor" );
70              sink.link_();
71              sink.link( "../index.html#anchor" );
72              sink.link_();
73              sink.link( "index.html" );
74              sink.link_();
75          }
76          finally
77          {
78              if ( sink != null )
79              {
80                  sink.close();
81              }
82          }
83  
84          String actual = writer.toString();
85          assertTrue( actual.contains( "<a class=\"externalLink\" href=\"http:/www.xdoc.com\"></a>" ) );
86          assertTrue( actual.contains( "<a href=\"./index.html#anchor\"></a>" ) );
87          assertTrue( actual.contains( "<a href=\"../index.html#anchor\"></a>" ) );
88          assertTrue( actual.contains( "<a href=\"index.html\"></a>" ) );
89      }
90  
91      /** {@inheritDoc} */
92      protected String getTitleBlock( String title )
93      {
94          return "<title>" + title + "</title>";
95      }
96  
97      /** {@inheritDoc} */
98      protected String getAuthorBlock( String author )
99      {
100         return author;
101     }
102 
103     /** {@inheritDoc} */
104     protected String getDateBlock( String date )
105     {
106         return date;
107     }
108 
109     /** {@inheritDoc} */
110     protected String getHeadBlock()
111     {
112         return "<!DOCTYPE html\">" +
113                 "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<title></title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/></head>";
114     }
115 
116     /** {@inheritDoc} */
117     protected String getBodyBlock()
118     {
119         return "<body></body></html>";
120     }
121 
122     /** {@inheritDoc} */
123     protected String getArticleBlock()
124     {
125         return "<article></article>";
126     }
127 
128     /** {@inheritDoc} */
129     protected String getNavigationBlock()
130     {
131         return "<nav></nav>";
132     }
133 
134     /** {@inheritDoc} */
135     protected String getSidebarBlock()
136     {
137         return "<aside></aside>";
138     }
139 
140     /** {@inheritDoc} */
141     protected String getSectionTitleBlock( String title )
142     {
143         return title;
144     }
145 
146     /** {@inheritDoc} */
147     protected String getSection1Block( String title )
148     {
149         return "<section><header>\n<h2>" + title + "</h2></header></section>";
150     }
151 
152     /** {@inheritDoc} */
153     protected String getSection2Block( String title )
154     {
155         return "<section><header>\n<h3>" + title + "</h3></header></section>";
156     }
157 
158     /** {@inheritDoc} */
159     protected String getSection3Block( String title )
160     {
161         return "<section><header>\n<h4>" + title + "</h4></header></section>";
162     }
163 
164     /** {@inheritDoc} */
165     protected String getSection4Block( String title )
166     {
167         return "<section><header>\n<h5>" + title + "</h5></header></section>";
168     }
169 
170     /** {@inheritDoc} */
171     protected String getSection5Block( String title )
172     {
173         return "<section><header>\n<h6>" + title + "</h6></header></section>";
174     }
175 
176     /** {@inheritDoc} */
177     protected String getHeaderBlock()
178     {
179         return "<header></header>";
180     }
181 
182     /** {@inheritDoc} */
183     protected String getContentBlock()
184     {
185         return "<main>" + EOL + "<div class=\"content\"></div></main>";
186     }
187 
188     /** {@inheritDoc} */
189     protected String getFooterBlock()
190     {
191         return "<footer></footer>";
192     }
193 
194     /** {@inheritDoc} */
195     protected String getListBlock( String item )
196     {
197         return "<ul>\n<li>" + item + "</li></ul>";
198     }
199 
200     /** {@inheritDoc} */
201     protected String getNumberedListBlock( String item )
202     {
203         return "<ol style=\"list-style-type: lower-roman\">\n<li>" + item + "</li></ol>";
204     }
205 
206     /** {@inheritDoc} */
207     protected String getDefinitionListBlock( String definum, String definition )
208     {
209         return "<dl>\n<dt>" + definum + "</dt>\n<dd>" + definition + "</dd></dl>";
210     }
211 
212     /** {@inheritDoc} */
213     protected String getFigureBlock( String source, String caption )
214     {
215         String figureBlock = "<figure><img src=\"" + escapeHTML( source, true ) + "\" alt=\"\" />";
216         if( caption != null )
217         {
218             figureBlock += "<figcaption>" + caption + "</figcaption>";
219         }
220         figureBlock += "</figure>";
221         return figureBlock;
222     }
223 
224     /** {@inheritDoc} */
225     protected String getTableBlock( String cell, String caption )
226     {
227         return "<table border=\"0\" class=\"bodyTable\">"
228             + "<caption>Table caption</caption><tr class=\"a\">\n<td>cell</td></tr>"
229             + "</table>";
230     }
231 
232     // Disable testTable until the order of attributes issue is clarified
233     // TODO: remove
234     /** {@inheritDoc} */
235     public void testTable()
236     {
237         assertEquals( "Dummy!", "", "" );
238     }
239 
240     /** {@inheritDoc} */
241     protected String getParagraphBlock( String text )
242     {
243         return "<p>" + text + "</p>";
244     }
245 
246     /** {@inheritDoc} */
247     protected String getDataBlock( String value, String text )
248     {
249         return "<data value=\"" + value + "\">" + text + "</data>";
250     }
251 
252     /** {@inheritDoc} */
253     protected String getTimeBlock( String datetime, String text )
254     {
255         return "<time datetime=\"" + datetime + "\">" + text + "</time>";
256     }
257 
258     /** {@inheritDoc} */
259     protected String getAddressBlock( String text )
260     {
261         return "<address>" + text + "</address>";
262     }
263 
264     /** {@inheritDoc} */
265     protected String getBlockquoteBlock( String text )
266     {
267         return "<blockquote>" + text + "</blockquote>";
268     }
269 
270     /** {@inheritDoc} */
271     protected String getDivisionBlock( String text )
272     {
273         return "<div>" + text + "</div>";
274     }
275 
276     /** {@inheritDoc} */
277     protected String getVerbatimBlock( String text )
278     {
279         return "<div class=\"source\">\n<pre>" + text + "</pre></div>";
280     }
281 
282     /** {@inheritDoc} */
283     protected String getHorizontalRuleBlock()
284     {
285         return "<hr />";
286     }
287 
288     /** {@inheritDoc} */
289     protected String getPageBreakBlock()
290     {
291         return "<!-- PB -->";
292     }
293 
294     /** {@inheritDoc} */
295     protected String getAnchorBlock( String anchor )
296     {
297         return "<a name=\"" + anchor + "\">" + anchor + "</a>";
298     }
299 
300     /** {@inheritDoc} */
301     protected String getLinkBlock( String link, String text )
302     {
303         return "<a href=\"" + link + "\">" + text + "</a>";
304     }
305 
306     /** {@inheritDoc} */
307     protected String getInlineBlock( String text )
308     {
309         return text;
310     }
311 
312     /** {@inheritDoc} */
313     protected String getInlineItalicBlock( String text )
314     {
315         return "<i>" + text + "</i>";
316     }
317 
318     /** {@inheritDoc} */
319     protected String getInlineBoldBlock( String text )
320     {
321         return "<b>" + text + "</b>";
322     }
323 
324     /** {@inheritDoc} */
325     protected String getInlineCodeBlock( String text )
326     {
327         return "<code>" + text + "</code>";
328     }
329 
330     /** {@inheritDoc} */
331     protected String getItalicBlock( String text )
332     {
333         return "<i>" + text + "</i>";
334     }
335 
336     /** {@inheritDoc} */
337     protected String getBoldBlock( String text )
338     {
339         return "<b>" + text + "</b>";
340     }
341 
342     /** {@inheritDoc} */
343     protected String getMonospacedBlock( String text )
344     {
345         return "<code>" + text + "</code>";
346     }
347 
348     /** {@inheritDoc} */
349     protected String getLineBreakBlock()
350     {
351         return "<br />";
352     }
353 
354     /** {@inheritDoc} */
355     protected String getLineBreakOpportunityBlock()
356     {
357         return "<wbr />";
358     }
359 
360     /** {@inheritDoc} */
361     protected String getNonBreakingSpaceBlock()
362     {
363         return "&#160;";
364     }
365 
366     /** {@inheritDoc} */
367     protected String getTextBlock( String text )
368     {
369         // TODO: need to be able to retreive those from outside the sink
370         return "~,_=,_-,_+,_*,_[,_],_&lt;,_&gt;,_{,_},_\\";
371     }
372 
373     /** {@inheritDoc} */
374     protected String getRawTextBlock( String text )
375     {
376         return text;
377     }
378 
379     /**
380      * Test entities is section titles and paragraphs.
381      */
382     public void testEntities()
383     {
384         Xhtml5Sink sink = null;
385         Writer writer =  new StringWriter();
386 
387         try
388         {
389             sink = new Xhtml5Sink( writer );
390             sink.section( Sink.SECTION_LEVEL_1, null );
391             sink.header();
392             sink.sectionTitle( Sink.SECTION_LEVEL_1, null );
393             sink.text( "&", null );
394             sink.sectionTitle_( Sink.SECTION_LEVEL_1 );
395             sink.header_();
396             sink.paragraph( null );
397             sink.text( "&", null );
398             sink.paragraph_();
399             sink.section_( Sink.SECTION_LEVEL_1 );
400         }
401         finally
402         {
403             sink.close();
404         }
405 
406         assertEquals( "<section><header>\n<h2>&amp;</h2></header>\n<p>&amp;</p></section>", writer.toString() );
407     }
408 
409     /**
410      * Test head events.
411      */
412     public void testHead()
413     {
414         Xhtml5Sink sink = null;
415         Writer writer =  new StringWriter();
416 
417         try
418         {
419             sink = new Xhtml5Sink( writer );
420             sink.head();
421             sink.title();
422             sink.text( "Title" );
423             sink.title_();
424             sink.comment( "A comment" );
425             sink.author();
426             // note: this is really illegal, there should be no un-resolved entities emitted into text()
427             sink.text( "&#x123;&" );
428             sink.author_();
429             SinkEventAttributeSet atts = new SinkEventAttributeSet( 1 );
430             atts.addAttribute( "href", "http://maven.apache.org/" );
431             sink.unknown( "base", new Object[] { HtmlMarkup.TAG_TYPE_SIMPLE }, atts );
432             sink.head_();
433         }
434         finally
435         {
436             sink.close();
437         }
438 
439         String expected =
440             "<head>\n<title>Title</title><!--A comment--><meta name=\"author\" content=\"&#x123;&amp;\" />"
441                 + "<base href=\"http://maven.apache.org/\" /></head>";
442         String actual = writer.toString();
443         assertTrue( actual, actual.contains( expected ) );
444     }
445 
446     /** {@inheritDoc} */
447     protected String getCommentBlock( String text )
448     {
449         return "<!--" + toXmlComment( text ) + "-->";
450     }
451 }