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       */
58      public void testLinks()
59      {
60          Xhtml5Sink sink = null;
61          Writer writer =  new StringWriter();
62          try
63          {
64              sink = (Xhtml5Sink) createSink( writer );
65              sink.link( "http:/www.xdoc.com" );
66              sink.link_();
67              sink.link( "./index.html#anchor" );
68              sink.link_();
69              sink.link( "../index.html#anchor" );
70              sink.link_();
71              sink.link( "index.html" );
72              sink.link_();
73          }
74          finally
75          {
76              if ( sink != null )
77              {
78                  sink.close();
79              }
80          }
81  
82          String actual = writer.toString();
83          assertTrue( actual.contains( "<a class=\"externalLink\" href=\"http:/www.xdoc.com\"></a>" ) );
84          assertTrue( actual.contains( "<a href=\"./index.html#anchor\"></a>" ) );
85          assertTrue( actual.contains( "<a href=\"../index.html#anchor\"></a>" ) );
86          assertTrue( actual.contains( "<a href=\"index.html\"></a>" ) );
87      }
88  
89      /** {@inheritDoc} */
90      protected String getTitleBlock( String title )
91      {
92          return "<title>" + title + "</title>";
93      }
94  
95      /** {@inheritDoc} */
96      protected String getAuthorBlock( String author )
97      {
98          return author;
99      }
100 
101     /** {@inheritDoc} */
102     protected String getDateBlock( String date )
103     {
104         return date;
105     }
106 
107     /** {@inheritDoc} */
108     protected String getHeadBlock()
109     {
110         return "<!DOCTYPE html\">" +
111                 "<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>";
112     }
113 
114     /** {@inheritDoc} */
115     protected String getBodyBlock()
116     {
117         return "<body></body></html>";
118     }
119 
120     /** {@inheritDoc} */
121     protected String getArticleBlock()
122     {
123         return "<article></article>";
124     }
125 
126     /** {@inheritDoc} */
127     protected String getNavigationBlock()
128     {
129         return "<nav></nav>";
130     }
131 
132     /** {@inheritDoc} */
133     protected String getSidebarBlock()
134     {
135         return "<aside></aside>";
136     }
137 
138     /** {@inheritDoc} */
139     protected String getSectionTitleBlock( String title )
140     {
141         return title;
142     }
143 
144     /** {@inheritDoc} */
145     protected String getSection1Block( String title )
146     {
147         return "<section><header>\n<h2>" + title + "</h2></header></section>";
148     }
149 
150     /** {@inheritDoc} */
151     protected String getSection2Block( String title )
152     {
153         return "<section><header>\n<h3>" + title + "</h3></header></section>";
154     }
155 
156     /** {@inheritDoc} */
157     protected String getSection3Block( String title )
158     {
159         return "<section><header>\n<h4>" + title + "</h4></header></section>";
160     }
161 
162     /** {@inheritDoc} */
163     protected String getSection4Block( String title )
164     {
165         return "<section><header>\n<h5>" + title + "</h5></header></section>";
166     }
167 
168     /** {@inheritDoc} */
169     protected String getSection5Block( String title )
170     {
171         return "<section><header>\n<h6>" + title + "</h6></header></section>";
172     }
173 
174     /** {@inheritDoc} */
175     protected String getHeaderBlock()
176     {
177         return "<header></header>";
178     }
179 
180     /** {@inheritDoc} */
181     protected String getContentBlock()
182     {
183         return "<main>" + EOL + "<div class=\"content\"></div></main>";
184     }
185 
186     /** {@inheritDoc} */
187     protected String getFooterBlock()
188     {
189         return "<footer></footer>";
190     }
191 
192     /** {@inheritDoc} */
193     protected String getListBlock( String item )
194     {
195         return "<ul>\n<li>" + item + "</li></ul>";
196     }
197 
198     /** {@inheritDoc} */
199     protected String getNumberedListBlock( String item )
200     {
201         return "<ol style=\"list-style-type: lower-roman\">\n<li>" + item + "</li></ol>";
202     }
203 
204     /** {@inheritDoc} */
205     protected String getDefinitionListBlock( String definum, String definition )
206     {
207         return "<dl>\n<dt>" + definum + "</dt>\n<dd>" + definition + "</dd></dl>";
208     }
209 
210     /** {@inheritDoc} */
211     protected String getFigureBlock( String source, String caption )
212     {
213         String figureBlock = "<figure><img src=\"" + escapeHTML( source, true ) + "\" alt=\"\" />";
214         if( caption != null )
215         {
216             figureBlock += "<figcaption>" + caption + "</figcaption>";
217         }
218         figureBlock += "</figure>";
219         return figureBlock;
220     }
221 
222     /** {@inheritDoc} */
223     protected String getTableBlock( String cell, String caption )
224     {
225         return "<table border=\"0\" class=\"bodyTable\">"
226             + "<caption>Table caption</caption><tr class=\"a\">\n<td>cell</td></tr>"
227             + "</table>";
228     }
229 
230     // Disable testTable until the order of attributes issue is clarified
231     // TODO: remove
232     /** {@inheritDoc} */
233     public void testTable()
234     {
235         assertEquals( "Dummy!", "", "" );
236     }
237 
238     /** {@inheritDoc} */
239     protected String getParagraphBlock( String text )
240     {
241         return "<p>" + text + "</p>";
242     }
243 
244     /** {@inheritDoc} */
245     protected String getDataBlock( String value, String text )
246     {
247         return "<data value=\"" + value + "\">" + text + "</data>";
248     }
249 
250     /** {@inheritDoc} */
251     protected String getTimeBlock( String datetime, String text )
252     {
253         return "<time datetime=\"" + datetime + "\">" + text + "</time>";
254     }
255 
256     /** {@inheritDoc} */
257     protected String getAddressBlock( String text )
258     {
259         return "<address>" + text + "</address>";
260     }
261 
262     /** {@inheritDoc} */
263     protected String getBlockquoteBlock( String text )
264     {
265         return "<blockquote>" + text + "</blockquote>";
266     }
267 
268     /** {@inheritDoc} */
269     protected String getDivisionBlock( String text )
270     {
271         return "<div>" + text + "</div>";
272     }
273 
274     /** {@inheritDoc} */
275     protected String getVerbatimBlock( String text )
276     {
277         return "<div class=\"source\">\n<pre>" + text + "</pre></div>";
278     }
279 
280     /** {@inheritDoc} */
281     protected String getHorizontalRuleBlock()
282     {
283         return "<hr />";
284     }
285 
286     /** {@inheritDoc} */
287     protected String getPageBreakBlock()
288     {
289         return "<!-- PB -->";
290     }
291 
292     /** {@inheritDoc} */
293     protected String getAnchorBlock( String anchor )
294     {
295         return "<a name=\"" + anchor + "\">" + anchor + "</a>";
296     }
297 
298     /** {@inheritDoc} */
299     protected String getLinkBlock( String link, String text )
300     {
301         return "<a href=\"" + link + "\">" + text + "</a>";
302     }
303 
304     /** {@inheritDoc} */
305     protected String getInlineBlock( String text )
306     {
307         return text;
308     }
309 
310     /** {@inheritDoc} */
311     protected String getInlineItalicBlock( String text )
312     {
313         return "<i>" + text + "</i>";
314     }
315 
316     /** {@inheritDoc} */
317     protected String getInlineBoldBlock( String text )
318     {
319         return "<b>" + text + "</b>";
320     }
321 
322     /** {@inheritDoc} */
323     protected String getInlineCodeBlock( String text )
324     {
325         return "<code>" + text + "</code>";
326     }
327 
328     /** {@inheritDoc} */
329     protected String getItalicBlock( String text )
330     {
331         return "<i>" + text + "</i>";
332     }
333 
334     /** {@inheritDoc} */
335     protected String getBoldBlock( String text )
336     {
337         return "<b>" + text + "</b>";
338     }
339 
340     /** {@inheritDoc} */
341     protected String getMonospacedBlock( String text )
342     {
343         return "<code>" + text + "</code>";
344     }
345 
346     /** {@inheritDoc} */
347     protected String getLineBreakBlock()
348     {
349         return "<br />";
350     }
351 
352     /** {@inheritDoc} */
353     protected String getLineBreakOpportunityBlock()
354     {
355         return "<wbr />";
356     }
357 
358     /** {@inheritDoc} */
359     protected String getNonBreakingSpaceBlock()
360     {
361         return "&#160;";
362     }
363 
364     /** {@inheritDoc} */
365     protected String getTextBlock( String text )
366     {
367         // TODO: need to be able to retreive those from outside the sink
368         return "~,_=,_-,_+,_*,_[,_],_&lt;,_&gt;,_{,_},_\\";
369     }
370 
371     /** {@inheritDoc} */
372     protected String getRawTextBlock( String text )
373     {
374         return text;
375     }
376 
377     /**
378      * Test entities is section titles and paragraphs.
379      */
380     public void testEntities()
381     {
382         Xhtml5Sink sink = null;
383         Writer writer =  new StringWriter();
384 
385         try
386         {
387             sink = new Xhtml5Sink( writer );
388             sink.section( Sink.SECTION_LEVEL_1, null );
389             sink.header();
390             sink.sectionTitle( Sink.SECTION_LEVEL_1, null );
391             sink.text( "&", null );
392             sink.sectionTitle_( Sink.SECTION_LEVEL_1 );
393             sink.header_();
394             sink.paragraph( null );
395             sink.text( "&", null );
396             sink.paragraph_();
397             sink.section_( Sink.SECTION_LEVEL_1 );
398         }
399         finally
400         {
401             sink.close();
402         }
403 
404         assertEquals( "<section><header>\n<h2>&amp;</h2></header>\n<p>&amp;</p></section>", writer.toString() );
405     }
406 
407     /**
408      * Test head events.
409      */
410     public void testHead()
411     {
412         Xhtml5Sink sink = null;
413         Writer writer =  new StringWriter();
414 
415         try
416         {
417             sink = new Xhtml5Sink( writer );
418             sink.head();
419             sink.title();
420             sink.text( "Title" );
421             sink.title_();
422             sink.comment( "A comment" );
423             sink.author();
424             // note: this is really illegal, there should be no un-resolved entities emitted into text()
425             sink.text( "&#x123;&" );
426             sink.author_();
427             SinkEventAttributeSet atts = new SinkEventAttributeSet( 1 );
428             atts.addAttribute( "href", "http://maven.apache.org/" );
429             sink.unknown( "base", new Object[] { HtmlMarkup.TAG_TYPE_SIMPLE }, atts );
430             sink.head_();
431         }
432         finally
433         {
434             sink.close();
435         }
436 
437         String expected =
438             "<head>\n<title>Title</title><!--A comment--><meta name=\"author\" content=\"&#x123;&amp;\" />"
439                 + "<base href=\"http://maven.apache.org/\" /></head>";
440         String actual = writer.toString();
441         assertTrue( actual, actual.contains( expected ) );
442     }
443 
444     /** {@inheritDoc} */
445     protected String getCommentBlock( String text )
446     {
447         return "<!--" + toXmlComment( text ) + "-->";
448     }
449 }