asciidoctor / asciidoctor-gradle-examples

A collection of example projects that demonstrates how to use the Asciidoctor Gradle plugin
http://asciidoctor.github.io/asciidoctor-gradle-examples
Other
146 stars 132 forks source link

Example to create PDF with diagrams #15

Open pajoma opened 8 years ago

pajoma commented 8 years ago

Here's a working example to generate PDFs with PlantUML diagrams

buildscript {
    dependencies {
        classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.11'
    }
}

plugins {
    id 'org.asciidoctor.convert' version '1.5.3'
    id 'com.github.jruby-gradle.base' version '0.3.0'
}

apply plugin: 'java'
apply plugin: 'org.asciidoctor.convert'

version = '1.0.0-SNAPSHOT'

asciidoctorj {
    version = '1.5.4'
}

dependencies {
    gems 'rubygems:asciidoctor-diagram:1.2.0'
}

asciidoctor {
    backends 'pdf'
    dependsOn jrubyPrepareGems
    requires = ['asciidoctor-diagram']
    gemPath = jrubyPrepareGems.outputDir
    attributes  'build-gradle': file('build.gradle'),
                'source-highlighter' : 'coderay',
                'imagesdir':'images',
                'toc':'left',
                'icons': 'font',
                'setanchors':'true',
                'idprefix':'',
                'idseparator':'-',
                'docinfo1':'true'
}

Changes to the HTML5 Version

Here is another example which uses the diagram plugin from asciidoctorj. It compiles, but I don't get how to include the images in the PDF (the generated diagram images are in the built directory, the PDF-Compiler expects them in the source directory).

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
                classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.11'
                classpath 'org.asciidoctor:asciidoctorj-diagram:1.3.1'
    }
}

// apply plugin: 'org.asciidoctor.gradle.asciidoctor'  
apply plugin: 'org.asciidoctor.convert'

asciidoctorj {
    version = '1.5.4'
}

repositories {
    mavenLocal()
    jcenter()
}

resources {
    from(sourceDir) {
        include
    }
}

asciidoctor {
    backends  'pdf'
    requires ['asciidoctor-diagram']
    attributes 'build-gradle': file('build.gradle'),
            'imagesdir':'./images'
}
rwinch commented 8 years ago

@pajoma Thanks for the submission! I'm not quite clear if this is a request to add the original sample or if it is asking for help with the second sample?

pajoma commented 8 years ago

It depends ;)

If the second approach is the preferred way (which I guess it should be, since it seems cleaner without the gems), then this is a request to include it into the examples (if a solution to the image problem exists).

In the other case, see the first approach as a suggestion which could be included it to the original examples.

mojavelinux commented 8 years ago

