-
CSR
-
Resolution: Unresolved
-
P3
-
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:
- A standard
@info
tag to add generic info notes to APIs. - 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
andDoclet
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();
}
}
- csr of
-
JDK-8358754 Add @note tag for inline notes
-
- Open
-