AsciidoctorJ macro to include dynamically other AsciiDoc files.
URLs
-
Project home (this page)
Do you want to improve this page? Please edit it on GitHub. |
Description
AsciidoctorJ dynamic-include is an extension for AsciidoctorJ that allows to include files using a globbing pattern.
More concretely instead of including different files one by one:
= My book
include::content/chapter01.adoc[]
include::content/chapter02.adoc[]
include::content/chapter03.adoc[]
It is possible to include them all with a single include:
= My book
include::dynamic:content/*.adoc[]
Ordering pages
To control the order of the included files, the approach using pages.yaml
described in the project path-order can be used.
Title level correction
The processor will take care of the title levels.
Each file can start with a level 2: == My title
Meaning that they are valid documents individually.
When the pages are combined using the dynamic-include, the processor will add the corresponding :leveloffset:
necessary to have a consistent level.
A sub-folder will correspond to a shift of one in the hierarchy, with a special processing of the index.adoc
page.
This allows to have a tree structure like this:
├── chapter-one │ ├── content-section │ │ ├── content-1.adoc │ │ ├── content-2.adoc │ │ └── index.adoc │ ├── end-section │ │ └── index.adoc │ ├── index.adoc │ ├── intro.adoc │ └── pages.yaml ├── chapter-three │ ├── index.adoc │ ├── page1.adoc │ └── page2.adoc ├── chapter-two │ ├── index.adoc │ ├── info.adoc │ ├── pages.yaml │ ├── section-1.adoc │ └── section-a.adoc ├── index.adoc ├── index.html └── pages.yaml
xref link correction
When the same title is used several times, Asciidoc is handling the colliding anchors and create unique ids. For My Title
it will create anchors like _my_title
, _my_title_2
, _my_title_3
…
The macro is correcting the xref links accordingly to the title anchor in the final document.
xref link optimization
The macro is normalizing xref links.
When xref link definition contains attributes (like xref:{root}/pages/page1.adoc
) if the attribute value is defined in the main document (the one using the dynamic include macro), then its value will be already replaced before including the content in the main document.
If not defined, the attribute will not be changed, letting Asciidoctor handling the value replacement.
Normalization and anchor correction can only be applied if the targeted file exists (checked first relatively to the main document and secondly relatively to the included document).
Options
All options can be used as attribute of the include processor:
link:dynamic:content/*.adoc[external-xref-as-text="true"]
Or as attribute of the document:
:dynamic-include-external-xref-as-text: true
In this second case it will be applied to all usages of the dynamic-include processor.
level-offset-shifting
-
option
level-offset-shifting
-
or as document attribute
dynamic-include-level-offset-shifting
This option allows to shift the title level of the included document.
This can be useful if you have already some title in the main document.
When not set the default value is 1
.
external-xref-as-text
-
option
external-xref-as-text
-
or as document attribute
dynamic-include-external-xref-as-text
When set, xref
links to pages that are not included in the list of pages are turned to regular text.
logfile
-
option
logfile
-
or as document attribute
dynamic-include-logfile
When set a file listing the pages that are included by the dynamic-include processor will be generated at the location indicated by the value of this option.
Example output:
# File:
# Target: dynamic:pages/*.adoc
# level-offset-shifting: 1
pages/index.adoc (leveloffset: 0)
pages/page1.adoc (leveloffset: +1)
pages/page2.adoc (leveloffset: +1)
suffixes
-
option
suffixes
-
or as document attribute
dynamic-include-suffixes
Following the possibility qualify files introduced by the path-oder project, the suffix is defined as the section between the file name and the extension. For the file page.adoc
(no suffix), following files add a suffix: page.draft.adoc
(draft
suffix), page.advanced.adoc
(advanced
suffix).
By default the files with suffixes are not included by the dynamic include processor.
When suffixes
is specified, the corresponding pages are included after each corresponding file without suffix.
Values are separated with :
.
The order in the list impacts the order of the inclusion.
Given this page tree:
├── document.adoc
└── pages
├── page1.adoc
├── page1.advanced.adoc
├── page1.draft.adoc
├── page2.adoc
├── page2.advanced.adoc
└── page2.draft.adoc
In the main document document.adoc
:
-
include::dynamic:pages/*.adoc[]
will include onlypage1.adoc
andpage2.adoc
. -
include::dynamic:pages/*.adoc[suffixes="draft"]
will includepage1.adoc
,page1.draft.adoc
,page2.adoc
andpage2.draft.adoc
-
include::dynamic:pages/*.adoc[suffixes="draft:advanced"]
will includepage1.adoc
,page1.draft.adoc
,page1.advanced.adoc
,page2.adoc
,page2.draft.adoc
andpage2.advanced.adoc
link to the source file
Before each inclusion it is possible to have a link to the included document.
-
Indicates if the link is present or not:
-
option
display-view-source
-
or as document attribute
dynamic-include-display-view-source
-
-
Pattern of the link:
-
option
view-source-link-pattern
-
or as document attribute
dynamic-include-view-source-link-pattern
-
-
Text of the link:
-
option
view-source-link-text
-
or as document attribute
dynamic-include-view-source-link-text
-
The pattern of the link can use following special attributes (they will be computed dynamically):
-
file-relative-to-git-repository
: path of the file relatively to the folder defined bylocal-git-repository-path
attribute. -
file-relative-to-gradle-projectdir
: path of the file relatively to the folder defined bygradle-projectdir
attribute. -
file-relative-to-gradle-rootdir
: path of the file relatively to the folder defined bygradle-rootdir
attribute. -
file-absolute-with-leading-slash
: absolute path of the file with a leading slash.
Examples setup:
dynamic-include-display-view-source : true
dynamic-include-view-source-link-text : edit in vscode
dynamic-include-view-source-link-pattern : vscode://file{file-absolute-with-leading-slash}.
dynamic-include-display-view-source : true
dynamic-include-view-source-link-text : view in github
dynamic-include-view-source-link-pattern : https://github.com/jmini/asciidoctorj-dynamic-include/blob/HEAD/{file-relative-to-gradle-rootdir}
AsciidoctorJ version
This extension is compatible with org.asciidoctor:asciidoctorj
in range [2.0.0, 3.0.0[
.
The continuous integration server runs the test suite with different AsciidoctorJ versions within this range.
Usage examples
The extension is published on maven central and can be directly consumed from maven or gradle.
Integration in a maven build
You need to declare fr.jmini.asciidoctorj:dynamic-include
as a dependency for the org.asciidoctor:asciidoctor-maven-plugin
plugin.
Your <build>
section could looks like this:
<build>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>${asciidoctor.maven.plugin.version}</version>
<dependencies>
<dependency> (1)
<groupId>fr.jmini.asciidoctorj</groupId>
<artifactId>dynamic-include</artifactId>
<version>2.1.0</version>
</dependency>
<!-- ... (other dependencies) -->
</dependencies>
<configuration>
<!-- ... (other configuration) -->
<attributes>
<dynamic-include-logfile>${project.build.directory}/dynamic-import.log</dynamic-include-logfile>
<local-git-repository-path>${project.basedir}/../../</local-git-repository-path>
<!-- ... (other attributes) -->
</attributes>
</configuration>
<!-- ... (other blocks like executions) -->
</plugin>
<!-- ... (other plugins) -->
</plugins>
</build>
1 | Dependency declaration |
For a complete example, see: pom.xml
Integration in a gradle build
The fr.jmini.asciidoctorj:dynamic-include
jar can be declared as dependency of the asciidoctor
task:
asciidoctor {
configurations 'asciidoctorExtensions'
sourceDir = file('docs')
sources {
include 'index.adoc'
}
baseDirFollowsSourceFile()
outputDir = file('build/generated-docs')
attributes = ['project-version' : "$version",
'dynamic-include-display-view-source' : 'true',
'dynamic-include-view-source-link-text' : 'edit in vscode',
'dynamic-include-view-source-link-pattern' : 'vscode://file{file-absolute-with-leading-slash}',
'attribute-missing' : 'warn',
'toc' : 'left',
'icons' : 'font',
'sectanchors' : 'true',
'idprefix' : '',
'idseparator' : '-']
repositories {
mavenCentral()
}
dependencies {
asciidoctorExtensions 'fr.jmini.asciidoctorj:dynamic-include:2.1.0' (1)
}
}
1 | Dependency declaration |
For a complete example, see: build.gradle
Download
The library is hosted on maven central.
<dependency>
<groupId>fr.jmini.asciidoctorj</groupId>
<artifactId>dynamic-include</artifactId>
<version>2.1.4</version>
</dependency>
Source Code
As for any grade plugin, the source code of the plugin is available in the src/ folder.
Build
This project is using gradle.
Command to build the sources locally:
./gradlew build
The AsciidoctorJ version can be controlled with the asciidoctorjVersion
project property.
The property will influence the strict version in the dependency definition.
This is used to test the extension against a specific AsciidoctorJ version.
Usage example:
./gradlew build -PasciidoctorjVersion=2.2.0
Command to deploy to your local maven repository:
./gradlew publishToMavenLocal
Command to build the documentation page:
./gradlew asciidoctor
The output of this command is an HTML page located at <git repo root>/build/docs/html5/index.html
.
For project maintainers
signing.gnupg.keyName
and signing.gnupg.passphrase
are expected to be set in your local gradle.properties
file to be able to sign.
sonatypeUser
and sonatypePassword
are expected to be set in order to be able to publish to a distant repository.
Command to build and publish the result to maven central:
./gradlew publishToSonatype
Command to upload the documentation page on GitHub pages:
./gradlew gitPublishPush
Command to perform a release:
./gradlew release -Prelease.useAutomaticVersion=true
Using ssh-agent
Some tasks requires pushing into the distant git repository (release task or updating the gh-pages
branch).
If they are failing with errors like this:
org.eclipse.jgit.api.errors.TransportException: ... Permission denied (publickey).
Then ssh-agent
can be used.
eval `ssh-agent -s` ssh-add ~/.ssh/id_rsa
(source for this approach)
Get in touch
Use the AsciidoctorJ dynamic-include issue tracker on GitHub.
You can also contact me on Twitter: @j2r2b