8246435: Replace Javascript implementation of pandoc filters with Java
Reviewed-by: erikj
This commit is contained in:
parent
71c926c4f6
commit
cd651b9aad
@ -103,8 +103,8 @@ ifeq ($(ENABLE_PANDOC), true)
|
|||||||
SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-troff-manpage-filter.sh.template, \
|
SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-troff-manpage-filter.sh.template, \
|
||||||
OUTPUT_FILE := $(PANDOC_TROFF_MANPAGE_FILTER), \
|
OUTPUT_FILE := $(PANDOC_TROFF_MANPAGE_FILTER), \
|
||||||
REPLACEMENTS := \
|
REPLACEMENTS := \
|
||||||
@@JJS@@ => $(JJS) ; \
|
@@JAVA_SMALL@@ => $(JAVA_SMALL) ; \
|
||||||
@@TOPDIR@@ => $(TOPDIR) ; \
|
@@BUILDTOOLS_OUTPUTDIR@@ => $(BUILDTOOLS_OUTPUTDIR) ; \
|
||||||
))
|
))
|
||||||
|
|
||||||
# Created script must be made executable
|
# Created script must be made executable
|
||||||
@ -126,8 +126,8 @@ ifeq ($(ENABLE_PANDOC), true)
|
|||||||
SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-html-manpage-filter.sh.template, \
|
SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-html-manpage-filter.sh.template, \
|
||||||
OUTPUT_FILE := $(PANDOC_HTML_MANPAGE_FILTER), \
|
OUTPUT_FILE := $(PANDOC_HTML_MANPAGE_FILTER), \
|
||||||
REPLACEMENTS := \
|
REPLACEMENTS := \
|
||||||
@@JJS@@ => $(JJS) ; \
|
@@JAVA_SMALL@@ => $(JAVA_SMALL) ; \
|
||||||
@@TOPDIR@@ => $(TOPDIR) ; \
|
@@BUILDTOOLS_OUTPUTDIR@@ => $(BUILDTOOLS_OUTPUTDIR) ; \
|
||||||
))
|
))
|
||||||
|
|
||||||
# Created script must be made executable
|
# Created script must be made executable
|
||||||
|
@ -610,9 +610,9 @@ ifeq ($(ENABLE_PANDOC), true)
|
|||||||
# PANDOC_HTML_MANPAGE_FILTER, a wrapper around
|
# PANDOC_HTML_MANPAGE_FILTER, a wrapper around
|
||||||
# PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT. This is created by buildtools-jdk.
|
# PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT. This is created by buildtools-jdk.
|
||||||
|
|
||||||
# We should also depend on the source javascript filter
|
# We should also depend on the source code for the filter
|
||||||
PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT := \
|
PANDOC_HTML_MANPAGE_FILTER_SOURCE := $(call FindFiles, \
|
||||||
$(TOPDIR)/make/scripts/pandoc-html-manpage-filter.js
|
$(TOPDIR)/make/jdk/src/classes/build/tools/pandocfilter)
|
||||||
|
|
||||||
$(foreach m, $(ALL_MODULES), \
|
$(foreach m, $(ALL_MODULES), \
|
||||||
$(eval MAN_$m := $(call FindModuleManDirs, $m)) \
|
$(eval MAN_$m := $(call FindModuleManDirs, $m)) \
|
||||||
@ -632,7 +632,7 @@ ifeq ($(ENABLE_PANDOC), true)
|
|||||||
OPTIONS := --toc -V include-before='$(SPECS_TOP)' -V include-after='$(SPECS_BOTTOM_1)', \
|
OPTIONS := --toc -V include-before='$(SPECS_TOP)' -V include-after='$(SPECS_BOTTOM_1)', \
|
||||||
POST_PROCESS := $(TOOL_FIXUPPANDOC), \
|
POST_PROCESS := $(TOOL_FIXUPPANDOC), \
|
||||||
EXTRA_DEPS := $(PANDOC_HTML_MANPAGE_FILTER) \
|
EXTRA_DEPS := $(PANDOC_HTML_MANPAGE_FILTER) \
|
||||||
$(PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT), \
|
$(PANDOC_HTML_MANPAGE_FILTER_SOURCE), \
|
||||||
)) \
|
)) \
|
||||||
$(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
|
$(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
|
||||||
) \
|
) \
|
||||||
|
@ -381,22 +381,6 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
|
|||||||
BOOTJDK_USE_LOCAL_CDS=false
|
BOOTJDK_USE_LOCAL_CDS=false
|
||||||
AC_MSG_RESULT([no, -XX:SharedArchiveFile not supported])
|
AC_MSG_RESULT([no, -XX:SharedArchiveFile not supported])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for jjs in bootjdk
|
|
||||||
UTIL_SETUP_TOOL(JJS,
|
|
||||||
[
|
|
||||||
AC_MSG_CHECKING([for jjs in Boot JDK])
|
|
||||||
JJS=$BOOT_JDK/bin/jjs
|
|
||||||
if test ! -x $JJS; then
|
|
||||||
AC_MSG_RESULT(not found)
|
|
||||||
JJS=""
|
|
||||||
AC_MSG_NOTICE([Cannot use pandoc without jjs])
|
|
||||||
ENABLE_PANDOC=false
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(ok)
|
|
||||||
fi
|
|
||||||
AC_SUBST(JJS)
|
|
||||||
])
|
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
|
AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
|
||||||
|
@ -625,7 +625,6 @@ JAR_CMD:=@JAR@
|
|||||||
JLINK_CMD := @JLINK@
|
JLINK_CMD := @JLINK@
|
||||||
JMOD_CMD := @JMOD@
|
JMOD_CMD := @JMOD@
|
||||||
JARSIGNER_CMD:=@JARSIGNER@
|
JARSIGNER_CMD:=@JARSIGNER@
|
||||||
JJS_CMD:=@JJS@
|
|
||||||
# These variables are meant to be used. They are defined with = instead of := to make
|
# These variables are meant to be used. They are defined with = instead of := to make
|
||||||
# it possible to override only the *_CMD variables.
|
# it possible to override only the *_CMD variables.
|
||||||
JAVA=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
|
JAVA=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
|
||||||
@ -637,7 +636,6 @@ JAR=@FIXPATH@ $(JAR_CMD)
|
|||||||
JLINK = @FIXPATH@ $(JLINK_CMD)
|
JLINK = @FIXPATH@ $(JLINK_CMD)
|
||||||
JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL)
|
JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL)
|
||||||
JARSIGNER=@FIXPATH@ $(JARSIGNER_CMD)
|
JARSIGNER=@FIXPATH@ $(JARSIGNER_CMD)
|
||||||
JJS=@FIXPATH@ $(JJS_CMD) $(JAVA_TOOL_FLAGS_SMALL)
|
|
||||||
|
|
||||||
BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@
|
BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@
|
||||||
BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
|
BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
|
||||||
|
@ -199,9 +199,9 @@ ifeq ($(call isTargetOsType, unix), true)
|
|||||||
# PANDOC_TROFF_MANPAGE_FILTER, a wrapper around
|
# PANDOC_TROFF_MANPAGE_FILTER, a wrapper around
|
||||||
# PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT. This is created by buildtools-jdk.
|
# PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT. This is created by buildtools-jdk.
|
||||||
|
|
||||||
# We should also depend on the source javascript filter
|
# We should also depend on the source code for the filter
|
||||||
PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT := \
|
PANDOC_TROFF_MANPAGE_FILTER_SOURCE := $(call FindFiles, \
|
||||||
$(TOPDIR)/make/scripts/pandoc-troff-manpage-filter.js
|
$(TOPDIR)/make/jdk/src/classes/build/tools/pandocfilter)
|
||||||
|
|
||||||
# The norm in man pages is to display code literals as bold, but pandoc
|
# The norm in man pages is to display code literals as bold, but pandoc
|
||||||
# "correctly" converts these constructs (encoded in markdown using `...`
|
# "correctly" converts these constructs (encoded in markdown using `...`
|
||||||
@ -231,7 +231,7 @@ ifeq ($(call isTargetOsType, unix), true)
|
|||||||
@@VERSION_SHORT@@ => $(VERSION_SHORT) ; \
|
@@VERSION_SHORT@@ => $(VERSION_SHORT) ; \
|
||||||
@@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION), \
|
@@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION), \
|
||||||
EXTRA_DEPS := $(PANDOC_TROFF_MANPAGE_FILTER) \
|
EXTRA_DEPS := $(PANDOC_TROFF_MANPAGE_FILTER) \
|
||||||
$(PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT), \
|
$(PANDOC_TROFF_MANPAGE_FILTER_SOURCE), \
|
||||||
))
|
))
|
||||||
|
|
||||||
TARGETS += $(BUILD_MAN_PAGES)
|
TARGETS += $(BUILD_MAN_PAGES)
|
||||||
|
@ -604,10 +604,6 @@ var getJibProfilesProfiles = function (input, common, data) {
|
|||||||
dependencies: [ name + ".jdk" ],
|
dependencies: [ name + ".jdk" ],
|
||||||
configure_args: [
|
configure_args: [
|
||||||
"--with-boot-jdk=" + input.get(name + ".jdk", "home_path"),
|
"--with-boot-jdk=" + input.get(name + ".jdk", "home_path"),
|
||||||
// Full docs do not currently work with bootcycle build
|
|
||||||
// since Nashorn was removed. This negates the
|
|
||||||
// --enable-full-docs from the main profile.
|
|
||||||
"--enable-full-docs=auto",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
profiles[bootcyclePrebuiltName] = concatObjects(profiles[name],
|
profiles[bootcyclePrebuiltName] = concatObjects(profiles[name],
|
||||||
|
108
make/jdk/src/classes/build/tools/pandocfilter/PandocFilter.java
Normal file
108
make/jdk/src/classes/build/tools/pandocfilter/PandocFilter.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package build.tools.pandocfilter;
|
||||||
|
|
||||||
|
import build.tools.pandocfilter.json.JSON;
|
||||||
|
import build.tools.pandocfilter.json.JSONArray;
|
||||||
|
import build.tools.pandocfilter.json.JSONObject;
|
||||||
|
import build.tools.pandocfilter.json.JSONString;
|
||||||
|
import build.tools.pandocfilter.json.JSONValue;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PandocFilter {
|
||||||
|
/**
|
||||||
|
* Traverse a tree of pandoc format objects, calling callback on each
|
||||||
|
* element, and replacing it if callback returns a new object.
|
||||||
|
* <p>
|
||||||
|
* Inspired by the walk method in
|
||||||
|
* https://github.com/jgm/pandocfilters/blob/master/pandocfilters.py
|
||||||
|
*/
|
||||||
|
public JSONValue traverse(JSONValue obj, Callback callback, boolean deep) {
|
||||||
|
if (obj instanceof JSONArray) {
|
||||||
|
JSONArray array = (JSONArray) obj;
|
||||||
|
|
||||||
|
JSONArray processed_array = new JSONArray();
|
||||||
|
for (JSONValue elem : array) {
|
||||||
|
if (elem instanceof JSONObject && elem.contains("t")) {
|
||||||
|
JSONValue replacement = callback.invoke(elem.get("t").asString(), elem.contains("c") ? elem.get("c") : new JSONArray());
|
||||||
|
if (replacement == null) {
|
||||||
|
// no replacement object returned, use original
|
||||||
|
processed_array.add(traverse(elem, callback, deep));
|
||||||
|
} else if (replacement instanceof JSONArray) {
|
||||||
|
// array of objects returned, splice all elements into array
|
||||||
|
JSONArray replacement_array = (JSONArray) replacement;
|
||||||
|
for (JSONValue repl_elem : replacement_array) {
|
||||||
|
processed_array.add(traverse(repl_elem, callback, deep));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// replacement object given, traverse it
|
||||||
|
processed_array.add(traverse(replacement, callback, deep));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
processed_array.add(traverse(elem, callback, deep));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return processed_array;
|
||||||
|
} else if (obj instanceof JSONObject) {
|
||||||
|
if (deep && obj.contains("t")) {
|
||||||
|
JSONValue replacement = callback.invoke(obj.get("t").asString(), obj.contains("c") ? obj.get("c") : new JSONArray());
|
||||||
|
if (replacement != null) {
|
||||||
|
return replacement;
|
||||||
|
}
|
||||||
|
} JSONObject obj_obj = (JSONObject) obj;
|
||||||
|
var processed_obj = new JSONObject();
|
||||||
|
for (String key : obj_obj.keys()) {
|
||||||
|
processed_obj.put(key, traverse(obj_obj.get(key), callback, deep));
|
||||||
|
}
|
||||||
|
return processed_obj;
|
||||||
|
} else {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue createPandocNode(String type, JSONValue content) {
|
||||||
|
if (content == null) {
|
||||||
|
return new JSONObject(Map.of(
|
||||||
|
"t", new JSONString(type)));
|
||||||
|
} else {
|
||||||
|
return new JSONObject(Map.of(
|
||||||
|
"t", new JSONString(type),
|
||||||
|
"c", content));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue createPandocNode(String type) {
|
||||||
|
return createPandocNode(type, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper constructors to create pandoc format objects
|
||||||
|
*/
|
||||||
|
public JSONValue createSpace() {
|
||||||
|
return createPandocNode("Space");
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue createStr(String string) {
|
||||||
|
return createPandocNode("Str", new JSONString(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONValue loadJson(String[] args) throws FileNotFoundException {
|
||||||
|
StringBuffer input = new StringBuffer();
|
||||||
|
InputStreamReader reader;
|
||||||
|
if (args.length > 0)
|
||||||
|
reader = new FileReader(args[0]);
|
||||||
|
else {
|
||||||
|
reader = new InputStreamReader(System.in);
|
||||||
|
}
|
||||||
|
new BufferedReader(reader).lines().forEach(line -> input.append(line));
|
||||||
|
|
||||||
|
return JSON.parse(input.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Callback {
|
||||||
|
JSONValue invoke(String type, JSONValue value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package build.tools.pandocfilter;
|
||||||
|
|
||||||
|
import build.tools.pandocfilter.json.JSONArray;
|
||||||
|
import build.tools.pandocfilter.json.JSONObject;
|
||||||
|
import build.tools.pandocfilter.json.JSONValue;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class PandocManPageHtmlFilter extends PandocFilter {
|
||||||
|
|
||||||
|
private JSONValue MetaInlines(JSONValue value) {
|
||||||
|
return createPandocNode("MetaInlines", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONValue changeTitle(String type, JSONValue value) {
|
||||||
|
if (type.equals("MetaInlines")) {
|
||||||
|
String subType = value.get(0).get("t").asString();
|
||||||
|
String subContent = value.get(0).get("c").asString();
|
||||||
|
if (subType.equals("Str")) {
|
||||||
|
Pattern pattern = Pattern.compile("^([A-Z0-9]+)\\([0-9]+\\)$");
|
||||||
|
Matcher matcher = pattern.matcher(subContent);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String commandName = matcher.group(1).toLowerCase();
|
||||||
|
return MetaInlines(new JSONArray(
|
||||||
|
createStr("The"), createSpace(),
|
||||||
|
createStr(commandName),
|
||||||
|
createSpace(), createStr("Command")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws FileNotFoundException {
|
||||||
|
JSONValue json = loadJson(args);
|
||||||
|
|
||||||
|
PandocManPageHtmlFilter filter = new PandocManPageHtmlFilter();
|
||||||
|
|
||||||
|
JSONValue meta = json.get("meta");
|
||||||
|
if (meta != null && meta instanceof JSONObject) {
|
||||||
|
JSONObject metaobj = (JSONObject) meta;
|
||||||
|
metaobj.remove("date");
|
||||||
|
JSONValue title = meta.get("title");
|
||||||
|
if (title != null) {
|
||||||
|
metaobj.put("title", filter.traverse(title, filter::changeTitle, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(json);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package build.tools.pandocfilter;
|
||||||
|
|
||||||
|
import build.tools.pandocfilter.json.JSONArray;
|
||||||
|
import build.tools.pandocfilter.json.JSONValue;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
public class PandocManPageTroffFilter extends PandocFilter {
|
||||||
|
|
||||||
|
private JSONValue createStrong(JSONValue value) {
|
||||||
|
return createPandocNode("Strong", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONValue createHeader(JSONValue value) {
|
||||||
|
return createPandocNode("Header", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to change all Str texts to upper case
|
||||||
|
*/
|
||||||
|
private JSONValue uppercase(String type, JSONValue value) {
|
||||||
|
if (type.equals("Str")) {
|
||||||
|
return createStr(value.asString().toUpperCase());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main callback function that performs our man page AST rewrites
|
||||||
|
*/
|
||||||
|
private JSONValue manpageFilter(String type, JSONValue value) {
|
||||||
|
// If it is a header, decrease the heading level by one, and
|
||||||
|
// if it is a level 1 header, convert it to upper case.
|
||||||
|
if (type.equals("Header")) {
|
||||||
|
JSONArray array = value.asArray();
|
||||||
|
int level = array.get(0).asInt();
|
||||||
|
array.set(0, JSONValue.from(level - 1));
|
||||||
|
if (value.asArray().get(0).asInt() == 1) {
|
||||||
|
return createHeader(traverse(value, this::uppercase, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Man pages does not have superscript. We use it for footnotes, so
|
||||||
|
// enclose in [...] for best representation.
|
||||||
|
if (type.equals("Superscript")) {
|
||||||
|
return new JSONArray(createStr("["), value, createStr("]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it is a link, put the link name in bold. If it is an external
|
||||||
|
// link, put it in brackets. Otherwise, it is either an internal link
|
||||||
|
// (like "#next-heading"), or a relative link to another man page
|
||||||
|
// (like "java.html"), so remove it for man pages.
|
||||||
|
if (type.equals("Link")) {
|
||||||
|
JSONValue target = value.asArray().get(2).asArray().get(0);
|
||||||
|
String targetStr = target.asString();
|
||||||
|
if (targetStr.startsWith("https:") || targetStr.startsWith("http:")) {
|
||||||
|
return new JSONArray(createStrong(value.asArray().get(1)), createSpace(), createStr("[" + targetStr + "]"));
|
||||||
|
} else {
|
||||||
|
return createStrong(value.asArray().get(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws FileNotFoundException {
|
||||||
|
JSONValue json = loadJson(args);
|
||||||
|
build.tools.pandocfilter.PandocManPageTroffFilter filter = new build.tools.pandocfilter.PandocManPageTroffFilter();
|
||||||
|
|
||||||
|
JSONValue transformed_json = filter.traverse(json, filter::manpageFilter, false);
|
||||||
|
|
||||||
|
System.out.println(transformed_json);
|
||||||
|
}
|
||||||
|
}
|
61
make/jdk/src/classes/build/tools/pandocfilter/json/JSON.java
Normal file
61
make/jdk/src/classes/build/tools/pandocfilter/json/JSON.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
public class JSON {
|
||||||
|
public static JSONValue parse(String s) {
|
||||||
|
return new JSONParser().parse(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONValue of(int i) {
|
||||||
|
return JSONValue.from(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONValue of(long l) {
|
||||||
|
return JSONValue.from(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONValue of(double d) {
|
||||||
|
return JSONValue.from(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONValue of(boolean b) {
|
||||||
|
return JSONValue.from(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONValue of(String s) {
|
||||||
|
return JSONValue.from(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONValue of() {
|
||||||
|
return JSONValue.fromNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONArray array() {
|
||||||
|
return new JSONArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject object() {
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class JSONArray implements JSONValue, Iterable<JSONValue> {
|
||||||
|
private final List<JSONValue> values;
|
||||||
|
|
||||||
|
public JSONArray() {
|
||||||
|
this.values = new ArrayList<JSONValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray(JSONValue[] array) {
|
||||||
|
this.values = new ArrayList<JSONValue>(array.length);
|
||||||
|
for (var v : array) {
|
||||||
|
values.add(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void append(JSONValue value) {
|
||||||
|
if (value instanceof JSONArray) {
|
||||||
|
for (var v : value.asArray()) {
|
||||||
|
append(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.values.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray(JSONValue value, JSONValue... values) {
|
||||||
|
this.values = new ArrayList<JSONValue>(values.length + 1);
|
||||||
|
append(value);
|
||||||
|
for (var v : values) {
|
||||||
|
append(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray(List<JSONValue> values) {
|
||||||
|
this.values = new ArrayList<JSONValue>(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isArray() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray asArray() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray set(int i, boolean value) {
|
||||||
|
values.set(i, JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray set(int i, int value) {
|
||||||
|
values.set(i, JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray set(int i, long value) {
|
||||||
|
values.set(i, JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray set(int i, String value) {
|
||||||
|
values.set(i, JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray set(int i, double value) {
|
||||||
|
values.set(i, JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray set(int i, JSONValue value) {
|
||||||
|
values.set(i, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray setNull(int i) {
|
||||||
|
values.set(i, JSON.of());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray add(boolean value) {
|
||||||
|
values.add(JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray add(int value) {
|
||||||
|
values.add(JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray add(long value) {
|
||||||
|
values.add(JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray add(String value) {
|
||||||
|
values.add(JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray add(double value) {
|
||||||
|
values.add(JSON.of(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray add(JSONValue value) {
|
||||||
|
values.add(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray addNull() {
|
||||||
|
values.add(JSON.of());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue get(int i) {
|
||||||
|
return values.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return values.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
builder.append("[");
|
||||||
|
for (var i = 0; i < size(); i++) {
|
||||||
|
builder.append(get(i).toString());
|
||||||
|
if (i != (size() - 1)) {
|
||||||
|
builder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<JSONValue> stream() {
|
||||||
|
return values.stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<JSONValue> iterator() {
|
||||||
|
return values.iterator();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
public class JSONBoolean implements JSONValue {
|
||||||
|
private boolean value;
|
||||||
|
|
||||||
|
public JSONBoolean(boolean value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBoolean() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean asBoolean() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value ? "true" : "false";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
public class JSONDecimal implements JSONValue {
|
||||||
|
private double value;
|
||||||
|
|
||||||
|
public JSONDecimal(double value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDouble() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double asDouble() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Double.toString(value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
public class JSONNull implements JSONValue {
|
||||||
|
public JSONNull() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNull() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String asString() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray asArray() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject asObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
public class JSONNumber implements JSONValue {
|
||||||
|
private long value;
|
||||||
|
|
||||||
|
public JSONNumber(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONNumber(long value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInt() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLong() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int asInt() {
|
||||||
|
return Math.toIntExact(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long asLong() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Long.toString(value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class JSONObject implements JSONValue {
|
||||||
|
public static class Field {
|
||||||
|
private final String name;
|
||||||
|
private final JSONValue value;
|
||||||
|
|
||||||
|
private Field(String name, JSONValue value) {
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<String, JSONValue> value;
|
||||||
|
|
||||||
|
public JSONObject() {
|
||||||
|
this.value = new HashMap<String, JSONValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject(Map<String, JSONValue> map) {
|
||||||
|
this.value = new HashMap<String, JSONValue>(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isObject() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject asObject() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject put(String k, boolean v) {
|
||||||
|
value.put(k, JSON.of(v));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject put(String k, int v) {
|
||||||
|
value.put(k, JSON.of(v));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject put(String k, long v) {
|
||||||
|
value.put(k, JSON.of(v));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject put(String k, String v) {
|
||||||
|
value.put(k, JSON.of(v));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject put(String k, double v) {
|
||||||
|
value.put(k, JSON.of(v));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject put(String k, JSONArray v) {
|
||||||
|
value.put(k, v);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject put(String k, JSONObject v) {
|
||||||
|
value.put(k, v);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject put(String k, JSONValue v) {
|
||||||
|
value.put(k, v);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject putNull(String k) {
|
||||||
|
value.put(k, JSON.of());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue remove(String k) {
|
||||||
|
return value.remove(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue get(String k) {
|
||||||
|
return value.get(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Field> fields() {
|
||||||
|
return value.entrySet()
|
||||||
|
.stream()
|
||||||
|
.map(e -> new Field(e.getKey(), e.getValue()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(String field) {
|
||||||
|
return value.containsKey(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> keys() {
|
||||||
|
return value.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
builder.append("{");
|
||||||
|
for (var key : value.keySet()) {
|
||||||
|
builder.append("\"");
|
||||||
|
builder.append(key);
|
||||||
|
builder.append("\":");
|
||||||
|
builder.append(value.get(key).toString());
|
||||||
|
builder.append(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
var end = builder.length() - 1;
|
||||||
|
if (builder.charAt(end) == ',') {
|
||||||
|
builder.deleteCharAt(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("}");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,391 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class JSONParser {
|
||||||
|
private int pos = 0;
|
||||||
|
private String input;
|
||||||
|
|
||||||
|
JSONParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private IllegalStateException failure(String message) {
|
||||||
|
return new IllegalStateException(String.format("[%d]: %s : %s", pos, message, input));
|
||||||
|
}
|
||||||
|
|
||||||
|
private char current() {
|
||||||
|
return input.charAt(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void advance() {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasInput() {
|
||||||
|
return pos < input.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expectMoreInput(String message) {
|
||||||
|
if (!hasInput()) {
|
||||||
|
throw failure(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private char next(String message) {
|
||||||
|
advance();
|
||||||
|
if (!hasInput()) {
|
||||||
|
throw failure(message);
|
||||||
|
}
|
||||||
|
return current();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void expect(char c) {
|
||||||
|
var msg = String.format("Expected character %c", c);
|
||||||
|
|
||||||
|
var n = next(msg);
|
||||||
|
if (n != c) {
|
||||||
|
throw failure(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assume(char c, String message) {
|
||||||
|
expectMoreInput(message);
|
||||||
|
if (current() != c) {
|
||||||
|
throw failure(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONBoolean parseBoolean() {
|
||||||
|
if (current() == 't') {
|
||||||
|
expect('r');
|
||||||
|
expect('u');
|
||||||
|
expect('e');
|
||||||
|
advance();
|
||||||
|
return new JSONBoolean(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current() == 'f') {
|
||||||
|
expect('a');
|
||||||
|
expect('l');
|
||||||
|
expect('s');
|
||||||
|
expect('e');
|
||||||
|
advance();
|
||||||
|
return new JSONBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw failure("a boolean can only be 'true' or 'false'");
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONValue parseNumber() {
|
||||||
|
var isInteger = true;
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
if (current() == '-') {
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
expectMoreInput("a number cannot consist of only '-'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current() == '0') {
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
|
||||||
|
if (hasInput() && current() == '.') {
|
||||||
|
isInteger = false;
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
|
||||||
|
expectMoreInput("a number cannot end with '.'");
|
||||||
|
|
||||||
|
if (!isDigit(current())) {
|
||||||
|
throw failure("must be at least one digit after '.'");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (hasInput() && isDigit(current())) {
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (hasInput() && isDigit(current())) {
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasInput() && current() == '.') {
|
||||||
|
isInteger = false;
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
|
||||||
|
expectMoreInput("a number cannot end with '.'");
|
||||||
|
|
||||||
|
if (!isDigit(current())) {
|
||||||
|
throw failure("must be at least one digit after '.'");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (hasInput() && isDigit(current())) {
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasInput() && (current() == 'e' || current() == 'E')) {
|
||||||
|
isInteger = false;
|
||||||
|
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
expectMoreInput("a number cannot end with 'e' or 'E'");
|
||||||
|
|
||||||
|
if (current() == '+' || current() == '-') {
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDigit(current())) {
|
||||||
|
throw failure("a digit must follow {'e','E'}{'+','-'}");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (hasInput() && isDigit(current())) {
|
||||||
|
builder.append(current());
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = builder.toString();
|
||||||
|
return isInteger ? new JSONNumber(Long.parseLong(value)) :
|
||||||
|
new JSONDecimal(Double.parseDouble(value));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONString parseString() {
|
||||||
|
var missingEndChar = "string is not terminated with '\"'";
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
for (var c = next(missingEndChar); c != '"'; c = next(missingEndChar)) {
|
||||||
|
if (c == '\\') {
|
||||||
|
var n = next(missingEndChar);
|
||||||
|
switch (n) {
|
||||||
|
case '"':
|
||||||
|
builder.append("\"");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
builder.append("\\");
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
builder.append("/");
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
builder.append("\b");
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
builder.append("\f");
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
builder.append("\n");
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
builder.append("\r");
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
builder.append("\t");
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
var u1 = next(missingEndChar);
|
||||||
|
var u2 = next(missingEndChar);
|
||||||
|
var u3 = next(missingEndChar);
|
||||||
|
var u4 = next(missingEndChar);
|
||||||
|
var cp = Integer.parseInt(String.format("%c%c%c%c", u1, u2, u3, u4), 16);
|
||||||
|
builder.append(new String(new int[]{cp}, 0, 1));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw failure(String.format("Unexpected escaped character '%c'", n));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
advance(); // step beyond closing "
|
||||||
|
return new JSONString(builder.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONArray parseArray() {
|
||||||
|
var error = "array is not terminated with ']'";
|
||||||
|
var list = new ArrayList<JSONValue>();
|
||||||
|
|
||||||
|
advance(); // step beyond opening '['
|
||||||
|
consumeWhitespace();
|
||||||
|
expectMoreInput(error);
|
||||||
|
|
||||||
|
while (current() != ']') {
|
||||||
|
var val = parseValue();
|
||||||
|
list.add(val);
|
||||||
|
|
||||||
|
expectMoreInput(error);
|
||||||
|
if (current() == ',') {
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
expectMoreInput(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
advance(); // step beyond closing ']'
|
||||||
|
return new JSONArray(list.toArray(new JSONValue[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONNull parseNull() {
|
||||||
|
expect('u');
|
||||||
|
expect('l');
|
||||||
|
expect('l');
|
||||||
|
advance();
|
||||||
|
return new JSONNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject parseObject() {
|
||||||
|
var error = "object is not terminated with '}'";
|
||||||
|
var map = new HashMap<String, JSONValue>();
|
||||||
|
|
||||||
|
advance(); // step beyond opening '{'
|
||||||
|
consumeWhitespace();
|
||||||
|
expectMoreInput(error);
|
||||||
|
|
||||||
|
while (current() != '}') {
|
||||||
|
var key = parseValue();
|
||||||
|
if (!(key instanceof JSONString)) {
|
||||||
|
throw failure("a field must of type string");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasInput() || current() != ':') {
|
||||||
|
throw failure("a field must be followed by ':'");
|
||||||
|
}
|
||||||
|
advance(); // skip ':'
|
||||||
|
|
||||||
|
var val = parseValue();
|
||||||
|
map.put(key.asString(), val);
|
||||||
|
|
||||||
|
expectMoreInput(error);
|
||||||
|
if (current() == ',') {
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
expectMoreInput(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
advance(); // step beyond '}'
|
||||||
|
return new JSONObject(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDigit(char c) {
|
||||||
|
return c == '0' ||
|
||||||
|
c == '1' ||
|
||||||
|
c == '2' ||
|
||||||
|
c == '3' ||
|
||||||
|
c == '4' ||
|
||||||
|
c == '5' ||
|
||||||
|
c == '6' ||
|
||||||
|
c == '7' ||
|
||||||
|
c == '8' ||
|
||||||
|
c == '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStartOfNumber(char c) {
|
||||||
|
return isDigit(c) || c == '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStartOfString(char c) {
|
||||||
|
return c == '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStartOfBoolean(char c) {
|
||||||
|
return c == 't' || c == 'f';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStartOfArray(char c) {
|
||||||
|
return c == '[';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStartOfNull(char c) {
|
||||||
|
return c == 'n';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWhitespace(char c) {
|
||||||
|
return c == '\r' ||
|
||||||
|
c == '\n' ||
|
||||||
|
c == '\t' ||
|
||||||
|
c == ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStartOfObject(char c) {
|
||||||
|
return c == '{';
|
||||||
|
}
|
||||||
|
|
||||||
|
private void consumeWhitespace() {
|
||||||
|
while (hasInput() && isWhitespace(current())) {
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue parseValue() {
|
||||||
|
JSONValue ret = null;
|
||||||
|
|
||||||
|
consumeWhitespace();
|
||||||
|
if (hasInput()) {
|
||||||
|
var c = current();
|
||||||
|
|
||||||
|
if (isStartOfNumber(c)) {
|
||||||
|
ret = parseNumber();
|
||||||
|
} else if (isStartOfString(c)) {
|
||||||
|
ret = parseString();
|
||||||
|
} else if (isStartOfBoolean(c)) {
|
||||||
|
ret = parseBoolean();
|
||||||
|
} else if (isStartOfArray(c)) {
|
||||||
|
ret = parseArray();
|
||||||
|
} else if (isStartOfNull(c)) {
|
||||||
|
ret = parseNull();
|
||||||
|
} else if (isStartOfObject(c)) {
|
||||||
|
ret = parseObject();
|
||||||
|
} else {
|
||||||
|
throw failure("not a valid start of a JSON value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
consumeWhitespace();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONValue parse(String s) {
|
||||||
|
if (s == null || s.equals("")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = 0;
|
||||||
|
input = s;
|
||||||
|
|
||||||
|
var result = parseValue();
|
||||||
|
if (hasInput()) {
|
||||||
|
throw failure("can only have one top-level JSON value");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
public class JSONString implements JSONValue {
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public JSONString(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isString() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String asString() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
builder.append("\"");
|
||||||
|
|
||||||
|
for (var i = 0; i < value.length(); i++) {
|
||||||
|
var c = value.charAt(i);
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case '"':
|
||||||
|
builder.append("\\\"");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
builder.append("\\\\");
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
builder.append("\\/");
|
||||||
|
break;
|
||||||
|
case '\b':
|
||||||
|
builder.append("\\b");
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
builder.append("\\f");
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
builder.append("\\n");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
builder.append("\\r");
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
builder.append("\\t");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builder.append(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("\"");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2020, 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.
|
||||||
|
*/
|
||||||
|
package build.tools.pandocfilter.json;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface JSONValue {
|
||||||
|
default int asInt() {
|
||||||
|
throw new IllegalStateException("Unsupported conversion to int");
|
||||||
|
}
|
||||||
|
|
||||||
|
default long asLong() {
|
||||||
|
throw new IllegalStateException("Unsupported conversion to long");
|
||||||
|
}
|
||||||
|
|
||||||
|
default double asDouble() {
|
||||||
|
throw new IllegalStateException("Unsupported conversion to double");
|
||||||
|
}
|
||||||
|
|
||||||
|
default String asString() {
|
||||||
|
throw new IllegalStateException("Unsupported conversion to String");
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean asBoolean() {
|
||||||
|
throw new IllegalStateException("Unsupported conversion to boolean");
|
||||||
|
}
|
||||||
|
|
||||||
|
default JSONArray asArray() {
|
||||||
|
throw new IllegalStateException("Unsupported conversion to array");
|
||||||
|
}
|
||||||
|
|
||||||
|
default JSONObject asObject() {
|
||||||
|
throw new IllegalStateException("Unsupported conversion to object");
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isInt() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isLong() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isDouble() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isString() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isBoolean() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isArray() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isObject() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isNull() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<JSONObject.Field> fields() {
|
||||||
|
return asObject().fields();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean contains(String key) {
|
||||||
|
return asObject().contains(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
default JSONValue get(String key) {
|
||||||
|
return asObject().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
default JSONValue get(int i) {
|
||||||
|
return asArray().get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Stream<JSONValue> stream() {
|
||||||
|
return Stream.of(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSONValue from(int i) {
|
||||||
|
return new JSONNumber(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSONValue from(long l) {
|
||||||
|
return new JSONNumber(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSONValue from(double d) {
|
||||||
|
return new JSONDecimal(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSONValue from(boolean b) {
|
||||||
|
return new JSONBoolean(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSONValue from(String s) {
|
||||||
|
return new JSONString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSONValue fromNull() {
|
||||||
|
return new JSONNull();
|
||||||
|
}
|
||||||
|
}
|
@ -1,125 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2018, 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Traverse a tree of pandoc format objects, calling callback on each
|
|
||||||
// element, and replacing it if callback returns a new object.
|
|
||||||
//
|
|
||||||
// Inspired by the walk method in
|
|
||||||
// https://github.com/jgm/pandocfilters/blob/master/pandocfilters.py
|
|
||||||
//
|
|
||||||
function traverse(obj, callback) {
|
|
||||||
if (Array.isArray(obj)) {
|
|
||||||
var processed_array = [];
|
|
||||||
obj.forEach(function(elem) {
|
|
||||||
if (elem === Object(elem) && elem.t) {
|
|
||||||
var replacement = callback(elem.t, elem.c || []);
|
|
||||||
if (!replacement) {
|
|
||||||
// no replacement object returned, use original
|
|
||||||
processed_array.push(traverse(elem, callback));
|
|
||||||
} else if (Array.isArray(replacement)) {
|
|
||||||
// array of objects returned, splice all elements into array
|
|
||||||
replacement.forEach(function(repl_elem) {
|
|
||||||
processed_array.push(traverse(repl_elem, callback));
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// replacement object given, traverse it
|
|
||||||
processed_array.push(traverse(replacement, callback));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
processed_array.push(traverse(elem, callback));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return processed_array;
|
|
||||||
} else if (obj === Object(obj)) {
|
|
||||||
if (obj.t) {
|
|
||||||
var replacement = callback(obj.t, obj.c || []);
|
|
||||||
if (replacement) {
|
|
||||||
return replacement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var processed_obj = {};
|
|
||||||
Object.keys(obj).forEach(function(key) {
|
|
||||||
processed_obj[key] = traverse(obj[key], callback);
|
|
||||||
})
|
|
||||||
return processed_obj;
|
|
||||||
} else {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Helper constructors to create pandoc format objects
|
|
||||||
//
|
|
||||||
function Space() {
|
|
||||||
return { 't': 'Space' };
|
|
||||||
}
|
|
||||||
|
|
||||||
function Str(value) {
|
|
||||||
return { 't': 'Str', 'c': value };
|
|
||||||
}
|
|
||||||
|
|
||||||
function MetaInlines(value) {
|
|
||||||
return { 't': 'MetaInlines', 'c': value };
|
|
||||||
}
|
|
||||||
|
|
||||||
function change_title(type, value) {
|
|
||||||
if (type === 'MetaInlines') {
|
|
||||||
if (value[0].t === 'Str') {
|
|
||||||
var match = value[0].c.match(/^([A-Z0-9]+)\([0-9]+\)$/);
|
|
||||||
if (match) {
|
|
||||||
return MetaInlines([
|
|
||||||
Str("The"), Space(),
|
|
||||||
Str(match[1].toLowerCase()),
|
|
||||||
Space(), Str("Command")
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Main function
|
|
||||||
//
|
|
||||||
function main() {
|
|
||||||
var input = "";
|
|
||||||
while (line = readLine()) {
|
|
||||||
input = input.concat(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
var json = JSON.parse(input);
|
|
||||||
|
|
||||||
var meta = json.meta;
|
|
||||||
if (meta) {
|
|
||||||
meta.date = undefined;
|
|
||||||
var title = meta.title;
|
|
||||||
if (meta.title) {
|
|
||||||
meta.title = traverse(meta.title, change_title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print(JSON.stringify(json));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and execute it
|
|
||||||
main();
|
|
@ -22,7 +22,7 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Simple wrapper script to call Nashorn with the javascript pandoc filter
|
# Simple wrapper script to call Java with the pandoc filter
|
||||||
|
|
||||||
@@JJS@@ -scripting \
|
@@JAVA_SMALL@@ -cp @@BUILDTOOLS_OUTPUTDIR@@/jdk_tools_classes \
|
||||||
"@@TOPDIR@@/make/scripts/pandoc-html-manpage-filter.js" 2> /dev/null
|
build.tools.pandocfilter.PandocManPageHtmlFilter
|
||||||
|
@ -1,142 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2018, 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Traverse a tree of pandoc format objects, calling callback on each
|
|
||||||
// element, and replacing it if callback returns a new object.
|
|
||||||
//
|
|
||||||
// Inspired by the walk method in
|
|
||||||
// https://github.com/jgm/pandocfilters/blob/master/pandocfilters.py
|
|
||||||
//
|
|
||||||
function traverse(obj, callback) {
|
|
||||||
if (Array.isArray(obj)) {
|
|
||||||
var processed_array = [];
|
|
||||||
obj.forEach(function(elem) {
|
|
||||||
if (elem === Object(elem) && elem.t) {
|
|
||||||
var replacement = callback(elem.t, elem.c || []);
|
|
||||||
if (!replacement) {
|
|
||||||
// no replacement object returned, use original
|
|
||||||
processed_array.push(traverse(elem, callback));
|
|
||||||
} else if (Array.isArray(replacement)) {
|
|
||||||
// array of objects returned, splice all elements into array
|
|
||||||
replacement.forEach(function(repl_elem) {
|
|
||||||
processed_array.push(traverse(repl_elem, callback));
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// replacement object given, traverse it
|
|
||||||
processed_array.push(traverse(replacement, callback));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
processed_array.push(traverse(elem, callback));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return processed_array;
|
|
||||||
} else if (obj === Object(obj)) {
|
|
||||||
var processed_obj = {};
|
|
||||||
Object.keys(obj).forEach(function(key) {
|
|
||||||
processed_obj[key] = traverse(obj[key], callback);
|
|
||||||
})
|
|
||||||
return processed_obj;
|
|
||||||
} else {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Helper constructors to create pandoc format objects
|
|
||||||
//
|
|
||||||
function Space() {
|
|
||||||
return { 't': 'Space', 'c': [] };
|
|
||||||
}
|
|
||||||
|
|
||||||
function Str(value) {
|
|
||||||
return { 't': 'Str', 'c': value };
|
|
||||||
}
|
|
||||||
|
|
||||||
function Strong(value) {
|
|
||||||
return { 't': 'Strong', 'c': value };
|
|
||||||
}
|
|
||||||
|
|
||||||
function Header(value) {
|
|
||||||
return { 't': 'Header', 'c': value };
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Callback to change all Str texts to upper case
|
|
||||||
//
|
|
||||||
function uppercase(type, value) {
|
|
||||||
if (type === 'Str') {
|
|
||||||
return Str(value.toUpperCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Main callback function that performs our man page AST rewrites
|
|
||||||
//
|
|
||||||
function manpage_filter(type, value) {
|
|
||||||
// If it is a header, decrease the heading level by one, and
|
|
||||||
// if it is a level 1 header, convert it to upper case.
|
|
||||||
if (type === 'Header') {
|
|
||||||
value[0] = Math.max(1, value[0] - 1);
|
|
||||||
if (value[0] == 1) {
|
|
||||||
return Header(traverse(value, uppercase));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Man pages does not have superscript. We use it for footnotes, so
|
|
||||||
// enclose in [...] for best representation.
|
|
||||||
if (type === 'Superscript') {
|
|
||||||
return [ Str('['), value[0], Str(']') ];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it is a link, put the link name in bold. If it is an external
|
|
||||||
// link, put it in brackets. Otherwise, it is either an internal link
|
|
||||||
// (like "#next-heading"), or a relative link to another man page
|
|
||||||
// (like "java.html"), so remove it for man pages.
|
|
||||||
if (type === 'Link') {
|
|
||||||
var target = value[2][0];
|
|
||||||
if (target.match(/^http[s]?:/)) {
|
|
||||||
return [ Strong(value[1]), Space(), Str('[' + target + ']') ];
|
|
||||||
} else {
|
|
||||||
return Strong(value[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Main function
|
|
||||||
//
|
|
||||||
function main() {
|
|
||||||
var input = "";
|
|
||||||
while (line = readLine()) {
|
|
||||||
input = input.concat(line);
|
|
||||||
}
|
|
||||||
var json = JSON.parse(input);
|
|
||||||
|
|
||||||
var transformed_json = traverse(json, manpage_filter);
|
|
||||||
|
|
||||||
print(JSON.stringify(transformed_json));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and execute it
|
|
||||||
main();
|
|
@ -22,7 +22,7 @@
|
|||||||
# questions.
|
# questions.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Simple wrapper script to call Nashorn with the javascript pandoc filter
|
# Simple wrapper script to call Java with the pandoc filter
|
||||||
|
|
||||||
@@JJS@@ -scripting \
|
@@JAVA_SMALL@@ -cp @@BUILDTOOLS_OUTPUTDIR@@/jdk_tools_classes \
|
||||||
"@@TOPDIR@@/make/scripts/pandoc-troff-manpage-filter.js" 2> /dev/null
|
build.tools.pandocfilter.PandocManPageTroffFilter
|
||||||
|
Loading…
Reference in New Issue
Block a user