You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
6.0 KiB
Groovy
178 lines
6.0 KiB
Groovy
3 years ago
|
package org.xbib.gradle.plugin.asciidoctor.groovydsl
|
||
|
|
||
|
import groovy.transform.CompileStatic
|
||
|
import org.asciidoctor.Asciidoctor
|
||
|
import org.codehaus.groovy.control.CompilerConfiguration
|
||
|
import org.codehaus.groovy.control.customizers.ImportCustomizer
|
||
|
|
||
|
import java.nio.file.Files
|
||
|
import java.nio.file.Path
|
||
|
|
||
|
/**
|
||
|
* An instance of this class holds all extension closure and scripts.
|
||
|
* It evaluates the blocks and scripts and forwards the extracted extensions
|
||
|
* to the GroovyExtensionRegistry which is service implementation
|
||
|
* of org.asciidoctor.extension.spi.wExtensionRegistry
|
||
|
*/
|
||
|
@CompileStatic
|
||
|
class AsciidoctorExtensions {
|
||
|
|
||
|
private final List<Object> registeredExtensions = []
|
||
|
|
||
|
private static final AsciidoctorExtensions INSTANCE = new AsciidoctorExtensions()
|
||
|
|
||
|
/** Add an extension from a closure
|
||
|
*
|
||
|
* @param cl Closure containing an extension
|
||
|
*/
|
||
|
void addExtension(@DelegatesTo(AsciidoctorExtensionHandler) Closure cl) {
|
||
|
registeredExtensions.add(cl)
|
||
|
}
|
||
|
|
||
|
/** Add an extension via a string.
|
||
|
*
|
||
|
* @param groovyScript String containing extension.
|
||
|
*/
|
||
|
void addExtension(final String groovyScript) {
|
||
|
registeredExtensions.add(groovyScript)
|
||
|
}
|
||
|
|
||
|
/** Add an extension via a file.
|
||
|
*
|
||
|
* @param groovyScript File containing extension
|
||
|
*/
|
||
|
void addExtension(final File groovyScript) {
|
||
|
registeredExtensions.add(groovyScript)
|
||
|
}
|
||
|
|
||
|
/** Add an extension via a path instance
|
||
|
*
|
||
|
* @param groovyScript Path pointing to an extension
|
||
|
*/
|
||
|
void addExtension(final Path groovyScript) {
|
||
|
registeredExtensions.add(groovyScript)
|
||
|
}
|
||
|
|
||
|
/** Remove all extensions.
|
||
|
*
|
||
|
*/
|
||
|
void clearExtensions() {
|
||
|
registeredExtensions.clear()
|
||
|
}
|
||
|
|
||
|
/** Register all extension with an instance of Asciidoctor.
|
||
|
*
|
||
|
* @param asciidoctor Asciidoctor instance awaiting extensions.
|
||
|
* @throw AsciidoctorExtensionException
|
||
|
*/
|
||
|
@SuppressWarnings('UnnecessarySetter')
|
||
|
void registerExtensionsWith(Asciidoctor asciidoctor) {
|
||
|
AsciidoctorExtensionHandler extensionHandler = new AsciidoctorExtensionHandler(asciidoctor)
|
||
|
for (def it : registeredExtensions) {
|
||
|
switch (it) {
|
||
|
case Closure:
|
||
|
try {
|
||
|
((Closure) it).delegate = extensionHandler
|
||
|
((Closure) it).call()
|
||
|
} catch (e) {
|
||
|
throw new AsciidoctorExtensionException("Error registering extension from class in ${it.class.name}", e)
|
||
|
}
|
||
|
break
|
||
|
case String:
|
||
|
GroovyShell shell = makeGroovyShell()
|
||
|
DelegatingScript script = (DelegatingScript) shell.parse((String) it)
|
||
|
script.setDelegate(extensionHandler)
|
||
|
try {
|
||
|
script.run()
|
||
|
} catch (e) {
|
||
|
registeredExtensions.clear()
|
||
|
throw new AsciidoctorExtensionException('Error registering extension from string', e)
|
||
|
}
|
||
|
break
|
||
|
case File:
|
||
|
File file = (File) it
|
||
|
GroovyShell shell = makeGroovyShell()
|
||
|
file.withReader { reader ->
|
||
|
DelegatingScript script = (DelegatingScript) shell.parse(reader, file.name)
|
||
|
script.setDelegate(extensionHandler)
|
||
|
try {
|
||
|
script.run()
|
||
|
} catch (e) {
|
||
|
throw new AsciidoctorExtensionException("Error registering extension from file ${file.name}", e)
|
||
|
}
|
||
|
}
|
||
|
break
|
||
|
case Path:
|
||
|
Path path = (Path) it
|
||
|
GroovyShell shell = makeGroovyShell()
|
||
|
Files.newBufferedReader(path).withReader { reader ->
|
||
|
DelegatingScript script = (DelegatingScript) shell.parse(reader, path.toString())
|
||
|
script.setDelegate(extensionHandler)
|
||
|
try {
|
||
|
script.run()
|
||
|
} catch (e) {
|
||
|
throw new AsciidoctorExtensionException("Error registering extension from file ${path}", e)
|
||
|
}
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Adds an extension to the AsciidoctorExtension singleton instance.
|
||
|
*
|
||
|
* @param cl Closure containing an instance
|
||
|
*/
|
||
|
static void extensions(@DelegatesTo(AsciidoctorExtensionHandler) Closure cl) {
|
||
|
INSTANCE.addExtension(cl)
|
||
|
}
|
||
|
|
||
|
/** Adds an extension to the AsciidoctorExtension singleton instance.
|
||
|
*
|
||
|
* @param s String containing an instance
|
||
|
*/
|
||
|
static void extensions(String s) {
|
||
|
INSTANCE.addExtension(s)
|
||
|
}
|
||
|
|
||
|
/** Adds an extension to the AsciidoctorExtension singleton instance.
|
||
|
*
|
||
|
* @param f File containing an instance
|
||
|
*/
|
||
|
static void extensions(File f) {
|
||
|
INSTANCE.addExtension(f)
|
||
|
}
|
||
|
|
||
|
/** Attempt to register all exteniosn with ASciidoctor instance.
|
||
|
*
|
||
|
* This method has the side-effect of removing all extensions as well.
|
||
|
*
|
||
|
* @param asciidoctor
|
||
|
*/
|
||
|
static void registerTo(Asciidoctor asciidoctor) {
|
||
|
try {
|
||
|
INSTANCE.registerExtensionsWith(asciidoctor)
|
||
|
} finally {
|
||
|
INSTANCE.clearExtensions()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static GroovyShell makeGroovyShell() {
|
||
|
def config = new CompilerConfiguration()
|
||
|
|
||
|
config.scriptBaseClass = DelegatingScript.name
|
||
|
|
||
|
ImportCustomizer importCustomizer = new ImportCustomizer()
|
||
|
importCustomizer.addStarImports(
|
||
|
'org.asciidoctor',
|
||
|
'org.asciidoctor.ast',
|
||
|
'org.asciidoctor.extension'
|
||
|
)
|
||
|
|
||
|
config.addCompilationCustomizers(
|
||
|
importCustomizer
|
||
|
)
|
||
|
|
||
|
new GroovyShell(new Binding(), config)
|
||
|
}
|
||
|
}
|