Working with the Docs

The THREDDS project utilizes Jekyll for building and organizing documentation. We use JRuby to run Jekyll, and have included into our gradle build system. Jekyll can build an html based documentation set for publication on the web, which we run in an automated fashon and publish to our nexus server with each github commit. Jekyll also has the capability to stand up a local webserver to allow for live editing of the documentation. Simply execute the following from the command line at the top level of the github repo:

./gradlew serveUserGuide 

Once the appropriate ruby gems have been downloaded, Jekyll will start:

Configuration file: C:\Users\lesserwhirls\dev\unidata\repos\thredds\50\docs\src\public\userguide/_config.yml
Configuration file: C:\Users\lesserwhirls\dev\unidata\repos\thredds\50\docs\src\public\userguide/_config.yml
            Source: C:\Users\lesserwhirls\dev\unidata\repos\thredds\50\docs\src\public\userguide
       Destination: C:\Users\lesserwhirls\dev\unidata\repos\thredds\50\docs\build\userguide
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 6.778 seconds.
  Please add the following to your Gemfile to avoid polling for changes:
    gem 'wdm', '>= 0.1.0' if Gem.win_platform?
 Auto-regeneration: enabled for 'C:\Users\lesserwhirls\dev\unidata\repos\thredds\50\docs\src\public\userguide'
Configuration file: C:\Users\lesserwhirls\dev\unidata\repos\thredds\50\docs\src\public\userguide/_config.yml
    Server address: http://127.0.0.1:4005/
  Server running... press ctrl-c to stop.

Note the Server address in the output - this is where you should point your browser to see a live view of the documentation. Each time a documentation file is edited and saved, Jekyll will regenerate the html file:

Regenerating: 1 file(s) changed at 2018-10-08 17:10:10 ...done in 5.132 seconds.

If there is an error in the markdown syntax, a message will appear on the command line, like so:

Regenerating: 1 file(s) changed at 2018-10-08 17:14:34   Liquid Exception: Liquid error (line 2): Invalid syntax for include tag: ~~~ ## General Kramdown Syntax Jekyll uses kramdown, which is a superset of Markdown. General kramdown syntax can be found here: <https://kramdown.gettalong.org/syntax.html>){:target="_blank"} ## Documentation Theme for Jekyll We use the Documentation Theme for Jekyll. Information on how the theme works can be found here: <http://idratherbewriting.com/documentation-theme-jekyll/index.html>){:target="_blank"} ## Front Matter Each markdown file needs to start with some front matter: ~~~md title: Documentation Guide last_updated: 2016-09-27 sidebar: netcdfJavaTutorial_sidebar toc: false permalink: doc_guide.html ~~~ ## Headers All headings start off as level 2. The `title` set in the front matter will be displayed at the top of the rendered html page and uses the level 1 heading. Headings, and their level number, are denoted by the number of hashtags on a line: # level 1 ## level 2 ### level 3 ~~~md # level 1 ## level 2 ### level 3 ~~~ ## netCDF-Java, TDS jargon italicize TDS specific jargon on first use: _catalog roots_ _client catalog_ _configuration catalog_ ~~~md _catalog roots_ _client catalog_ _configuration catalog_ ~~~ inline text html, xml elements, properties, code variables, snippits, file paths, surround in back ticks, like this: `<catalog>` ~~~md `<catalog>` ~~~ ## Keeping git diffs clean One line of text per line in file blank line needed for new paragraph, so no formatting issue in doing this. this keeps git diff clean ~~~md One line of text per line in file blank line needed for new paragraph, so no formatting issue in doing this. this keeps git diff clean ~~~ ## links General format is: ~~~md [text of link](url){:target="_blank"} ~~~ When linking between markdown files, the `url` will be the permalink defined in the front matter of the markdown file you wish to link to. ## highlight blocks These templates under the top level `_includes/` directory. Here is what we have right now: {%include troubleshooting.html content=" Troubleshooting block. " Valid syntax: {%include troubleshooting.html content=" Troubleshooting block. " Valid syntax: {% include file.ext param='value' param2='value' %} in pages/netcdfJava/developer/DocGuide.md block. "

Note that these errors are often cryptic, so it is a good idea to save and force Jekyll to regenerate often.

General Kramdown Syntax

