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      FlexmarkDoxiaNodeRenderer( DataHolder options )
43      {
44      }
45  
46      /** {@inheritDoc} */
47      @Override
48      public Set<NodeRenderingHandler<?>> getNodeRenderingHandlers()
49      {
50          return new HashSet<NodeRenderingHandler<?>>( Arrays.asList(
51                  new NodeRenderingHandler<>( IndentedCodeBlock.class, new CustomNodeRenderer<IndentedCodeBlock>()
52                  {
53                      @Override
54                      public void render( IndentedCodeBlock node, NodeRendererContext context, HtmlWriter html )
55                      {
56                          FlexmarkDoxiaNodeRenderer.this.render( node, context, html );
57                      }
58                  } ),
59                  new NodeRenderingHandler<>( FencedCodeBlock.class, new CustomNodeRenderer<FencedCodeBlock>()
60                  {
61                      @Override
62                      public void render( FencedCodeBlock node, NodeRendererContext context, HtmlWriter html )
63                      {
64                          FlexmarkDoxiaNodeRenderer.this.render( node, context, html );
65                      }
66                  } )
67          ) );
68      }
69  
70      private void render( IndentedCodeBlock node, NodeRendererContext context, HtmlWriter html )
71      {
72          html.line();
73          html.attr( "class", "source" ).withAttr().tag( "div" );
74          html.srcPosWithEOL( node.getChars() ).tag( "pre" ).openPre();
75  
76          String noLanguageClass = context.getHtmlOptions().noLanguageClass.trim();
77          if ( !noLanguageClass.isEmpty() )
78          {
79              html.attr( "class", noLanguageClass );
80          }
81  
82          //html.srcPosWithEOL(node.getContentChars()).withAttr(CoreNodeRenderer.CODE_CONTENT).tag("code");
83          String s = node.getContentChars().trimTailBlankLines().normalizeEndWithEOL();
84          while ( !s.isEmpty() && s.charAt( 0 ) == '\n' )
85          {
86              html.raw( "<br/>" );
87              s = s.substring( 1 );
88          }
89          html.text( s );
90  
91          //html.tag("/code");
92          html.tag( "/pre" ).closePre();
93          html.tag( "/div" );
94          html.line();
95      }
96  
97      private void render( FencedCodeBlock node, NodeRendererContext context, HtmlWriter html )
98      {
99          html.line();
100         html.attr( "class", "source" ).withAttr().tag( "div" );
101         html.srcPosWithTrailingEOL( node.getChars() ).tag( "pre" ).openPre();
102 
103         //BasedSequence info = node.getInfo();
104         //if (info.isNotNull() && !info.isBlank()) {
105         //    int space = info.indexOf(' ');
106         //    BasedSequence language;
107         //    if (space == -1) {
108         //        language = info;
109         //    } else {
110         //        language = info.subSequence(0, space);
111         //    }
112         //    html.attr("class", context.getHtmlOptions().languageClassPrefix + language.unescape());
113         //} else  {
114         //    String noLanguageClass = context.getHtmlOptions().noLanguageClass.trim();
115         //    if (!noLanguageClass.isEmpty()) {
116         //        html.attr("class", noLanguageClass);
117         //    }
118         //}
119 
120         //html.srcPosWithEOL(node.getContentChars()).withAttr(CoreNodeRenderer.CODE_CONTENT).tag("code");
121         String s = node.getContentChars().normalizeEOL();
122         while ( !s.isEmpty() && s.charAt( 0 ) == '\n' )
123         {
124             html.raw( "<br/>" );
125             s = s.substring( 1 );
126         }
127         html.text( s );
128 
129         //html.tag("/code");
130         html.tag( "/pre" ).closePre();
131         html.tag( "/div" );
132         html.line();
133     }
134 
135     /**
136      * Factory for doxia node renderer
137      */
138     public static class Factory implements NodeRendererFactory
139     {
140         @Override
141         public NodeRenderer create( final DataHolder options )
142         {
143             return new FlexmarkDoxiaNodeRenderer( options );
144         }
145     }
146 }