16
16
package com .diffplug .spotless .markdown ;
17
17
18
18
import java .io .Serializable ;
19
- import java .lang .reflect .Array ;
20
- import java .lang .reflect .Method ;
19
+ import java .lang .reflect .Constructor ;
21
20
import java .util .Objects ;
22
21
23
22
import com .diffplug .spotless .FormatterFunc ;
@@ -34,13 +33,6 @@ private FlexmarkStep() {}
34
33
private static final String NAME = "flexmark-java" ;
35
34
private static final String MAVEN_COORDINATE = "com.vladsch.flexmark:flexmark-all:" ;
36
35
37
- /**
38
- * The emulation profile is used by both the parser and the formatter and generally determines the markdown flavor.
39
- * COMMONMARK is the default defined by flexmark-java. It's defined here so it can be used in both the parser and
40
- * the formatter, to keep the step idempotent.
41
- */
42
- private static final String DEFAULT_EMULATION_PROFILE = "COMMONMARK" ;
43
-
44
36
/** Creates a formatter step for the default version. */
45
37
public static FormatterStep create (Provisioner provisioner ) {
46
38
return create (defaultVersion (), provisioner );
@@ -70,87 +62,9 @@ private static class State implements Serializable {
70
62
71
63
FormatterFunc createFormat () throws Exception {
72
64
final ClassLoader classLoader = jarState .getClassLoader ();
73
-
74
- // flexmark-java has a separate parser and renderer (formatter)
75
- // this is build from the example in https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter
76
-
77
- // first we need to create the parser and find the parse method
78
- final Class <?> parserClazz = classLoader .loadClass ("com.vladsch.flexmark.parser.Parser" );
79
- final Class <?> parserBuilderClazz = classLoader .loadClass ("com.vladsch.flexmark.parser.Parser$Builder" );
80
- final Class <?> parserEmulationProfileClazz = classLoader .loadClass ("com.vladsch.flexmark.parser.ParserEmulationProfile" );
81
- final Class <?> dataHolderClazz = classLoader .loadClass ("com.vladsch.flexmark.util.data.DataHolder" );
82
- final Class <?> dataKeyClazz = classLoader .loadClass ("com.vladsch.flexmark.util.data.DataKey" );
83
- final Object parserEmulationProfile = parserEmulationProfileClazz .getField (DEFAULT_EMULATION_PROFILE ).get (null );
84
- final Object parserOptions = buildParserOptions (classLoader , parserClazz , dataHolderClazz , dataKeyClazz , parserEmulationProfile );
85
- final Object parserBuilder = parserClazz .getMethod ("builder" , dataHolderClazz ).invoke (null , parserOptions );
86
- final Object parser = parserBuilderClazz .getMethod ("build" ).invoke (parserBuilder );
87
- final Method parseMethod = parserClazz .getMethod ("parse" , String .class );
88
-
89
- // now we can create the formatter and find the render method
90
- final Class <?> formatterClazz = classLoader .loadClass ("com.vladsch.flexmark.formatter.Formatter" );
91
- final Class <?> nodeClazz = classLoader .loadClass ("com.vladsch.flexmark.util.ast.Node" );
92
- final Class <?> formatterBuilderClazz = classLoader .loadClass ("com.vladsch.flexmark.formatter.Formatter$Builder" );
93
- final Object formatterOptions = buildFormatterOptions (
94
- classLoader , parserClazz , formatterClazz , dataKeyClazz , dataHolderClazz , parserOptions , parserEmulationProfile );
95
- final Object formatterBuilder = formatterClazz .getMethod ("builder" , dataHolderClazz ).invoke (null , formatterOptions );
96
- final Object formatter = formatterBuilderClazz .getMethod ("build" ).invoke (formatterBuilder );
97
- final Method renderMethod = formatterClazz .getMethod ("render" , nodeClazz );
98
-
99
- // the input must be parsed by the parser and then rendered by the formatter
100
- return input -> (String ) renderMethod .invoke (formatter , parseMethod .invoke (parser , input ));
101
- }
102
-
103
- private Object buildParserOptions (
104
- ClassLoader classLoader ,
105
- Class <?> parserClazz ,
106
- Class <?> dataHolderClazz ,
107
- Class <?> dataKeyClazz ,
108
- Object parserEmulationProfile ) throws Exception {
109
- final Class <?> pegdownOptionsAdapterClazz = classLoader .loadClass ("com.vladsch.flexmark.profile.pegdown.PegdownOptionsAdapter" );
110
- final Class <?> pegdownExtensionsClazz = classLoader .loadClass ("com.vladsch.flexmark.parser.PegdownExtensions" );
111
- final Class <?> extensionClazz = classLoader .loadClass ("com.vladsch.flexmark.util.misc.Extension" );
112
- final Class <?> mutableDataHolderClazz = classLoader .loadClass ("com.vladsch.flexmark.util.data.MutableDataHolder" );
113
-
114
- final int pegDownExtensionsConstantAll = pegdownExtensionsClazz .getField ("ALL" ).getInt (null );
115
- final Object extensions = Array .newInstance (extensionClazz , 0 );
116
- final Class <?> extensionArrayClazz = extensions .getClass ();
117
-
118
- final Object parserOptions = pegdownOptionsAdapterClazz
119
- .getMethod ("flexmarkOptions" , Integer .TYPE , extensionArrayClazz )
120
- .invoke (null , pegDownExtensionsConstantAll , extensions );
121
- final Object mutableParserOptions = dataHolderClazz .getMethod ("toMutable" ).invoke (parserOptions );
122
- final Object parserEmulationProfileKey = parserClazz .getField ("PARSER_EMULATION_PROFILE" ).get (null );
123
- final Method mutableDataHolderSetMethod = mutableDataHolderClazz .getMethod ("set" , dataKeyClazz , Object .class );
124
- mutableDataHolderSetMethod .invoke (mutableParserOptions , parserEmulationProfileKey , parserEmulationProfile );
125
- return mutableParserOptions ;
126
- }
127
-
128
- /**
129
- * Creates the formatter options, copies the parser extensions and changes defaults that make sense for a formatter.
130
- * See: https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options
131
- */
132
- private Object buildFormatterOptions (
133
- ClassLoader classLoader ,
134
- Class <?> parserClazz ,
135
- Class <?> formatterClazz ,
136
- Class <?> dataKeyClazz ,
137
- Class <?> dataHolderClazz ,
138
- Object parserOptions ,
139
- Object parserEmulationProfile ) throws Exception {
140
- final Class <?> mutableDataSetClazz = classLoader .loadClass ("com.vladsch.flexmark.util.data.MutableDataSet" );
141
- final Object formatterOptions = mutableDataSetClazz .getConstructor ().newInstance ();
142
- final Method mutableDataSetMethodSet = mutableDataSetClazz .getMethod ("set" , dataKeyClazz , Object .class );
143
-
144
- // copy the parser extensions like the example in https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter
145
- final Object parserExtensions = parserClazz .getField ("EXTENSIONS" ).get (null );
146
- final Object copiedExtensions = dataKeyClazz .getMethod ("get" , dataHolderClazz ).invoke (parserExtensions , parserOptions );
147
- mutableDataSetMethodSet .invoke (formatterOptions , parserExtensions , copiedExtensions );
148
-
149
- // use the same emulation profile for the parser and the formatted, to make sure the step is idempotent
150
- final Object formatterEmulationProfile = formatterClazz .getField ("FORMATTER_EMULATION_PROFILE" ).get (null );
151
- mutableDataSetMethodSet .invoke (formatterOptions , formatterEmulationProfile , parserEmulationProfile );
152
-
153
- return formatterOptions ;
65
+ final Class <?> formatterFunc = classLoader .loadClass ("com.diffplug.spotless.glue.markdown.FlexmarkFormatterFunc" );
66
+ final Constructor <?> constructor = formatterFunc .getConstructor ();
67
+ return (FormatterFunc ) constructor .newInstance ();
154
68
}
155
69
156
70
}
0 commit comments