Skip to content

Latest commit

 

History

History
229 lines (144 loc) · 8.19 KB

CONTRIBUTING.adoc

File metadata and controls

229 lines (144 loc) · 8.19 KB

Contributing to Asciidoctor Spring Backends

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.

Code of Conduct

This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.

Sign the Contributor License Agreement

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.

Building from Source

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

Working with the Code

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:

  1. An AsciidoctorJ compatible extension providing the backends

  2. A set of web assets (CSS & Javascript) used by the HTML generated by the backend.

AsciidoctorJ Backend

The AsciidoctorJ backend is Ruby and Java code that provides a Asciidoctor::Converter implementation.

Ruby Code

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.

Java Code

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.

Hacking on the Ruby Code

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

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 and site.js files in the /js folder.

  • Images in the /img folder.

Build

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.

Javascript

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 a js class to the html 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

CSS

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

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

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.

Hacking on the web assets

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".

Formatting

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.