= 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 link:CODE_OF_CONDUCT.adoc[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 https://cla.pivotal.io/sign/spring[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 https://gradle.org[Gradle] on JDK 1.8 or above. We include https://docs.gradle.org/current/userguide/gradle_wrapper.html[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: [indent=0] ---- $ ./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: . An AsciidoctorJ compatible extension providing the backends . 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 https://www.rubydoc.info/gems/asciidoctor/Asciidoctor/Converter[Asciidoctor::Converter] implementation. ==== Ruby Code The main converter implementation is written in Ruby. You can find the code in the link:src/main/ruby[`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 link:src/main/ruby[`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 link:src/main/java[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 link:src/test/java[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. [source,shell] ---- $ 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: [source,shell] ---- $ npm install ---- Then run it with the `build` target: [source,shell] ---- $ 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 `