View Javadoc
1   package org.apache.maven.doxia.module.markdown;
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 com.vladsch.flexmark.ast.FencedCodeBlock;
23  import com.vladsch.flexmark.ast.IndentedCodeBlock;
24  import com.vladsch.flexmark.html.CustomNodeRenderer;
25  import com.vladsch.flexmark.html.HtmlWriter;
26  import com.vladsch.flexmark.html.renderer.NodeRenderer;
27  import com.vladsch.flexmark.html.renderer.NodeRendererContext;
28  import com.vladsch.flexmark.html.renderer.NodeRendererFactory;
29  import com.vladsch.flexmark.html.renderer.NodeRenderingHandler;
30  import com.vladsch.flexmark.util.options.DataHolder;
31  
32  import java.util.Arrays;
33  import java.util.HashSet;
34  import java.util.Set;
35  
36  /**
37   * The node renderer that renders all the core nodes (comes last in the order of node renderers).
38   */
39  @SuppressWarnings( "WeakerAccess" )
40  class FlexmarkDoxiaNodeRenderer implements NodeRenderer
41  {
42      public FlexmarkDoxiaNodeRenderer( DataHolder options )
43      {
44      }
45  
46      @Override
47      public Set<NodeRenderingHandler<?>> getNodeRenderingHandlers()
48      {
49          //noinspection unchecked
50          return new HashSet<NodeRenderingHandler<?>>( Arrays.asList(
51                  new NodeRenderingHandler<IndentedCodeBlock>( IndentedCodeBlock.class,
52                          new CustomNodeRenderer<IndentedCodeBlock>()
53                          {
54                              @Override
55                              public void render( IndentedCodeBlock node, NodeRendererContext context, HtmlWriter html )
56                              {
57                                  FlexmarkDoxiaNodeRenderer.this.render( node, context, html );
58                              }
59                          } ),
60                  new NodeRenderingHandler<FencedCodeBlock>( FencedCodeBlock.class,
61                          new CustomNodeRenderer<FencedCodeBlock>()
62                          {
63                              @Override
64                              public void render( FencedCodeBlock node, NodeRendererContext context, HtmlWriter html )
65                              {
66                                  FlexmarkDoxiaNodeRenderer.this.render( node, context, html );
67                              }
68                          } )
69          ) );
70      }
71  
72      private void render( IndentedCodeBlock node, NodeRendererContext context, HtmlWriter html )
73      {
74          html.line();
75          html.attr( "class", "source" ).tag( "div" );
76          html.srcPosWithEOL( node.getChars() ).withAttr().tag( "pre" ).openPre();
77  
78          String noLanguageClass = context.getHtmlOptions().noLanguageClass.trim();
79          if ( !noLanguageClass.isEmpty() )
80          {
81              html.attr( "class", noLanguageClass );
82          }
83  
84          //html.srcPosWithEOL(node.getContentChars()).withAttr(CoreNodeRenderer.CODE_CONTENT).tag("code");
85          String s = node.getContentChars().trimTailBlankLines().normalizeEndWithEOL();
86          while ( !s.isEmpty() && s.charAt( 0 ) == '\n' )
87          {
88              html.raw( "<br/>" );
89              s = s.substring( 1 );
90          }
91          html.text( s );
92  
93          //html.tag("/code");
94          html.tag( "/pre" ).closePre();
95          html.tag( "/div" );
96          html.line();
97      }
98  
99      private void render( FencedCodeBlock node, NodeRendererContext context, HtmlWriter html )
100     {
101         html.line();
102         html.attr( "class", "source" ).tag( "div" );
103         html.srcPosWithTrailingEOL( node.getChars() ).withAttr().tag( "pre" ).openPre();
104 
105         //BasedSequence info = node.getInfo();
106         //if (info.isNotNull() && !info.isBlank()) {
107         //    int space = info.indexOf(' ');
108         //    BasedSequence language;
109         //    if (space == -1) {
110         //        language = info;
111         //    } else {
112         //        language = info.subSequence(0, space);
113         //    }
114         //    html.attr("class", context.getHtmlOptions().languageClassPrefix + language.unescape());
115         //} else  {
116         //    String noLanguageClass = context.getHtmlOptions().noLanguageClass.trim();
117         //    if (!noLanguageClass.isEmpty()) {
118         //        html.attr("class", noLanguageClass);
119         //    }
120         //}
121 
122         //html.srcPosWithEOL(node.getContentChars()).withAttr(CoreNodeRenderer.CODE_CONTENT).tag("code");
123         String s = node.getContentChars().normalizeEOL();
124         while ( !s.isEmpty() && s.charAt( 0 ) == '\n' )
125         {
126             html.raw( "<br/>" );
127             s = s.substring( 1 );
128         }
129         html.text( s );
130 
131         //html.tag("/code");
132         html.tag( "/pre" ).closePre();
133         html.tag( "/div" );
134         html.line();
135     }
136 
137     /**
138      * Factory for doxia node renderer
139      */
140     public static class Factory implements NodeRendererFactory
141     {
142         @Override
143         public NodeRenderer create( final DataHolder options )
144         {
145             return new FlexmarkDoxiaNodeRenderer( options );
146         }
147     }
148 }