Browse Source

Restore the leading hunk of the first line of a fragment

Also correctly determine the line number of a fragment.
tags/v0.9.0
James Moger 12 years ago
parent
commit
12c31ef28e
2 changed files with 81 additions and 40 deletions
  1. 55
    40
      src/com/gitblit/LuceneExecutor.java
  2. 26
    0
      src/com/gitblit/utils/StringUtils.java

+ 55
- 40
src/com/gitblit/LuceneExecutor.java View File

@@ -1114,17 +1114,14 @@ public class LuceneExecutor implements Runnable {
*/
private String getHighlightedFragment(Analyzer analyzer, Query query,
String content, SearchResult result) throws IOException, InvalidTokenOffsetsException {
content = content == null ? "":StringUtils.escapeForHtml(content, false);
if (content == null) {
content = "";
}
int fragmentLength = SearchObjectType.commit == result.type ? 512 : 150;
QueryScorer scorer = new QueryScorer(query, "content");
Fragmenter fragmenter;
// TODO improve the fragmenter - hopefully on line breaks
if (SearchObjectType.commit == result.type) {
fragmenter = new SimpleSpanFragmenter(scorer, 1024);
} else {
fragmenter = new SimpleSpanFragmenter(scorer, 150);
}
Fragmenter fragmenter = new SimpleSpanFragmenter(scorer, fragmentLength);
// use an artificial delimiter for the token
String termTag = "<!--[";
@@ -1132,22 +1129,64 @@ public class LuceneExecutor implements Runnable {
SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(termTag, termTagEnd);
Highlighter highlighter = new Highlighter(formatter, scorer);
highlighter.setTextFragmenter(fragmenter);
String [] fragments = highlighter.getBestFragments(analyzer, "content", content, 3);
if (ArrayUtils.isEmpty(fragments)) {
if (SearchObjectType.blob == result.type) {
return "";
}
return "<pre class=\"text\">" + content + "</pre>";
// clip commit message
String fragment = content;
if (fragment.length() > fragmentLength) {
fragment = fragment.substring(0, fragmentLength) + "...";
}
return "<pre class=\"text\">" + StringUtils.escapeForHtml(fragment, true) + "</pre>";
}
int contentPos = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0, len = fragments.length; i < len; i++) {
String fragment = fragments[i];
String tag = "<pre class=\"text\">";
// resurrect the raw fragment from removing the artificial delimiters
String raw = fragment.replace(termTag, "").replace(termTagEnd, "");
sb.append(getPreTag(result, raw, content));
String raw = fragment.replace(termTag, "").replace(termTagEnd, "");
// determine position of the raw fragment in the content
int pos = content.indexOf(raw, contentPos);
// restore complete first line of fragment
int c = pos;
while (c > 0) {
c--;
if (content.charAt(c) == '\n') {
break;
}
}
if (c > 0) {
// inject leading chunk of first fragment line
fragment = content.substring(c + 1, pos) + fragment;
}
if (SearchObjectType.blob == result.type) {
// count lines as offset into the content for this fragment
int line = StringUtils.countLines(content.substring(0, pos));
// create fragment tag with line number and language
String lang = "";
String ext = StringUtils.getFileExtension(result.path).toLowerCase();
if (!StringUtils.isEmpty(ext)) {
// maintain leading space!
lang = " lang-" + ext;
}
tag = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0}{1}\">", line, lang);
// update offset into content
contentPos = pos + raw.length() + 1;
}
sb.append(tag);
// replace the artificial delimiter with html tags
String html = fragment.replace(termTag, "<span class=\"highlight\">").replace(termTagEnd, "</span>");
sb.append(html);
@@ -1157,31 +1196,7 @@ public class LuceneExecutor implements Runnable {
}
}
return sb.toString();
}
/**
* Returns the appropriate tag for a fragment. Commit messages are visually
* differentiated from blob fragments.
*
* @param result
* @param fragment
* @param content
* @return an html tag appropriate for the fragment
*/
private String getPreTag(SearchResult result, String fragment, String content) {
String pre = "<pre class=\"text\">";
if (SearchObjectType.blob == result.type) {
int line = StringUtils.countLines(content.substring(0, content.indexOf(fragment)));
int lastDot = result.path.lastIndexOf('.');
if (lastDot > -1) {
String ext = result.path.substring(lastDot + 1).toLowerCase();
pre = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0} lang-{1}\">", line, ext);
} else {
pre = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0}\">", line);
}
}
return pre;
}
}
/**
* Simple class to track the results of an index update.

+ 26
- 0
src/com/gitblit/utils/StringUtils.java View File

@@ -479,6 +479,12 @@ public class StringUtils {
return "#" + rs + gs + bs;
}
/**
* Strips a trailing ".git" from the value.
*
* @param value
* @return a stripped value or the original value if .git is not found
*/
public static String stripDotGit(String value) {
if (value.toLowerCase().endsWith(".git")) {
return value.substring(0, value.length() - 4);
@@ -486,10 +492,30 @@ public class StringUtils {
return value;
}
/**
* Count the number of lines in a string.
*
* @param value
* @return the line count
*/
public static int countLines(String value) {
if (isEmpty(value)) {
return 0;
}
return value.split("\n").length;
}
/**
* Returns the file extension of a path.
*
* @param path
* @return a blank string or a file extension
*/
public static String getFileExtension(String path) {
int lastDot = path.lastIndexOf('.');
if (lastDot > -1) {
return path.substring(lastDot + 1);
}
return "";
}
}

Loading…
Cancel
Save