From 12c31ef28e1396f652f6f80f84480c0833182150 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Wed, 21 Mar 2012 20:01:30 -0400 Subject: [PATCH] Restore the leading hunk of the first line of a fragment --- src/com/gitblit/LuceneExecutor.java | 95 +++++++++++++++++++++++++++-------------------- 1 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/com/gitblit/LuceneExecutor.java b/src/com/gitblit/LuceneExecutor.java index 65e1b2b..12f2305 100644 --- a/src/com/gitblit/LuceneExecutor.java +++ b/src/com/gitblit/LuceneExecutor.java @@ -1114,17 +1114,14 @@ */ 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 @@ 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 @@ } } 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. -- Gitblit v1.9.1