Vector* PolyCompiler_Highlight_Spans_IMP(PolyCompiler *self, Searcher *searcher, DocVector *doc_vec, String *field) { PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self); Vector *spans = Vec_new(0); for (size_t i = 0, max = Vec_Get_Size(ivars->children); i < max; i++) { Compiler *child = (Compiler*)Vec_Fetch(ivars->children, i); Vector *child_spans = Compiler_Highlight_Spans(child, searcher, doc_vec, field); if (child_spans) { Vec_Push_All(spans, child_spans); DECREF(child_spans); } } return spans; }
String* Highlighter_Create_Excerpt_IMP(Highlighter *self, HitDoc *hit_doc) { HighlighterIVARS *const ivars = Highlighter_IVARS(self); String *field_val = (String*)HitDoc_Extract(hit_doc, ivars->field); String *retval; if (!field_val || !Obj_Is_A((Obj*)field_val, STRING)) { retval = NULL; } else if (!Str_Get_Size(field_val)) { // Empty string yields empty string. retval = Str_new_from_trusted_utf8("", 0); } else { DocVector *doc_vec = Searcher_Fetch_Doc_Vec(ivars->searcher, HitDoc_Get_Doc_ID(hit_doc)); VArray *maybe_spans = Compiler_Highlight_Spans(ivars->compiler, ivars->searcher, doc_vec, ivars->field); VArray *score_spans = maybe_spans ? maybe_spans : VA_new(0); VA_Sort(score_spans, NULL, NULL); HeatMap *heat_map = HeatMap_new(score_spans, (ivars->excerpt_length * 2) / 3); int32_t top; String *raw_excerpt = Highlighter_Raw_Excerpt(self, field_val, &top, heat_map); String *highlighted = Highlighter_Highlight_Excerpt(self, score_spans, raw_excerpt, top); DECREF(raw_excerpt); DECREF(heat_map); DECREF(score_spans); DECREF(doc_vec); retval = highlighted; } DECREF(field_val); return retval; }