Jekyll uses kramdown, which is a superset of Markdown. General kramdown syntax can be found here:

https://kramdown.gettalong.org/syntax.html

Documentation Theme for Jekyll

We use the Documentation Theme for Jekyll. Information on how the theme works can be found here:

http://idratherbewriting.com/documentation-theme-jekyll/index.html

Front Matter

Each markdown file needs to start with some front matter:

title: Documentation Guide
last_updated: 2016-09-27
sidebar: netcdfJavaTutorial_sidebar
toc: false
permalink: doc_guide.html

Headers

All headings start off as level 2. The title set in the front matter will be displayed at the top of the rendered html page and uses the level 1 heading. Headings, and their level number, are denoted by the number of hashtags on a line:

level 1

level 2

level 3

# level 1
## level 2
### level 3

netCDF-Java, TDS jargon

italicize TDS specific jargon on first use:

catalog roots

client catalog

configuration catalog

_catalog roots_

_client catalog_

_configuration catalog_

inline text html, xml elements, properties, code variables, snippits, file paths, surround in back ticks, like this:

<catalog>

`<catalog>`

Keeping git diffs clean

One line of text per line in file blank line needed for new paragraph, so no formatting issue in doing this. this keeps git diff clean

One line of text per line in file
blank line needed for new paragraph, so no formatting issue in doing this.
this keeps git diff clean

General format is:

[text of link](url){:target="_blank"}

When linking between markdown files, the url will be the permalink defined in the front matter of the markdown file you wish to link to (do not include a leading /). Also, when linking between markdown files, drop the {:target="_blank"} markup, as we want pages of the tutorial to open in the same window.

highlight blocks

These templates under the top level _includes/ directory. Here is what we have right now:

{%include troubleshooting.html content="
Troubleshooting block.
" %}

{%include note.html content="
Note block.
" %}

{%include important.html content="
Important block.
" %}

{%include question.html content="
Question block.
" %}

{%include ahead.html content="
Thinking ahead block
" %}

{%include warning.html content="
Warning block
" %}

Note - if you want to include a link inside a highlight block that opens in a new window, you will need to use actual html, like:

<a href=\"https://tomcat.apache.org/tomcat-8.0-doc/config/realm.html\" target=\"_blank\">

So, for example:

{%include ahead.html content="
Tomcat Realms:
A <a href=\"https://tomcat.apache.org/tomcat-8.0-doc/config/realm.html\" target=\"_blank\">realm</a> element represents a database of usernames, passwords, and roles (similar to Unix groups) assigned to those users.
" %}

looks like:

files

To include a link to download a file contained within the documentation, use:

{% include link_file.html file="<path to file starting directly under files/>" text="my link text" %}

For example, to link the NcML file $PATH_TO_GIT_REPO/docs/src/public/userguide/files/netcdfJava_tutorial/ncml/basic_ncml/exercise1.ncml , like this:

my link text

use:

{% include link_file.html file="netcdfJava_tutorial/ncml/basic_ncml/exercise1.ncml" text="my link text" %}

images

Image

{% include image.html file="<location of image starting at images/>" alt="alt text" caption="caption" %}

Note that you must always include a caption, even if it is empty. For example, to link to the image $PATH_TO_GIT_REPO/docs/src/public/userguide/images/sl_website-under-construction.jpeg:

alt text
{% include image.html file="sl_website-under-construction.jpeg" alt="alt text" caption="" %}

To add an image in line, like this → Save button , use:

{% include inline_image.html file="netcdf-java/tutorial/basic_ncml/Save.jpg" alt="Save button" %}

Sidebar information can be found under _data/sidebars/. For example, the sidebar used in the TDS Tutorial is _data/sidebars/tdsTutorial_sidebar.yml. If you add a new sidebar, you will need to make sure to add it to the _config.yml file at the top level of the docs directory.`

Indenting text, code blocks, etc. in a list:

  1. Restart Tomcat so the TDS is reinitialized:

    $ cd ${tomcat_home}/bin
    $ ./shutdown.sh
    $ ./startup.sh
    
    ~~~bash
    $ cd ${tomcat_home}/bin
    $ ./shutdown.sh
    $ ./startup.sh
    ~~~
    

    All indented text are aligned with the "R" in "Restart", which is 3 spaces. Alignment is with the start of the text in the bullet of the list. This works the same way with nested lists.

  2. Using the ~ character in code blocks

    In order to get the ~~~bash~~~ and ~~~ to show up in the code block above, I had to do the following:

    ~~~~~md
    ~~~bash
    $ cd ${tomcat_home}/bin
    $ ./shutdown.sh
    $ ./startup.sh
    ~~~
    ~~~~~
    

    Whatever hightlighting you would like, just make sure it has more ~ characters than any nested code blocks.

Include content contained in external file

In order to link the same content in multiple tutorials or documentation sets, you need to keep the actual content in a separate file that the markdown file containing the frontmatter. Take this guide for example. This guide is used in both the netCDF-Java tutorial and the TDS Tutorial. In order to do this, we need to create a markdown for each tutorial. For example, pages/tds_tutorial/developer/DocGuide.md

---
title: Documentation Guide
last_updated: 2017-02-17
sidebar: netcdfJavaTutorial_sidebar
toc: false
permalink: tds_doc_guide.html
---

{% capture rmd %}{% includefile pages/netcdfJava/developer/DocGuide.inc %}{% endcapture %}
{{ rmd | liquify | markdownify }}

and pages/netcdfJava/developer/DocGuide.md

---
title: Documentation Guide
last_updated: 2017-02-17
sidebar: netcdfJavaTutorial_sidebar
toc: false
permalink: doc_guide.html
---

{% capture rmd %}{% includefile pages/netcdfJava/developer/DocGuide.inc %}{% endcapture %}
{{ rmd | liquify | markdownify }}

Each markdown file contains both identical (title, last_update, toc) as well as unique (sidebar, permalink) frontmatter, but references the same actual content, which is contained within the file pages/netcdfJava/developer/DocGuide.inc This is the only way to have the same information contained within different tutorials, while preserving the tutorial sidebar.

Yes, this is ugly. First, we capture the raw text and store it as a string called "rmd". From there, the string is passed through two Liquid Filters - liquify and markdownify. "liquify" interprets the liquid tags in the file, and markidownify renders any markdown in the text. Note that the filters must be applied in this order.

Include code snippets contained elsewhere in the project

To import code snippets directly from project files, use the "includecodeblock" tag. The tag takes the following arguments:

  • name of the project home directory
  • path to the file containing the code snippet, relative to the home directory
  • either:
    • name of a function to include
    • first and last line numbers of code to include

Arguments to the tag are separated by the ‘&’ character.

For example, including the function openNCFile from netcdf-java/docs/src/test/java/examples/cdmdatasets/ReadingCdmTutorial.java would be written like this:


{% capture rmd %}
{% includecodeblock netcdf-java&docs/src/test/java/examples/cdmdatasets/ReadingCdmTutorial.java&openNCFile %}
{% endcapture %}
{{ rmd | markdownify }}

The markdownified text would look like this:

try (NetcdfFile ncfile = NetcdfFiles.open(pathToYourFileAsStr)) {
  // Do cool stuff here
} catch (IOException ioe) {
  // Handle less-cool exceptions here
  logger.log(yourOpenNetCdfFileErrorMsgTxt, ioe);
}

Alternatively, to include the same code snippet by line number:


{% capture rmd %}
{% includecodeblock netcdf-java&docs/src/test/java/examples/cdmdatasets/ReadingCdmTutorial.java&33&38 %}
{% endcapture %}
{{ rmd | markdownify }}

The include-by-line-numbers option is provided since not all documented code can be isolated in a function. However, when code blocks are included by function name, the blocks will update automatically if the code is edited such that the line numbers change; for code blocks included by line numbers, markdown files will need to be manually updated.

To exclude lines of Java code from the documentation, add the /* DOCS-IGNORE */ tag to the line. For example, the following function:

 public static Array readAllVarData(Variable v) throws IOException {
    Array data = v.read();
    return data; /* DOCS-IGNORE */
  }

will render as:

Array data = v.read();

The allows code included in the documentation to log or return values for the purpose of testing.

Conversely, the /* INSERT ... */ tag will render enclosed text in the documentation, for example:

/* INSERT private */ArrayInt.D1 dateArray;

will render as:

private ArrayInt.D1 dateArray;