8348282: Add option for syntax highlighting in javadoc snippets

Reviewed-by: liach, nbenalla, erikj
This commit is contained in:
Hannes Wallnöfer 2025-04-28 10:04:20 +00:00
parent 2447b9812a
commit b0c3485d6c
13 changed files with 3527 additions and 14 deletions

View File

@ -98,7 +98,7 @@ JAVADOC_DISABLED_DOCLINT_PACKAGES := org.w3c.* javax.smartcardio
JAVADOC_OPTIONS := -use -keywords -notimestamp \
-serialwarn -encoding ISO-8859-1 -docencoding UTF-8 -breakiterator \
-splitIndex --system none -javafx --expand-requires transitive \
--override-methods=summary
--override-methods=summary --syntax-highlight
# The reference options must stay stable to allow for comparisons across the
# development cycle.

View File

@ -311,6 +311,12 @@ public class HtmlDoclet extends AbstractDoclet {
copyFontResources();
}
var syntaxHighlight = options.syntaxHighlight();
if (syntaxHighlight) {
copyResource(DocPaths.HIGHLIGHT_CSS, DocPaths.RESOURCE_FILES.resolve(DocPaths.HIGHLIGHT_CSS), true);
copyResource(DocPaths.HIGHLIGHT_JS, DocPaths.SCRIPT_FILES.resolve(DocPaths.HIGHLIGHT_JS), true);
}
// If a stylesheet file is not specified, copy the default stylesheet
// and replace newline with platform-specific newline.
if (options.stylesheetFile().isEmpty()) {

View File

@ -511,6 +511,7 @@ public abstract class HtmlDocletWriter {
.setStylesheets(configuration.getMainStylesheet(), additionalStylesheets, localStylesheets)
.setAdditionalScripts(configuration.getAdditionalScripts())
.setIndex(options.createIndex(), mainBodyScript)
.setSyntaxHighlight(options.syntaxHighlight())
.addContent(extraHeadContent);
HtmlDocument htmlDocument = new HtmlDocument(

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -198,6 +198,11 @@ public class HtmlOptions extends BaseOptions {
*/
private String stylesheetFile = "";
/**
* Argument for command line option {@code --syntax-highlight}.
*/
private boolean syntaxHighlight = false;
/**
* Argument for command-line option {@code -tagletpath}.
* The path to Taglets
@ -423,6 +428,14 @@ public class HtmlOptions extends BaseOptions {
}
},
new Option(resources, "--syntax-highlight") {
@Override
public boolean process(String opt, List<String> args) {
syntaxHighlight = true;
return true;
}
},
new Option(resources, "-tag", 1) {
@Override
public boolean process(String opt, List<String> args) {
@ -806,6 +819,13 @@ public class HtmlOptions extends BaseOptions {
return stylesheetFile;
}
/**
* Argument for command line option {@code --syntax-highlight}.
* True if command line option "--syntax-highlight" is used and syntax
* highlighting should be enabled. Default value is false.
*/
public boolean syntaxHighlight() { return syntaxHighlight; }
/**
* Argument for command-line option {@code -tagletpath}.
* The path to Taglets

View File

@ -70,6 +70,7 @@ public class Head extends Content {
private final List<Content> extraContent;
private boolean addDefaultScript = true;
private DocPath canonicalLink;
private boolean syntaxHighlight = false;
/**
* Creates a {@code Head} object, for a given file and HTML version.
@ -238,6 +239,16 @@ public class Head extends Content {
this.canonicalLink = link;
}
/**
* Enables or disables support for syntax highlighting.
* @param value {@code true} to enable syntax highligting
* @return this object
*/
public Head setSyntaxHighlight(boolean value) {
this.syntaxHighlight = value;
return this;
}
/**
* Adds additional content to be included in the HEAD element.
*
@ -339,6 +350,11 @@ public class Head extends Content {
addStylesheet(head, DocPaths.RESOURCE_FILES.resolve(path));
}
if (syntaxHighlight) {
addStylesheet(head, DocPaths.RESOURCE_FILES.resolve(DocPaths.HIGHLIGHT_CSS));
addScriptElement(head, DocPaths.HIGHLIGHT_JS);
}
for (DocPath path : localStylesheets) {
// Local stylesheets are contained in doc-files, so omit resource-files prefix
addStylesheet(head, path);

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
*/
/* Syntax highlight style sheet */
.hljs-title.function_,
.hljs-template-variable {
color: #00738F;
}
.hljs-code,
.hljs-comment,
.hljs-quote {
color: #6e6e71;
font-style: italic;
}
.hljs-meta {
color: #836F00;
}
.hljs-symbol,
.hljs-template-tag,
.hljs-keyword,
.hljs-literal,
.hljs-name,
.hljs-built_in,
.hljs-char.escape_ {
color: #0C40C2;
}
.hljs-variable,
.hljs-property,
.hljs-attr,
.hljs-section {
color: #841191;
}
.hljs-attribute {
color: #164ad9;
}
.hljs-regexp,
.hljs-number {
color: #104BEB;
}
.hljs-link {
color: #47688a;
}
.hljs-string {
color: #008313;
}
.hljs-doctag {
text-decoration: underline;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-subst,
.hljs-title,
.hljs-params,
.hljs-bullet,
.hljs-formula,
.hljs-tag,
.hljs-type {
/* ignored */
}

View File

@ -21,6 +21,10 @@ var activeTableTab = "active-table-tab";
const linkIcon = "##REPLACE:doclet.Link_icon##";
const linkToSection = "##REPLACE:doclet.Link_to_section##";
if (hljs) {
hljs.highlightAll();
}
function loadScripts(doc, tag) {
createElem(doc, tag, 'script-files/search.js');

View File

@ -735,6 +735,10 @@ doclet.usage.allow-script-in-comments.description=\
Allow JavaScript in documentation comments, and options\n\
whose value is html-code
doclet.usage.syntax-highlight.description=\
Enable syntax highlighting for code fragments in {@snippet} tags\n\
and <pre><code> elements.
doclet.usage.xdocrootparent.parameters=\
<url>
doclet.usage.xdocrootparent.description=\

View File

@ -23,11 +23,11 @@
/* Base font sizes for body and code elements */
--body-font-size: 14.2px;
--block-font-size: 14.4px;
--code-font-size: 14px;
--code-font-size: 13.9px;
--nav-font-size: 13.4px;
/* Line height for continuous text blocks */
--block-line-height: 1.5;
--code-line-height: 1.55;
--code-line-height: 1.6;
/* Text colors for body and block elements */
--body-text-color: #282828;
--block-text-color: #282828;
@ -63,10 +63,10 @@
--toc-highlight-color: var(--subnav-background-color);
--toc-hover-color: #e9ecf0;
/* Snippet and pre colors */
--snippet-background-color: #f0f0f2;
--snippet-background-color: #f2f2f4;
--snippet-text-color: var(--block-text-color);
--snippet-highlight-color: #f7c590;
--pre-background-color: #f3f3f5;
--pre-background-color: var(--snippet-background-color);
--pre-text-color: var(--snippet-text-color);
/* Border colors for structural elements and user defined tables */
--border-color: #e6e6e6;
@ -565,9 +565,6 @@ ul.horizontal li {
display:inline;
font-size:0.9em;
}
div.inheritance {
font-size: 0.99em;
}
div.inheritance div.inheritance {
margin-left:2em;
}
@ -1389,8 +1386,8 @@ button#page-search-copy span {
/* snippet copy button */
button.snippet-copy {
position: absolute;
top: 2px;
right: 2px;
top: 4px;
right: 1px;
height: 32px;
}
button.snippet-copy img {
@ -1653,7 +1650,7 @@ table.striped > tbody > tr > th {
pre.snippet {
background-color: var(--snippet-background-color);
color: var(--snippet-text-color);
padding: 10px;
padding: 12px;
}
div.snippet-container {
position: relative;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -115,6 +115,12 @@ public class DocPaths {
/** The name of the right pointing angle icon. */
public static final DocPath RIGHT_SVG = DocPath.create("right.svg");
/** The name of the syntax highlighting style sheet. */
public static final DocPath HIGHLIGHT_CSS = DocPath.create("highlight.css");
/** The name of the syntax highlighting script file. */
public static final DocPath HIGHLIGHT_JS = DocPath.create("highlight.js");
/** The name of the default jQuery directory. */
public static final DocPath JQUERY_DIR = DocPath.create("jquery");

View File

@ -1,5 +1,5 @@
---
# Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -867,6 +867,23 @@ The following options are provided by the standard doclet.
letter, plus a file for any index entries that start with non-alphabetical
symbols.
<span id="option-syntax-highlight">`--syntax-highlight`</span>
: Enables syntax highlighting for code fragments in `{@snippet}` tags and
`<pre><code>` elements. For snippets, the `lang` attribute is used to
determine the language of code fragments, which defaults to "java" for
inline snippets and is derived from the file extension for external
snippets. In HTML `<pre><code>` tags, the `class` attribute can be used
to specify the language of the contained code fragment as shown below:
```
<pre><code class="language-java">...</code></pre>
```
If neither of these attributes is available automatic language detection is
applied. To disable syntax highlighting for a code fragment set the language
to "text" using one of the mechanisms described above. The languages and
formats supported by this option are Java, Properties, JSON, HTML and XML.
<span id="option-tag">`-tag` *name*:*locations*:*header*</span>
: Specifies a custom tag with a single argument. For the `javadoc` tool to
spell-check tag names, it is important to include a `-tag` option for every

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8348282
* @summary Add option for syntax highlighting in javadoc snippets
* @library /tools/lib ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
* @build toolbox.ToolBox javadoc.tester.*
* @run main TestSyntaxHighlightOption
*/
import java.io.IOException;
import java.nio.file.Path;
import javadoc.tester.JavadocTester;
import toolbox.ToolBox;
public class TestSyntaxHighlightOption extends JavadocTester {
public static void main(String... args) throws Exception {
var tester = new TestSyntaxHighlightOption();
tester.runTests();
}
ToolBox tb = new ToolBox();
Path src = Path.of("src");
TestSyntaxHighlightOption() throws IOException {
tb.writeJavaFiles(src, """
package p;
/** Class C. */
public class C {
/**
* Method m.
*/
public void m() {
}
}
""");
}
@Test
public void testSyntaxHighlightOption(Path base) {
javadoc("-d", base.resolve("out").toString(),
"-sourcepath", src.toString(),
"--syntax-highlight",
"p");
checkExit(Exit.OK);
checkOutput("resource-files/highlight.css", true, "Syntax highlight style sheet");
checkOutput("script-files/highlight.js", true, "Highlight.js v11.11.1 (git: 08cb242e7d)");
checkOutput("index-all.html", true, """
<link rel="stylesheet" type="text/css" href="resource-files/highlight.css">
<script type="text/javascript" src="script-files/highlight.js"></script>""");
checkOutput("p/package-summary.html", true, """
<link rel="stylesheet" type="text/css" href="../resource-files/highlight.css">
<script type="text/javascript" src="../script-files/highlight.js"></script>""");
checkOutput("p/C.html", true, """
<link rel="stylesheet" type="text/css" href="../resource-files/highlight.css">
<script type="text/javascript" src="../script-files/highlight.js"></script>""");
}
@Test
public void testNoSyntaxHighlightOption(Path base) {
javadoc("-d", base.resolve("out").toString(),
"-sourcepath", src.toString(),
"p");
checkExit(Exit.OK);
checkFiles(false, "resource-files/highlight.css", "script-files/highlight.js");
checkOutput("index-all.html", false, "highlight.css", "highlight.js");
checkOutput("p/package-summary.html", false, "highlight.css", "highlight.js");
checkOutput("p/C.html", false, "highlight.css", "highlight.js");
}
}