Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.commonmark.ext.autolink;

import java.util.EnumSet;
import java.util.Set;

import org.commonmark.Extension;
import org.commonmark.ext.autolink.internal.AutolinkPostProcessor;
import org.commonmark.parser.Parser;
Expand All @@ -18,16 +21,75 @@
*/
public class AutolinkExtension implements Parser.ParserExtension {

private AutolinkExtension() {
private final Set<AutolinkType> linkTypes;

private AutolinkExtension(Builder builder) {
this.linkTypes = builder.linkTypes;
}

/**
* @return the extension with default options
*/
public static Extension create() {
return new AutolinkExtension();
return builder().build();
}

/**
* @return a builder to configure the behavior of the extension.
*/
public static Builder builder() {
return new Builder();
}

@Override
public void extend(Parser.Builder parserBuilder) {
parserBuilder.postProcessor(new AutolinkPostProcessor());
parserBuilder.postProcessor(new AutolinkPostProcessor(linkTypes));
}

public static class Builder {

private Set<AutolinkType> linkTypes = EnumSet.of(AutolinkType.URL, AutolinkType.EMAIL);

/**
* @param linkTypes the link types that should be converted. By default, {@link AutolinkType#URL}
* and {@link AutolinkType#EMAIL} are converted.
* @return {@code this}
*/
public Builder linkTypes(AutolinkType... linkTypes) {
if (linkTypes == null) {
throw new NullPointerException("linkTypes must not be null");
}

if (linkTypes.length == 0) {
throw new IllegalArgumentException("linkTypes must not be empty");
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to duplicate the checks above if we're delegating to linkTypes(Set<AutolinkType> linkTypes) anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the second check. The first check was just to provide a more explicit error message than whatever is thrown by calling Set.of(null), but I can remove if we think that's unnecessary.


return this.linkTypes(Set.of(linkTypes));
}

/**
* @param linkTypes the link types that should be converted. By default, {@link AutolinkType#URL}
* and {@link AutolinkType#EMAIL} are converted.
* @return {@code this}
*/
public Builder linkTypes(Set<AutolinkType> linkTypes) {
if (linkTypes == null) {
throw new NullPointerException("linkTypes must not be null");
}

if (linkTypes.isEmpty()) {
throw new IllegalArgumentException("linkTypes must not be empty");
}

this.linkTypes = EnumSet.copyOf(linkTypes);
return this;
}

/**
* @return a configured extension
*/
public Extension build() {
return new AutolinkExtension(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.commonmark.ext.autolink;

public enum AutolinkType {
/**
* URL such as {@code http://example.com}
*/
URL,
/**
* Email address such as {@code foo@example.com}
*/
EMAIL,
/**
* URL such as {@code www.example.com}
*/
WWW
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.commonmark.ext.autolink.internal;

import org.commonmark.ext.autolink.AutolinkType;
import org.commonmark.node.*;
import org.commonmark.parser.PostProcessor;
import org.nibor.autolink.LinkExtractor;
Expand All @@ -11,9 +12,40 @@

public class AutolinkPostProcessor implements PostProcessor {

private LinkExtractor linkExtractor = LinkExtractor.builder()
.linkTypes(EnumSet.of(LinkType.URL, LinkType.EMAIL))
.build();
private final LinkExtractor linkExtractor;

public AutolinkPostProcessor() {
this(EnumSet.of(AutolinkType.URL, AutolinkType.EMAIL));
}
Comment thread
rdestefa marked this conversation as resolved.
Outdated

public AutolinkPostProcessor(Set<AutolinkType> linkTypes) {
if (linkTypes == null) {
throw new NullPointerException("linkTypes must not be null");
}

if (linkTypes.isEmpty()) {
throw new IllegalArgumentException("linkTypes must not be empty");
}

EnumSet<LinkType> types = EnumSet.noneOf(LinkType.class);
Comment thread
rdestefa marked this conversation as resolved.
Outdated
for (AutolinkType linkType : linkTypes) {
switch (linkType) {
case URL:
types.add(LinkType.URL);
break;
case EMAIL:
types.add(LinkType.EMAIL);
break;
case WWW:
types.add(LinkType.WWW);
break;
}
}

this.linkExtractor = LinkExtractor.builder()
.linkTypes(types)
.build();
}

@Override
public Node process(Node node) {
Expand Down Expand Up @@ -67,8 +99,12 @@ private static Text createTextNode(String literal, Span span, SourceSpan sourceS
}

private static String getDestination(LinkSpan linkSpan, String linkText) {
if (linkSpan.getType() == LinkType.EMAIL) {
LinkType type = linkSpan.getType();
Comment thread
rdestefa marked this conversation as resolved.
Outdated

if (type == LinkType.EMAIL) {
return "mailto:" + linkText;
} else if (type == LinkType.WWW) {
return "http://" + linkText;
Comment thread
rdestefa marked this conversation as resolved.
} else {
return linkText;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public class AutolinkTest extends RenderingTestCase {
private static final Parser PARSER = Parser.builder().extensions(EXTENSIONS).build();
private static final HtmlRenderer RENDERER = HtmlRenderer.builder().extensions(EXTENSIONS).build();

private static final Set<Extension> WWW_EXTENSIONS = Set.of(AutolinkExtension.builder()
.linkTypes(AutolinkType.URL, AutolinkType.EMAIL, AutolinkType.WWW)
.build());
private static final Parser WWW_PARSER = Parser.builder().extensions(WWW_EXTENSIONS).build();
private static final HtmlRenderer WWW_RENDERER = HtmlRenderer.builder().extensions(WWW_EXTENSIONS).build();

@Test
public void oneTextNode() {
assertRendering("foo http://one.org/ bar http://two.org/",
Expand Down Expand Up @@ -57,6 +63,18 @@ public void dontLinkTextWithinLinks() {
"<p><a href=\"http://example.com\">http://example.com</a></p>\n");
}

@Test
public void wwwLinksDontWorkByDefault() {
assertRendering("www.example.com",
"<p>www.example.com</p>\n");
}

@Test
public void wwwLinks() {
String html = WWW_RENDERER.render(WWW_PARSER.parse("www.example.com"));
assertThat(html).isEqualTo("<p><a href=\"http://www.example.com\">www.example.com</a></p>\n");
}

@Test
public void sourceSpans() {
Parser parser = Parser.builder()
Expand Down