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       * @param context a {@link com.vladsch.flexmark.html.renderer.LinkResolverContext} object.
63       */
64      public FlexmarkDoxiaLinkResolver(@NotNull LinkResolverBasicContext context) {
65          this.pattern = Pattern.compile("^(?![^:]+:)((?:\\./)?(?:\\.\\./)*[^\\.]+).(?:"
66                  + MarkdownParserModule.FILE_EXTENSION
67                  + "|"
68                  + MarkdownParserModule.ALTERNATE_FILE_EXTENSION
69                  + ")(#[^#\\.]*){0,1}$");
70      }
71  
72      /** {@inheritDoc} */
73      @Override
74      public @NotNull ResolvedLink resolveLink(
75              @NotNull Node node, @NotNull LinkResolverBasicContext context, @NotNull ResolvedLink link) {
76          if (link.getLinkType() == LinkType.LINK) {
77              Matcher matcher = this.pattern.matcher(link.getUrl());
78              if (matcher.matches()) {
79                  return link.withStatus(LinkStatus.VALID).withUrl(matcher.replaceAll("$1.html$2"));
80              }
81          }
82  
83          return link;
84      }
85  
86      /**
87       * Factory that creates FlexmarkDoxiaLinkResolver objects.
88       */
89      public static class Factory extends IndependentLinkResolverFactory {
90          @Override
91          public @Nullable Set<Class<?>> getBeforeDependents() {
92              Set<Class<?>> set = new HashSet<>();
93              set.add(WikiLinkLinkResolver.Factory.class);
94              return set;
95          }
96  
97          @Override
98          public @NotNull LinkResolver apply(@NotNull LinkResolverBasicContext context) {
99              return new FlexmarkDoxiaLinkResolver(context);
100         }
101     }
102 }