001package org.apache.maven.doxia.module.xhtml5;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.StringWriter;
023import java.io.Writer;
024
025import org.apache.maven.doxia.markup.HtmlMarkup;
026import org.apache.maven.doxia.module.xhtml5.Xhtml5Sink;
027import org.apache.maven.doxia.sink.Sink;
028import org.apache.maven.doxia.sink.impl.AbstractSinkTest;
029import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
030
031import static org.apache.maven.doxia.util.HtmlTools.escapeHTML;
032
033public class Xhtml5SinkTest
034    extends AbstractSinkTest
035{
036    /** {@inheritDoc} */
037    protected String outputExtension()
038    {
039        return "html";
040    }
041
042    /** {@inheritDoc} */
043    protected Sink createSink( Writer writer )
044    {
045        return new Xhtml5Sink( writer, "UTF-8" );
046    }
047
048    /** {@inheritDoc} */
049    protected boolean isXmlSink()
050    {
051        return true;
052    }
053
054    /**
055     * Test link generation.
056     *
057     */
058    public void testLinks()
059    {
060        Xhtml5Sink sink = null;
061        Writer writer =  new StringWriter();
062        try
063        {
064            sink = (Xhtml5Sink) createSink( writer );
065            sink.link( "http:/www.xdoc.com" );
066            sink.link_();
067            sink.link( "./index.html#anchor" );
068            sink.link_();
069            sink.link( "../index.html#anchor" );
070            sink.link_();
071            sink.link( "index.html" );
072            sink.link_();
073        }
074        finally
075        {
076            if ( sink != null )
077            {
078                sink.close();
079            }
080        }
081
082        String actual = writer.toString();
083        assertTrue( actual.contains( "<a class=\"externalLink\" href=\"http:/www.xdoc.com\"></a>" ) );
084        assertTrue( actual.contains( "<a href=\"./index.html#anchor\"></a>" ) );
085        assertTrue( actual.contains( "<a href=\"../index.html#anchor\"></a>" ) );
086        assertTrue( actual.contains( "<a href=\"index.html\"></a>" ) );
087    }
088
089    /** {@inheritDoc} */
090    protected String getTitleBlock( String title )
091    {
092        return "<title>" + title + "</title>";
093    }
094
095    /** {@inheritDoc} */
096    protected String getAuthorBlock( String author )
097    {
098        return author;
099    }
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}