asciidoctor-gradle-plugin
asciidoctor-gradle-plugin copied to clipboard
AsciidoctorJS require not working
I am trying to require a custom extension for AsciidoctorJS with the gradle plugin. I couldn't make this work, so I prepared a small example which uses the emoji extension from public npm repository to rule out problems with my local extension.
The extenstion is installed with npm install:
npm ls
jens@ /home/jens
├── @asciidoctor/[email protected]
├── @asciidoctor/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
and I installed it manually in the npm folder generated when running gradle asciidoctor task
asciidoctorjs-test/build/.npm/test$ npm ls
test-asciidoctor@unspecified /home/jens/SWP-Updt/asciidoctorjs-test/build/.npm/test
├── [email protected]
└── [email protected]
When I now try to require the emoji extensions in my gradle build script
import org.asciidoctor.gradle.js.nodejs.AsciidoctorTask
plugins {
id("org.asciidoctor.js.convert") version "3.3.2"
}
asciidoctorjs {
require '', 'asciidoctor-emoji', ''
}
asciidoctor {
sourceDir file('.')
outputDir file('build')
sources {
include 'test.adoc'
}
}
because a) the documentation says "Additional NPM modules can be added via asciidoctorj.require."
and AsciidoctorJSExtension has
/** Adds an additional NPM package that is required
*
* @param name Name of package
* @param tag Tag of package
*/
void require(final String name, final String tag) {
this.additionalRequires.add(new NpmDependency(name, tag))
}
/** Adds an additional NPM package that is required
*
* @param scope Scope of package
* @param name Name of package
* @param tag Tag of package
*/
void require(final String scope, final String name, final String tag) {
this.additionalRequires.add(new NpmDependency(scope, name, tag))
}
However, the emoji macro in my test.adoc
I emoji:heart[1x] Asciidoctor.js!
test
does not work.
I tried to understand how the mechanism works, but from what I can see in the code the extension should be added to additionalRequires
void require(final String scope, final String name, final String tag) {
this.additionalRequires.add(new NpmDependency(scope, name, tag))
}
but the only references to the field are in
- requires
- clearRequires
- getAllAdditionalRequires
- versionsDifferFromGlobal
From these, only getAllAdditionalRequires has a return value that uses additionalRequires, but this functions seems to be not used as I could not find any reference. Even getRequires does not consider additionalRequires. Is this intended?
The runner gets passed
new AsciidoctorJSRunner(
nodejs.resolvableNodeExecutable.executable,
project,
asciidoctorjsExe,
backend,
asciidoctorjs.safeMode,
lang.present ? getBaseDir(lang.get()) : getBaseDir(),
lang.present ? getOutputDirFor(backend, lang.get()) : getOutputDirFor(backend),
attributes,
asciidoctorjs.requires,
Optional.empty(),
logDocuments
)
I then tried to use requires as for AsciidoctorJ and added it to plugin and task configuration
import org.asciidoctor.gradle.js.nodejs.AsciidoctorTask
plugins {
id("org.asciidoctor.js.convert") version "3.3.2"
}
asciidoctorjs {
require '', 'asciidoctor-emoji'
requires ['asciidoctor-emoji']
println requires
}
asciidoctor {
asciidoctorjs {
require '', 'asciidoctor-emoji'
requires ['asciidoctor-emoji']
println requires
}
sourceDir file('.')
outputDir file('build')
sources {
include 'test.adoc'
}
}
However no result. I would be really grateful for some help or guidance. A RTFM with a working example would be very appreciated.
I think it is a bug. AsciidoctorJSRunner gets passed asciidoctorjs.requires, but the property is implemented as
Set<String> getRequires() {
List<String> reqs = [].toSet()
final String docbook = moduleVersion(modules.docbook)
if (docbook) {
reqs.add(packageDescriptorFor(modules.docbook).toString())
}
reqs
}
This returns a new set for every invocation, explaining why the set cannot be modified with add or addAll. It also totally ignores modules in additionalRequires added with require.
I think the implementation should be more like
Set<String> getRequires() {
List<String> reqs = getAllAdditionalRequires().collect { asModuleVersionString(it) }
final String docbook = moduleVersion(modules.docbook)
if (docbook) {
reqs.add(packageDescriptorFor(modules.docbook).toString())
}
Set.copyOf( reqs )
}
private String asModuleVersionString(NpmDependency dep) {
final String scope = it.scope
final String name = it.packageName
final String version = it.tag
final String r = (scope != null && !scope.isEmpty()) ? ("@${scope}/${name}") : name
if (version != null && !version.isEmpty()) {
r + "@${version}"
} else {
r
}
}