Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

extract and display matching text snippets

  • Loading branch information...
commit b9be0e027b07911cfbe10470b14feffd39f6079f 1 parent 0d17ac3
Bryan Fink authored
47  apps/wriaki/src/wiki_resource.erl
@@ -255,8 +255,43 @@ render_404(RD, Ctx) ->
255 255
 
256 256
 -define(SEARCH_FUN,
257 257
         iolist_to_binary(
258  
-          [<<"function(v) {\n">>,
259  
-           <<"return [v.key];\n">>,
  258
+          [<<"function(v, d) {\n">>,
  259
+
  260
+           %% always want the key in the result
  261
+           <<"var result = {key: v.key};\n">>,
  262
+
  263
+           %% if the object was found, and we have word position info
  264
+           <<"if (v.values && v.values[0] && d.p) {\n">>,
  265
+
  266
+           %% sort positions
  267
+           <<"d.p.sort();\n">>,
  268
+
  269
+           %% create a list of start/end position pairs that attempt
  270
+           %% to group "close" positions (within 5 words) together
  271
+           <<"result.ranges=[{start: d.p[0], end: d.p[0]}];\n">>,
  272
+           <<"for (var i = 1; i < d.p.length; i++) {\n">>,
  273
+           <<"if (result.ranges[result.ranges.length-1].end-d.p[i] < 5)\n">>,
  274
+           <<"result.ranges[result.ranges.length-1].end = d.p[i];\n">>,
  275
+           <<"else\n">>,
  276
+           <<"result.ranges[result.ranges.length] = {start: d.p[i], end: d.p[i]};\n">>,
  277
+           <<"}\n">>,
  278
+
  279
+           %% extract the phrases from the text
  280
+           <<"var text = JSON.parse(v.values[0].data).text;\n">>,
  281
+           <<"var words = text.match(/[a-z0-9\u80-\uff]*/g).filter(function(s) { return s != \"\"; }).length\n">>,
  282
+
  283
+           <<"for (var i = 0; i < result.ranges.length; i++) {\n">>,
  284
+           <<"var s = result.ranges[i].start < 5 ? 0 : result.ranges[i].start-5;\n">>,
  285
+           <<"var e = result.ranges[i].end+5 > words ? words : result.ranges[i].end+5;\n">>,
  286
+           %% regexp is basically "match START words, then grab everything
  287
+           %% until WORDS-END words from the end"
  288
+           <<"var match = (new RegExp(\"(?:[a-z0-9\u80-\uff]+[^a-z0-9\u80-\uff]+){\"+s+\"}(.*)[^a-z0-9\u80-\uff](?:[a-z0-9\u80-\uff]+[^a-z0-9\u80-\uff]+){\"+(words-e)+\"}\")).exec(text);\n">>,
  289
+           <<"result.ranges[i] = match[1];\n">>,
  290
+           <<"}\n">>,
  291
+
  292
+           <<"}\n">>, % end of if values & positions
  293
+
  294
+           <<"return [result];\n">>,
260 295
            <<"}">>])).
261 296
 
262 297
 search(Client, RawSearch) ->
@@ -269,9 +304,11 @@ search(Client, RawSearch) ->
269 304
                             [<<"article">>, iolist_to_binary(Search)]},
270 305
                            [{map, {jsanon, ?SEARCH_FUN}, <<>>, true}]),
271 306
             case RawResults of
272  
-                [{0, RawKeys}] ->
273  
-                    [ [{title, base64url:decode(R)}]
274  
-                      || R <- RawKeys ];
  307
+                [{0, Results}] ->
  308
+                    [ [{title, base64url:decode(
  309
+                                 proplists:get_value(<<"key">>, R))},
  310
+                       {ranges, proplists:get_value(<<"ranges">>, R)}]
  311
+                      || {struct, R} <- Results ];
275 312
                 _ ->
276 313
                     []
277 314
             end;
7  apps/wriaki/templates/error_404.dtl
@@ -29,6 +29,13 @@
29 29
     <ul>
30 30
       {% for result in results %}
31 31
       <li><a href="/wiki/{{result.title|urlencode}}">{{result.title|escape}}</a></li>
  32
+      {% if result.ranges %}
  33
+      <ul>
  34
+        {% for range in result.ranges %}
  35
+        <li>&hellip;{{range|escape}}&hellip;</li>
  36
+        {% endfor %}
  37
+      </ul>
  38
+      {% endif %}
32 39
       {% endfor %}
33 40
     </ul>
34 41
     {% endif%}

0 notes on commit b9be0e0

Please sign in to comment.
Something went wrong with that request. Please try again.