Skip to content

Instantly share code, notes, and snippets.

@eriwen
Created August 7, 2018 19:57
Show Gist options
  • Save eriwen/94f654d00d1d8560bda7716297255a01 to your computer and use it in GitHub Desktop.
Save eriwen/94f654d00d1d8560bda7716297255a01 to your computer and use it in GitHub Desktop.
/*
* Copyright 2016 the original author or authors.
*
* 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 org.gradle.docs.asciidoctor;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.DocumentRuby;
import org.asciidoctor.extension.IncludeProcessor;
import org.asciidoctor.extension.PreprocessorReader;
import java.util.*;
public class SampleIncludeProcessor extends IncludeProcessor {
private static final String SAMPLE = "sample";
private static final Map<String, String> FILE_SUFFIX_TO_SYNTAX = initializeSyntaxMap();
// Map file suffixes to syntax highlighting where they differ
private static Map<String, String> initializeSyntaxMap() {
Map<String, String> map = new HashMap<>();
map.put("gradle", "groovy");
map.put("kt", "kotlin");
map.put("kts", "kotlin");
map.put("py", "python");
map.put("sh", "bash");
map.put("rb", "ruby");
return Collections.unmodifiableMap(map);
}
// Even though these are unused, these constructors are necessary to prevent
// "(ArgumentError) asciidoctor: FAILED: Failed to load AsciiDoc document - wrong number of arguments (1 for 0)"
// See https://github.com/asciidoctor/asciidoctorj/issues/451#issuecomment-210914940
// This is fixed in asciidoctorj 1.6.0
public SampleIncludeProcessor() {
super(new HashMap<>());
}
public SampleIncludeProcessor(Map<String, Object> config) {
super(config);
}
@Override
public boolean handles(String target) {
return target.equals(SAMPLE);
}
@Override
public void process(DocumentRuby document, PreprocessorReader reader, String target, Map<String, Object> attributes) {
this.process(document(document), reader, target, attributes);
}
// This method adheres the asciidoctorj 1.6.0 API
public void process(Document document, PreprocessorReader reader, String target, Map<String, Object> attributes) {
if (!attributes.containsKey("dir") || !attributes.containsKey("files")) {
throw new IllegalStateException("Both the 'dir' and 'files' attributes are required to include a sample");
}
String dir = attributes.get("dir").toString();
List<String> files = Arrays.asList(attributes.get("files").toString().split(";"));
final String sampleContent = getSampleContent(dir, files);
reader.push_include(sampleContent, target, target, 1, attributes);
}
private String getSourceSyntax(String fileName) {
String syntax = "txt";
int i = fileName.lastIndexOf('.');
if (i > 0) {
String substring = fileName.substring(i + 1);
syntax = FILE_SUFFIX_TO_SYNTAX.getOrDefault(substring, substring);
}
return syntax;
}
private String getSampleContent(String sampleDir, List<String> files) {
StringBuilder builder = new StringBuilder(String.format("%n[.testable-sample,dir=\"%s\"]%n=====%n", sampleDir));
for (String fileDeclaration : files) {
String sourceFilePath = fileDeclaration.replaceAll("\\[[^]]*\\]", "");
String sourceSyntax = getSourceSyntax(sourceFilePath);
// FIXME: ensure includes here get processed
builder.append(String.format(".%s%n[source,%s]%n----%ninclude::%s/%s%n----%n", sourceFilePath, sourceSyntax, sampleDir, fileDeclaration));
}
builder.append(String.format("=====%n"));
return builder.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment