Skip to content

Commit

Permalink
8246435: Replace Javascript implementation of pandoc filters with Java
Browse files Browse the repository at this point in the history
Reviewed-by: erikj
  • Loading branch information
magicus committed Jun 6, 2020
1 parent 71c926c commit cd651b9
Show file tree
Hide file tree
Showing 23 changed files with 1,510 additions and 308 deletions.
8 changes: 4 additions & 4 deletions make/CompileToolsJdk.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ ifeq ($(ENABLE_PANDOC), true)
SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-troff-manpage-filter.sh.template, \
OUTPUT_FILE := $(PANDOC_TROFF_MANPAGE_FILTER), \
REPLACEMENTS := \
@@JJS@@ => $(JJS) ; \
@@TOPDIR@@ => $(TOPDIR) ; \
@@JAVA_SMALL@@ => $(JAVA_SMALL) ; \
@@BUILDTOOLS_OUTPUTDIR@@ => $(BUILDTOOLS_OUTPUTDIR) ; \
))

# Created script must be made executable
Expand All @@ -126,8 +126,8 @@ ifeq ($(ENABLE_PANDOC), true)
SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-html-manpage-filter.sh.template, \
OUTPUT_FILE := $(PANDOC_HTML_MANPAGE_FILTER), \
REPLACEMENTS := \
@@JJS@@ => $(JJS) ; \
@@TOPDIR@@ => $(TOPDIR) ; \
@@JAVA_SMALL@@ => $(JAVA_SMALL) ; \
@@BUILDTOOLS_OUTPUTDIR@@ => $(BUILDTOOLS_OUTPUTDIR) ; \
))

# Created script must be made executable
Expand Down
8 changes: 4 additions & 4 deletions make/Docs.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -610,9 +610,9 @@ ifeq ($(ENABLE_PANDOC), true)
# PANDOC_HTML_MANPAGE_FILTER, a wrapper around
# PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT. This is created by buildtools-jdk.

# We should also depend on the source javascript filter
PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT := \
$(TOPDIR)/make/scripts/pandoc-html-manpage-filter.js
# We should also depend on the source code for the filter
PANDOC_HTML_MANPAGE_FILTER_SOURCE := $(call FindFiles, \
$(TOPDIR)/make/jdk/src/classes/build/tools/pandocfilter)

$(foreach m, $(ALL_MODULES), \
$(eval MAN_$m := $(call FindModuleManDirs, $m)) \
Expand All @@ -632,7 +632,7 @@ ifeq ($(ENABLE_PANDOC), true)
OPTIONS := --toc -V include-before='$(SPECS_TOP)' -V include-after='$(SPECS_BOTTOM_1)', \
POST_PROCESS := $(TOOL_FIXUPPANDOC), \
EXTRA_DEPS := $(PANDOC_HTML_MANPAGE_FILTER) \
$(PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT), \
$(PANDOC_HTML_MANPAGE_FILTER_SOURCE), \
)) \
$(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
) \
Expand Down
16 changes: 0 additions & 16 deletions make/autoconf/boot-jdk.m4
Original file line number Diff line number Diff line change
Expand Up @@ -381,22 +381,6 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
BOOTJDK_USE_LOCAL_CDS=false
AC_MSG_RESULT([no, -XX:SharedArchiveFile not supported])
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],
Expand Down
2 changes: 0 additions & 2 deletions make/autoconf/spec.gmk.in
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,6 @@ JAR_CMD:=@JAR@
JLINK_CMD := @JLINK@
JMOD_CMD := @JMOD@
JARSIGNER_CMD:=@JARSIGNER@
JJS_CMD:=@JJS@
# These variables are meant to be used. They are defined with = instead of := to make
# it possible to override only the *_CMD variables.
JAVA=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
Expand All @@ -637,7 +636,6 @@ JAR=@FIXPATH@ $(JAR_CMD)
JLINK = @FIXPATH@ $(JLINK_CMD)
JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL)
JARSIGNER=@FIXPATH@ $(JARSIGNER_CMD)
JJS=@FIXPATH@ $(JJS_CMD) $(JAVA_TOOL_FLAGS_SMALL)

BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@
BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
Expand Down
8 changes: 4 additions & 4 deletions make/common/modules/LauncherCommon.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,9 @@ ifeq ($(call isTargetOsType, unix), true)
# PANDOC_TROFF_MANPAGE_FILTER, a wrapper around
# PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT. This is created by buildtools-jdk.

# We should also depend on the source javascript filter
PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT := \
$(TOPDIR)/make/scripts/pandoc-troff-manpage-filter.js
# We should also depend on the source code for the filter
PANDOC_TROFF_MANPAGE_FILTER_SOURCE := $(call FindFiles, \
$(TOPDIR)/make/jdk/src/classes/build/tools/pandocfilter)

# The norm in man pages is to display code literals as bold, but pandoc
# "correctly" converts these constructs (encoded in markdown using `...`
Expand Down Expand Up @@ -231,7 +231,7 @@ ifeq ($(call isTargetOsType, unix), true)
@@VERSION_SHORT@@ => $(VERSION_SHORT) ; \
@@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION), \
EXTRA_DEPS := $(PANDOC_TROFF_MANPAGE_FILTER) \
$(PANDOC_TROFF_MANPAGE_FILTER_JAVASCRIPT), \
$(PANDOC_TROFF_MANPAGE_FILTER_SOURCE), \
))

TARGETS += $(BUILD_MAN_PAGES)
Expand Down
6 changes: 1 addition & 5 deletions make/conf/jib-profiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,6 @@ var getJibProfilesProfiles = function (input, common, data) {
dependencies: [ name + ".jdk" ],
configure_args: [
"--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],
Expand Down Expand Up @@ -765,7 +761,7 @@ var getJibProfilesProfiles = function (input, common, data) {
profiles[cmpBaselineName].make_args = [ "COMPARE_BUILD=CONF=" ];
profiles[cmpBaselineName].configure_args = concat(
profiles[cmpBaselineName].configure_args,
"--with-hotspot-build-time=n/a",
"--with-hotspot-build-time=n/a",
"--disable-precompiled-headers");
// Do not inherit artifact definitions from base profile
delete profiles[cmpBaselineName].artifacts;
Expand Down
108 changes: 108 additions & 0 deletions make/jdk/src/classes/build/tools/pandocfilter/PandocFilter.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading

0 comments on commit cd651b9

Please sign in to comment.