Skip to content

Commit

Permalink
Merge pull request #1011 from korthout/flexmark-java
Browse files Browse the repository at this point in the history
Add native markdown formatting for maven
  • Loading branch information
nedtwigg authored Dec 23, 2021
2 parents bebaa59 + 0fcfee5 commit 376b561
Show file tree
Hide file tree
Showing 19 changed files with 482 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This document is intended for Spotless developers.
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* Added support for Markdown with `flexmark` at `0.62.2` ([#1011](https://github.com/diffplug/spotless/pull/1011)).

## [2.20.3] - 2021-12-15
### Fixed
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ lib('kotlin.KtLintStep') +'{{yes}} | {{yes}}
lib('kotlin.KtfmtStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('kotlin.DiktatStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} | {{no}} |',
lib('markdown.FlexmarkStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |',
lib('npm.PrettierFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('pom.SortPomStepStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |',
Expand Down Expand Up @@ -103,6 +104,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}}
| [`kotlin.KtfmtStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`kotlin.DiktatStep`](lib/src/main/java/com/diffplug/spotless/kotlin/DiktatStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: |
| [`markdown.FlexmarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: |
| [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`pom.SortPomStepStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStepStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: |
Expand Down
6 changes: 5 additions & 1 deletion lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ apply from: rootProject.file('gradle/java-publish.gradle')

def NEEDS_GLUE = [
'sortPom',
'ktlint'
'ktlint',
'flexmark'
]
for (glue in NEEDS_GLUE) {
sourceSets.register(glue) {
Expand All @@ -32,6 +33,9 @@ dependencies {
ktlintCompileOnly "com.pinterest:ktlint:$VER_KTLINT"
ktlintCompileOnly "com.pinterest.ktlint:ktlint-core:$VER_KTLINT"
ktlintCompileOnly "com.pinterest.ktlint:ktlint-ruleset-standard:$VER_KTLINT"

// used for markdown formatting
flexmarkCompileOnly 'com.vladsch.flexmark:flexmark-all:0.62.2'
}

// we'll hold the core lib to a high standard
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright 2021 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.glue.markdown;

import com.vladsch.flexmark.formatter.Formatter;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.parser.ParserEmulationProfile;
import com.vladsch.flexmark.parser.PegdownExtensions;
import com.vladsch.flexmark.profile.pegdown.PegdownOptionsAdapter;
import com.vladsch.flexmark.util.ast.Document;
import com.vladsch.flexmark.util.data.MutableDataHolder;
import com.vladsch.flexmark.util.data.MutableDataSet;

import com.diffplug.spotless.FormatterFunc;

/**
* The formatter function for <a href="https://github.com/vsch/flexmark-java">flexmark-java</a>.
*/
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 final Parser parser;
private final Formatter formatter;

public FlexmarkFormatterFunc() {
// 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 MutableDataHolder parserOptions = createParserOptions(emulationProfile);
final MutableDataHolder formatterOptions = createFormatterOptions(parserOptions, emulationProfile);

parser = Parser.builder(parserOptions).build();
formatter = Formatter.builder(formatterOptions).build();
}

/**
* Creates the parser options.
* See: https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options
*
* @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();
parserOptions.set(Parser.PARSER_EMULATION_PROFILE, emulationProfile);
return parserOptions;
}

/**
* 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
*
* @param parserOptions the options used for the parser
* @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) {
final MutableDataHolder formatterOptions = new MutableDataSet();
formatterOptions.set(Parser.EXTENSIONS, Parser.EXTENSIONS.get(parserOptions));
formatterOptions.set(Formatter.FORMATTER_EMULATION_PROFILE, emulationProfile);
return formatterOptions;
}

@Override
public String apply(String input) throws Exception {
final Document parsedMarkdown = parser.parse(input);
return formatter.render(parsedMarkdown);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public static boolean defaultReflowLongStrings() {
static final class State implements Serializable {
private static final long serialVersionUID = 1L;

/** The jar that contains the eclipse formatter. */
/** The jar that contains the formatter. */
final JarState jarState;
final String stepName;
final String version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static final class State implements Serializable {
/** Are the files being linted Kotlin script files. */
private final boolean isScript;
private final String pkg;
/** The jar that contains the eclipse formatter. */
/** The jar that contains the formatter. */
final JarState jarState;
private final TreeMap<String, String> userData;
private final boolean useParams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ static final class State implements Serializable {
* Option that allows to apply formatting options to perform a 4 spaces block and continuation indent.
*/
private final Style style;
/** The jar that contains the eclipse formatter. */
/** The jar that contains the formatter. */
final JarState jarState;

State(String version, Provisioner provisioner, Style style) throws IOException {
Expand Down
72 changes: 72 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2016-2021 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.lang.reflect.Constructor;
import java.util.Objects;

import com.diffplug.spotless.FormatterFunc;
import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.JarState;
import com.diffplug.spotless.Provisioner;

/** A step for <a href="https://github.com/vsch/flexmark-java">flexmark-java</a>. */
public class FlexmarkStep {
// prevent direct instantiation
private FlexmarkStep() {}

private static final String DEFAULT_VERSION = "0.62.2";
private static final String NAME = "flexmark-java";
private static final String MAVEN_COORDINATE = "com.vladsch.flexmark:flexmark-all:";

/** Creates a formatter step for the default version. */
public static FormatterStep create(Provisioner provisioner) {
return create(defaultVersion(), provisioner);
}

/** Creates a formatter step for the given version. */
public static FormatterStep create(String version, Provisioner provisioner) {
Objects.requireNonNull(version, "version");
Objects.requireNonNull(provisioner, "provisioner");
return FormatterStep.createLazy(NAME,
() -> new State(JarState.from(MAVEN_COORDINATE + version, provisioner)),
State::createFormat);
}

public static String defaultVersion() {
return DEFAULT_VERSION;
}

private static class State implements Serializable {
private static final long serialVersionUID = 1L;

/** The jar that contains the formatter. */
final JarState jarState;

State(JarState jarState) {
this.jarState = jarState;
}

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();
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static String defaultVersion() {
private static class State implements Serializable {
private static final long serialVersionUID = 1L;

/** The jar that contains the eclipse formatter. */
/** The jar that contains the formatter. */
final JarState jarState;
final NavigableMap<String, ?> properties;

Expand Down
1 change: 1 addition & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]
### Added
* Incremental up-to-date checking ([#935](https://github.com/diffplug/spotless/pull/935)).
* Support for Markdown with `flexmark` at `0.62.2` ([#1011](https://github.com/diffplug/spotless/pull/1011)).

## [2.17.7] - 2021-12-16
### Fixed
Expand Down
23 changes: 23 additions & 0 deletions plugin-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ user@machine repo % mvn spotless:check
- [Antlr4](#antlr4) ([antlr4formatter](#antlr4formatter))
- [Sql](#sql) ([dbeaver](#dbeaver))
- [Maven Pom](#maven-pom) ([sortPom](#sortpom))
- [Markdown](#markdown) ([flexmark](#flexmark))
- [Typescript](#typescript) ([tsfmt](#tsfmt), [prettier](#prettier))
- Multiple languages
- [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection))
Expand Down Expand Up @@ -585,6 +586,28 @@ All configuration settings are optional, they are described in detail [here](htt
</sortPom>
```

## Markdown

[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown).

```xml
<configuration>
<markdown>
<includes> <!-- You have to set the target manually -->
<include>**/*.md</include>
</includes>

<flexmark/> <!-- has its own section below -->
</markdown>
</configuration>
```

### Flexmark

[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`.

<a name="applying-to-typescript-source"></a>

## Typescript
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import com.diffplug.spotless.maven.incremental.UpToDateChecking;
import com.diffplug.spotless.maven.java.Java;
import com.diffplug.spotless.maven.kotlin.Kotlin;
import com.diffplug.spotless.maven.markdown.Markdown;
import com.diffplug.spotless.maven.pom.Pom;
import com.diffplug.spotless.maven.python.Python;
import com.diffplug.spotless.maven.scala.Scala;
Expand Down Expand Up @@ -151,6 +152,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
@Parameter
private Python python;

@Parameter
private Markdown markdown;

@Parameter(property = "spotlessFiles")
private String filePatterns;

Expand Down Expand Up @@ -278,7 +282,7 @@ private Set<String> getIncludes(FormatterFactory formatterFactory) {
Set<String> configuredIncludes = formatterFactory.includes();
Set<String> includes = configuredIncludes.isEmpty() ? formatterFactory.defaultIncludes() : configuredIncludes;
if (includes.isEmpty()) {
throw new PluginException("You must specify some files to include, such as '<includes><include>src/**</include></includes>'");
throw new PluginException("You must specify some files to include, such as '<includes><include>src/**/*.blah</include></includes>'");
}
return includes;
}
Expand Down Expand Up @@ -308,7 +312,7 @@ private FileLocator getFileLocator() {
}

private List<FormatterFactory> getFormatterFactories() {
return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, antlr4, pom, sql, python))
return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, antlr4, pom, sql, python, markdown))
.filter(Objects::nonNull)
.collect(toList());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2021 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.maven.markdown;

import org.apache.maven.plugins.annotations.Parameter;

import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.markdown.FlexmarkStep;
import com.diffplug.spotless.maven.FormatterStepConfig;
import com.diffplug.spotless.maven.FormatterStepFactory;

public class Flexmark implements FormatterStepFactory {

@Parameter
private String version;

@Override
public FormatterStep newFormatterStep(FormatterStepConfig config) {
String version = this.version != null ? this.version : FlexmarkStep.defaultVersion();
return FlexmarkStep.create(version, config.getProvisioner());
}
}
Loading

0 comments on commit 376b561

Please sign in to comment.