Related to and also resolves: http://drupal.org/node/128816

The issue I was having was related to links of this form:
[[Some CamelCase Here|Link Name]]

I mentioned this http://drupal.org/node/48326 and was told it was nightmarish. Which I agree, it can be. But I thought I'd give the solution a shot anyway. It involves splitting the filter into two passes. The first handles bracketed links, and the second the CamelCase links. Here is the modified _freelinking_do_filtering function:

function _freelinking_do_filtering($text, $store = FALSE) {
    // First pass. Only bracketed links
    $freelinkingregexp = '/\[\[.+]]/U'; // this finds [[ links like this]], un-greedily
    preg_match_all($freelinkingregexp, $text, $flmatches);
    $wikiwords = $flmatches[0];

    $tokens = $phrases = $replacements = array();
    foreach (array_unique($wikiwords) as $wikiword) {
        if (substr($wikiword, 0, 2) == '[[') { // if it's a freelink, the expressions are different
            $phrase = substr($wikiword, 2, -2);
            $freelink = $phrase;
            $barpos = strpos($phrase, '|');
            $pattern = '/\[\[' . preg_quote($phrase, '/') . ']]/';
            if ($barpos) {
                $freelink = substr($freelink, 0, $barpos);
                $phrase = substr($phrase, $barpos + 1);
            }
            if (preg_match('/^(http|mailto|https|ftp):/', $freelink)) {
                $replacement = '<a class="freelinking external" href="' . $freelink . '">' . $phrase . '</a>';
            }
            else {
                $replacement = l($phrase, 'freelinking/' . rawurlencode($freelink), array('class' => 'freelinking'));
            }
        }
        $index = count($tokens);
        $token = '::TOKEN'.$index.'::';
        $tokens[$index] = '/'.$token.'/';
        $phrases[$index] = $phrase;
        $replacements[$index] = $replacement;

        $text = preg_replace($pattern, $token, $text);
    } // foreach wikiword

    // Second pass. CamelCase links (if required).
    $allowcamelcase = variable_get("freelinking_camelcase", TRUE);

    $cctokens = $ccphrases = $ccreplacements = array();
    if ($allowcamelcase) {
        $camelcaseregexp = '/\b([[:upper:]][[:lower:][:digit:]]+){2,}\b/'; // this gets us close, but is not perfect. Example: ThisIsACamelCaseWord won't match
        preg_match_all($camelcaseregexp, $text, $ccmatches);
        $wikiwords = $ccmatches[0];

        foreach (array_unique($wikiwords) as $wikiword) {
            $pattern = '/\b' . $wikiword . '\b(?![^<]*>)/';
            $phrase = $wikiword; // consistency for the db
            $freelink = $wikiword; // also for the db
            $replacement = l($wikiword, 'freelinking/' . urlencode($wikiword));

            $index = count($cctokens);
            $token = '::CCTOKEN'.$index.'::';
            $cctokens[$index] = '/'.$token.'/';
            $ccphrases[$index] = $phrase;
            $ccreplacements[$index] = $replacement;

            $text = preg_replace($pattern, $token, $text);
        } // foreach wikiword
    }

    // Replace the tokens
    ksort($tokens);
    ksort($replacements);
    $text = preg_replace($tokens, $replacements, $text);
    ksort($cctokens);
    ksort($ccreplacements);
    $text = preg_replace($cctokens, $ccreplacements, $text, variable_get("freelinking_onceonly", 0) ? 1 : -1);

    if ($store) {
        ksort($phrases);
        foreach ($phrases as $key => $phrase) {
            _freelinking_store($phrases[$key], $replacements[$key]);
        }

        if ($allowcamelcase) {
            ksort($ccphrases);
            foreach ($ccphrases as $key => $phrase) {
                _freelinking_store($ccphrases[$key], $ccreplacements[$key]);
            }
        }
    }

    return $text;
} // endfunction _freelinking_do_filtering

The filter runs in three passes: the first for bracketed links; the second for CamelCase links. These two replaces the links with a token. In the final pass, the tokens will be replaced with the actual links.

Should work for:

[[Some CamelCase Here|Link Text]]
[[CamelCase|Link Text]]
CamelCase

I would appreciate any feedback for this patch. It seems to do what is expected, but there may be cases I have not considered.

Comments

eafarris’s picture

Status: Needs review » Needs work

Interesting idea. Care to make this a real patch? http://drupal.org/patch/create

ecalos’s picture

StatusFileSize
new5.08 KB

Attached. :)

Let me know if there're any problems with it.

ecalos’s picture

StatusFileSize
new5.08 KB

Tweaked. It now correctly supports "Only link first occurance" for CamelCase.

mlncn’s picture

Subscribing. (Turned off CamelCase to get around this.)

eafarris’s picture

Status: Needs work » Fixed

Fixed in freelinking-6.x-1.7. Please verify and close.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.