W06: Sass vs CSS

This week was spent on doing some follow-up work on the doctesting PR (#774) and working on incorporating the Bulma-based SCSS theme into Documenter. In addition to that, I also worked on a set of small maintenance PRs (#1056, #1058, #1059, #1060).

Bulma-based front end

The latest version of the front end code now lives in #1043. A part of this week was spent on just fiddling around with the theme, making small UI fixes.

The SCSS source files are now incorporated into Documenter in that PR. The idea is that Documenter will ship with the SCSS source files and the compiled CSS files. The latter are necessary so that you would not have to rebuild the CSS files every time you run makedocs. It will save slightly on build time but, more importantly, it avoids having to add too many dependencies to Documenter.

I decided to vendor the Sass sources of the external dependencies (Bulma, Bulma Dashboard, Darkly theme) so that we would not have to worry about downloading and verifying remote dependencies on every Documenter install. That would require a non-trivial deps/build.jl script to make sure that it works cross-platform.

DocumenterTools provides the actual functions that can be used to easily compile a theme. The first iteration is available in #27, in a new Themes submodule and uses the LibSass library via Sass.jl.

The API in DocumenterTools currently ended up being much simpler than I anticipated. It simply provides two functions at the moment:

  • Themes.compile_native_theme(theme_name): compiles a theme that ships with Documenter.jl and places it in the correct place in the Documenter package directory. This is intended to be used when developing the native themes for Documenter.

  • Themes.compile(source[, destination]): compiles the file source, while setting up the LibSass include paths appropriately, so that the Sass compiler can find the Documenter and Bulma Sass/SCSS files.

Documenter's HTMLWriter module also defines a few variables that DocumenterTools uses to determine what natives theme Documenter has (HTMLWriter.THEMES), where the Sass source files live in the Documenter repository (HTMLWriter.ASSETS_SASS) and where the compiled themes should be placed (HTMLWriter.ASSETS_THEMES). This is to slightly future proof things, in case we want to re-organize the files in the repository.

The Themes module in DocumenterTools also contains a simple FileWatching-based tool to automatically recompile themes as you change the Sass files.

Keeping CSS up to date. To make sure that the compiled CSS files that Documenter ships with do not get outdated as the Sass files are edited, I added a new Travis build stage for Documenter, which just verifies that the CSS files in the repository are exactly the same as the ones you get if you compile the Sass sources.

It assumes that LibSass produces a deterministic output. Since I am not sure if that is the case, at least across different versions of LibSass, I did not want to integrate this check into the standard test suite. If the Travis checks start failing at some point, we can just ignore them if need be. But test failures would mean that previously successful tagged versions suddenly start failing tests.

Doctesting

On Monday, I finally merged #774, which refactored aspects of doctesting and allows doctests to be run separately from the rest of the manual build.

However, the hook to integrate doctesting into the test suite implemented in that PR was not ideal. So, based on feedback, I implemented an improved version in #1054 this week.

using Test, Documenter, MyPackage
@testset "MyPackage" begin
    ... # other tests & testsets
    doctest(MyPackage)
    ... # other tests & testsets
end

This will verify all the doctests in all docstrings and manual pages, and it also integrates with testsets (in fact, the doctest call basically is a testset). It currently only reports the doctesting a single test, but that can hopefully be improved in the future (#1053).

You can also run that function in the REPL and pass fix=true, to fix all the doctests in a package:

julia> using Documenter, MyPackage

julia> doctest(MyPackage, fix=true)

This provides a more straightforward interface for fixing outdated doctests, compared to the old way where you had to edit the make.jl script.

Next week

Next week I need to focus on wrapping up the first iteration of the new front end. I want to merge #1043 relatively soon (after ticking off the TODOs in the issue) and then additional theme fixes to the front end can be done in separate follow-up PRs.

Once #1043 is merged, I can also start properly implementing the new APIs for managing JS dependencies. As that is a separate relatively large change, I would prefer to do it in a separate PR. But at the same time, it conflicts quite a bit with the front end refactoring.