From 20dd28787bc82804da2e86e33d7bf3a11db9ed9b Mon Sep 17 00:00:00 2001 From: Christian Grubert Date: Sun, 2 Nov 2025 16:40:48 +0100 Subject: [PATCH] Add more configuration options for flexmark --- CHANGES.md | 2 + .../glue/markdown/FlexmarkFormatterFunc.java | 100 +++++++++++++++--- .../spotless/markdown/FlexmarkConfig.java | 56 ++++++++++ .../spotless/markdown/FlexmarkStep.java | 22 ++-- plugin-gradle/CHANGES.md | 2 + plugin-gradle/README.md | 8 +- .../gradle/spotless/FlexmarkExtension.java | 27 ++++- .../spotless/FlexmarkExtensionTest.java | 30 +++++- plugin-maven/README.md | 13 ++- .../spotless/maven/markdown/Flexmark.java | 24 ++++- .../maven/markdown/FlexmarkMavenTest.java | 15 ++- .../markdown/flexmark/FlexmarkFormatted.md | 5 + .../markdown/flexmark/FlexmarkUnformatted.md | 4 + .../spotless/markdown/FlexmarkStepTest.java | 10 +- 14 files changed, 284 insertions(+), 34 deletions(-) create mode 100644 lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkConfig.java diff --git a/CHANGES.md b/CHANGES.md index 704c7b9364..a1fafc0062 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( * Bump default `ktfmt` version to latest `0.58` -> `0.59`. ([#2681](https://github.com/diffplug/spotless/pull/2681) ### Fixed - palantirJavaFormat is no longer arbitrarily set to outdated versions on Java 17, latest available version is always used ([#2686](https://github.com/diffplug/spotless/pull/2686) fixes [#2685](https://github.com/diffplug/spotless/issues/2685)) +### Added +- new options to customize Flexmark, e.g. to allow YAML front matter ([#2616](https://github.com/diffplug/spotless/issues/2616)) ## [4.0.0] - 2025-09-24 ### Changes diff --git a/lib/src/flexmark/java/com/diffplug/spotless/glue/markdown/FlexmarkFormatterFunc.java b/lib/src/flexmark/java/com/diffplug/spotless/glue/markdown/FlexmarkFormatterFunc.java index dccb4fee7c..072b958580 100644 --- a/lib/src/flexmark/java/com/diffplug/spotless/glue/markdown/FlexmarkFormatterFunc.java +++ b/lib/src/flexmark/java/com/diffplug/spotless/glue/markdown/FlexmarkFormatterFunc.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 DiffPlug + * Copyright 2021-2025 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,12 @@ */ package com.diffplug.spotless.glue.markdown; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import com.vladsch.flexmark.formatter.Formatter; import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.parser.ParserEmulationProfile; @@ -23,32 +29,50 @@ import com.vladsch.flexmark.util.ast.Document; import com.vladsch.flexmark.util.data.MutableDataHolder; import com.vladsch.flexmark.util.data.MutableDataSet; +import com.vladsch.flexmark.util.misc.Extension; import com.diffplug.spotless.FormatterFunc; +import com.diffplug.spotless.markdown.FlexmarkConfig; /** * The formatter function for flexmark-java. */ public class FlexmarkFormatterFunc implements FormatterFunc { - /** - * The emulation profile is used by both the parser and the formatter and generally determines the markdown flavor. - * COMMONMARK is the default defined by flexmark-java. - */ - private static final String DEFAULT_EMULATION_PROFILE = "COMMONMARK"; + private static final Map KNOWN_EXTENSIONS = new HashMap<>(); + static { + // using strings to maximize compatibility with older flexmark versions + KNOWN_EXTENSIONS.put("Abbreviation", "com.vladsch.flexmark.ext.abbreviation.AbbreviationExtension"); + KNOWN_EXTENSIONS.put("Admonition", "com.vladsch.flexmark.ext.admonition.AdmonitionExtension"); + KNOWN_EXTENSIONS.put("Aside", "com.vladsch.flexmark.ext.aside.AsideExtension"); + KNOWN_EXTENSIONS.put("Attributes", "com.vladsch.flexmark.ext.attributes.AttributesExtension"); + KNOWN_EXTENSIONS.put("Definition", "com.vladsch.flexmark.ext.definition.DefinitionExtension"); + KNOWN_EXTENSIONS.put("Emoji", "com.vladsch.flexmark.ext.emoji.EmojiExtension"); + KNOWN_EXTENSIONS.put("EnumeratedReference", "com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceExtension"); + KNOWN_EXTENSIONS.put("Footnote", "com.vladsch.flexmark.ext.footnotes.FootnoteExtension"); + KNOWN_EXTENSIONS.put("GitLab", "com.vladsch.flexmark.ext.gitlab.GitLabExtension"); + KNOWN_EXTENSIONS.put("JekyllFrontMatter", "com.vladsch.flexmark.ext.jekyll.front.matter.JekyllFrontMatterExtension"); + KNOWN_EXTENSIONS.put("JekyllTag", "com.vladsch.flexmark.ext.jekyll.tag.JekyllTagExtension"); + KNOWN_EXTENSIONS.put("Macros", "com.vladsch.flexmark.ext.macros.MacrosExtension"); + KNOWN_EXTENSIONS.put("SimToc", "com.vladsch.flexmark.ext.toc.SimTocExtension"); + KNOWN_EXTENSIONS.put("Tables", "com.vladsch.flexmark.ext.tables.TablesExtension"); + KNOWN_EXTENSIONS.put("TaskList", "com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension"); + KNOWN_EXTENSIONS.put("WikiLink", "com.vladsch.flexmark.ext.wikilink.WikiLinkExtension"); + KNOWN_EXTENSIONS.put("YamlFrontMatter", "com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension"); + } private final Parser parser; private final Formatter formatter; - public FlexmarkFormatterFunc() { + public FlexmarkFormatterFunc(FlexmarkConfig config) { // flexmark-java has a separate parser and renderer (formatter) // this is build from the example in https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter // The emulation profile generally determines the markdown flavor. We use the same one for both the parser and // the formatter, to make sure this formatter func is idempotent. - final ParserEmulationProfile emulationProfile = ParserEmulationProfile.valueOf(DEFAULT_EMULATION_PROFILE); + final ParserEmulationProfile emulationProfile = ParserEmulationProfile.valueOf(config.getEmulationProfile()); - final MutableDataHolder parserOptions = createParserOptions(emulationProfile); + final MutableDataHolder parserOptions = createParserOptions(emulationProfile, config); final MutableDataHolder formatterOptions = createFormatterOptions(parserOptions, emulationProfile); parser = Parser.builder(parserOptions).build(); @@ -62,12 +86,63 @@ public FlexmarkFormatterFunc() { * @param emulationProfile the emulation profile (or flavor of markdown) the parser should use * @return the created parser options */ - private static MutableDataHolder createParserOptions(ParserEmulationProfile emulationProfile) { - final MutableDataHolder parserOptions = PegdownOptionsAdapter.flexmarkOptions(PegdownExtensions.ALL).toMutable(); + private static MutableDataHolder createParserOptions(ParserEmulationProfile emulationProfile, FlexmarkConfig config) { + int pegdownExtensions = buildPegdownExtensions(config.getPegdownExtensions()); + Extension[] extensions = buildExtensions(config.getExtensions()); + final MutableDataHolder parserOptions = PegdownOptionsAdapter.flexmarkOptions( + pegdownExtensions, extensions).toMutable(); parserOptions.set(Parser.PARSER_EMULATION_PROFILE, emulationProfile); return parserOptions; } + /** + * Loads all listed pegdown extensions by using the constants defined in {@link PegdownExtensions}. + * Additionally, pure digit strings are directly converted to allow highly customized configurations. + * + * @param config the string-array configuration for pegdown + * @return bit-wise or'd extensions + */ + private static int buildPegdownExtensions(List config) { + int extensions = PegdownExtensions.NONE; + for (String str : config) { + if (str.matches("\\d+")) { + extensions |= Integer.parseInt(str); + } else if (str.matches("(0x|0X)?[a-fA-F0-9]+")) { + extensions |= Integer.decode(str); + } else { + try { + Field field = PegdownExtensions.class.getField(str); + extensions |= field.getInt(null); + } catch (ReflectiveOperationException e) { + throw new IllegalArgumentException("Unknown PegdownExtension '" + str + "'"); + } + } + } + return extensions; + } + + /** + * Loads all listed extensions by looking up the implementation class (optionally resolving shortcuts + * for known extensions) and calling the conventional create-method. + * + * @param config the string-list of the configured extensions + * @return the array of Extension instances + */ + private static Extension[] buildExtensions(List config) { + Extension[] extensions = new Extension[config.size()]; + for (int i = 0; i < extensions.length; i++) { + String className = KNOWN_EXTENSIONS.getOrDefault(config.get(i), config.get(i)); + try { + Class c = Extension.class.getClassLoader().loadClass(className); + Method create = c.getMethod("create"); + extensions[i] = Extension.class.cast(create.invoke(null)); + } catch (ReflectiveOperationException e) { + throw new IllegalArgumentException("Unknown flexmark extension '" + config.get(i) + "'"); + } + } + return extensions; + } + /** * Creates the formatter options, copies the parser extensions and changes defaults that make sense for a formatter. * See: https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options @@ -76,7 +151,8 @@ private static MutableDataHolder createParserOptions(ParserEmulationProfile emul * @param emulationProfile the emulation profile (or flavor of markdown) the formatter should use * @return the created formatter options */ - private static MutableDataHolder createFormatterOptions(MutableDataHolder parserOptions, ParserEmulationProfile emulationProfile) { + private static MutableDataHolder createFormatterOptions(MutableDataHolder parserOptions, + ParserEmulationProfile emulationProfile) { final MutableDataHolder formatterOptions = new MutableDataSet(); formatterOptions.set(Parser.EXTENSIONS, Parser.EXTENSIONS.get(parserOptions)); formatterOptions.set(Formatter.FORMATTER_EMULATION_PROFILE, emulationProfile); diff --git a/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkConfig.java b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkConfig.java new file mode 100644 index 0000000000..822e105b4f --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkConfig.java @@ -0,0 +1,56 @@ +/* + * Copyright 2025 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.markdown; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class FlexmarkConfig implements Serializable { + + /** + * The emulation profile is used by both the parser and the formatter and generally determines the markdown flavor. + * COMMONMARK is the default defined by flexmark-java. + */ + private String emulationProfile = "COMMONMARK"; + private List pegdownExtensions = List.of("ALL"); + private List extensions = new ArrayList<>(); + + public String getEmulationProfile() { + return emulationProfile; + } + + public void setEmulationProfile(String emulationProfile) { + this.emulationProfile = emulationProfile; + } + + public List getPegdownExtensions() { + return pegdownExtensions; + } + + public void setPegdownExtensions(List pegdownExtensions) { + this.pegdownExtensions = pegdownExtensions; + } + + public List getExtensions() { + return extensions; + } + + public void setExtensions(List extensions) { + this.extensions = extensions; + } + +} diff --git a/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java index 91ac81d847..82848e08ef 100644 --- a/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java +++ b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java @@ -34,22 +34,24 @@ public final class FlexmarkStep implements Serializable { public static final String NAME = "flexmark-java"; private final JarState.Promised jarState; + private final FlexmarkConfig config; - private FlexmarkStep(JarState.Promised jarState) { + private FlexmarkStep(JarState.Promised jarState, FlexmarkConfig config) { this.jarState = jarState; + this.config = config; } /** Creates a formatter step for the default version. */ - public static FormatterStep create(Provisioner provisioner) { - return create(defaultVersion(), provisioner); + public static FormatterStep create(Provisioner provisioner, FlexmarkConfig config) { + return create(defaultVersion(), provisioner, config); } /** Creates a formatter step for the given version. */ - public static FormatterStep create(String version, Provisioner provisioner) { + public static FormatterStep create(String version, Provisioner provisioner, FlexmarkConfig config) { Objects.requireNonNull(version, "version"); Objects.requireNonNull(provisioner, "provisioner"); return FormatterStep.create(NAME, - new FlexmarkStep(JarState.promise(() -> JarState.from(MAVEN_COORDINATE + version, provisioner))), + new FlexmarkStep(JarState.promise(() -> JarState.from(MAVEN_COORDINATE + version, provisioner)), config), FlexmarkStep::equalityState, State::createFormat); } @@ -59,7 +61,7 @@ public static String defaultVersion() { } private State equalityState() { - return new State(jarState.get()); + return new State(jarState.get(), config); } private static class State implements Serializable { @@ -67,16 +69,18 @@ private static class State implements Serializable { private static final long serialVersionUID = 1L; private final JarState jarState; + private final FlexmarkConfig config; - State(JarState jarState) { + State(JarState jarState, FlexmarkConfig config) { this.jarState = jarState; + this.config = config; } FormatterFunc createFormat() throws Exception { final ClassLoader classLoader = jarState.getClassLoader(); final Class formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.markdown.FlexmarkFormatterFunc"); - final Constructor constructor = formatterFunc.getConstructor(); - return (FormatterFunc) constructor.newInstance(); + final Constructor constructor = formatterFunc.getConstructor(FlexmarkConfig.class); + return (FormatterFunc) constructor.newInstance(config); } } } diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 987999e6d5..8b3188cb39 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -8,6 +8,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( * Use absolute path in the git pre push hook ### Fixed - palantirJavaFormat is no longer arbitrarily set to outdated versions on Java 17, latest available version is always used ([#2686](https://github.com/diffplug/spotless/pull/2686) fixes [#2685](https://github.com/diffplug/spotless/issues/2685)) +### Added +- new options to customize Flexmark, e.g. to allow YAML front matter ([#2616](https://github.com/diffplug/spotless/issues/2616)) ## [8.0.0] - 2025-09-24 ### Changed diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index ac7b0f4ede..8c8e17efb4 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -736,7 +736,10 @@ spotless { [homepage](https://github.com/vsch/flexmark-java). Flexmark is a flexible Commonmark/Markdown parser that can be used to format Markdown files. It supports different [flavors of Markdown](https://github.com/vsch/flexmark-java#markdown-processor-emulation) and [many formatting options](https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options). -Currently, none of the available options can be configured yet. It uses only the default options together with `COMMONMARK` as `FORMATTER_EMULATION_PROFILE`. +The default configuration uses a pegdown compatible parser with `COMMONMARK` as `FORMATTER_EMULATION_PROFILE`. +You can change the `emulationProfile` to one of the other [supported profiles](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/parser/ParserEmulationProfile.java). +The `pegdownExtensions` can be configured as a list of [constants](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/parser/PegdownExtensions.java) or as a custom bitset as an integer. +Any other `extension` can be configured using either the simple name as shown in the example or using a full-qualified class name. To apply flexmark to all of the `.md` files in your project, use this snippet: @@ -745,6 +748,9 @@ spotless { flexmark { target '**/*.md' // you have to set the target manually flexmark() // or flexmark('0.64.8') // version is optional + .emulationProfile('COMMONMARK') // optional + .pegdownExtensions('ALL') // optional + .extensions('YamlFrontMatter') // optional } } ``` diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FlexmarkExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FlexmarkExtension.java index d1f941613b..4147645835 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FlexmarkExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FlexmarkExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 DiffPlug + * Copyright 2023-2025 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,13 @@ */ package com.diffplug.gradle.spotless; +import java.util.List; import java.util.Objects; import javax.inject.Inject; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.markdown.FlexmarkConfig; import com.diffplug.spotless.markdown.FlexmarkStep; public class FlexmarkExtension extends FormatExtension { @@ -50,14 +52,35 @@ protected void setupTask(SpotlessTask task) { public class FlexmarkFormatterConfig { private final String version; + private final FlexmarkConfig config = new FlexmarkConfig(); FlexmarkFormatterConfig(String version) { this.version = Objects.requireNonNull(version); addStep(createStep()); } + public FlexmarkFormatterConfig emulationProfile(String emulationProfile) { + this.config.setEmulationProfile(emulationProfile); + return this; + } + + public FlexmarkFormatterConfig pegdownExtensions(int pegdownExtensions) { + this.config.setPegdownExtensions(List.of(Integer.toString(pegdownExtensions))); + return this; + } + + public FlexmarkFormatterConfig pegdownExtensions(String... pegdownExtensions) { + this.config.setPegdownExtensions(List.of(pegdownExtensions)); + return this; + } + + public FlexmarkFormatterConfig extensions(String... extensions) { + this.config.setExtensions(List.of(extensions)); + return this; + } + private FormatterStep createStep() { - return FlexmarkStep.create(this.version, provisioner()); + return FlexmarkStep.create(this.version, provisioner(), config); } } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FlexmarkExtensionTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FlexmarkExtensionTest.java index 6264c0c230..b449c1416a 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FlexmarkExtensionTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FlexmarkExtensionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 DiffPlug + * Copyright 2023-2025 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,31 @@ import org.junit.jupiter.api.Test; class FlexmarkExtensionTest extends GradleIntegrationHarness { + + @Test + void integrationSimpleExtensions() throws IOException { + setFile("build.gradle").toLines( + "plugins {", + " id 'java'", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "spotless {", + " flexmark {", + " target '*.md'", + " flexmark()", + " .emulationProfile('COMMONMARK')", + " .pegdownExtensions('ALL')", + " .extensions('YamlFrontMatter')", + " }", + "}"); + setFile("markdown_test.md").toResource("markdown/flexmark/FlexmarkUnformatted.md"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("markdown_test.md").sameAsResource("markdown/flexmark/FlexmarkFormatted.md"); + } + @Test - void integration() throws IOException { + void integrationComplex() throws IOException { setFile("build.gradle").toLines( "plugins {", " id 'java'", @@ -32,6 +55,9 @@ void integration() throws IOException { " flexmark {", " target '*.md'", " flexmark()", + " .emulationProfile('COMMONMARK')", + " .pegdownExtensions(0x0000FFFF)", + " .extensions('com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension')", " }", "}"); setFile("markdown_test.md").toResource("markdown/flexmark/FlexmarkUnformatted.md"); diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 7de87eb5fa..62055f9a7f 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -800,7 +800,18 @@ All configuration settings are optional, they are described in detail [here](htt [homepage](https://github.com/vsch/flexmark-java). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java). Flexmark is a flexible Commonmark/Markdown parser that can be used to format Markdown files. It supports different [flavors of Markdown](https://github.com/vsch/flexmark-java#markdown-processor-emulation) and [many formatting options](https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options). -Currently, none of the available options can be configured yet. It uses only the default options together with `COMMONMARK` as `FORMATTER_EMULATION_PROFILE`. +The default configuration uses a pegdown compatible parser with `COMMONMARK` as `FORMATTER_EMULATION_PROFILE`. +You can change the `emulationProfile` to one of the other [supported profiles](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/parser/ParserEmulationProfile.java). +The `pegdownExtensions` can be configured as a comma-seperated list of [constants](https://github.com/vsch/flexmark-java/blob/master/flexmark/src/main/java/com/vladsch/flexmark/parser/PegdownExtensions.java) or as a custom bitset as an integer. +Any other `extension` can be configured using either the simple name as shown in the example or using a full-qualified class name. + +```xml + + COMMONMARK + ALL,TOC + YamlFrontMatter,Emoji + +``` diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java index 6e64e26e15..a187019c22 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 DiffPlug + * Copyright 2021-2025 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,12 @@ */ package com.diffplug.spotless.maven.markdown; +import java.util.List; + import org.apache.maven.plugins.annotations.Parameter; import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.markdown.FlexmarkConfig; import com.diffplug.spotless.markdown.FlexmarkStep; import com.diffplug.spotless.maven.FormatterStepConfig; import com.diffplug.spotless.maven.FormatterStepFactory; @@ -26,10 +29,27 @@ public class Flexmark implements FormatterStepFactory { @Parameter private String version; + @Parameter + private String emulationProfile; + + @Parameter + private String pegdownExtensions; + @Parameter + private String extensions; @Override public FormatterStep newFormatterStep(FormatterStepConfig config) { String version = this.version != null ? this.version : FlexmarkStep.defaultVersion(); - return FlexmarkStep.create(version, config.getProvisioner()); + FlexmarkConfig flexmarkConfig = new FlexmarkConfig(); + if (this.emulationProfile != null) { + flexmarkConfig.setEmulationProfile(this.emulationProfile); + } + if (this.pegdownExtensions != null) { + flexmarkConfig.setPegdownExtensions(List.of(this.pegdownExtensions.split(","))); + } + if (this.extensions != null) { + flexmarkConfig.setExtensions(List.of(this.extensions.split(","))); + } + return FlexmarkStep.create(version, config.getProvisioner(), flexmarkConfig); } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/markdown/FlexmarkMavenTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/markdown/FlexmarkMavenTest.java index eb1c6cc95f..df55059c45 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/markdown/FlexmarkMavenTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/markdown/FlexmarkMavenTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2023 DiffPlug + * Copyright 2021-2025 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,8 +22,17 @@ public class FlexmarkMavenTest extends MavenIntegrationHarness { @Test - public void testFlexmarkWithDefaultConfig() throws Exception { - writePomWithMarkdownSteps(""); + public void testFlexmarkWithSimpleConfig() throws Exception { + writePomWithMarkdownSteps("ALL,TOCYamlFrontMatter,Emoji"); + + setFile("markdown_test.md").toResource("markdown/flexmark/FlexmarkUnformatted.md"); + mavenRunner().withArguments("spotless:apply").runNoError(); + assertFile("markdown_test.md").sameAsResource("markdown/flexmark/FlexmarkFormatted.md"); + } + + @Test + public void testFlexmarkWithComplexConfig() throws Exception { + writePomWithMarkdownSteps("COMMONMARK0x0000FFFFcom.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension"); setFile("markdown_test.md").toResource("markdown/flexmark/FlexmarkUnformatted.md"); mavenRunner().withArguments("spotless:apply").runNoError(); diff --git a/testlib/src/main/resources/markdown/flexmark/FlexmarkFormatted.md b/testlib/src/main/resources/markdown/flexmark/FlexmarkFormatted.md index d85efcff03..e59263a8ce 100644 --- a/testlib/src/main/resources/markdown/flexmark/FlexmarkFormatted.md +++ b/testlib/src/main/resources/markdown/flexmark/FlexmarkFormatted.md @@ -1,3 +1,8 @@ +--- +layout: post +title: YAML Front Matter +--- + # Heading ----- diff --git a/testlib/src/main/resources/markdown/flexmark/FlexmarkUnformatted.md b/testlib/src/main/resources/markdown/flexmark/FlexmarkUnformatted.md index 3682454761..935d61b5a8 100644 --- a/testlib/src/main/resources/markdown/flexmark/FlexmarkUnformatted.md +++ b/testlib/src/main/resources/markdown/flexmark/FlexmarkUnformatted.md @@ -1,3 +1,7 @@ +--- +layout: post +title: YAML Front Matter +--- #Heading ----- diff --git a/testlib/src/test/java/com/diffplug/spotless/markdown/FlexmarkStepTest.java b/testlib/src/test/java/com/diffplug/spotless/markdown/FlexmarkStepTest.java index 9876f118e0..89e387bb85 100644 --- a/testlib/src/test/java/com/diffplug/spotless/markdown/FlexmarkStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/markdown/FlexmarkStepTest.java @@ -15,6 +15,8 @@ */ package com.diffplug.spotless.markdown; +import java.util.List; + import org.junit.jupiter.api.Test; import com.diffplug.spotless.StepHarness; @@ -25,7 +27,9 @@ class FlexmarkStepTest { @Test void behaviorOldest() { - StepHarness.forStep(FlexmarkStep.create(OLDEST_SUPPORTED, TestProvisioner.mavenCentral())) + FlexmarkConfig config = new FlexmarkConfig(); + config.setExtensions(List.of("YamlFrontMatter")); + StepHarness.forStep(FlexmarkStep.create(OLDEST_SUPPORTED, TestProvisioner.mavenCentral(), config)) .testResource( "markdown/flexmark/FlexmarkUnformatted.md", "markdown/flexmark/FlexmarkFormatted.md"); @@ -33,7 +37,9 @@ void behaviorOldest() { @Test void behaviorLatest() { - StepHarness.forStep(FlexmarkStep.create(TestProvisioner.mavenCentral())) + FlexmarkConfig config = new FlexmarkConfig(); + config.setExtensions(List.of("YamlFrontMatter")); + StepHarness.forStep(FlexmarkStep.create(TestProvisioner.mavenCentral(), config)) .testResource( "markdown/flexmark/FlexmarkUnformatted.md", "markdown/flexmark/FlexmarkFormatted.md");