Skip to content

Commit

Permalink
Opens MarkupDocBuilders for additional/external markup builders (incl…
Browse files Browse the repository at this point in the history
…udes an example for Confluence wiki markup)
  • Loading branch information
2bad4u committed Mar 13, 2016
1 parent 9ce6fc6 commit 7e0d5bc
Show file tree
Hide file tree
Showing 4 changed files with 333 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,63 +19,70 @@
package io.github.robwin.markup.builder;


import io.github.robwin.markup.builder.asciidoc.AsciiDocBuilder;
import io.github.robwin.markup.builder.markdown.MarkdownBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
* @author Robert Winkler
*/
public final class MarkupDocBuilders {

public static final String LINE_SEPARATOR_UNIX = "\n";
public static final String LINE_SEPARATOR_WINDOWS= "\r\n";
public static final String LINE_SEPARATOR_UNIX = "\n";
public static final String LINE_SEPARATOR_WINDOWS = "\r\n";

private static final Logger LOGGER = LoggerFactory.getLogger(MarkupDocBuilder.class);

private MarkupDocBuilders(){}
private MarkupDocBuilders() {
}

/**
* Creates a MarkupDocBuilder which uses the system line separator.
*
* @param markupLanguage the markup language which is used to generate the files
* @return a MarkupDocBuilder
*/
public static MarkupDocBuilder documentBuilder(MarkupLanguage markupLanguage){
switch(markupLanguage){
case MARKDOWN: return new MarkdownBuilder();
case ASCIIDOC: return new AsciiDocBuilder();
default: return new AsciiDocBuilder();
}
public static MarkupDocBuilder documentBuilder(MarkupLanguage markupLanguage) {
return documentBuilder(markupLanguage, null);
}

/**
* Creates a MarkupDocBuilder which uses a custom line separator.
* If the custom line separator is null, it uses the system line separator.
*
* @param markupLanguage the markup language which is used to generate the files
* @param lineSeparator the line separator which should be used
* @param lineSeparator the line separator which should be used
* @return a MarkupDocBuilder
*/
public static MarkupDocBuilder documentBuilder(MarkupLanguage markupLanguage, LineSeparator lineSeparator){
public static MarkupDocBuilder documentBuilder(MarkupLanguage markupLanguage, LineSeparator lineSeparator) {
String lineSeparatorAsString;
if(lineSeparator == null){
if (lineSeparator == null) {
lineSeparatorAsString = System.getProperty("line.separator");
}else{
} else {
lineSeparatorAsString = lineSeparator.toString();
}
switch(markupLanguage){
case MARKDOWN: return new MarkdownBuilder(lineSeparatorAsString);
case ASCIIDOC: return new AsciiDocBuilder(lineSeparatorAsString);
default: return new AsciiDocBuilder(lineSeparatorAsString);
}
return createInstance(markupLanguage, lineSeparatorAsString);
}

/**
* Instantiate a new builder from {@code docBuilder} with the same configuration.
* You can use it to build intermediate MarkupDocBuilder for composition purpose.
*/
public static MarkupDocBuilder documentBuilder(MarkupDocBuilder docBuilder){
return docBuilder.copy();
public static MarkupDocBuilder documentBuilder(MarkupDocBuilder docBuilder) {
return docBuilder.copy();
}



private static MarkupDocBuilder createInstance(MarkupLanguage markupLanguage, String lineSeparator) {
final Class<? extends MarkupDocBuilder> clazz = markupLanguage.getMarkupDocBuilderClass();
try {
final Constructor<? extends MarkupDocBuilder> constructor = clazz.getConstructor(String.class);
return constructor.newInstance(lineSeparator);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
LOGGER.error("Unable to instantiate builder!", e);
throw new IllegalStateException(e);
}
}
}
20 changes: 15 additions & 5 deletions src/main/java/io/github/robwin/markup/builder/MarkupLanguage.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,36 @@

package io.github.robwin.markup.builder;

import io.github.robwin.markup.builder.asciidoc.AsciiDocBuilder;
import io.github.robwin.markup.builder.markdown.MarkdownBuilder;

import java.util.Arrays;
import java.util.List;

/**
* @author Robert Winkler
*/
public enum MarkupLanguage {
ASCIIDOC(".adoc,.asciidoc"),
MARKDOWN(".md,.markdown");
public final class MarkupLanguage {
public static final MarkupLanguage ASCIIDOC = new MarkupLanguage(".adoc,.asciidoc", AsciiDocBuilder.class);
public static final MarkupLanguage MARKDOWN = new MarkupLanguage(".md,.markdown", MarkdownBuilder.class);

private final String fileNameExtensions;
private final Class<? extends MarkupDocBuilder> markupDocBuilderClass;

/**
* @param fileNameExtensions file name suffix
* @param fileNameExtensions file name suffix
* @param markupDocBuilderClass the builder class
*/
private MarkupLanguage(final String fileNameExtensions) {
public MarkupLanguage(final String fileNameExtensions, Class<? extends MarkupDocBuilder> markupDocBuilderClass) {
this.fileNameExtensions = fileNameExtensions;
this.markupDocBuilderClass = markupDocBuilderClass;
}

public List<String> getFileNameExtensions() {
return Arrays.asList(fileNameExtensions.split(","));
}

public Class<? extends MarkupDocBuilder> getMarkupDocBuilderClass() {
return markupDocBuilderClass;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package io.github.robwin.markup.builder.confluence;

import io.github.robwin.markup.builder.*;
import jdk.nashorn.internal.ir.annotations.Ignore;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.List;

import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

@Ignore
public final class ConfluenceMarkupBuilder extends AbstractMarkupDocBuilder {

private static final String FILE_EXTENSION = ".txt";

public static final MarkupLanguage CONFLUENCE = new MarkupLanguage(FILE_EXTENSION, ConfluenceMarkupBuilder.class);

public ConfluenceMarkupBuilder(String lineSeparator) {
super(lineSeparator);
}

@Override
public MarkupDocBuilder documentTitle(String title) {
return this;
}

@Override
public MarkupDocBuilder sectionTitleWithAnchorLevel(int level, String title, String anchor) {
documentBuilder.append(newLine);
documentBuilder.append(".h").append(level + 1).append(" ").append(title);
if (isNotBlank(anchor)) {
documentBuilder.append(" {anchor:").append(anchor).append("}");
}
documentBuilder.append(newLine).append(newLine);
return this;
}

@Override
public MarkupDocBuilder block(String text, MarkupBlockStyle style, String title, MarkupAdmonition admonition) {
switch (style) {
case SIDEBAR:
documentBuilder.append(newLine).append("{quote}").append(newLine);
if (isNotBlank(title)) {
documentBuilder.append(title).append(" \\\\ ");
}
documentBuilder.append(text);
documentBuilder.append(newLine).append("{quote}").append(newLine);
break;
case EXAMPLE:
case LITERAL:
documentBuilder.append(newLine);
if (isBlank(title)) {
documentBuilder.append("{panel}");
} else {
documentBuilder.append("{panel:title=").append(title).append("}");
}
documentBuilder.append(newLine);
documentBuilder.append(text);
documentBuilder.append(newLine).append("{panel}").append(newLine);
break;
case LISTING:
documentBuilder.append(newLine);
if (isBlank(title)) {
documentBuilder.append("{code}");
} else {
documentBuilder.append("{code:title=").append(title).append("}");
}
documentBuilder.append(newLine);
documentBuilder.append(text);
documentBuilder.append(newLine).append("{code}").append(newLine);
break;
case PASSTHROUGH:
documentBuilder.append(newLine).append("{noformat}").append(newLine);
if (isNotBlank(title)) {
documentBuilder.append(title);
documentBuilder.append(newLine);
}
documentBuilder.append(text);
documentBuilder.append(newLine).append("{noformat}").append(newLine);
break;
}
return this;
}

@Override
public MarkupDocBuilder listing(String text, String language) {
documentBuilder.append(newLine);
if (isBlank(language)) {
documentBuilder.append("{code}");
} else {
documentBuilder.append("{code:language=").append(language).append("}");
}
documentBuilder.append(newLine);
documentBuilder.append(text);
documentBuilder.append(newLine).append("{code}").append(newLine).append(newLine);
return this;
}

@Override
public MarkupDocBuilder boldText(String text) {
documentBuilder.append("*").append(text).append("*");
return this;
}

@Override
public MarkupDocBuilder italicText(String text) {
documentBuilder.append("_").append(text).append("_");
return this;
}

@Override
public MarkupDocBuilder unorderedList(List<String> list) {
documentBuilder.append(newLine).append(newLine);
list.forEach(item -> documentBuilder.append("* ").append(item).append(newLine));
documentBuilder.append(newLine);
return this;
}

@Override
public MarkupDocBuilder unorderedListItem(String item) {
documentBuilder.append("* ").append(item);
return this;
}

@Override
public MarkupDocBuilder tableWithHeaderRow(List<String> rowsInPSV) {
return this;
}

@Override
public MarkupDocBuilder tableWithColumnSpecs(List<MarkupTableColumn> columnSpecs, List<List<String>> cells) {
documentBuilder.append(newLine);
if (columnSpecs != null && !columnSpecs.isEmpty()) {
documentBuilder.append("||");
columnSpecs.forEach(spec -> documentBuilder.append(escapeCellContent(spec.header)).append("||"));
documentBuilder.append(newLine);
}
if (cells != null && !cells.isEmpty()) {
cells.forEach(row -> {
documentBuilder.append("|");
row.forEach(cell -> documentBuilder.append(escapeCellContent(cell)).append("|"));
documentBuilder.append(newLine);
});
}
return this;
}

private String escapeCellContent(String content) {
if (content == null) {
return " ";
}
return content.replace("|", "\\|").replace(newLine, "\\\\");
}

@Override
public MarkupDocBuilder anchor(String anchor, String text) {
documentBuilder.append("{anchor:").append(anchor).append("}");
return this;
}

@Override
public MarkupDocBuilder crossReferenceRaw(String document, String anchor, String text) {
crossReference(document, anchor, text);
return this;
}

@Override
public MarkupDocBuilder crossReference(String document, String anchor, String text) {
documentBuilder.append("[");
if (isNotBlank(document)) {
documentBuilder.append(document);
}
documentBuilder.append("#").append(anchor);
if (isNotBlank(text)) {
documentBuilder.append("|").append(document);
}
documentBuilder.append("]");
return this;
}

@Override
public MarkupDocBuilder newLine(boolean forceLineBreak) {
documentBuilder.append(" \\\\ ").append(newLine);
return this;
}

@Override
public MarkupDocBuilder importMarkup(Reader markupText, int levelOffset) throws IOException {
final BufferedReader reader = new BufferedReader(markupText);
reader.lines().forEach(documentBuilder::append);
return this;
}

@Override
public MarkupDocBuilder copy() {
return this;
}

@Override
public String addFileExtension(String fileName) {
return fileName + FILE_EXTENSION;
}
}

0 comments on commit 7e0d5bc

Please sign in to comment.