/*
* call-seq:
* searcher.highlight(query, doc_id, field, options = {}) -> Array
*
* Returns an array of strings with the matches highlighted.
*
* === Options
*
* :excerpt_length:: Default: 150. Length of excerpt to show. Highlighted
* terms will be in the centre of the excerpt. Set to
* :all to highlight the entire field.
* :num_excerpts:: Default: 2. Number of excerpts to return.
* :pre_tag:: Default: "<b>". Tag to place to the left of the match.
* You'll probably want to change this to a "<span>" tag
* with a class. Try "\033[7m" for use in a terminal.
* :post_tag:: Default: "</b>". This tag should close the +:pre_tag+.
* Try tag "\033[m" in the terminal.
* :ellipsis:: Default: "...". This is the string that is appended at
* the beginning and end of excerpts (unless the excerpt
* hits the start or end of the field. You'll probably
* want to change this so a Unicode ellipsis character.
*/
static VALUE
frt_sea_highlight(int argc, VALUE *argv, VALUE self)
{
GET_SEA();
VALUE rquery, rdoc_id, rfield, roptions, v;
Query *query;
int excerpt_length = 150;
int num_excerpts = 2;
char *pre_tag = "<b>";
char *post_tag = "</b>";
char *ellipsis = "...";
char **excerpts;
rb_scan_args(argc, argv, "31", &rquery, &rdoc_id, &rfield, &roptions);
Data_Get_Struct(rquery, Query, query);
if (argc > 3) {
if (TYPE(roptions) != T_HASH) {
rb_raise(rb_eArgError, "The fourth argument to Searcher#highlight must be a hash");
}
if (Qnil != (v = rb_hash_aref(roptions, sym_num_excerpts))) {
num_excerpts = FIX2INT(v);
}
if (Qnil != (v = rb_hash_aref(roptions, sym_excerpt_length))) {
if (v == sym_all) {
num_excerpts = 1;
excerpt_length = INT_MAX/2;
}
else {
excerpt_length = FIX2INT(v);
}
}
if (Qnil != (v = rb_hash_aref(roptions, sym_pre_tag))) {
pre_tag = rs2s(rb_obj_as_string(v));
}
if (Qnil != (v = rb_hash_aref(roptions, sym_post_tag))) {
post_tag = rs2s(rb_obj_as_string(v));
}
if (Qnil != (v = rb_hash_aref(roptions, sym_ellipsis))) {
ellipsis = rs2s(rb_obj_as_string(v));
}
}
if ((excerpts = searcher_highlight(sea,
query,
FIX2INT(rdoc_id),
frt_field(rfield),
excerpt_length,
num_excerpts,
pre_tag,
post_tag,
ellipsis)) != NULL) {
const int size = ary_size(excerpts);
int i;
VALUE rexcerpts = rb_ary_new2(size);
for (i = 0; i < size; i++) {
RARRAY(rexcerpts)->ptr[i] = rb_str_new2(excerpts[i]);
RARRAY(rexcerpts)->len++;
}
ary_destroy(excerpts, &free);
return rexcerpts;
}
return Qnil;
}