| /* | |
| * Copyright 2011 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.utils; | |
| import static org.pegdown.Extensions.ALL; | |
| import static org.pegdown.Extensions.SMARTYPANTS; | |
| import java.io.IOException; | |
| import java.io.Reader; | |
| import java.io.StringWriter; | |
| import java.text.MessageFormat; | |
| import org.apache.commons.io.IOUtils; | |
| import org.pegdown.LinkRenderer; | |
| import org.pegdown.ParsingTimeoutException; | |
| import org.pegdown.PegDownProcessor; | |
| import org.pegdown.ast.RootNode; | |
| import com.gitblit.IStoredSettings; | |
| import com.gitblit.Keys; | |
| import com.gitblit.wicket.MarkupProcessor.WorkaroundHtmlSerializer; | |
| /** | |
| * Utility methods for transforming raw markdown text to html. | |
| * | |
| * @author James Moger | |
| * | |
| */ | |
| public class MarkdownUtils { | |
| /** | |
| * Returns the html version of the plain source text. | |
| * | |
| * @param text | |
| * @return html version of plain text | |
| * @throws java.text.ParseException | |
| */ | |
| public static String transformPlainText(String text) { | |
| // url auto-linking | |
| text = text.replaceAll("((http|https)://[0-9A-Za-z-_=\\?\\.\\$#&/]*)", "<a href=\"$1\">$1</a>"); | |
| String html = "<pre>" + text + "</pre>"; | |
| return html; | |
| } | |
| /** | |
| * Returns the html version of the markdown source text. | |
| * | |
| * @param markdown | |
| * @return html version of markdown text | |
| * @throws java.text.ParseException | |
| */ | |
| public static String transformMarkdown(String markdown) { | |
| return transformMarkdown(markdown, null); | |
| } | |
| /** | |
| * Returns the html version of the markdown source text. | |
| * | |
| * @param markdown | |
| * @return html version of markdown text | |
| * @throws java.text.ParseException | |
| */ | |
| public static String transformMarkdown(String markdown, LinkRenderer linkRenderer) { | |
| try { | |
| PegDownProcessor pd = new PegDownProcessor(ALL & ~SMARTYPANTS); | |
| RootNode astRoot = pd.parseMarkdown(markdown.toCharArray()); | |
| return new WorkaroundHtmlSerializer(linkRenderer == null ? new LinkRenderer() : linkRenderer).toHtml(astRoot); | |
| } catch (ParsingTimeoutException e) { | |
| return null; | |
| } | |
| } | |
| /** | |
| * Returns the html version of the markdown source reader. The reader is | |
| * closed regardless of success or failure. | |
| * | |
| * @param markdownReader | |
| * @return html version of the markdown text | |
| * @throws java.text.ParseException | |
| */ | |
| public static String transformMarkdown(Reader markdownReader) throws IOException { | |
| // Read raw markdown content and transform it to html | |
| StringWriter writer = new StringWriter(); | |
| try { | |
| IOUtils.copy(markdownReader, writer); | |
| String markdown = writer.toString(); | |
| return transformMarkdown(markdown); | |
| } finally { | |
| try { | |
| writer.close(); | |
| } catch (IOException e) { | |
| // IGNORE | |
| } | |
| } | |
| } | |
| /** | |
| * Transforms GFM (Github Flavored Markdown) to html. | |
| * Gitblit does not support the complete GFM specification. | |
| * | |
| * @param input | |
| * @param repositoryName | |
| * @return html | |
| */ | |
| public static String transformGFM(IStoredSettings settings, String input, String repositoryName) { | |
| String text = input; | |
| // strikethrough | |
| text = text.replaceAll("~~(.*)~~", "<s>$1</s>"); | |
| text = text.replaceAll("\\{(?:-){2}(.*)(?:-){2}}", "<s>$1</s>"); | |
| // underline | |
| text = text.replaceAll("\\{(?:\\+){2}(.*)(?:\\+){2}}", "<u>$1</u>"); | |
| // strikethrough, replacement | |
| text = text.replaceAll("\\{~~(.*)~>(.*)~~}", "<s>$1</s><u>$2</u>"); | |
| // highlight | |
| text = text.replaceAll("\\{==(.*)==}", "<span class='highlight'>$1</span>"); | |
| String canonicalUrl = settings.getString(Keys.web.canonicalUrl, "https://localhost:8443"); | |
| // emphasize and link mentions | |
| String mentionReplacement = String.format(" **[@$1](%1s/user/$1)**", canonicalUrl); | |
| text = text.replaceAll("\\s@([A-Za-z0-9-_]+)", mentionReplacement); | |
| // link ticket refs | |
| String ticketReplacement = MessageFormat.format("$1[#$2]({0}/tickets?r={1}&h=$2)$3", canonicalUrl, repositoryName); | |
| text = text.replaceAll("([\\s,]+)#(\\d+)([\\s,:\\.\\n])", ticketReplacement); | |
| // link commit shas | |
| int shaLen = settings.getInteger(Keys.web.shortCommitIdLength, 6); | |
| String commitPattern = MessageFormat.format("\\s([A-Fa-f0-9]'{'{0}'}')([A-Fa-f0-9]'{'{1}'}')", shaLen, 40 - shaLen); | |
| String commitReplacement = String.format(" [`$1`](%1$s/commit?r=%2$s&h=$1$2)", canonicalUrl, repositoryName); | |
| text = text.replaceAll(commitPattern, commitReplacement); | |
| String html = transformMarkdown(text); | |
| return html; | |
| } | |
| } |