package cucumber.contrib.formatter.pdf; import com.itextpdf.text.Element; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.tool.xml.*; import com.itextpdf.tool.xml.css.CssFile; import com.itextpdf.tool.xml.css.CssFileImpl; import com.itextpdf.tool.xml.css.CssFilesImpl; import com.itextpdf.tool.xml.css.StyleAttrCSSResolver; import com.itextpdf.tool.xml.exceptions.CssResolverException; import com.itextpdf.tool.xml.html.TagProcessorFactory; import com.itextpdf.tool.xml.html.Tags; import com.itextpdf.tool.xml.parser.XMLParser; import com.itextpdf.tool.xml.pipeline.css.CSSResolver; import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline; import com.itextpdf.tool.xml.pipeline.end.ElementHandlerPipeline; import com.itextpdf.tool.xml.pipeline.html.AbstractImageProvider; import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline; import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext; import cucumber.contrib.formatter.pdf.html.*; import cucumber.contrib.formatter.util.BricABrac; import cucumber.contrib.formatter.FormatterException; import cucumber.contrib.util.Provider; import org.pegdown.LinkRenderer; import org.pegdown.PegDownProcessor; import org.pegdown.ToHtmlSerializer; import org.pegdown.ast.RootNode; import org.pegdown.plugins.ToHtmlSerializerPlugin; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.List; public class MarkdownEmitter { private final Configuration configuration; private final Provider<PdfWriter> writer; public MarkdownEmitter(Configuration configuration, Provider<PdfWriter> writer) { this.configuration = configuration; this.writer = writer; } public List<Element> markdownToElements(String markdownText) { try { ElementList elementList = new ElementList(); parseXHtml(elementList, formatHtmlAsReader(markdownText)); return elementList; } catch (IOException e) { throw new FormatterException("Failed to transform markdown content", e); } } // copied from XMLWorkerHelper private void parseXHtml(final ElementHandler d, final Reader in) throws IOException { CssFilesImpl cssFiles = new CssFilesImpl(); cssFiles.add(getDefaultCSS()); cssFiles.add(getHtmlCSS()); StyleAttrCSSResolver cssResolver = new StyleAttrCSSResolver(cssFiles) { @Override public void resolveStyles(Tag t) { configuration.resolveDefaultStyles(t); super.resolveStyles(t); } @Override public CSSResolver clear() throws CssResolverException { // prevent css files from being been removed return this; } }; HtmlPipelineContext hpc = new HtmlPipelineContext(null); final String imageRootPath = configuration.getImageRootPath(); if (imageRootPath != null) { hpc.setImageProvider(new AbstractImageProvider() { /** * @return a rootpath to set before the src attribute */ @Override public String getImageRootPath() { return imageRootPath; } }); } hpc.setAcceptUnknown(true).autoBookmark(true).setTagFactory(getDefaultTagProcessorFactory()); Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(hpc, new ElementHandlerPipeline(d, null))); XMLWorker worker = new XMLWorker(pipeline, true); XMLParser p = new XMLParser(); p.addListener(worker); p.parse(in); } private CssFile getDefaultCSS() { return XMLWorkerHelper.getInstance().getDefaultCSS(); } private CssFile getHtmlCSS() { CssFileImpl cssFile = new CssFileImpl(); configuration.fillDefaultHtmlCSS(cssFile); return cssFile; } private TagProcessorFactory getDefaultTagProcessorFactory() { TagProcessorFactory tpf = Tags.getHtmlTagProcessorFactory(); tpf.addProcessor(new HeaderProcessor(configuration, 1), "h1"); tpf.addProcessor(new HeaderProcessor(configuration, 2), "h2"); tpf.addProcessor(new ImageProcessor(), "img"); tpf.addProcessor(new GralProcessor(writer), "gral"); tpf.addProcessor(new TableDataHeaderProcessor(configuration), "th"); tpf.addProcessor(new TableDataContentProcessor(configuration), "td"); return tpf; } StringReader formatHtmlAsReader(String text) { String html = formatHtml(text); return new StringReader(html); } private String formatHtml(String text) { if (BricABrac.isBlank(text)) { return ""; } PegDownProcessor markdownProcessor = configuration.getMarkdownProcessor(); RootNode astRoot = markdownProcessor.parseMarkdown(text.toCharArray()); //astRoot.accept(Visitors.dump()); List<ToHtmlSerializerPlugin> htmlPlugins = configuration.htmlSerializerPlugins(); ToHtmlSerializer htmlSerializer = new ToHtmlSerializer(new LinkRenderer(), htmlPlugins); return htmlSerializer.toHtml(astRoot); } }