Feature/open api v3 support (#405)
This commit is contained in:
@@ -54,6 +54,9 @@ configure(project.coreProjects) {
|
||||
options.encoding = 'UTF-8'
|
||||
options.compilerArgs += ["-Xlint:unchecked", "-parameters"]
|
||||
}
|
||||
tasks.withType(Javadoc){
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
jmh {
|
||||
duplicateClassesStrategy = 'warn'
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ ext {
|
||||
dependencyOverrides = [:]
|
||||
}
|
||||
implLibraries = [
|
||||
asciiDocJApi : "org.asciidoctor:asciidoctorj-api:2.2.0",
|
||||
commonsBeanUtils : "commons-beanutils:commons-beanutils:1.9.4",
|
||||
commonsCodec : "commons-codec:commons-codec:1.13",
|
||||
commonsCollections4: "org.apache.commons:commons-collections4:4.4",
|
||||
@@ -13,16 +14,20 @@ implLibraries = [
|
||||
commonsLang3 : "org.apache.commons:commons-lang3:3.9",
|
||||
commonsIO : "commons-io:commons-io:2.6",
|
||||
commonsText : "org.apache.commons:commons-text:1.8",
|
||||
guava : 'com.google.guava:guava:27.0.1-android',
|
||||
jacksonDatabind : 'com.fasterxml.jackson.core:jackson-databind:2.9.10',
|
||||
mark2Ascii : "nl.jworks.markdown_to_asciidoc:markdown_to_asciidoc:1.1",
|
||||
paleo : "ch.netzwerg:paleo-core:0.14.0",
|
||||
pegdown : "org.pegdown:pegdown:1.6.0",
|
||||
slf4j : "org.slf4j:slf4j-api:1.7.28",
|
||||
swaggerConverterV2 : "io.swagger.parser.v3:swagger-parser-v2-converter:2.0.15",
|
||||
swaggerV2 : "io.swagger:swagger-parser:1.0.47",
|
||||
swaggerV2Converter : "io.swagger.parser.v3:swagger-parser-v2-converter:2.0.15",
|
||||
swaggerV3 : "io.swagger.parser.v3:swagger-parser:2.0.15",
|
||||
vavr : "io.vavr:vavr:0.10.2"
|
||||
]
|
||||
|
||||
testLibraries = [
|
||||
asciiDocJ : "org.asciidoctor:asciidoctorj:2.1.0",
|
||||
asciiDocJ : "org.asciidoctor:asciidoctorj:2.2.0",
|
||||
assertj : "org.assertj:assertj-core:3.13.2",
|
||||
assertjDiff: "io.github.robwin:assertj-diff:0.1.1",
|
||||
junit : "junit:junit:4.12",
|
||||
@@ -36,9 +41,9 @@ dependencyOverrides = [
|
||||
commonsIO : implLibraries.commonsIO,
|
||||
commonsLang3 : implLibraries.commonsLang3,
|
||||
findBugs : 'com.google.code.findbugs:jsr305:3.0.2',
|
||||
guava : 'com.google.guava:guava:27.0.1-android',
|
||||
guava : implLibraries.guava,
|
||||
jaksonCore : 'com.github.fge:jackson-coreutils:1.8',
|
||||
jacksonDatabind: 'com.fasterxml.jackson.core:jackson-databind:2.9.10',
|
||||
jacksonDatabind: implLibraries.jacksonDatabind,
|
||||
jnrConstants : 'com.github.jnr:jnr-constants:0.9.12',
|
||||
jnrEnxio : 'com.github.jnr:jnr-enxio:0.19',
|
||||
jnrPosix : 'com.github.jnr:jnr-posix:3.0.49',
|
||||
|
||||
34
openapi2markup/build.gradle
Normal file
34
openapi2markup/build.gradle
Normal file
@@ -0,0 +1,34 @@
|
||||
ext.moduleName="io.github.swagger2markup.openapi2markup"
|
||||
|
||||
dependencies {
|
||||
configurations.all {
|
||||
resolutionStrategy.force dependencyOverrides.commonsCodec
|
||||
resolutionStrategy.force dependencyOverrides.commonsIO
|
||||
resolutionStrategy.force dependencyOverrides.commonsLang3
|
||||
resolutionStrategy.force dependencyOverrides.jnrConstants
|
||||
resolutionStrategy.force dependencyOverrides.jnrEnxio
|
||||
resolutionStrategy.force dependencyOverrides.jnrPosix
|
||||
resolutionStrategy.force dependencyOverrides.jodaTime
|
||||
resolutionStrategy.force dependencyOverrides.slf4j
|
||||
resolutionStrategy.force dependencyOverrides.jacksonDatabind
|
||||
resolutionStrategy.force dependencyOverrides.guava
|
||||
resolutionStrategy.force dependencyOverrides.findBugs
|
||||
resolutionStrategy.force dependencyOverrides.jaksonCore
|
||||
resolutionStrategy.force dependencyOverrides.assertj
|
||||
}
|
||||
// implementation implLibraries.swaggerV2Converter
|
||||
compile project(':swagger2markup-asciidoc')
|
||||
compile project(':swagger2markup-core')
|
||||
implementation implLibraries.asciiDocJApi
|
||||
implementation implLibraries.commonsText
|
||||
implementation implLibraries.commonsBeanUtils
|
||||
implementation implLibraries.slf4j
|
||||
implementation implLibraries.swaggerV3
|
||||
implementation implLibraries.commonsCollections4
|
||||
implementation implLibraries.commonsConf2
|
||||
implementation implLibraries.vavr
|
||||
testImplementation testLibraries.assertj
|
||||
testImplementation testLibraries.assertjDiff
|
||||
testImplementation testLibraries.junit
|
||||
testImplementation testLibraries.logback
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup;
|
||||
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.config.Labels;
|
||||
import io.github.swagger2markup.config.MarkupLanguage;
|
||||
import io.github.swagger2markup.config.OpenAPILabels;
|
||||
import io.github.swagger2markup.config.builder.OpenAPI2MarkupConfigBuilder;
|
||||
import io.github.swagger2markup.extension.OpenAPI2MarkupExtensionRegistry;
|
||||
import io.github.swagger2markup.extension.builder.OpenAPI2MarkupExtensionRegistryBuilder;
|
||||
import io.github.swagger2markup.internal.document.ComponentsDocument;
|
||||
import io.github.swagger2markup.internal.document.OverviewDocument;
|
||||
import io.github.swagger2markup.internal.document.PathsDocument;
|
||||
import io.github.swagger2markup.internal.document.SecurityDocument;
|
||||
import io.github.swagger2markup.utils.URIUtils;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.parser.OpenAPIV3Parser;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class OpenAPI2MarkupConverter extends AbstractSchema2MarkupConverter<OpenAPI> {
|
||||
private final OverviewDocument overviewDocument;
|
||||
private final PathsDocument pathsDocument;
|
||||
private final ComponentsDocument componentsDocument;
|
||||
private final SecurityDocument securityDocument;
|
||||
private final OpenAPIContext openAPIContext;
|
||||
|
||||
|
||||
public OpenAPI2MarkupConverter(OpenAPIContext context) {
|
||||
super(context);
|
||||
this.openAPIContext = context;
|
||||
this.overviewDocument = new OverviewDocument(context);
|
||||
this.pathsDocument = new PathsDocument(context);
|
||||
this.componentsDocument = new ComponentsDocument(context);
|
||||
this.securityDocument = new SecurityDocument(context);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder from a URI.
|
||||
*
|
||||
* @param swaggerUri the URI
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(URI swaggerUri) {
|
||||
Validate.notNull(swaggerUri, "swaggerUri must not be null");
|
||||
String scheme = swaggerUri.getScheme();
|
||||
if (scheme != null && swaggerUri.getScheme().startsWith("http")) {
|
||||
try {
|
||||
return from(swaggerUri.toURL());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException("Failed to convert URI to URL", e);
|
||||
}
|
||||
} else if (scheme != null && swaggerUri.getScheme().startsWith("file")) {
|
||||
return from(Paths.get(swaggerUri));
|
||||
} else {
|
||||
return from(URIUtils.convertUriWithoutSchemeToFileScheme(swaggerUri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder using a remote URL.
|
||||
*
|
||||
* @param swaggerURL the remote URL
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(URL swaggerURL) {
|
||||
Validate.notNull(swaggerURL, "swaggerURL must not be null");
|
||||
return new Builder(swaggerURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder using a local Path.
|
||||
*
|
||||
* @param swaggerPath the local Path
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(Path swaggerPath) {
|
||||
Validate.notNull(swaggerPath, "swaggerPath must not be null");
|
||||
if (Files.notExists(swaggerPath)) {
|
||||
throw new IllegalArgumentException(String.format("swaggerPath does not exist: %s", swaggerPath));
|
||||
}
|
||||
try {
|
||||
if (Files.isHidden(swaggerPath)) {
|
||||
throw new IllegalArgumentException("swaggerPath must not be a hidden file");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to check if swaggerPath is a hidden file", e);
|
||||
}
|
||||
return new Builder(swaggerPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger model.
|
||||
*
|
||||
* @param openAPI the Swagger source.
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(OpenAPI openAPI) {
|
||||
Validate.notNull(openAPI, "schema must not be null");
|
||||
return new Builder(openAPI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger YAML or JSON String.
|
||||
*
|
||||
* @param swaggerString the Swagger YAML or JSON String.
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(String swaggerString) {
|
||||
Validate.notEmpty(swaggerString, "swaggerString must not be null");
|
||||
return from(new StringReader(swaggerString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a OpenAPI2MarkupConverter.Builder from a given Swagger YAML or JSON reader.
|
||||
*
|
||||
* @param schemaReader the schema YAML or JSON reader.
|
||||
* @return a OpenAPI2MarkupConverter
|
||||
*/
|
||||
public static Builder from(Reader schemaReader) {
|
||||
Validate.notNull(schemaReader, "swaggerReader must not be null");
|
||||
OpenAPI openAPI;
|
||||
try {
|
||||
//TODO
|
||||
openAPI = new OpenAPIV3Parser().read(IOUtils.toString(schemaReader));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Swagger source can not be parsed", e);
|
||||
}
|
||||
if (openAPI == null)
|
||||
throw new IllegalArgumentException("Swagger source is in a wrong format");
|
||||
|
||||
return new Builder(openAPI);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void toFolder(Path outputDirectory) {
|
||||
Validate.notNull(outputDirectory, "outputDirectory must not be null");
|
||||
openAPIContext.setOutputPath(outputDirectory);
|
||||
writeToFile(applyOverviewDocument(), outputDirectory.resolve(openAPIContext.config.getOverviewDocument()));
|
||||
writeToFile(applyPathsDocument(), outputDirectory.resolve(openAPIContext.config.getPathsDocument()));
|
||||
writeToFile(applyComponentsDocument(), outputDirectory.resolve(openAPIContext.config.getDefinitionsDocument()));
|
||||
writeToFile(applySecurityDocument(), outputDirectory.resolve(openAPIContext.config.getSecurityDocument()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toFile(Path outputFile) {
|
||||
Validate.notNull(outputFile, "outputFile must not be null");
|
||||
|
||||
writeToFile(applyOverviewDocument(), outputFile);
|
||||
writeToFile(applyPathsDocument(), outputFile);
|
||||
writeToFile(applyComponentsDocument(), outputFile);
|
||||
writeToFile(applySecurityDocument(), outputFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toFileWithoutExtension(Path outputFile) {
|
||||
Validate.notNull(outputFile, "outputFile must not be null");
|
||||
|
||||
writeToFileWithoutExtension(applyOverviewDocument(), outputFile);
|
||||
writeToFileWithoutExtension(applyPathsDocument(), outputFile);
|
||||
writeToFileWithoutExtension(applyComponentsDocument(), outputFile);
|
||||
writeToFileWithoutExtension(applySecurityDocument(), outputFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return applyOverviewDocument().convert() +
|
||||
applyPathsDocument().convert() +
|
||||
applyComponentsDocument().convert() +
|
||||
applySecurityDocument().convert();
|
||||
}
|
||||
|
||||
private Document applyOverviewDocument() {
|
||||
return overviewDocument.apply(
|
||||
openAPIContext.createDocument(),
|
||||
OverviewDocument.parameters(openAPIContext.getSchema()));
|
||||
}
|
||||
|
||||
private Document applyPathsDocument() {
|
||||
return pathsDocument.apply(
|
||||
openAPIContext.createDocument(),
|
||||
PathsDocument.parameters(openAPIContext.getSchema()));
|
||||
}
|
||||
|
||||
private Document applyComponentsDocument() {
|
||||
return componentsDocument.apply(
|
||||
openAPIContext.createDocument(),
|
||||
ComponentsDocument.parameters(openAPIContext.getSchema().getComponents()));
|
||||
}
|
||||
|
||||
private Document applySecurityDocument() {
|
||||
return securityDocument.apply(
|
||||
openAPIContext.createDocument(),
|
||||
SecurityDocument.parameters(openAPIContext.getSchema()));
|
||||
}
|
||||
|
||||
private void writeToFile(Document document, Path path) {
|
||||
MarkupLanguage markupLanguage = openAPIContext.config.getMarkupLanguage();
|
||||
if (isMarkupLanguageSupported(markupLanguage)) {
|
||||
String fileExtension = markupLanguage.getFileNameExtensions().get(0);
|
||||
writeToFileWithoutExtension(document, path.resolveSibling(path.getFileName().toString() + fileExtension));
|
||||
} else {
|
||||
throw new RuntimeException("Given Markup language '"+markupLanguage+"' is not supported by "+getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMarkupLanguageSupported(MarkupLanguage markupLanguage) {
|
||||
return markupLanguage == MarkupLanguage.ASCIIDOC;
|
||||
}
|
||||
|
||||
private void writeToFileWithoutExtension(Document document, Path file) {
|
||||
if (file.getParent() != null) {
|
||||
try {
|
||||
Files.createDirectories(file.getParent());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed create directory", e);
|
||||
}
|
||||
}
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
|
||||
writer.write(document.convert());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to write file", e);
|
||||
}
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Markup document written to: {}", file);
|
||||
}
|
||||
}
|
||||
|
||||
public static class OpenAPIContext extends Context<OpenAPI> {
|
||||
private OpenAPI2MarkupConfigBuilder.OpenSchema2MarkupConfig config;
|
||||
private OpenAPI2MarkupExtensionRegistry extensionRegistry;
|
||||
|
||||
public OpenAPIContext(OpenAPI2MarkupConfigBuilder.OpenSchema2MarkupConfig config,
|
||||
OpenAPI2MarkupExtensionRegistry extensionRegistry,
|
||||
OpenAPI schema, URI swaggerLocation, Labels labels) {
|
||||
super(config, extensionRegistry, schema, swaggerLocation, labels);
|
||||
this.config = config;
|
||||
this.extensionRegistry = extensionRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenAPI2MarkupConfigBuilder.OpenSchema2MarkupConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenAPI2MarkupExtensionRegistry getExtensionRegistry() {
|
||||
return extensionRegistry;
|
||||
}
|
||||
|
||||
public Document createDocument() {
|
||||
return new DocumentImpl();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final OpenAPI openAPI;
|
||||
private final URI schemaLocation;
|
||||
private OpenAPI2MarkupConfigBuilder.OpenSchema2MarkupConfig config;
|
||||
private OpenAPI2MarkupExtensionRegistry extensionRegistry;
|
||||
|
||||
/**
|
||||
* Creates a Builder from a remote URL.
|
||||
*
|
||||
* @param schemaUrl the remote URL
|
||||
*/
|
||||
Builder(URL schemaUrl) {
|
||||
try {
|
||||
this.schemaLocation = schemaUrl.toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException("swaggerURL is in a wrong format", e);
|
||||
}
|
||||
this.openAPI = readSchema(schemaUrl.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder from a local Path.
|
||||
*
|
||||
* @param swaggerPath the local Path
|
||||
*/
|
||||
Builder(Path swaggerPath) {
|
||||
this.schemaLocation = swaggerPath.toAbsolutePath().toUri();
|
||||
this.openAPI = readSchema(swaggerPath.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Builder using a given Swagger model.
|
||||
*
|
||||
* @param openAPI the Swagger source.
|
||||
*/
|
||||
Builder(OpenAPI openAPI) {
|
||||
this.openAPI = openAPI;
|
||||
this.schemaLocation = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the SwaggerParser to read the Swagger source.
|
||||
*
|
||||
* @param schemaLocation the location of the Swagger source
|
||||
* @return the Swagger model
|
||||
*/
|
||||
private OpenAPI readSchema(String schemaLocation) {
|
||||
OpenAPI openAPI = new OpenAPIV3Parser().read(schemaLocation);
|
||||
if (openAPI == null) {
|
||||
throw new IllegalArgumentException("Failed to read the schema");
|
||||
}
|
||||
return openAPI;
|
||||
}
|
||||
|
||||
public Builder withConfig(OpenAPI2MarkupConfigBuilder.OpenSchema2MarkupConfig config) {
|
||||
Validate.notNull(config, "config must not be null");
|
||||
this.config = config;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withExtensionRegistry(OpenAPI2MarkupExtensionRegistry registry) {
|
||||
Validate.notNull(registry, "registry must not be null");
|
||||
this.extensionRegistry = registry;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupConverter build() {
|
||||
if (config == null)
|
||||
config = new OpenAPI2MarkupConfigBuilder().build();
|
||||
|
||||
if (extensionRegistry == null)
|
||||
extensionRegistry = new OpenAPI2MarkupExtensionRegistryBuilder().build();
|
||||
OpenAPILabels openApiLabels = new OpenAPILabels(config);
|
||||
OpenAPIContext context = new OpenAPIContext(config, extensionRegistry, openAPI, schemaLocation, openApiLabels);
|
||||
|
||||
initExtensions(context);
|
||||
|
||||
applySwaggerExtensions(context);
|
||||
|
||||
return new OpenAPI2MarkupConverter(context);
|
||||
}
|
||||
|
||||
private void initExtensions(OpenAPIContext context) {
|
||||
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
extensionRegistry.getOverviewDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
extensionRegistry.getDefinitionsDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
extensionRegistry.getSecurityDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
|
||||
}
|
||||
|
||||
private void applySwaggerExtensions(OpenAPIContext context) {
|
||||
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.apply(context.getSchema()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup;
|
||||
|
||||
import org.apache.commons.configuration2.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class OpenAPI2MarkupProperties extends Schema2MarkupProperties {
|
||||
|
||||
public OpenAPI2MarkupProperties(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupProperties(Map<String, String> map) {
|
||||
super(map);
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupProperties(Configuration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package io.github.swagger2markup.config;
|
||||
|
||||
import io.github.swagger2markup.config.builder.OpenAPI2MarkupConfigBuilder;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class OpenAPILabels extends Labels {
|
||||
|
||||
public static final String LABEL_CONTENT = "label_content";
|
||||
public static final String LABEL_DEFAULT = "label_default";
|
||||
public static final String LABEL_DEPRECATED = "label_deprecated";
|
||||
public static final String LABEL_EXAMPLE = "label_example";
|
||||
public static final String LABEL_EXAMPLES = "label_examples";
|
||||
public static final String LABEL_EXCLUSIVE_MAXIMUM = "label_exclusive_maximum";
|
||||
public static final String LABEL_EXCLUSIVE_MINIMUM = "label_exclusive_minimum";
|
||||
public static final String LABEL_EXTERNAL_VALUE = "label_external_value";
|
||||
public static final String LABEL_FORMAT = "label_format";
|
||||
public static final String LABEL_MAXIMUM = "label_maximum";
|
||||
public static final String LABEL_MAX_ITEMS = "label_max_items";
|
||||
public static final String LABEL_MAX_LENGTH = "label_max_length";
|
||||
public static final String LABEL_MAX_PROPERTIES = "label_max_properties";
|
||||
public static final String LABEL_MINIMUM = "label_minimum";
|
||||
public static final String LABEL_MIN_ITEMS = "label_min_items";
|
||||
public static final String LABEL_MIN_LENGTH = "label_min_length";
|
||||
public static final String LABEL_MIN_PROPERTIES = "label_min_properties";
|
||||
public static final String LABEL_MULTIPLE_OF = "label_multiple_of";
|
||||
public static final String LABEL_NO_LINKS = "label_no_links";
|
||||
public static final String LABEL_NULLABLE = "label_nullable";
|
||||
public static final String LABEL_OPERATION = "label_operation";
|
||||
public static final String LABEL_OPTIONAL = "label_optional";
|
||||
public static final String LABEL_PARAMETERS = "label_parameters";
|
||||
public static final String LABEL_READ_ONLY = "label_read_only";
|
||||
public static final String LABEL_REQUIRED = "label_required";
|
||||
public static final String LABEL_SERVER = "label_server";
|
||||
public static final String LABEL_TERMS_OF_SERVICE = "label_terms_of_service";
|
||||
public static final String LABEL_TITLE = "label_title";
|
||||
public static final String LABEL_TYPE = "label_type";
|
||||
public static final String LABEL_UNIQUE_ITEMS = "label_unique_items";
|
||||
public static final String LABEL_WRITE_ONLY = "label_write_only";
|
||||
public static final String SECTION_TITLE_COMPONENTS = "section_title_components";
|
||||
public static final String SECTION_TITLE_PARAMETERS = "section_title_parameters";
|
||||
public static final String SECTION_TITLE_PATHS = "section_title_paths";
|
||||
public static final String SECTION_TITLE_SCHEMAS = "section_title_schemas";
|
||||
public static final String SECTION_TITLE_SECURITY = "section_title_security";
|
||||
public static final String SECTION_TITLE_SERVERS = "section_title_servers";
|
||||
public static final String SECTION_TITLE_OVERVIEW = "section_title_overview";
|
||||
public static final String SECTION_TITLE_TAGS = "section_title_tags";
|
||||
public static final String SECTION_TITLE_RESPONSES = "section_title_responses";
|
||||
public static final String SECTION_TITLE_HEADERS = "section_title_headers";
|
||||
public static final String SECTION_TITLE_LINKS = "section_title_links";
|
||||
public static final String TABLE_HEADER_DEFAULT = "table_header_default";
|
||||
public static final String TABLE_HEADER_DESCRIPTION = "table_header_description";
|
||||
public static final String TABLE_HEADER_HTTP_CODE = "table_header_http_code";
|
||||
public static final String TABLE_HEADER_LINKS = "table_header_links";
|
||||
public static final String TABLE_HEADER_NAME = "table_header_name";
|
||||
public static final String TABLE_HEADER_POSSIBLE_VALUES = "table_header_possible_values";
|
||||
public static final String TABLE_HEADER_SCHEMA = "table_header_schema";
|
||||
public static final String TABLE_HEADER_SCOPES = "table_header_scopes";
|
||||
public static final String TABLE_HEADER_TYPE = "table_header_type";
|
||||
public static final String TABLE_HEADER_VARIABLE = "table_header_variable";
|
||||
public static final String TABLE_TITLE_HEADERS = "table_title_headers";
|
||||
public static final String TABLE_TITLE_PARAMETERS = "table_title_parameters";
|
||||
public static final String TABLE_TITLE_PROPERTIES = "table_title_properties";
|
||||
public static final String TABLE_TITLE_RESPONSES = "table_title_responses";
|
||||
public static final String TABLE_TITLE_SECURITY = "table_title_security";
|
||||
public static final String TABLE_TITLE_SERVER_VARIABLES = "table_title_server_variables";
|
||||
|
||||
public OpenAPILabels(OpenAPI2MarkupConfigBuilder.OpenSchema2MarkupConfig config) {
|
||||
super(ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getLanguage().toLocale()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package io.github.swagger2markup.config.builder;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupProperties;
|
||||
import org.apache.commons.configuration2.Configuration;
|
||||
import org.apache.commons.configuration2.ConfigurationConverter;
|
||||
import org.apache.commons.configuration2.MapConfiguration;
|
||||
import org.apache.commons.configuration2.PropertiesConfiguration;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class OpenAPI2MarkupConfigBuilder extends Schema2MarkupConfigBuilder {
|
||||
private OpenSchema2MarkupConfig openApi2MarkupConfig;
|
||||
|
||||
public OpenAPI2MarkupConfigBuilder() {
|
||||
this(new PropertiesConfiguration());
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupConfigBuilder(Properties properties) {
|
||||
this(ConfigurationConverter.getConfiguration(properties));
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupConfigBuilder(Map<String, String> map) {
|
||||
this(new MapConfiguration(map));
|
||||
}
|
||||
|
||||
private OpenAPI2MarkupConfigBuilder(Configuration configuration) {
|
||||
super(new OpenAPI2MarkupProperties(getCompositeConfiguration(configuration)), configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultSchema2MarkupConfig createConfigInstance() {
|
||||
if(openApi2MarkupConfig == null) {
|
||||
openApi2MarkupConfig = new OpenSchema2MarkupConfig();
|
||||
}
|
||||
return openApi2MarkupConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenSchema2MarkupConfig build() {
|
||||
buildNaturalOrdering();
|
||||
return openApi2MarkupConfig;
|
||||
}
|
||||
|
||||
public static class OpenSchema2MarkupConfig extends DefaultSchema2MarkupConfig {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter.OpenAPIContext;
|
||||
|
||||
/**
|
||||
* An abstract OpenAPI extension which must be extended by an other OpenAPI extensions
|
||||
*/
|
||||
abstract class AbstractExtension implements Extension {
|
||||
|
||||
protected OpenAPIContext globalContext;
|
||||
|
||||
/**
|
||||
* Global context lazy initialization
|
||||
*
|
||||
* @param globalContext Global context
|
||||
*/
|
||||
public void setGlobalContext(OpenAPIContext globalContext) {
|
||||
this.globalContext = globalContext;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.github.swagger2markup.extension;
|
||||
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
public class ContentContext {
|
||||
private Document document;
|
||||
|
||||
public ContentContext(Document document) {
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
public Document getDocument() {
|
||||
return document;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import io.swagger.models.Model;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* DefinitionsDocumentExtension extension point can be used to extend the definitions document content.
|
||||
*/
|
||||
public abstract class DefinitionsDocumentExtension extends AbstractExtension {
|
||||
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
DOCUMENT_AFTER,
|
||||
DEFINITION_BEFORE,
|
||||
DEFINITION_BEGIN,
|
||||
DEFINITION_END,
|
||||
DEFINITION_AFTER
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private String definitionName;
|
||||
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private Model model;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
*/
|
||||
public Context(Position position, Document document) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param definitionName the name of the current definition
|
||||
* @param model the current Model of the definition
|
||||
*/
|
||||
public Context(Position position, Document document, String definitionName, Model model) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.DEFINITION_BEFORE, Position.DEFINITION_AFTER, position);
|
||||
Validate.notNull(definitionName);
|
||||
Validate.notNull(model);
|
||||
this.position = position;
|
||||
this.definitionName = definitionName;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Optional<String> getDefinitionName() {
|
||||
return Optional.ofNullable(definitionName);
|
||||
}
|
||||
|
||||
public Optional<Model> getModel() {
|
||||
return Optional.ofNullable(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import static io.github.swagger2markup.OpenAPI2MarkupConverter.OpenAPIContext;
|
||||
|
||||
/**
|
||||
* Extension interface which must be implemented by an OpenAPI extension
|
||||
*/
|
||||
interface Extension {
|
||||
|
||||
/**
|
||||
* Global context lazy initialization
|
||||
*
|
||||
* @param globalContext Global context
|
||||
*/
|
||||
void setGlobalContext(OpenAPIContext globalContext);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import io.github.swagger2markup.config.builder.OpenAPI2MarkupConfigBuilder;
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.config.Labels;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.vavr.Function2;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class MarkupComponent<D, T, R> implements Function2<D, T, R> {
|
||||
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
protected OpenAPI2MarkupConverter.Context<OpenAPI> context;
|
||||
protected Labels labels;
|
||||
protected OpenAPI2MarkupConfigBuilder.OpenSchema2MarkupConfig config;
|
||||
protected OpenAPI2MarkupExtensionRegistry extensionRegistry;
|
||||
|
||||
public MarkupComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
this.context = context;
|
||||
this.config = context.getConfig();
|
||||
this.extensionRegistry = context.getExtensionRegistry();
|
||||
this.labels = context.getLabels();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Extension points registry interface.
|
||||
*/
|
||||
public interface OpenAPI2MarkupExtensionRegistry extends Schema2MarkupExtensionRegistry {
|
||||
/**
|
||||
* OpenAPIModelExtension extension point can be used to preprocess the Swagger model.
|
||||
*
|
||||
* @return registered extensions extending OpenAPIModelExtension extension point
|
||||
*/
|
||||
List<OpenAPIModelExtension> getSwaggerModelExtensions();
|
||||
|
||||
/**
|
||||
* OverviewDocumentExtension extension point can be used to extend the overview document content.
|
||||
*
|
||||
* @return registered extensions extending OverviewDocumentExtension extension point
|
||||
*/
|
||||
List<OverviewDocumentExtension> getOverviewDocumentExtensions();
|
||||
|
||||
/**
|
||||
* DefinitionsDocumentExtension extension point can be used to extend the definitions document content.
|
||||
*
|
||||
* @return registered extensions extending DefinitionsDocumentExtension extension point
|
||||
*/
|
||||
List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions();
|
||||
|
||||
/**
|
||||
* SecurityContentExtension extension point can be used to extend the security document content.
|
||||
*
|
||||
* @return registered extensions extending SecurityContentExtension extension point
|
||||
*/
|
||||
List<SecurityDocumentExtension> getSecurityDocumentExtensions();
|
||||
|
||||
/**
|
||||
* PathsDocumentExtension extension point can be used to extend the paths document content.
|
||||
*
|
||||
* @return registered extensions extending PathsDocumentExtension extension point
|
||||
*/
|
||||
List<PathsDocumentExtension> getPathsDocumentExtensions();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
|
||||
/**
|
||||
* OpenAPIModelExtension extension point can be used to preprocess the Swagger model.
|
||||
*/
|
||||
public abstract class OpenAPIModelExtension extends AbstractExtension {
|
||||
|
||||
public abstract void apply(OpenAPI openAPI);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
/**
|
||||
* OverviewDocumentExtension extension point can be used to extend the overview document content.
|
||||
*/
|
||||
public abstract class OverviewDocumentExtension extends AbstractExtension {
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_AFTER,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
*/
|
||||
public Context(Position position, Document document) {
|
||||
super(document);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import io.github.swagger2markup.model.PathOperation;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* PathsDocumentExtension extension point can be used to extend the paths document content.
|
||||
*/
|
||||
public abstract class PathsDocumentExtension extends AbstractExtension {
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
DOCUMENT_AFTER,
|
||||
OPERATION_BEFORE,
|
||||
OPERATION_BEGIN,
|
||||
OPERATION_END,
|
||||
OPERATION_AFTER,
|
||||
OPERATION_DESCRIPTION_BEFORE,
|
||||
OPERATION_DESCRIPTION_BEGIN,
|
||||
OPERATION_DESCRIPTION_END,
|
||||
OPERATION_DESCRIPTION_AFTER,
|
||||
OPERATION_PARAMETERS_BEFORE,
|
||||
OPERATION_PARAMETERS_BEGIN,
|
||||
OPERATION_PARAMETERS_END,
|
||||
OPERATION_PARAMETERS_AFTER,
|
||||
OPERATION_RESPONSES_BEFORE,
|
||||
OPERATION_RESPONSES_BEGIN,
|
||||
OPERATION_RESPONSES_END,
|
||||
OPERATION_RESPONSES_AFTER,
|
||||
OPERATION_SECURITY_BEFORE,
|
||||
OPERATION_SECURITY_BEGIN,
|
||||
OPERATION_SECURITY_END,
|
||||
OPERATION_SECURITY_AFTER
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private PathOperation operation;
|
||||
|
||||
/**
|
||||
* Context for positions DOCUMENT_*
|
||||
*
|
||||
* @param position the current position
|
||||
* @param document document object
|
||||
*/
|
||||
public Context(Position position, Document document) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Context for all other positions
|
||||
*
|
||||
* @param position the current position
|
||||
* @param document document object
|
||||
* @param operation the current path operation
|
||||
*/
|
||||
public Context(Position position, Document document, PathOperation operation) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.OPERATION_BEFORE, Position.OPERATION_SECURITY_AFTER, position);
|
||||
Validate.notNull(operation);
|
||||
this.position = position;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Optional<PathOperation> getOperation() {
|
||||
return Optional.ofNullable(operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension;
|
||||
|
||||
import io.swagger.models.auth.SecuritySchemeDefinition;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* SecurityContentExtension extension point can be used to extend the security document content.
|
||||
*/
|
||||
public abstract class SecurityDocumentExtension extends AbstractExtension {
|
||||
|
||||
|
||||
public abstract void apply(Context context);
|
||||
|
||||
public enum Position {
|
||||
DOCUMENT_BEFORE,
|
||||
DOCUMENT_BEGIN,
|
||||
DOCUMENT_END,
|
||||
DOCUMENT_AFTER,
|
||||
SECURITY_SCHEME_BEFORE,
|
||||
SECURITY_SCHEME_BEGIN,
|
||||
SECURITY_SCHEME_END,
|
||||
SECURITY_SCHEME_AFTER
|
||||
}
|
||||
|
||||
public static class Context extends ContentContext {
|
||||
private Position position;
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private String securitySchemeName;
|
||||
/**
|
||||
* null if position == DOCUMENT_*
|
||||
*/
|
||||
private SecuritySchemeDefinition securityScheme;
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param document the MarkupDocBuilder
|
||||
*/
|
||||
public Context(Position position, Document document) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.DOCUMENT_BEFORE, Position.DOCUMENT_AFTER, position);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the current position
|
||||
* @param document the MarkupDocBuilder
|
||||
* @param securitySchemeName the name of the current securityScheme
|
||||
* @param securityScheme the current security scheme securityScheme
|
||||
*/
|
||||
public Context(Position position, Document document, String securitySchemeName, SecuritySchemeDefinition securityScheme) {
|
||||
super(document);
|
||||
Validate.inclusiveBetween(Position.SECURITY_SCHEME_BEFORE, Position.SECURITY_SCHEME_AFTER, position);
|
||||
Validate.notNull(securitySchemeName);
|
||||
Validate.notNull(securityScheme);
|
||||
this.position = position;
|
||||
this.securitySchemeName = securitySchemeName;
|
||||
this.securityScheme = securityScheme;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Optional<String> getSecuritySchemeName() {
|
||||
return Optional.ofNullable(securitySchemeName);
|
||||
}
|
||||
|
||||
public Optional<SecuritySchemeDefinition> getSecurityScheme() {
|
||||
return Optional.ofNullable(securityScheme);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.extension.builder;
|
||||
|
||||
import io.github.swagger2markup.extension.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.ServiceLoader.load;
|
||||
import static org.apache.commons.collections4.IteratorUtils.toList;
|
||||
|
||||
public class OpenAPI2MarkupExtensionRegistryBuilder {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder() {
|
||||
List<OpenAPIModelExtension> openAPIModelExtensions = toList(load(OpenAPIModelExtension.class).iterator());
|
||||
List<OverviewDocumentExtension> overviewDocumentExtensions = toList(load(OverviewDocumentExtension.class).iterator());
|
||||
List<DefinitionsDocumentExtension> definitionsDocumentExtensions = toList(load(DefinitionsDocumentExtension.class).iterator());
|
||||
List<PathsDocumentExtension> pathsDocumentExtensions = toList(load(PathsDocumentExtension.class).iterator());
|
||||
List<SecurityDocumentExtension> securityDocumentExtensions = toList(load(SecurityDocumentExtension.class).iterator());
|
||||
context = new Context(
|
||||
openAPIModelExtensions,
|
||||
overviewDocumentExtensions,
|
||||
definitionsDocumentExtensions,
|
||||
pathsDocumentExtensions,
|
||||
securityDocumentExtensions);
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistry build() {
|
||||
return new DefaultOpenAPI2MarkupExtensionRegistry(context);
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withSwaggerModelExtension(OpenAPIModelExtension extension) {
|
||||
context.openAPIModelExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withOverviewDocumentExtension(OverviewDocumentExtension extension) {
|
||||
context.overviewDocumentExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withDefinitionsDocumentExtension(DefinitionsDocumentExtension extension) {
|
||||
context.definitionsDocumentExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withPathsDocumentExtension(PathsDocumentExtension extension) {
|
||||
context.pathsDocumentExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OpenAPI2MarkupExtensionRegistryBuilder withSecurityDocumentExtension(SecurityDocumentExtension extension) {
|
||||
context.securityDocumentExtensions.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
static class DefaultOpenAPI2MarkupExtensionRegistry implements OpenAPI2MarkupExtensionRegistry {
|
||||
|
||||
private Context context;
|
||||
|
||||
DefaultOpenAPI2MarkupExtensionRegistry(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OpenAPIModelExtension> getSwaggerModelExtensions() {
|
||||
return context.openAPIModelExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OverviewDocumentExtension> getOverviewDocumentExtensions() {
|
||||
return context.overviewDocumentExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions() {
|
||||
return context.definitionsDocumentExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SecurityDocumentExtension> getSecurityDocumentExtensions() {
|
||||
return context.securityDocumentExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PathsDocumentExtension> getPathsDocumentExtensions() {
|
||||
return context.pathsDocumentExtensions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Context {
|
||||
final List<OpenAPIModelExtension> openAPIModelExtensions;
|
||||
final List<OverviewDocumentExtension> overviewDocumentExtensions;
|
||||
final List<DefinitionsDocumentExtension> definitionsDocumentExtensions;
|
||||
final List<PathsDocumentExtension> pathsDocumentExtensions;
|
||||
final List<SecurityDocumentExtension> securityDocumentExtensions;
|
||||
|
||||
Context(List<OpenAPIModelExtension> openAPIModelExtensions,
|
||||
List<OverviewDocumentExtension> overviewDocumentExtensions,
|
||||
List<DefinitionsDocumentExtension> definitionsDocumentExtensions,
|
||||
List<PathsDocumentExtension> pathsDocumentExtensions,
|
||||
List<SecurityDocumentExtension> securityDocumentExtensions) {
|
||||
this.openAPIModelExtensions = openAPIModelExtensions;
|
||||
this.overviewDocumentExtensions = overviewDocumentExtensions;
|
||||
this.definitionsDocumentExtensions = definitionsDocumentExtensions;
|
||||
this.pathsDocumentExtensions = pathsDocumentExtensions;
|
||||
this.securityDocumentExtensions = securityDocumentExtensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.media.Encoding;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLES;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.italicUnconstrained;
|
||||
|
||||
public class EncodingComponent extends MarkupComponent<StructuralNode, EncodingComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final HeadersComponent headersComponent;
|
||||
|
||||
public EncodingComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.headersComponent = new HeadersComponent(context);
|
||||
}
|
||||
|
||||
public static EncodingComponent.Parameters parameters(Map<String, Encoding> encodings) {
|
||||
return new EncodingComponent.Parameters(encodings);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Map<String, Encoding> encodings) {
|
||||
return apply(node, parameters(encodings));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, EncodingComponent.Parameters parameters) {
|
||||
Map<String, Encoding> encodings = parameters.encodings;
|
||||
if (encodings == null || encodings.isEmpty()) return node;
|
||||
|
||||
DescriptionListImpl encodingList = new DescriptionListImpl(node);
|
||||
encodingList.setTitle(labels.getLabel(LABEL_EXAMPLES));
|
||||
|
||||
encodings.forEach((name, encoding) -> {
|
||||
DescriptionListEntryImpl encodingEntry = new DescriptionListEntryImpl(encodingList, Collections.singletonList(new ListItemImpl(encodingList, name)));
|
||||
ListItemImpl tagDesc = new ListItemImpl(encodingEntry, "");
|
||||
ParagraphBlockImpl encodingBlock = new ParagraphBlockImpl(tagDesc);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String contentType = encoding.getContentType();
|
||||
if(StringUtils.isNotBlank(contentType)){
|
||||
sb.append("Content-Type:").append(contentType).append(LINE_SEPARATOR);
|
||||
}
|
||||
if(encoding.getAllowReserved()){
|
||||
sb.append(italicUnconstrained("Allow Reserved").toLowerCase()).append(LINE_SEPARATOR);
|
||||
}
|
||||
if(encoding.getExplode()){
|
||||
sb.append(italicUnconstrained("Explode").toLowerCase()).append(LINE_SEPARATOR);
|
||||
}
|
||||
Encoding.StyleEnum style = encoding.getStyle();
|
||||
if(style != null){
|
||||
sb.append("style").append(style).append(LINE_SEPARATOR);
|
||||
}
|
||||
encodingBlock.setSource(sb.toString());
|
||||
tagDesc.append(encodingBlock);
|
||||
headersComponent.apply(tagDesc, encoding.getHeaders());
|
||||
|
||||
encodingEntry.setDescription(tagDesc);
|
||||
|
||||
encodingList.addEntry(encodingEntry);
|
||||
});
|
||||
node.append(encodingList);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Map<String, Encoding> encodings;
|
||||
|
||||
public Parameters(Map<String, Encoding> encodings) {
|
||||
this.encodings = encodings;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.examples.Example;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLES;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXTERNAL_VALUE;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.appendDescription;
|
||||
|
||||
public class ExamplesComponent extends MarkupComponent<StructuralNode, ExamplesComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final MediaTypeExampleComponent mediaTypeExampleComponent;
|
||||
|
||||
public ExamplesComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.mediaTypeExampleComponent = new MediaTypeExampleComponent(context);
|
||||
}
|
||||
|
||||
public static ExamplesComponent.Parameters parameters(Map<String, Example> examples) {
|
||||
return new ExamplesComponent.Parameters(examples);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Map<String, Example> examples) {
|
||||
return apply(node, parameters(examples));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, ExamplesComponent.Parameters parameters) {
|
||||
Map<String, Example> examples = parameters.examples;
|
||||
if (examples == null || examples.isEmpty()) return node;
|
||||
|
||||
DescriptionListImpl examplesList = new DescriptionListImpl(node);
|
||||
examplesList.setTitle(labels.getLabel(LABEL_EXAMPLES));
|
||||
|
||||
examples.forEach((name, example) -> {
|
||||
DescriptionListEntryImpl exampleEntry = new DescriptionListEntryImpl(examplesList, Collections.singletonList(new ListItemImpl(examplesList, name)));
|
||||
ListItemImpl tagDesc = new ListItemImpl(exampleEntry, "");
|
||||
|
||||
ParagraphBlockImpl exampleBlock = new ParagraphBlockImpl(tagDesc);
|
||||
|
||||
appendDescription(exampleBlock, example.getSummary());
|
||||
appendDescription(exampleBlock, example.getDescription());
|
||||
mediaTypeExampleComponent.apply(tagDesc, example.getValue());
|
||||
|
||||
ParagraphBlockImpl paragraphBlock = new ParagraphBlockImpl(tagDesc);
|
||||
String source = "";
|
||||
generateRefLink(source, example.getExternalValue(), labels.getLabel(LABEL_EXTERNAL_VALUE));
|
||||
generateRefLink(source, example.get$ref(), "");
|
||||
if(StringUtils.isNotBlank(source)){
|
||||
paragraphBlock.setSource(source);
|
||||
tagDesc.append(paragraphBlock);
|
||||
}
|
||||
|
||||
exampleEntry.setDescription(tagDesc);
|
||||
|
||||
examplesList.addEntry(exampleEntry);
|
||||
});
|
||||
node.append(examplesList);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private String generateRefLink(String source, String ref, String alt) {
|
||||
if (StringUtils.isNotBlank(ref)) {
|
||||
if (StringUtils.isBlank(alt)) {
|
||||
alt = ref.substring(ref.lastIndexOf('/') + 1);
|
||||
}
|
||||
String anchor = ref.replaceFirst("#", "").replaceAll("/", "_");
|
||||
source += "<<" + anchor + "," + alt + ">>" + LINE_SEPARATOR;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Map<String, Example> examples;
|
||||
|
||||
public Parameters(Map<String, Example> examples) {
|
||||
this.examples = examples;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.swagger.v3.oas.models.ExternalDocumentation;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Block;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
|
||||
public class ExternalDocumentationComponent extends MarkupComponent<StructuralNode, ExternalDocumentationComponent.Parameters, StructuralNode> {
|
||||
|
||||
public ExternalDocumentationComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(ExternalDocumentation externalDocs) {
|
||||
return new Parameters(externalDocs);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, ExternalDocumentation externalDocs) {
|
||||
return apply(node, parameters(externalDocs));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, Parameters params) {
|
||||
ExternalDocumentation externalDocs = params.externalDocs;
|
||||
if (externalDocs == null) return node;
|
||||
|
||||
String url = externalDocs.getUrl();
|
||||
if (StringUtils.isNotBlank(url)) {
|
||||
Block paragraph = new ParagraphBlockImpl(node);
|
||||
String desc = externalDocs.getDescription();
|
||||
paragraph.setSource(url + (StringUtils.isNotBlank(desc) ? "[" + desc + "]" : ""));
|
||||
node.append(paragraph);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final ExternalDocumentation externalDocs;
|
||||
|
||||
public Parameters(ExternalDocumentation externalDocs) {
|
||||
this.externalDocs = externalDocs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.headers.Header;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.generateInnerDoc;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.getSchemaTypeAsString;
|
||||
|
||||
public class HeadersComponent extends MarkupComponent<StructuralNode, HeadersComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final SchemaComponent schemaComponent;
|
||||
|
||||
public HeadersComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
}
|
||||
|
||||
public static HeadersComponent.Parameters parameters(Map<String, Header> headers) {
|
||||
return new HeadersComponent.Parameters(headers);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Map<String, Header> headers) {
|
||||
return apply(node, parameters(headers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, HeadersComponent.Parameters parameters) {
|
||||
Map<String, Header> headers = parameters.headers;
|
||||
if (null == headers || headers.isEmpty()) return node;
|
||||
|
||||
TableImpl responseHeadersTable = new TableImpl(node, new HashMap<>(), new ArrayList<>());
|
||||
responseHeadersTable.setOption("header");
|
||||
responseHeadersTable.setAttribute("caption", "", true);
|
||||
responseHeadersTable.setAttribute("cols", ".^2a,.^14a,.^4a", true);
|
||||
responseHeadersTable.setTitle(labels.getLabel(TABLE_TITLE_HEADERS));
|
||||
responseHeadersTable.setHeaderRow(labels.getLabel(TABLE_HEADER_NAME), labels.getLabel(TABLE_HEADER_DESCRIPTION), labels.getLabel(TABLE_HEADER_SCHEMA));
|
||||
headers.forEach((name, header) ->
|
||||
responseHeadersTable.addRow(
|
||||
generateInnerDoc(responseHeadersTable, name),
|
||||
generateInnerDoc(responseHeadersTable, Optional.ofNullable(header.getDescription()).orElse("")),
|
||||
generateInnerDoc(responseHeadersTable, getSchemaTypeAsString(header.getSchema()))
|
||||
));
|
||||
node.append(responseHeadersTable);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Map<String, Header> headers;
|
||||
|
||||
public Parameters(Map<String, Header> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.links.Link;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.italicUnconstrained;
|
||||
|
||||
public class LinkComponent extends MarkupComponent<StructuralNode, LinkComponent.Parameters, StructuralNode> {
|
||||
|
||||
public LinkComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static LinkComponent.Parameters parameters(Map<String, Link> links) {
|
||||
return new LinkComponent.Parameters(links);
|
||||
}
|
||||
|
||||
public Document apply(StructuralNode parent, Map<String, Link> links) {
|
||||
return apply(parent, parameters(links));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(StructuralNode parent, LinkComponent.Parameters parameters) {
|
||||
DocumentImpl linksDocument = new DocumentImpl(parent);
|
||||
ParagraphBlockImpl linkParagraph = new ParagraphBlockImpl(linksDocument);
|
||||
|
||||
Map<String, Link> links = parameters.links;
|
||||
if (null == links || links.isEmpty()) {
|
||||
linkParagraph.setSource(labels.getLabel(LABEL_NO_LINKS));
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
links.forEach((name, link) -> {
|
||||
sb.append(name).append(" +").append(LINE_SEPARATOR);
|
||||
sb.append(italicUnconstrained(labels.getLabel(LABEL_OPERATION))).append(' ')
|
||||
.append(italicUnconstrained(link.getOperationId())).append(" +").append(LINE_SEPARATOR);
|
||||
Map<String, String> linkParameters = link.getParameters();
|
||||
if (null != linkParameters && !linkParameters.isEmpty()) {
|
||||
sb.append(italicUnconstrained(labels.getLabel(LABEL_PARAMETERS))).append(" {").append(" +").append(LINE_SEPARATOR);
|
||||
linkParameters.forEach((param, value) ->
|
||||
sb.append('"').append(param).append("\": \"").append(value).append('"').append(" +").append(LINE_SEPARATOR)
|
||||
);
|
||||
sb.append('}').append(" +").append(LINE_SEPARATOR);
|
||||
}
|
||||
});
|
||||
linkParagraph.setSource(sb.toString());
|
||||
}
|
||||
linksDocument.append(linkParagraph);
|
||||
return linksDocument;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final Map<String, Link> links;
|
||||
|
||||
public Parameters(Map<String, Link> links) {
|
||||
this.links = links;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.media.Content;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_CONTENT;
|
||||
|
||||
public class MediaContentComponent extends MarkupComponent<StructuralNode, MediaContentComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final MediaTypeExampleComponent mediaTypeExampleComponent;
|
||||
private final ExamplesComponent examplesComponent;
|
||||
private final SchemaComponent schemaComponent;
|
||||
private final EncodingComponent encodingComponent;
|
||||
|
||||
public MediaContentComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.mediaTypeExampleComponent = new MediaTypeExampleComponent(context);
|
||||
this.examplesComponent = new ExamplesComponent(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
this.encodingComponent = new EncodingComponent(context);
|
||||
}
|
||||
|
||||
public static MediaContentComponent.Parameters parameters(Content content) {
|
||||
return new MediaContentComponent.Parameters(content);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Content content) {
|
||||
return apply(node, parameters(content));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, MediaContentComponent.Parameters parameters) {
|
||||
Content content = parameters.content;
|
||||
if (content == null || content.isEmpty()) return node;
|
||||
|
||||
DescriptionListImpl mediaContentList = new DescriptionListImpl(node);
|
||||
mediaContentList.setTitle(labels.getLabel(LABEL_CONTENT));
|
||||
|
||||
content.forEach((type, mediaType) -> {
|
||||
DescriptionListEntryImpl tagEntry = new DescriptionListEntryImpl(mediaContentList, Collections.singletonList(new ListItemImpl(mediaContentList, type)));
|
||||
ListItemImpl tagDesc = new ListItemImpl(tagEntry, "");
|
||||
|
||||
Document tagDescDocument = schemaComponent.apply(mediaContentList, mediaType.getSchema());
|
||||
mediaTypeExampleComponent.apply(tagDescDocument, mediaType.getExample());
|
||||
examplesComponent.apply(tagDescDocument, mediaType.getExamples());
|
||||
encodingComponent.apply(tagDescDocument, mediaType.getEncoding());
|
||||
tagDesc.append(tagDescDocument);
|
||||
|
||||
tagEntry.setDescription(tagDesc);
|
||||
mediaContentList.addEntry(tagEntry);
|
||||
});
|
||||
node.append(mediaContentList);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Content content;
|
||||
|
||||
public Parameters(Content content) {
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.DELIMITER_BLOCK;
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_EXAMPLE;
|
||||
|
||||
public class MediaTypeExampleComponent extends MarkupComponent<StructuralNode, MediaTypeExampleComponent.Parameters, StructuralNode> {
|
||||
|
||||
public MediaTypeExampleComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static MediaTypeExampleComponent.Parameters parameters(Object example) {
|
||||
return new MediaTypeExampleComponent.Parameters(example);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode node, Object example) {
|
||||
return apply(node, parameters(example));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, MediaTypeExampleComponent.Parameters parameters) {
|
||||
Object example = parameters.example;
|
||||
if (example == null || StringUtils.isBlank(example.toString())) return node;
|
||||
|
||||
ParagraphBlockImpl sourceBlock = new ParagraphBlockImpl(node);
|
||||
sourceBlock.setTitle(labels.getLabel(LABEL_EXAMPLE));
|
||||
sourceBlock.setAttribute("style", "source", true);
|
||||
sourceBlock.setSource(DELIMITER_BLOCK + LINE_SEPARATOR + example + LINE_SEPARATOR + DELIMITER_BLOCK);
|
||||
node.append(sourceBlock);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Object example;
|
||||
|
||||
public Parameters(Object example) {
|
||||
this.example = example;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
|
||||
|
||||
public class ParametersComponent extends MarkupComponent<StructuralNode, ParametersComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final SchemaComponent schemaComponent;
|
||||
|
||||
public ParametersComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
}
|
||||
|
||||
public static ParametersComponent.Parameters parameters(Map<String, Parameter> parameters) {
|
||||
return new ParametersComponent.Parameters(parameters);
|
||||
}
|
||||
|
||||
public static ParametersComponent.Parameters parameters(List<Parameter> parameters) {
|
||||
if(null == parameters) {
|
||||
return new ParametersComponent.Parameters(new HashMap<>());
|
||||
}
|
||||
return new ParametersComponent.Parameters(parameters.stream().collect(Collectors.toMap(Parameter::getName, parameter -> parameter)));
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode parent, List<Parameter> params) {
|
||||
return apply(parent, parameters(params));
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode parent, Map<String, Parameter> params) {
|
||||
return apply(parent, parameters(params));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode parent, ParametersComponent.Parameters componentParameters) {
|
||||
Map<String, Parameter> parameters = componentParameters.parameters;
|
||||
if (null == parameters || parameters.isEmpty()) return parent;
|
||||
|
||||
TableImpl pathParametersTable = new TableImpl(parent, new HashMap<>(), new ArrayList<>());
|
||||
pathParametersTable.setOption("header");
|
||||
pathParametersTable.setAttribute("caption", "", true);
|
||||
pathParametersTable.setAttribute("cols", ".^2a,.^3a,.^10a,.^5a", true);
|
||||
pathParametersTable.setTitle(labels.getLabel(TABLE_TITLE_PARAMETERS));
|
||||
pathParametersTable.setHeaderRow(
|
||||
labels.getLabel(TABLE_HEADER_TYPE),
|
||||
labels.getLabel(TABLE_HEADER_NAME),
|
||||
labels.getLabel(TABLE_HEADER_DESCRIPTION),
|
||||
labels.getLabel(TABLE_HEADER_SCHEMA));
|
||||
|
||||
parameters.forEach((alt, parameter) ->
|
||||
pathParametersTable.addRow(
|
||||
generateInnerDoc(pathParametersTable, boldUnconstrained(parameter.getIn()), alt),
|
||||
getParameterNameDocument(pathParametersTable, parameter),
|
||||
generateInnerDoc(pathParametersTable, Optional.ofNullable(parameter.getDescription()).orElse("")),
|
||||
generateInnerDoc(pathParametersTable, getSchemaTypeAsString(parameter.getSchema()))
|
||||
));
|
||||
parent.append(pathParametersTable);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
private Document getParameterNameDocument(Table table, Parameter parameter) {
|
||||
String documentContent = boldUnconstrained(parameter.getName()) + " +" + LINE_SEPARATOR + requiredIndicator(parameter.getRequired(),
|
||||
labels.getLabel(LABEL_REQUIRED), labels.getLabel(LABEL_OPTIONAL));
|
||||
return generateInnerDoc(table, documentContent);
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final Map<String, Parameter> parameters;
|
||||
|
||||
public Parameters(Map<String, Parameter> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
|
||||
|
||||
public class PropertiesTableComponent extends MarkupComponent<StructuralNode, PropertiesTableComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final SchemaComponent schemaComponent;
|
||||
|
||||
PropertiesTableComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(@SuppressWarnings("rawtypes") Map<String, Schema> properties, List<String> schemaRequired) {
|
||||
return new Parameters(properties, schemaRequired);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode parent, @SuppressWarnings("rawtypes") Map<String, Schema> properties, List<String> schemaRequired) {
|
||||
return apply(parent, parameters(properties, schemaRequired));
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode parent, Parameters params) {
|
||||
@SuppressWarnings("rawtypes") Map<String, Schema> properties = params.properties;
|
||||
List<String> schemaRequired = params.schemaRequired;
|
||||
|
||||
if (null == properties || properties.isEmpty()) return parent;
|
||||
|
||||
List<String> finalSchemaRequired = (null == schemaRequired) ? new ArrayList<>() : schemaRequired;
|
||||
|
||||
TableImpl propertiesTable = new TableImpl(parent, new HashMap<>(), new ArrayList<>());
|
||||
propertiesTable.setOption("header");
|
||||
propertiesTable.setAttribute("caption", "", true);
|
||||
propertiesTable.setAttribute("cols", ".^4a,.^16a,.^4a", true);
|
||||
propertiesTable.setTitle(labels.getLabel(TABLE_TITLE_PROPERTIES));
|
||||
propertiesTable.setHeaderRow(
|
||||
labels.getLabel(TABLE_HEADER_NAME),
|
||||
labels.getLabel(TABLE_HEADER_DESCRIPTION),
|
||||
labels.getLabel(TABLE_HEADER_SCHEMA));
|
||||
|
||||
properties.forEach((name, schema) -> propertiesTable.addRow(
|
||||
generateInnerDoc(propertiesTable, name + LINE_SEPARATOR + requiredIndicator(finalSchemaRequired.contains(name),
|
||||
labels.getLabel(LABEL_REQUIRED), labels.getLabel(LABEL_OPTIONAL))),
|
||||
schemaComponent.apply(propertiesTable, schema),
|
||||
generateInnerDoc(propertiesTable, getSchemaTypeAsString(schema))
|
||||
));
|
||||
parent.append(propertiesTable);
|
||||
return parent;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static class Parameters {
|
||||
private final Map<String, Schema> properties;
|
||||
private final List<String> schemaRequired;
|
||||
|
||||
public Parameters(Map<String, Schema> properties, List<String> schemaRequired) {
|
||||
|
||||
this.properties = properties;
|
||||
this.schemaRequired = schemaRequired;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.generateInnerDoc;
|
||||
|
||||
public class ResponseComponent extends MarkupComponent<StructuralNode, ResponseComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final HeadersComponent headersComponent;
|
||||
private final LinkComponent linkComponent;
|
||||
private final MediaContentComponent mediaContentComponent;
|
||||
|
||||
public ResponseComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.headersComponent = new HeadersComponent(context);
|
||||
this.linkComponent = new LinkComponent(context);
|
||||
this.mediaContentComponent = new MediaContentComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(Map<String, ApiResponse> apiResponses) {
|
||||
return new Parameters(apiResponses);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode serverSection, Map<String, ApiResponse> apiResponses) {
|
||||
return apply(serverSection, parameters(apiResponses));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode serverSection, Parameters params) {
|
||||
Map<String, ApiResponse> apiResponses = params.apiResponses;
|
||||
|
||||
if (null == apiResponses || apiResponses.isEmpty()) return serverSection;
|
||||
|
||||
TableImpl pathResponsesTable = new TableImpl(serverSection, new HashMap<>(), new ArrayList<>());
|
||||
pathResponsesTable.setOption("header");
|
||||
pathResponsesTable.setAttribute("caption", "", true);
|
||||
pathResponsesTable.setAttribute("cols", ".^2a,.^14a,.^4a", true);
|
||||
pathResponsesTable.setTitle(labels.getLabel(TABLE_TITLE_RESPONSES));
|
||||
pathResponsesTable.setHeaderRow(
|
||||
labels.getLabel(TABLE_HEADER_HTTP_CODE),
|
||||
labels.getLabel(TABLE_HEADER_DESCRIPTION),
|
||||
labels.getLabel(TABLE_HEADER_LINKS));
|
||||
|
||||
apiResponses.forEach((httpCode, apiResponse) ->
|
||||
pathResponsesTable.addRow(
|
||||
generateInnerDoc(pathResponsesTable, httpCode),
|
||||
getResponseDescriptionColumnDocument(pathResponsesTable, apiResponse),
|
||||
linkComponent.apply(pathResponsesTable, apiResponse.getLinks())
|
||||
));
|
||||
serverSection.append(pathResponsesTable);
|
||||
return serverSection;
|
||||
}
|
||||
|
||||
private Document getResponseDescriptionColumnDocument(Table table, ApiResponse apiResponse) {
|
||||
Document document = generateInnerDoc(table, Optional.ofNullable(apiResponse.getDescription()).orElse(""));
|
||||
headersComponent.apply(document, apiResponse.getHeaders());
|
||||
mediaContentComponent.apply(document, apiResponse.getContent());
|
||||
return document;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final Map<String, ApiResponse> apiResponses;
|
||||
|
||||
public Parameters(Map<String, ApiResponse> apiResponses) {
|
||||
|
||||
this.apiResponses = apiResponses;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.internal.helper.OpenApiHelpers;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.boldUnconstrained;
|
||||
|
||||
public class SchemaComponent extends MarkupComponent<StructuralNode, SchemaComponent.Parameters, StructuralNode> {
|
||||
|
||||
private final OpenAPI2MarkupConverter.OpenAPIContext context;
|
||||
|
||||
public SchemaComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static SchemaComponent.Parameters parameters(@SuppressWarnings("rawtypes") Schema schema) {
|
||||
return new SchemaComponent.Parameters(schema);
|
||||
}
|
||||
|
||||
public Document apply(StructuralNode parent, @SuppressWarnings("rawtypes") Schema schema) {
|
||||
return apply(parent, parameters(schema));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
public Document apply(StructuralNode parent, SchemaComponent.Parameters parameters) {
|
||||
Document schemaDocument = new DocumentImpl(parent);
|
||||
Schema schema = parameters.schema;
|
||||
if (null == schema) return schemaDocument;
|
||||
|
||||
OpenApiHelpers.appendDescription(schemaDocument, schema.getDescription());
|
||||
|
||||
Map<String, Boolean> schemasBooleanProperties = new HashMap<String, Boolean>() {{
|
||||
put(labels.getLabel(LABEL_DEPRECATED), schema.getDeprecated());
|
||||
put(labels.getLabel(LABEL_NULLABLE), schema.getNullable());
|
||||
put(labels.getLabel(LABEL_READ_ONLY), schema.getReadOnly());
|
||||
put(labels.getLabel(LABEL_WRITE_ONLY), schema.getWriteOnly());
|
||||
put(labels.getLabel(LABEL_UNIQUE_ITEMS), schema.getUniqueItems());
|
||||
put(labels.getLabel(LABEL_EXCLUSIVE_MAXIMUM), schema.getExclusiveMaximum());
|
||||
put(labels.getLabel(LABEL_EXCLUSIVE_MINIMUM), schema.getExclusiveMinimum());
|
||||
}};
|
||||
|
||||
Map<String, Object> schemasValueProperties = new HashMap<String, Object>() {{
|
||||
put(labels.getLabel(LABEL_TITLE), schema.getTitle());
|
||||
put(labels.getLabel(LABEL_DEFAULT), schema.getDefault());
|
||||
put(labels.getLabel(LABEL_MAXIMUM), schema.getMaximum());
|
||||
put(labels.getLabel(LABEL_MINIMUM), schema.getMinimum());
|
||||
put(labels.getLabel(LABEL_MAX_LENGTH), schema.getMaxLength());
|
||||
put(labels.getLabel(LABEL_MIN_LENGTH), schema.getMinLength());
|
||||
put(labels.getLabel(LABEL_MAX_ITEMS), schema.getMaxItems());
|
||||
put(labels.getLabel(LABEL_MIN_ITEMS), schema.getMinItems());
|
||||
put(labels.getLabel(LABEL_MAX_PROPERTIES), schema.getMaxProperties());
|
||||
put(labels.getLabel(LABEL_MIN_PROPERTIES), schema.getMinProperties());
|
||||
put(labels.getLabel(LABEL_MULTIPLE_OF), schema.getMultipleOf());
|
||||
}};
|
||||
|
||||
Stream<String> schemaBooleanStream = schemasBooleanProperties.entrySet().stream()
|
||||
.filter(e -> null != e.getValue() && e.getValue())
|
||||
.map(e -> OpenApiHelpers.italicUnconstrained(e.getKey().toLowerCase()));
|
||||
Stream<String> schemaValueStream = schemasValueProperties.entrySet().stream()
|
||||
.filter(e -> null != e.getValue() && StringUtils.isNotBlank(e.getValue().toString()))
|
||||
.map(e -> boldUnconstrained(e.getKey()) + ": " + e.getValue());
|
||||
|
||||
ParagraphBlockImpl paragraphBlock = new ParagraphBlockImpl(schemaDocument);
|
||||
String source = Stream.concat(schemaBooleanStream, schemaValueStream).collect(Collectors.joining(" +" + LINE_SEPARATOR));
|
||||
paragraphBlock.setSource(source);
|
||||
|
||||
schemaDocument.append(paragraphBlock);
|
||||
|
||||
Map<String, Schema> properties = schema.getProperties();
|
||||
if (null != properties && !properties.isEmpty()) {
|
||||
PropertiesTableComponent propertiesTableComponent = new PropertiesTableComponent(context);
|
||||
propertiesTableComponent.apply(schemaDocument, properties, schema.getRequired());
|
||||
}
|
||||
|
||||
return schemaDocument;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static class Parameters {
|
||||
|
||||
private final Schema schema;
|
||||
|
||||
public Parameters(Schema schema) {
|
||||
this.schema = schema;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
|
||||
|
||||
public class SecurityRequirementTableComponent extends MarkupComponent<StructuralNode, SecurityRequirementTableComponent.Parameters, StructuralNode> {
|
||||
|
||||
public SecurityRequirementTableComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public static SecurityRequirementTableComponent.Parameters parameters(List<SecurityRequirement> securityRequirements, boolean addTitle) {
|
||||
return new SecurityRequirementTableComponent.Parameters(securityRequirements, addTitle);
|
||||
}
|
||||
|
||||
public StructuralNode apply(StructuralNode document, List<SecurityRequirement> securityRequirements, boolean addTitle) {
|
||||
return apply(document, parameters(securityRequirements, addTitle));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructuralNode apply(StructuralNode node, SecurityRequirementTableComponent.Parameters parameters) {
|
||||
List<SecurityRequirement> securityRequirements = parameters.securityRequirements;
|
||||
|
||||
if (securityRequirements == null || securityRequirements.isEmpty()) return node;
|
||||
|
||||
TableImpl securityRequirementsTable = new TableImpl(node, new HashMap<>(), new ArrayList<>());
|
||||
securityRequirementsTable.setOption("header");
|
||||
securityRequirementsTable.setAttribute("caption", "", true);
|
||||
securityRequirementsTable.setAttribute("cols", ".^3a,.^4a,.^13a", true);
|
||||
if (parameters.addTitle) {
|
||||
securityRequirementsTable.setTitle(labels.getLabel(TABLE_TITLE_SECURITY));
|
||||
}
|
||||
securityRequirementsTable.setHeaderRow(
|
||||
labels.getLabel(TABLE_HEADER_TYPE),
|
||||
labels.getLabel(TABLE_HEADER_NAME),
|
||||
labels.getLabel(TABLE_HEADER_SCOPES));
|
||||
|
||||
securityRequirements.forEach(securityRequirement ->
|
||||
securityRequirement.forEach((name, scopes) ->
|
||||
securityRequirementsTable.addRow(
|
||||
generateInnerDoc(securityRequirementsTable, boldUnconstrained(scopes.isEmpty() ? "apiKey" : "oauth2")),
|
||||
generateInnerDoc(securityRequirementsTable, name),
|
||||
generateInnerDoc(securityRequirementsTable, String.join(", ", scopes))
|
||||
)
|
||||
)
|
||||
);
|
||||
node.append(securityRequirementsTable);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final List<SecurityRequirement> securityRequirements;
|
||||
private final boolean addTitle;
|
||||
|
||||
public Parameters(List<SecurityRequirement> securityRequirements, boolean addTitle) {
|
||||
this.securityRequirements = securityRequirements;
|
||||
this.addTitle = addTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup.internal.component;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListEntryImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DescriptionListImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ListItemImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.swagger.v3.oas.models.tags.Tag;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_TAGS;
|
||||
|
||||
|
||||
public class TagsComponent extends MarkupComponent<Document, TagsComponent.Parameters, Document> {
|
||||
|
||||
private final ExternalDocumentationComponent externalDocumentationComponent;
|
||||
|
||||
public TagsComponent(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
|
||||
}
|
||||
|
||||
public static TagsComponent.Parameters parameters(List<Tag> tags) {
|
||||
return new TagsComponent.Parameters(tags);
|
||||
}
|
||||
|
||||
public Document apply(Document document, List<Tag> tags) {
|
||||
return apply(document, parameters(tags));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, TagsComponent.Parameters parameters) {
|
||||
List<Tag> openAPITags = parameters.tags;
|
||||
if (null == openAPITags || openAPITags.isEmpty()) return document;
|
||||
|
||||
Section tagsSection = new SectionImpl(document);
|
||||
tagsSection.setTitle(labels.getLabel(SECTION_TITLE_TAGS));
|
||||
|
||||
DescriptionListImpl tagsList = new DescriptionListImpl(tagsSection);
|
||||
openAPITags.forEach(tag -> {
|
||||
DescriptionListEntryImpl tagEntry = new DescriptionListEntryImpl(tagsList, Collections.singletonList(new ListItemImpl(tagsList, tag.getName())));
|
||||
String description = tag.getDescription();
|
||||
if(StringUtils.isNotBlank(description)){
|
||||
ListItemImpl tagDesc = new ListItemImpl(tagEntry, "");
|
||||
tagDesc.setSource(description);
|
||||
externalDocumentationComponent.apply(tagDesc, tag.getExternalDocs());
|
||||
tagEntry.setDescription(tagDesc);
|
||||
}
|
||||
tagsList.addEntry(tagEntry);
|
||||
});
|
||||
|
||||
tagsSection.append(tagsList);
|
||||
document.append(tagsSection);
|
||||
return document;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
|
||||
private final List<Tag> tags;
|
||||
|
||||
public Parameters(List<Tag> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package io.github.swagger2markup.internal.document;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.internal.component.*;
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.headers.Header;
|
||||
import io.swagger.v3.oas.models.links.Link;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
|
||||
public class ComponentsDocument extends MarkupComponent<Document, ComponentsDocument.Parameters, Document> {
|
||||
|
||||
private final ParametersComponent parametersComponent;
|
||||
private final ResponseComponent responseComponent;
|
||||
private final HeadersComponent headersComponent;
|
||||
private final SchemaComponent schemaComponent;
|
||||
private final LinkComponent linkComponent;
|
||||
|
||||
public ComponentsDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.parametersComponent = new ParametersComponent(context);
|
||||
this.responseComponent = new ResponseComponent(context);
|
||||
this.headersComponent = new HeadersComponent(context);
|
||||
this.schemaComponent = new SchemaComponent(context);
|
||||
this.linkComponent = new LinkComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(Components components) {
|
||||
return new Parameters(components);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, ComponentsDocument.Parameters parameters) {
|
||||
|
||||
appendComponentsSection(document, parameters.components);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final Components components;
|
||||
|
||||
public Parameters(Components components) {
|
||||
this.components = Validate.notNull(components, "Schema must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
private void appendComponentsSection(Document document, Components components) {
|
||||
if (null == components) return;
|
||||
|
||||
Section componentsSection = new SectionImpl(document);
|
||||
componentsSection.setTitle(labels.getLabel(SECTION_TITLE_COMPONENTS));
|
||||
String componentSectionId = "_components";
|
||||
componentsSection.setId(componentSectionId);
|
||||
|
||||
appendComponentsSchemasSection(componentsSection, componentSectionId, components.getSchemas());
|
||||
Map<String, Parameter> parameters = components.getParameters();
|
||||
if (null != parameters && !parameters.isEmpty()) {
|
||||
appendSubSection(componentsSection, componentSectionId, parametersComponent, SECTION_TITLE_PARAMETERS,
|
||||
new ParametersComponent.Parameters(parameters));
|
||||
}
|
||||
Map<String, ApiResponse> responses = components.getResponses();
|
||||
if (null != responses && !responses.isEmpty()) {
|
||||
appendSubSection(componentsSection, componentSectionId, responseComponent, SECTION_TITLE_RESPONSES,
|
||||
new ResponseComponent.Parameters(responses));
|
||||
}
|
||||
Map<String, Header> headers = components.getHeaders();
|
||||
if (null != headers && !headers.isEmpty()) {
|
||||
appendSubSection(componentsSection, componentSectionId, headersComponent, SECTION_TITLE_HEADERS,
|
||||
new HeadersComponent.Parameters(headers));
|
||||
}
|
||||
Map<String, Link> links = components.getLinks();
|
||||
if (null != links && !links.isEmpty()) {
|
||||
appendSubSection(componentsSection, componentSectionId, linkComponent, SECTION_TITLE_LINKS,
|
||||
new LinkComponent.Parameters(links));
|
||||
}
|
||||
document.append(componentsSection);
|
||||
}
|
||||
|
||||
private void appendComponentsSchemasSection(
|
||||
Section componentsSection, String componentSectionId,
|
||||
@SuppressWarnings("rawtypes") Map<String, Schema> schemas) {
|
||||
if (null == schemas || schemas.isEmpty()) return;
|
||||
|
||||
SectionImpl schemasSection = new SectionImpl(componentsSection);
|
||||
String schemasSectionId = componentSectionId + "_schemas";
|
||||
schemasSection.setTitle(labels.getLabel(SECTION_TITLE_SCHEMAS));
|
||||
schemasSection.setId(schemasSectionId);
|
||||
schemas.forEach((name, schema) -> {
|
||||
String schemaDocumentId = schemasSectionId + "_" + name;
|
||||
Document schemaDocument = schemaComponent.apply(schemasSection, schema);
|
||||
schemaDocument.setTitle(name);
|
||||
schemaDocument.setId(schemaDocumentId);
|
||||
schemasSection.append(schemaDocument);
|
||||
});
|
||||
componentsSection.append(schemasSection);
|
||||
}
|
||||
|
||||
private <T> void appendSubSection(Section componentsSection, String componentSectionId,
|
||||
MarkupComponent<StructuralNode, T, StructuralNode> markupComponent,
|
||||
String sectionLabel, T parameters) {
|
||||
SectionImpl parametersSection = new SectionImpl(componentsSection);
|
||||
String parametersSectionId = componentSectionId + "_parameters";
|
||||
parametersSection.setTitle(labels.getLabel(sectionLabel));
|
||||
parametersSection.setId(parametersSectionId);
|
||||
markupComponent.apply(parametersSection, parameters);
|
||||
componentsSection.append(parametersSection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
package io.github.swagger2markup.internal.document;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.BlockImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.extension.OverviewDocumentExtension;
|
||||
import io.github.swagger2markup.internal.component.ExternalDocumentationComponent;
|
||||
import io.github.swagger2markup.internal.component.TagsComponent;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.info.License;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Block;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.LABEL_TERMS_OF_SERVICE;
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_OVERVIEW;
|
||||
import static io.github.swagger2markup.extension.OverviewDocumentExtension.Context;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.appendDescription;
|
||||
|
||||
public class OverviewDocument extends MarkupComponent<Document, OverviewDocument.Parameters, Document> {
|
||||
private final TagsComponent tagsComponent;
|
||||
private final ExternalDocumentationComponent externalDocumentationComponent;
|
||||
|
||||
public OverviewDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
tagsComponent = new TagsComponent(context);
|
||||
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
|
||||
}
|
||||
|
||||
public static OverviewDocument.Parameters parameters(OpenAPI schema) {
|
||||
return new OverviewDocument.Parameters(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, Parameters parameters) {
|
||||
Info apiInfo = parameters.openAPI.getInfo();
|
||||
document.setAttribute("openapi", parameters.openAPI.getOpenapi(), true);
|
||||
addDocumentTitle(document, apiInfo);
|
||||
addAuthorInfo(document, apiInfo);
|
||||
addVersionInfo(document, apiInfo);
|
||||
|
||||
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_BEFORE, document));
|
||||
Document subDocument = new DocumentImpl(document);
|
||||
Section overviewDoc = new SectionImpl(subDocument, "section", new HashMap<>(), new ArrayList<>(),
|
||||
null, new ArrayList<>(), 1, "", new ArrayList<>(),
|
||||
null, null, "", "", false, false);
|
||||
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_BEGIN, subDocument));
|
||||
overviewDoc.setTitle(labels.getLabel(SECTION_TITLE_OVERVIEW));
|
||||
|
||||
appendDescription(overviewDoc, apiInfo.getDescription());
|
||||
appendTermsOfServiceInfo(overviewDoc, apiInfo);
|
||||
appendLicenseInfo(overviewDoc, apiInfo);
|
||||
subDocument.append(overviewDoc);
|
||||
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_END, subDocument));
|
||||
document.append(subDocument);
|
||||
|
||||
externalDocumentationComponent.apply(document, parameters.openAPI.getExternalDocs());
|
||||
tagsComponent.apply(document, parameters.openAPI.getTags());
|
||||
applyOverviewDocumentExtension(new Context(OverviewDocumentExtension.Position.DOCUMENT_AFTER, document));
|
||||
return document;
|
||||
}
|
||||
|
||||
private void applyOverviewDocumentExtension(Context context) {
|
||||
extensionRegistry.getOverviewDocumentExtensions().forEach(extension -> extension.apply(context));
|
||||
}
|
||||
|
||||
private void addDocumentTitle(Document rootDocument, Info apiInfo) {
|
||||
String title = apiInfo.getTitle();
|
||||
if (StringUtils.isNotBlank(title)) {
|
||||
rootDocument.setTitle(title);
|
||||
}
|
||||
}
|
||||
|
||||
private void addVersionInfo(Document rootDocument, Info info) {
|
||||
String version = info.getVersion();
|
||||
if (StringUtils.isNotBlank(version)) {
|
||||
rootDocument.setAttribute("revnumber", version, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void addAuthorInfo(Document rootDocument, Info info) {
|
||||
Contact contact = info.getContact();
|
||||
if (null != contact) {
|
||||
String author = Optional.ofNullable(contact.getName()).orElse("");
|
||||
String email = contact.getEmail();
|
||||
if (StringUtils.isNotBlank(email)) {
|
||||
rootDocument.setAttribute("email", email, true);
|
||||
}
|
||||
rootDocument.setAttribute("author", author, true);
|
||||
rootDocument.setAttribute("authorcount", 1L, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendLicenseInfo(Section overviewDoc, Info info) {
|
||||
License license = info.getLicense();
|
||||
if (null != license) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (StringUtils.isNotBlank(license.getUrl())) {
|
||||
sb.append(license.getUrl()).append("[");
|
||||
}
|
||||
sb.append(license.getName());
|
||||
if (StringUtils.isNotBlank(license.getUrl())) {
|
||||
sb.append("]");
|
||||
}
|
||||
BlockImpl paragraph = new ParagraphBlockImpl(overviewDoc);
|
||||
paragraph.setSource(sb.toString());
|
||||
overviewDoc.append(paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendTermsOfServiceInfo(Section overviewDoc, Info info) {
|
||||
String termsOfService = info.getTermsOfService();
|
||||
if (StringUtils.isNotBlank(termsOfService)) {
|
||||
Block paragraph = new ParagraphBlockImpl(overviewDoc);
|
||||
paragraph.setSource(termsOfService + "[" + labels.getLabel(LABEL_TERMS_OF_SERVICE) + "]");
|
||||
overviewDoc.append(paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final OpenAPI openAPI;
|
||||
|
||||
public Parameters(OpenAPI openAPI) {
|
||||
this.openAPI = Validate.notNull(openAPI, "Schema must not be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package io.github.swagger2markup.internal.document;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.TableImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.internal.component.ExternalDocumentationComponent;
|
||||
import io.github.swagger2markup.internal.component.ParametersComponent;
|
||||
import io.github.swagger2markup.internal.component.ResponseComponent;
|
||||
import io.github.swagger2markup.internal.component.SecurityRequirementTableComponent;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.Paths;
|
||||
import io.swagger.v3.oas.models.servers.Server;
|
||||
import io.swagger.v3.oas.models.servers.ServerVariables;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.*;
|
||||
import static io.github.swagger2markup.internal.helper.OpenApiHelpers.*;
|
||||
|
||||
public class PathsDocument extends MarkupComponent<Document, PathsDocument.Parameters, Document> {
|
||||
private final ParametersComponent parametersComponent;
|
||||
private final ExternalDocumentationComponent externalDocumentationComponent;
|
||||
private final ResponseComponent responseComponent;
|
||||
private final SecurityRequirementTableComponent securityRequirementTableComponent;
|
||||
|
||||
public PathsDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.parametersComponent = new ParametersComponent(context);
|
||||
this.externalDocumentationComponent = new ExternalDocumentationComponent(context);
|
||||
this.responseComponent = new ResponseComponent(context);
|
||||
this.securityRequirementTableComponent = new SecurityRequirementTableComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(OpenAPI schema) {
|
||||
return new Parameters(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, Parameters parameters) {
|
||||
Paths apiPaths = parameters.schema.getPaths();
|
||||
|
||||
if (null == apiPaths || apiPaths.isEmpty()) return document;
|
||||
|
||||
SectionImpl allPathsSection = new SectionImpl(document);
|
||||
allPathsSection.setTitle(labels.getLabel(SECTION_TITLE_PATHS));
|
||||
|
||||
apiPaths.forEach((name, pathItem) ->
|
||||
pathItem.readOperationsMap().forEach(((httpMethod, operation) -> {
|
||||
SectionImpl operationSection = new SectionImpl(allPathsSection);
|
||||
String summary = Optional.ofNullable(operation.getSummary()).orElse("");
|
||||
operationSection.setTitle((italicUnconstrained(httpMethod.name().toUpperCase()) + " " + monospaced(name) + " " + summary).trim());
|
||||
appendDescription(operationSection, operation.getDescription());
|
||||
externalDocumentationComponent.apply(operationSection, operation.getExternalDocs());
|
||||
parametersComponent.apply(operationSection, operation.getParameters());
|
||||
responseComponent.apply(operationSection, operation.getResponses());
|
||||
appendServersSection(operationSection, operation.getServers());
|
||||
securityRequirementTableComponent.apply(operationSection, operation.getSecurity(), false);
|
||||
allPathsSection.append(operationSection);
|
||||
})));
|
||||
|
||||
document.append(allPathsSection);
|
||||
return document;
|
||||
}
|
||||
|
||||
private void appendServersSection(StructuralNode node, List<Server> servers) {
|
||||
if (null == servers || servers.isEmpty()) return;
|
||||
|
||||
Section serversSection = new SectionImpl(node);
|
||||
serversSection.setTitle(labels.getLabel(SECTION_TITLE_SERVERS));
|
||||
|
||||
servers.forEach(server -> {
|
||||
Section serverSection = new SectionImpl(serversSection);
|
||||
serverSection.setTitle(italicUnconstrained(labels.getLabel(LABEL_SERVER)) + ": " + server.getUrl());
|
||||
|
||||
appendDescription(serverSection, server.getDescription());
|
||||
ServerVariables variables = server.getVariables();
|
||||
appendVariables(serverSection, variables);
|
||||
serversSection.append(serverSection);
|
||||
});
|
||||
node.append(serversSection);
|
||||
}
|
||||
|
||||
private void appendVariables(Section serverSection, ServerVariables variables) {
|
||||
if (null == variables || variables.isEmpty()) return;
|
||||
|
||||
TableImpl serverVariables = new TableImpl(serverSection, new HashMap<String, Object>() {{
|
||||
put("header-option", "");
|
||||
put("cols", ".^2a,.^9a,.^3a,.^4a");
|
||||
}}, new ArrayList<>());
|
||||
serverVariables.setTitle(labels.getLabel(TABLE_TITLE_SERVER_VARIABLES));
|
||||
|
||||
serverVariables.setHeaderRow(labels.getLabel(TABLE_HEADER_VARIABLE), labels.getLabel(TABLE_HEADER_DESCRIPTION),
|
||||
labels.getLabel(TABLE_HEADER_POSSIBLE_VALUES), labels.getLabel(TABLE_HEADER_DEFAULT)
|
||||
);
|
||||
|
||||
variables.forEach((name, variable) -> {
|
||||
String possibleValues = String.join(", ", Optional.ofNullable(variable.getEnum()).orElse(Collections.singletonList("Any")));
|
||||
serverVariables.addRow(name, Optional.ofNullable(variable.getDescription()).orElse(""), possibleValues, variable.getDefault());
|
||||
|
||||
});
|
||||
serverSection.append(serverVariables);
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final OpenAPI schema;
|
||||
|
||||
public Parameters(OpenAPI schema) {
|
||||
this.schema = Validate.notNull(schema, "Schema must not be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package io.github.swagger2markup.internal.document;
|
||||
|
||||
import io.github.swagger2markup.OpenAPI2MarkupConverter;
|
||||
import io.github.swagger2markup.adoc.ast.impl.SectionImpl;
|
||||
import io.github.swagger2markup.extension.MarkupComponent;
|
||||
import io.github.swagger2markup.internal.component.SecurityRequirementTableComponent;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Section;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.config.OpenAPILabels.SECTION_TITLE_SECURITY;
|
||||
|
||||
public class SecurityDocument extends MarkupComponent<Document, SecurityDocument.Parameters, Document> {
|
||||
private final SecurityRequirementTableComponent securityRequirementTableComponent;
|
||||
|
||||
public SecurityDocument(OpenAPI2MarkupConverter.OpenAPIContext context) {
|
||||
super(context);
|
||||
this.securityRequirementTableComponent = new SecurityRequirementTableComponent(context);
|
||||
}
|
||||
|
||||
public static Parameters parameters(OpenAPI schema) {
|
||||
return new Parameters(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document apply(Document document, SecurityDocument.Parameters parameters) {
|
||||
List<SecurityRequirement> securityRequirements = parameters.schema.getSecurity();
|
||||
if (null == securityRequirements || securityRequirements.isEmpty()) return document;
|
||||
|
||||
Section securityRequirementsSection = new SectionImpl(document);
|
||||
securityRequirementsSection.setTitle(labels.getLabel(SECTION_TITLE_SECURITY));
|
||||
securityRequirementTableComponent.apply(securityRequirementsSection, securityRequirements, false);
|
||||
document.append(securityRequirementsSection);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static class Parameters {
|
||||
private final OpenAPI schema;
|
||||
|
||||
public Parameters(OpenAPI schema) {
|
||||
this.schema = Validate.notNull(schema, "Schema must not be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package io.github.swagger2markup.internal.helper;
|
||||
|
||||
import io.github.swagger2markup.adoc.ast.impl.DocumentImpl;
|
||||
import io.github.swagger2markup.adoc.ast.impl.ParagraphBlockImpl;
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Block;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.LINE_SEPARATOR;
|
||||
|
||||
public class OpenApiHelpers {
|
||||
|
||||
public static void appendDescription(StructuralNode node, String description) {
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
Block paragraph = new ParagraphBlockImpl(node);
|
||||
paragraph.setSource(description);
|
||||
node.append(paragraph);
|
||||
}
|
||||
}
|
||||
|
||||
public static Document generateInnerDoc(Table table, String documentContent) {
|
||||
return generateInnerDoc(table, documentContent, "");
|
||||
}
|
||||
|
||||
public static Document generateInnerDoc(Table table, String documentContent, String id) {
|
||||
Document innerDoc = new DocumentImpl(table);
|
||||
if (StringUtils.isNotBlank(id)) {
|
||||
innerDoc.setId(id);
|
||||
}
|
||||
|
||||
Block paragraph = new ParagraphBlockImpl(innerDoc);
|
||||
paragraph.setSource(documentContent);
|
||||
innerDoc.append(paragraph);
|
||||
return innerDoc;
|
||||
}
|
||||
|
||||
public static String requiredIndicator(boolean isRequired, String labelRequired, String labelOptional) {
|
||||
return italicUnconstrained(isRequired ? labelRequired : labelOptional).toLowerCase();
|
||||
}
|
||||
|
||||
public static String superScript(String str) {
|
||||
return "^" + str + "^";
|
||||
}
|
||||
|
||||
public static String subScript(String str) {
|
||||
return "~" + str + "~";
|
||||
}
|
||||
|
||||
public static String italicUnconstrained(String str) {
|
||||
return "__" + str + "__";
|
||||
}
|
||||
|
||||
public static String boldUnconstrained(String str) {
|
||||
return "**" + str + "**";
|
||||
}
|
||||
|
||||
public static String monospaced(String str) {
|
||||
return "`" + str + "`";
|
||||
}
|
||||
|
||||
public static String getSchemaTypeAsString(Schema schema) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (schema instanceof ArraySchema) {
|
||||
stringBuilder.append("< ");
|
||||
Schema<?> items = ((ArraySchema) schema).getItems();
|
||||
stringBuilder.append(getSchemaType(items));
|
||||
stringBuilder.append(" > ");
|
||||
stringBuilder.append(schema.getType());
|
||||
} else {
|
||||
List enumList = schema.getEnum();
|
||||
if (enumList != null) {
|
||||
stringBuilder.append("enum (");
|
||||
for (Object value : enumList) {
|
||||
stringBuilder.append(value.toString());
|
||||
stringBuilder.append(",");
|
||||
}
|
||||
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
|
||||
stringBuilder.append(')');
|
||||
} else {
|
||||
stringBuilder.append(getSchemaType(schema));
|
||||
String format = schema.getFormat();
|
||||
if (format != null) {
|
||||
stringBuilder.append(' ');
|
||||
stringBuilder.append('(');
|
||||
stringBuilder.append(format);
|
||||
stringBuilder.append(')');
|
||||
}
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private static String getSchemaType(Schema<?> schema) {
|
||||
String type = schema.getType();
|
||||
if (StringUtils.isNotEmpty(type)) {
|
||||
return type;
|
||||
} else {
|
||||
return generateRefLink(schema.get$ref());
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateRefLink(String ref) {
|
||||
if (StringUtils.isNotBlank(ref)) {
|
||||
String anchor = ref.toLowerCase().replaceFirst("#", "").replaceAll("/", "_");
|
||||
return "<<" + anchor + ">>" + LINE_SEPARATOR;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
swagger2markup.markupLanguage=ASCIIDOC
|
||||
swagger2markup.swaggerMarkupLanguage=ASCIIDOC
|
||||
swagger2markup.generatedExamplesEnabled=false
|
||||
swagger2markup.hostnameEnabled=false
|
||||
swagger2markup.basePathPrefixEnabled=false
|
||||
swagger2markup.operationExtensionsEnabled=false
|
||||
swagger2markup.definitionExtensionsEnabled=false
|
||||
swagger2markup.separatedDefinitionsEnabled=false
|
||||
swagger2markup.separatedOperationsEnabled=false
|
||||
swagger2markup.pathsGroupedBy=AS_IS
|
||||
swagger2markup.outputLanguage=EN
|
||||
swagger2markup.inlineSchemaEnabled=true
|
||||
swagger2markup.interDocumentCrossReferencesEnabled=false
|
||||
swagger2markup.flatBodyEnabled=false
|
||||
swagger2markup.pathSecuritySectionEnabled=true
|
||||
swagger2markup.overviewDocument=overview
|
||||
swagger2markup.pathsDocument=paths
|
||||
swagger2markup.definitionsDocument=definitions
|
||||
swagger2markup.securityDocument=security
|
||||
swagger2markup.separatedOperationsFolder=operations
|
||||
swagger2markup.separatedDefinitionsFolder=definitions
|
||||
swagger2markup.tagOrderBy=NATURAL
|
||||
swagger2markup.operationOrderBy=NATURAL
|
||||
swagger2markup.definitionOrderBy=NATURAL
|
||||
swagger2markup.parameterOrderBy=NATURAL
|
||||
swagger2markup.propertyOrderBy=NATURAL
|
||||
swagger2markup.responseOrderBy=NATURAL
|
||||
swagger2markup.listDelimiterEnabled=false
|
||||
swagger2markup.listDelimiter=,
|
||||
swagger2markup.asciidoc.pegdown.timeoutMillis=2000
|
||||
@@ -0,0 +1,58 @@
|
||||
label_content=Content
|
||||
label_default=Default
|
||||
label_deprecated=Deprecated
|
||||
label_example=Example
|
||||
label_examples=Examples
|
||||
label_exclusive_maximum=Exclusive Maximum
|
||||
label_exclusive_minimum=Exclusive Minimum
|
||||
label_external_value=External Value
|
||||
label_format=Format
|
||||
label_maximum=Maximum
|
||||
label_max_items=Maximum Items
|
||||
label_max_length=Maximum Length
|
||||
label_max_properties=Maximum Properties
|
||||
label_minimum=Minimum
|
||||
label_min_items=Minimum Items
|
||||
label_min_length=Minimum Length
|
||||
label_min_properties=Minimum Properties
|
||||
label_multiple_of=Multiple Of
|
||||
label_no_links=No Links
|
||||
label_nullable=Nullable
|
||||
label_operation=Operation
|
||||
label_optional=Optional
|
||||
label_parameters=Parameters
|
||||
label_read_only=Read Only
|
||||
label_required=Required
|
||||
label_server=Server
|
||||
label_terms_of_service=Terms Of Service
|
||||
label_title=Title
|
||||
label_type=Type
|
||||
label_unique_items=Unique Items
|
||||
label_write_only=Write Only
|
||||
section_title_components=Components
|
||||
section_title_parameters=Parameters
|
||||
section_title_paths=Paths
|
||||
section_title_schemas=Schemas
|
||||
section_title_security=Security
|
||||
section_title_servers=Servers
|
||||
section_title_overview=Overview
|
||||
section_title_tags=Tags
|
||||
section_title_responses=Responses
|
||||
section_title_headers=Headers
|
||||
section_title_links=Links
|
||||
table_header_default=Default
|
||||
table_header_description=Description
|
||||
table_header_http_code=Code
|
||||
table_header_links=Links
|
||||
table_header_name=Name
|
||||
table_header_possible_values=Possible Values
|
||||
table_header_schema=Schema
|
||||
table_header_scopes=Scopes
|
||||
table_header_type=Type
|
||||
table_header_variable=Variable
|
||||
table_title_headers=Headers
|
||||
table_title_parameters=Parameters
|
||||
table_title_properties=Properties
|
||||
table_title_responses=Responses
|
||||
table_title_security=Security
|
||||
table_title_server_variables=Server Variables
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2017 Robert Winkler
|
||||
*
|
||||
* 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 io.github.swagger2markup;
|
||||
|
||||
import io.github.swagger2markup.assertions.DiffUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class AsciidocConverterTest {
|
||||
|
||||
private static final String[] EXPECTED_FILES = new String[]{"definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"};
|
||||
private List<String> expectedFiles;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() throws URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
|
||||
//When
|
||||
String asciiDocAsString = OpenAPI2MarkupConverter.from(file).build()
|
||||
.toString();
|
||||
//Then
|
||||
Assertions.assertThat(asciiDocAsString).isNotEmpty();
|
||||
System.out.println(asciiDocAsString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToFolder() throws URISyntaxException {
|
||||
//Given
|
||||
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
|
||||
Path outputDirectory = Paths.get("build/test/asciidoc/to_folder");
|
||||
FileUtils.deleteQuietly(outputDirectory.toFile());
|
||||
|
||||
//When
|
||||
OpenAPI2MarkupConverter.from(file).build()
|
||||
.toFolder(outputDirectory);
|
||||
|
||||
//Then
|
||||
String[] files = outputDirectory.toFile().list();
|
||||
assertThat(files).hasSize(4).containsAll(expectedFiles);
|
||||
|
||||
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/to_folder").toURI());
|
||||
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testToFolder.html");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package io.github.swagger2markup;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.parser.OpenAPIV3Parser;
|
||||
import io.swagger.v3.parser.core.models.ParseOptions;
|
||||
import io.swagger.v3.parser.core.models.SwaggerParseResult;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class OpenApi2AsciiDocTest {
|
||||
|
||||
final private String openApiFile;
|
||||
final private String expectedAsciiDoc;
|
||||
|
||||
public OpenApi2AsciiDocTest(String openApiFile, String expectedAsciiDoc) throws IOException {
|
||||
this.openApiFile = "./src/test/resources/open_api/" + openApiFile;
|
||||
this.expectedAsciiDoc = IOUtils.toString(getClass().getResourceAsStream("/asciidoc/" + expectedAsciiDoc), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "Run {index}: open api={0}, asciidoc={1}")
|
||||
public static Iterable<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{"simple.yaml", "simple.adoc"},
|
||||
{"petstore.yaml", "petstore.adoc"}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void converts_open_api_v3_to_asciidoc() {
|
||||
ParseOptions options = new ParseOptions();
|
||||
options.setResolve(true);
|
||||
SwaggerParseResult result = new OpenAPIV3Parser().readLocation(openApiFile, null, options);
|
||||
OpenAPI swagger = result.getOpenAPI();
|
||||
assertNotNull(swagger);
|
||||
|
||||
OpenAPI2MarkupConverter converter = OpenAPI2MarkupConverter.from(swagger).build();
|
||||
converter.toFolder(Paths.get("build/test/asciidoc"));
|
||||
}
|
||||
}
|
||||
1898
openapi2markup/src/test/resources/asciidoc/petstore.adoc
Normal file
1898
openapi2markup/src/test/resources/asciidoc/petstore.adoc
Normal file
File diff suppressed because it is too large
Load Diff
276
openapi2markup/src/test/resources/asciidoc/simple.adoc
Normal file
276
openapi2markup/src/test/resources/asciidoc/simple.adoc
Normal file
@@ -0,0 +1,276 @@
|
||||
= Simple Inventory API
|
||||
<you@your-company.com>
|
||||
v1.0.0
|
||||
:revnumber: 1.0.0
|
||||
:openapi: 3.0.0
|
||||
:authorcount: 1
|
||||
:email: you@your-company.com
|
||||
|
||||
== Overview
|
||||
This is a simple API
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0]
|
||||
|
||||
== Tags
|
||||
admins::
|
||||
Secured Admin-only calls
|
||||
developers::
|
||||
Operations available to regular developers
|
||||
|
||||
== Servers
|
||||
=== __Server__: /
|
||||
|
||||
== Paths
|
||||
=== __GET__ `/inventory` searches inventory
|
||||
By passing in the appropriate options, you can search for
|
||||
available inventory in the system
|
||||
|
||||
.Parameters
|
||||
[%header,caption=,cols=".^2a,.^3a,.^10a,.^5a"]
|
||||
|===
|
||||
<.<|Type
|
||||
|
||||
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|**query**
|
||||
|
||||
|
||||
<.<|**searchString** +
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|pass an optional search string for looking up inventory
|
||||
|
||||
|
||||
<.<|type: string
|
||||
|
||||
|
||||
|
||||
<.<|**query**
|
||||
|
||||
|
||||
<.<|**limit** +
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|maximum number of records to return
|
||||
|
||||
|
||||
<.<|minimum: 0 +
|
||||
type: integer +
|
||||
maximum: 50 +
|
||||
format: int32
|
||||
|
||||
|
||||
|
||||
<.<|**query**
|
||||
|
||||
|
||||
<.<|**skip** +
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|number of records to skip for pagination
|
||||
|
||||
|
||||
<.<|minimum: 0 +
|
||||
type: integer +
|
||||
format: int32
|
||||
|
||||
|
||||
|
||||
|===
|
||||
.Responses
|
||||
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|
||||
|===
|
||||
<.<|Code
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Links
|
||||
|
||||
|
||||
|
||||
<.<|200
|
||||
|
||||
|
||||
<.<|search results matching criteria
|
||||
|
||||
.Content
|
||||
application/json::
|
||||
+
|
||||
|
||||
type: array
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
<.<|400
|
||||
|
||||
|
||||
<.<|bad input parameter
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
=== __POST__ `/inventory` adds an inventory item
|
||||
Adds an item to the system
|
||||
|
||||
.Responses
|
||||
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|
||||
|===
|
||||
<.<|Code
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Links
|
||||
|
||||
|
||||
|
||||
<.<|201
|
||||
|
||||
|
||||
<.<|item created
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
<.<|400
|
||||
|
||||
|
||||
<.<|invalid input, object invalid
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
<.<|409
|
||||
|
||||
|
||||
<.<|an existing item already exists
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
[[_components]]
|
||||
== Components
|
||||
[[_components_schemas]]
|
||||
=== Schemas
|
||||
[[_components_schemas_inventoryitem]]
|
||||
==== InventoryItem
|
||||
|
||||
type: object
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__required__
|
||||
|
||||
|
||||
<.<|type: string +
|
||||
format: uuid
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__required__
|
||||
|
||||
|
||||
<.<|type: string
|
||||
|
||||
|
||||
|
||||
<.<|releaseDate
|
||||
__required__
|
||||
|
||||
|
||||
<.<|type: string +
|
||||
format: date-time
|
||||
|
||||
|
||||
|
||||
<.<|manufacturer
|
||||
__required__
|
||||
|
||||
|
||||
<.<|<<_components_schemas_Manufacturer,Manufacturer>>
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_manufacturer]]
|
||||
==== Manufacturer
|
||||
|
||||
type: object
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__required__
|
||||
|
||||
|
||||
<.<|type: string
|
||||
|
||||
|
||||
|
||||
<.<|homePage
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|type: string +
|
||||
format: url
|
||||
|
||||
|
||||
|
||||
<.<|phone
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|type: string
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
|
||||
[[_components]]
|
||||
== Components
|
||||
[[_components_schemas]]
|
||||
=== Schemas
|
||||
[[_components_schemas_user]]
|
||||
==== User
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|username
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|firstName
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|lastName
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|email
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|password
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|phone
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|userStatus
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|User Status
|
||||
|
||||
|
||||
<.<|integer (int32)
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_category]]
|
||||
==== Category
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|The name of the category
|
||||
|
||||
**Maximum Length**: 255 +
|
||||
**Minimum Length**: 0 +
|
||||
**Default**: DefaultCategory
|
||||
|
||||
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_pet]]
|
||||
==== Pet
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|category
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|<<_components_schemas_category>>
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__required__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
<.<|photoUrls
|
||||
__required__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|< string > array
|
||||
|
||||
|
||||
|
||||
<.<|tags
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|< <<_components_schemas_tag>>
|
||||
> array
|
||||
|
||||
|
||||
|
||||
<.<|status
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|pet status in the store,
|
||||
|
||||
|
||||
<.<|enum (Dead,Alive)
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_tag]]
|
||||
==== Tag
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|name
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string
|
||||
|
||||
|
||||
|
||||
|===
|
||||
[[_components_schemas_order]]
|
||||
==== Order
|
||||
|
||||
.Properties
|
||||
[%header,caption=,cols=".^4a,.^16a,.^4a"]
|
||||
|===
|
||||
<.<|Name
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Schema
|
||||
|
||||
|
||||
|
||||
<.<|id
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|petId
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|integer (int64)
|
||||
|
||||
|
||||
|
||||
<.<|quantity
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|**Maximum**: 10000 +
|
||||
**Minimum**: 0 +
|
||||
**Default**: 0
|
||||
|
||||
|
||||
<.<|integer (int32)
|
||||
|
||||
|
||||
|
||||
<.<|shipDate
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|string (date-time)
|
||||
|
||||
|
||||
|
||||
<.<|status
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|Order Status
|
||||
|
||||
|
||||
<.<|enum (Ordered,Cancelled)
|
||||
|
||||
|
||||
|
||||
<.<|complete
|
||||
__optional__
|
||||
|
||||
|
||||
<.<|
|
||||
<.<|boolean
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
[[_components_parameters]]
|
||||
=== Responses
|
||||
.Responses
|
||||
[%header,caption=,cols=".^2a,.^14a,.^4a"]
|
||||
|===
|
||||
<.<|Code
|
||||
|
||||
|
||||
<.<|Description
|
||||
|
||||
|
||||
<.<|Links
|
||||
|
||||
|
||||
|
||||
<.<|InvalidId
|
||||
|
||||
|
||||
<.<|Invalid ID supplied
|
||||
|
||||
|
||||
<.<|No Links
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
= Swagger Petstore
|
||||
apiteam@swagger.io
|
||||
v1.0.0
|
||||
:revnumber: 1.0.0
|
||||
:openapi: 3.0.0
|
||||
:author: apiteam@swagger.io
|
||||
:authorcount: 1
|
||||
|
||||
|
||||
== Overview
|
||||
This is a sample server Petstore server.
|
||||
|
||||
[Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
|
||||
|
||||
For this sample, you can use the api key `special-key` to test the authorization filters
|
||||
|
||||
http://helloreverb.com/terms/[Terms Of Service]
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0]
|
||||
|
||||
http://swagger.io[Find out more about Swagger]
|
||||
|
||||
== Tags
|
||||
pet::
|
||||
Pet resource
|
||||
store::
|
||||
Store resource
|
||||
user::
|
||||
User resource
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
|
||||
14
openapi2markup/src/test/resources/logback.xml
Normal file
14
openapi2markup/src/test/resources/logback.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true">
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="io.github.swagger2markup" level="DEBUG"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
732
openapi2markup/src/test/resources/open_api/petstore.yaml
Normal file
732
openapi2markup/src/test/resources/open_api/petstore.yaml
Normal file
@@ -0,0 +1,732 @@
|
||||
openapi: 3.0.0
|
||||
servers:
|
||||
- url: 'http://localhost:8000/v2/api'
|
||||
info:
|
||||
description: >-
|
||||
This is a sample server Petstore server. You can find out more about
|
||||
Swagger at http://swagger.io or on
|
||||
irc.freenode.net, #swagger. For this sample, you can use the api key
|
||||
"special-key" to test the authorization filters
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
termsOfService: 'http://swagger.io/terms/'
|
||||
contact:
|
||||
name: apiteam@swagger.io
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
externalDocs:
|
||||
description: Find more info here
|
||||
url: 'https://swagger.io'
|
||||
tags:
|
||||
- name: pet
|
||||
description: Pet Operations
|
||||
externalDocs:
|
||||
url: 'http://swagger.io'
|
||||
- name: user
|
||||
description: All about the Users
|
||||
paths:
|
||||
/pet/add:
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Add a new pet to the store
|
||||
description: ''
|
||||
operationId: createPet
|
||||
responses:
|
||||
'200':
|
||||
description: This is a sample
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
example: 'whoa!'
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet object that needs to be added to the store
|
||||
/pet:
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Add a new pet to the store
|
||||
description: ''
|
||||
operationId: addPet
|
||||
responses:
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet object that needs to be added to the store
|
||||
put:
|
||||
tags:
|
||||
- pet
|
||||
summary: Update an existing pet
|
||||
description: ''
|
||||
operationId: updatePet
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Pet not found
|
||||
'405':
|
||||
description: Validation exception
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/Pet'
|
||||
/pet/findByStatus:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by status
|
||||
description: Multiple status values can be provided with comma seperated strings
|
||||
operationId: findPetsByStatus
|
||||
parameters:
|
||||
- name: status
|
||||
in: query
|
||||
description: Status values that need to be considered for filter
|
||||
required: false
|
||||
style: pipeDelimited
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
default: available
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PetArray'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PetArray'
|
||||
'400':
|
||||
description: Invalid status value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
/pet/findByTags:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by tags
|
||||
description: >-
|
||||
Muliple tags can be provided with comma seperated strings. Use tag1,
|
||||
tag2, tag3 for testing.
|
||||
operationId: findPetsByTags
|
||||
parameters:
|
||||
- name: tags
|
||||
in: query
|
||||
description: Tags to filter by
|
||||
required: false
|
||||
explode: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid tag value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
'/pet/{petId}':
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Find pet by ID
|
||||
description: >-
|
||||
Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API
|
||||
error conditions
|
||||
operationId: getPetById
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Pet not found
|
||||
security:
|
||||
- api_key: []
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Updates a pet in the store with form data
|
||||
description: ''
|
||||
operationId: updatePetWithForm
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: Updated name of the pet
|
||||
type: string
|
||||
status:
|
||||
description: Updated status of the pet
|
||||
type: string
|
||||
delete:
|
||||
tags:
|
||||
- pet
|
||||
summary: Deletes a pet
|
||||
description: ''
|
||||
operationId: deletePet
|
||||
parameters:
|
||||
- name: api_key
|
||||
in: header
|
||||
description: ''
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: petId
|
||||
in: path
|
||||
description: Pet id to delete
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid pet value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet extra params that needs to be deleted
|
||||
'/pet/{petId}/uploadImage':
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: uploads an image
|
||||
description: ''
|
||||
operationId: uploadFile
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet to update
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ApiResponse"
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: Additional data to pass to server
|
||||
type: string
|
||||
file:
|
||||
description: file to upload
|
||||
type: string
|
||||
format: binary
|
||||
/store/inventory:
|
||||
get:
|
||||
tags:
|
||||
- store
|
||||
summary: Returns pet inventories by status
|
||||
description: Returns a map of status codes to quantities
|
||||
operationId: get inventory+1
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: integer
|
||||
format: int32
|
||||
application/xml:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: integer
|
||||
format: int32
|
||||
security:
|
||||
- api_key: []
|
||||
/store/order:
|
||||
post:
|
||||
tags:
|
||||
- store
|
||||
summary: Place an order for a pet
|
||||
description: ''
|
||||
operationId: placeOrder
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
'400':
|
||||
description: Invalid Order
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
description: order placed for purchasing the pet
|
||||
'/store/order/{orderId}':
|
||||
get:
|
||||
tags:
|
||||
- store
|
||||
summary: Find purchase order by ID
|
||||
description: >-
|
||||
For valid response try integer IDs with value <= 5 or > 10. Other values
|
||||
will generated exceptions
|
||||
operationId: getOrderById
|
||||
parameters:
|
||||
- name: orderId
|
||||
in: path
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Order not found
|
||||
delete:
|
||||
tags:
|
||||
- store
|
||||
summary: Delete purchase order by ID
|
||||
description: >-
|
||||
For valid response try integer IDs with value < 1000. Anything above
|
||||
1000 or nonintegers will generate API errors
|
||||
operationId: deleteOrder
|
||||
parameters:
|
||||
- name: orderId
|
||||
in: path
|
||||
description: ID of the order that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Order not found
|
||||
/user:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Create user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: createUser
|
||||
responses:
|
||||
200:
|
||||
content:
|
||||
'application/json':
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
# default is text/plain
|
||||
type: string
|
||||
format: text
|
||||
examples:
|
||||
foo:
|
||||
value: {"foo": "bar"}
|
||||
bar:
|
||||
summary: A bar example
|
||||
value: {"bar": "baz"}
|
||||
default:
|
||||
description: successful operation
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
description: Created user object
|
||||
/user/createWithArray:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Creates list of users with given input array
|
||||
description: ''
|
||||
operationId: createUsersWithArrayInput
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/UserArray'
|
||||
/user/createWithList:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Creates list of users with given input array
|
||||
description: ''
|
||||
operationId: createUsersWithListInput
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/UserArray'
|
||||
/user/login:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
security:
|
||||
- https
|
||||
summary: Logs user into the system
|
||||
description: ''
|
||||
operationId: loginUser
|
||||
parameters:
|
||||
- name: username
|
||||
in: query
|
||||
description: The user name for login
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: password
|
||||
in: query
|
||||
description: The password for login in clear text
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
application/xml:
|
||||
schema:
|
||||
type: string
|
||||
'400':
|
||||
description: Invalid username/password supplied
|
||||
/user/logout:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
security:
|
||||
- https
|
||||
summary: Logs out current logged in user session
|
||||
description: ''
|
||||
operationId: logoutUser
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
'/user/{username}':
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Get user by user name
|
||||
description: ''
|
||||
operationId: getUserByName
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: 'The name that needs to be fetched. Use user1 for testing.'
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
'400':
|
||||
description: Invalid username supplied
|
||||
'404':
|
||||
description: User not found
|
||||
put:
|
||||
tags:
|
||||
- user
|
||||
summary: Updated user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: updateUser
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: name that need to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid user supplied
|
||||
'404':
|
||||
description: User not found
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
description: Updated user object
|
||||
delete:
|
||||
tags:
|
||||
- user
|
||||
summary: Delete user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: deleteUser
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: The name that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid username supplied
|
||||
'404':
|
||||
description: User not found
|
||||
security:
|
||||
- foo:
|
||||
- bar
|
||||
- baz
|
||||
a:
|
||||
- b
|
||||
- c
|
||||
components:
|
||||
parameters:
|
||||
sharedSkip:
|
||||
name: skip
|
||||
in: query
|
||||
description: Results to skip
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
veryBad:
|
||||
description: failed
|
||||
requestBodies:
|
||||
UserArray:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/User'
|
||||
description: List of user object
|
||||
Pet:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet object that needs to be added to the store
|
||||
securitySchemes:
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: header
|
||||
petstore_auth:
|
||||
type: oauth2
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
|
||||
scopes:
|
||||
'write:pets': modify pets in your account
|
||||
'read:pets': read your pets
|
||||
schemas:
|
||||
User:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
username:
|
||||
type: string
|
||||
firstName:
|
||||
type: string
|
||||
lastName:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
phone:
|
||||
type: string
|
||||
userStatus:
|
||||
type: integer
|
||||
format: int32
|
||||
description: User Status
|
||||
xml:
|
||||
name: User
|
||||
Category:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
xml:
|
||||
name: Category
|
||||
Pet:
|
||||
required:
|
||||
- name
|
||||
- photoUrls
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
category:
|
||||
$ref: '#/components/schemas/Category'
|
||||
name:
|
||||
type: string
|
||||
example: doggie
|
||||
photoUrls:
|
||||
type: array
|
||||
xml:
|
||||
name: photoUrl
|
||||
wrapped: true
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
xml:
|
||||
name: tag
|
||||
wrapped: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Tag'
|
||||
status:
|
||||
type: string
|
||||
description: pet status in the store
|
||||
xml:
|
||||
name: Pet
|
||||
Tag:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
xml:
|
||||
name: Tag
|
||||
Order:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
petId:
|
||||
type: integer
|
||||
format: int64
|
||||
quantity:
|
||||
type: integer
|
||||
format: int32
|
||||
shipDate:
|
||||
type: string
|
||||
format: date-time
|
||||
status:
|
||||
type: string
|
||||
description: Order Status
|
||||
complete:
|
||||
type: boolean
|
||||
xml:
|
||||
name: Order
|
||||
PetArray:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
115
openapi2markup/src/test/resources/open_api/simple.yaml
Normal file
115
openapi2markup/src/test/resources/open_api/simple.yaml
Normal file
@@ -0,0 +1,115 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
description: This is a simple API
|
||||
version: "1.0.0"
|
||||
title: Simple Inventory API
|
||||
contact:
|
||||
email: you@your-company.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
tags:
|
||||
- name: admins
|
||||
description: Secured Admin-only calls
|
||||
- name: developers
|
||||
description: Operations available to regular developers
|
||||
paths:
|
||||
/inventory:
|
||||
get:
|
||||
tags:
|
||||
- developers
|
||||
summary: searches inventory
|
||||
operationId: searchInventory
|
||||
description: |
|
||||
By passing in the appropriate options, you can search for
|
||||
available inventory in the system
|
||||
parameters:
|
||||
- in: query
|
||||
name: searchString
|
||||
description: pass an optional search string for looking up inventory
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: skip
|
||||
description: number of records to skip for pagination
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
- in: query
|
||||
name: limit
|
||||
description: maximum number of records to return
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
responses:
|
||||
'200':
|
||||
description: search results matching criteria
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/InventoryItem'
|
||||
'400':
|
||||
description: bad input parameter
|
||||
post:
|
||||
tags:
|
||||
- admins
|
||||
summary: adds an inventory item
|
||||
operationId: addInventory
|
||||
description: Adds an item to the system
|
||||
responses:
|
||||
'201':
|
||||
description: item created
|
||||
'400':
|
||||
description: 'invalid input, object invalid'
|
||||
'409':
|
||||
description: an existing item already exists
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InventoryItem'
|
||||
description: Inventory item to add
|
||||
components:
|
||||
schemas:
|
||||
InventoryItem:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- manufacturer
|
||||
- releaseDate
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: d290f1ee-6c54-4b01-90e6-d701748f0851
|
||||
name:
|
||||
type: string
|
||||
example: Widget Adapter
|
||||
releaseDate:
|
||||
type: string
|
||||
format: date-time
|
||||
example: '2016-08-29T09:12:33.001Z'
|
||||
manufacturer:
|
||||
$ref: '#/components/schemas/Manufacturer'
|
||||
Manufacturer:
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: ACME Corporation
|
||||
homePage:
|
||||
type: string
|
||||
format: url
|
||||
example: 'https://www.acme-corp.com'
|
||||
phone:
|
||||
type: string
|
||||
example: 408-867-5309
|
||||
type: object
|
||||
693
openapi2markup/src/test/resources/yaml/swagger_petstore.yaml
Normal file
693
openapi2markup/src/test/resources/yaml/swagger_petstore.yaml
Normal file
@@ -0,0 +1,693 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
description: >
|
||||
This is a sample server Petstore server.
|
||||
|
||||
|
||||
[Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
|
||||
|
||||
|
||||
For this sample, you can use the api key `special-key` to test the authorization filters
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
termsOfService: http://helloreverb.com/terms/
|
||||
contact:
|
||||
name: apiteam@swagger.io
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
tags:
|
||||
- name: pet
|
||||
description: Pet resource
|
||||
- name: store
|
||||
description: Store resource
|
||||
- name: user
|
||||
description: User resource
|
||||
paths:
|
||||
/pets:
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Add a new pet to the store
|
||||
description: ""
|
||||
operationId: addPet
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/Pet"
|
||||
responses:
|
||||
"405":
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
put:
|
||||
tags:
|
||||
- pet
|
||||
summary: Update an existing pet
|
||||
description: ""
|
||||
operationId: updatePet
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/Pet"
|
||||
responses:
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidId"
|
||||
"404":
|
||||
description: Pet not found
|
||||
"405":
|
||||
description: Validation exception
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
/pets/findByStatus:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by status
|
||||
description: Multiple status values can be provided with comma seperated strings
|
||||
operationId: findPetsByStatus
|
||||
parameters:
|
||||
- in: query
|
||||
name: status
|
||||
description: Status values that need to be considered for filter
|
||||
required: false
|
||||
explode: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
"400":
|
||||
description: Invalid status value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
/pets/findByTags:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by tags
|
||||
description: Muliple tags can be provided with comma seperated strings. Use tag1,
|
||||
tag2, tag3 for testing.
|
||||
operationId: findPetsByTags
|
||||
parameters:
|
||||
- in: query
|
||||
name: tags
|
||||
description: Tags to filter by
|
||||
required: false
|
||||
example: adorable
|
||||
explode: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
"400":
|
||||
description: Invalid tag value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
"/pets/{petId}":
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Find pet by ID
|
||||
description: Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API
|
||||
error conditions
|
||||
operationId: getPetById
|
||||
parameters:
|
||||
- in: path
|
||||
name: petId
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
example: 30
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidId"
|
||||
"404":
|
||||
description: Pet not found
|
||||
security:
|
||||
- api_key: []
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Updates a pet in the store with form data
|
||||
description: ""
|
||||
operationId: updatePetWithForm
|
||||
parameters:
|
||||
- in: path
|
||||
name: petId
|
||||
description: ID of pet that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: Updated name of the pet
|
||||
type: string
|
||||
status:
|
||||
description: Updated status of the pet
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- status
|
||||
responses:
|
||||
"405":
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
delete:
|
||||
tags:
|
||||
- pet
|
||||
summary: Deletes a pet
|
||||
description: ""
|
||||
operationId: deletePet
|
||||
parameters:
|
||||
- in: header
|
||||
name: api_key
|
||||
description: ""
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- in: path
|
||||
name: petId
|
||||
description: Pet id to delete
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
"400":
|
||||
description: Invalid pet value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write_pets
|
||||
- read_pets
|
||||
/stores/order:
|
||||
post:
|
||||
tags:
|
||||
- store
|
||||
summary: Place an order for a pet
|
||||
description: ""
|
||||
operationId: placeOrder
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
description: order placed for purchasing the pet
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
"400":
|
||||
description: Invalid Order
|
||||
"/stores/order/{orderId}":
|
||||
get:
|
||||
tags:
|
||||
- store
|
||||
summary: Find purchase order by ID
|
||||
description: For valid response try integer IDs with value <= 5 or > 10. Other values
|
||||
will generated exceptions
|
||||
operationId: getOrderById
|
||||
parameters:
|
||||
- in: path
|
||||
name: orderId
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Order"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidId"
|
||||
"404":
|
||||
description: Order not found
|
||||
delete:
|
||||
tags:
|
||||
- store
|
||||
summary: Delete purchase order by ID
|
||||
description: For valid response try integer IDs with value < 1000. Anything above
|
||||
1000 or nonintegers will generate API errors
|
||||
operationId: deleteOrder
|
||||
parameters:
|
||||
- in: path
|
||||
name: orderId
|
||||
description: ID of the order that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidId"
|
||||
"404":
|
||||
description: Order not found
|
||||
/users:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Create user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: createUser
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
description: Created user object
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
/users/createWithArray:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Creates list of users with given input array
|
||||
description: ""
|
||||
operationId: createUsersWithArrayInput
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/UserArray"
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
/users/createWithList:
|
||||
post:
|
||||
tags:
|
||||
- user
|
||||
summary: Creates list of users with given input array
|
||||
description: ""
|
||||
operationId: createUsersWithListInput
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/UserArray"
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
/users/login:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Logs user into the system
|
||||
description: ""
|
||||
operationId: loginUser
|
||||
parameters:
|
||||
- in: query
|
||||
name: username
|
||||
description: The user name for login
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: password
|
||||
description: The password for login in clear text
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
application/xml:
|
||||
schema:
|
||||
type: string
|
||||
"400":
|
||||
description: Invalid username/password supplied
|
||||
/users/logout:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Logs out current logged in user session
|
||||
description: ""
|
||||
operationId: logoutUser
|
||||
responses:
|
||||
default:
|
||||
description: successful operation
|
||||
"/users/{username}":
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Get user by user name
|
||||
description: ""
|
||||
operationId: getUserByName
|
||||
parameters:
|
||||
- in: path
|
||||
name: username
|
||||
description: The name that needs to be fetched. Use user1 for testing.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: successful operation
|
||||
headers:
|
||||
X-Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Remaining:
|
||||
description: The number of remaining requests in the current period
|
||||
schema:
|
||||
type: integer
|
||||
X-Rate-Limit-Reset:
|
||||
description: The number of seconds left in the current period
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
"400":
|
||||
description: Invalid username supplied
|
||||
"404":
|
||||
description: User not found
|
||||
put:
|
||||
tags:
|
||||
- user
|
||||
summary: Updated user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: updateUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: username
|
||||
description: name that need to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
description: Updated user object
|
||||
responses:
|
||||
"400":
|
||||
description: Invalid user supplied
|
||||
"404":
|
||||
description: User not found
|
||||
delete:
|
||||
tags:
|
||||
- user
|
||||
summary: Delete user
|
||||
description: This can only be done by the logged in user.
|
||||
operationId: deleteUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: username
|
||||
description: The name that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"400":
|
||||
description: Invalid username supplied
|
||||
"404":
|
||||
description: User not found
|
||||
externalDocs:
|
||||
description: Find out more about Swagger
|
||||
url: http://swagger.io
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v2
|
||||
components:
|
||||
responses:
|
||||
InvalidId:
|
||||
description: Invalid ID supplied
|
||||
requestBodies:
|
||||
UserArray:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/User"
|
||||
description: List of user object
|
||||
Pet:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
description: Pet object that needs to be added to the store
|
||||
securitySchemes:
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: header
|
||||
description: This is another description
|
||||
petstore_auth:
|
||||
type: oauth2
|
||||
description: This is a standard oauth flow
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
|
||||
scopes:
|
||||
write_pets: modify pets in your account
|
||||
read_pets: read your pets
|
||||
schemas:
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
username:
|
||||
type: string
|
||||
firstName:
|
||||
type: string
|
||||
lastName:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
phone:
|
||||
type: string
|
||||
userStatus:
|
||||
type: integer
|
||||
format: int32
|
||||
description: User Status
|
||||
Category:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
description: The name of the category
|
||||
minLength: 0
|
||||
maxLength: 255
|
||||
pattern: "[A-Za-zäöüÄÖÜß]{0,255}"
|
||||
default: DefaultCategory
|
||||
example: FoobarCategory
|
||||
Pet:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- photoUrls
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
category:
|
||||
$ref: "#/components/schemas/Category"
|
||||
name:
|
||||
type: string
|
||||
example: doggie
|
||||
photoUrls:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Tag"
|
||||
status:
|
||||
type: string
|
||||
description: pet status in the store,
|
||||
enum:
|
||||
- Dead
|
||||
- Alive
|
||||
Tag:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
Order:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
petId:
|
||||
type: integer
|
||||
format: int64
|
||||
quantity:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 10000
|
||||
default: 0
|
||||
example: 10
|
||||
shipDate:
|
||||
type: string
|
||||
format: date-time
|
||||
status:
|
||||
type: string
|
||||
description: Order Status
|
||||
enum:
|
||||
- Ordered
|
||||
- Cancelled
|
||||
complete:
|
||||
type: boolean
|
||||
@@ -1,6 +1,10 @@
|
||||
rootProject.name = 'swagger2markup'
|
||||
|
||||
include 'swagger2markup-asciidoc'
|
||||
include 'swagger2markup-bom'
|
||||
include 'swagger2markup-builder'
|
||||
include 'swagger2markup-core'
|
||||
include 'swagger2markup-documentation'
|
||||
include 'swagger2markup'
|
||||
include 'swagger2markup-core'
|
||||
include 'openapi2markup'
|
||||
|
||||
|
||||
25
swagger2markup-asciidoc/build.gradle
Normal file
25
swagger2markup-asciidoc/build.gradle
Normal file
@@ -0,0 +1,25 @@
|
||||
ext.moduleName="io.github.swagger2markup.asciidoc"
|
||||
|
||||
dependencies {
|
||||
configurations.all {
|
||||
// resolutionStrategy.force dependencyOverrides.commonsCodec
|
||||
// resolutionStrategy.force dependencyOverrides.commonsIO
|
||||
// resolutionStrategy.force dependencyOverrides.commonsLang3
|
||||
resolutionStrategy.force dependencyOverrides.jnrConstants
|
||||
resolutionStrategy.force dependencyOverrides.jnrEnxio
|
||||
resolutionStrategy.force dependencyOverrides.jnrPosix
|
||||
// resolutionStrategy.force dependencyOverrides.jodaTime
|
||||
resolutionStrategy.force dependencyOverrides.slf4j
|
||||
// resolutionStrategy.force dependencyOverrides.jacksonDatabind
|
||||
// resolutionStrategy.force dependencyOverrides.guava
|
||||
// resolutionStrategy.force dependencyOverrides.findBugs
|
||||
// resolutionStrategy.force dependencyOverrides.jaksonCore
|
||||
}
|
||||
implementation implLibraries.asciiDocJApi
|
||||
implementation implLibraries.commonsText
|
||||
implementation implLibraries.slf4j
|
||||
testImplementation implLibraries.commonsIO
|
||||
testImplementation testLibraries.asciiDocJ
|
||||
testImplementation testLibraries.junit
|
||||
testImplementation testLibraries.logback
|
||||
}
|
||||
@@ -0,0 +1,887 @@
|
||||
package io.github.swagger2markup.adoc;
|
||||
|
||||
import io.github.swagger2markup.adoc.converter.internal.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.asciidoctor.ast.List;
|
||||
import org.asciidoctor.ast.*;
|
||||
import org.asciidoctor.converter.ConverterFor;
|
||||
import org.asciidoctor.converter.StringConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
|
||||
|
||||
@ConverterFor(AsciidocConverter.NAME)
|
||||
public class AsciidocConverter extends StringConverter {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public static final String NAME = "adoc";
|
||||
|
||||
private final Pattern emptyLineOrStartWith = Pattern.compile("(?m)^\\s*(?:\\r?\\n)|(?m)^\\s+");
|
||||
private final Pattern coListItemIdPattern = Pattern.compile(".*-(\\d+)");
|
||||
private final Pattern tableColumnsStylePattern = Pattern.compile("((\\d+)\\*)?([<^>])?(\\.[<^>])?(\\d+)?([adehlmsv])?");
|
||||
|
||||
private static final java.util.List<String> attributeToExclude = Arrays.asList(
|
||||
"localtime",
|
||||
"filetype",
|
||||
"asciidoctor-version",
|
||||
"doctime",
|
||||
"localyear",
|
||||
"docdate",
|
||||
"localdate",
|
||||
"localdatetime",
|
||||
"docdatetime",
|
||||
"backend",
|
||||
"basebackend",
|
||||
"doctitle",
|
||||
"docyear"
|
||||
);
|
||||
|
||||
private static final String[] supportedUrlSchemes = new String[]{
|
||||
"http",
|
||||
"https",
|
||||
"ftp",
|
||||
"irc",
|
||||
"mailto"
|
||||
};
|
||||
|
||||
public AsciidocConverter(String backend, Map<String, Object> opts) {
|
||||
super(backend, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an {@link ContentNode} using the specified transform along
|
||||
* with additional options. If a transform is not specified, implementations
|
||||
* typically derive one from the {@link ContentNode#getNodeName()} property.
|
||||
*
|
||||
* <p>Implementations are free to decide how to carry out the conversion. In
|
||||
* the case of the built-in converters, the tranform value is used to
|
||||
* dispatch to a handler method. The TemplateConverter uses the value of
|
||||
* the transform to select a template to render.
|
||||
*
|
||||
* @param node The concrete instance of FlowNode to convert
|
||||
* @param transform An optional String transform that hints at which transformation
|
||||
* should be applied to this node. If a transform is not specified,
|
||||
* the transform is typically derived from the value of the
|
||||
* node's node_name property. (optional, default: null)
|
||||
* @param opts An optional map of options that provide additional hints about
|
||||
* how to convert the node. (optional, default: empty map)
|
||||
* @return the converted result
|
||||
*/
|
||||
@Override
|
||||
public String convert(ContentNode node, String transform, Map<Object, Object> opts) {
|
||||
if (null == transform) {
|
||||
transform = node.getNodeName();
|
||||
}
|
||||
switch (transform) {
|
||||
case "inline_quoted":
|
||||
return convertInlineQuoted((PhraseNode) node);
|
||||
case "paragraph":
|
||||
return convertParagraph((StructuralNode) node);
|
||||
case "inline_anchor":
|
||||
return convertInlineAnchor((PhraseNode) node);
|
||||
case "section":
|
||||
return convertSection((Section) node);
|
||||
case "listing":
|
||||
return convertListing((Block) node);
|
||||
case "literal":
|
||||
return convertLiteral((StructuralNode) node);
|
||||
case "ulist":
|
||||
return convertUList((List) node);
|
||||
case "olist":
|
||||
return convertOList((List) node);
|
||||
case "dlist":
|
||||
return convertDescriptionList((DescriptionList) node);
|
||||
case "admonition":
|
||||
return convertAdmonition((Block) node);
|
||||
case "colist":
|
||||
return convertCoList((List) node);
|
||||
case "embedded":
|
||||
case "document":
|
||||
return convertEmbedded((Document) node);
|
||||
case "example":
|
||||
return convertExample((Block) node);
|
||||
case "floating_title":
|
||||
return convertFloatingTitle((StructuralNode) node);
|
||||
case "image":
|
||||
return convertImage((StructuralNode) node);
|
||||
case "inline_break":
|
||||
return convertInlineBreak(node);
|
||||
case "inline_button":
|
||||
return convertInlineButton(node);
|
||||
case "inline_callout":
|
||||
return convertInlineCallout(node);
|
||||
case "inline_footnote":
|
||||
return convertInlineFootnote(node);
|
||||
case "inline_image":
|
||||
return convertInlineImage((PhraseNode) node);
|
||||
case "inline_indexterm":
|
||||
return convertInlineIndexTerm(node);
|
||||
case "inline_kbd":
|
||||
return convertInlineKbd(node);
|
||||
case "inline_menu":
|
||||
return convertInlineMenu(node);
|
||||
case "open":
|
||||
return convertOpen((StructuralNode) node);
|
||||
case "page_break":
|
||||
return convertPageBreak(node);
|
||||
case "preamble":
|
||||
return convertPreamble((StructuralNode) node);
|
||||
case "quote":
|
||||
return convertQuote((StructuralNode) node);
|
||||
case "sidebar":
|
||||
return convertSidebar((StructuralNode) node);
|
||||
case "stem":
|
||||
return convertStem(node);
|
||||
case "table":
|
||||
return convertTable((Table) node);
|
||||
case "thematic_break":
|
||||
return convertThematicBreak(node);
|
||||
case "verse":
|
||||
return convertVerse((StructuralNode) node);
|
||||
case "video":
|
||||
return convertVideo(node);
|
||||
case "toc":
|
||||
return convertToc(node);
|
||||
case "pass":
|
||||
return convertPass(node);
|
||||
case "audio":
|
||||
return convertAudio(node);
|
||||
// didn't exist on html converter
|
||||
case "list":
|
||||
return convertList((List) node);
|
||||
case "list_item":
|
||||
return convertListItem((ListItem) node);
|
||||
default:
|
||||
logger.debug("Don't know how to convert transform: [" + transform + "] Node: " + node);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String convertEmbedded(Document node) {
|
||||
logger.debug("convertEmbedded");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendId(node, sb);
|
||||
if (StringUtils.isNotBlank(node.getDoctitle())) {
|
||||
sb.append(repeat(node.getLevel() + 1,DOCUMENT_TITLE)).append(' ').append(StringEscapeUtils.unescapeHtml4(node.getDoctitle())).append(LINE_SEPARATOR);
|
||||
}
|
||||
Map<String, Object> attributes = node.getAttributes();
|
||||
appendAuthors(sb, attributes);
|
||||
appendRevisionDetails(sb, attributes);
|
||||
appendDocumentAttributes(sb, attributes);
|
||||
appendTrailingNewLine(sb);
|
||||
appendChildBlocks(node, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void appendAuthors(StringBuilder sb, Map<String, Object> attributes) {
|
||||
Long authorCount = (Long) attributes.getOrDefault("authorcount", 0L);
|
||||
if (authorCount == 1) {
|
||||
String author = getAuthorDetail(attributes, "author", "email");
|
||||
if (StringUtils.isNotBlank(author)) {
|
||||
sb.append(author).append(LINE_SEPARATOR);
|
||||
}
|
||||
} else if (authorCount > 1) {
|
||||
String authors = LongStream.rangeClosed(1, authorCount)
|
||||
.mapToObj(i -> getAuthorDetail(attributes, "author_" + i, "email_" + i))
|
||||
.collect(Collectors.joining("; "));
|
||||
|
||||
if (StringUtils.isNotBlank(authors)) {
|
||||
sb.append(authors).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendDocumentAttributes(StringBuilder sb, Map<String, Object> attributes) {
|
||||
attributes.forEach((k, v) -> {
|
||||
if (!attributeToExclude.contains(k) && v != null && !v.toString().isEmpty())
|
||||
sb.append(COLON).append(k).append(COLON).append(" ").append(v).append(LINE_SEPARATOR);
|
||||
});
|
||||
}
|
||||
|
||||
private void appendRevisionDetails(StringBuilder sb, Map<String, Object> attributes) {
|
||||
String revDetails = Stream.of(attributes.get("revnumber"), attributes.get("revdate")).filter(Objects::nonNull)
|
||||
.filter(o -> !o.toString().isEmpty()).map(Object::toString)
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
if (!revDetails.isEmpty()) {
|
||||
sb.append("v").append(revDetails).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private String getAuthorDetail(Map<String, Object> attributes, String authorKey, String emailKey) {
|
||||
String author = attributes.getOrDefault(authorKey, "").toString();
|
||||
String email = attributes.getOrDefault(emailKey, "").toString();
|
||||
if (StringUtils.isNotBlank(email)) {
|
||||
email = " <" + email + ">";
|
||||
}
|
||||
|
||||
return (author + email).trim();
|
||||
}
|
||||
|
||||
private String convertInlineAnchor(PhraseNode node) {
|
||||
logger.debug("convertInlineAnchor");
|
||||
String type = node.getType();
|
||||
switch (type) {
|
||||
case "xref": {
|
||||
String attrs;
|
||||
String text;
|
||||
String path = Optional.ofNullable(node.getAttributes().get("path")).orElse("").toString();
|
||||
if (StringUtils.isNotBlank(path)) {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(node.getRole())) {
|
||||
list.add(" class=\"#{node.role}\"");
|
||||
}
|
||||
append_link_constraint_attrs(node, list);
|
||||
attrs = String.join(" ", list);
|
||||
text = StringUtils.isNotBlank(node.getText()) ? node.getText() : path;
|
||||
} else {
|
||||
attrs = StringUtils.isNotBlank(node.getRole()) ? " class=\"" + node.getRole() + "\"" : "";
|
||||
text = node.getText();
|
||||
if (StringUtils.isNotBlank(text)) {
|
||||
text = node.getAttributes().get("refid").toString();
|
||||
}
|
||||
}
|
||||
return node.getTarget() + ATTRIBUTES_BEGIN + text + (StringUtils.isNotBlank(attrs) ? "," + attrs : "") + ATTRIBUTES_END;
|
||||
}
|
||||
case "ref":
|
||||
return node.getId();
|
||||
case "link": {
|
||||
ArrayList<String> attrs = new ArrayList<>();
|
||||
String target = node.getTarget();
|
||||
String includePrefix = !StringUtils.startsWithAny(target, supportedUrlSchemes) ? "include::" : "";
|
||||
|
||||
String text = node.getText();
|
||||
if (!target.equals(text)) {
|
||||
attrs.add(text);
|
||||
}
|
||||
if (StringUtils.isNotBlank(node.getId())) {
|
||||
attrs.add("id=\"" + node.getId() + "\"");
|
||||
}
|
||||
String role = node.getRole();
|
||||
if (StringUtils.isNotBlank(role) && !role.equals("bare")) {
|
||||
attrs.add("role=\"" + role + "\"");
|
||||
}
|
||||
String title = node.getAttribute("title", "").toString();
|
||||
if (StringUtils.isNotBlank(title)) {
|
||||
attrs.add("title=\"" + title + "\"");
|
||||
}
|
||||
return includePrefix + target + ATTRIBUTES_BEGIN + String.join(",", attrs) + ATTRIBUTES_END;
|
||||
}
|
||||
case "bibref":
|
||||
return node.getId() + ATTRIBUTES_BEGIN + (StringUtils.isNotBlank(node.getReftext()) ? node.getReftext() : node.getId()) + ATTRIBUTES_END;
|
||||
default:
|
||||
logger.warn("unknown anchor type: " + node.getType());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String convertAdmonition(Block node) {
|
||||
logger.debug("convertAdmonition");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
java.util.List<StructuralNode> blocks = node.getBlocks();
|
||||
if (blocks.isEmpty()) {
|
||||
sb.append(node.getStyle()).append(": ").append(node.getSource());
|
||||
} else {
|
||||
appendTitle(node, sb);
|
||||
sb.append(ATTRIBUTES_BEGIN).append(node.getStyle()).append(ATTRIBUTES_END)
|
||||
.append(LINE_SEPARATOR).append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
|
||||
appendChildBlocks(node, sb);
|
||||
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertInlineQuoted(PhraseNode node) {
|
||||
logger.debug("convertInlineQuoted");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String marker = "";
|
||||
switch (node.getType()) {
|
||||
case "monospaced":
|
||||
marker = "`";
|
||||
break;
|
||||
case "emphasis":
|
||||
marker = "_";
|
||||
break;
|
||||
case "strong":
|
||||
marker = "*";
|
||||
break;
|
||||
case "superscript":
|
||||
marker = "^";
|
||||
break;
|
||||
case "subscript":
|
||||
marker = "~";
|
||||
break;
|
||||
case "double":
|
||||
case "single":
|
||||
case "mark":
|
||||
case "asciimath":
|
||||
case "latexmath":
|
||||
marker = "";
|
||||
break;
|
||||
}
|
||||
sb.append(marker).append(node.getText()).append(marker);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertFloatingTitle(StructuralNode node) {
|
||||
logger.debug("convertFloatingTitle");
|
||||
return ATTRIBUTES_BEGIN + "discrete" + ATTRIBUTES_END + LINE_SEPARATOR +
|
||||
repeat(node.getLevel() + 1, TITLE) + ' ' + node.getTitle() + LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
private String convertExample(Block node) {
|
||||
logger.debug("convertExample");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
|
||||
appendChildBlocks(node, sb);
|
||||
sb.append(DELIMITER_EXAMPLE).append(LINE_SEPARATOR);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertInlineButton(ContentNode node) {
|
||||
logger.debug("convertInlineButton: name" + node.getNodeName());
|
||||
return "convertInlineButton";
|
||||
}
|
||||
|
||||
private String convertInlineCallout(ContentNode node) {
|
||||
logger.debug("convertInlineCallout: name" + node.getNodeName());
|
||||
return "convertInlineCallout";
|
||||
}
|
||||
|
||||
private String convertInlineBreak(ContentNode node) {
|
||||
logger.debug("convertInlineBreak: name" + node.getNodeName());
|
||||
return "convertInlineBreak";
|
||||
}
|
||||
|
||||
private String convertInlineFootnote(ContentNode node) {
|
||||
logger.debug("convertInlineFootnote: name" + node.getNodeName());
|
||||
return "convertInlineFootnote";
|
||||
}
|
||||
|
||||
private String convertInlineImage(PhraseNode node) {
|
||||
logger.debug("convertInlineImage");
|
||||
if (node.getType().equals("icon")) {
|
||||
return (new IconNode(node)).toAsciiDocContent();
|
||||
} else {
|
||||
return (new BlockImageNode(node)).toAsciiDocContent();
|
||||
}
|
||||
}
|
||||
|
||||
private String convertInlineIndexTerm(ContentNode node) {
|
||||
logger.debug("convertInlineIndexTerm: name" + node.getNodeName());
|
||||
return "convertInlineIndexTerm";
|
||||
}
|
||||
|
||||
private String convertInlineKbd(ContentNode node) {
|
||||
logger.debug("convertInlineKbd: name" + node.getNodeName());
|
||||
return "convertInlineKbd";
|
||||
}
|
||||
|
||||
private String convertInlineMenu(ContentNode node) {
|
||||
logger.debug("convertInlineMenu: name" + node.getNodeName());
|
||||
return "convertInlineMenu";
|
||||
}
|
||||
|
||||
private String convertOpen(StructuralNode node) {
|
||||
logger.debug("convertOpen");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
switch (node.getStyle()) {
|
||||
case "abstract":
|
||||
sb.append(ATTRIBUTES_BEGIN).append("abstract").append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
break;
|
||||
case "open":
|
||||
sb.append(DELIMITER_OPEN_BLOCK).append(LINE_SEPARATOR);
|
||||
}
|
||||
sb.append(Optional.ofNullable(((Block) node).getSource()).orElse(""));
|
||||
appendChildBlocks(node, sb);
|
||||
|
||||
if ("open".equals(node.getStyle())) {
|
||||
sb.append(DELIMITER_OPEN_BLOCK).append(LINE_SEPARATOR);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertPageBreak(ContentNode node) {
|
||||
logger.debug("convertPageBreak: name" + node.getNodeName());
|
||||
return DELIMITER_PAGE_BREAK + LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
private String convertQuote(StructuralNode node) {
|
||||
logger.debug("convertQuote");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(ATTRIBUTES_BEGIN);
|
||||
java.util.List<String> attrs = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(node.getStyle())) {
|
||||
attrs.add("quote");
|
||||
}
|
||||
appendAttributeTo(node, attrs, "attribution");
|
||||
appendAttributeTo(node, attrs, "citetitle");
|
||||
sb.append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
java.util.List<StructuralNode> blocks = node.getBlocks();
|
||||
if (!blocks.isEmpty()) {
|
||||
sb.append("____").append(LINE_SEPARATOR);
|
||||
appendChildBlocks(node, sb);
|
||||
sb.append("____").append(LINE_SEPARATOR);
|
||||
} else {
|
||||
sb.append(((Block) node).getSource());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertSidebar(StructuralNode node) {
|
||||
logger.debug("convertSidebar");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
appendChildBlocks(node, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertStem(ContentNode node) {
|
||||
logger.debug("convertStem: name" + node.getNodeName());
|
||||
return "convertStem";
|
||||
}
|
||||
|
||||
private String convertThematicBreak(ContentNode node) {
|
||||
logger.debug("convertThematicBreak: name" + node.getNodeName());
|
||||
return DELIMITER_THEMATIC_BREAK + LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
private String convertVerse(StructuralNode node) {
|
||||
logger.debug("convertVerse");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(ATTRIBUTES_BEGIN);
|
||||
java.util.List<String> attrs = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(node.getStyle())) {
|
||||
attrs.add("verse");
|
||||
}
|
||||
appendAttributeTo(node, attrs, "attribution");
|
||||
appendAttributeTo(node, attrs, "citetitle");
|
||||
sb.append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
String source = ((Block) node).getSource();
|
||||
boolean matches = emptyLineOrStartWith.matcher(source).find();
|
||||
if (matches) {
|
||||
sb.append(DELIMITER_VERSE).append(LINE_SEPARATOR);
|
||||
}
|
||||
sb.append(source);
|
||||
if (matches) {
|
||||
sb.append(LINE_SEPARATOR).append(DELIMITER_VERSE);
|
||||
}
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertVideo(ContentNode node) {
|
||||
logger.debug("convertVideo: name" + node.getNodeName());
|
||||
return "convertVideo";
|
||||
}
|
||||
|
||||
private String convertToc(ContentNode node) {
|
||||
logger.debug("convertToc: name" + node.getNodeName());
|
||||
return "convertToc";
|
||||
}
|
||||
|
||||
private String convertPass(ContentNode node) {
|
||||
logger.debug("convertPass: name" + node.getNodeName());
|
||||
return "convertPass";
|
||||
}
|
||||
|
||||
private String convertAudio(ContentNode node) {
|
||||
logger.debug("convertAudio: name" + node.getNodeName());
|
||||
return "convertAudio";
|
||||
}
|
||||
|
||||
private String convertCell(Cell node) {
|
||||
logger.debug("convertCell");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String source = node.getSource();
|
||||
if (StringUtils.isNotBlank(source)) {
|
||||
sb.append(source);
|
||||
}
|
||||
Document innerDocument = node.getInnerDocument();
|
||||
if (null != innerDocument) {
|
||||
appendChildBlocks(innerDocument, sb, false);
|
||||
}
|
||||
return sb.toString().replaceAll(LINE_SEPARATOR + LINE_SEPARATOR + "+", LINE_SEPARATOR + LINE_SEPARATOR);
|
||||
}
|
||||
|
||||
private String convertRow(Row node, java.util.List<TableCellStyle> columnStyles, String delimiterTableCell) {
|
||||
logger.debug("convertRow");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
node.getCells().forEach(cell -> {
|
||||
boolean addNewLine = false;
|
||||
int colspan = cell.getColspan();
|
||||
if (colspan != 0) {
|
||||
addNewLine = true;
|
||||
sb.append(colspan).append('+');
|
||||
}
|
||||
int rowspan = cell.getRowspan();
|
||||
if (rowspan != 0) {
|
||||
addNewLine = true;
|
||||
sb.append('.').append(rowspan).append('+');
|
||||
}
|
||||
int index = cell.getColumn().getColumnNumber() - 1;
|
||||
TableCellStyle tableCellStyle = (columnStyles.size() > index) ? columnStyles.get(index) : null;
|
||||
|
||||
boolean hAlignmentAdded = false;
|
||||
TableCellHorizontalAlignment hAlignment = TableCellHorizontalAlignment.fromName(cell.getHorizontalAlignment().name());
|
||||
if ((null != hAlignment) && (null == tableCellStyle || hAlignment != tableCellStyle.horizontalAlignment)) {
|
||||
hAlignmentAdded = true;
|
||||
addNewLine = true;
|
||||
sb.append(hAlignment.getDelimiter());
|
||||
}
|
||||
|
||||
TableCellVerticalAlignment vAlignment = TableCellVerticalAlignment.fromName(cell.getVerticalAlignment().name());
|
||||
if ((null != vAlignment) && (null == tableCellStyle || hAlignmentAdded || vAlignment != tableCellStyle.verticalAlignment)) {
|
||||
addNewLine = true;
|
||||
sb.append(vAlignment.getDelimiter());
|
||||
}
|
||||
|
||||
Style style = Style.fromName(cell.getAttribute("style", "").toString());
|
||||
if (null != style && (null == tableCellStyle || style != tableCellStyle.style)) {
|
||||
addNewLine = true;
|
||||
sb.append(style.getShortHand());
|
||||
}
|
||||
sb.append(delimiterTableCell).append(convertCell(cell));
|
||||
if (addNewLine) {
|
||||
sb.append(LINE_SEPARATOR);
|
||||
} else {
|
||||
sb.append(' ');
|
||||
}
|
||||
});
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertTable(Table node) {
|
||||
logger.debug("convertTable");
|
||||
java.util.List<TableCellStyle> columnStyles = new ArrayList<>();
|
||||
for (String col : node.getAttribute("cols", "").toString().split(",")) {
|
||||
Matcher matcher = tableColumnsStylePattern.matcher(col);
|
||||
if (matcher.find()) {
|
||||
int multiplier = 1;
|
||||
String multiplierGroup = matcher.group(2);
|
||||
if (null != multiplierGroup) {
|
||||
try {
|
||||
multiplier = Integer.parseInt(multiplierGroup);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
int width = 0;
|
||||
try {
|
||||
width = Integer.parseInt(matcher.group(5));
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
TableCellStyle tableCellStyle = new TableCellStyle(
|
||||
TableCellHorizontalAlignment.fromString(matcher.group(3)),
|
||||
TableCellVerticalAlignment.fromString(matcher.group(4)),
|
||||
Style.fromString(matcher.group(6)),
|
||||
width
|
||||
);
|
||||
for (int i = 0; i < multiplier; i++) {
|
||||
columnStyles.add(tableCellStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(new TableNode(node).toAsciiDocContent());
|
||||
boolean innerTable = isInnerTable(node);
|
||||
String tableDelimiter = innerTable ? DELIMITER_INNER_TABLE : DELIMITER_TABLE;
|
||||
String cellDelimiter = innerTable ? DELIMITER_INNER_TABLE_CELL : DELIMITER_TABLE_CELL;
|
||||
sb.append(tableDelimiter).append(LINE_SEPARATOR);
|
||||
appendRows(node.getHeader(), sb, columnStyles, cellDelimiter);
|
||||
appendRows(node.getBody(), sb, columnStyles, cellDelimiter);
|
||||
appendRows(node.getFooter(), sb, columnStyles, cellDelimiter);
|
||||
sb.append(tableDelimiter).append(LINE_SEPARATOR);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private boolean isInnerTable(ContentNode node) {
|
||||
if(null != node) {
|
||||
ContentNode parent = node.getParent();
|
||||
if (null != parent) {
|
||||
return parent instanceof Table || isInnerTable(parent);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void appendRows(java.util.List<Row> rows, StringBuilder sb, java.util.List<TableCellStyle> columnStyles, String delimiterTableCell) {
|
||||
rows.forEach(row -> sb.append(convertRow(row, columnStyles, delimiterTableCell)).append(LINE_SEPARATOR));
|
||||
}
|
||||
|
||||
private String convertDescriptionList(DescriptionList node) {
|
||||
logger.debug("convertDescriptionList");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
appendTitle(node, sb);
|
||||
String style = Optional.ofNullable(node.getStyle()).orElse("");
|
||||
switch (style) {
|
||||
case STYLE_HORIZONTAL:
|
||||
sb.append(ATTRIBUTES_BEGIN).append(STYLE_HORIZONTAL).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
node.getItems().forEach(item -> sb.append(convertDescriptionListEntry(item, node.getLevel(), false)));
|
||||
break;
|
||||
case STYLE_Q_AND_A:
|
||||
sb.append(ATTRIBUTES_BEGIN).append(STYLE_Q_AND_A).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
default:
|
||||
node.getItems().forEach(item -> sb.append(convertDescriptionListEntry(item, node.getLevel(), true)));
|
||||
break;
|
||||
}
|
||||
appendTrailingNewLine(sb);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertDescriptionListEntry(DescriptionListEntry node, int level, Boolean descriptionOnNewLine) {
|
||||
logger.debug("convertDescriptionListEntry");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String delimiter = repeat(level + 1, MARKER_D_LIST_ITEM);
|
||||
String entryTerms = node.getTerms().stream()
|
||||
.map(term -> Optional.ofNullable(term.getSource()).orElse(""))
|
||||
.collect(Collectors.joining(delimiter + LINE_SEPARATOR, "", delimiter));
|
||||
sb.append(entryTerms);
|
||||
ListItem description = node.getDescription();
|
||||
if (null != description) {
|
||||
if (descriptionOnNewLine) {
|
||||
sb.append(LINE_SEPARATOR);
|
||||
}
|
||||
String desc = Optional.ofNullable(description.getSource()).orElse("");
|
||||
if (StringUtils.isNotBlank(desc)) {
|
||||
sb.append(desc).append(LINE_SEPARATOR);
|
||||
}
|
||||
appendChildBlocks(description, sb);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertListing(Block node) {
|
||||
logger.debug("convertListing");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
if (STYLE_SOURCE.equals(node.getStyle())) {
|
||||
sb.append(new SourceNode(node).toAsciiDocContent());
|
||||
} else {
|
||||
sb.append(new BlockListingNode(node).toAsciiDocContent());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertUList(List node) {
|
||||
logger.debug("convertUList");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendStyle(node, sb);
|
||||
appendTitle(node, sb);
|
||||
appendChildBlocks(node, sb);
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertOList(List node) {
|
||||
logger.debug("convertOList");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
java.util.List<String> attrs = new ArrayList<>();
|
||||
String start = node.getAttribute("start", "").toString();
|
||||
if (StringUtils.isNotBlank(start)) {
|
||||
attrs.add("start=" + start);
|
||||
}
|
||||
if (node.isOption("reversed")) {
|
||||
attrs.add("%reversed");
|
||||
}
|
||||
if (!attrs.isEmpty()) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
appendTitle(node, sb);
|
||||
appendChildBlocks(node, sb);
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertCoList(List node) {
|
||||
logger.debug("convertCoList");
|
||||
StringBuilder result = new StringBuilder();
|
||||
appendChildBlocks(node, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String convertListItem(ListItem node) {
|
||||
logger.debug("convertListItem");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
String marker = Optional.ofNullable(node.getMarker()).orElse(repeat(node.getLevel(), MARKER_LIST_ITEM));
|
||||
|
||||
String coids = node.getAttribute("coids", "").toString();
|
||||
Matcher matcher = coListItemIdPattern.matcher(coids);
|
||||
if (matcher.find()) {
|
||||
marker = marker.replaceAll("\\d+", matcher.group(1));
|
||||
}
|
||||
|
||||
sb.append(marker).append(" ");
|
||||
|
||||
if (node.hasAttribute("checkbox")) {
|
||||
sb.append('[');
|
||||
if (node.hasAttribute("checked")) {
|
||||
sb.append('x');
|
||||
} else {
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(']').append(' ');
|
||||
}
|
||||
|
||||
sb.append(Optional.ofNullable(node.getSource()).orElse(""));
|
||||
appendTrailingNewLine(sb);
|
||||
appendChildBlocks(node, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertList(List node) {
|
||||
logger.debug("convertList");
|
||||
return node.getContent().toString();
|
||||
}
|
||||
|
||||
private String convertPreamble(StructuralNode node) {
|
||||
logger.debug("convertPreamble");
|
||||
return node.getContent().toString();
|
||||
}
|
||||
|
||||
private String convertImage(StructuralNode node) {
|
||||
logger.debug("convertImage");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
appendRoles(node, sb);
|
||||
sb.append(new BlockImageNode(node).toAsciiDocContent());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertLiteral(StructuralNode node) {
|
||||
logger.debug("convertLiteral");
|
||||
return ATTRIBUTES_BEGIN + node.getContext() + ATTRIBUTES_END + LINE_SEPARATOR +
|
||||
StringEscapeUtils.unescapeHtml4(node.getContent().toString()) + LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
private String convertParagraph(StructuralNode node) {
|
||||
logger.debug("convertParagraph");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendTitle(node, sb);
|
||||
sb.append(new ParagraphAttributes(node).toAsciiDocContent());
|
||||
appendSource((Block) node, sb);
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String convertSection(Section node) {
|
||||
logger.debug("convertSection");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendId(node, sb);
|
||||
sb.append(new DelimitedBlockNode(node).toAsciiDocContent()).append(StringUtils.repeat(TITLE, node.getLevel() + 1))
|
||||
.append(" ").append(StringEscapeUtils.unescapeHtml4(node.getTitle())).append(LINE_SEPARATOR);
|
||||
appendChildBlocks(node, sb);
|
||||
appendTrailingNewLine(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void append_link_constraint_attrs(ContentNode node, java.util.List<String> attrs) {
|
||||
String rel = node.getAttribute("nofollow-option").toString();
|
||||
String window = node.getAttributes().get("window").toString();
|
||||
if (StringUtils.isNotBlank(window)) {
|
||||
attrs.add("target = \"#{window}\"");
|
||||
if (window.equals("_blank") || (node.getAttributes().containsKey("option-noopener"))) {
|
||||
if (StringUtils.isNotBlank(rel)) {
|
||||
attrs.add("rel = \"" + rel + "noopener\"");
|
||||
} else {
|
||||
attrs.add(" rel=\"noopener\"");
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.isNotBlank(rel)) {
|
||||
attrs.add("rel = " + rel + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
private String repeat(int count, String with) {
|
||||
return new String(new char[count]).replace("\0", with);
|
||||
}
|
||||
|
||||
private void appendChildBlocks(StructuralNode parentNode, StringBuilder sb) {
|
||||
appendChildBlocks(parentNode, sb, true);
|
||||
}
|
||||
|
||||
private void appendChildBlocks(StructuralNode parentNode, StringBuilder sb, boolean addTrailingLineSeparator) {
|
||||
final boolean isParentAListItem = parentNode instanceof ListItem || parentNode instanceof DescriptionListEntry;
|
||||
parentNode.getBlocks().forEach(childNode -> {
|
||||
String childNodeValue = childNode.convert();
|
||||
if (StringUtils.isNotBlank(childNodeValue)) {
|
||||
if (isParentAListItem && (sb.toString().contains("+" + LINE_SEPARATOR) || !(childNode instanceof List || childNode instanceof DescriptionList))) {
|
||||
sb.append('+').append(LINE_SEPARATOR);
|
||||
}
|
||||
sb.append(childNodeValue);
|
||||
if (addTrailingLineSeparator && !StringUtils.endsWith(childNodeValue, LINE_SEPARATOR)) {
|
||||
sb.append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void appendTrailingNewLine(StringBuilder sb) {
|
||||
if (!sb.toString().endsWith(LINE_SEPARATOR + LINE_SEPARATOR)) {
|
||||
sb.append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendId(StructuralNode node, StringBuilder sb) {
|
||||
String id = node.getId();
|
||||
if (StringUtils.isNotBlank(id)) {
|
||||
sb.append("[[").append(id).append("]]").append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendSource(Block node, StringBuilder sb) {
|
||||
String source = node.getSource();
|
||||
if (StringUtils.isNotBlank(source)) {
|
||||
sb.append(source).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendTitle(StructuralNode node, StringBuilder sb) {
|
||||
String title = node.getTitle();
|
||||
if (StringUtils.isNotBlank(title)) {
|
||||
sb.append(".").append(StringEscapeUtils.unescapeHtml4(title)).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendStyle(StructuralNode node, StringBuilder sb) {
|
||||
String style = node.getStyle();
|
||||
if (StringUtils.isNotBlank(style)) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(style).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendRoles(StructuralNode node, StringBuilder sb) {
|
||||
java.util.List<String> roles = node.getRoles();
|
||||
if (!roles.isEmpty()) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(".").append(String.join(".", roles))
|
||||
.append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendAttributeTo(StructuralNode node, java.util.List<String> attrs, String name) {
|
||||
String attribution = node.getAttribute(name, "").toString();
|
||||
if (StringUtils.isNotBlank(attribution)) {
|
||||
attrs.add(attribution);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Block;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BlockImpl extends StructuralNodeImpl implements Block {
|
||||
|
||||
private List<String> lines;
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context) {
|
||||
this(parent, context, "");
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Object content) {
|
||||
this(parent, context, new HashMap<>(), content);
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes) {
|
||||
this(parent, context, attributes, "");
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, Object content) {
|
||||
this(parent, context, attributes, new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>());
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs) {
|
||||
this(parent, context, attributes, roles, content, blocks, calculateLevel(parent), contentModel, subs);
|
||||
}
|
||||
|
||||
public BlockImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level, String contentModel, List<String> subs) {
|
||||
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
this.lines = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public List<String> lines() {
|
||||
return getLines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLines(List<String> lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String source() {
|
||||
return getSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSource() {
|
||||
return String.join("\n", lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(String source) {
|
||||
setLines(Arrays.asList(source.split("\n")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Cell;
|
||||
import org.asciidoctor.ast.Column;
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CellImpl extends ContentNodeImpl implements Cell {
|
||||
|
||||
private final int colspan;
|
||||
private final int rowspan;
|
||||
private String text;
|
||||
private String style;
|
||||
private Document innerDocument;
|
||||
|
||||
public CellImpl(Column parent, String text) {
|
||||
this(parent, "table_cell", new HashMap<>(), new ArrayList<>(), 0, 0);
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public CellImpl(Column parent, Document innerDocument) {
|
||||
this(parent, "table_cell", new HashMap<>(), new ArrayList<>(), 0, 0);
|
||||
this.innerDocument = innerDocument;
|
||||
}
|
||||
|
||||
public CellImpl(Column parent, String context, Map<String, Object> attributes, List<String> roles, int colspan, int rowspan) {
|
||||
super(parent, context, attributes, roles);
|
||||
this.colspan = colspan;
|
||||
this.rowspan = rowspan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Column getColumn() {
|
||||
return (Column) getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColspan() {
|
||||
return colspan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowspan() {
|
||||
return rowspan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSource() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(String source) {
|
||||
this.text = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getContent() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStyle(String style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table.HorizontalAlignment getHorizontalAlignment() {
|
||||
return Table.HorizontalAlignment.valueOf(((String) getAttribute("halign", "left")).toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHorizontalAlignment(Table.HorizontalAlignment halign) {
|
||||
setAttribute("halign", halign.name().toLowerCase(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table.VerticalAlignment getVerticalAlignment() {
|
||||
return Table.VerticalAlignment.valueOf(((String) getAttribute("valign", "top")).toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVerticalAlignment(Table.VerticalAlignment valign) {
|
||||
setAttribute("valign", valign.name().toLowerCase(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document getInnerDocument() {
|
||||
return innerDocument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInnerDocument(Document document) {
|
||||
this.innerDocument = document;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Column;
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ColumnImpl extends ContentNodeImpl implements Column {
|
||||
|
||||
private String style;
|
||||
private Number columnNumber = -1;
|
||||
private Number width = 0;
|
||||
|
||||
public ColumnImpl(Table parent) {
|
||||
this(parent, "table_column", new HashMap<>(), new ArrayList<>());
|
||||
}
|
||||
|
||||
public ColumnImpl(Table parent, String context, Map<String, Object> attributes, List<String> roles) {
|
||||
super(parent, context, attributes, roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStyle(String style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table getTable() {
|
||||
return (Table) getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnNumber() {
|
||||
return columnNumber.intValue();
|
||||
}
|
||||
|
||||
public void setColumnNumber(Integer columnNumber) {
|
||||
setAttribute("colnumber", columnNumber, true);
|
||||
this.columnNumber = columnNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWidth(int width) {
|
||||
setAttribute("width", width, true);
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table.HorizontalAlignment getHorizontalAlignment() {
|
||||
return Table.HorizontalAlignment.valueOf(((String) getAttribute("halign", "left")).toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHorizontalAlignment(Table.HorizontalAlignment halign) {
|
||||
setAttribute("halign", halign.name().toLowerCase(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table.VerticalAlignment getVerticalAlignment() {
|
||||
return Table.VerticalAlignment.valueOf(((String) getAttribute("valign", "top")).toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVerticalAlignment(Table.VerticalAlignment valign) {
|
||||
setAttribute("valign", valign.name().toLowerCase(), true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
import org.asciidoctor.ast.Document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("SuspiciousMethodCalls")
|
||||
public abstract class ContentNodeImpl implements ContentNode {
|
||||
|
||||
private String id;
|
||||
private final String context;
|
||||
private final Map<String, Object> attributes;
|
||||
private final List<String> roles;
|
||||
private final ContentNode parent;
|
||||
|
||||
public ContentNodeImpl(ContentNode parent, String context) {
|
||||
this(parent, context, new HashMap<>(), new ArrayList<>());
|
||||
}
|
||||
|
||||
public ContentNodeImpl(ContentNode parent, String context, Map<String, Object> attributes, List<String> roles) {
|
||||
this.parent = parent;
|
||||
this.context = context;
|
||||
this.attributes = attributes;
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String id() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id.toLowerCase().replaceAll("\\s+", "_");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String context() {
|
||||
return getContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public ContentNode parent() {
|
||||
return getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentNode getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Document document() {
|
||||
return getDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document getDocument() {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNodeName() {
|
||||
return getContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object getAttr(Object name, Object defaultValue, boolean inherit) {
|
||||
return getAttribute(name, defaultValue, inherit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object getAttr(Object name, Object defaultValue) {
|
||||
return getAttribute(name, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object getAttr(Object name) {
|
||||
return getAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(Object name, Object defaultValue, boolean inherit) {
|
||||
return getAttribute(name, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(Object name, Object defaultValue) {
|
||||
return attributes.getOrDefault(name, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(Object name) {
|
||||
return attributes.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isAttr(Object name, Object expected, boolean inherit) {
|
||||
return isAttribute(name, expected, inherit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isAttr(Object name, Object expected) {
|
||||
return isAttribute(name, expected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAttribute(Object name, Object expected, boolean inherit) {
|
||||
return isAttribute(name, expected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAttribute(Object name, Object expected) {
|
||||
try {
|
||||
if (attributes.containsKey(name)) {
|
||||
return attributes.get(name).equals(expected);
|
||||
} else return false;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean hasAttr(Object name) {
|
||||
return hasAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean hasAttr(Object name, boolean inherited) {
|
||||
return hasAttribute(name, inherited);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAttribute(Object name) {
|
||||
return attributes.containsKey(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAttribute(Object name, boolean inherited) {
|
||||
return hasAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean setAttr(Object name, Object value, boolean overwrite) {
|
||||
return setAttribute(name, value, overwrite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setAttribute(Object name, Object value, boolean overwrite) {
|
||||
return setAttribute((String)name, value, overwrite);
|
||||
}
|
||||
|
||||
public boolean setAttribute(String name, Object value, boolean overwrite) {
|
||||
try {
|
||||
if (overwrite) {
|
||||
attributes.put(name, value);
|
||||
} else {
|
||||
attributes.putIfAbsent(name, value);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Object removeAttribute(String name){
|
||||
return attributes.remove(name);
|
||||
}
|
||||
|
||||
public boolean removeAttribute(String name, Object value){
|
||||
return attributes.remove(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOption(Object name) {
|
||||
try {
|
||||
Object o = attributes.get(name + "-option");
|
||||
return null != o && o.toString().equals("");
|
||||
}catch (Exception ignored){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setOption(String name){
|
||||
return setAttribute(name + "-option", "", true);
|
||||
}
|
||||
|
||||
public Object removeOption(String name){
|
||||
return removeAttribute(name + "-option");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRole() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRole() {
|
||||
return String.join(",", roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String role() {
|
||||
return getRole();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(String role) {
|
||||
return roles.contains(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRole(String role) {
|
||||
roles.add(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRole(String role) {
|
||||
roles.remove(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReftext() {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReftext() {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String iconUri(String name) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mediaUri(String target) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String imageUri(String targetImage) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String imageUri(String targetImage, String assetDirKey) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readAsset(String path, Map<Object, Object> opts) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String normalizeWebPath(String path, String start, boolean preserveUriTarget) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Cursor;
|
||||
|
||||
public class CursorImpl implements Cursor {
|
||||
|
||||
private int lineno;
|
||||
|
||||
public CursorImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineNumber() {
|
||||
return lineno;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDir() {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFile() {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.DescriptionListEntry;
|
||||
import org.asciidoctor.ast.ListItem;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DescriptionListEntryImpl extends StructuralNodeImpl implements DescriptionListEntry {
|
||||
|
||||
private final List<ListItem> terms;
|
||||
private ListItem description;
|
||||
|
||||
public DescriptionListEntryImpl(StructuralNode parent) {
|
||||
this(parent, new ArrayList<>());
|
||||
}
|
||||
|
||||
public DescriptionListEntryImpl(StructuralNode parent, List<ListItem> terms) {
|
||||
this(parent, terms, null);
|
||||
}
|
||||
|
||||
public DescriptionListEntryImpl(StructuralNode parent, List<ListItem> terms, ListItem description) {
|
||||
this(parent, null, terms, description);
|
||||
}
|
||||
|
||||
public DescriptionListEntryImpl(StructuralNode parent, Object content, List<ListItem> terms, ListItem description) {
|
||||
this(parent, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>(), terms, description);
|
||||
}
|
||||
|
||||
public DescriptionListEntryImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs,
|
||||
List<ListItem> terms, ListItem description) {
|
||||
this(parent, attributes, roles, content, blocks, null != parent ? parent.getLevel() : 1, contentModel, subs, terms, description);
|
||||
}
|
||||
|
||||
public DescriptionListEntryImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level, String contentModel,
|
||||
List<String> subs, List<ListItem> terms, ListItem description) {
|
||||
super(parent, "dlist_item", attributes, roles, content, blocks, level, contentModel, subs);
|
||||
this.terms = terms;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ListItem> getTerms() {
|
||||
return terms;
|
||||
}
|
||||
|
||||
public boolean addTerm(ListItem term) {
|
||||
return terms.add(term);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListItem getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(final ListItem description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.DescriptionList;
|
||||
import org.asciidoctor.ast.DescriptionListEntry;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DescriptionListImpl extends StructuralNodeImpl implements DescriptionList {
|
||||
|
||||
public static final String CONTEXT = "dlist";
|
||||
private List<DescriptionListEntry> items;
|
||||
|
||||
public DescriptionListImpl(StructuralNode parent) {
|
||||
this(parent, new ArrayList<>());
|
||||
}
|
||||
|
||||
public DescriptionListImpl(StructuralNode parent, List<DescriptionListEntry> items) {
|
||||
this(parent, null, items);
|
||||
}
|
||||
|
||||
public DescriptionListImpl(StructuralNode parent, Object content, List<DescriptionListEntry> items) {
|
||||
this(parent, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>(), items);
|
||||
}
|
||||
|
||||
public DescriptionListImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel,
|
||||
List<String> subs, List<DescriptionListEntry> items) {
|
||||
this(parent, attributes, roles, content, blocks, calculateLevel(parent), contentModel, subs, items);
|
||||
}
|
||||
|
||||
public DescriptionListImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level,
|
||||
String contentModel, List<String> subs, List<DescriptionListEntry> items) {
|
||||
super(parent, CONTEXT, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DescriptionListEntry> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<DescriptionListEntry> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public void addEntry(DescriptionListEntry entry) {
|
||||
this.items.add(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItems() {
|
||||
return !items.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String render() {
|
||||
return convert();
|
||||
}
|
||||
|
||||
protected static Integer calculateLevel(StructuralNode parent) {
|
||||
int level = 1;
|
||||
if (parent instanceof DescriptionList)
|
||||
level = parent.getLevel() + 1;
|
||||
return level;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Document;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
import org.asciidoctor.ast.Title;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DocumentImpl extends StructuralNodeImpl implements Document {
|
||||
|
||||
public DocumentImpl() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public DocumentImpl(StructuralNode parent) {
|
||||
this(parent, "document", "");
|
||||
}
|
||||
|
||||
public DocumentImpl(StructuralNode parent, String context, Object content) {
|
||||
this(parent, context, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>());
|
||||
}
|
||||
|
||||
public DocumentImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel,
|
||||
List<String> subs) {
|
||||
this(parent, context, attributes, roles, content, blocks, null != parent ? parent.getLevel() + 1 : 0, contentModel, subs);
|
||||
}
|
||||
|
||||
public DocumentImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level, String contentModel,
|
||||
List<String> subs) {
|
||||
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBasebackend(String backend) {
|
||||
return isAttribute("basebackend", backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean basebackend(String backend) {
|
||||
return isBasebackend(backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Object> getOptions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Title getStructuredDoctitle() {
|
||||
return (Title) getOptions().get("doctitle");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDoctitle() {
|
||||
return getTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String doctitle() {
|
||||
return getDoctitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAndIncrementCounter(String name) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAndIncrementCounter(String name, int initialValue) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSourcemap() {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourcemap(boolean state) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.List;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ListImpl extends StructuralNodeImpl implements List {
|
||||
|
||||
private final java.util.List<StructuralNode> items;
|
||||
|
||||
public ListImpl(StructuralNode parent, String context) {
|
||||
this(parent, context, new ArrayList<>());
|
||||
}
|
||||
|
||||
|
||||
public ListImpl(StructuralNode parent, String context, java.util.List<StructuralNode> items) {
|
||||
this(parent, context, null, items);
|
||||
}
|
||||
|
||||
public ListImpl(StructuralNode parent, String context, Object content, java.util.List<StructuralNode> items) {
|
||||
this(parent, context, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>(), items);
|
||||
}
|
||||
|
||||
public ListImpl(StructuralNode parent, String context, Map<String, Object> attributes, java.util.List<String> roles,
|
||||
Object content, java.util.List<StructuralNode> blocks,
|
||||
String contentModel, java.util.List<String> subs, java.util.List<StructuralNode> items) {
|
||||
this(parent, context, attributes, roles, content, blocks, null != parent ? parent.getLevel() + 1 : 0, contentModel, subs, items);
|
||||
}
|
||||
|
||||
public ListImpl(StructuralNode parent, String context, Map<String, Object> attributes, java.util.List<String> roles,
|
||||
Object content, java.util.List<StructuralNode> blocks,
|
||||
Integer level, String contentModel, java.util.List<String> subs, java.util.List<StructuralNode> items) {
|
||||
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.List<StructuralNode> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItems() {
|
||||
return !items.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String render() {
|
||||
return convert();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.ListItem;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ListItemImpl extends StructuralNodeImpl implements ListItem {
|
||||
|
||||
private final String marker;
|
||||
private String text;
|
||||
|
||||
public ListItemImpl(StructuralNode parent, String text) {
|
||||
this(parent, "list_item", null, "*", text);
|
||||
}
|
||||
|
||||
public ListItemImpl(StructuralNode parent, String context, Object content, String marker, String text) {
|
||||
this(parent, context, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>(), marker, text);
|
||||
}
|
||||
|
||||
public ListItemImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel,
|
||||
List<String> subs, String marker, String text) {
|
||||
this(parent, context, attributes, roles, content, blocks, null != parent ? parent.getLevel() : 1, contentModel, subs, marker, text);
|
||||
}
|
||||
|
||||
public ListItemImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level,
|
||||
String contentModel, List<String> subs, String marker, String text) {
|
||||
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
this.marker = marker;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMarker() {
|
||||
return marker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSource() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(String source) {
|
||||
this.text = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasText() {
|
||||
return StringUtils.isNotBlank(text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ParagraphBlockImpl extends BlockImpl {
|
||||
|
||||
public static final String CONTEXT = "paragraph";
|
||||
|
||||
public ParagraphBlockImpl(StructuralNode parent) {
|
||||
super(parent, CONTEXT);
|
||||
}
|
||||
|
||||
public ParagraphBlockImpl(StructuralNode parent, Object content) {
|
||||
super(parent, CONTEXT, content);
|
||||
}
|
||||
|
||||
public ParagraphBlockImpl(StructuralNode parent, Map<String, Object> attributes) {
|
||||
super(parent, CONTEXT, attributes);
|
||||
}
|
||||
|
||||
public ParagraphBlockImpl(StructuralNode parent, Map<String, Object> attributes, Object content) {
|
||||
super(parent, CONTEXT, attributes, content);
|
||||
}
|
||||
|
||||
public ParagraphBlockImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs) {
|
||||
super(parent, CONTEXT, attributes, roles, content, blocks, contentModel, subs);
|
||||
}
|
||||
|
||||
public ParagraphBlockImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level, String contentModel,
|
||||
List<String> subs) {
|
||||
super(parent, CONTEXT, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import io.github.swagger2markup.adoc.AsciidocConverter;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
import org.asciidoctor.ast.PhraseNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PhraseNodeImpl extends ContentNodeImpl implements PhraseNode {
|
||||
|
||||
private final String type;
|
||||
private final String text;
|
||||
private final String target;
|
||||
private final AsciidocConverter converter = new AsciidocConverter(AsciidocConverter.NAME, new HashMap<>());
|
||||
|
||||
public PhraseNodeImpl(ContentNode parent, String context, Map<String, Object> attributes, List<String> roles, String type, String text, String target) {
|
||||
super(parent, context, attributes, roles);
|
||||
this.type = type;
|
||||
this.text = text;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String render() {
|
||||
return convert();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convert() {
|
||||
return converter.convert(this, null, new HashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Cell;
|
||||
import org.asciidoctor.ast.Row;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RowImpl implements Row {
|
||||
|
||||
private final List<Cell> cells;
|
||||
|
||||
public RowImpl(List<Cell> cells) {
|
||||
this.cells = cells;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cell> getCells() {
|
||||
return cells;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Section;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SectionImpl extends StructuralNodeImpl implements Section {
|
||||
|
||||
private final Integer index;
|
||||
private final Integer number;
|
||||
private final String numeral;
|
||||
private final String sectionName;
|
||||
private final boolean special;
|
||||
private final boolean numbered;
|
||||
|
||||
public SectionImpl(StructuralNode parent) {
|
||||
this(parent, new HashMap<>());
|
||||
}
|
||||
|
||||
public SectionImpl(StructuralNode parent, Map<String, Object> attributes) {
|
||||
this(parent, "section", null, "");
|
||||
}
|
||||
|
||||
|
||||
public SectionImpl(StructuralNode parent, String context, Object content, String sectionName) {
|
||||
this(parent, context, content, null, null, "", sectionName, false, false);
|
||||
}
|
||||
|
||||
public SectionImpl(StructuralNode parent, String context, Object content, Integer index, Integer number, String numeral,
|
||||
String sectionName, boolean special, boolean numbered) {
|
||||
this(parent, context, new HashMap<>(), new ArrayList<>(), content, new ArrayList<>(),
|
||||
"", new ArrayList<>(), index, number, numeral, sectionName, special, numbered);
|
||||
}
|
||||
|
||||
public SectionImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs,
|
||||
Integer index, Integer number, String numeral, String sectionName, boolean special, boolean numbered) {
|
||||
this(parent, context, attributes, roles, content, blocks, calculateLevel(parent), contentModel, subs, index, number, numeral, sectionName, special, numbered);
|
||||
}
|
||||
|
||||
public SectionImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level, String contentModel, List<String> subs,
|
||||
Integer index, Integer number, String numeral, String sectionName, boolean special, boolean numbered) {
|
||||
super(parent, context, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
this.index = index;
|
||||
this.number = number;
|
||||
this.numeral = numeral;
|
||||
this.sectionName = sectionName;
|
||||
this.special = special;
|
||||
this.numbered = numbered;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public int index() {
|
||||
return getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public int number() {
|
||||
return getNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNumeral() {
|
||||
return numeral;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String sectname() {
|
||||
return getSectionName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSectionName() {
|
||||
return sectionName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean special() {
|
||||
return isSpecial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecial() {
|
||||
return special;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean numbered() {
|
||||
return isNumbered();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNumbered() {
|
||||
return numbered;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import io.github.swagger2markup.adoc.AsciidocConverter;
|
||||
import org.asciidoctor.ast.Cursor;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class StructuralNodeImpl extends ContentNodeImpl implements StructuralNode {
|
||||
|
||||
private String title;
|
||||
private String caption;
|
||||
private String style;
|
||||
private final Object content;
|
||||
private final List<StructuralNode> blocks;
|
||||
private Integer level;
|
||||
private final String contentModel;
|
||||
private List<String> subs;
|
||||
private final AsciidocConverter converter = new AsciidocConverter(AsciidocConverter.NAME, new HashMap<>());
|
||||
|
||||
public StructuralNodeImpl(StructuralNode parent, String context) {
|
||||
this(parent, context, new HashMap<>());
|
||||
}
|
||||
|
||||
public StructuralNodeImpl(StructuralNode parent, String context, Map<String, Object> attributes) {
|
||||
this(parent, context, attributes, null);
|
||||
}
|
||||
|
||||
public StructuralNodeImpl(StructuralNode parent, String context, Object content) {
|
||||
this(parent, context, new HashMap<>(), content);
|
||||
}
|
||||
|
||||
public StructuralNodeImpl(StructuralNode parent, String context, Map<String, Object> attributes, Object content) {
|
||||
this(parent, context, attributes, new ArrayList<>(), content, new ArrayList<>(), "", new ArrayList<>());
|
||||
}
|
||||
|
||||
public StructuralNodeImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, String contentModel, List<String> subs) {
|
||||
this(parent, context, attributes, roles, content, blocks, calculateLevel(parent), contentModel, subs);
|
||||
}
|
||||
|
||||
public StructuralNodeImpl(StructuralNode parent, String context, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level, String contentModel, List<String> subs) {
|
||||
super(parent, context, attributes, roles);
|
||||
this.content = content;
|
||||
this.blocks = blocks;
|
||||
this.level = level;
|
||||
this.contentModel = contentModel;
|
||||
this.subs = subs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String title() {
|
||||
return getTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCaption() {
|
||||
return caption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCaption(String caption) {
|
||||
this.caption = caption;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String style() {
|
||||
return getStyle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStyle(String style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public List<StructuralNode> blocks() {
|
||||
return getBlocks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructuralNode> getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(StructuralNode block) {
|
||||
blocks.add(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object content() {
|
||||
return getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convert() {
|
||||
return converter.convert(this, null, new HashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor getSourceLocation() {
|
||||
return new CursorImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentModel() {
|
||||
return contentModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSubstitutions() {
|
||||
return subs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSubstitutionEnabled(String substitution) {
|
||||
return subs.contains(substitution);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSubstitution(String substitution) {
|
||||
subs.remove(substitution);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSubstitution(String substitution) {
|
||||
subs.add(substitution);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prependSubstitution(String substitution) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubstitutions(String... substitutions) {
|
||||
subs = Arrays.asList(substitutions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructuralNode> findBy(Map<Object, Object> selector) {
|
||||
throw new UnsupportedOperationException("Not implemented, yet");
|
||||
}
|
||||
|
||||
protected static Integer calculateLevel(StructuralNode parent) {
|
||||
return null != parent ? parent.getLevel() + 1 : 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class TableImpl extends StructuralNodeImpl implements Table {
|
||||
public static final String OPTION_UNBREAKABLE = "unbreakable";
|
||||
public static final String OPTION_BREAKABLE = "breakable";
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
public static final String CONTEXT = "table";
|
||||
private static final String FRAME_ATTR = "frame";
|
||||
private static final String GRID_ATTR = "grid";
|
||||
private RowList headerRows;
|
||||
private RowList bodyRows;
|
||||
private RowList footerRows;
|
||||
|
||||
private List<Column> columns = new ArrayList<>();
|
||||
|
||||
public TableImpl(StructuralNode parent) {
|
||||
this(parent, new HashMap<>(), new ArrayList<>());
|
||||
}
|
||||
|
||||
public TableImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles) {
|
||||
this(parent, attributes, roles, calculateLevel(parent));
|
||||
}
|
||||
|
||||
public TableImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles, Integer level) {
|
||||
this(parent, attributes, roles, null, new ArrayList<>(), level, "", new ArrayList<>());
|
||||
}
|
||||
|
||||
public TableImpl(StructuralNode parent, Map<String, Object> attributes, List<String> roles,
|
||||
Object content, List<StructuralNode> blocks, Integer level, String contentModel, List<String> subs) {
|
||||
super(parent, CONTEXT, attributes, roles, content, blocks, level, contentModel, subs);
|
||||
this.headerRows = new RowList(new ArrayList<>());
|
||||
this.bodyRows = new RowList(new ArrayList<>());
|
||||
this.footerRows = new RowList(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHeaderOption() {
|
||||
return isOption("header");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFrame() {
|
||||
return (String) getAttribute(FRAME_ATTR, "all");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFrame(String frame) {
|
||||
setAttribute(FRAME_ATTR, frame, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrid() {
|
||||
return (String) getAttribute(GRID_ATTR, "all");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGrid(String grid) {
|
||||
setAttribute(GRID_ATTR, grid, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Column> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Row> getHeader() {
|
||||
return headerRows;
|
||||
}
|
||||
|
||||
public void setHeaderRow(Row row) {
|
||||
headerRows.clear();
|
||||
headerRows.add(row);
|
||||
scanRowForColumns(row);
|
||||
}
|
||||
|
||||
public void setHeaderRow(List<Cell> cells) {
|
||||
setHeaderRow(new RowImpl(cells));
|
||||
}
|
||||
|
||||
public void setHeaderRow(String... documentContents) {
|
||||
headerRows.clear();
|
||||
headerRows.add(generateRow(documentContents));
|
||||
}
|
||||
|
||||
public RowImpl generateRow(Document... innerDocs) {
|
||||
List<Cell> cells = new ArrayList<>();
|
||||
for (int i = 0; i < innerDocs.length; i++) {
|
||||
|
||||
Column column = null;
|
||||
try {
|
||||
column = columns.get(i);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (null == column) {
|
||||
ColumnImpl newColumn = new ColumnImpl(this);
|
||||
newColumn.setColumnNumber(i + 1);
|
||||
column = newColumn;
|
||||
addColumnAt(column, i);
|
||||
}
|
||||
cells.add(new CellImpl(column, innerDocs[i]));
|
||||
|
||||
}
|
||||
return new RowImpl(cells);
|
||||
}
|
||||
|
||||
public RowImpl generateRow(String... documentContents) {
|
||||
Document[] documents = Arrays.stream(documentContents).map(documentContent -> {
|
||||
Document innerDoc = new DocumentImpl();
|
||||
Block paragraph = new ParagraphBlockImpl(innerDoc);
|
||||
paragraph.setSource(documentContent);
|
||||
innerDoc.append(paragraph);
|
||||
return innerDoc;
|
||||
}).toArray(Document[]::new);
|
||||
return generateRow(documents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Row> getBody() {
|
||||
return bodyRows;
|
||||
}
|
||||
|
||||
public void setBodyRows(List<Row> rows) {
|
||||
bodyRows.clear();
|
||||
bodyRows.addAll(rows);
|
||||
bodyRows.forEach(this::scanRowForColumns);
|
||||
}
|
||||
|
||||
public void addRow(Row row) {
|
||||
bodyRows.add(row);
|
||||
scanRowForColumns(row);
|
||||
}
|
||||
|
||||
public void addRow(List<Cell> cells) {
|
||||
bodyRows.add(new RowImpl(cells));
|
||||
}
|
||||
|
||||
public RowImpl addRow(Document... documentContents) {
|
||||
RowImpl row = generateRow(documentContents);
|
||||
bodyRows.add(row);
|
||||
return row;
|
||||
}
|
||||
|
||||
public RowImpl addRow(String... documentContents) {
|
||||
RowImpl row = generateRow(documentContents);
|
||||
bodyRows.add(row);
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Row> getFooter() {
|
||||
return footerRows;
|
||||
}
|
||||
|
||||
public void setFooterRow(Row row) {
|
||||
footerRows.clear();
|
||||
footerRows.add(row);
|
||||
scanRowForColumns(row);
|
||||
}
|
||||
|
||||
public void setFooterRow(String... documentContents) {
|
||||
footerRows.clear();
|
||||
footerRows.add(generateRow(documentContents));
|
||||
}
|
||||
|
||||
private void scanRowForColumns(Row row) {
|
||||
row.getCells().forEach(cell -> {
|
||||
Column column = cell.getColumn();
|
||||
int i = column.getColumnNumber() - 1;
|
||||
addColumnAt(column, i);
|
||||
});
|
||||
}
|
||||
|
||||
private void addColumnAt(Column column, int i) {
|
||||
if (columns.size() >= i) {
|
||||
columns.add(i, column);
|
||||
} else {
|
||||
while (columns.size() < i) {
|
||||
columns.add(columns.size(), null);
|
||||
}
|
||||
columns.add(column);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFooterRow(List<Cell> cells) {
|
||||
setFooterRow(new RowImpl(cells));
|
||||
}
|
||||
|
||||
class RowList extends AbstractList<Row> {
|
||||
|
||||
private final List<Row> rubyArray;
|
||||
|
||||
private RowList(List<Row> rubyArray) {
|
||||
this.rubyArray = rubyArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return rubyArray.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return rubyArray.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return rubyArray.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Row row) {
|
||||
boolean changed = false;
|
||||
try {
|
||||
changed = rubyArray.add(row);
|
||||
setAttribute("rowcount", size(), true);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Couldn't add row", e);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
if (!(o instanceof RowImpl)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
boolean changed = rubyArray.remove(o);
|
||||
setAttribute("rowcount", size(), true);
|
||||
return changed;
|
||||
} catch (Exception e) {
|
||||
logger.debug("Couldn't add row", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
rubyArray.clear();
|
||||
setAttribute("rowcount", size(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Row get(int index) {
|
||||
return rubyArray.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Row set(int index, Row element) {
|
||||
Row oldRow = get(index);
|
||||
rubyArray.set(index, element);
|
||||
return oldRow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, Row element) {
|
||||
rubyArray.add(index, element);
|
||||
setAttribute("rowcount", size(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Row remove(int index) {
|
||||
Row removed = rubyArray.remove(index);
|
||||
setAttribute("rowcount", size(), true);
|
||||
return removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
if (!(o instanceof RowImpl)) {
|
||||
return -1;
|
||||
}
|
||||
return rubyArray.indexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
if (!(o instanceof RowImpl)) {
|
||||
return -1;
|
||||
}
|
||||
return rubyArray.lastIndexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Integer calculateLevel(StructuralNode parent) {
|
||||
int level = 1;
|
||||
if (parent instanceof Table)
|
||||
level = parent.getLevel() + 1;
|
||||
return level;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package io.github.swagger2markup.adoc.ast.impl;
|
||||
|
||||
import org.asciidoctor.ast.Title;
|
||||
|
||||
public class TitleImpl implements Title {
|
||||
|
||||
private final String main;
|
||||
private final String subtitle;
|
||||
|
||||
public TitleImpl(String main, String subtitle) {
|
||||
this.main = main;
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMain() {
|
||||
return main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSubtitle() {
|
||||
return subtitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCombined() {
|
||||
return main + ": " + subtitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSanitized() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
|
||||
public class BlockImageNode extends NodeAttributes {
|
||||
|
||||
final private String target;
|
||||
|
||||
public BlockImageNode(ContentNode node) {
|
||||
super(node.getAttributes());
|
||||
target = pop("target").replaceAll("\\s", "{sp}");
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPositionalAttributes() {
|
||||
String attr1 = pop("1", "alt");
|
||||
if (StringUtils.isNotBlank(attr1)) {
|
||||
attrs.add(attr1);
|
||||
}
|
||||
|
||||
String attr2 = pop("2", "width");
|
||||
if (StringUtils.isNotBlank(attr2)) {
|
||||
attrs.add(attr2);
|
||||
}
|
||||
|
||||
String attr3 = pop("3", "height");
|
||||
if (StringUtils.isNotBlank(attr3)) {
|
||||
attrs.add(attr3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void processAttributes() {
|
||||
attributes.forEach((k, v) -> {
|
||||
if (!k.equals("role") && null != v) {
|
||||
attrs.add(k + "=" + v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processAsciiDocContent() {
|
||||
return "image::" + target + '[' + String.join(",", attrs) + ']';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.asciidoctor.ast.Block;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
|
||||
|
||||
public class BlockListingNode extends ParagraphAttributes {
|
||||
|
||||
final private Block node;
|
||||
|
||||
public BlockListingNode(Block node) {
|
||||
super(node);
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processAsciiDocContent() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
attrsToString(sb, attrs);
|
||||
sb.append(LINE_SEPARATOR).append(DELIMITER_BLOCK).append(LINE_SEPARATOR).append(node.getSource()).append(LINE_SEPARATOR).append(DELIMITER_BLOCK).append(LINE_SEPARATOR);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void attrsToString(StringBuilder sb, List<String> list) {
|
||||
if (!list.isEmpty()) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", list)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
|
||||
|
||||
public class DelimitedBlockNode extends ParagraphAttributes {
|
||||
|
||||
public DelimitedBlockNode(StructuralNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPositionalAttributes() {
|
||||
String source = pop("1", "style");
|
||||
StringBuilder options = new StringBuilder();
|
||||
List<String> toRemove = new ArrayList<>();
|
||||
attributes.forEach((k, v) -> {
|
||||
if (k.endsWith(OPTION_SUFFIX)) {
|
||||
toRemove.add(k);
|
||||
options.append('%').append(k.replace(OPTION_SUFFIX, ""));
|
||||
}
|
||||
});
|
||||
toRemove.forEach(attributes::remove);
|
||||
source += options.toString();
|
||||
|
||||
if (StringUtils.isNotBlank(source)) {
|
||||
attrs.add(source);
|
||||
}
|
||||
super.processPositionalAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processAsciiDocContent() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (!attrs.isEmpty()) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
public class Delimiters {
|
||||
public static final String ATTRIBUTES_BEGIN = "[";
|
||||
public static final String ATTRIBUTES_END = "]";
|
||||
public static final String COLON = ":";
|
||||
public static final String DELIMITER_BLOCK = "----";
|
||||
public static final String DELIMITER_EXAMPLE = "====";
|
||||
public static final String DELIMITER_INNER_TABLE_CELL = "!";
|
||||
public static final String DELIMITER_INNER_TABLE = "!===";
|
||||
public static final String DELIMITER_PAGE_BREAK = "<<<";
|
||||
public static final String DELIMITER_OPEN_BLOCK = "--";
|
||||
public static final String DELIMITER_SIDEBAR = "****";
|
||||
public static final String DELIMITER_TABLE = "|===";
|
||||
public static final String DELIMITER_TABLE_CELL = "|";
|
||||
public static final String DELIMITER_THEMATIC_BREAK = "'''";
|
||||
public static final String DELIMITER_VERSE = "____";
|
||||
public static final String DOCUMENT_TITLE = "=";
|
||||
public static final String LINE_SEPARATOR = "\n";
|
||||
public static final String MARKER_LIST_ITEM = "*";
|
||||
public static final String MARKER_D_LIST_ITEM = ":";
|
||||
public static final String STYLE_HORIZONTAL = "horizontal";
|
||||
public static final String STYLE_Q_AND_A = "qanda";
|
||||
public static final String STYLE_SOURCE = "source";
|
||||
public static final String TITLE = "=";
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
|
||||
public class IconNode extends NodeAttributes {
|
||||
|
||||
final private String alt;
|
||||
|
||||
public IconNode(ContentNode node) {
|
||||
super(node.getAttributes());
|
||||
alt = pop("alt", "default-alt");
|
||||
}
|
||||
|
||||
public String getAlt() {
|
||||
return alt;
|
||||
}
|
||||
|
||||
@Override
|
||||
void processPositionalAttributes() {
|
||||
String attr1 = pop("1", "size");
|
||||
if (StringUtils.isNotBlank(attr1)) {
|
||||
attrs.add(attr1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void processAttributes() {
|
||||
attributes.forEach((k, v) -> {
|
||||
attrs.add(k + "=" + v);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
String processAsciiDocContent() {
|
||||
return "icon:" + alt + '[' + String.join(",", attrs) + ']';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
|
||||
|
||||
abstract class NodeAttributes {
|
||||
public static final String TITLE = "title";
|
||||
|
||||
final Map<String, Object> attributes;
|
||||
List<String> attrs = new ArrayList<>();
|
||||
|
||||
NodeAttributes(Map<String, Object> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public String pop(String... keys) {
|
||||
AtomicReference<String> value = new AtomicReference<>("");
|
||||
Stream.of(keys).forEach(key -> {
|
||||
try {
|
||||
String tmpValue = attributes.remove(key).toString();
|
||||
if (null != tmpValue && !tmpValue.isEmpty() && value.get().isEmpty()) {
|
||||
value.set(tmpValue);
|
||||
}
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
});
|
||||
return value.get();
|
||||
}
|
||||
|
||||
String pop(String key) {
|
||||
try {
|
||||
String value = attributes.remove(key).toString();
|
||||
if (null == value) {
|
||||
value = "";
|
||||
}
|
||||
return value;
|
||||
} catch (NullPointerException ignored) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
final public String toAsciiDocContent() {
|
||||
processPositionalAttributes();
|
||||
processAttributes();
|
||||
return processAsciiDocContent();
|
||||
}
|
||||
|
||||
abstract void processPositionalAttributes();
|
||||
|
||||
abstract void processAttributes();
|
||||
|
||||
String processAsciiDocContent() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (!attrs.isEmpty()) {
|
||||
sb.append(ATTRIBUTES_BEGIN).append(String.join(",", attrs)).append(ATTRIBUTES_END).append(LINE_SEPARATOR);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.StructuralNode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ParagraphAttributes extends NodeAttributes {
|
||||
|
||||
public static final String OPTION_SUFFIX = "-option";
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public ParagraphAttributes(StructuralNode node) {
|
||||
super(node.getAttributes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPositionalAttributes() {
|
||||
String attr1 = pop("1", "style");
|
||||
if (StringUtils.isNotBlank(attr1)) {
|
||||
attrs.add(attr1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void processAttributes() {
|
||||
String id = pop("id");
|
||||
if (StringUtils.isNotBlank(id)) {
|
||||
id = "#" + id;
|
||||
}
|
||||
String roles = String.join(".", pop("role").split(" "));
|
||||
if (StringUtils.isNotBlank(roles)) {
|
||||
roles = "." + roles;
|
||||
}
|
||||
StringBuilder options = new StringBuilder();
|
||||
List<String> namedAttributes = new ArrayList<>();
|
||||
|
||||
attributes.forEach((k, v) -> {
|
||||
if (k.equals(TITLE)) {
|
||||
logger.debug("Skipping attribute: " + TITLE);
|
||||
} else if (k.endsWith(OPTION_SUFFIX)) {
|
||||
options.append('%').append(k.replace(OPTION_SUFFIX, ""));
|
||||
} else if (null != v) {
|
||||
if(v.toString().contains(" ") || v.toString().contains(",")) {
|
||||
namedAttributes.add(k + "=\"" + v +"\"");
|
||||
} else {
|
||||
namedAttributes.add(k + "=" + v);
|
||||
}
|
||||
} else {
|
||||
logger.warn("Don't know how to handle key: " + k);
|
||||
}
|
||||
});
|
||||
|
||||
String nonNamedAttributes = id + roles + options.toString();
|
||||
if (StringUtils.isNotBlank(nonNamedAttributes)) {
|
||||
attrs.add(nonNamedAttributes);
|
||||
}
|
||||
attrs.addAll(namedAttributes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.asciidoctor.ast.Block;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.swagger2markup.adoc.converter.internal.Delimiters.*;
|
||||
|
||||
public class SourceNode extends BlockListingNode {
|
||||
|
||||
private List<String> sourceAttrs = new ArrayList<>();
|
||||
private final Block node;
|
||||
|
||||
public SourceNode(Block node) {
|
||||
super(node);
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPositionalAttributes() {
|
||||
String source = pop("1", "style");
|
||||
String language = pop("2", "language");
|
||||
StringBuilder options = new StringBuilder();
|
||||
List<String> toRemove = new ArrayList<>();
|
||||
attributes.forEach((k, v) -> {
|
||||
if (k.endsWith(OPTION_SUFFIX)) {
|
||||
toRemove.add(k);
|
||||
options.append('%').append(k.replace(OPTION_SUFFIX, ""));
|
||||
}
|
||||
});
|
||||
toRemove.forEach(attributes::remove);
|
||||
source += options.toString();
|
||||
|
||||
if (StringUtils.isNotBlank(source)) {
|
||||
sourceAttrs.add(source);
|
||||
}
|
||||
if (StringUtils.isNotBlank(language)) {
|
||||
sourceAttrs.add(language);
|
||||
}
|
||||
super.processPositionalAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processAsciiDocContent() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
attrsToString(sb, attrs);
|
||||
attrsToString(sb, sourceAttrs);
|
||||
sb.append(LINE_SEPARATOR).append(DELIMITER_BLOCK).append(LINE_SEPARATOR).append(node.getSource()).append(LINE_SEPARATOR).append(DELIMITER_BLOCK).append(LINE_SEPARATOR);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public enum Style {
|
||||
ASCIIDOC("a"), EMPHASIS("e"), HEADER("h"), LITERAL("l"), MONOSPACED("m"), NONE("d"), STRONG("s"), VERSE("v");
|
||||
|
||||
String shortHand;
|
||||
|
||||
Style(String h) {
|
||||
this.shortHand = h;
|
||||
}
|
||||
|
||||
public static Style fromString(String text) {
|
||||
if(StringUtils.isNotBlank(text)) {
|
||||
for (Style s : Style.values()) {
|
||||
if (s.shortHand.equalsIgnoreCase(text)) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Style fromName(String text) {
|
||||
if(StringUtils.isNotBlank(text)) {
|
||||
return valueOf(text.toUpperCase());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getShortHand() {
|
||||
return shortHand;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public enum TableCellHorizontalAlignment {
|
||||
LEFT("<"), CENTER("^"), RIGHT(">");
|
||||
|
||||
String delimiter;
|
||||
|
||||
TableCellHorizontalAlignment(String s) {
|
||||
this.delimiter = s;
|
||||
}
|
||||
|
||||
public static TableCellHorizontalAlignment fromString(String text) {
|
||||
if(StringUtils.isNotBlank(text)) {
|
||||
for (TableCellHorizontalAlignment a : TableCellHorizontalAlignment.values()) {
|
||||
if (a.delimiter.equalsIgnoreCase(text)) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static TableCellHorizontalAlignment fromName(String text) {
|
||||
if(StringUtils.isNotBlank(text)) {
|
||||
return valueOf(text.toUpperCase());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getDelimiter() {
|
||||
return delimiter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
public class TableCellStyle {
|
||||
public final TableCellHorizontalAlignment horizontalAlignment;
|
||||
public final TableCellVerticalAlignment verticalAlignment;
|
||||
public final Style style;
|
||||
public final int width;
|
||||
|
||||
public TableCellStyle(TableCellHorizontalAlignment horizontalAlignment, TableCellVerticalAlignment verticalAlignment, Style style, int width) {
|
||||
this.horizontalAlignment = horizontalAlignment;
|
||||
this.verticalAlignment = verticalAlignment;
|
||||
this.style = style;
|
||||
this.width = width;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public enum TableCellVerticalAlignment {
|
||||
TOP(".<"), MIDDLE(".^"), BOTTOM(".>");
|
||||
|
||||
String delimiter;
|
||||
|
||||
TableCellVerticalAlignment(String s) {
|
||||
this.delimiter = s;
|
||||
}
|
||||
|
||||
public static TableCellVerticalAlignment fromString(String text) {
|
||||
if(StringUtils.isNotBlank(text)) {
|
||||
for (TableCellVerticalAlignment a : TableCellVerticalAlignment.values()) {
|
||||
if (a.delimiter.equalsIgnoreCase(text)) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static TableCellVerticalAlignment fromName(String text) {
|
||||
if(StringUtils.isNotBlank(text)) {
|
||||
return valueOf(text.toUpperCase());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getDelimiter() {
|
||||
return delimiter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.github.swagger2markup.adoc.converter.internal;
|
||||
|
||||
import org.asciidoctor.ast.Table;
|
||||
|
||||
public class TableNode extends DelimitedBlockNode {
|
||||
public TableNode(Table table) {
|
||||
super(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
void processAttributes() {
|
||||
pop("colcount", "rowcount", "tablepcwidth");
|
||||
super.processAttributes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
io.github.swagger2markup.adoc.AsciiDocConverterRegistry
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.github.swagger2markup.adoc;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.asciidoctor.Asciidoctor;
|
||||
import org.asciidoctor.OptionsBuilder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class AsciidocConverterTest {
|
||||
|
||||
private Asciidoctor asciidoctor = Asciidoctor.Factory.create();
|
||||
|
||||
@Parameterized.Parameters(name = "Run {index}: file={0}")
|
||||
public static Iterable<?> data() {
|
||||
return Arrays.asList(
|
||||
"simple.adoc",
|
||||
"arrows-and-boxes-example.ad",
|
||||
"brokeninclude.asciidoc",
|
||||
"changeattribute.adoc",
|
||||
"chronicles-example.adoc",
|
||||
"document-with-arrays.adoc"
|
||||
);
|
||||
}
|
||||
|
||||
@Parameterized.Parameter
|
||||
public String asciidocFile;
|
||||
|
||||
|
||||
@Test
|
||||
public void converts_asciidoc_to_asciidoc() throws IOException {
|
||||
//Given
|
||||
String originalAsciiDoc = IOUtils.toString(getClass().getResourceAsStream("/asciidoc/original/" + asciidocFile), StandardCharsets.UTF_8);
|
||||
String expectedAsciiDoc = IOUtils.toString(getClass().getResourceAsStream("/asciidoc/expected/" + asciidocFile), StandardCharsets.UTF_8);
|
||||
|
||||
//When
|
||||
asciidoctor.javaConverterRegistry().register(AsciidocConverter.class, AsciidocConverter.NAME);
|
||||
String result = asciidoctor.convert(originalAsciiDoc, OptionsBuilder.options().backend(AsciidocConverter.NAME).headerFooter(false).asMap());
|
||||
|
||||
//Then
|
||||
assertEquals(expectedAsciiDoc, result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
= Document Title
|
||||
:tip-caption: Tip
|
||||
:appendix-caption: Appendix
|
||||
:appendix-refsig: Appendix
|
||||
:toc-title: Table of Contents
|
||||
:iconsdir: ./images/icons
|
||||
:warning-caption: Warning
|
||||
:figure-caption: Figure
|
||||
:attribute-missing: skip
|
||||
:section-refsig: Section
|
||||
:toc-placement: auto
|
||||
:important-caption: Important
|
||||
:note-caption: Note
|
||||
:stylesdir: .
|
||||
:untitled-label: Untitled
|
||||
:max-include-depth: 64
|
||||
:caution-caption: Caution
|
||||
:user-home: .
|
||||
:max-attribute-value-size: 4096
|
||||
:safe-mode-level: 20
|
||||
:safe-mode-name: secure
|
||||
:table-caption: Table
|
||||
:part-refsig: Part
|
||||
:authorcount: 0
|
||||
:example-caption: Example
|
||||
:version-label: Version
|
||||
:last-update-label: Last updated
|
||||
:doctype: article
|
||||
:chapter-refsig: Chapter
|
||||
:attribute-undefined: drop-line
|
||||
|
||||
[arrowsAndBoxes]
|
||||
(User) > (Admin)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
= Title
|
||||
:tip-caption: Tip
|
||||
:appendix-caption: Appendix
|
||||
:appendix-refsig: Appendix
|
||||
:toc-title: Table of Contents
|
||||
:iconsdir: ./images/icons
|
||||
:warning-caption: Warning
|
||||
:figure-caption: Figure
|
||||
:attribute-missing: skip
|
||||
:section-refsig: Section
|
||||
:toc-placement: auto
|
||||
:important-caption: Important
|
||||
:note-caption: Note
|
||||
:stylesdir: .
|
||||
:untitled-label: Untitled
|
||||
:max-include-depth: 64
|
||||
:caution-caption: Caution
|
||||
:user-home: .
|
||||
:max-attribute-value-size: 4096
|
||||
:safe-mode-level: 20
|
||||
:safe-mode-name: secure
|
||||
:table-caption: Table
|
||||
:part-refsig: Part
|
||||
:authorcount: 0
|
||||
:example-caption: Example
|
||||
:version-label: Version
|
||||
:last-update-label: Last updated
|
||||
:doctype: article
|
||||
:chapter-refsig: Chapter
|
||||
:attribute-undefined: drop-line
|
||||
|
||||
link:b.adoc[]
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
= Document Title
|
||||
:tip-caption: Tip
|
||||
:appendix-caption: Appendix
|
||||
:appendix-refsig: Appendix
|
||||
:toc-title: Table of Contents
|
||||
:iconsdir: ./images/icons
|
||||
:warning-caption: Warning
|
||||
:figure-caption: Figure
|
||||
:attribute-missing: skip
|
||||
:section-refsig: Section
|
||||
:toc-placement: auto
|
||||
:important-caption: Important
|
||||
:note-caption: Note
|
||||
:stylesdir: .
|
||||
:untitled-label: Untitled
|
||||
:max-include-depth: 64
|
||||
:caution-caption: Caution
|
||||
:user-home: .
|
||||
:max-attribute-value-size: 4096
|
||||
:safe-mode-level: 20
|
||||
:safe-mode-name: secure
|
||||
:table-caption: Table
|
||||
:part-refsig: Part
|
||||
:authorcount: 0
|
||||
:example-caption: Example
|
||||
:version-label: Version
|
||||
:last-update-label: Last updated
|
||||
:doctype: article
|
||||
:chapter-refsig: Chapter
|
||||
:attribute-undefined: drop-line
|
||||
|
||||
sample {content}
|
||||
|
||||
@@ -0,0 +1,535 @@
|
||||
= The Dangerous & _Thrilling_ Documentation Chronicles: Based on True Events
|
||||
Kismet Caméléon; Lazarus het Draeke
|
||||
v1.0, 2014-01-01
|
||||
:tip-caption: Tip
|
||||
:appendix-caption: Appendix
|
||||
:toclevels: 3
|
||||
:appendix-refsig: Appendix
|
||||
:author_2: Lazarus het Draeke
|
||||
:uri-stbernardusabt12: http://www.sintbernardus.be/stbernardusabt12.php?l=en
|
||||
:authorinitials: KC
|
||||
:author_1: Kismet Caméléon
|
||||
:toc-title: Table of Contents
|
||||
:iconsdir: ./images/icons
|
||||
:author: Kismet Caméléon
|
||||
:warning-caption: Warning
|
||||
:figure-caption: Figure
|
||||
:lastname: Caméléon
|
||||
:attribute-missing: skip
|
||||
:lastname_1: Caméléon
|
||||
:section-refsig: Section
|
||||
:uri-devoxx: https://devoxx.be
|
||||
:lastname_2: het Draeke
|
||||
:toc-placement: auto
|
||||
:important-caption: Important
|
||||
:authors: Kismet Caméléon, Lazarus het Draeke
|
||||
:note-caption: Note
|
||||
:firstname: Kismet
|
||||
:stylesdir: .
|
||||
:uri-devoxx-top-talks: https://www.youtube.com/watch?v=1OpAgZvYXLQ&list=PLRsbF2sD7JVq7fv1GZGORShSUIae1ZAPy&index=1
|
||||
:untitled-label: Untitled
|
||||
:description: This story chronicles the inexplicable hazards and vicious beasts a team must conquer and vanquish on their journey to discovering the true power of Open Source.
|
||||
:max-include-depth: 64
|
||||
:caution-caption: Caution
|
||||
:listing-caption: Listing
|
||||
:user-home: .
|
||||
:max-attribute-value-size: 4096
|
||||
:safe-mode-level: 20
|
||||
:safe-mode-name: secure
|
||||
:table-caption: Table
|
||||
:part-refsig: Part
|
||||
:firstname_1: Kismet
|
||||
:authorcount: 2
|
||||
:revdate: 2014-01-01
|
||||
:example-caption: Example
|
||||
:firstname_2: Lazarus
|
||||
:version-label: Version
|
||||
:revnumber: 1.0
|
||||
:last-update-label: Last updated
|
||||
:doctype: book
|
||||
:chapter-refsig: Chapter
|
||||
:uri-wolpertinger: http://en.wikipedia.org/wiki/Wolpertinger
|
||||
:organization: Company Name
|
||||
:authorinitials_1: KC
|
||||
:authorinitials_2: Lh
|
||||
:attribute-undefined: drop-line
|
||||
|
||||
[abstract]
|
||||
{description}
|
||||
[[_its_a_city_under_siege]]
|
||||
== It’s a City Under Siege
|
||||
This journey begins one late Monday afternoon at {uri-devoxx}[((Devoxx))].
|
||||
Our team needs coffee, _desperately_, but none of us dare open the theater doors...
|
||||
|
||||
During the {uri-devoxx-top-talks}[opening university session], a script-happy warlock inadvertently released a legion of Wolpertingers!
|
||||
To leave now would mean *code dismemberment and certain death*.
|
||||
|
||||
Behold -> the horror!
|
||||
|
||||
.Wolpertinger, stuffed
|
||||
[.left.thumb]
|
||||
image::wolpertinger.jpg[Wolpertinger,link=http://en.wikipedia.org/wiki/Wolpertinger,pdfwidth=50%]
|
||||
(((Wolpertinger)))
|
||||
(((Ravenous Beast,Wolpertinger)))
|
||||
You may not be familiar with these {uri-wolpertinger}[ravenous beasts].
|
||||
Trust us, they'll eat your shorts and suck loops from your code.
|
||||
In light of this danger, we've searched high and wide for the security crew's defensive operations manual.
|
||||
We can't find it and the DefOps{empty}footnote:defops[DefOps is a portmanteau of "`defensive`" and "`operations`".] werewolves haven't returned from their rendezvous at Bier Central.
|
||||
They've either eaten each other or fallen victim to the Wolpertingers roaming the streets of ((Antwerp)).
|
||||
Quick, hit kbd:[Ctrl,Alt,Backspace] or select menu:File[Quit] and let's bail out of here!
|
||||
|
||||
WARNING: Working with DefOps{empty}footnote:defops[] werewolves leads to howling and trying to train aggressive regular expressions with Pavlovian reinforcement.
|
||||
_Weak light from the hallway trickled across the theater, chased by a distant scream._
|
||||
|
||||
[[_rendezvous_point]]
|
||||
=== Rendezvous Point
|
||||
Come on, [[bier-central,Bier Central]]_Bier Central_, of course!
|
||||
Did you have to ask?
|
||||
If you beat me there, order me a {uri-stbernardusabt12}[St. Bernardus Abt 12].
|
||||
Here's some €.
|
||||
|
||||
[[ravages]]
|
||||
[#ravages]
|
||||
== The Ravages of Writing
|
||||
Crystalline XML tags relentlessly bombarded the theater.
|
||||
|
||||
.XML tags
|
||||
[source,xml]
|
||||
|
||||
----
|
||||
<author id="1">
|
||||
<personname>
|
||||
<firstname>Lazarus</firstname>
|
||||
<surname>het Draeke</surname>
|
||||
</personname>
|
||||
</author>
|
||||
----
|
||||
Despite the assault, we continued our pursuit to draft a DefOps{empty}footnote:defops[] plan.
|
||||
|
||||
.DefOps Plan
|
||||
====
|
||||
Click btn:[Download Zip] to download the defensive operation plan bundle.
|
||||
|
||||
OMG!
|
||||
Somebody please save us now!
|
||||
I want my mum -- and an extra-large double macchiato, please.
|
||||
|
||||
====
|
||||
Unfortunately, Lazarus and I had both come to the conclusion that we weren't going to get out of this without corrupted hardrives if we didn't locate caffeine within the next few hours.
|
||||
|
||||
[[_a_recipe_for_potion_that_will_ensure_you_win_the_hearts_of_developers]]
|
||||
=== A Recipe for Potion That Will Ensure You Win the Hearts of Developers
|
||||
This potion for a sample document contains the following ingredients, which are listed in a very random, chaotically nested order.
|
||||
|
||||
.Ingredients for Potion that Demystifies Documents
|
||||
* all the headings
|
||||
** syntax highlighted source code
|
||||
*** non-syntax highlighted source code or just a listing block
|
||||
|
||||
* quote block
|
||||
** verse block
|
||||
*** table with some cell formatting
|
||||
**** sequential paragraphs
|
||||
***** admonition blocks, but use them sparingly
|
||||
|
||||
*** bullet list with nesting
|
||||
|
||||
** numbered list with nesting
|
||||
** definition list
|
||||
*** sidebar
|
||||
|
||||
* example block
|
||||
** block image (no inline images)
|
||||
*** inline formatting in a paragraph
|
||||
**** two fresh Burdockian leaves
|
||||
***** They must be harvested by the light of the teal moons.
|
||||
|
||||
Are you square?
|
||||
|
||||
[square]
|
||||
* one
|
||||
* two
|
||||
* three
|
||||
|
||||
What is there to do?
|
||||
|
||||
* [x] Done
|
||||
* [ ] Next
|
||||
* Who's counting?
|
||||
|
||||
[[_searching_for_burdockian]]
|
||||
==== Searching for Burdockian
|
||||
.Steps for finding and preparing Burdockian leaves
|
||||
. Locate dusty botany
|
||||
.. Sneeze
|
||||
... Sneeze some more
|
||||
|
||||
. Find section on Burdockian
|
||||
.. Review its characteristics
|
||||
... Take a picture of the diagram of its leaves
|
||||
.... Don't rip out the picture like a troglodyte
|
||||
..... Don't do it, I'm watching you
|
||||
|
||||
. Put on your hiking boots
|
||||
. Freeze your butt off on the side of a mountain at midnight
|
||||
|
||||
Let's skip a few steps and start counting from 10.
|
||||
|
||||
[start=10]
|
||||
. arabic (10)
|
||||
.. loweralpha (a)
|
||||
... lowerroman (i)
|
||||
... lowerroman (ii)
|
||||
... lowerroman (iii)
|
||||
... lowerroman (iv)
|
||||
.... upperalpha (A)
|
||||
|
||||
. arabic (11)
|
||||
|
||||
It's time for a top 5 list, made using the `reversed` option on an ordered list!
|
||||
|
||||
[%reversed]
|
||||
. Stone Imperial Russian Stout
|
||||
. Pliny the Elder
|
||||
. Chimay Grande Réserve (Blue)
|
||||
. St. Bernardus Abt 12
|
||||
. Westvleteren 12 (XII)
|
||||
|
||||
How about a list with some terms?
|
||||
|
||||
* Fruits
|
||||
Apple::::
|
||||
The round fruit of a tree of the rose family, which typically has thin red or green skin and crisp flesh.
|
||||
Yes, I said _flesh_.
|
||||
Pear::::
|
||||
A yellowish- or brownish-green edible fruit that is typically narrow at the stalk and wider toward the base, with sweet, slightly gritty flesh.
|
||||
More flesh.
|
||||
Mmmmm.
|
||||
|
||||
* Vegetables
|
||||
Carrot::::
|
||||
An orange-colored root eaten as a vegetable.
|
||||
Beware, it's a favorite of the Wolpertinger.
|
||||
|
||||
[[_are_you_still_here]]
|
||||
===== Are You Still Here?
|
||||
.Move, move, move!
|
||||
[CAUTION]
|
||||
====
|
||||
The Wolpertingers can smell your procrastination.
|
||||
It's not their fault you can't find your boots.
|
||||
|
||||
====
|
||||
[[_sigh]]
|
||||
====== Sigh…
|
||||
TIP: Your boots are in your closet.
|
||||
|
||||
[[_dawn_on_the_plateau]]
|
||||
== Dawn on the Plateau
|
||||
Lazarus was hanging from the bottom limb of a Burdockian tree, licking the bark.
|
||||
|
||||
[quote,Mark Tobey]
|
||||
On pavements and the bark of trees I have found whole worlds.
|
||||
"`If there are whole worlds on that bark, he just swallowed them,`" Kizmet replied.
|
||||
|
||||
[verse,The documentation attorneys]
|
||||
____
|
||||
No bark was harmed in the making of this potion.
|
||||
We're not so sure about a couple ants though.
|
||||
|
||||
Nor those worlds...
|
||||
|
||||
Crap, I smell an injunction.
|
||||
____
|
||||
We'd retrieved the leaves, but we'd obviously lost our minds in the process.
|
||||
|
||||
[verse]
|
||||
Roses are +++<span style="color: #FF0000">red</span>+++.
|
||||
Violets are +++<span style="color: #0000FF">blue</span>+++__-ish__.
|
||||
|
||||
[[_words_seasoned_with_power]]
|
||||
== Words Seasoned with Power
|
||||
To _tame_ the [.wild]#wild# wolpertingers, we needed to build a *charm*.
|
||||
But **ul**timate victory could only be won if we divined the *_true name_* of the __war__lock.
|
||||
|
||||
"`What kind of charm?`" Lazarus asked. "`An odoriferous one or a mineral one?`"
|
||||
Kizmet shrugged. "`The note from Olaf's desk says '`wormwood and licorice,`' but these could be normal groceries for werewolves.`"
|
||||
|
||||
"`Well the H~2~O written on the security whiteboard could be part of a shopping list, but I don't think the local bodega also sells e = mc^2^,`" Lazarus replied.
|
||||
|
||||
"`Wait!`" Indigo plucked a small vial from her desk's top drawer and held it toward us.
|
||||
The vial's label read '```e = mc^2^ *_the scent of science_* _smells like a genius_```'.
|
||||
|
||||
[[_can_i_get_some_code]]
|
||||
=== Can I Get Some `Code`?
|
||||
[%hardbreaks]
|
||||
Sure.
|
||||
Have a listing block.
|
||||
|
||||
[listing]
|
||||
|
||||
----
|
||||
This is an example of a listing block.
|
||||
The content inside is rendered as <pre> text.
|
||||
----
|
||||
But I'm not giving you any highlighting shazam just yet.
|
||||
|
||||
.What is a listing block?
|
||||
Like literal blocks, the content in listing blocks is displayed exactly as you entered it.
|
||||
Listing block content is rendered as `<pre>` text.
|
||||
|
||||
The `listing` style is applied to an element, such as a paragraph, by setting the `listing` attribute on that element.
|
||||
|
||||
Let's get our #((highlighting))# on!
|
||||
|
||||
<<<
|
||||
Install Prawn:
|
||||
|
||||
[literal]
|
||||
$ gem install prawn
|
||||
Then create your first PDF document in Ruby!
|
||||
|
||||
.Generates a basic PDF document using Prawn
|
||||
[source,ruby]
|
||||
|
||||
----
|
||||
require 'prawn' # <1>
|
||||
|
||||
Prawn::Document.generate 'output.pdf' do # <3>
|
||||
text 'Hello, World!' # <2>
|
||||
end
|
||||
----
|
||||
<1> Imports Prawn library
|
||||
<3> Adds text “Hello, World!” to first page
|
||||
<2> Writes PDF to [file]_output.pdf_ after executing all statements
|
||||
How about some source code that styles code? So meta!
|
||||
|
||||
[source,css]
|
||||
|
||||
----
|
||||
code {
|
||||
padding: 2px 4px;
|
||||
font-size: 90%;
|
||||
font-weight: normal;
|
||||
color: #c7254e;
|
||||
white-space: nowrap !important;
|
||||
background-color: #f9f2f4;
|
||||
border-radius: 4px;
|
||||
}
|
||||
----
|
||||
Where could we go without some Java(TM)?
|
||||
Naturally, some autosizing is necessary.
|
||||
|
||||
[source%autofit,java]
|
||||
|
||||
----
|
||||
package org.javaee7.cdi.events;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.enterprise.context.SessionScoped;
|
||||
import javax.enterprise.event.Observes;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.*;
|
||||
|
||||
/**
|
||||
* This session-scoped bean receives greeting strings from the event bus
|
||||
* and provides access to the collection of these greetings via a REST API.
|
||||
*
|
||||
* @author The Duke
|
||||
* @since 1.0
|
||||
*/
|
||||
@SessionScoped
|
||||
public class GreetingReceiver implements EventReceiver, Serializable {
|
||||
|
||||
private List<String> greetings;
|
||||
|
||||
@PostConstruct
|
||||
void init() {
|
||||
this.greetings = new ArrayList<String>();
|
||||
}
|
||||
|
||||
void receive(@Observes String greet) {
|
||||
this.greetings.add(greet);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces("application/json")
|
||||
public List<String> listAll(@QueryParam("start") Integer start, @QueryParam("max") Integer max) {
|
||||
int numGreetings = this.greetings.size();
|
||||
|
||||
if (numGreetings == 0 || max == 0) {
|
||||
return Collections.<String>emptyList();
|
||||
}
|
||||
|
||||
if (start == null) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (max == null) {
|
||||
max = numGreetings;
|
||||
}
|
||||
|
||||
return this.greetings.subList(start, Math.min(max + start, numGreetings));
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
We already showed you an XML example in <<ravages>>, a language we often rant about over beers at <<bier-central>>.
|
||||
|
||||
I'll trade you a little table for some of that bark.
|
||||
|
||||
[table%header,grid=rows,cols=4,frame=topbot]
|
||||
|===
|
||||
<.<|Column 1
|
||||
<.<|Column 2
|
||||
<.<|Column 3
|
||||
<.<|Column 4
|
||||
|
||||
^.<m|Prefix `{vbar}` with `{caret}` to center content horizontally within the cell.
|
||||
<.>|Prefix `{vbar}` with a `.` and `>` to align content to the bottom of the cell.
|
||||
^.^|Prefix `{vbar}` with a `^`, `.`, and `^` to place content in the middle of the cell.
|
||||
>.<|Prefix `{vbar}` with `>` to align content to the right horizontally within the cell.
|
||||
|
||||
4+^.<e|This content spans all four columns (`4{plus}`) and is centered horizontally (`{caret}`) within the cell.
|
||||
|
||||
|===
|
||||
Wait.
|
||||
What?
|
||||
Where is this story going?
|
||||
|
||||
`<span>`:::
|
||||
an html tag that makes me crazy
|
||||
align:::
|
||||
something I never get going in the right direction.
|
||||
Also has to do with my poor verbal communication skills
|
||||
float:::
|
||||
style:::
|
||||
don't make me laugh
|
||||
|
||||
Does anyone have the time?
|
||||
|
||||
Tg lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
||||
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborumj.
|
||||
|
||||
[[_keeping_it_together]]
|
||||
== Keeping It Together
|
||||
On this page we have nested "`keep together`" logic.
|
||||
The combined block will be shifted to the next page if there isn't room available on this one.
|
||||
|
||||
[verse]
|
||||
First,
|
||||
we
|
||||
need
|
||||
to
|
||||
waste
|
||||
several
|
||||
lines
|
||||
using
|
||||
a
|
||||
verse
|
||||
to
|
||||
push
|
||||
the
|
||||
next
|
||||
block
|
||||
to
|
||||
its
|
||||
breaking
|
||||
point.
|
||||
.What happens if there is both a field and a method with the same name?
|
||||
[NOTE]
|
||||
====
|
||||
Back to the previous example, suppose that we have both a field and a method with the same name, as in:
|
||||
|
||||
.Java class with a field and method that share the same name
|
||||
[source,java]
|
||||
|
||||
----
|
||||
public class Foo {
|
||||
public String bar;
|
||||
|
||||
public String bar() {
|
||||
return bar;
|
||||
}
|
||||
}
|
||||
----
|
||||
*Golo resolves methods first, fields last.*
|
||||
Hence, the following Golo code will resolve the `bar()` method, not the `bar` field:
|
||||
|
||||
.Golo picks the method over the field with the same name
|
||||
[source,golo]
|
||||
|
||||
----
|
||||
let foo = Foo()
|
||||
|
||||
foo: bar("baz") # <1>
|
||||
|
||||
println(foo: bar()) # <2>
|
||||
----
|
||||
<1> Writes the field
|
||||
<2> Calls the `bar()` method
|
||||
====
|
||||
<<<
|
||||
Here's a preview of how each heading level is rendered.
|
||||
|
||||
[discrete]
|
||||
= Heading 1 (Level 0)
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
== Heading 2 (Level 1)
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
=== Heading 3 (Level 2)
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
==== Heading 4 (Level 3)
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
===== Heading 5 (Level 4)
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
====== Heading 6 (Level 5)
|
||||
filler content
|
||||
|
||||
'''
|
||||
--
|
||||
Here's some content inside an open block.
|
||||
|
||||
--
|
||||
|
||||
[[_credits]]
|
||||
[appendix]
|
||||
== Credits
|
||||
.Brought to you with icon:heart[set=fas,role=love] by OpenDevise
|
||||
[table%footer%header,grid=rows,width=75%,cols="2,2s,^4",frame=topbot]
|
||||
|===
|
||||
<.<|Name
|
||||
<.<|Title
|
||||
.<|Alias
|
||||
|
||||
<.<|Sarah White
|
||||
<.<|President
|
||||
.<|http://twitter.com/carbonfray[@carbonfray]
|
||||
|
||||
<.<|Dan Allen
|
||||
<.<|Vice President
|
||||
.<|http://twitter.com/mojavelinux[@mojavelinux]
|
||||
|
||||
3+^.<e|Powered by Open Source
|
||||
|
||||
|===
|
||||
|
||||
[[_index]]
|
||||
[index]
|
||||
== Index
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
= Asciidoctor Changelog
|
||||
:tip-caption: Tip
|
||||
:appendix-caption: Appendix
|
||||
:appendix-refsig: Appendix
|
||||
:toc-title: Table of Contents
|
||||
:iconsdir: ./images/icons
|
||||
:warning-caption: Warning
|
||||
:figure-caption: Figure
|
||||
:attribute-missing: skip
|
||||
:section-refsig: Section
|
||||
:toc-placement: auto
|
||||
:important-caption: Important
|
||||
:note-caption: Note
|
||||
:stylesdir: .
|
||||
:untitled-label: Untitled
|
||||
:max-include-depth: 64
|
||||
:caution-caption: Caution
|
||||
:user-home: .
|
||||
:max-attribute-value-size: 4096
|
||||
:safe-mode-level: 20
|
||||
:safe-mode-name: secure
|
||||
:table-caption: Table
|
||||
:part-refsig: Part
|
||||
:authorcount: 0
|
||||
:example-caption: Example
|
||||
:version-label: Version
|
||||
:last-update-label: Last updated
|
||||
:doctype: article
|
||||
:chapter-refsig: Chapter
|
||||
:attribute-undefined: drop-line
|
||||
|
||||
http://asciidoctor.org[Asciidoctor] is an open source text processor and publishing toolchain for converting http://asciidoctor.org[AsciiDoc] markup into HTML, DocBook and custom formats.
|
||||
|
||||
|
||||
This document provides a high-level view of the changes introduced in Asciidoctor by release.
|
||||
For a detailed view of what has changed, refer to the https://github.com/asciidoctor/asciidoctor/commits/master[commit history] on GitHub.
|
||||
|
||||
[[_0_1_4_2013_09_05_mojavelinux]]
|
||||
== 0.1.4 (2013-09-05) - @mojavelinux
|
||||
Performance::
|
||||
* 15% increase in speed compared to 0.1.3
|
||||
|
||||
Enhancements::
|
||||
* updated xref inline macro to support inter-document references (#417)
|
||||
|
||||
Bug Fixes::
|
||||
* lowercase attribute names passed to API (#508)
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
= Simple Inventory API
|
||||
You <you@your-company.com>
|
||||
v1.0.0
|
||||
:tip-caption: Tip
|
||||
:appendix-caption: Appendix
|
||||
:appendix-refsig: Appendix
|
||||
:authorinitials: Y
|
||||
:toc-title: Table of Contents
|
||||
:iconsdir: ./images/icons
|
||||
:author: You
|
||||
:warning-caption: Warning
|
||||
:figure-caption: Figure
|
||||
:attribute-missing: skip
|
||||
:section-refsig: Section
|
||||
:toc-placement: auto
|
||||
:important-caption: Important
|
||||
:authors: You
|
||||
:note-caption: Note
|
||||
:firstname: You
|
||||
:stylesdir: .
|
||||
:untitled-label: Untitled
|
||||
:max-include-depth: 64
|
||||
:caution-caption: Caution
|
||||
:user-home: .
|
||||
:max-attribute-value-size: 4096
|
||||
:safe-mode-level: 20
|
||||
:safe-mode-name: secure
|
||||
:table-caption: Table
|
||||
:part-refsig: Part
|
||||
:authorcount: 1
|
||||
:example-caption: Example
|
||||
:email: you@your-company.com
|
||||
:version-label: Version
|
||||
:revnumber: 1.0.0
|
||||
:last-update-label: Last updated
|
||||
:doctype: article
|
||||
:chapter-refsig: Chapter
|
||||
:attribute-undefined: drop-line
|
||||
|
||||
[[_overview]]
|
||||
== Overview
|
||||
This is a simple API
|
||||
|
||||
[[_license]]
|
||||
=== License
|
||||
[%hardbreaks]
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0]
|
||||
|
||||
[[_servers]]
|
||||
== Servers
|
||||
* https://{username}.gigantic-server.com:{port}/{basePath}
|
||||
+
|
||||
The production API server
|
||||
|
||||
+
|
||||
.Variables
|
||||
username::
|
||||
*this* __value__ is assigned by the service provider, in this example `gigantic-server.com`
|
||||
Possible Values::
|
||||
Any
|
||||
Default::
|
||||
demo
|
||||
|
||||
port::
|
||||
Possible Values::
|
||||
- 8443
|
||||
- 443
|
||||
|
||||
Default::
|
||||
8443
|
||||
|
||||
basePath::
|
||||
Possible Values::
|
||||
Any
|
||||
Default::
|
||||
v2
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
= Document Title
|
||||
|
||||
[arrowsAndBoxes]
|
||||
(User) > (Admin)
|
||||
@@ -0,0 +1,3 @@
|
||||
= Title
|
||||
|
||||
include::b.adoc[]
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
= Document Title
|
||||
|
||||
sample {content}
|
||||
@@ -0,0 +1,529 @@
|
||||
= The Dangerous & _Thrilling_ Documentation Chronicles: Based on True Events
|
||||
Kismet Caméléon; Lazarus het_Draeke
|
||||
v1.0, 2014-01-01
|
||||
:description: This story chronicles the inexplicable hazards and vicious beasts a \
|
||||
team must conquer and vanquish on their journey to discovering the true power of \
|
||||
Open Source.
|
||||
:organization: Company Name
|
||||
:doctype: book
|
||||
// Settings:
|
||||
:experimental:
|
||||
:reproducible:
|
||||
:icons: font
|
||||
:listing-caption: Listing
|
||||
:sectnums:
|
||||
:toc:
|
||||
:toclevels: 3
|
||||
ifeval::["{asciidoctor-version}" < "1.5.7"]
|
||||
:legacy-footnoteref:
|
||||
endif::[]
|
||||
ifdef::backend-pdf[]
|
||||
:pdf-theme: chronicles
|
||||
:pdf-themesdir: {docdir}
|
||||
:title-logo-image: image:sample-banner.svg[pdfwidth=4.25in,align=center]
|
||||
:source-highlighter: rouge
|
||||
//:rouge-style: github
|
||||
endif::[]
|
||||
// URIs:
|
||||
:uri-devoxx: https://devoxx.be
|
||||
:uri-devoxx-top-talks: https://www.youtube.com/watch?v=1OpAgZvYXLQ&list=PLRsbF2sD7JVq7fv1GZGORShSUIae1ZAPy&index=1
|
||||
:uri-stbernardusabt12: http://www.sintbernardus.be/stbernardusabt12.php?l=en
|
||||
:uri-wolpertinger: http://en.wikipedia.org/wiki/Wolpertinger
|
||||
|
||||
[abstract]
|
||||
{description}
|
||||
|
||||
== It's a City Under Siege
|
||||
|
||||
This journey begins one late Monday afternoon at {uri-devoxx}[((Devoxx))].
|
||||
Our team needs coffee, _desperately_, but none of us dare open the theater doors...
|
||||
|
||||
During the {uri-devoxx-top-talks}[opening university session], a script-happy warlock inadvertently released a legion of Wolpertingers!
|
||||
To leave now would mean *code dismemberment and certain death*.
|
||||
|
||||
Behold -> the horror!
|
||||
|
||||
.Wolpertinger, stuffed
|
||||
[.left.thumb]
|
||||
image::wolpertinger.jpg[Wolpertinger,pdfwidth=50%,link={uri-wolpertinger}]
|
||||
|
||||
(((Wolpertinger)))
|
||||
(((Ravenous Beast,Wolpertinger)))
|
||||
You may not be familiar with these {uri-wolpertinger}[ravenous beasts].
|
||||
Trust us, they'll eat your shorts and suck loops from your code.
|
||||
In light of this danger, we've searched high and wide for the security crew's defensive operations manual.
|
||||
ifndef::legacy-footnoteref[]
|
||||
We can't find it and the DefOps{empty}footnote:defops[DefOps is a portmanteau of "`defensive`" and "`operations`".] werewolves haven't returned from their rendezvous at Bier Central.
|
||||
endif::[]
|
||||
ifdef::legacy-footnoteref[]
|
||||
We can't find it and the DefOps{empty}footnoteref:[defops,DefOps is a portmanteau of "`defensive`" and "`operations`".] werewolves haven't returned from their rendezvous at Bier Central.
|
||||
endif::[]
|
||||
They've either eaten each other or fallen victim to the Wolpertingers roaming the streets of ((Antwerp)).
|
||||
Quick, hit kbd:[Ctrl,Alt,Backspace] or select menu:File[Quit] and let's bail out of here!
|
||||
|
||||
ifndef::legacy-footnoteref[]
|
||||
WARNING: Working with DefOps{empty}footnote:defops[] werewolves leads to howling and trying to train aggressive regular expressions with Pavlovian reinforcement.
|
||||
endif::[]
|
||||
ifdef::legacy-footnoteref[]
|
||||
WARNING: Working with DefOps{empty}footnoteref:[defops] werewolves leads to howling and trying to train aggressive regular expressions with Pavlovian reinforcement.
|
||||
endif::[]
|
||||
|
||||
_Weak light from the hallway trickled across the theater, chased by a distant scream._
|
||||
|
||||
=== Rendezvous Point
|
||||
|
||||
Come on, [[bier-central,Bier Central]]_Bier Central_, of course!
|
||||
Did you have to ask?
|
||||
If you beat me there, order me a {uri-stbernardusabt12}[St. Bernardus Abt 12].
|
||||
Here's some €.
|
||||
|
||||
[#ravages]
|
||||
== The Ravages of Writing
|
||||
|
||||
Crystalline XML tags relentlessly bombarded the theater.
|
||||
|
||||
.XML tags
|
||||
[source,xml]
|
||||
----
|
||||
<author id="1">
|
||||
<personname>
|
||||
<firstname>Lazarus</firstname>
|
||||
<surname>het Draeke</surname>
|
||||
</personname>
|
||||
</author>
|
||||
----
|
||||
|
||||
ifndef::legacy-footnoteref[]
|
||||
Despite the assault, we continued our pursuit to draft a DefOps{empty}footnote:defops[] plan.
|
||||
endif::[]
|
||||
ifdef::legacy-footnoteref[]
|
||||
Despite the assault, we continued our pursuit to draft a DefOps{empty}footnoteref:[defops] plan.
|
||||
endif::[]
|
||||
|
||||
.DefOps Plan
|
||||
====
|
||||
Click btn:[Download Zip] to download the defensive operation plan bundle.
|
||||
|
||||
OMG!
|
||||
Somebody please save us now!
|
||||
I want my mum -- and an extra-large double macchiato, please.
|
||||
====
|
||||
|
||||
Unfortunately, Lazarus and I had both come to the conclusion that we weren't going to get out of this without corrupted hardrives if we didn't locate caffeine within the next few hours.
|
||||
|
||||
=== A Recipe for Potion That Will Ensure You Win the Hearts of Developers
|
||||
|
||||
This potion for a sample document contains the following ingredients, which are listed in a very random, chaotically nested order.
|
||||
|
||||
.Ingredients for Potion that Demystifies Documents
|
||||
* all the headings
|
||||
** syntax highlighted source code
|
||||
*** non-syntax highlighted source code or just a listing block
|
||||
* quote block
|
||||
** verse block
|
||||
*** table with some cell formatting
|
||||
**** sequential paragraphs
|
||||
***** admonition blocks, but use them sparingly
|
||||
*** bullet list with nesting
|
||||
** numbered list with nesting
|
||||
** definition list
|
||||
*** sidebar
|
||||
* example block
|
||||
** block image (no inline images)
|
||||
*** inline formatting in a paragraph
|
||||
**** two fresh Burdockian leaves
|
||||
***** They must be harvested by the light of the teal moons.
|
||||
|
||||
Are you square?
|
||||
|
||||
[square]
|
||||
* one
|
||||
* two
|
||||
* three
|
||||
|
||||
What is there to do?
|
||||
|
||||
* [x] Done
|
||||
* [ ] Next
|
||||
* Who's counting?
|
||||
|
||||
==== Searching for Burdockian
|
||||
|
||||
.Steps for finding and preparing Burdockian leaves
|
||||
. Locate dusty botany
|
||||
.. Sneeze
|
||||
... Sneeze some more
|
||||
. Find section on Burdockian
|
||||
.. Review its characteristics
|
||||
... Take a picture of the diagram of its leaves
|
||||
.... Don't rip out the picture like a troglodyte
|
||||
..... Don't do it, I'm watching you
|
||||
. Put on your hiking boots
|
||||
. Freeze your butt off on the side of a mountain at midnight
|
||||
|
||||
Let's skip a few steps and start counting from 10.
|
||||
|
||||
[start=10]
|
||||
. arabic (10)
|
||||
.. loweralpha (a)
|
||||
... lowerroman (i)
|
||||
... lowerroman (ii)
|
||||
... lowerroman (iii)
|
||||
... lowerroman (iv)
|
||||
.... upperalpha (A)
|
||||
. arabic (11)
|
||||
|
||||
It's time for a top 5 list, made using the `reversed` option on an ordered list!
|
||||
|
||||
[%reversed]
|
||||
. Stone Imperial Russian Stout
|
||||
. Pliny the Elder
|
||||
. Chimay Grande Réserve (Blue)
|
||||
. St. Bernardus Abt 12
|
||||
. Westvleteren 12 (XII)
|
||||
|
||||
How about a list with some terms?
|
||||
|
||||
* Fruits
|
||||
|
||||
Apple::
|
||||
The round fruit of a tree of the rose family, which typically has thin red or green skin and crisp flesh.
|
||||
Yes, I said _flesh_.
|
||||
|
||||
Pear::
|
||||
A yellowish- or brownish-green edible fruit that is typically narrow at the stalk and wider toward the base, with sweet, slightly gritty flesh.
|
||||
More flesh.
|
||||
Mmmmm.
|
||||
|
||||
* Vegetables
|
||||
|
||||
Carrot::
|
||||
An orange-colored root eaten as a vegetable.
|
||||
Beware, it's a favorite of the Wolpertinger.
|
||||
|
||||
===== Are You Still Here?
|
||||
|
||||
.Move, move, move!
|
||||
[CAUTION]
|
||||
====
|
||||
The Wolpertingers can smell your procrastination.
|
||||
It's not their fault you can't find your boots.
|
||||
====
|
||||
|
||||
====== Sigh...
|
||||
|
||||
TIP: Your boots are in your closet.
|
||||
|
||||
== Dawn on the Plateau
|
||||
|
||||
Lazarus was hanging from the bottom limb of a Burdockian tree, licking the bark.
|
||||
|
||||
[quote,Mark Tobey]
|
||||
On pavements and the bark of trees I have found whole worlds.
|
||||
|
||||
"`If there are whole worlds on that bark, he just swallowed them,`" Kizmet replied.
|
||||
|
||||
[verse,The documentation attorneys]
|
||||
____
|
||||
No bark was harmed in the making of this potion.
|
||||
We're not so sure about a couple ants though.
|
||||
|
||||
Nor those worlds...
|
||||
|
||||
Crap, I smell an injunction.
|
||||
____
|
||||
|
||||
We'd retrieved the leaves, but we'd obviously lost our minds in the process.
|
||||
|
||||
[verse]
|
||||
Roses are +++<span style="color: #FF0000">red</span>+++.
|
||||
Violets are +++<span style="color: #0000FF">blue</span>+++__-ish__.
|
||||
|
||||
== Words Seasoned with Power
|
||||
|
||||
To _tame_ the [.wild]#wild# wolpertingers, we needed to build a *charm*.
|
||||
But **ul**timate victory could only be won if we divined the *_true name_* of the __war__lock.
|
||||
|
||||
"`What kind of charm?`" Lazarus asked. "`An odoriferous one or a mineral one?`"
|
||||
Kizmet shrugged. "`The note from Olaf's desk says '`wormwood and licorice,`' but these could be normal groceries for werewolves.`"
|
||||
|
||||
"`Well the H~2~O written on the security whiteboard could be part of a shopping list, but I don't think the local bodega also sells e = mc^2^,`" Lazarus replied.
|
||||
|
||||
"`Wait!`" Indigo plucked a small vial from her desk's top drawer and held it toward us.
|
||||
The vial's label read '```e = mc^2^ *_the scent of science_* _smells like a genius_```'.
|
||||
|
||||
=== Can I Get Some `Code`?
|
||||
|
||||
[%hardbreaks]
|
||||
Sure.
|
||||
Have a listing block.
|
||||
|
||||
----
|
||||
This is an example of a listing block.
|
||||
The content inside is rendered as <pre> text.
|
||||
----
|
||||
|
||||
But I'm not giving you any highlighting shazam just yet.
|
||||
|
||||
.What is a listing block?
|
||||
****
|
||||
Like literal blocks, the content in listing blocks is displayed exactly as you entered it.
|
||||
Listing block content is rendered as `<pre>` text.
|
||||
|
||||
The `listing` style is applied to an element, such as a paragraph, by setting the `listing` attribute on that element.
|
||||
****
|
||||
|
||||
Let's get our #((highlighting))# on!
|
||||
|
||||
<<<
|
||||
|
||||
Install Prawn:
|
||||
|
||||
$ gem install prawn
|
||||
|
||||
Then create your first PDF document in Ruby!
|
||||
|
||||
.Generates a basic PDF document using Prawn
|
||||
[source,ruby]
|
||||
----
|
||||
require 'prawn' # <1>
|
||||
|
||||
Prawn::Document.generate 'output.pdf' do # <3>
|
||||
text 'Hello, World!' # <2>
|
||||
end
|
||||
----
|
||||
<1> Imports Prawn library
|
||||
<2> Adds text “Hello, World!” to first page
|
||||
<3> Writes PDF to [file]_output.pdf_ after executing all statements
|
||||
|
||||
How about some source code that styles code? So meta!
|
||||
|
||||
[source,css]
|
||||
----
|
||||
code {
|
||||
padding: 2px 4px;
|
||||
font-size: 90%;
|
||||
font-weight: normal;
|
||||
color: #c7254e;
|
||||
white-space: nowrap !important;
|
||||
background-color: #f9f2f4;
|
||||
border-radius: 4px;
|
||||
}
|
||||
----
|
||||
|
||||
Where could we go without some Java(TM)?
|
||||
Naturally, some autosizing is necessary.
|
||||
|
||||
[source%autofit,java]
|
||||
----
|
||||
package org.javaee7.cdi.events;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.enterprise.context.SessionScoped;
|
||||
import javax.enterprise.event.Observes;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.*;
|
||||
|
||||
/**
|
||||
* This session-scoped bean receives greeting strings from the event bus
|
||||
* and provides access to the collection of these greetings via a REST API.
|
||||
*
|
||||
* @author The Duke
|
||||
* @since 1.0
|
||||
*/
|
||||
@SessionScoped
|
||||
public class GreetingReceiver implements EventReceiver, Serializable {
|
||||
|
||||
private List<String> greetings;
|
||||
|
||||
@PostConstruct
|
||||
void init() {
|
||||
this.greetings = new ArrayList<String>();
|
||||
}
|
||||
|
||||
void receive(@Observes String greet) {
|
||||
this.greetings.add(greet);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces("application/json")
|
||||
public List<String> listAll(@QueryParam("start") Integer start, @QueryParam("max") Integer max) {
|
||||
int numGreetings = this.greetings.size();
|
||||
|
||||
if (numGreetings == 0 || max == 0) {
|
||||
return Collections.<String>emptyList();
|
||||
}
|
||||
|
||||
if (start == null) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (max == null) {
|
||||
max = numGreetings;
|
||||
}
|
||||
|
||||
return this.greetings.subList(start, Math.min(max + start, numGreetings));
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
We already showed you an XML example in <<ravages>>, a language we often rant about over beers at <<bier-central>>.
|
||||
|
||||
I'll trade you a little table for some of that bark.
|
||||
|
||||
[cols=4,frame=topbot,grid=rows]
|
||||
|===
|
||||
|Column 1 |Column 2 |Column 3 |Column 4
|
||||
|
||||
^m|Prefix `{vbar}` with `{caret}` to center content horizontally within the cell.
|
||||
.>|Prefix `{vbar}` with a `.` and `>` to align content to the bottom of the cell.
|
||||
^.^|Prefix `{vbar}` with a `^`, `.`, and `^` to place content in the middle of the cell.
|
||||
>|Prefix `{vbar}` with `>` to align content to the right horizontally within the cell.
|
||||
|
||||
4+^e|This content spans all four columns (`4{plus}`) and is centered horizontally (`{caret}`) within the cell.
|
||||
|===
|
||||
|
||||
Wait.
|
||||
What?
|
||||
Where is this story going?
|
||||
|
||||
`<span>`:: an html tag that makes me crazy
|
||||
|
||||
align:: something I never get going in the right direction.
|
||||
Also has to do with my poor verbal communication skills
|
||||
|
||||
float::
|
||||
style::
|
||||
don't make me laugh
|
||||
|
||||
Does anyone have the time?
|
||||
|
||||
Tg lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
||||
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborumj.
|
||||
|
||||
== Keeping It Together
|
||||
|
||||
On this page we have nested "`keep together`" logic.
|
||||
The combined block will be shifted to the next page if there isn't room available on this one.
|
||||
|
||||
[verse]
|
||||
First,
|
||||
we
|
||||
need
|
||||
to
|
||||
waste
|
||||
several
|
||||
lines
|
||||
using
|
||||
a
|
||||
verse
|
||||
to
|
||||
push
|
||||
the
|
||||
next
|
||||
block
|
||||
to
|
||||
its
|
||||
breaking
|
||||
point.
|
||||
|
||||
[NOTE]
|
||||
.What happens if there is both a field and a method with the same name?
|
||||
====
|
||||
Back to the previous example, suppose that we have both a field and a method with the same name, as in:
|
||||
|
||||
.Java class with a field and method that share the same name
|
||||
[source,java]
|
||||
----
|
||||
public class Foo {
|
||||
public String bar;
|
||||
|
||||
public String bar() {
|
||||
return bar;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
*Golo resolves methods first, fields last.*
|
||||
Hence, the following Golo code will resolve the `bar()` method, not the `bar` field:
|
||||
|
||||
.Golo picks the method over the field with the same name
|
||||
[source,golo]
|
||||
----
|
||||
let foo = Foo()
|
||||
|
||||
foo: bar("baz") # <1>
|
||||
|
||||
println(foo: bar()) # <2>
|
||||
----
|
||||
<1> Writes the field
|
||||
<2> Calls the `bar()` method
|
||||
====
|
||||
|
||||
<<<
|
||||
|
||||
Here's a preview of how each heading level is rendered.
|
||||
|
||||
[discrete]
|
||||
= Heading 1 (Level 0)
|
||||
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
== Heading 2 (Level 1)
|
||||
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
=== Heading 3 (Level 2)
|
||||
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
==== Heading 4 (Level 3)
|
||||
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
===== Heading 5 (Level 4)
|
||||
|
||||
filler content
|
||||
|
||||
[discrete]
|
||||
====== Heading 6 (Level 5)
|
||||
|
||||
filler content
|
||||
|
||||
---
|
||||
|
||||
--
|
||||
Here's some content inside an open block.
|
||||
--
|
||||
|
||||
[appendix]
|
||||
== Credits
|
||||
|
||||
.Brought to you with icon:heart[set=fas,role=love] by OpenDevise
|
||||
[%header%footer,cols="2,2s,^4",grid=rows,frame=topbot,width=75%,caption=]
|
||||
|===
|
||||
|Name |Title |Alias
|
||||
|
||||
|Sarah White
|
||||
|President
|
||||
|http://twitter.com/carbonfray[@carbonfray]
|
||||
|
||||
|Dan Allen
|
||||
|Vice President
|
||||
|http://twitter.com/mojavelinux[@mojavelinux]
|
||||
|
||||
3+^.e|Powered by Open Source
|
||||
|===
|
||||
|
||||
[index]
|
||||
== Index
|
||||
@@ -0,0 +1,21 @@
|
||||
= Asciidoctor Changelog
|
||||
|
||||
http://asciidoctor.org[Asciidoctor] is an open source text processor and publishing toolchain for converting http://asciidoctor.org[AsciiDoc] markup into HTML, DocBook and custom formats.
|
||||
|
||||
This document provides a high-level view of the changes introduced in Asciidoctor by release.
|
||||
For a detailed view of what has changed, refer to the https://github.com/asciidoctor/asciidoctor/commits/master[commit history] on GitHub.
|
||||
|
||||
== 0.1.4 (2013-09-05) - @mojavelinux
|
||||
|
||||
Performance::
|
||||
|
||||
* 15% increase in speed compared to 0.1.3
|
||||
|
||||
Enhancements::
|
||||
|
||||
* updated xref inline macro to support inter-document references (#417)
|
||||
|
||||
|
||||
Bug Fixes::
|
||||
|
||||
* lowercase attribute names passed to API (#508)
|
||||
@@ -0,0 +1,28 @@
|
||||
= Simple Inventory API
|
||||
You <you@your-company.com>
|
||||
v1.0.0
|
||||
|
||||
== Overview
|
||||
This is a simple API
|
||||
|
||||
=== License
|
||||
[%hardbreaks]
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0]
|
||||
|
||||
== Servers
|
||||
* https://{username}.gigantic-server.com:{port}/{basePath}
|
||||
+
|
||||
The production API server
|
||||
+
|
||||
.Variables
|
||||
username:: *this* __value__ is assigned by the service provider, in this example `gigantic-server.com`
|
||||
Possible Values::: Any
|
||||
Default::: demo
|
||||
port::
|
||||
Possible Values:::
|
||||
- 8443
|
||||
- 443
|
||||
Default::: 8443
|
||||
basePath::
|
||||
Possible Values::: Any
|
||||
Default::: v2
|
||||
14
swagger2markup-asciidoc/src/test/resources/logback.xml
Normal file
14
swagger2markup-asciidoc/src/test/resources/logback.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true">
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="io.github.swagger2markup" level="DEBUG"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -25,6 +25,7 @@ import io.github.swagger2markup.markup.builder.internal.Markup;
|
||||
* @author Robert Winkler
|
||||
*/
|
||||
public enum AsciiDoc implements Markup {
|
||||
ATTRIBUTE(":"),
|
||||
TABLE("|==="),
|
||||
TABLE_COLUMN_DELIMITER("|"),
|
||||
TITLE("="),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user