MarkdownTransformer.java 7.8 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.cq.dam.cfm.ContentFragmentException
 *  com.petebevin.markdown.MarkdownProcessor
 *  org.apache.sling.xss.XSSAPI
 *  org.jsoup.Jsoup
 *  org.jsoup.nodes.Document
 *  org.jsoup.nodes.Element
 *  org.jsoup.nodes.Node
 *  org.jsoup.nodes.TextNode
 *  org.jsoup.select.NodeVisitor
 */
package com.adobe.cq.dam.cfm.impl.transformer;

import com.adobe.cq.dam.cfm.ContentFragmentException;
import com.adobe.cq.dam.cfm.impl.transformer.Transformer;
import com.petebevin.markdown.MarkdownProcessor;
import org.apache.sling.xss.XSSAPI;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.NodeVisitor;

public class MarkdownTransformer
implements Transformer {
    @Override
    public String getContentType() {
        return "text/x-markdown";
    }

    @Override
    public String fromHTML(String html) throws ContentFragmentException {
        final StringBuilder result = new StringBuilder();
        Document doc = Jsoup.parse((String)html, (String)"UTF-8");
        doc.traverse(new NodeVisitor(){
            int listDepth;

            public void head(Node node, int depth) {
                if (node instanceof TextNode) {
                    TextNode textNode = (TextNode)node;
                    result.append(textNode.text());
                } else if (node instanceof Element) {
                    Element element = (Element)node;
                    HTMLTags tagName = HTMLTags.getByName(element.tagName());
                    switch (tagName) {
                        case H1: {
                            result.append("\n# ");
                            break;
                        }
                        case H2: {
                            result.append("\n## ");
                            break;
                        }
                        case H3: {
                            result.append("\n### ");
                            break;
                        }
                        case H4: {
                            result.append("\n#### ");
                            break;
                        }
                        case H5: {
                            result.append("\n##### ");
                            break;
                        }
                        case HR: {
                            result.append("\n***\n");
                            break;
                        }
                        case OL: 
                        case UL: {
                            ++this.listDepth;
                            break;
                        }
                        case LI: {
                            boolean numericList = element.parent().tagName().equals("ol");
                            for (int i = 0; i < this.listDepth - 1; ++i) {
                                result.append(" ");
                            }
                            result.append(numericList ? "1. " : "* ");
                            break;
                        }
                        case B: 
                        case STRONG: {
                            result.append("**");
                            break;
                        }
                        case BR: {
                            result.append("\n");
                            break;
                        }
                        case I: 
                        case EM: {
                            result.append("_");
                            break;
                        }
                        case PRE: {
                            result.append("```\n");
                            break;
                        }
                        case CODE: {
                            result.append("`");
                            break;
                        }
                        case A: {
                            String href = element.attr("href");
                            if (href == null || href.length() <= 0) break;
                            result.append("[");
                            break;
                        }
                        case IMG: {
                            String src = element.attr("src");
                            String alt = element.attr("alt");
                            if (src == null || src.length() <= 0) break;
                            if (alt == null || "".equals(alt)) {
                                alt = "";
                            }
                            result.append("![").append(alt).append("](").append(src).append(")\n");
                            break;
                        }
                    }
                }
            }

            public void tail(Node node, int depth) {
                if (node instanceof Element) {
                    Element element = (Element)node;
                    HTMLTags tagName = HTMLTags.getByName(element.tagName());
                    switch (tagName) {
                        case H1: 
                        case H2: 
                        case H3: 
                        case H4: 
                        case H5: 
                        case LI: {
                            result.append("\n");
                            break;
                        }
                        case OL: 
                        case UL: {
                            --this.listDepth;
                            break;
                        }
                        case B: 
                        case STRONG: {
                            result.append("**");
                            break;
                        }
                        case I: 
                        case EM: {
                            result.append("_");
                            break;
                        }
                        case P: {
                            result.append("\n\n");
                            break;
                        }
                        case PRE: {
                            result.append("\n```\n");
                            break;
                        }
                        case CODE: {
                            result.append("`");
                            break;
                        }
                        case A: {
                            String href = element.attr("href");
                            if (href == null || href.length() <= 0) break;
                            result.append(']').append('(').append(href).append(')');
                            break;
                        }
                    }
                }
            }
        });
        return result.toString();
    }

    @Override
    public String toHTML(String formattedText, XSSAPI xss) throws ContentFragmentException {
        MarkdownProcessor markdownProcessor = new MarkdownProcessor();
        return markdownProcessor.markdown(formattedText);
    }

    private static enum HTMLTags {
        A("A"),
        H1("H1"),
        H2("H2"),
        H3("H3"),
        H4("H4"),
        H5("H5"),
        HR("HR"),
        B("B"),
        BR("BR"),
        STRONG("STRONG"),
        I("I"),
        EM("EM"),
        P("P"),
        PRE("PRE"),
        CODE("CODE"),
        UL("UL"),
        OL("OL"),
        LI("LI"),
        IMG("IMG"),
        NOT_SUPPORTED("");
        
        private String tag;

        private HTMLTags(String tag) {
            this.tag = tag;
        }

        public String toString() {
            return this.tag;
        }

        public static HTMLTags getByName(String tagName) {
            HTMLTags tag;
            try {
                tag = HTMLTags.valueOf(tagName.toUpperCase());
            }
            catch (IllegalArgumentException e) {
                tag = NOT_SUPPORTED;
            }
            return tag;
        }
    }

}