Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AsciidoctorJS require not working #681

Open
jens-auer opened this issue Jul 28, 2023 · 1 comment
Open

AsciidoctorJS require not working #681

jens-auer opened this issue Jul 28, 2023 · 1 comment
Milestone

Comments

@jens-auer
Copy link

jens-auer commented Jul 28, 2023

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/core@2.2.6
├── @asciidoctor/docbook-converter@2.0.0
├── asciidoctor-emoji@0.4.2
├── asciidoctor-pdf@1.0.0-alpha.16
├── asciidoctor.js@1.5.9
├── asciidoctor@2.2.6
├── node-pty@0.10.1
├── opal-compiler@2.3.0

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
├── asciidoctor-emoji@0.4.2
└── asciidoctor@2.0.2

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.

@jens-auer
Copy link
Author

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
        }
    }

@ysb33r ysb33r added this to the 4.0.0 milestone Dec 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants