Skip to content
Permalink
master
Switch branches/tags
Go to file
6 contributors

Users who have contributed to this file

@martinklepsch @lread @SevereOverfl0w @bbatsov @mfikes @mjhanninen

cljdoc for Library Authors

Why cljdoc?

cljdoc aims to automate as much as possible of the process of publishing documentation. This means you get to spend time on crafting great documentation while cljdoc takes care of publishing and serving them to your users.

Basic Setup

For basic docs to be available you don鈥檛 have to do anything at all. cljdoc will pick up new releases as they are published to Clojars. It will automatically display the README.* and CHANGELOG.* files (case-insensitive), provided they are in a supported format (see Articles below).

Building docs for older releases: If you would like to build docs for a version that existed before cljdoc started building docs automatically just head to the homepage, search for your project and pick it from the list. If we haven鈥檛 built docs for it yet you鈥檒l be able to do so with the press of a button.

Point users to your project鈥檚 documentation: You can link to cljdoc from your project鈥檚 README using a plain Markdown link or the cljdoc badge:

# This will redirect to the latest released version
https://cljdoc.org/d/$group-id/$artifact-id
# This will show a badge with the latest released version
https://cljdoc.org/badge/$group-id/$artifact-id

In full it may look like this for markdown:

[![cljdoc badge](https://cljdoc.org/badge/manifold/manifold)](https://cljdoc.org/d/manifold/manifold)

or this for asciidoctor:

image::https://cljdoc.org/badge/manifold/manifold[cljdoc badge, link=https://cljdoc.org/d/manifold/manifold]

cljdoc badge

Important
In the cljdoc URLs above $group-id and $artifact-id always refer to the Clojars/Maven group/artifact ID, not e.g. GitHub鈥檚 owner/repo names.

That鈥檚 pretty much it. Read on for some more advanced stuff that will make your docs extra awesome!

Docstrings

Docstrings are rendered as Markdown in the CommonMark dialect. Follow these 4 recommendations for best results:

  1. Backtick-Quote Function Arguments & Special Keywords to make them stand out more

  2. Link To Other Functions Using [[Wikilink]] Syntax

  3. Include Small Examples using Markdown fenced code blocks (```clojure 鈥︹ ```)

  4. Use (Markdown) Tables To Describe Complex Options Maps

  5. Can include images and links to articles, just be sure to use root relative links here (links that start with a /):

    • ![my image](/dir1/dir2/image1.png)

    • [my article](/dir1/dir2/article.adoc)

With the notion that it would be more problematic than helpful, HTML within docstrings is not interpreted.

Articles

Some libraries may want to publish additional guides, tutorials or, as they are called in cljdoc: articles. They can be written in Markdown (in the CommonMark dialect, file extension .md) or AsciiDoc (in the Asciidoctor dialect, file extension .adoc) and you can mix and match the two formats as you please.

In order to do so the following prerequisites must be met:

This allows cljdoc to retrieve files at the revision/commit the respective release was made. Those docs always being in sync will save your users a lot of trouble.

Note
Articles are always read at the revision linked to the version docs are being built for. This means you cannot update docs for previous releases but are instead encouraged to cut a new release. For testing purposes you can build any -SNAPSHOT release which will cause cljdoc to use master as revision.
Note
Referencing files in submodules is not currently supported, please open an issue if you need it.

If an article refers to another article鈥檚 source file via a link cljdoc will automatically rewrite that link if one of the known articles has the same source file. All links that work on GitHub should also work on cljdoc.

Auto-inferred Articles

If your repository does not contain a doc/cljdoc.edn file cljdoc will try to include articles from your doc/ or docs/ folder automatically.

The title is read from the file鈥檚 first heading. There will be no nesting and articles will be ordered alphabetically by filename. If you don鈥檛 need nesting this may be sufficient.

Tip
Use filenames prefixed with digits like 01-intro.md to easily define the order of articles.

Configuring Articles

If you need more control you may provide a file doc/cljdoc.edn to specify a tree of articles.

Assuming you have a directory doc/ in your repository as follows:

doc/
  getting-started.md
  installation.md
  configuration.md

You can integrate those files into your cljdoc build by adding a file doc/cljdoc.edn with the following contents:

{:cljdoc.doc/tree [["Readme" {:file "README.md"}]
                   ["Getting Started" {:file "doc/getting-started.md"}
                    ["Installation" {:file "doc/installation.md"}]]
                   ["Configuration" {:file "doc/configuration.md"}]]}

Which will result in the following hierarchy being shown in your docs:

鈹溾攢鈹 Readme
鈹溾攢鈹 Getting Started
鈹偮犅 鈹斺攢鈹 Installation
鈹斺攢鈹 Configuration
Important
The resulting URLs for those articles will be based on the title provided in the cljdoc.edn file and not on the filename.
Tip
Since sometimes people forget to update the paths after moving files around we recommend you add the following to your CI setup:
curl -fsSL https://raw.githubusercontent.com/cljdoc/cljdoc/master/script/verify-cljdoc-edn | bash -s doc/cljdoc.edn

Module Support

Some libraries consist of smaller submodules and cljdoc provides some facilities for library authors to make their documentation available in one location:

Module specific settings

If you want to provide a different doc tree for one module, simply nest it in the project鈥檚 name, e.g.:

{
  ;; used for metosin/reitit
  ;; when building docs for metosin/reitit this will be used as if
  ;; the doc/cljdoc.edn file contained just the value of this key
  metosin/reitit {:cljdoc.doc/tree [["Introduction" {:file "intro.md"}]]}

  ;; used for any project except metosin/reitit
  ;; could contain an overview about all modules and a pointer
  ;; to the overarching documentation for metosin/reitit
  :cljdoc.doc/tree [["Overview" {:file "modules/README.md"}]]
}

:cljdoc/include-namespaces-from-dependencies

If you want a project to include API documentation for some or all of it鈥檚 dependencies, specify their maven coordinates under :cljdoc/include-namespaces-from-dependencies:

{:cljdoc/include-namespaces-from-dependencies
 [metosin/reitit
  metosin/reitit-core
  metosin/reitit-ring
  metosin/reitit-spec
  metosin/reitit-schema
  metosin/reitit-swagger
  metosin/reitit-swagger-ui]}
Note
This option can be specified on a per artifact basis as described in the previous section.
Note
To be included, each dependency must also be specified as a maven dependency of the project itself (in the project鈥檚 deps.edn, project.clj, etc). The project鈥檚 resulting POM file will be used to load API information for the correct version.
Tip
Reitit is a great example reference for a project with sub modules.
Warning
If analysis for a specified dependency has failed or hasn鈥檛 been run, its API documentation will not appear on cljdoc.

More Features

You can refer to other namespaces and functions inside your docstrings using [[wikilink]] syntax. Note that if you want to link to vars outside the current namespace you need to either fully qualify those vars or specify them relative to the current namespace. An example: if you want to link to compojure.core/GET from compojure.route you鈥檒l need to provide the wiki in one of the two forms below:

[[compojure.core/GET]]
[[core/GET]]

Intelligent Version Resolving

If you want to refer to namespaces, vars or similar in an article you can use CURRENT instead of a specific version.

  • If that link is clicked while viewing the project鈥檚 docs on cljdoc the version will be resolved based on the referring URL.

  • If that link is clicked outside of cljdoc the version will be resolved to the latest release version.

An example linking to reagent.core:

Hiding Namespaces & Vars in Documentation

To hide namespaces or vars from documentation, annotate them with :no-doc metadata as in the examples below:

(defn ^:no-doc hidden [x])
(ns ^:no-doc namespace.hidden
  "This ns shouldn't show in the docs.")
(ns namespace.hidden
  "This ns shouldn't show in the docs."
  {:no-doc true})

Getting Dependencies Right

cljdoc will try to load all namespaces that are part of the jar for your artifact. If you include namespaces that require additional/optional dependencies, make sure you declare them in your pom.xml (commonly done via Leiningen/Boot). If you don鈥檛 want these dependencies to be included by default, mark them with :scope "provided". This will cause dependency resolution to skip those dependencies but allow cljdoc to inspect your pom.xml and load them.

Offline Docs

Building Docs Locally

This may be useful to test your changes without pushing new releases to Clojars or commits to Github. See Running cljdoc locally for details.

Asciidoc Environment

Similar to env-github on GitHub, cljdoc will set an env-cljdoc attribute when rendering your Asciidoc file. This allows you to hide or show sections of your document or set configuration parameters.

As an example, this AsciiDoctor snippit:

ifdef::env-cljdoc[]
THIS WILL BE SHOWN ON CLJDOC
endif::[]
ifndef::env-cljdoc[]
THIS WILL BE SHOWN EVERYWHERE ELSE
endif::[]

will render as so:

THIS WILL BE SHOWN EVERYWHERE ELSE

Supported rich text formats

Our rich text render supports two formats: