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 */ 063 public FlexmarkDoxiaLinkResolver() { 064 this.pattern = Pattern.compile("^(?![^:]+:)((?:\\./)?(?:\\.\\./)*[^\\.]+).(?:" 065 + MarkdownParserModule.FILE_EXTENSION 066 + "|" 067 + MarkdownParserModule.ALTERNATE_FILE_EXTENSION 068 + ")(#[^#\\.]*){0,1}$"); 069 } 070 071 @Override 072 public @NotNull ResolvedLink resolveLink( 073 @NotNull Node node, @NotNull LinkResolverBasicContext context, @NotNull ResolvedLink link) { 074 if (link.getLinkType() == LinkType.LINK) { 075 Matcher matcher = this.pattern.matcher(link.getUrl()); 076 if (matcher.matches()) { 077 return link.withStatus(LinkStatus.VALID).withUrl(matcher.replaceAll("$1.html$2")); 078 } 079 } 080 081 return link; 082 } 083 084 /** 085 * Factory that creates FlexmarkDoxiaLinkResolver objects. 086 */ 087 public static class Factory extends IndependentLinkResolverFactory { 088 @Override 089 public @Nullable Set<Class<?>> getBeforeDependents() { 090 Set<Class<?>> set = new HashSet<>(); 091 set.add(WikiLinkLinkResolver.Factory.class); 092 return set; 093 } 094 095 @Override 096 public @NotNull LinkResolver apply(@NotNull LinkResolverBasicContext context) { 097 return new FlexmarkDoxiaLinkResolver(); 098 } 099 } 100}