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

Add @note tag for inline notes

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P3 P3
    • 26
    • tools
    • None

      Summary

      Introduce a new {@note} tag in the JavaDoc Standard Doclet to create emphasized notes. On its own, the {@note} tag allows the creation of generic highlighted inline notes. Together with a new jdk.javadoc.doclet API and JavaDoc option, the {@note} tag can also be used to create specialized notes with custom rendering.

      Problem

      JavaDoc does not provide a way to create emphasized notes embedded in the main description of doc comments. Notes are usually implemented as [block tags] and displayed in a separate section after the main description, such as with the API and implementation note and spec tags used in OpenJDK. This works well for notes that are self-contained and separate from other content, but it isn't a good solution for notes that require the context of the surrounding text or highlighting to be applied to the note.

      It is also difficult to implement custom inline notes using the jdk.javadoc.doclet.Taglet interface. Custom inline tags implementing the Taglet interface do not have their content parsed as rich text and therefore cannot contain nested tags such as {@link} or {@code}. The Taglet API also does not provide access to the Standard Doclet to render rich content containing nested tags.

      Tags defined with the JavaDoc -tag option on the other hand can contain and generate rich content, inluding nested inline tags. However, they are limited to block tags and do not allow custom formatting to be applied to the tag output.

      During the development cycle for JDK 25, we worked on two features that would have benefitted from, and ultimatively merged into the development, of this new feature:

      1. A standard @info tag to add generic info notes to APIs.
      2. A custom @previewNote tag to add preview-related notes to permanent APIs.

      Solution

      A new {@note ...} inline tag is added to the Standard Doclet to create highlighted notes. The body of the note is provided in the tag content and may contain rich text including nested tags. Additionally, the tag content may contain attributes encoded as key=value pairs to control and be used in custom rendering of the note output.

      An accompanying new interface StandardDoclet.NoteTag is added to the jdk.javadoc.doclet.StandardDoclet class which allows to override default rendering of the note output. Instances of StandardDoclet.NoteTag are registered with JavaDoc with a new --note-tag option.

      Alternatives

      Several alternative solutions were considered that fall into two categories, extending the Taglet API and adding command line options.

      Extending the Taglet API

      A number of approaches were considered that would enhance the Taglet API to enable rich custom inline tags.

      • Allowing Taglets to enable rich text parsing of tag content. This would be a simple solution, but not flexible enough to enable notes to use rich formatting based on metadata attributes.
      • Allowing Taglets to define custom content parsers. While very flexible, this would add too much complexity and does not suit the architecture of JavaDoc.
      • Allowing custom taglets to extend standard tags in the Standard Doclet. This also adds a lot of complexity, and does not suit existing JavaDoc architecture.
      • Adding a API to allow Taglets to tap into the functionality of the Doclet to render rich content. This would be simple enough to implement, but it would also complicate interaction between Taglet and Doclet APIs.

      In the end these approaches abandoned because they either could not support a truly flexible implementation of custom notes based on metadata attributes and custom rendering, or the would add too much complexity, not fit into JavaDoc architecture, and blur the border between Standard Doclet functionality and the doclet-agnostic Taglet API.

      New Command Line Option for Custom Inline Notes

      As an alternative, it would have been possible to define custom note kinds purely using options on the command line, similar to how custom block tags are defined using the -tag name:locations:header option.

      However, while block tags only require a header, highlighted inline notes usually require more complex wrapping of their content in custom HTML, which exceeds what can and should be done in a command line option. Also, a solution driven purely by command line options would not be able to support custom rendering based on metadata attributes.

      Specification

      The new tag uses the following syntax:

      {@note body }
      
      {@note [ attributes ] body }

      The body may contain rich content including nested inline JavaDoc and HTML tags. It is terminated by the first unbalanced closing curly brace character.

      The attributes use the form of name=value pairs. The attribute name is a simple identifier. The attribute value may be an unquoted, single-quoted or double-quoted string. The attribute value and the preceding = may be omitted. Attributes are separated from each other by whitespace, such as space or newline characters.

      In its simple form without attributes, the note tag is rendered as simple generic info box.

      {@note Note content }

      Note tags with attributes can select different layouts of notes using the special kind attribute. Custom attributes can be used to pass additional data to the code rendering the note output.

      {@note [kind=warning] Note content }

      A new --note-tag option is added to the javadoc command to allow registration of custom note tags.

      javadoc --note-tag pkg.MyNoteTagImpl

      JavaDoc consults the -tagletpath option to locate the specified class.

      Custom note tags are implemented as instances of interface StandardDoclet.NoteTag. The interface provides methods to specify the kind of note supported by the class, and a method to render the note content.

      /**
       * An interface for rendering custom {@code {@note}} tags. Instances of this 
       * interface are registered with the `--note-tag` option. {@code {@note}} tags
       * can select instances of this interface using the `kind` attribute.
       */
      public interface NoteTag {
          /**
           * {@return the kind of note this {@code NoteTag} should be applied to}
           */
          String getKind();
      
          /**
           * {@return the rendered output for a note tag for the given {@code element} 
           * with the given attributes and pre-rendered note {@code content}}
           */
          String toString(Map<String,String> attr, String content, Element element);
      }

      Example Usage

      An example of a preview note tag implemented with this new feature could look as follows:

      {@note [kind=preview jep=101 title="Preview Note Title"]
      Preview note body }

      JavaDoc option to register the preview note:

      javadoc ... --note-tag pkg.PreviewNote ...

      Implementation of the preview note:

      package pkg;
      
      import jdk.javadoc.doclet.StandardDoclet;
      
      public PreviewNote implements StandardDoclet.NoteTag {
      
          @Override
          public String getKind() {
              return "preview";
          }
      
          @Override
          public String toString(Map<String, String> attr, String content, Element element) {
              var title = attr.get("title");
              return new StringBuilder()
                  .append(...)
                  .append(title)
                  .append(...)
                  .append(content)
                  .append(...)
                  .toString();
          }
      }

            hannesw Hannes Wallnoefer
            hannesw Hannes Wallnoefer
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated: