Simple Markdown rendering for skydoc
This uses apache velocity engine templates to create markdown-HTML. There are other alternatives, but there is already precedent for depending on this library from docgen.
RELNOTES: None.
PiperOrigin-RevId: 203795431
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/AttributeInfo.java b/src/main/java/com/google/devtools/build/skydoc/rendering/AttributeInfo.java
new file mode 100644
index 0000000..8051057
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/AttributeInfo.java
@@ -0,0 +1,37 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.skydoc.rendering;
+
+/**
+ * Stores information about a skylark attribute definition.
+ */
+public class AttributeInfo {
+
+ private final String name;
+ private final String docString;
+
+ public AttributeInfo(String name, String docString) {
+ this.name = name;
+ this.docString = docString;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDocString() {
+ return docString;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/BUILD b/src/main/java/com/google/devtools/build/skydoc/rendering/BUILD
index 0dc5f08..6a2633b 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/BUILD
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/BUILD
@@ -12,11 +12,20 @@
java_library(
name = "rendering",
srcs = glob(["*.java"]),
+ resources = [":template_files"],
deps = [
"//src/main/java/com/google/devtools/build/lib:events",
"//src/main/java/com/google/devtools/build/lib:skylarkinterface",
"//src/main/java/com/google/devtools/build/lib:syntax",
+ "//third_party:apache_velocity",
"//third_party:guava",
"//third_party:jsr305",
],
)
+
+filegroup(
+ name = "template_files",
+ srcs = glob([
+ "templates/*.vm",
+ ]),
+)
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
new file mode 100644
index 0000000..f9f5495
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
@@ -0,0 +1,77 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.skydoc.rendering;
+
+import com.google.common.base.Joiner;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+import org.apache.velocity.runtime.resource.loader.JarResourceLoader;
+
+/**
+ * Produces skydoc output in markdown form.
+ */
+public class MarkdownRenderer {
+
+ private static final String TEMPLATE_FILENAME =
+ "com/google/devtools/build/skydoc/rendering/templates/test.vm";
+
+ private final VelocityEngine velocityEngine;
+
+ public MarkdownRenderer() {
+ this.velocityEngine = new VelocityEngine();
+ velocityEngine.setProperty("resource.loader", "classpath, jar");
+ velocityEngine.setProperty("classpath.resource.loader.class",
+ ClasspathResourceLoader.class.getName());
+ velocityEngine.setProperty("jar.resource.loader.class", JarResourceLoader.class.getName());
+ velocityEngine.setProperty("input.encoding", "UTF-8");
+ velocityEngine.setProperty("output.encoding", "UTF-8");
+ velocityEngine.setProperty("runtime.references.strict", true);
+ }
+
+ /**
+ * Returns a markdown rendering of rule documentation for the given rule information object with
+ * the given rule name.
+ */
+ public String render(String ruleName, RuleInfo ruleInfo) throws IOException {
+ VelocityContext context = new VelocityContext();
+ // TODO(cparsons): Attributes in summary form should have links.
+ context.put("summaryform", getSummaryForm(ruleName, ruleInfo));
+ context.put("ruleName", ruleName);
+ context.put("ruleInfo", ruleInfo);
+
+ StringWriter stringWriter = new StringWriter();
+ try {
+ velocityEngine.mergeTemplate(TEMPLATE_FILENAME, "UTF-8", context, stringWriter);
+ } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
+ throw new IOException(e);
+ }
+ return stringWriter.toString();
+ }
+
+ private static String getSummaryForm(String ruleName, RuleInfo ruleInfo) {
+ List<String> attributeNames = ruleInfo.getAttributes().stream()
+ .map(attr -> attr.getName())
+ .collect(Collectors.toList());
+ return String.format("%s(%s)", ruleName, Joiner.on(", ").join(attributeNames));
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfo.java b/src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfo.java
index dee5e0f..6f231cf 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfo.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/RuleInfo.java
@@ -14,8 +14,6 @@
package com.google.devtools.build.skydoc.rendering;
-import com.google.common.base.Joiner;
-import com.google.common.base.Strings;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.syntax.BaseFunction;
import java.util.Collection;
@@ -28,16 +26,16 @@
private final BaseFunction identifierFunction;
private final Location location;
private final String docString;
- private final Collection<String> attrNames;
+ private final Collection<AttributeInfo> attrInfos;
public RuleInfo(BaseFunction identifierFunction,
Location location,
String docString,
- Collection<String> attrNames) {
+ Collection<AttributeInfo> attrInfos) {
this.identifierFunction = identifierFunction;
this.location = location;
this.docString = docString;
- this.attrNames = attrNames;
+ this.attrInfos = attrInfos;
}
public BaseFunction getIdentifierFunction() {
@@ -52,17 +50,7 @@
return docString;
}
- public Collection<String> getAttrNames() {
- return attrNames;
- }
-
- public String getDescription() {
- StringBuilder stringBuilder = new StringBuilder();
- if (!Strings.isNullOrEmpty(docString)) {
- stringBuilder.append(docString);
- stringBuilder.append("\n");
- }
- Joiner.on(",").appendTo(stringBuilder, attrNames);
- return stringBuilder.toString();
+ public Collection<AttributeInfo> getAttributes() {
+ return attrInfos;
}
}
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/templates/test.vm b/src/main/java/com/google/devtools/build/skydoc/rendering/templates/test.vm
new file mode 100644
index 0000000..b1600e9
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/templates/test.vm
@@ -0,0 +1,27 @@
+<a name="#${ruleName}"></a>
+#[[##]]# ${ruleName}
+
+<pre>
+${summaryform}
+</pre>
+
+${ruleInfo.docString}
+
+#[[###]]# Attributes
+
+#if (!$ruleInfo.attributes.isEmpty())
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+#foreach ($attribute in $ruleInfo.attributes)
+ <tr id="#${ruleName}_${attribute.name}">
+ <td><code>${attribute.name}</code></td>
+ <td>${attribute.docString}</td>
+ </tr>
+#end
+ </tbody>
+</table>
+#end