diff --git a/README.md b/README.md index 190ba6dc..fc98ce31 100644 --- a/README.md +++ b/README.md @@ -313,6 +313,20 @@ HtmlRenderer renderer = HtmlRenderer.builder() To configure another extension in the above example, just add it to the list. +To enable tables, strikethrough, autolinks, task list items, alerts, and footnotes +together, use the `org.commonmark:commonmark-ext-github` dependency. Pass its preset +to both builders: + +```java +import org.commonmark.ext.github.GitHubExtensions; + +List extensions = GitHubExtensions.create(); +Parser parser = Parser.builder().extensions(extensions).build(); +HtmlRenderer renderer = HtmlRenderer.builder().extensions(extensions).build(); +``` + +Other extensions can still be enabled individually. + The following extensions are developed with this library, each in their own artifact. diff --git a/commonmark-android-test/app/build.gradle b/commonmark-android-test/app/build.gradle index 30b7cce8..2f5d1292 100644 --- a/commonmark-android-test/app/build.gradle +++ b/commonmark-android-test/app/build.gradle @@ -36,10 +36,14 @@ android { [ '../../commonmark', '../../commonmark-ext-autolink', + '../../commonmark-ext-footnotes', + '../../commonmark-ext-gfm-alerts', '../../commonmark-ext-gfm-strikethrough', '../../commonmark-ext-gfm-tables', + '../../commonmark-ext-github', '../../commonmark-ext-heading-anchor', '../../commonmark-ext-ins', + '../../commonmark-ext-task-list-items', '../../commonmark-ext-yaml-front-matter' ].forEach { d -> // don't include module-info files, otherwise we get diff --git a/commonmark-ext-gfm-alerts/src/main/java/org/commonmark/ext/gfm/alerts/AlertsExtension.java b/commonmark-ext-gfm-alerts/src/main/java/org/commonmark/ext/gfm/alerts/AlertsExtension.java index 9c451585..f2f94e91 100644 --- a/commonmark-ext-gfm-alerts/src/main/java/org/commonmark/ext/gfm/alerts/AlertsExtension.java +++ b/commonmark-ext-gfm-alerts/src/main/java/org/commonmark/ext/gfm/alerts/AlertsExtension.java @@ -63,13 +63,17 @@ public class AlertsExtension * The standard GitHub Flavored Markdown (GFM) types that the extension enables by default. * These can be overwritten with {@link Builder#setAllowedTypes(Map)}. */ - public static final Map STANDARD_TYPES = - Map.ofEntries( - Map.entry("NOTE", "Note"), - Map.entry("TIP", "Tip"), - Map.entry("IMPORTANT", "Important"), - Map.entry("WARNING", "Warning"), - Map.entry("CAUTION", "Caution")); + public static final Map STANDARD_TYPES; + + static { + Map types = new HashMap<>(); + types.put("NOTE", "Note"); + types.put("TIP", "Tip"); + types.put("IMPORTANT", "Important"); + types.put("WARNING", "Warning"); + types.put("CAUTION", "Caution"); + STANDARD_TYPES = Collections.unmodifiableMap(types); + } /** A map of alert marker ({@code [!TYPE]}) to the default title for that marker. */ private final Map allowedTypes; diff --git a/commonmark-ext-github/pom.xml b/commonmark-ext-github/pom.xml new file mode 100644 index 00000000..a67e97bb --- /dev/null +++ b/commonmark-ext-github/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + + org.commonmark + commonmark-parent + 0.32.1-SNAPSHOT + + + commonmark-ext-github + commonmark-java GitHub extensions + A bundle of extensions for GitHub Markdown features + + + + org.commonmark + commonmark + + + org.commonmark + commonmark-ext-autolink + + + org.commonmark + commonmark-ext-footnotes + + + org.commonmark + commonmark-ext-gfm-alerts + + + org.commonmark + commonmark-ext-gfm-strikethrough + + + org.commonmark + commonmark-ext-gfm-tables + + + org.commonmark + commonmark-ext-task-list-items + + + diff --git a/commonmark-ext-github/src/main/java/module-info.java b/commonmark-ext-github/src/main/java/module-info.java new file mode 100644 index 00000000..862d5663 --- /dev/null +++ b/commonmark-ext-github/src/main/java/module-info.java @@ -0,0 +1,11 @@ +module org.commonmark.ext.github { + exports org.commonmark.ext.github; + + requires transitive org.commonmark; + requires org.commonmark.ext.autolink; + requires org.commonmark.ext.footnotes; + requires org.commonmark.ext.gfm.alerts; + requires org.commonmark.ext.gfm.strikethrough; + requires org.commonmark.ext.gfm.tables; + requires org.commonmark.ext.task.list.items; +} diff --git a/commonmark-ext-github/src/main/java/org/commonmark/ext/github/GitHubExtensions.java b/commonmark-ext-github/src/main/java/org/commonmark/ext/github/GitHubExtensions.java new file mode 100644 index 00000000..ac6d72fa --- /dev/null +++ b/commonmark-ext-github/src/main/java/org/commonmark/ext/github/GitHubExtensions.java @@ -0,0 +1,34 @@ +package org.commonmark.ext.github; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.commonmark.Extension; +import org.commonmark.ext.autolink.AutolinkExtension; +import org.commonmark.ext.footnotes.FootnotesExtension; +import org.commonmark.ext.gfm.alerts.AlertsExtension; +import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension; +import org.commonmark.ext.gfm.tables.TablesExtension; +import org.commonmark.ext.task.list.items.TaskListItemsExtension; + +/** A preset for tables, strikethrough, autolinks, task lists, alerts and footnotes. */ +public final class GitHubExtensions { + private GitHubExtensions() {} + + /** + * Creates the extensions with their default settings. Use the same list when building the + * parser and renderer. + * + * @return an unmodifiable list of extensions + */ + public static List create() { + return Collections.unmodifiableList( + Arrays.asList( + AutolinkExtension.create(), + FootnotesExtension.create(), + AlertsExtension.create(), + StrikethroughExtension.create(), + TablesExtension.create(), + TaskListItemsExtension.create())); + } +} diff --git a/commonmark-ext-github/src/main/java/org/commonmark/ext/github/package-info.java b/commonmark-ext-github/src/main/java/org/commonmark/ext/github/package-info.java new file mode 100644 index 00000000..b9fac00d --- /dev/null +++ b/commonmark-ext-github/src/main/java/org/commonmark/ext/github/package-info.java @@ -0,0 +1,2 @@ +/** A preset for Markdown features supported by GitHub. */ +package org.commonmark.ext.github; diff --git a/commonmark-integration-test/pom.xml b/commonmark-integration-test/pom.xml index 1808731d..36d21122 100644 --- a/commonmark-integration-test/pom.xml +++ b/commonmark-integration-test/pom.xml @@ -16,6 +16,10 @@ org.commonmark commonmark + + org.commonmark + commonmark-ext-github + org.commonmark commonmark-ext-autolink diff --git a/commonmark-integration-test/src/test/java/org/commonmark/integration/GitHubExtensionsTest.java b/commonmark-integration-test/src/test/java/org/commonmark/integration/GitHubExtensionsTest.java new file mode 100644 index 00000000..367d20fb --- /dev/null +++ b/commonmark-integration-test/src/test/java/org/commonmark/integration/GitHubExtensionsTest.java @@ -0,0 +1,85 @@ +package org.commonmark.integration; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import org.commonmark.Extension; +import org.commonmark.ext.autolink.AutolinkExtension; +import org.commonmark.ext.footnotes.FootnotesExtension; +import org.commonmark.ext.gfm.alerts.AlertsExtension; +import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension; +import org.commonmark.ext.gfm.tables.TablesExtension; +import org.commonmark.ext.github.GitHubExtensions; +import org.commonmark.ext.task.list.items.TaskListItemsExtension; +import org.commonmark.parser.Parser; +import org.commonmark.renderer.html.HtmlRenderer; +import org.junit.jupiter.api.Test; + +class GitHubExtensionsTest { + @Test + void rendersTheSixBundledFeaturesTogether() { + String markdown = + """ + | column | + | ------ | + | ~~old~~ | + + - [x] See https://example.com + + > [!NOTE] + > See the note[^one]. + + [^one]: A footnote. + """; + List manual = + List.of( + AutolinkExtension.create(), + FootnotesExtension.create(), + AlertsExtension.create(), + StrikethroughExtension.create(), + TablesExtension.create(), + TaskListItemsExtension.create()); + List preset = GitHubExtensions.create(); + assertEquals( + manual.stream().map(Object::getClass).toList(), + preset.stream().map(Object::getClass).toList()); + String html = render(markdown, preset); + assertEquals(render(markdown, manual), html); + for (String feature : + List.of( + "column", + "old", + "type=\"checkbox\"", + "", + "markdown-alert-note", + "class=\"footnote-ref\"")) { + assertTrue(html.contains(feature), feature); + } + } + + @Test + void preservesCoreRenderingForOtherExtensions() { + String markdown = + """ + --- + title: example + --- + + # Heading + + ++insert++ ![text](/img.png){width=6} + """; + assertEquals(render(markdown, List.of()), render(markdown, GitHubExtensions.create())); + } + + @Test + void callersCannotChangeThePreset() { + assertThrows(UnsupportedOperationException.class, () -> GitHubExtensions.create().clear()); + assertEquals(6, GitHubExtensions.create().size()); + } + + private static String render(String markdown, List extensions) { + Parser parser = Parser.builder().extensions(extensions).build(); + return HtmlRenderer.builder().extensions(extensions).build().render(parser.parse(markdown)); + } +} diff --git a/pom.xml b/pom.xml index eebe2deb..14b5027a 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ commonmark-ext-gfm-alerts commonmark-ext-gfm-strikethrough commonmark-ext-gfm-tables + commonmark-ext-github commonmark-ext-heading-anchor commonmark-ext-image-attributes commonmark-ext-ins @@ -183,6 +184,11 @@ commonmark-ext-gfm-tables 0.32.1-SNAPSHOT + + org.commonmark + commonmark-ext-github + 0.32.1-SNAPSHOT + org.commonmark commonmark-ext-heading-anchor