blob: 7b1d4bb3c308e402ad686d7baa400d037cb136d3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask
import org.apache.groovy.gradle.ConcurrentExecutionControlBuildService
plugins {
id 'org.asciidoctor.jvm.convert'
}
configurations {
asciidocElements {
canBeConsumed = true
canBeResolved = false
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.DOCUMENTATION))
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType, DocsType.USER_MANUAL))
}
outgoing {
artifact tasks.named('asciidoctor')
}
}
}
tasks.withType(AbstractAsciidoctorTask).configureEach {
outputs.cacheIf { true }
usesService(ConcurrentExecutionControlBuildService.restrict(AbstractAsciidoctorTask, gradle))
}
asciidoctor {
baseDirFollowsSourceFile()
def (full, major, minor, patch, flavor) = (groovyVersion =~ /(\d+)\.(\d++)\.(\d+)(?:-(.+))?/)[0]
logDocuments = true
sourceDir = project.file('src/spec/doc')
sources {
include '*.adoc'
}
outputDir = "$buildDir/asciidoc/html5"
resources {
duplicatesStrategy = DuplicatesStrategy.WARN
from("${rootProject.projectDir}/src/spec/doc/assets") {
include 'css/style.css'
}
from("$buildDir/tmp/asciidoctor-assets")
into 'assets'
}
forkOptions {
jvmArgs("--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", "--add-opens", "java.base/java.io=ALL-UNNAMED")
}
attributes 'source-highlighter': 'prettify',
groovyversion: groovyVersion,
'groovy-major-version': major,
'groovy-minor-version': minor,
'groovy-patch-version': patch,
'groovy-full-version': groovyVersion,
'groovy-short-version': "${major}.${minor}",
doctype: 'book',
revnumber: groovyVersion,
icons: 'font',
toc2: '',
linkcss: '',
stylesheet: "assets/css/style.css",
encoding: 'utf-8',
toclevels: 10,
numbered: '',
sectanchors: true,
sectlinks: true
}
asciidoctorj {
jrubyVersion = versions.jruby
version = versions.asciidoctorj
def vers = versions.groovy
resolutionStrategy {
it.disableDependencyVerification()
}
docExtensions {
def baseUrls = [
jdk: 'https://docs.oracle.com/en/java/javase/11/docs/api/index.html',
gjdk: "https://docs.groovy-lang.org/${vers}/html/groovy-jdk/index.html",
gapi: "https://docs.groovy-lang.org/${vers}/html/gapi/index.html",
gapid: "https://docs.groovy-lang.org/${vers}/html/gapi/",
]
baseUrls.each { macroName, baseURL ->
inline_macro(name: macroName) {
parent, target, attributes ->
def (className, anchor) = target.split('#') as List
def base = className == 'index' ?
baseURL : baseURL + '?' + className.replace('.', '/') + '.html' + (anchor ? '#' + anchor : '')
createPhraseNode(parent, 'anchor', attributes.text ?: target, attributes, [type: ':link', target: base])
}
}
}
modules {
diagram.version(versions.asciidoctorDiagram)
pdf.version(versions.asciidoctorPdf)
groovyDsl.version(versions.asciidoctorGroovyDsl)
}
}
// skip the asciidoctor task if there's no directory with asciidoc files
asciidoctor.onlyIf { project.file('src/spec/doc').exists() }
def asciidoctorAssets = tasks.register("asciidoctorAssets", Copy) {
from project.fileTree('src/spec/doc/assets')
into "$buildDir/tmp/asciidoctor-assets"
}
asciidoctor.dependsOn asciidoctorAssets
def adocSanityCheck = { file, text, errors ->
Set localErrors = []
text.eachLine(1) { line, i ->
if (line =~ /tag:[a-zA-Z0-9]/) {
localErrors << "line $i misses semicolon. Should be tag::\n $line"
}
if (line =~ /end:[a-zA-Z0-9]/) {
localErrors << "line $i misses semicolon. Should be end::\n $line"
}
if (line =~ /(tag|end)::[^\[\]]$/) {
localErrors << "line $i contains incorrect tag definition (misses []):\n $line"
}
}
localErrors.collect(errors) { " $file, $it" }
}
def htmlOutputSanityCheck = { file, text, errors ->
Set localErrors = []
text.eachLine(1) { line, i ->
if (line =~ /^={1,5} /) {
localErrors << "line $i starting with asciidoctor raw markup:\n$line"
}
if (line =~ /<code class=".+?"><\/code>/) {
localErrors << "contains empty code block, probably incorrect import of a tag."
}
if (line =~ /(gapi|jdk|gjdk):(\S.+?)/) {
localErrors << "line $i starting with asciidoctor raw markup:\n$line"
}
}
localErrors.collect(errors) { " $file, $it" }
}
asciidoctor {
def errors = new LinkedHashSet<String>()
doFirst {
def specTestDir = file('src/spec/test')
if (specTestDir.exists()) {
specTestDir.eachFileRecurse { file ->
if (file.isFile()) {
adocSanityCheck(file, file.getText('utf-8'), errors)
}
}
}
if (errors) {
throw new GradleException("Incorrect Asciidoctor input:\n${errors.join('\n')}")
}
}
doLast {
def scripts = '''<link rel="stylesheet" href="assets/css/view-example.css">
<script src='assets/js/jquery-min-2.1.1.js'></script>
<script src='assets/js/view-example.js'></script>'''
// gapi macro expansion
outputDir.eachFileMatch(~'.*html') { File file ->
def text = file.getText('UTF-8')
text = text.replaceAll('</head>', "$scripts</head>")
htmlOutputSanityCheck(file, text, errors)
file.write(text, 'UTF-8')
}
if (errors) {
throw new GradleException("Incorrect Asciidoctor output:\n${errors.join('\n')}")
}
}
}