View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.doxia.module.markdown;
20  
21  import java.util.HashSet;
22  import java.util.Set;
23  import java.util.regex.Matcher;
24  import java.util.regex.Pattern;
25  
26  import com.vladsch.flexmark.ext.wikilink.internal.WikiLinkLinkResolver;
27  import com.vladsch.flexmark.html.IndependentLinkResolverFactory;
28  import com.vladsch.flexmark.html.LinkResolver;
29  import com.vladsch.flexmark.html.renderer.LinkResolverBasicContext;
30  import com.vladsch.flexmark.html.renderer.LinkStatus;
31  import com.vladsch.flexmark.html.renderer.LinkType;
32  import com.vladsch.flexmark.html.renderer.ResolvedLink;
33  import com.vladsch.flexmark.util.ast.Node;
34  import org.jetbrains.annotations.NotNull;
35  import org.jetbrains.annotations.Nullable;
36  
37  /**
38   * The FlexmarkDoxiaLinkResolver rewrites the md, markdown links to html.
39   *
40   * Sample links it rewrites:
41   * - doc.md to doc.html
42   * - doc.markdown to doc.html
43   * - doc.md#anchor to doc.html#anchor
44   * - doc.markdown#anchor to doc.html#anchor
45   * - ../doc.markdown#anchor to ../doc.html#anchor
46   * - :doc.md to :doc.html
47   * - :doc.markdown to :doc.html
48   *
49   * Sample links it leaves untouched:
50   * - http://doc.md
51   * - https://doc.markdown
52   * - doc.md.badformat
53   * - doc.md#bad#format
54   * - doc.md#bad.format
55   */
56  public class FlexmarkDoxiaLinkResolver implements LinkResolver {
57      final Pattern pattern;
58  
59      /**
60       * <p>Constructor for FlexmarkDoxiaLinkResolver.</p>
61       *
62       */
63      public FlexmarkDoxiaLinkResolver() {
64          this.pattern = Pattern.compile("^(?![^:]+:)((?:\\./)?(?:\\.\\./)*[^\\.]+).(?:"
65                  + MarkdownParserModule.FILE_EXTENSION
66                  + "|"
67                  + MarkdownParserModule.ALTERNATE_FILE_EXTENSION
68                  + ")(#[^#\\.]*){0,1}$");
69      }
70  
71      @Override
72      public @NotNull ResolvedLink resolveLink(
73              @NotNull Node node, @NotNull LinkResolverBasicContext context, @NotNull ResolvedLink link) {
74          if (link.getLinkType() == LinkType.LINK) {
75              Matcher matcher = this.pattern.matcher(link.getUrl());
76              if (matcher.matches()) {
77                  return link.withStatus(LinkStatus.VALID).withUrl(matcher.replaceAll("$1.html$2"));
78              }
79          }
80  
81          return link;
82      }
83  
84      /**
85       * Factory that creates FlexmarkDoxiaLinkResolver objects.
86       */
87      public static class Factory extends IndependentLinkResolverFactory {
88          @Override
89          public @Nullable Set<Class<?>> getBeforeDependents() {
90              Set<Class<?>> set = new HashSet<>();
91              set.add(WikiLinkLinkResolver.Factory.class);
92              return set;
93          }
94  
95          @Override
96          public @NotNull LinkResolver apply(@NotNull LinkResolverBasicContext context) {
97              return new FlexmarkDoxiaLinkResolver();
98          }
99      }
100 }