blob: 2da5f6988f70c37b1271f814aebca78f6e999c4c [file] [log] [blame]
// Copyright (C) 2014 The Android Open Source Project
//
// 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.googlesource.gerrit.plugins.xdocs.formatter;
import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_ALLOW_HTML;
import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_INCLUDE_TOC;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.xdocs.ConfigSection;
import org.asciidoctor.Asciidoctor;
import org.asciidoctor.AttributesBuilder;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.SafeMode;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.Properties;
@Singleton
public class AsciidoctorFormatter implements StringFormatter {
public static final String NAME = "ASCIIDOCTOR";
private static final String BACKEND = "html5";
private static final String DOCTYPE = "article";
private static final String ERUBY = "erb";
private final Properties attributes;
private final FormatterUtil util;
private final Formatters formatters;
@Inject
public AsciidoctorFormatter(
FormatterUtil formatterUtil,
Formatters formatters) throws IOException {
this.attributes = readAttributes();
this.util = formatterUtil;
this.formatters = formatters;
}
@Override
public String format(String projectName, String path, String revision,
String abbrRev, ConfigSection globalCfg, String raw) throws IOException {
if (!globalCfg.getBoolean(KEY_ALLOW_HTML, false)) {
raw = suppressHtml(raw);
}
ConfigSection projectCfg =
formatters.getFormatterConfig(NAME, projectName);
String html = Asciidoctor.Factory.create(AsciidoctorFormatter.class.getClassLoader())
.convert(raw, createOptions(projectCfg, abbrRev));
return util.applyCss(html, NAME, projectName);
}
private String suppressHtml(String raw) throws IOException {
try (BufferedReader br = new BufferedReader(new StringReader(raw))) {
StringBuilder sb = new StringBuilder();
boolean embeddedHtml = false;
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith("++++")) {
embeddedHtml = !embeddedHtml;
}
if (!embeddedHtml && !line.startsWith("++++")) {
sb.append(line);
sb.append("\n");
}
}
return sb.toString();
}
}
private OptionsBuilder createOptions(ConfigSection cfg, String revision) {
return OptionsBuilder.options()
.backend(BACKEND)
.docType(DOCTYPE)
.eruby(ERUBY)
.safe(SafeMode.SECURE)
.attributes(getAttributes(cfg, revision))
.mkDirs(true);
}
private AttributesBuilder getAttributes(ConfigSection cfg, String revision) {
AttributesBuilder ab = AttributesBuilder.attributes()
.tableOfContents(cfg.getBoolean(KEY_INCLUDE_TOC, true))
.sourceHighlighter("prettify");
for (String name : attributes.stringPropertyNames()) {
ab.attribute(name, attributes.getProperty(name));
}
ab.attribute("last-update-label!");
ab.attribute("revnumber", revision);
return ab;
}
private static Properties readAttributes() throws IOException {
Properties attributes = new Properties();
try (InputStream in = AsciidoctorFormatter.class
.getResourceAsStream("asciidoctor.properties")) {
attributes.load(in);
}
return attributes;
}
}