Change-Id: I0eb217064abc4f4b0f6bfbbc21302c470cc2f9c6tags/v1.4.0
@@ -38,6 +38,8 @@ import com.gitblit.utils.ArrayUtils; | |||
import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.MarkdownUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.MarkupProcessor; | |||
import com.gitblit.wicket.MarkupProcessor.MarkupDocument; | |||
/** | |||
* Serves the content of a gh-pages branch. | |||
@@ -142,21 +144,20 @@ public class PagesServlet extends HttpServlet { | |||
return; | |||
} | |||
MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings()); | |||
String [] encodings = GitBlit.getEncodings(); | |||
RevTree tree = commit.getTree(); | |||
byte[] content = null; | |||
if (StringUtils.isEmpty(resource)) { | |||
// find resource | |||
List<String> markdownExtensions = GitBlit.getStrings(Keys.web.markdownExtensions); | |||
List<String> extensions = new ArrayList<String>(markdownExtensions.size() + 2); | |||
List<String> extensions = new ArrayList<String>(processor.getMarkupExtensions()); | |||
extensions.add("html"); | |||
extensions.add("htm"); | |||
extensions.addAll(markdownExtensions); | |||
for (String ext : extensions){ | |||
for (String ext : extensions) { | |||
String file = "index." + ext; | |||
String stringContent = JGitUtils.getStringContent(r, tree, file, encodings); | |||
if(stringContent == null){ | |||
if (stringContent == null) { | |||
continue; | |||
} | |||
content = stringContent.getBytes(Constants.ENCODING); | |||
@@ -213,14 +214,13 @@ public class PagesServlet extends HttpServlet { | |||
return; | |||
} | |||
// check to see if we should transform markdown files | |||
for (String ext : GitBlit.getStrings(Keys.web.markdownExtensions)) { | |||
if (resource.endsWith(ext)) { | |||
String mkd = new String(content, Constants.ENCODING); | |||
content = MarkdownUtils.transformMarkdown(mkd).getBytes(Constants.ENCODING); | |||
response.setContentType("text/html; charset=" + Constants.ENCODING); | |||
break; | |||
} | |||
// check to see if we should transform markup files | |||
String ext = StringUtils.getFileExtension(resource); | |||
if (processor.getMarkupExtensions().contains(ext)) { | |||
String markup = new String(content, Constants.ENCODING); | |||
MarkupDocument markupDoc = processor.parse(repository, commit.getName(), resource, markup); | |||
content = markupDoc.html.getBytes("UTF-8"); | |||
response.setContentType("text/html; charset=" + Constants.ENCODING); | |||
} | |||
try { |
@@ -555,6 +555,20 @@ public class StringUtils { | |||
return ""; | |||
} | |||
/** | |||
* Returns the file extension of a path. | |||
* | |||
* @param path | |||
* @return a blank string or a file extension | |||
*/ | |||
public static String stripFileExtension(String path) { | |||
int lastDot = path.lastIndexOf('.'); | |||
if (lastDot > -1) { | |||
return path.substring(0, lastDot); | |||
} | |||
return path; | |||
} | |||
/** | |||
* Replace all occurences of a substring within a string with | |||
* another string. |
@@ -39,6 +39,7 @@ import com.gitblit.wicket.pages.BranchesPage; | |||
import com.gitblit.wicket.pages.CommitDiffPage; | |||
import com.gitblit.wicket.pages.CommitPage; | |||
import com.gitblit.wicket.pages.ComparePage; | |||
import com.gitblit.wicket.pages.DocPage; | |||
import com.gitblit.wicket.pages.DocsPage; | |||
import com.gitblit.wicket.pages.FederationRegistrationPage; | |||
import com.gitblit.wicket.pages.ForkPage; | |||
@@ -49,7 +50,6 @@ import com.gitblit.wicket.pages.HistoryPage; | |||
import com.gitblit.wicket.pages.LogPage; | |||
import com.gitblit.wicket.pages.LogoutPage; | |||
import com.gitblit.wicket.pages.LuceneSearchPage; | |||
import com.gitblit.wicket.pages.MarkdownPage; | |||
import com.gitblit.wicket.pages.MetricsPage; | |||
import com.gitblit.wicket.pages.MyDashboardPage; | |||
import com.gitblit.wicket.pages.OverviewPage; | |||
@@ -121,9 +121,9 @@ public class GitBlitWebApp extends WebApplication { | |||
mount("/users", UsersPage.class); | |||
mount("/logout", LogoutPage.class); | |||
// setup the markdown urls | |||
// setup the markup document urls | |||
mount("/docs", DocsPage.class, "r"); | |||
mount("/markdown", MarkdownPage.class, "r", "h", "f"); | |||
mount("/doc", DocPage.class, "r", "h", "f"); | |||
// federation urls | |||
mount("/proposal", ReviewProposalPage.class, "t"); |
@@ -0,0 +1,216 @@ | |||
/* | |||
* Copyright 2013 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.wicket; | |||
import java.io.Serializable; | |||
import java.io.UnsupportedEncodingException; | |||
import java.net.URLEncoder; | |||
import java.text.MessageFormat; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.wicket.Page; | |||
import org.apache.wicket.RequestCycle; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.pegdown.LinkRenderer; | |||
import org.pegdown.ast.WikiLinkNode; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.gitblit.IStoredSettings; | |||
import com.gitblit.Keys; | |||
import com.gitblit.models.PathModel; | |||
import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.MarkdownUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.pages.DocPage; | |||
/** | |||
* Processes markup content and generates html with repository-relative page and | |||
* image linking. | |||
* | |||
* @author James Moger | |||
* | |||
*/ | |||
public class MarkupProcessor { | |||
public enum MarkupSyntax { | |||
PLAIN, MARKDOWN | |||
} | |||
private Logger logger = LoggerFactory.getLogger(getClass()); | |||
private final IStoredSettings settings; | |||
public MarkupProcessor(IStoredSettings settings) { | |||
this.settings = settings; | |||
} | |||
public List<String> getMarkupExtensions() { | |||
List<String> list = new ArrayList<String>(); | |||
list.addAll(settings.getStrings(Keys.web.markdownExtensions)); | |||
return list; | |||
} | |||
private MarkupSyntax determineSyntax(String documentPath) { | |||
String ext = StringUtils.getFileExtension(documentPath).toLowerCase(); | |||
if (StringUtils.isEmpty(ext)) { | |||
return MarkupSyntax.PLAIN; | |||
} | |||
if (settings.getStrings(Keys.web.markdownExtensions).contains(ext)) { | |||
return MarkupSyntax.MARKDOWN; | |||
} | |||
return MarkupSyntax.PLAIN; | |||
} | |||
public MarkupDocument parseReadme(Repository r, String repositoryName, String commitId) { | |||
String readme = null; | |||
RevCommit commit = JGitUtils.getCommit(r, commitId); | |||
List<PathModel> paths = JGitUtils.getFilesInPath(r, null, commit); | |||
for (PathModel path : paths) { | |||
if (!path.isTree()) { | |||
String name = path.name.toLowerCase(); | |||
if (name.equals("readme") || name.equals("readme.txt")) { | |||
readme = path.name; | |||
break; | |||
} else if (name.startsWith("readme.")) { | |||
String ext = StringUtils.getFileExtension(name).toLowerCase(); | |||
if (getMarkupExtensions().contains(ext)) { | |||
readme = path.name; | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
if (!StringUtils.isEmpty(readme)) { | |||
String [] encodings = settings.getStrings(Keys.web.blobEncodings).toArray(new String[0]); | |||
String markup = JGitUtils.getStringContent(r, commit.getTree(), readme, encodings); | |||
return parse(repositoryName, commitId, readme, markup); | |||
} | |||
return null; | |||
} | |||
public MarkupDocument parse(String repositoryName, String commitId, String documentPath, String markupText) { | |||
final MarkupSyntax syntax = determineSyntax(documentPath); | |||
final MarkupDocument doc = new MarkupDocument(documentPath, markupText, syntax); | |||
if (markupText != null) { | |||
try { | |||
switch (syntax){ | |||
case MARKDOWN: | |||
parse(doc, repositoryName, commitId); | |||
break; | |||
default: | |||
doc.html = MarkdownUtils.transformPlainText(markupText); | |||
break; | |||
} | |||
} catch (Exception e) { | |||
logger.error("failed to transform " + syntax, e); | |||
} | |||
} | |||
if (doc.html == null) { | |||
// failed to transform markup | |||
if (markupText == null) { | |||
markupText = String.format("Document <b>%1$s</b> not found in <em>%2$s</em>", documentPath, repositoryName); | |||
} | |||
markupText = MessageFormat.format("<div class=\"alert alert-error\"><strong>{0}:</strong> {1}</div>{2}", "Error", "failed to parse markup", markupText); | |||
doc.html = StringUtils.breakLinesForHtml(markupText); | |||
} | |||
return doc; | |||
} | |||
/** | |||
* Parses the document as Markdown using Pegdown. | |||
* | |||
* @param doc | |||
* @param repositoryName | |||
* @param commitId | |||
*/ | |||
private void parse(final MarkupDocument doc, final String repositoryName, final String commitId) { | |||
LinkRenderer renderer = new LinkRenderer() { | |||
@Override | |||
public Rendering render(WikiLinkNode node) { | |||
String path = doc.getRelativePath(node.getText()); | |||
String name = getDocumentName(path); | |||
String url = getWicketUrl(DocPage.class, repositoryName, commitId, path); | |||
return new Rendering(url, name); | |||
} | |||
}; | |||
doc.html = MarkdownUtils.transformMarkdown(doc.markup, renderer); | |||
} | |||
private String getWicketUrl(Class<? extends Page> pageClass, final String repositoryName, final String commitId, final String document) { | |||
String fsc = settings.getString(Keys.web.forwardSlashCharacter, "/"); | |||
String encodedPath = document.replace(' ', '-'); | |||
try { | |||
encodedPath = URLEncoder.encode(encodedPath, "UTF-8"); | |||
} catch (UnsupportedEncodingException e) { | |||
logger.error(null, e); | |||
} | |||
encodedPath = encodedPath.replace("/", fsc).replace("%2F", fsc); | |||
String url = RequestCycle.get().urlFor(pageClass, WicketUtils.newPathParameter(repositoryName, commitId, encodedPath)).toString(); | |||
return url; | |||
} | |||
private String getDocumentName(final String document) { | |||
// extract document name | |||
String name = StringUtils.stripFileExtension(document); | |||
name = name.replace('_', ' '); | |||
if (name.indexOf('/') > -1) { | |||
name = name.substring(name.lastIndexOf('/') + 1); | |||
} | |||
return name; | |||
} | |||
public static class MarkupDocument implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
public final String documentPath; | |||
public final String markup; | |||
public final MarkupSyntax syntax; | |||
public String html; | |||
MarkupDocument(String documentPath, String markup, MarkupSyntax syntax) { | |||
this.documentPath = documentPath; | |||
this.markup = markup; | |||
this.syntax = syntax; | |||
} | |||
String getCurrentPath() { | |||
String basePath = ""; | |||
if (documentPath.indexOf('/') > -1) { | |||
basePath = documentPath.substring(0, documentPath.lastIndexOf('/') + 1); | |||
if (basePath.charAt(0) == '/') { | |||
return basePath.substring(1); | |||
} | |||
} | |||
return basePath; | |||
} | |||
String getRelativePath(String ref) { | |||
return ref.charAt(0) == '/' ? ref.substring(1) : (getCurrentPath() + ref); | |||
} | |||
} | |||
} |
@@ -21,7 +21,6 @@ import java.text.SimpleDateFormat; | |||
import java.util.Collection; | |||
import java.util.Date; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.TimeZone; | |||
@@ -190,11 +189,10 @@ public class WicketUtils { | |||
return newImage(wicketId, "file_settings_16x16.png"); | |||
} | |||
List<String> mdExtensions = GitBlit.getStrings(Keys.web.markdownExtensions); | |||
for (String ext : mdExtensions) { | |||
if (filename.endsWith('.' + ext.toLowerCase())) { | |||
return newImage(wicketId, "file_world_16x16.png"); | |||
} | |||
MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings()); | |||
String ext = StringUtils.getFileExtension(filename).toLowerCase(); | |||
if (processor.getMarkupExtensions().contains(ext)) { | |||
return newImage(wicketId, "file_world_16x16.png"); | |||
} | |||
return newImage(wicketId, "file_16x16.png"); | |||
} |
@@ -35,6 +35,7 @@ import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.CacheControl; | |||
import com.gitblit.wicket.CacheControl.LastModified; | |||
import com.gitblit.wicket.ExternalImage; | |||
import com.gitblit.wicket.MarkupProcessor; | |||
import com.gitblit.wicket.WicketUtils; | |||
import com.gitblit.wicket.panels.CommitHeaderPanel; | |||
import com.gitblit.wicket.panels.PathBreadcrumbsPanel; | |||
@@ -73,10 +74,11 @@ public class BlobPage extends RepositoryPage { | |||
extension = blobPath.substring(blobPath.lastIndexOf('.') + 1).toLowerCase(); | |||
} | |||
// see if we should redirect to the markdown page | |||
for (String ext : GitBlit.getStrings(Keys.web.markdownExtensions)) { | |||
// see if we should redirect to the doc page | |||
MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings()); | |||
for (String ext : processor.getMarkupExtensions()) { | |||
if (ext.equals(extension)) { | |||
setResponsePage(MarkdownPage.class, params); | |||
setResponsePage(DocPage.class, params); | |||
return; | |||
} | |||
} |
@@ -6,13 +6,13 @@ | |||
<body> | |||
<wicket:extend> | |||
<!-- markdown nav links --> | |||
<!-- doc nav links --> | |||
<div class="page_nav2"> | |||
<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> | |||
</div> | |||
<!-- markdown content --> | |||
<div class="markdown" style="padding-bottom:5px;" wicket:id="markdownText">[markdown content]</div> | |||
<!-- document content --> | |||
<div class="markdown" style="padding-bottom:5px;" wicket:id="content">[content]</div> | |||
</wicket:extend> | |||
</body> | |||
</html> |
@@ -15,7 +15,6 @@ | |||
*/ | |||
package com.gitblit.wicket.pages; | |||
import java.text.MessageFormat; | |||
import java.util.List; | |||
import org.apache.wicket.PageParameters; | |||
@@ -26,76 +25,64 @@ import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import com.gitblit.GitBlit; | |||
import com.gitblit.Keys; | |||
import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.MarkdownUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.CacheControl; | |||
import com.gitblit.wicket.CacheControl.LastModified; | |||
import com.gitblit.wicket.MarkupProcessor; | |||
import com.gitblit.wicket.MarkupProcessor.MarkupDocument; | |||
import com.gitblit.wicket.WicketUtils; | |||
@CacheControl(LastModified.BOOT) | |||
public class MarkdownPage extends RepositoryPage { | |||
public class DocPage extends RepositoryPage { | |||
public MarkdownPage(PageParameters params) { | |||
public DocPage(PageParameters params) { | |||
super(params); | |||
final String path = WicketUtils.getPath(params).replace("%2f", "/").replace("%2F", "/"); | |||
MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings()); | |||
Repository r = getRepository(); | |||
RevCommit commit = JGitUtils.getCommit(r, objectId); | |||
String [] encodings = GitBlit.getEncodings(); | |||
List<String> extensions = GitBlit.getStrings(Keys.web.markdownExtensions); | |||
// Read raw markdown content and transform it to html | |||
String markdownPath = path; | |||
String markdownText = JGitUtils.getStringContent(r, commit.getTree(), path, encodings); | |||
if (StringUtils.isEmpty(markdownText)) { | |||
String name = path; | |||
if (path.indexOf('.') > -1) { | |||
name = path.substring(0, path.lastIndexOf('.')); | |||
} | |||
// Read raw markup content and transform it to html | |||
String documentPath = path; | |||
String markupText = JGitUtils.getStringContent(r, commit.getTree(), path, encodings); | |||
// Hunt for document | |||
if (StringUtils.isEmpty(markupText)) { | |||
String name = StringUtils.stripFileExtension(path); | |||
for (String ext : extensions) { | |||
List<String> docExtensions = processor.getMarkupExtensions(); | |||
for (String ext : docExtensions) { | |||
String checkName = name + "." + ext; | |||
markdownText = JGitUtils.getStringContent(r, commit.getTree(), checkName, encodings); | |||
if (!StringUtils.isEmpty(markdownText)) { | |||
markupText = JGitUtils.getStringContent(r, commit.getTree(), checkName, encodings); | |||
if (!StringUtils.isEmpty(markupText)) { | |||
// found it | |||
markdownPath = path; | |||
documentPath = path; | |||
break; | |||
} | |||
} | |||
} | |||
// markdown page links | |||
// document page links | |||
add(new BookmarkablePageLink<Void>("blameLink", BlamePage.class, | |||
WicketUtils.newPathParameter(repositoryName, objectId, markdownPath))); | |||
WicketUtils.newPathParameter(repositoryName, objectId, documentPath))); | |||
add(new BookmarkablePageLink<Void>("historyLink", HistoryPage.class, | |||
WicketUtils.newPathParameter(repositoryName, objectId, markdownPath))); | |||
WicketUtils.newPathParameter(repositoryName, objectId, documentPath))); | |||
add(new BookmarkablePageLink<Void>("rawLink", RawPage.class, WicketUtils.newPathParameter( | |||
repositoryName, objectId, markdownPath))); | |||
add(new BookmarkablePageLink<Void>("headLink", MarkdownPage.class, | |||
WicketUtils.newPathParameter(repositoryName, Constants.HEAD, markdownPath))); | |||
String htmlText; | |||
try { | |||
htmlText = MarkdownUtils.transformMarkdown(markdownText, getMarkdownLinkRenderer()); | |||
} catch (Exception e) { | |||
logger.error("failed to transform markdown", e); | |||
if (markdownText == null) { | |||
markdownText = String.format("Markdown document <b>%1$s</b> not found in <em>%2$s</em>", markdownPath, repositoryName); | |||
} | |||
markdownText = MessageFormat.format("<div class=\"alert alert-error\"><strong>{0}:</strong> {1}</div>{2}", getString("gb.error"), getString("gb.markdownFailure"), markdownText); | |||
htmlText = StringUtils.breakLinesForHtml(markdownText); | |||
} | |||
repositoryName, objectId, documentPath))); | |||
add(new BookmarkablePageLink<Void>("headLink", DocPage.class, | |||
WicketUtils.newPathParameter(repositoryName, Constants.HEAD, documentPath))); | |||
// Add the html to the page | |||
add(new Label("markdownText", htmlText).setEscapeModelStrings(false)); | |||
MarkupDocument markupDoc = processor.parse(repositoryName, getBestCommitId(commit), documentPath, markupText); | |||
add(new Label("content", markupDoc.html).setEscapeModelStrings(false)); | |||
} | |||
@Override | |||
protected String getPageName() { | |||
return getString("gb.markdown"); | |||
return getString("gb.docs"); | |||
} | |||
@Override |
@@ -30,14 +30,14 @@ import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import com.gitblit.GitBlit; | |||
import com.gitblit.Keys; | |||
import com.gitblit.models.PathModel; | |||
import com.gitblit.utils.ByteFormat; | |||
import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.MarkdownUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.CacheControl; | |||
import com.gitblit.wicket.CacheControl.LastModified; | |||
import com.gitblit.wicket.MarkupProcessor; | |||
import com.gitblit.wicket.MarkupProcessor.MarkupDocument; | |||
import com.gitblit.wicket.WicketUtils; | |||
import com.gitblit.wicket.panels.LinkPanel; | |||
@@ -47,13 +47,15 @@ public class DocsPage extends RepositoryPage { | |||
public DocsPage(PageParameters params) { | |||
super(params); | |||
MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings()); | |||
Repository r = getRepository(); | |||
RevCommit head = JGitUtils.getCommit(r, null); | |||
List<String> extensions = GitBlit.getStrings(Keys.web.markdownExtensions); | |||
List<String> extensions = processor.getMarkupExtensions(); | |||
List<PathModel> paths = JGitUtils.getDocuments(r, extensions); | |||
String doc = null; | |||
String markdown = null; | |||
String markup = null; | |||
String html = null; | |||
List<String> roots = Arrays.asList("home"); | |||
@@ -61,9 +63,7 @@ public class DocsPage extends RepositoryPage { | |||
// try to find a custom index/root page | |||
for (PathModel path : paths) { | |||
String name = path.name.toLowerCase(); | |||
if (name.indexOf('.') > -1) { | |||
name = name.substring(0, name.lastIndexOf('.')); | |||
} | |||
name = StringUtils.stripFileExtension(name); | |||
if (roots.contains(name)) { | |||
doc = path.name; | |||
break; | |||
@@ -73,8 +73,11 @@ public class DocsPage extends RepositoryPage { | |||
if (!StringUtils.isEmpty(doc)) { | |||
// load the document | |||
String [] encodings = GitBlit.getEncodings(); | |||
markdown = JGitUtils.getStringContent(r, head.getTree(), doc, encodings); | |||
html = MarkdownUtils.transformMarkdown(markdown, getMarkdownLinkRenderer()); | |||
markup = JGitUtils.getStringContent(r, head.getTree(), doc, encodings); | |||
// parse document | |||
MarkupDocument markupDoc = processor.parse(repositoryName, getBestCommitId(head), doc, markup); | |||
html = markupDoc.html; | |||
} | |||
Fragment fragment = null; | |||
@@ -103,11 +106,11 @@ public class DocsPage extends RepositoryPage { | |||
PathModel entry = item.getModelObject(); | |||
item.add(WicketUtils.newImage("docIcon", "file_world_16x16.png")); | |||
item.add(new Label("docSize", byteFormat.format(entry.size))); | |||
item.add(new LinkPanel("docName", "list", entry.name, MarkdownPage.class, WicketUtils | |||
item.add(new LinkPanel("docName", "list", entry.name, DocPage.class, WicketUtils | |||
.newPathParameter(repositoryName, id, entry.path))); | |||
// links | |||
item.add(new BookmarkablePageLink<Void>("view", MarkdownPage.class, WicketUtils | |||
item.add(new BookmarkablePageLink<Void>("view", DocPage.class, WicketUtils | |||
.newPathParameter(repositoryName, id, entry.path))); | |||
item.add(new BookmarkablePageLink<Void>("raw", RawPage.class, WicketUtils | |||
.newPathParameter(repositoryName, id, entry.path))); |
@@ -16,8 +16,6 @@ | |||
package com.gitblit.wicket.pages; | |||
import java.io.Serializable; | |||
import java.io.UnsupportedEncodingException; | |||
import java.net.URLEncoder; | |||
import java.text.MessageFormat; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
@@ -44,8 +42,6 @@ import org.eclipse.jgit.diff.DiffEntry.ChangeType; | |||
import org.eclipse.jgit.lib.PersonIdent; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.pegdown.LinkRenderer; | |||
import org.pegdown.ast.WikiLinkNode; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
@@ -647,47 +643,6 @@ public abstract class RepositoryPage extends RootPage { | |||
return isOwner; | |||
} | |||
/** | |||
* Returns a Pegdown/Markdown link renderer which renders WikiLinks. | |||
* | |||
* @return a link renderer | |||
*/ | |||
protected LinkRenderer getMarkdownLinkRenderer() { | |||
RevCommit head = JGitUtils.getCommit(r, "HEAD"); | |||
final String id = getBestCommitId(head); | |||
LinkRenderer renderer = new LinkRenderer() { | |||
@Override | |||
public Rendering render(WikiLinkNode node) { | |||
try { | |||
String fsc = GitBlit.getString(Keys.web.forwardSlashCharacter, "/"); | |||
// adjust the request path | |||
String path = node.getText().charAt(0) == '/' ? node.getText().substring(1) : node.getText(); | |||
path = URLEncoder.encode(path.replace(' ', '-'), "UTF-8").replace("%2F", fsc); | |||
// extract document name | |||
String name = node.getText().replace('_', ' '); | |||
if (name.indexOf('/') > -1) { | |||
name = name.substring(name.lastIndexOf('/') + 1); | |||
} | |||
// strip Markdown extension | |||
for (String ext : GitBlit.getStrings(Keys.web.markdownExtensions)) { | |||
String x = "." + ext; | |||
if (name.endsWith(x)) { | |||
name = name.substring(0, name.length() - x.length()); | |||
break; | |||
} | |||
} | |||
String url = urlFor(MarkdownPage.class, WicketUtils.newPathParameter(repositoryName, id, path)).toString(); | |||
return new Rendering(url, name); | |||
} catch (UnsupportedEncodingException e) { | |||
throw new IllegalStateException(); | |||
} | |||
} | |||
}; | |||
return renderer; | |||
} | |||
private class SearchForm extends SessionlessForm<Void> implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
@@ -43,15 +43,16 @@ import org.wicketstuff.googlecharts.ShapeMarker; | |||
import com.gitblit.GitBlit; | |||
import com.gitblit.Keys; | |||
import com.gitblit.models.Metric; | |||
import com.gitblit.models.PathModel; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.MarkdownUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.CacheControl; | |||
import com.gitblit.wicket.CacheControl.LastModified; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.MarkupProcessor; | |||
import com.gitblit.wicket.MarkupProcessor.MarkupDocument; | |||
import com.gitblit.wicket.MarkupProcessor.MarkupSyntax; | |||
import com.gitblit.wicket.WicketUtils; | |||
import com.gitblit.wicket.charting.SecureChart; | |||
import com.gitblit.wicket.panels.BranchesPanel; | |||
@@ -137,55 +138,17 @@ public class SummaryPage extends RepositoryPage { | |||
add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs).hideIfEmpty()); | |||
add(new BranchesPanel("branchesPanel", getRepositoryModel(), r, numberRefs, false).hideIfEmpty()); | |||
String htmlText = null; | |||
String markdownText = null; | |||
String readme = null; | |||
boolean isMarkdown = false; | |||
try { | |||
RevCommit head = JGitUtils.getCommit(r, null); | |||
List<String> markdownExtensions = GitBlit.getStrings(Keys.web.markdownExtensions); | |||
List<PathModel> paths = JGitUtils.getFilesInPath(r, null, head); | |||
for (PathModel path : paths) { | |||
if (!path.isTree()) { | |||
String name = path.name.toLowerCase(); | |||
if (name.equals("readme") || name.equals("readme.txt")) { | |||
readme = path.name; | |||
isMarkdown = false; | |||
} else if (name.startsWith("readme")) { | |||
if (name.indexOf('.') > -1) { | |||
String ext = name.substring(name.lastIndexOf('.') + 1); | |||
if (markdownExtensions.contains(ext)) { | |||
readme = path.name; | |||
isMarkdown = true; | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if (!StringUtils.isEmpty(readme)) { | |||
String [] encodings = GitBlit.getEncodings(); | |||
markdownText = JGitUtils.getStringContent(r, head.getTree(), readme, encodings); | |||
if (isMarkdown) { | |||
htmlText = MarkdownUtils.transformMarkdown(markdownText, getMarkdownLinkRenderer()); | |||
} else { | |||
htmlText = MarkdownUtils.transformPlainText(markdownText); | |||
} | |||
} | |||
} catch (Exception e) { | |||
logger.error("failed to transform markdown", e); | |||
markdownText = MessageFormat.format("<div class=\"alert alert-error\"><strong>{0}:</strong> {1}</div>{2}", getString("gb.error"), getString("gb.markdownFailure"), markdownText); | |||
htmlText = MarkdownUtils.transformPlainText(markdownText); | |||
} | |||
if (StringUtils.isEmpty(htmlText)) { | |||
RevCommit head = JGitUtils.getCommit(r, null); | |||
MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings()); | |||
MarkupDocument markupDoc = processor.parseReadme(r, repositoryName, getBestCommitId(head)); | |||
if (markupDoc.markup == null) { | |||
add(new Label("readme").setVisible(false)); | |||
} else { | |||
Fragment fragment = new Fragment("readme", isMarkdown ? "markdownPanel" : "plaintextPanel", this); | |||
fragment.add(new Label("readmeFile", readme)); | |||
Fragment fragment = new Fragment("readme", MarkupSyntax.PLAIN.equals(markupDoc.syntax) ? "plaintextPanel" : "markdownPanel", this); | |||
fragment.add(new Label("readmeFile", markupDoc.documentPath)); | |||
// Add the html to the page | |||
Component content = new Label("readmeContent", htmlText).setEscapeModelStrings(false); | |||
fragment.add(content.setVisible(!StringUtils.isEmpty(htmlText))); | |||
Component content = new Label("readmeContent", markupDoc.html).setEscapeModelStrings(false); | |||
fragment.add(content.setVisible(!StringUtils.isEmpty(markupDoc.html))); | |||
add(fragment); | |||
} | |||
@@ -1540,6 +1540,29 @@ div.markdown a { | |||
text-decoration: underline; | |||
} | |||
div.markdown table { | |||
max-width: 100%; | |||
background-color: transparent; | |||
border-collapse: collapse; | |||
border-spacing: 0px; | |||
font-size: inherit; | |||
border-width: 0px 1px 1px 0px; | |||
border-style: solid solid solid none; | |||
border-color: rgb(221, 221, 221); | |||
border-image: none; | |||
border-collapse: separate; | |||
margin: 10px 0px 20px; | |||
} | |||
div.markdown table td, div.markdown table th { | |||
padding: 8px; | |||
line-height: 20px; | |||
text-align: left; | |||
vertical-align: top; | |||
border-top: 1px solid rgb(221, 221, 221); | |||
border-left: 1px solid rgb(221, 221, 221); | |||
} | |||
div.markdown table.text th, div.markdown table.text td { | |||
vertical-align: top; | |||
border-top: 1px solid #ccc; |