implemented adding targets to links in markdown

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2026-05-19 09:53:43 +02:00
parent 9bec33d5de
commit aa48bbcbf5
2 changed files with 33 additions and 2 deletions
@@ -3,21 +3,34 @@ package de.srsoftware.umbrella.markdown;
import static de.srsoftware.tools.MimeType.MIME_HTML;
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
import static de.srsoftware.umbrella.core.constants.Field.BASE_URL;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingField;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.configuration.Configuration;
import de.srsoftware.tools.Path;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.ModuleRegistry;
import de.srsoftware.umbrella.core.Util;
import de.srsoftware.umbrella.core.api.MarkdownService;
import de.srsoftware.umbrella.core.constants.Field;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import java.io.IOException;
import java.util.Optional;
import java.util.regex.Pattern;
public class MarkdownApi extends BaseHandler implements MarkdownService {
private static Pattern ANCHOR = Pattern.compile("(?is)<a\\b[^>]*>.*?</a>");
private static Pattern HREF = Pattern.compile("(?i)\\bhref\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+))");
private static Pattern TARGET = Pattern.compile("(?i)\\btarget\\s*=");
private final String baseUrl;
public MarkdownApi() {
public MarkdownApi(Configuration config) {
super();
Optional<String> baseUrl = config.get(BASE_URL);
if (baseUrl.isEmpty()) throw missingField(BASE_URL);
this.baseUrl = baseUrl.get();
ModuleRegistry.add(this);
}
@@ -29,6 +42,24 @@ public class MarkdownApi extends BaseHandler implements MarkdownService {
if (user.isEmpty()) throw UmbrellaException.forbidden("You must be logged in to use the markdown renderer!");
var rendered = Util.markdown(body(ex));
var anchors = ANCHOR.matcher(rendered);
while (anchors.find()){
String anchor = anchors.group();
var urls = HREF.matcher(anchor);
if (!urls.find()) continue; // no url → nothing to do
var href = urls.group(1) != null ? urls.group(1) : (urls.group(2) != null ? urls.group(2) : urls.group(3));
var target = TARGET.matcher(anchor);
if (target.find()) continue; // target already set → leave untouched
if (!href.startsWith("http")) continue; // relative url? good!
if (!href.startsWith(baseUrl)) { // add target
var replacement = "<a target=\"_blank\""+anchor.substring(2);
rendered = rendered.replace(anchor, replacement);
anchors.reset(rendered);
}
}
ex.getResponseHeaders().add(CONTENT_TYPE,MIME_HTML);
return sendContent(ex,rendered);
} catch (UmbrellaException e){