JDrupes MDoclet

A Doclet that enables Markdown in JavaDoc comments.

MDoclet

The MDoclet converts all JavaDoc documentation to HTML using a configurable Markdown processor (flexmark-java by default)

Basically, the doclet intercepts the standard doclet’s access to the AST generated by the javadoc tool and converts the texts from the comments from markdown to HTML.

Javadoc Tags

The following known tags are processed as Markdown:

  • @author
  • @deprecated
  • @param
  • @return
  • @since
  • @throws
  • @version

@see Tags

The @see tag is a special case, as there are several variants of this tag. These two variants will remain unchanged:

  • Javadoc-Links: @see Foo#bar()
  • Links: @see <a href="http://www.example.com/">Example</a>

The third variant however, which is originally meant to refer to a printed book, may also contain Markdown-style links:

  • @see "[Example](http://www.example.com/)"

This is rendered as @see <a href="http://www.example.com/">LABEL</a>, where LABEL falls back to the link’s URL, if no label is given.

Inline Tags

Inline tags will be removed before processing the Markdown source and re-inserted afterwards. Therefore, Markdown within inline tags won’t work.

Syntax Highlighting

MDoclet integrates highlight.js to enable syntax highlighting for fenced blocks.

Invoking

Specify the Doclet on JavaDoc’s command line:

javadoc -J--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED \
    -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
    -doclet org.jdrupes.mdoclet.MDoclet -docletpath /path/to/org.jdrupes.mdoclet.jar:another.jar

A prebuilt version can be downloaded from Maven Central (use the JAR with the suffix “-all” for a JAR file that includes all dependencies).

--markdown-processor
Specify the Markdown processor, see below.
-overview <file>
Specify an overview page. This is an option from the standard doclet. If the file name ends with “.md”, the file will be converted by the Markdown processor.
-highlight-style <style>
The style to be used for syntax highlighting.
-disable-highlight
Disable syntax highlighting entirely.
-disable-auto-highlight
Disable auto-highlighting. If no language is specified for a fenced block, the highlighter will not try to guess the correct language. This option has to be implemented by the Markdown processor.

Gradle

Because the standard doclet relies on an implementation class instead of the interface DocletEnvironment, a module must be made accessible. This can only be done when forking a new JVM, which is not supported by the gradle JavaDoc task (see the corresponding issue). Until this is fixed, the only way to run the doclet is by using a JavaExec task.

configurations {
    markdownDoclet
}

dependencies {
    markdownDoclet "org.jdrupes.mdoclet:doclet:3.0.0"
}

task apidocs(type: JavaExec) {
    enabled = JavaVersion.current() == JavaVersion.VERSION_17

    dependsOn classes
    inputs.file "overview.md"

    jvmArgs = ['--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED',
        '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED']
    classpath sourceSets.main.compileClasspath
    main = 'jdk.javadoc.internal.tool.Main'
    args = ['-doctitle', "My Code",
        '-overview', "overview.md",
        '-use',
        '-linksource',
        '-link', 'https://docs.oracle.com/en/java/javase/17/docs/api/',
        '--add-exports', 'jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED',
        '--add-exports', 'jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
        '-doclet', 'org.jdrupes.mdoclet.MDoclet',
        '-docletpath', configurations.markdownDoclet.files.asType(List).join(":"),
        '-d', file("${project.buildDir}/javadoc"),
        // Specify sources to be processed
        ]
}

The latest version available on maven central is shown in the badge on the project page.

Maven

I don’t use maven, but according to this contribution (and updates provided by others) it should be sufficient to add the following to your pom:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <!-- do not use 3.5.1: transitive dependencies of docletArtifact are not added to 
         docletpath, version 3.5.1 resolves this issue. https://issues.apache.org/jira/browse/MJAVADOC-742 -->
    <version>3.4.1</version>
    <executions>
      <execution>
        <id>attach-sources</id>
        <goals>
            <goal>jar</goal>
            <goal>test-jar</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <useStandardDocletOptions>true</useStandardDocletOptions>
      <doclet>org.jdrupes.mdoclet.MDoclet</doclet>
      <docletArtifacts>
        <docletArtifact>
          <groupId>org.jdrupes.mdoclet</groupId>
          <artifactId>doclet</artifactId>
          <!-- version 2.2.0 for java 11 and version 1.0.10 for java 8 -->
          <version>3.1.0</version>
        </docletArtifact>
        <docletArtifact>
          <groupId>com.vladsch.flexmark</groupId>
          <artifactId>flexmark-all</artifactId>
          <version>0.64.0</version>   
        </docletArtifact>   
      </docletArtifacts>      
      <!--  Note: additionalDependencies are added to the -classpath, not the docletpath -->
      <additionalDependencies>
      </additionalDependencies>
      <additionalJOptions>
        <additionalJOption>-J--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED</additionalJOption>
        <additionalJOption>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</additionalJOption>
      </additionalJOptions>
    </configuration>
  </plugin>

Selecting a Markdown processor

The doclet accesses the Markdown processor using the interface MarkdownProcessor. If you want to use another Markdown processor than the default flexmark-java processor, you must provide an adapter class that implements the interface and has a default (no parameters) constructor. To make the doclet use your class, supply its fully qualified class name as parameter to the option --markdown-processor. The class (and all its dependencies) must be in the doclet classpath.

The default behavior is equivalent to “--markdown-processor org.jdrupes.mdoclet.processors.FlexmarkProcessor”.

Configuring the Markdown processor

Markdown processors may support further configuration. As the available options are unknown to this doclet, it uses a “flag forwarding” mechanism. The argument of flag -M is forwarded to the Markdown processor. E.g. “-M -profile=kramdown” is passed to the Markdown processor as “-profile=kramdown”. The option may be used multiple times.

The flags supported by the default Markdown processor can be found in the description of its adapter class.

Notes

While based on JDK 1.8 (doclet version < 2.0), this project was an architectural redesign and extension of Abnaxos’ great pegdown-doclet. Aside from making the Markdown processor configurable, the PlantUML functionality had been factored out in a project of its own.

Starting with doclet version 2.0.0, this project is an independent development based on the API introduced in JDK 9.

This Doclet is released under the AGPL 3.0.

The project’s sources can be found on GitHub.

Packages
Package
Beschreibung
This package provides the main doclet classes.
The implementation of the javadoc tool and associated doclets.
This package provides the javadoc implementation of relevant public API defined in javax.tools, which provides an API alternative to invoking javadoc via the command line.
Doclets provide the user-selectable back ends for processing the documentation comments in Java source code.
The set of low-level file-formats, to be used in conjunction with the doclets.toolkit API.
This is the default HTML doclet provided with the JDK.
This package contains classes that create and write HTML markup tags.
Contains the base classes that make up a doclet.
This doclet-independent package has a set of classes and interfaces that are the building blocks for doclets.
This package has classes used to generate output for Javadoc tags.
 
This package has utility classes that perform common services required for API documentation generation.
 
This package contains Markdown processor adapters provided together with this doclet.
This package provides non-standard extensions for flexmark.