/* * Copyright 2014 gitblit.com. * * 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 com.gitblit.plugin.slack; import org.pegdown.LinkRenderer; import org.pegdown.ToHtmlSerializer; import org.pegdown.ast.SimpleNode; import org.pegdown.ast.SuperNode; import org.pegdown.ast.TextNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Slack only supports a minimal set of markup syntax. This class helps generate Slack-friendly * content from richer Markdown text. If there is no equivalent Slack markup, the plain HTML is * injected. This is not ideal, but it's better than injecting all HTML messages into your Slack * channels. * * @author James Moger * */ public class SlackMarkupSerializer extends ToHtmlSerializer { private final Logger log = LoggerFactory.getLogger(getClass()); public SlackMarkupSerializer() { super(new LinkRenderer()); } @Override public void visit(SimpleNode node) { switch (node.getType()) { case Linebreak: printer.print("\n"); break; case Nbsp: printer.print(" "); break; default: super.visit(node); } } @Override protected void printTag(TextNode node, String tag) { String pre = ""; String post = ""; switch (tag.toLowerCase()) { case "b": case "strong": pre = post = "*"; break; case "i": case "em": pre = post = "_"; break; case "p": post = "\n\n"; break; case "br": post = "\n"; break; case "code": pre = post = "`"; break; case "pre": pre = post = "```\n"; break; case "blockquote": pre = "> "; break; case "ul": case "ol": pre = post = "\n"; break; case "li": pre = " - "; post = "\n"; break; default: // unsupported transform type log.warn("Slack does not offer a markup substitute for tag {}", tag); pre = String.format("<%s>", tag); post = String.format("</%s>", tag); } printer.print(pre); printer.printEncoded(node.getText()); printer.print(post); } @Override protected void printTag(SuperNode node, String tag) { String pre = ""; String post = ""; switch (tag.toLowerCase()) { case "b": case "strong": pre = post = "*"; break; case "i": case "em": pre = post = "_"; break; case "p": post = "\n\n"; break; case "br": post = "\n"; break; case "code": pre = post = "`"; break; case "pre": pre = post = "```\n"; break; case "blockquote": pre = "> "; break; default: // unsupported transform type log.warn("Slack does not offer a markup substitute for tag {}", tag); pre = String.format("<%s>", tag); post = String.format("</%s>", tag); } printer.print(pre); visitChildren(node); printer.print(post); } @Override protected void printIndentedTag(SuperNode node, String tag) { printTag(node, tag); } @Override protected void printImageTag(LinkRenderer.Rendering rendering) { printer.print('<').print(rendering.href).print('>'); } @Override protected void printLink(LinkRenderer.Rendering rendering) { printer.print('<').print(rendering.href).print('|').print(rendering.text).print('>'); } }