001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.doxia.module.markdown; 020 021import java.util.HashSet; 022import java.util.Set; 023import java.util.regex.Matcher; 024import java.util.regex.Pattern; 025 026import com.vladsch.flexmark.ext.wikilink.internal.WikiLinkLinkResolver; 027import com.vladsch.flexmark.html.IndependentLinkResolverFactory; 028import com.vladsch.flexmark.html.LinkResolver; 029import com.vladsch.flexmark.html.renderer.LinkResolverBasicContext; 030import com.vladsch.flexmark.html.renderer.LinkStatus; 031import com.vladsch.flexmark.html.renderer.LinkType; 032import com.vladsch.flexmark.html.renderer.ResolvedLink; 033import com.vladsch.flexmark.util.ast.Node; 034import org.jetbrains.annotations.NotNull; 035import org.jetbrains.annotations.Nullable; 036 037/** 038 * The FlexmarkDoxiaLinkResolver rewrites the md, markdown links to html. 039 * 040 * Sample links it rewrites: 041 * - doc.md to doc.html 042 * - doc.markdown to doc.html 043 * - doc.md#anchor to doc.html#anchor 044 * - doc.markdown#anchor to doc.html#anchor 045 * - ../doc.markdown#anchor to ../doc.html#anchor 046 * - :doc.md to :doc.html 047 * - :doc.markdown to :doc.html 048 * 049 * Sample links it leaves untouched: 050 * - http://doc.md 051 * - https://doc.markdown 052 * - doc.md.badformat 053 * - doc.md#bad#format 054 * - doc.md#bad.format 055 */ 056public class FlexmarkDoxiaLinkResolver implements LinkResolver { 057 final Pattern pattern; 058 059 /** 060 * <p>Constructor for FlexmarkDoxiaLinkResolver.</p> 061 * 062 * @param context a {@link com.vladsch.flexmark.html.renderer.LinkResolverContext} object. 063 */ 064 public FlexmarkDoxiaLinkResolver(@NotNull LinkResolverBasicContext context) { 065 this.pattern = Pattern.compile("^(?![^:]+:)((?:\\./)?(?:\\.\\./)*[^\\.]+).(?:" 066 + MarkdownParserModule.FILE_EXTENSION 067 + "|" 068 + MarkdownParserModule.ALTERNATE_FILE_EXTENSION 069 + ")(#[^#\\.]*){0,1}$"); 070 } 071 072 /** {@inheritDoc} */ 073 @Override 074 public @NotNull ResolvedLink resolveLink( 075 @NotNull Node node, @NotNull LinkResolverBasicContext context, @NotNull ResolvedLink link) { 076 if (link.getLinkType() == LinkType.LINK) { 077 Matcher matcher = this.pattern.matcher(link.getUrl()); 078 if (matcher.matches()) { 079 return link.withStatus(LinkStatus.VALID).withUrl(matcher.replaceAll("$1.html$2")); 080 } 081 } 082 083 return link; 084 } 085 086 /** 087 * Factory that creates FlexmarkDoxiaLinkResolver objects. 088 */ 089 public static class Factory extends IndependentLinkResolverFactory { 090 @Override 091 public @Nullable Set<Class<?>> getBeforeDependents() { 092 Set<Class<?>> set = new HashSet<>(); 093 set.add(WikiLinkLinkResolver.Factory.class); 094 return set; 095 } 096 097 @Override 098 public @NotNull LinkResolver apply(@NotNull LinkResolverBasicContext context) { 099 return new FlexmarkDoxiaLinkResolver(context); 100 } 101 } 102}