Using AsciidoctorJ Diagram is the preferred method for the reason you cited (though, keep in mind, you always have the option of switching to using the gem directly...so there's no wrong way).

if a solution to the image problem exists

This is a common problem with Asciidoctor Diagram and build tools because we have a lot of different directories involved. What it comes down to is that, when running the PDF converter, the imagesoutdir attribute has to be set to somewhere in the build output directory and the imagesdir must be an absolute path that matches that location.

Unlike the HTML converter, the PDF converter has to be able to find and read the generated images in order to include them in the document. That location must be the same as for all other images (Asciidoctor only looks in one place for images). It's an engineering challenge we've yet to solve transparently.

eshepelyuk commented 8 years ago

The provided example can be simplified to not fetch Ruby Gems, by using asciidoctorj artifacts, as suggested by @mojavelinux

buildscript {
    dependencies {
        classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.11',
            'org.asciidoctor:asciidoctorj-diagram:1.3.1'
    }
}

plugins {
    id 'org.asciidoctor.convert' version '1.5.3'
}

repositories {
    jcenter()
}

asciidoctor {
    backends 'pdf'
    requires 'asciidoctor-diagram'
    attributes 'buildDir': buildDir
}

And as example, in src/docs/asciidoc/plantuml.adoc

= AsciiDoctor + Gradle + Plant UML
:imagesdir: {buildDir}/asciidoc/pdf

== PlantUML Diagram 

[plantuml, ./diagram, png]
.Diagram Title
....
@startuml
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response

Alice -> Bob: Another authentication Request
Alice <-- Bob: another authentication Response
@enduml

Versions

I think asciidoctor-gradle should be updated to 1.5.4 (as latest RubyGem) And asciidoctorj-diagram should be updated to 1.4.0 (as latest RubyGem)

mojavelinux commented 8 years ago

I think asciidoctor-gradle should be updated to 1.5.4 (as latest RubyGem)

I think we're still waiting on this release. It is possible to upgrade AsciidoctorJ independently of the plugin, though we probably want to keep configuration to a minimum for the example, so best to wait.

And asciidoctorj-diagram should be updated to 1.4.0 (as latest RubyGem)

:+1:

msgilligan commented 7 years ago

I had some trouble getting this to work with multiple backends.

Ultimately I used the following Gradle:

asciidoctor.doFirst {
    // pre-process
    copy {
        from file('doc/images')
        into file("$buildDir/site/pdf/images")
        include '*.png'
    }
}
asciidoctor {
    sourceDir = file('doc')
    outputDir = file("$buildDir/site")
    separateOutputDirs = true
    logDocuments = true

    sources {
        include 'Filename.adoc'
    }

    backends 'html5', 'pdf'

    requires  'asciidoctor-diagram'
}

And added the following attributes to the document:

ifdef::backend-pdf[:imagesoutdir: ../build/site/{backend}/images]
ifdef::backend-pdf[:imagesdir: ../build/site/{backend}/images]
ifdef::backend-html5[:imagesoutdir: ../build/site/{backend}/images]
ifdef::backend-html5[:imagesdir: images]

There's probably a more elegant way, but this seems to work correctly.

So, as I understand it, what is happening is the following:

  1. The asciidoctor.doFirst block runs once before any of the backends and copies the images to build/site/pdf/images. It is necessary to do this because the Asciidoctor Gradle plugin doesn't copy the resources until after rendering the documents, but the PDF renderer needs the images copied first.
  2. As each document is processed, the diagrams are rendered into build/site/{backend}/images
  3. After each document is processed, images are copied into build/site/{backend}/images
mojavelinux commented 7 years ago

It is necessary to do this because the Asciidoctor Gradle plugin doesn't copy the resources until after rendering the documents, but the PDF renderer needs the images copied first.

That really depends on how the images are being referenced. If you are generating images into the build directory, and you want the converter to look for all images there, then yes, you need to copy the static images there before the converter runs.

robfletcher commented 7 years ago

I'm trying to migrate from using the rubygems directly but diagram generation fails because /usr/bin/dot is not found. Does asciidoctorj-diagram require me to install GraphViz separately? If I do so with Homebrew it works but it means the build is not as portable as if I use Ruby.

eshepelyuk commented 7 years ago

@robfletcher, yes. You have to install it separately. dot should be available from your PATH

rdmueller commented 7 years ago

are there any updates on the handling of the image path? My HTML renders fine but the PDF renderer (alpha-15) still complains that it can't find the plantUML image in src/docs/images ...

mojavelinux commented 7 years ago

Yes.

I describe the solution in the following comment:

https://github.com/asciidoctor/asciidoctor-pdf/issues/271#issuecomment-291992364

and some more information here:

https://github.com/asciidoctor/asciidoctor-pdf/issues/495#issuecomment-292363478

mojavelinux commented 7 years ago

I recommend looking at what the junit5 project is doing since they have a working configuration.

aheusingfeld commented 7 years ago

FYI I managed to create a less complex setup in https://github.com/arc42/quality-requirements. The generated PDF (and docx via pandoc) are created via TravisCI and uploaded to Github Releases for each Git tag.

brnhffmnn commented 6 years ago

Another option to this is, to create a new task just for the PDF backend. The advantage is, you don't have to deal with ifdefs in the source file.

asciidoctor {
    dependsOn "asciidoctorPdf"
}

task asciidoctorPdf(type: org.asciidoctor.gradle.AsciidoctorTask) {
    group "documentation"

    requires 'asciidoctor-diagram'
    backends 'pdf'

    sources {
        include "index.adoc"
    }

    attributes = [
            "imagesoutdir"  : "$buildDir/asciidoc/pdf/images",
            "imagesdir"     : "$buildDir/asciidoc/pdf/images"
    ]
}

By the way: why couldn't this be handled by the plugin?

jeffcjohnson commented 5 years ago

I created a new asciidoc-diagram-to-pdf-example project in a fork and would like to make it work. After that, I would like to update the asciidoc-to-all-example project so it also uses a diagram to show how to make a single project use diagrams with output to html5 and pdf.

Is one of the examples in this issue the recommended approach?

mojavelinux commented 5 years ago

@jeffcjohnson You could enhance asciidoc-diagram-to-html-example to produce both html and pdf. If you aren't keen on that idea, then I'd recommend adding a separate project / folder. Feel free to submit the PR and I'm sure it will get merged.

jeffcjohnson commented 5 years ago

@mojavelinux I created the example to show how it could be done and failed. I was hoping someone that knew more about the project would be able to show where I went wrong.

mojavelinux commented 5 years ago

Oops, I missed that you had submitted https://github.com/asciidoctor/asciidoctor-gradle-examples/pull/49.

The reason it failed is because you were ahead of your time. Using the latest versions, it should now work. I'll give it a quick test.

mojavelinux commented 5 years ago

With a few upgrades, it works.

The last step would be to merge it with asciidoc-diagram-to-html-example into a single example named asciidoctor-diagram-example. I don't think the "to" part is needed. The focus is on Asciidoctor Diagram, not the output.

jeffcjohnson commented 5 years ago

@mojavelinux thank you! I will try to get your suggestions into the PR for your review.