static void checkTerm(char *term, char *target, enum dbDbMatchType type, struct dbDb *dbDb, struct hash *matchHash, struct dbDbMatch **pMatchList) /* If target starts with term (case-insensitive), and target is not already in matchHash, * add target to matchHash and add a new match to pMatchList. */ { // Make uppercase version of target for case-insensitive matching. int targetLen = strlen(target); char targetUpcase[targetLen + 1]; safencpy(targetUpcase, sizeof(targetUpcase), target, targetLen); touppers(targetUpcase); int offset = wordMatchOffset(term, targetUpcase); if (offset >= 0) { addIfFirstMatch(dbDb, type, offset, targetUpcase, term, matchHash, pMatchList); } else if (offset < 0 && type == ddmtSciName && term[0] == targetUpcase[0]) { // For scientific names ("Genus species"), see if the user entered the term as 'G. species' // e.g. term 'P. trog' for target 'Pan troglodytes' regmatch_t substrArr[3]; if (regexMatchSubstrNoCase(term, "^[a-z](\\.| ) *([a-z]+)", substrArr, ArraySize(substrArr))) { char *termSpecies = term + substrArr[2].rm_so; char *targetSpecies = skipLeadingSpaces(skipToSpaces(targetUpcase)); if (targetSpecies && startsWithNoCase(termSpecies, targetSpecies)) { // Keep the negative offset since we can't just bold one chunk of target... addIfFirstMatch(dbDb, type, offset, targetUpcase, term, matchHash, pMatchList); } } } }
static char *stripAnchor(char *textIn) /* If textIn contains an HTML anchor tag, strip it out (and its end tag). */ { regmatch_t matches[3]; if (regexMatchSubstrNoCase(textIn, "<a href[^>]+>", matches, ArraySize(matches))) { char *textOut = cloneString(textIn); memmove(textOut+matches[0].rm_so, textOut+matches[0].rm_eo, strlen(textOut) + 1 - matches[0].rm_eo); if (regexMatchSubstrNoCase(textOut, "</a>", matches, ArraySize(matches))) memmove(textOut+matches[0].rm_so, textOut+matches[0].rm_eo, strlen(textOut) + 1 - matches[0].rm_eo); return textOut; } return textIn; }