Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 7 additions & 0 deletions .idea/google-java-format.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,19 @@

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

import org.commonmark.Extension;
import org.commonmark.ext.autolink.internal.AutolinkPostProcessor;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;

/**
* Extension for automatically turning plain URLs and email addresses into links.
* <p>
* Create it with {@link #create()} and then configure it on the builders
* ({@link org.commonmark.parser.Parser.Builder#extensions(Iterable)},
* {@link HtmlRenderer.Builder#extensions(Iterable)}).
* </p>
* <p>
* The parsed links are turned into normal {@link org.commonmark.node.Link} nodes.
* </p>
*
* <p>Create it with {@link #create()} and then configure it on the builders ({@link
* org.commonmark.parser.Parser.Builder#extensions(Iterable)}, {@link
* HtmlRenderer.Builder#extensions(Iterable)}).
*
* <p>The parsed links are turned into normal {@link org.commonmark.node.Link} nodes.
*/
public class AutolinkExtension implements Parser.ParserExtension {

Expand Down Expand Up @@ -51,8 +48,8 @@ public static class Builder {
private Set<AutolinkType> linkTypes = EnumSet.allOf(AutolinkType.class);

/**
* @param linkTypes the link types that should be converted. By default,
* all {@link AutolinkType}s are converted.
* @param linkTypes the link types that should be converted. By default, all {@link
* AutolinkType}s are converted.
* @return {@code this}
*/
public Builder linkTypes(AutolinkType... linkTypes) {
Expand All @@ -64,8 +61,8 @@ public Builder linkTypes(AutolinkType... linkTypes) {
}

/**
* @param linkTypes the link types that should be converted. By default,
* all {@link AutolinkType}s are converted.
* @param linkTypes the link types that should be converted. By default, all {@link
* AutolinkType}s are converted.
* @return {@code this}
*/
public Builder linkTypes(Set<AutolinkType> linkTypes) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
package org.commonmark.ext.autolink;

/**
* The types of strings that can be automatically turned into links.
*/
/** The types of strings that can be automatically turned into links. */
public enum AutolinkType {
/**
* URL such as {@code http://example.com}
*/
/** URL such as {@code http://example.com} */
URL,
/**
* Email address such as {@code foo@example.com}
*/
/** Email address such as {@code foo@example.com} */
EMAIL,
/**
* URL such as {@code www.example.com}
*/
/** 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 java.util.*;
import org.commonmark.ext.autolink.AutolinkType;
import org.commonmark.node.*;
import org.commonmark.parser.PostProcessor;
Expand All @@ -8,8 +9,6 @@
import org.nibor.autolink.LinkType;
import org.nibor.autolink.Span;

import java.util.*;

public class AutolinkPostProcessor implements PostProcessor {

private final LinkExtractor linkExtractor;
Expand Down Expand Up @@ -38,9 +37,7 @@ public AutolinkPostProcessor(Set<AutolinkType> linkTypes) {
}
}

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

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.commonmark.ext.autolink;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.Set;
import org.commonmark.Extension;
import org.commonmark.node.*;
import org.commonmark.parser.IncludeSourceSpans;
Expand All @@ -8,64 +12,69 @@
import org.commonmark.testutil.RenderingTestCase;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;

public class AutolinkTest extends RenderingTestCase {

private static final Set<Extension> EXTENSIONS = Set.of(AutolinkExtension.create());
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> NO_WWW_EXTENSIONS = Set.of(AutolinkExtension.builder()
.linkTypes(AutolinkType.URL, AutolinkType.EMAIL)
.build());
private static final Parser NO_WWW_PARSER = Parser.builder().extensions(NO_WWW_EXTENSIONS).build();
private static final HtmlRenderer NO_WWW_RENDERER = HtmlRenderer.builder().extensions(NO_WWW_EXTENSIONS).build();
private static final HtmlRenderer RENDERER =
HtmlRenderer.builder().extensions(EXTENSIONS).build();

private static final Set<Extension> NO_WWW_EXTENSIONS =
Set.of(
AutolinkExtension.builder()
.linkTypes(AutolinkType.URL, AutolinkType.EMAIL)
.build());
private static final Parser NO_WWW_PARSER =
Parser.builder().extensions(NO_WWW_EXTENSIONS).build();
private static final HtmlRenderer NO_WWW_RENDERER =
HtmlRenderer.builder().extensions(NO_WWW_EXTENSIONS).build();

@Test
public void oneTextNode() {
assertRendering("foo http://one.org/ bar http://two.org/",
assertRendering(
"foo http://one.org/ bar http://two.org/",
"<p>foo <a href=\"http://one.org/\">http://one.org/</a> bar <a href=\"http://two.org/\">http://two.org/</a></p>\n");
}

@Test
public void textNodeAndOthers() {
assertRendering("foo http://one.org/ bar `code` baz http://two.org/",
assertRendering(
"foo http://one.org/ bar `code` baz http://two.org/",
"<p>foo <a href=\"http://one.org/\">http://one.org/</a> bar <code>code</code> baz <a href=\"http://two.org/\">http://two.org/</a></p>\n");
}

@Test
public void tricky() {
assertRendering("http://example.com/one. Example 2 (see http://example.com/two). Example 3: http://example.com/foo_(bar)",
"<p><a href=\"http://example.com/one\">http://example.com/one</a>. " +
"Example 2 (see <a href=\"http://example.com/two\">http://example.com/two</a>). " +
"Example 3: <a href=\"http://example.com/foo_(bar)\">http://example.com/foo_(bar)</a></p>\n");
assertRendering(
"http://example.com/one. Example 2 (see http://example.com/two). Example 3: http://example.com/foo_(bar)",
"<p><a href=\"http://example.com/one\">http://example.com/one</a>. "
+ "Example 2 (see <a href=\"http://example.com/two\">http://example.com/two</a>). "
+ "Example 3: <a href=\"http://example.com/foo_(bar)\">http://example.com/foo_(bar)</a></p>\n");
}

@Test
public void emailUsesMailto() {
assertRendering("foo@example.com",
assertRendering(
"foo@example.com",
"<p><a href=\"mailto:foo@example.com\">foo@example.com</a></p>\n");
}

@Test
public void emailWithTldNotLinked() {
assertRendering("foo@com",
"<p>foo@com</p>\n");
assertRendering("foo@com", "<p>foo@com</p>\n");
}

@Test
public void dontLinkTextWithinLinks() {
assertRendering("<http://example.com>",
assertRendering(
"<http://example.com>",
"<p><a href=\"http://example.com\">http://example.com</a></p>\n");
}

@Test
public void wwwLinks() {
assertRendering("www.example.com",
assertRendering(
"www.example.com",
"<p><a href=\"http://www.example.com\">www.example.com</a></p>\n");
}

Expand All @@ -77,14 +86,17 @@ public void noWwwLinks() {

@Test
public void sourceSpans() {
Parser parser = Parser.builder()
.extensions(EXTENSIONS)
.includeSourceSpans(IncludeSourceSpans.BLOCKS_AND_INLINES)
.build();
Node document = parser.parse("abc\n" +
"http://example.com/one\n" +
"def http://example.com/two\n" +
"ghi http://example.com/three jkl");
Parser parser =
Parser.builder()
.extensions(EXTENSIONS)
.includeSourceSpans(IncludeSourceSpans.BLOCKS_AND_INLINES)
.build();
Node document =
parser.parse(
"abc\n"
+ "http://example.com/one\n"
+ "def http://example.com/two\n"
+ "ghi http://example.com/three jkl");

Paragraph paragraph = (Paragraph) document.getFirstChild();
Text abc = (Text) paragraph.getFirstChild();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@

/**
* A footnote definition, e.g.:
*
* <pre><code>
* [^foo]: This is the footnote text
* </code></pre>
* The {@link #getLabel() label} is the text in brackets after {@code ^}, so {@code foo} in the example. The contents
* of the footnote are child nodes of the definition, a {@link org.commonmark.node.Paragraph} in the example.
* <p>
* Footnote definitions are parsed even if there's no corresponding {@link FootnoteReference}.
*
* The {@link #getLabel() label} is the text in brackets after {@code ^}, so {@code foo} in the
* example. The contents of the footnote are child nodes of the definition, a {@link
* org.commonmark.node.Paragraph} in the example.
*
* <p>Footnote definitions are parsed even if there's no corresponding {@link FootnoteReference}.
*/
public class FootnoteDefinition extends CustomBlock {

Expand All @@ -24,4 +27,3 @@ public String getLabel() {
return label;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

/**
* A footnote reference, e.g. <code>[^foo]</code> in <code>Some text with a footnote[^foo]</code>
* <p>
* The {@link #getLabel() label} is the text within brackets after {@code ^}, so {@code foo} in the example. It needs to
* match the label of a corresponding {@link FootnoteDefinition} for the footnote to be parsed.
*
* <p>The {@link #getLabel() label} is the text within brackets after {@code ^}, so {@code foo} in
* the example. It needs to match the label of a corresponding {@link FootnoteDefinition} for the
* footnote to be parsed.
*/
public class FootnoteReference extends CustomNode {
private String label;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.commonmark.ext.footnotes;

import java.util.Set;
import org.commonmark.Extension;
import org.commonmark.ext.footnotes.internal.*;
import org.commonmark.parser.Parser;
Expand All @@ -9,42 +10,45 @@
import org.commonmark.renderer.markdown.MarkdownNodeRendererFactory;
import org.commonmark.renderer.markdown.MarkdownRenderer;

import java.util.Set;

/**
* Extension for footnotes with syntax like GitHub Flavored Markdown:
*
* <pre><code>
* Some text with a footnote[^1].
*
* [^1]: The text of the footnote.
* </code></pre>
*
* The <code>[^1]</code> is a {@link FootnoteReference}, with "1" being the label.
* <p>
* The line with <code>[^1]: ...</code> is a {@link FootnoteDefinition}, with the contents as child nodes (can be a
* paragraph like in the example, or other blocks like lists).
* <p>
* All the footnotes (definitions) will be rendered in a list at the end of a document, no matter where they appear in
* the source. The footnotes will be numbered starting from 1, then 2, etc, depending on the order in which they appear
* in the text (and not dependent on the label). The footnote reference is a link to the footnote, and from the footnote
* there is a link back to the reference (or multiple).
* <p>
* There is also optional support for inline footnotes, use {@link #builder()} and then set {@link Builder#inlineFootnotes}.
*
* @see <a href="https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#footnotes">GitHub docs for footnotes</a>
* <p>The line with <code>[^1]: ...</code> is a {@link FootnoteDefinition}, with the contents as
* child nodes (can be a paragraph like in the example, or other blocks like lists).
*
* <p>All the footnotes (definitions) will be rendered in a list at the end of a document, no matter
* where they appear in the source. The footnotes will be numbered starting from 1, then 2, etc,
* depending on the order in which they appear in the text (and not dependent on the label). The
* footnote reference is a link to the footnote, and from the footnote there is a link back to the
* reference (or multiple).
*
* <p>There is also optional support for inline footnotes, use {@link #builder()} and then set
* {@link Builder#inlineFootnotes}.
*
* @see <a
* href="https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#footnotes">GitHub
* docs for footnotes</a>
*/
public class FootnotesExtension implements Parser.ParserExtension,
HtmlRenderer.HtmlRendererExtension,
MarkdownRenderer.MarkdownRendererExtension {
public class FootnotesExtension
implements Parser.ParserExtension,
HtmlRenderer.HtmlRendererExtension,
MarkdownRenderer.MarkdownRendererExtension {

private final boolean inlineFootnotes;

private FootnotesExtension(boolean inlineFootnotes) {
this.inlineFootnotes = inlineFootnotes;
}

/**
* The extension with the default configuration (no support for inline footnotes).
*/
/** The extension with the default configuration (no support for inline footnotes). */
public static Extension create() {
return builder().build();
}
Expand All @@ -70,17 +74,18 @@ public void extend(HtmlRenderer.Builder rendererBuilder) {

@Override
public void extend(MarkdownRenderer.Builder rendererBuilder) {
rendererBuilder.nodeRendererFactory(new MarkdownNodeRendererFactory() {
@Override
public NodeRenderer create(MarkdownNodeRendererContext context) {
return new FootnoteMarkdownNodeRenderer(context);
}
rendererBuilder.nodeRendererFactory(
new MarkdownNodeRendererFactory() {
@Override
public NodeRenderer create(MarkdownNodeRendererContext context) {
return new FootnoteMarkdownNodeRenderer(context);
}

@Override
public Set<Character> getSpecialCharacters() {
return Set.of();
}
});
@Override
public Set<Character> getSpecialCharacters() {
return Set.of();
}
});
}

public static class Builder {
Expand All @@ -89,6 +94,7 @@ public static class Builder {

/**
* Enable support for inline footnotes without definitions, e.g.:
*
* <pre>
* Some text^[this is an inline footnote]
* </pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@

import org.commonmark.node.CustomNode;

public class InlineFootnote extends CustomNode {
}
public class InlineFootnote extends CustomNode {}
Loading
Loading