I've updated that link I sent you with an example (the first 2 words), first example being the one with an apostrophe (which looks like a space).
Actually it doesn't seem to have fixed the nested a problem, at least not fully. voluntary bankruptcy still gets highlighted (<a></a>) for glossary words: voluntary bankruptcy bankruptcy etc I think the scenario where the tip contained a glossary word may have been fixed by the (?=([^"]*"[^"]*")*[^"]*$) thing, but not the above example of where the content contains such. Do we need lookarounds or whatever they are called to see if the matched word is already contained within an anchor, and if so, skip it?
Tried this one, and it seems to work. Case insensitive Doesn't change keywords that are already linked If you have the definition 'creditor' it will match "creditor", "creditors" and "creditor's" Doesn't screw up the HTML/Javascript function red_glossary_parse($content){ //Run the glossary parser if (((!is_page() && get_option('red_glossaryOnlySingle') == 0) OR (!is_page() && get_option('red_glossaryOnlySingle') == 1 && is_single()) OR (is_page() && get_option('red_glossaryOnPages') == 1))){ $glossary_index = get_children(array( 'post_type' => 'glossary', 'post_status' => 'publish', )); usort($glossary_index,'sortByLength'); $content = str_replace('’', "'", $content); if ($glossary_index){ $timestamp = time(); foreach($glossary_index as $glossary_item){ $timestamp++; $glossary_title = $glossary_item->post_title; $glossary_search = '/(?<!>)('.str_replace('/\s+/','\s',$glossary_title).'(s|\'s)?)(?!<)(?=([^"]*"[^"]*")*[^"]*$)/i'; $glossary_replace = '<a'.$timestamp.'>$0</a'.$timestamp.'>'; if (get_option('red_glossaryFirstOnly') == 1) { $content_temp = preg_replace($glossary_search, $glossary_replace, $content, 1); } else { $content_temp = preg_replace($glossary_search, $glossary_replace, $content); } $content_temp = rtrim($content_temp); $link_search = '/<a'.$timestamp.'>('.$glossary_item->post_title.'[a-z\']*?)<\/a'.$timestamp.'>/i'; if (get_option('red_glossaryTooltip') == 1) { $link_replace = '<a class="glossaryLink" href="' . get_permalink($glossary_item) . '" title="Glossary: '. $glossary_title . '" onmouseover="tooltip.show(\'' . addslashes($glossary_item->post_content) . '\');" onmouseout="tooltip.hide();">$1</a>'; } else { $link_replace = '<a class="glossaryLink" href="' . get_permalink($glossary_item) . '" title="Glossary: '. $glossary_title . '">$1</a>'; } $content_temp = preg_replace($link_search, $link_replace, $content_temp); $content = $content_temp; } } } return $content; } PHP:
ugh... forgot to say, you need to change the line: $content = str_replace('’', "'", $content); PHP: To this, but without the spaces: $content = str_replace('& # 8 2 1 7 ;', "'", $content); PHP:
Thax mate, my code is modified from the original, so I copied the lines I thought you had changed. It now works, for creditors but doesn't detect creditor's or creditors'. I updated the example page on the server (in that link I sent you). Here is my code: function red_glossary_parse_content($content){ global $terms_done; //Run the glossary parser $glossaryPageID = get_option('red_glossaryID'); if (((!is_page() && get_option('red_glossaryOnlySingle') == 0) OR (!is_page() && get_option('red_glossaryOnlySingle') == 1 && is_single()) OR (is_page() && get_option('red_glossaryOnPages') == 1)) OR is_front_page()) { $glossary_index = get_children(array( 'post_type' => 'glossary', 'post_status' => 'publish', )); usort($glossary_index,'sortByLength'); $content = str_replace('& #8217;', "'", $content); //added space if ($glossary_index){ $timestamp = time(); foreach($glossary_index as $glossary_item){ $timestamp++; $glossary_title = $glossary_item->post_title; if (!in_array($glossary_title,$terms_done)) { //$glossary_search = '/\b'.$glossary_title.'[A-Za-z]*?\b(?=([^"]*"[^"]*")*[^"]*$)/i'; //$glossary_search = '/[^>]('.preg_replace('/\s+/', '\s', $glossary_title).')[^<\w](?=([^"]*"[^"]*")*[^"]*$)/i'; $glossary_search = '/(?<!>)('.str_replace('/\s+/','\s',$glossary_title).'(s|\'s)?)(?!<)(?=([^"]*"[^"]*")*[^"]*$)/i'; //echo $glossary_search; //$glossary_replace = '<a'.$timestamp.'>$0</a'.$timestamp.'>'; //$glossary_replace = ' <a'.$timestamp.'>$1</a'.$timestamp.'> '; $glossary_replace = '<a'.$timestamp.'>$0</a'.$timestamp.'>'; $content_temp = preg_replace($glossary_search, $glossary_replace, $content,1); $content_temp = rtrim($content_temp); $link_search = '/<a'.$timestamp.'>('.$glossary_item->post_title.'[A-Za-z]*?)<\/a'.$timestamp.'>/i'; if (get_option('red_glossaryTooltip') == 1) { $link_replace = '<a class="glossaryLink" href="' . get_permalink($glossary_item) . '" title="Glossary: '. $glossary_title . '" onmouseover="tooltip.show(\'' . addslashes(strip_tags($glossary_item->post_content)) . '\');" onmouseout="tooltip.hide();">$1</a>'; } else { $link_replace = '<a class="glossaryLink" href="' . get_permalink($glossary_item) . '" title="Glossary: '. $glossary_title . '">$1</a>'; } $content_temp_before = $content_temp; $content_temp = preg_replace($link_search, $link_replace, $content_temp,1); if ($content_temp_before != $content_temp) $terms_done[] = $glossary_title; $content = $content_temp; } } } } return $content; } PHP: THANKS SO MUCH SO FAR!!!!! Nearly there