Skip to content

Commit

Permalink
Allow for downloadable PDF themes (asciidoctor#186)
Browse files Browse the repository at this point in the history
Themes are registered via a `pdfThemes` extension. Themes can be local or
downlaodable from GitLab or GitHub repositories. `AsciidoctorJPdfTask`
instances have a `theme` property which refers to a registered theme
on the extension.
  • Loading branch information
ysb33r committed Jul 27, 2018
1 parent 5bde12b commit 80849ac
Show file tree
Hide file tree
Showing 9 changed files with 390 additions and 48 deletions.
55 changes: 50 additions & 5 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,10 @@ By convention it sets the

== The AsciidoctorPdf Plugin

When applying `org.asciidoctor.jvm.pdf` it creates a single task of type `org.asciidoctor.gradle.jvm.AsciidoctorPdfTask` which is then configured to:
When applying `org.asciidoctor.jvm.pdf` it creates a single task of type `org.asciidoctor.gradle.jvm.AsciidoctorPdfTask` an extension called `pdfThemes`


The default task is named `asciidoctorPdf` and is configured to:

* Output source to "${buildDir}/docs/asciidocPdf"
* Not to copy any resources to the output directory
Expand All @@ -466,11 +469,53 @@ When applying `org.asciidoctor.jvm.pdf` it creates a single task of type `org.as
The `AsciidoctorPdfTask` task type has the following additional methods:

[horizontal]
fontsDir:: Directory for custom PDF fonts
fontsDir:: Directory for custom PDF fonts.
Specify a directory in any form acceptable to `project.file`. Using this instead of directly setting the `pdf-fontsdir` attribute means that Gradle will be able to check out of date status dependent on the content of this folder.
stylesDir:: Directory for finding a theme.
Specify a directory in any form acceptable to `project.file`. Using this instead of directly setting the `pdf-stylesdir` attribute means that Gradle will be able to check out of date status dependent on the content of this folder.
styleName: Name of the PDF theme.
theme:: Name of the theme to use.
Optional. When specifying a theme name it must match one registered via `pdfThemes`.

The `pdfThemes` extension allows for themes to be registered from local copies or downloaded from GitHub or GitLab and has been inspired by earlier work of Florian Wilhelm (@fwilhe).

.Registering a local theme
[source,groovy]
----
pdfThemes {
local 'basic', { // <1>
styleDir = file('themes/basic') // <2>
styleName = 'very-basic' // <3>
}
}
----
<1> Local themes are registered using the `local` keyword and must be provided with a name
<2> Directory for finding the theme. Specify a directory in any form acceptable to `project.file`.
<3> Optional setting of the style name. If this is not set the theme name provided previsouly will be used.

.Registering a GitHub or GitLab theme
[source,groovy]
----
pdfThemes {
github 'basic', { // <1>
organisation = 'fwilhe' // <2>
repository = 'corporate-theme' // <3>
relativePath = 'resources/themes' // <4>
branch = 'master' // <5>
tag = '1.0.1' // <6>
commit = '4910271e8c3964b60e186a62f3e4339ed0752714' // <7>
}
}
----
<1> Specify a GitHub repository which contains one or more themes. (For GitLab replace `github` with `gitlab`).
<2> GitHub/GitLab Organisation (or user).
<3> Name of repository containing the theme(s).
<4> Relative path inside the repository to where the theme is located. If not speciified the theme is assumed to be in the root of the repository.
<5> Specify the branch
<6> Instead of a branch a tag can be used.
<7> Instead of a branch or a tag, a very specific commit can be used.

If a repository contains more than one theme, then the block will need to be repeated for each theme and the `name` and `relativePath` adjusted accordingly. Gradle will however, only downlaod the repository once.

Kotlin users can use equivalent `Action`-based configurations.

== The AsciidoctorEpub Plugin

Expand Down
1 change: 1 addition & 0 deletions asciidoctor-gradle-jvm/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ configurePlugin 'org.asciidoctor.jvm.pdf',

test {
systemProperties ROOT_PROJECT_DIR: rootProject.projectDir.absolutePath
systemProperties TEST_THEMES_DIR: file('src/test/resources/themes')
}

intTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,15 @@ asciidoctorPdf {
void 'Custom theme for PDF'() {
given:
getBuildFile("""
pdfThemes {
local 'basic', {
styleDir = 'src/docs/asciidoc/pdf-theme'
}
}
asciidoctorPdf {
theme 'basic'
sourceDir 'src/docs/asciidoc'
styleName 'basic'
stylesDir 'src/docs/asciidoc/pdf-theme'
fontsDir 'src/docs/asciidoc/pdf-theme'
}
""")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ class AsciidoctorJPdfPlugin implements Plugin<Project> {

void apply(Project project) {
project.with {
apply plugin : 'org.asciidoctor.jvm.base'
apply plugin: 'org.asciidoctor.jvm.base'

extensions.create(AsciidoctorPdfThemesExtension.NAME, AsciidoctorPdfThemesExtension, project)

AsciidoctorPdfTask task = tasks.create('asciidoctorPdf', AsciidoctorPdfTask)
task.group = AsciidoctorJBasePlugin.TASK_GROUP
task.description = 'Convert AsciiDoc files to PDF format'
task.outputDir = { "${project.buildDir}/docs/asciidocPdf"}
task.outputDir = { "${project.buildDir}/docs/asciidocPdf" }
extensions.getByType(AsciidoctorJExtension).pdfVersion = AsciidoctorJExtension.DEFAULT_PDF_VERSION

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@ package org.asciidoctor.gradle.jvm
import groovy.transform.CompileStatic
import org.asciidoctor.gradle.internal.AsciidoctorUtils
import org.gradle.api.Project
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.UnknownDomainObjectException
import org.gradle.api.tasks.*
import org.gradle.api.tasks.util.PatternSet
import org.gradle.util.GradleVersion
import org.gradle.workers.WorkerExecutor
import org.ysb33r.grolifant.api.StringUtils

import javax.inject.Inject

Expand All @@ -39,8 +35,7 @@ import javax.inject.Inject
class AsciidoctorPdfTask extends AbstractAsciidoctorTask {

private Object fontsDir
private Object stylesDir
private Object styleName
private String theme

@Inject
AsciidoctorPdfTask(WorkerExecutor we) {
Expand Down Expand Up @@ -73,26 +68,24 @@ class AsciidoctorPdfTask extends AbstractAsciidoctorTask {
this.fontsDir = f
}

/** Set the tehem to be used from the {@code pdfThemes} extension.
*
* @param themeName
*/
void setTheme(final String themeName) {
this.theme = themeName
}

/** The directory where custom theme is to be found.
*
* @return Directory or {@code null} is no directory was set.
* @throw {@link UnknownDomainObjectException} if theme was specified, but not registered.
*/
@InputDirectory
@PathSensitive(PathSensitivity.RELATIVE)
@Optional
File getStylesDir() {
this.stylesDir != null ? project.file(this.stylesDir) : null
}

/** Specify a directory where to load custom theme from.
*
* This will set the {@code pdf-stylesdir} attribute
*
* @param f Directory where custom syles can be found. anything convertible with {@link Project#file}
* can be used.
*/
void setStylesDir(Object f) {
this.stylesDir = f
this.theme != null ? project.extensions.getByType(AsciidoctorPdfThemesExtension).getByName(this.theme).styleDir : null
}

/** The theme to use.
Expand All @@ -102,18 +95,7 @@ class AsciidoctorPdfTask extends AbstractAsciidoctorTask {
@Input
@Optional
String getStyleName() {
this.styleName != null ? StringUtils.stringize(this.styleName) : null
}

/** The name of the YAML theme file to load.
*
* If the name ends with {@code .yml}, it’s assumed to be the complete name of a file.
* Otherwise, {@code -theme.yml} is appended to the name to make the file name (i.e., {@code <name>-theme.yml}).
*
* @param s Name of style (theme).
*/
void setStyleName(Object s) {
this.styleName = s
this.theme != null ? project.extensions.getByType(AsciidoctorPdfThemesExtension).getByName(this.theme).styleName : null
}

/** Selects a final process mode of PDF processing.
Expand All @@ -125,8 +107,8 @@ class AsciidoctorPdfTask extends AbstractAsciidoctorTask {
*/
@Override
protected ProcessMode getFinalProcessMode() {
if(GradleVersion.current() <= LAST_GRADLE_WITH_CLASSPATH_LEAKAGE && AsciidoctorUtils.OS.windows) {
if(inProcess != JAVA_EXEC) {
if (GradleVersion.current() <= LAST_GRADLE_WITH_CLASSPATH_LEAKAGE && AsciidoctorUtils.OS.windows) {
if (inProcess != JAVA_EXEC) {
logger.warn 'PDF processing on this version of Gradle combined with running on Microsoft Windows will fail due to classpath issues. Switching to JAVA_EXEC instead.'
}
JAVA_EXEC
Expand Down Expand Up @@ -161,18 +143,18 @@ class AsciidoctorPdfTask extends AbstractAsciidoctorTask {
Map<String, Object> attrs = super.getTaskSpecificDefaultAttributes(workingSourceDir)

File fonts = getFontsDir()
if(fonts != null) {
if (fonts != null) {
attrs['pdf-fontsdir'] = fonts.absolutePath
}

File styles = getStylesDir()
if(styles != null) {
if (styles != null) {
attrs['pdf-stylesdir'] = styles.absolutePath
}

String theme = getStyleName()
if(theme != null) {
attrs['pdf-style'] = theme
String selectedTheme = getStyleName()
if (selectedTheme != null) {
attrs['pdf-style'] = selectedTheme
}

attrs
Expand Down
Loading

0 comments on commit 80849ac

Please sign in to comment.