Refactor markup processing in preparation for supporting other formats
Change-Id: I0eb217064abc4f4b0f6bfbbc21302c470cc2f9c6
1 files renamed
1 files deleted
2 files added
9 files modified
| | |
| | | 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.
|
| | |
| | | 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);
|
| | |
| | | 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 {
|
| | |
| | | }
|
| | |
|
| | | /**
|
| | | * 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.
|
| | | *
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | | 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");
|
New file |
| | |
| | | /*
|
| | | * 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);
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | import java.util.Collection;
|
| | | import java.util.Date;
|
| | | import java.util.HashMap;
|
| | | import java.util.List;
|
| | | import java.util.Map;
|
| | | import java.util.TimeZone;
|
| | |
|
| | |
| | | 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");
|
| | | }
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
File was renamed from src/main/java/com/gitblit/wicket/pages/MarkdownPage.html |
| | |
| | |
|
| | | <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> |
New file |
| | |
| | | /*
|
| | | * 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.wicket.pages;
|
| | |
|
| | | import java.util.List;
|
| | |
|
| | | import org.apache.wicket.PageParameters;
|
| | | import org.apache.wicket.markup.html.basic.Label;
|
| | | import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
| | | import org.eclipse.jgit.lib.Constants;
|
| | | import org.eclipse.jgit.lib.Repository;
|
| | | import org.eclipse.jgit.revwalk.RevCommit;
|
| | |
|
| | | import com.gitblit.GitBlit;
|
| | | import com.gitblit.utils.JGitUtils;
|
| | | 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 DocPage extends RepositoryPage {
|
| | |
|
| | | 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();
|
| | |
|
| | | // 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);
|
| | |
|
| | | List<String> docExtensions = processor.getMarkupExtensions();
|
| | | for (String ext : docExtensions) {
|
| | | String checkName = name + "." + ext;
|
| | | markupText = JGitUtils.getStringContent(r, commit.getTree(), checkName, encodings);
|
| | | if (!StringUtils.isEmpty(markupText)) {
|
| | | // found it
|
| | | documentPath = path;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // document page links
|
| | | add(new BookmarkablePageLink<Void>("blameLink", BlamePage.class,
|
| | | WicketUtils.newPathParameter(repositoryName, objectId, documentPath)));
|
| | | add(new BookmarkablePageLink<Void>("historyLink", HistoryPage.class,
|
| | | WicketUtils.newPathParameter(repositoryName, objectId, documentPath)));
|
| | | add(new BookmarkablePageLink<Void>("rawLink", RawPage.class, WicketUtils.newPathParameter(
|
| | | repositoryName, objectId, documentPath)));
|
| | | add(new BookmarkablePageLink<Void>("headLink", DocPage.class,
|
| | | WicketUtils.newPathParameter(repositoryName, Constants.HEAD, documentPath)));
|
| | |
|
| | | MarkupDocument markupDoc = processor.parse(repositoryName, getBestCommitId(commit), documentPath, markupText);
|
| | | add(new Label("content", markupDoc.html).setEscapeModelStrings(false));
|
| | | }
|
| | |
|
| | | @Override
|
| | | protected String getPageName() {
|
| | | return getString("gb.docs");
|
| | | }
|
| | |
|
| | | @Override
|
| | | protected Class<? extends BasePage> getRepoNavPageClass() {
|
| | | return DocsPage.class;
|
| | | }
|
| | | }
|
| | |
| | | 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;
|
| | |
|
| | |
| | | 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");
|
| | |
| | | // 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;
|
| | |
| | | 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;
|
| | |
| | | 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)));
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
|
| | |
| | |
|
| | | public boolean isOwner() {
|
| | | 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 {
|
| | |
| | | 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;
|
| | |
| | | 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);
|
| | | }
|
| | |
|
| | |
| | | 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;
|