Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8363700

Rich Notes in Java API Documentation

XMLWordPrintable

    • Icon: JEP JEP
    • Resolution: Unresolved
    • Icon: P3 P3
    • None
    • tools
    • None
    • Hannes Wallnoefer
    • Feature
    • Open
    • JDK
    • javadoc dash dev at openjdk dot java dot net

      Summary

      Introduce an @note tag for JavaDoc's Standard Doclet, to highlight the presence of supplemental information such as warnings and tips in API documentation. This information can be formatted richly and presented inline, where it is most helpful to the reader. In addition, allow developers to define their own tags for useful kinds of supplemental information.

      Goals

      • Enhance the usefulness of API documentation without impacting its readability.
      • Help API authors to record information that is not essential to using an API but may be invaluable to understanding it.
      • Allow API authors to define their own types of supplemental information, such as safety tips or anti-examples.

      Non-Goals

      • It is not a goal to change how existing custom block tags are defined to the javadoc tool via the -tag option.

      Motivation

      Every Java developer is familiar with reading javadoc to understand an API. Most javadoc is about defining abstractions (classes) and regulating operations (methods), but authors of API documentation often wish to provide supplemental information about the design and use of the API. Examples of supplemental information are snippets of source code (as in the <code class="prettyprint" data-shared-secret="1761685802263-0.27874310165105276">Files</code> class), warnings (as in the <code class="prettyprint" data-shared-secret="1761685802263-0.27874310165105276">URL</code> class), tips (as in the <code class="prettyprint" data-shared-secret="1761685802263-0.27874310165105276">Pattern</code> class), and rationale (as in the <code class="prettyprint" data-shared-secret="1761685802263-0.27874310165105276">java.time</code> package). We refer to all these pieces of information as notes.

      In javadoc, notes work best in the main description of a class or method, where they immediately demonstrate best practice, provide context, or illuminate a complex point. That is, notes are inline by their nature. They are unlike other supplemental information that works best when set apart from the main description, such as See Also: and <code class="prettyprint" data-shared-secret="1761685802263-0.27874310165105276">API Note:</code> blocks.

      Unfortunately, authors of documentation comments have to manually label text in the main description to make it stand out as supplemental information. This results in notes with ad hoc, low impact formatting. For example, the main description of <code class="prettyprint" data-shared-secret="1761685802263-0.27874310165105276">java.util.Map</code> contains a usage tip that is easily missed:

      Note: great care must be exercised if mutable objects are used as map keys. ...

      Documentation authors and readers would be empowered if there was a standard way to indicate a note in documentation comments and have it rendered in HTML with consistent, high impact formatting. Authors could systematically highlight supplemental information and readers could systematically recognize it. As a result, all javadoc would be more insightful, comprehensive, and maintainable.

      Description

      We introduce a note tag for presenting supplemental information in the main description of a program element. For example, this documentation comment for a method:

      /**
       * Determine the maximum foo in a list of bars.
       *
       * {@note There is always a maximum foo, even if the list is empty.}
       *
       * The arguments to this method must be non-null.
       */

      generates documentation that resembles the following:

      Determine the maximum foo in a list of bars.

      Note: There is always a maximum foo, even if the list is empty.

      The arguments to this method must be non-null.

      Here is an example usage in the main description of <code class="prettyprint" data-shared-secret="1761685802263-0.27874310165105276">java.util.Map</code>.

      Tag syntax

      The note tag can be used as an inline tag, {@note ...}. The output appears congruent to the tag's use in the main description.

      The note tag also be used as a block tag, @note .... The output is grouped with other block tags after the main description.

      In both cases, the output is rendered as a text block with a header that defaults to Note:. The CSS class note-tag is declared in the HTML element generated for the note. Additional CSS classes can be added using attributes or custom note tags as discussed below.

      The note tag may contain inline tags, such as {@link}, {@code}, and {@snippet}, as well as HTML elements. For example, here is a snippet inside a note:

      /**
       * {@note The following code shows how to use {@link Optional#isPresent}:
       * {@snippet :
       * if (v.isPresent()) {
       *     System.out.println("v: " + v.get());
       * }
       * }
       * }
       */

      An inline tag {@note ...} is terminated by the first unbalanced closing curly brace character in the body. This means that an inline note may only contain balanced pairs of curly-brace characters (a restriction common to all inline tags).

      A block tag @note ... is terminated by the beginning of the next block tag or the end of the enclosing documentation comment.

      Additional details about the note can be given as attributes, in the form of name=value pairs placed inside a single pair of square brackets ([ ]) after the tag name. An attribute name is always a simple identifier. An attribute value may be enclosed in either single or double quote characters; no escape characters are supported. Multiple attributes are separated from each other by whitespace characters, such as space and newline.

      Attributes (except for the predefined attributes discussed below) are converted to custom data attributes in the HTML element generated for the note. For example, {@note [priority=high] ...} results in an HTML element with attribute data-priority="high". Such attributes may be used in user-defined stylesheets to customize the note's appearance.

      Predefined attributes

      There are two predefined attributes that customize a note's appearance.

      • The header attribute specifies a heading to replace **Note:**.

        For example, {@note [header='Caution:'] Beware of the dog!} produces the following output:

        Caution: Beware of the dog!

      • The kind attribute characterizes the content of the note. The attribute value is encoded as an additional CSS class in the HTML element generated for the note, prefixed by note-tag-. For example, {@note [kind=requirement] Buy dog food.} produces an HTML element with class="note-tag note-tag-requirement".

        The Standard Doclet's default stylesheet declares styles for two useful kinds of note:

        • kind='important' (CSS class: note-tag-important)
        • kind='critical' (CSS class: note-tag-critical)

        An important note has a blue header (example of inline use, example of block use).

        A critical note has a red header (example of inline use, example of block use).

        Further kinds can be defined as attributes or with custom note tags (discussed below), and styled via user-defined stylesheets.

      Custom Note Tags

      The javadoc -tag option already provides a mechanism to define custom tags that can be used for any purpose, including supplemental information. However, the tags are limited: They can only be used as block tags and provide no capability for styling or customization.

      We extend the -tag option to define custom tags that are aliases for the note tag. Such a custom tag can be used as both an inline tag and a block tag, and its output can be styled. Any use of the custom tag is equivalent to a note tag where the kind attribute records the name of the custom tag and the header attribute records the tag header specified on the command line. For example, running the javadoc tool with the option:

      -tag 'warning:a:Warning:'

      defines a custom @warning tag that is an alias for @note [kind='warning' header='Warning:'].

      This use:

      {@warning Remember to flush the cache before syncing.}

      is equivalent to:

      {@note [kind='warning' header='Warning:'] Remember to flush the cache before syncing.}

      Both tags produce the same output, with CSS class note-tag-warning in the HTML element generated for the note:

      Warning: Remember to flush the cache before syncing.

      Custom tags may contain attributes, including kind and header. For example, using the custom @warning tag defined above:

      {@warning [kind='supercritical'] Do not call this method until shutdown.}

      is equivalent to:

      {@note [kind='supercritical' header='Warning:'] Do not call this method until shutdown.}

      and the HTML generated for the note has CSS class note-tag-supercritical.

      Other features of the -tag option are unchanged, such as the ability to define the permitted locations of the tag. For example, the following option limits the custom @safetytip tag to method descriptions, not module/package/class descriptions.

      -tag 'safetytip:m:Safety Message:'

      Guidelines for Writing Notes

      Notes that appear inline can disrupt the flow of text and may distract the reader, so they should be used judiciously. Not every sentence or paragraph that contains a warning or a tip needs to be a formatted with a note tag. If the sentence or paragraph flows easily as part of the surrounding text, it may not benefit from special formatting.

      The following examples show where inline notes may be appropriate:

      • Notes that provide context, background, or other supplemental information that may be of interest to the reader. An example would be the following note in the documentation of method ExecutorService.submit(Callable):

        Note: The Executors class includes a set of methods that can convert some other common closure-like objects, for example, PrivilegedAction to Callable form so they can be submitted.

      • Notes that contain warnings or other important messages that deserve to be highlighted so that the reader does not overlook them. An example is the following note in the description of the List interface:

        Note: While it is permissible for lists to contain themselves as elements, extreme caution is advised: the equals and hashCode methods are no longer well defined on such a list.

        Maybe a "Caution" or "Warning" header and style would be more appropriate here than the generic "Note".

      Examples of where inline notes are not appropriate are found throughout the Java SE API documentation. Custom block tags are used heavily for special-purpose supplemental information, e.g., @apiNote creates an "API Note:" section and @implSpec creates an "Implementation Requirements:" section. This information stands on its own and doesn't rely on the context of the main description, so there is no benefit to putting it inline. Rather, inline notes should be used for material that belongs naturally in the main description and was previously authored with custom HTML markup or no markup at all.

      While it is possible to nest note tags inside note tags, we do not believe this will be a common usage pattern so we do not provide special CSS support for this case.

      Alternatives

      We considered extending the <code class="prettyprint" data-shared-secret="1761685802263-0.27874310165105276">Taglet</code> API to make it easier for developers to implement their own custom note tags. However, we believe that notes are important enough to provide a ready-to-use solution without requiring everybody to write their own taglets.

      We considered adding an option to the javadoc tool for custom notes, rather than extending the -tag option. However, a new option would have duplicated -tag in many respects, making usage of the tool more complicated.

      We considered a templating mechanism to customize the output of notes, but this added significant complexity. The CSS styling described above offers plenty of flexibility for common use cases.

      We considered using the attribute syntax from snippets, where attributes are not enclosed in a pair of square brackets. However, a snippet has an obligatory colon-newline separator to indicate the start of the body, and this would be inconvenient in the common case of a note tag with just a body, e.g., {@note The HTTP protocol requires ...}. It would also have been incompatible with traditional custom tags.

      Testing

      The new feature will be tested using the standard test infrastructure for JavaDoc features, such as jtreg tests and related tools to check the correctness of the generated documentation.

      Risks and Assumptions

      The rationale for providing two distinct ways to represent notes -- the built-in note tag versus custom tags defined with -tag -- is that these mechanisms will appeal to different sets of users. For smaller and more informal projects, the note tag provides an immediate and flexible way to create notes, without requiring changes to the application's build. For larger projects, the definition of custom tags via -tag is a way to provide an approved set of note-like functionality with a convenient tag syntax.

      A risk of the note tag is that it could be used excessively, and in places that would benefit more from continuous text. We assume that authors of API documentation will use the tag judiciously.

            hannesw Hannes Wallnoefer
            hannesw Hannes Wallnoefer
            Hannes Wallnoefer Hannes Wallnoefer
            Alex Buckley, Jonathan Gibbons
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: