Skip to content

Commit 3208a83

Browse files
committed
Allow Detection of WWW Autolinks
1 parent 24ddb2e commit 3208a83

File tree

4 files changed

+139
-7
lines changed

4 files changed

+139
-7
lines changed

commonmark-ext-autolink/src/main/java/org/commonmark/ext/autolink/AutolinkExtension.java

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.commonmark.ext.autolink;
22

3+
import java.util.EnumSet;
4+
import java.util.Set;
5+
36
import org.commonmark.Extension;
47
import org.commonmark.ext.autolink.internal.AutolinkPostProcessor;
58
import org.commonmark.parser.Parser;
@@ -18,16 +21,75 @@
1821
*/
1922
public class AutolinkExtension implements Parser.ParserExtension {
2023

21-
private AutolinkExtension() {
24+
private final Set<AutolinkType> linkTypes;
25+
26+
private AutolinkExtension(Builder builder) {
27+
this.linkTypes = builder.linkTypes;
2228
}
2329

30+
/**
31+
* @return the extension with default options
32+
*/
2433
public static Extension create() {
25-
return new AutolinkExtension();
34+
return builder().build();
35+
}
36+
37+
/**
38+
* @return a builder to configure the behavior of the extension.
39+
*/
40+
public static Builder builder() {
41+
return new Builder();
2642
}
2743

2844
@Override
2945
public void extend(Parser.Builder parserBuilder) {
30-
parserBuilder.postProcessor(new AutolinkPostProcessor());
46+
parserBuilder.postProcessor(new AutolinkPostProcessor(linkTypes));
3147
}
3248

49+
public static class Builder {
50+
51+
private Set<AutolinkType> linkTypes = EnumSet.of(AutolinkType.URL, AutolinkType.EMAIL);
52+
53+
/**
54+
* @param linkTypes the link types that should be converted. By default, {@link AutolinkType#URL}
55+
* and {@link AutolinkType#EMAIL} are converted.
56+
* @return {@code this}
57+
*/
58+
public Builder linkTypes(AutolinkType... linkTypes) {
59+
if (linkTypes == null) {
60+
throw new NullPointerException("linkTypes must not be null");
61+
}
62+
63+
if (linkTypes.length == 0) {
64+
throw new IllegalArgumentException("linkTypes must not be empty");
65+
}
66+
67+
return this.linkTypes(Set.of(linkTypes));
68+
}
69+
70+
/**
71+
* @param linkTypes the link types that should be converted. By default, {@link AutolinkType#URL}
72+
* and {@link AutolinkType#EMAIL} are converted.
73+
* @return {@code this}
74+
*/
75+
public Builder linkTypes(Set<AutolinkType> linkTypes) {
76+
if (linkTypes == null) {
77+
throw new NullPointerException("linkTypes must not be null");
78+
}
79+
80+
if (linkTypes.isEmpty()) {
81+
throw new IllegalArgumentException("linkTypes must not be empty");
82+
}
83+
84+
this.linkTypes = EnumSet.copyOf(linkTypes);
85+
return this;
86+
}
87+
88+
/**
89+
* @return a configured extension
90+
*/
91+
public Extension build() {
92+
return new AutolinkExtension(this);
93+
}
94+
}
3395
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.commonmark.ext.autolink;
2+
3+
public enum AutolinkType {
4+
/**
5+
* URL such as {@code http://example.com}
6+
*/
7+
URL,
8+
/**
9+
* Email address such as {@code [email protected]}
10+
*/
11+
EMAIL,
12+
/**
13+
* URL such as {@code www.example.com}
14+
*/
15+
WWW
16+
}

commonmark-ext-autolink/src/main/java/org/commonmark/ext/autolink/internal/AutolinkPostProcessor.java

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.commonmark.ext.autolink.internal;
22

3+
import org.commonmark.ext.autolink.AutolinkType;
34
import org.commonmark.node.*;
45
import org.commonmark.parser.PostProcessor;
56
import org.nibor.autolink.LinkExtractor;
@@ -11,9 +12,40 @@
1112

1213
public class AutolinkPostProcessor implements PostProcessor {
1314

14-
private LinkExtractor linkExtractor = LinkExtractor.builder()
15-
.linkTypes(EnumSet.of(LinkType.URL, LinkType.EMAIL))
16-
.build();
15+
private final LinkExtractor linkExtractor;
16+
17+
public AutolinkPostProcessor() {
18+
this(EnumSet.of(AutolinkType.URL, AutolinkType.EMAIL));
19+
}
20+
21+
public AutolinkPostProcessor(Set<AutolinkType> linkTypes) {
22+
if (linkTypes == null) {
23+
throw new NullPointerException("linkTypes must not be null");
24+
}
25+
26+
if (linkTypes.isEmpty()) {
27+
throw new IllegalArgumentException("linkTypes must not be empty");
28+
}
29+
30+
EnumSet<LinkType> types = EnumSet.noneOf(LinkType.class);
31+
for (AutolinkType linkType : linkTypes) {
32+
switch (linkType) {
33+
case URL:
34+
types.add(LinkType.URL);
35+
break;
36+
case EMAIL:
37+
types.add(LinkType.EMAIL);
38+
break;
39+
case WWW:
40+
types.add(LinkType.WWW);
41+
break;
42+
}
43+
}
44+
45+
this.linkExtractor = LinkExtractor.builder()
46+
.linkTypes(types)
47+
.build();
48+
}
1749

1850
@Override
1951
public Node process(Node node) {
@@ -67,8 +99,12 @@ private static Text createTextNode(String literal, Span span, SourceSpan sourceS
6799
}
68100

69101
private static String getDestination(LinkSpan linkSpan, String linkText) {
70-
if (linkSpan.getType() == LinkType.EMAIL) {
102+
LinkType type = linkSpan.getType();
103+
104+
if (type == LinkType.EMAIL) {
71105
return "mailto:" + linkText;
106+
} else if (type == LinkType.WWW) {
107+
return "http://" + linkText;
72108
} else {
73109
return linkText;
74110
}

commonmark-ext-autolink/src/test/java/org/commonmark/ext/autolink/AutolinkTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ public class AutolinkTest extends RenderingTestCase {
1919
private static final Parser PARSER = Parser.builder().extensions(EXTENSIONS).build();
2020
private static final HtmlRenderer RENDERER = HtmlRenderer.builder().extensions(EXTENSIONS).build();
2121

22+
private static final Set<Extension> WWW_EXTENSIONS = Set.of(AutolinkExtension.builder()
23+
.linkTypes(AutolinkType.URL, AutolinkType.EMAIL, AutolinkType.WWW)
24+
.build());
25+
private static final Parser WWW_PARSER = Parser.builder().extensions(WWW_EXTENSIONS).build();
26+
private static final HtmlRenderer WWW_RENDERER = HtmlRenderer.builder().extensions(WWW_EXTENSIONS).build();
27+
2228
@Test
2329
public void oneTextNode() {
2430
assertRendering("foo http://one.org/ bar http://two.org/",
@@ -57,6 +63,18 @@ public void dontLinkTextWithinLinks() {
5763
"<p><a href=\"http://example.com\">http://example.com</a></p>\n");
5864
}
5965

66+
@Test
67+
public void wwwLinksDontWorkByDefault() {
68+
assertRendering("www.example.com",
69+
"<p>www.example.com</p>\n");
70+
}
71+
72+
@Test
73+
public void wwwLinks() {
74+
String html = WWW_RENDERER.render(WWW_PARSER.parse("www.example.com"));
75+
assertThat(html).isEqualTo("<p><a href=\"http://www.example.com\">www.example.com</a></p>\n");
76+
}
77+
6078
@Test
6179
public void sourceSpans() {
6280
Parser parser = Parser.builder()

0 commit comments

Comments
 (0)