import com.gitblit.utils.JGitUtils;\r
import com.gitblit.utils.MarkdownUtils;\r
import com.gitblit.utils.StringUtils;\r
+import com.gitblit.wicket.MarkupProcessor;\r
+import com.gitblit.wicket.MarkupProcessor.MarkupDocument;\r
\r
/**\r
* Serves the content of a gh-pages branch.\r
return;\r
}\r
\r
+ MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings());\r
String [] encodings = GitBlit.getEncodings();\r
\r
RevTree tree = commit.getTree();\r
byte[] content = null;\r
if (StringUtils.isEmpty(resource)) {\r
// find resource\r
- List<String> markdownExtensions = GitBlit.getStrings(Keys.web.markdownExtensions);\r
- List<String> extensions = new ArrayList<String>(markdownExtensions.size() + 2);\r
+ List<String> extensions = new ArrayList<String>(processor.getMarkupExtensions());\r
extensions.add("html");\r
extensions.add("htm");\r
- extensions.addAll(markdownExtensions);\r
- for (String ext : extensions){\r
+ for (String ext : extensions) {\r
String file = "index." + ext;\r
String stringContent = JGitUtils.getStringContent(r, tree, file, encodings);\r
- if(stringContent == null){\r
+ if (stringContent == null) {\r
continue;\r
}\r
content = stringContent.getBytes(Constants.ENCODING);\r
return;\r
}\r
\r
- // check to see if we should transform markdown files\r
- for (String ext : GitBlit.getStrings(Keys.web.markdownExtensions)) {\r
- if (resource.endsWith(ext)) {\r
- String mkd = new String(content, Constants.ENCODING);\r
- content = MarkdownUtils.transformMarkdown(mkd).getBytes(Constants.ENCODING);\r
- response.setContentType("text/html; charset=" + Constants.ENCODING);\r
- break;\r
- }\r
+ // check to see if we should transform markup files\r
+ String ext = StringUtils.getFileExtension(resource);\r
+ if (processor.getMarkupExtensions().contains(ext)) {\r
+ String markup = new String(content, Constants.ENCODING);\r
+ MarkupDocument markupDoc = processor.parse(repository, commit.getName(), resource, markup);\r
+ content = markupDoc.html.getBytes("UTF-8");\r
+ response.setContentType("text/html; charset=" + Constants.ENCODING);\r
}\r
\r
try {\r
return "";\r
}\r
\r
+ /**\r
+ * Returns the file extension of a path.\r
+ *\r
+ * @param path\r
+ * @return a blank string or a file extension\r
+ */\r
+ public static String stripFileExtension(String path) {\r
+ int lastDot = path.lastIndexOf('.');\r
+ if (lastDot > -1) {\r
+ return path.substring(0, lastDot);\r
+ }\r
+ return path;\r
+ }\r
+\r
/**\r
* Replace all occurences of a substring within a string with\r
* another string.\r
import com.gitblit.wicket.pages.CommitDiffPage;\r
import com.gitblit.wicket.pages.CommitPage;\r
import com.gitblit.wicket.pages.ComparePage;\r
+import com.gitblit.wicket.pages.DocPage;\r
import com.gitblit.wicket.pages.DocsPage;\r
import com.gitblit.wicket.pages.FederationRegistrationPage;\r
import com.gitblit.wicket.pages.ForkPage;\r
import com.gitblit.wicket.pages.LogPage;\r
import com.gitblit.wicket.pages.LogoutPage;\r
import com.gitblit.wicket.pages.LuceneSearchPage;\r
-import com.gitblit.wicket.pages.MarkdownPage;\r
import com.gitblit.wicket.pages.MetricsPage;\r
import com.gitblit.wicket.pages.MyDashboardPage;\r
import com.gitblit.wicket.pages.OverviewPage;\r
mount("/users", UsersPage.class);\r
mount("/logout", LogoutPage.class);\r
\r
- // setup the markdown urls\r
+ // setup the markup document urls\r
mount("/docs", DocsPage.class, "r");\r
- mount("/markdown", MarkdownPage.class, "r", "h", "f");\r
+ mount("/doc", DocPage.class, "r", "h", "f");\r
\r
// federation urls\r
mount("/proposal", ReviewProposalPage.class, "t");\r
--- /dev/null
+/*\r
+ * Copyright 2013 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.wicket;\r
+\r
+import java.io.Serializable;\r
+import java.io.UnsupportedEncodingException;\r
+import java.net.URLEncoder;\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.apache.wicket.Page;\r
+import org.apache.wicket.RequestCycle;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.revwalk.RevCommit;\r
+import org.pegdown.LinkRenderer;\r
+import org.pegdown.ast.WikiLinkNode;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.gitblit.IStoredSettings;\r
+import com.gitblit.Keys;\r
+import com.gitblit.models.PathModel;\r
+import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.MarkdownUtils;\r
+import com.gitblit.utils.StringUtils;\r
+import com.gitblit.wicket.pages.DocPage;\r
+\r
+/**\r
+ * Processes markup content and generates html with repository-relative page and\r
+ * image linking.\r
+ *\r
+ * @author James Moger\r
+ *\r
+ */\r
+public class MarkupProcessor {\r
+\r
+ public enum MarkupSyntax {\r
+ PLAIN, MARKDOWN\r
+ }\r
+\r
+ private Logger logger = LoggerFactory.getLogger(getClass());\r
+\r
+ private final IStoredSettings settings;\r
+\r
+ public MarkupProcessor(IStoredSettings settings) {\r
+ this.settings = settings;\r
+ }\r
+\r
+ public List<String> getMarkupExtensions() {\r
+ List<String> list = new ArrayList<String>();\r
+ list.addAll(settings.getStrings(Keys.web.markdownExtensions));\r
+ return list;\r
+ }\r
+\r
+ private MarkupSyntax determineSyntax(String documentPath) {\r
+ String ext = StringUtils.getFileExtension(documentPath).toLowerCase();\r
+ if (StringUtils.isEmpty(ext)) {\r
+ return MarkupSyntax.PLAIN;\r
+ }\r
+\r
+ if (settings.getStrings(Keys.web.markdownExtensions).contains(ext)) {\r
+ return MarkupSyntax.MARKDOWN;\r
+ }\r
+\r
+ return MarkupSyntax.PLAIN;\r
+ }\r
+\r
+ public MarkupDocument parseReadme(Repository r, String repositoryName, String commitId) {\r
+ String readme = null;\r
+ RevCommit commit = JGitUtils.getCommit(r, commitId);\r
+ List<PathModel> paths = JGitUtils.getFilesInPath(r, null, commit);\r
+ for (PathModel path : paths) {\r
+ if (!path.isTree()) {\r
+ String name = path.name.toLowerCase();\r
+ if (name.equals("readme") || name.equals("readme.txt")) {\r
+ readme = path.name;\r
+ break;\r
+ } else if (name.startsWith("readme.")) {\r
+ String ext = StringUtils.getFileExtension(name).toLowerCase();\r
+ if (getMarkupExtensions().contains(ext)) {\r
+ readme = path.name;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!StringUtils.isEmpty(readme)) {\r
+ String [] encodings = settings.getStrings(Keys.web.blobEncodings).toArray(new String[0]);\r
+ String markup = JGitUtils.getStringContent(r, commit.getTree(), readme, encodings);\r
+ return parse(repositoryName, commitId, readme, markup);\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ public MarkupDocument parse(String repositoryName, String commitId, String documentPath, String markupText) {\r
+ final MarkupSyntax syntax = determineSyntax(documentPath);\r
+ final MarkupDocument doc = new MarkupDocument(documentPath, markupText, syntax);\r
+\r
+ if (markupText != null) {\r
+ try {\r
+ switch (syntax){\r
+ case MARKDOWN:\r
+ parse(doc, repositoryName, commitId);\r
+ break;\r
+ default:\r
+ doc.html = MarkdownUtils.transformPlainText(markupText);\r
+ break;\r
+ }\r
+ } catch (Exception e) {\r
+ logger.error("failed to transform " + syntax, e);\r
+ }\r
+ }\r
+\r
+ if (doc.html == null) {\r
+ // failed to transform markup\r
+ if (markupText == null) {\r
+ markupText = String.format("Document <b>%1$s</b> not found in <em>%2$s</em>", documentPath, repositoryName);\r
+ }\r
+ markupText = MessageFormat.format("<div class=\"alert alert-error\"><strong>{0}:</strong> {1}</div>{2}", "Error", "failed to parse markup", markupText);\r
+ doc.html = StringUtils.breakLinesForHtml(markupText);\r
+ }\r
+\r
+ return doc;\r
+ }\r
+\r
+ /**\r
+ * Parses the document as Markdown using Pegdown.\r
+ *\r
+ * @param doc\r
+ * @param repositoryName\r
+ * @param commitId\r
+ */\r
+ private void parse(final MarkupDocument doc, final String repositoryName, final String commitId) {\r
+ LinkRenderer renderer = new LinkRenderer() {\r
+ @Override\r
+ public Rendering render(WikiLinkNode node) {\r
+ String path = doc.getRelativePath(node.getText());\r
+ String name = getDocumentName(path);\r
+ String url = getWicketUrl(DocPage.class, repositoryName, commitId, path);\r
+ return new Rendering(url, name);\r
+ }\r
+ };\r
+ doc.html = MarkdownUtils.transformMarkdown(doc.markup, renderer);\r
+ }\r
+\r
+ private String getWicketUrl(Class<? extends Page> pageClass, final String repositoryName, final String commitId, final String document) {\r
+ String fsc = settings.getString(Keys.web.forwardSlashCharacter, "/");\r
+ String encodedPath = document.replace(' ', '-');\r
+ try {\r
+ encodedPath = URLEncoder.encode(encodedPath, "UTF-8");\r
+ } catch (UnsupportedEncodingException e) {\r
+ logger.error(null, e);\r
+ }\r
+ encodedPath = encodedPath.replace("/", fsc).replace("%2F", fsc);\r
+\r
+ String url = RequestCycle.get().urlFor(pageClass, WicketUtils.newPathParameter(repositoryName, commitId, encodedPath)).toString();\r
+ return url;\r
+ }\r
+\r
+ private String getDocumentName(final String document) {\r
+ // extract document name\r
+ String name = StringUtils.stripFileExtension(document);\r
+ name = name.replace('_', ' ');\r
+ if (name.indexOf('/') > -1) {\r
+ name = name.substring(name.lastIndexOf('/') + 1);\r
+ }\r
+ return name;\r
+ }\r
+\r
+ public static class MarkupDocument implements Serializable {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public final String documentPath;\r
+ public final String markup;\r
+ public final MarkupSyntax syntax;\r
+ public String html;\r
+\r
+ MarkupDocument(String documentPath, String markup, MarkupSyntax syntax) {\r
+ this.documentPath = documentPath;\r
+ this.markup = markup;\r
+ this.syntax = syntax;\r
+ }\r
+\r
+ String getCurrentPath() {\r
+ String basePath = "";\r
+ if (documentPath.indexOf('/') > -1) {\r
+ basePath = documentPath.substring(0, documentPath.lastIndexOf('/') + 1);\r
+ if (basePath.charAt(0) == '/') {\r
+ return basePath.substring(1);\r
+ }\r
+ }\r
+ return basePath;\r
+ }\r
+\r
+ String getRelativePath(String ref) {\r
+ return ref.charAt(0) == '/' ? ref.substring(1) : (getCurrentPath() + ref);\r
+ }\r
+ }\r
+}\r
import java.util.Collection;\r
import java.util.Date;\r
import java.util.HashMap;\r
-import java.util.List;\r
import java.util.Map;\r
import java.util.TimeZone;\r
\r
return newImage(wicketId, "file_settings_16x16.png");\r
}\r
\r
- List<String> mdExtensions = GitBlit.getStrings(Keys.web.markdownExtensions);\r
- for (String ext : mdExtensions) {\r
- if (filename.endsWith('.' + ext.toLowerCase())) {\r
- return newImage(wicketId, "file_world_16x16.png");\r
- }\r
+ MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings());\r
+ String ext = StringUtils.getFileExtension(filename).toLowerCase();\r
+ if (processor.getMarkupExtensions().contains(ext)) {\r
+ return newImage(wicketId, "file_world_16x16.png");\r
}\r
return newImage(wicketId, "file_16x16.png");\r
}\r
import com.gitblit.wicket.CacheControl;\r
import com.gitblit.wicket.CacheControl.LastModified;\r
import com.gitblit.wicket.ExternalImage;\r
+import com.gitblit.wicket.MarkupProcessor;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.panels.CommitHeaderPanel;\r
import com.gitblit.wicket.panels.PathBreadcrumbsPanel;\r
extension = blobPath.substring(blobPath.lastIndexOf('.') + 1).toLowerCase();\r
}\r
\r
- // see if we should redirect to the markdown page\r
- for (String ext : GitBlit.getStrings(Keys.web.markdownExtensions)) {\r
+ // see if we should redirect to the doc page\r
+ MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings());\r
+ for (String ext : processor.getMarkupExtensions()) {\r
if (ext.equals(extension)) {\r
- setResponsePage(MarkdownPage.class, params);\r
+ setResponsePage(DocPage.class, params);\r
return;\r
}\r
}\r
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" \r
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" \r
+ xml:lang="en" \r
+ lang="en">\r
+\r
+<body>\r
+<wicket:extend>\r
+ <!-- doc nav links --> \r
+ <div class="page_nav2">\r
+ <a wicket:id="blameLink"><wicket:message key="gb.blame"></wicket:message></a> | <a wicket:id="historyLink"><wicket:message key="gb.history"></wicket:message></a> | <a wicket:id="rawLink"><wicket:message key="gb.raw"></wicket:message></a> | <a wicket:id="headLink"><wicket:message key="gb.head"></wicket:message></a>\r
+ </div> \r
+ \r
+ <!-- document content -->\r
+ <div class="markdown" style="padding-bottom:5px;" wicket:id="content">[content]</div>\r
+</wicket:extend>\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.wicket.pages;\r
+\r
+import java.util.List;\r
+\r
+import org.apache.wicket.PageParameters;\r
+import org.apache.wicket.markup.html.basic.Label;\r
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.eclipse.jgit.lib.Constants;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.revwalk.RevCommit;\r
+\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.StringUtils;\r
+import com.gitblit.wicket.CacheControl;\r
+import com.gitblit.wicket.CacheControl.LastModified;\r
+import com.gitblit.wicket.MarkupProcessor;\r
+import com.gitblit.wicket.MarkupProcessor.MarkupDocument;\r
+import com.gitblit.wicket.WicketUtils;\r
+\r
+@CacheControl(LastModified.BOOT)\r
+public class DocPage extends RepositoryPage {\r
+\r
+ public DocPage(PageParameters params) {\r
+ super(params);\r
+\r
+ final String path = WicketUtils.getPath(params).replace("%2f", "/").replace("%2F", "/");\r
+ MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings());\r
+\r
+ Repository r = getRepository();\r
+ RevCommit commit = JGitUtils.getCommit(r, objectId);\r
+ String [] encodings = GitBlit.getEncodings();\r
+\r
+ // Read raw markup content and transform it to html\r
+ String documentPath = path;\r
+ String markupText = JGitUtils.getStringContent(r, commit.getTree(), path, encodings);\r
+\r
+ // Hunt for document\r
+ if (StringUtils.isEmpty(markupText)) {\r
+ String name = StringUtils.stripFileExtension(path);\r
+\r
+ List<String> docExtensions = processor.getMarkupExtensions();\r
+ for (String ext : docExtensions) {\r
+ String checkName = name + "." + ext;\r
+ markupText = JGitUtils.getStringContent(r, commit.getTree(), checkName, encodings);\r
+ if (!StringUtils.isEmpty(markupText)) {\r
+ // found it\r
+ documentPath = path;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ // document page links\r
+ add(new BookmarkablePageLink<Void>("blameLink", BlamePage.class,\r
+ WicketUtils.newPathParameter(repositoryName, objectId, documentPath)));\r
+ add(new BookmarkablePageLink<Void>("historyLink", HistoryPage.class,\r
+ WicketUtils.newPathParameter(repositoryName, objectId, documentPath)));\r
+ add(new BookmarkablePageLink<Void>("rawLink", RawPage.class, WicketUtils.newPathParameter(\r
+ repositoryName, objectId, documentPath)));\r
+ add(new BookmarkablePageLink<Void>("headLink", DocPage.class,\r
+ WicketUtils.newPathParameter(repositoryName, Constants.HEAD, documentPath)));\r
+\r
+ MarkupDocument markupDoc = processor.parse(repositoryName, getBestCommitId(commit), documentPath, markupText);\r
+ add(new Label("content", markupDoc.html).setEscapeModelStrings(false));\r
+ }\r
+\r
+ @Override\r
+ protected String getPageName() {\r
+ return getString("gb.docs");\r
+ }\r
+\r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return DocsPage.class;\r
+ }\r
+}\r
import org.eclipse.jgit.revwalk.RevCommit;\r
\r
import com.gitblit.GitBlit;\r
-import com.gitblit.Keys;\r
import com.gitblit.models.PathModel;\r
import com.gitblit.utils.ByteFormat;\r
import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.MarkdownUtils;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.CacheControl;\r
import com.gitblit.wicket.CacheControl.LastModified;\r
+import com.gitblit.wicket.MarkupProcessor;\r
+import com.gitblit.wicket.MarkupProcessor.MarkupDocument;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.panels.LinkPanel;\r
\r
public DocsPage(PageParameters params) {\r
super(params);\r
\r
+ MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings());\r
+\r
Repository r = getRepository();\r
RevCommit head = JGitUtils.getCommit(r, null);\r
- List<String> extensions = GitBlit.getStrings(Keys.web.markdownExtensions);\r
+ List<String> extensions = processor.getMarkupExtensions();\r
List<PathModel> paths = JGitUtils.getDocuments(r, extensions);\r
\r
String doc = null;\r
- String markdown = null;\r
+ String markup = null;\r
String html = null;\r
\r
List<String> roots = Arrays.asList("home");\r
// try to find a custom index/root page\r
for (PathModel path : paths) {\r
String name = path.name.toLowerCase();\r
- if (name.indexOf('.') > -1) {\r
- name = name.substring(0, name.lastIndexOf('.'));\r
- }\r
+ name = StringUtils.stripFileExtension(name);\r
if (roots.contains(name)) {\r
doc = path.name;\r
break;\r
if (!StringUtils.isEmpty(doc)) {\r
// load the document\r
String [] encodings = GitBlit.getEncodings();\r
- markdown = JGitUtils.getStringContent(r, head.getTree(), doc, encodings);\r
- html = MarkdownUtils.transformMarkdown(markdown, getMarkdownLinkRenderer());\r
+ markup = JGitUtils.getStringContent(r, head.getTree(), doc, encodings);\r
+\r
+ // parse document\r
+ MarkupDocument markupDoc = processor.parse(repositoryName, getBestCommitId(head), doc, markup);\r
+ html = markupDoc.html;\r
}\r
\r
Fragment fragment = null;\r
PathModel entry = item.getModelObject();\r
item.add(WicketUtils.newImage("docIcon", "file_world_16x16.png"));\r
item.add(new Label("docSize", byteFormat.format(entry.size)));\r
- item.add(new LinkPanel("docName", "list", entry.name, MarkdownPage.class, WicketUtils\r
+ item.add(new LinkPanel("docName", "list", entry.name, DocPage.class, WicketUtils\r
.newPathParameter(repositoryName, id, entry.path)));\r
\r
// links\r
- item.add(new BookmarkablePageLink<Void>("view", MarkdownPage.class, WicketUtils\r
+ item.add(new BookmarkablePageLink<Void>("view", DocPage.class, WicketUtils\r
.newPathParameter(repositoryName, id, entry.path)));\r
item.add(new BookmarkablePageLink<Void>("raw", RawPage.class, WicketUtils\r
.newPathParameter(repositoryName, id, entry.path)));\r
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml" \r
- xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" \r
- xml:lang="en" \r
- lang="en">\r
-\r
-<body>\r
-<wicket:extend>\r
- <!-- markdown nav links --> \r
- <div class="page_nav2">\r
- <a wicket:id="blameLink"><wicket:message key="gb.blame"></wicket:message></a> | <a wicket:id="historyLink"><wicket:message key="gb.history"></wicket:message></a> | <a wicket:id="rawLink"><wicket:message key="gb.raw"></wicket:message></a> | <a wicket:id="headLink"><wicket:message key="gb.head"></wicket:message></a>\r
- </div> \r
- \r
- <!-- markdown content -->\r
- <div class="markdown" style="padding-bottom:5px;" wicket:id="markdownText">[markdown content]</div>\r
-</wicket:extend>\r
-</body>\r
-</html>
\ No newline at end of file
+++ /dev/null
-/*\r
- * Copyright 2011 gitblit.com.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.gitblit.wicket.pages;\r
-\r
-import java.text.MessageFormat;\r
-import java.util.List;\r
-\r
-import org.apache.wicket.PageParameters;\r
-import org.apache.wicket.markup.html.basic.Label;\r
-import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
-import org.eclipse.jgit.lib.Constants;\r
-import org.eclipse.jgit.lib.Repository;\r
-import org.eclipse.jgit.revwalk.RevCommit;\r
-\r
-import com.gitblit.GitBlit;\r
-import com.gitblit.Keys;\r
-import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.MarkdownUtils;\r
-import com.gitblit.utils.StringUtils;\r
-import com.gitblit.wicket.CacheControl;\r
-import com.gitblit.wicket.CacheControl.LastModified;\r
-import com.gitblit.wicket.WicketUtils;\r
-\r
-@CacheControl(LastModified.BOOT)\r
-public class MarkdownPage extends RepositoryPage {\r
-\r
- public MarkdownPage(PageParameters params) {\r
- super(params);\r
-\r
- final String path = WicketUtils.getPath(params).replace("%2f", "/").replace("%2F", "/");\r
-\r
- Repository r = getRepository();\r
- RevCommit commit = JGitUtils.getCommit(r, objectId);\r
- String [] encodings = GitBlit.getEncodings();\r
- List<String> extensions = GitBlit.getStrings(Keys.web.markdownExtensions);\r
-\r
- // Read raw markdown content and transform it to html\r
- String markdownPath = path;\r
- String markdownText = JGitUtils.getStringContent(r, commit.getTree(), path, encodings);\r
- if (StringUtils.isEmpty(markdownText)) {\r
- String name = path;\r
- if (path.indexOf('.') > -1) {\r
- name = path.substring(0, path.lastIndexOf('.'));\r
- }\r
-\r
- for (String ext : extensions) {\r
- String checkName = name + "." + ext;\r
- markdownText = JGitUtils.getStringContent(r, commit.getTree(), checkName, encodings);\r
- if (!StringUtils.isEmpty(markdownText)) {\r
- // found it\r
- markdownPath = path;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- // markdown page links\r
- add(new BookmarkablePageLink<Void>("blameLink", BlamePage.class,\r
- WicketUtils.newPathParameter(repositoryName, objectId, markdownPath)));\r
- add(new BookmarkablePageLink<Void>("historyLink", HistoryPage.class,\r
- WicketUtils.newPathParameter(repositoryName, objectId, markdownPath)));\r
- add(new BookmarkablePageLink<Void>("rawLink", RawPage.class, WicketUtils.newPathParameter(\r
- repositoryName, objectId, markdownPath)));\r
- add(new BookmarkablePageLink<Void>("headLink", MarkdownPage.class,\r
- WicketUtils.newPathParameter(repositoryName, Constants.HEAD, markdownPath)));\r
-\r
- String htmlText;\r
- try {\r
- htmlText = MarkdownUtils.transformMarkdown(markdownText, getMarkdownLinkRenderer());\r
- } catch (Exception e) {\r
- logger.error("failed to transform markdown", e);\r
- if (markdownText == null) {\r
- markdownText = String.format("Markdown document <b>%1$s</b> not found in <em>%2$s</em>", markdownPath, repositoryName);\r
- }\r
- markdownText = MessageFormat.format("<div class=\"alert alert-error\"><strong>{0}:</strong> {1}</div>{2}", getString("gb.error"), getString("gb.markdownFailure"), markdownText);\r
- htmlText = StringUtils.breakLinesForHtml(markdownText);\r
- }\r
-\r
- // Add the html to the page\r
- add(new Label("markdownText", htmlText).setEscapeModelStrings(false));\r
- }\r
-\r
- @Override\r
- protected String getPageName() {\r
- return getString("gb.markdown");\r
- }\r
-\r
- @Override\r
- protected Class<? extends BasePage> getRepoNavPageClass() {\r
- return DocsPage.class;\r
- }\r
-}\r
package com.gitblit.wicket.pages;\r
\r
import java.io.Serializable;\r
-import java.io.UnsupportedEncodingException;\r
-import java.net.URLEncoder;\r
import java.text.MessageFormat;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
import org.eclipse.jgit.lib.PersonIdent;\r
import org.eclipse.jgit.lib.Repository;\r
import org.eclipse.jgit.revwalk.RevCommit;\r
-import org.pegdown.LinkRenderer;\r
-import org.pegdown.ast.WikiLinkNode;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
return isOwner;\r
}\r
\r
- /**\r
- * Returns a Pegdown/Markdown link renderer which renders WikiLinks.\r
- *\r
- * @return a link renderer\r
- */\r
- protected LinkRenderer getMarkdownLinkRenderer() {\r
- RevCommit head = JGitUtils.getCommit(r, "HEAD");\r
- final String id = getBestCommitId(head);\r
- LinkRenderer renderer = new LinkRenderer() {\r
- @Override\r
- public Rendering render(WikiLinkNode node) {\r
- try {\r
- String fsc = GitBlit.getString(Keys.web.forwardSlashCharacter, "/");\r
- // adjust the request path\r
- String path = node.getText().charAt(0) == '/' ? node.getText().substring(1) : node.getText();\r
- path = URLEncoder.encode(path.replace(' ', '-'), "UTF-8").replace("%2F", fsc);\r
-\r
- // extract document name\r
- String name = node.getText().replace('_', ' ');\r
- if (name.indexOf('/') > -1) {\r
- name = name.substring(name.lastIndexOf('/') + 1);\r
- }\r
-\r
- // strip Markdown extension\r
- for (String ext : GitBlit.getStrings(Keys.web.markdownExtensions)) {\r
- String x = "." + ext;\r
- if (name.endsWith(x)) {\r
- name = name.substring(0, name.length() - x.length());\r
- break;\r
- }\r
- }\r
- String url = urlFor(MarkdownPage.class, WicketUtils.newPathParameter(repositoryName, id, path)).toString();\r
- return new Rendering(url, name);\r
- } catch (UnsupportedEncodingException e) {\r
- throw new IllegalStateException();\r
- }\r
- }\r
- };\r
- return renderer;\r
- }\r
-\r
private class SearchForm extends SessionlessForm<Void> implements Serializable {\r
private static final long serialVersionUID = 1L;\r
\r
import com.gitblit.GitBlit;\r
import com.gitblit.Keys;\r
import com.gitblit.models.Metric;\r
-import com.gitblit.models.PathModel;\r
import com.gitblit.models.RepositoryModel;\r
import com.gitblit.models.UserModel;\r
import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.MarkdownUtils;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.CacheControl;\r
import com.gitblit.wicket.CacheControl.LastModified;\r
import com.gitblit.wicket.GitBlitWebSession;\r
+import com.gitblit.wicket.MarkupProcessor;\r
+import com.gitblit.wicket.MarkupProcessor.MarkupDocument;\r
+import com.gitblit.wicket.MarkupProcessor.MarkupSyntax;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.charting.SecureChart;\r
import com.gitblit.wicket.panels.BranchesPanel;\r
add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs).hideIfEmpty());\r
add(new BranchesPanel("branchesPanel", getRepositoryModel(), r, numberRefs, false).hideIfEmpty());\r
\r
- String htmlText = null;\r
- String markdownText = null;\r
- String readme = null;\r
- boolean isMarkdown = false;\r
- try {\r
- RevCommit head = JGitUtils.getCommit(r, null);\r
- List<String> markdownExtensions = GitBlit.getStrings(Keys.web.markdownExtensions);\r
- List<PathModel> paths = JGitUtils.getFilesInPath(r, null, head);\r
- for (PathModel path : paths) {\r
- if (!path.isTree()) {\r
- String name = path.name.toLowerCase();\r
- if (name.equals("readme") || name.equals("readme.txt")) {\r
- readme = path.name;\r
- isMarkdown = false;\r
- } else if (name.startsWith("readme")) {\r
- if (name.indexOf('.') > -1) {\r
- String ext = name.substring(name.lastIndexOf('.') + 1);\r
- if (markdownExtensions.contains(ext)) {\r
- readme = path.name;\r
- isMarkdown = true;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- if (!StringUtils.isEmpty(readme)) {\r
- String [] encodings = GitBlit.getEncodings();\r
- markdownText = JGitUtils.getStringContent(r, head.getTree(), readme, encodings);\r
- if (isMarkdown) {\r
- htmlText = MarkdownUtils.transformMarkdown(markdownText, getMarkdownLinkRenderer());\r
- } else {\r
- htmlText = MarkdownUtils.transformPlainText(markdownText);\r
- }\r
- }\r
- } catch (Exception e) {\r
- logger.error("failed to transform markdown", e);\r
- markdownText = MessageFormat.format("<div class=\"alert alert-error\"><strong>{0}:</strong> {1}</div>{2}", getString("gb.error"), getString("gb.markdownFailure"), markdownText);\r
- htmlText = MarkdownUtils.transformPlainText(markdownText);\r
- }\r
-\r
- if (StringUtils.isEmpty(htmlText)) {\r
+ RevCommit head = JGitUtils.getCommit(r, null);\r
+ MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings());\r
+ MarkupDocument markupDoc = processor.parseReadme(r, repositoryName, getBestCommitId(head));\r
+ if (markupDoc.markup == null) {\r
add(new Label("readme").setVisible(false));\r
} else {\r
- Fragment fragment = new Fragment("readme", isMarkdown ? "markdownPanel" : "plaintextPanel", this);\r
- fragment.add(new Label("readmeFile", readme));\r
+ Fragment fragment = new Fragment("readme", MarkupSyntax.PLAIN.equals(markupDoc.syntax) ? "plaintextPanel" : "markdownPanel", this);\r
+ fragment.add(new Label("readmeFile", markupDoc.documentPath));\r
// Add the html to the page\r
- Component content = new Label("readmeContent", htmlText).setEscapeModelStrings(false);\r
- fragment.add(content.setVisible(!StringUtils.isEmpty(htmlText)));\r
+ Component content = new Label("readmeContent", markupDoc.html).setEscapeModelStrings(false);\r
+ fragment.add(content.setVisible(!StringUtils.isEmpty(markupDoc.html)));\r
add(fragment);\r
}\r
\r
text-decoration: underline; \r
}\r
\r
+div.markdown table {\r
+ max-width: 100%;\r
+ background-color: transparent;\r
+ border-collapse: collapse;\r
+ border-spacing: 0px;\r
+ font-size: inherit;\r
+ border-width: 0px 1px 1px 0px;\r
+ border-style: solid solid solid none;\r
+ border-color: rgb(221, 221, 221);\r
+ border-image: none;\r
+ border-collapse: separate;\r
+ margin: 10px 0px 20px;\r
+}\r
+\r
+div.markdown table td, div.markdown table th {\r
+ padding: 8px;\r
+ line-height: 20px;\r
+ text-align: left;\r
+ vertical-align: top;\r
+ border-top: 1px solid rgb(221, 221, 221);\r
+ border-left: 1px solid rgb(221, 221, 221);\r
+}\r
+\r
div.markdown table.text th, div.markdown table.text td {\r
vertical-align: top;\r
border-top: 1px solid #ccc;\r