Unless otherwise noted, code in this project is released under the Apache 2.0 license. If you would like to contribute something, or want to hack on the code this document should help you get started.
This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].
Before we accept a non-trivial patch or pull request we will need you to sign the Contributor License Agreement. Signing the contributor’s agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests.
Source can be built from the command line using Gradle on JDK 1.8 or above.
We include Gradle’s wrapper scripts (./gradlew
or gradlew.bat
) that you can run rather than needing to install Gradle locally.
The project can be built from the root directory using the standard Gradle command:
$ ./gradlew build
There are quite a few moving parts to this project and a lot of different technologies involved. The project can broadly be split into two parts:
-
An AsciidoctorJ compatible extension providing the backends
-
A set of web assets (CSS & Javascript) used by the HTML generated by the backend.
The AsciidoctorJ backend is Ruby and Java code that provides a Asciidoctor::Converter implementation.
The main converter implementation is written in Ruby.
You can find the code in the src/main/ruby
folder.
The code delegates to the standard html5
converter, but changes a few areas to give us the HTML that we need.
It also writes the CSS, Javascript and Images to the output directory.
The code needs to be packaged as a Gem so that it can be picked up by AsciidoctorJ.
This means that the Jar needs to have the following layout:
specifications/ spring-asciidoctor-backends-0.0.0.gemspec gems/ spring-asciidoctor-backends-0.0.0/ lib/ spring-asciidoctor-backends data/
Note
|
The version number of the Gem isn’t really important in our case so we set it to 0.0.0 .
|
If you need to edit the gemspec
file you can find it in src/main/gemspec
.
AsciidoctorJ won’t find the converter from the Gem alone, it needs to be told that it’s a requireLibrary
.
This is done with the SpringBackendsExtensionRegistry
class which is registered using META-INF/services
.
The code folding and chomping features are implemented in Java. You can find the code in src/main/java.
There’s a convert_listing_content
method in the Ruby code that uses JRuby features to call the ListingContentConverters
class.
The ListingContentConverters
class is responsible for taking an Asciidoctor node and returning its content in a potentially modified form.
There a bit of adapter logic needed to convert the RubyObject
, but nothing too onerous.
All the project tests are also written in Java. There’s a mixture of both unit tests and integration tests. They’re available at src/test/java.
If you want to iterate quickly on the Ruby code it’s often easier to run it directly rather the using the Gradle build.
You can do this by using the asciidoctor
CLI command.
$ asciidoctor --trace -r ./src/main/ruby/lib/spring-asciidoctor-backends.rb -b spring-html -D build/converted-asciidoc/ src/test/asciidoc/standard.adoc
Note
|
Using asciidoctor directly means that JRuby doesn’t run.
Java calls will not occur and ListingContentConverters features will not apply.
|
Web assets are bundled up inside the Jar and copied out by the Ruby converter. The following web assets are used:
-
site.css
file in the/css
folder. -
setup.js
andsite.js
files in the/js
folder. -
Images in the
/img
folder.
The web assets are all build using GulpJS which is invoked via NPM from the Gradle build. You can also build the web assets directly using the gulp CLI.
Install it using NPM:
$ npm install
Then run it with the build
target:
$ gulp build
The gulp build will do the usual front-end related tasks such as minification and linting.
Take a look gulpfile.js
if you want to see the exact details.
There are two javascript assets produced by the build:
-
setup.js
provides any initial setup and is loaded with a regular<script>
element. -
site.js
provides the majority of the Javascript and is loaded with a<script async>
element.
The source code used to build these files is in src/main/js/setup
and src/main/js/site
respectively.
Tip
|
The setup.js file will block page loading and as such should only be used for critical functionality.
For example, it includes the dark theme switching logic so that the page doesn’t flash when loading.
|
The following files are used to create the setup.js
file:
-
layout.js
- Adds ajs
class to thehtml
element for CSS to use for Javascript detection. -
switchtheme.js
- Provides theme switcher logic
The following files are used to create the site.js
file:
-
codetools.js
- Provides the copy and fold/unfold buttons -
highlight.js
- Provide a HighlightJS bundle -
tabs.js
- Provides tab switching support -
toc.js
- Updates the table of contents when scrolling
The single site.css
file is build from a number of smaller CSS files.
CSS files can be found in src/main/css
.
PostCSS is used to follow @Import
declarations and create a single file.
Although it’s a little overkill for this project, CSS files are organized using the inverted triangle architecture.
-------------- _ \ / __ settings : (settings.css, settings-dark.css) \ / ___ tools : (none) \ / ____ generic : (generic.css) \ / _____ elements : (elements.css) \ / ______ objects : (none) \ / _______ components : (components.css) \/ _________utilities : (none)
CSS variables are used extensively for colors and variable styling.
The settings.css
file contains initial settings and settings-dark.css
provides dark-mode overrides.
Variables are usually scoped to a specific area and then reference a more generic value.
For example, --toc-font-color
is the font color of the TOC.
It has the value var(--body-font-color)
which references the general body font color.
Images are available in the src/main/img
folder.
It’s best to use SVG images as much as possible.
A single octicons-16.svg
file provides all the 16x16 icons used by the CSS.
This file contains a subset of the icons from https://github.com/primer/octicons.
If you need to work on the web assets you can run the following Gradle task:
$ ./gradlew dev
Alternatively you can generate some test HTML and the run gulp
directly:
$ ./gradlew convertTestAsciidoc
$ gulp dev
Note
|
The convertTestAsciidoc Gradle task will convert the contents of the src/test/asciidoc directory.
|
The dev
task will start a server at http://localhost:8080
and watch the source files for changes.
Saving any source file will trigger a rebuild and "live reload".
Java, Javascipt and CSS files can be formatted by running ./gradlew format
.
Java files are formatted using spring-javaformat
.
Other files are formatted using prettier.