nl2br event plugin improved

Discussion corner for Developers of Serendipity.
Post Reply
Brendon K
Regular
Posts: 44
Joined: Thu Feb 23, 2006 10:35 pm
Location: Saratoga Springs, NY, USA
Contact:

nl2br event plugin improved

Post by Brendon K »

As a programmer/developer, I love posting code snippets. I also prefer typing in my own HTML markup, unless it's a simple line-break. Unfortunately, there are times when line breaks aren't really desirable (such as in PRE tags since the BR tag will actually be visible). As such, I've finally found some time to modify the nl2br event plugin to make it a tiny bit smarter. I'd like some more help though, as I'd like to make it a bit more smarter, and unfortunately don't understand the plugin setup much at all.

Anyway...

With help from some members on the SitePoint forums, I've modified the serendipity_event_plugin_nl2br to work with HTML textarea, pre, and the BBCode GeSHi modifiers so that those ugly <br /> tags aren't added when they aren't wanted.

Here's what I did:
- Open up plugins\serendipity_event_nl2br\serendipity_event_nl2br.php in your serendipity folder
- add two new functions (within the class, but order of where they go is unimportant, I placed them before the event_hook function) as shown below:

Code: Select all

    function isolate($src, $regexp = NULL)
    {
        if($regexp) return preg_replace_callback($regexp, array($this, 'isolate'), $src);
        global $_buf;
        $_buf[] = $src[0];
        return "\001" . (count($_buf) - 1);
    }

    function restore($text)
    {
        global $_buf;
        return preg_replace('~\001(\d+)~e', '$_buf[$1]', $text);
    }
- find the following line in the event_hook function: <strong><code>$eventData[$element] = nl2br($eventData[$element]);</code></strong> and replace it with the following:

Code: Select all

$eventData[$element] = $this->isolate($eventData[$element], '~[<\[](textarea|pre|geshi).*?[>\]].*?[<\[]/\1[>\]]~si');
$eventData[$element] = nl2br($eventData[$element]);
$eventData[$element] = $this->restore($eventData[$element]);
What I'd like to do is to allow for users to modify the tags that would be used within the REGEXP (I know, I'd have to modify the regex, not a problem) by using a plugin administration page...this way, if a plugin that I'm not aware of yet is created that would benefit from this, a user (or possibly even the plugin itself) could modify the tags that are skipped from the nl2br PHP call.

This modified version should not effect anyone using the rich text editor, but will help those trying to use GeSHi or other code-posting methods. I would strongly suggest applying this to the current nl2br plugin, and/or replacing it and giving it a different name (nl2br_enhanced).
Last edited by Brendon K on Tue Nov 14, 2006 2:19 am, edited 2 times in total.
They say, "Practice makes perfect," yet they also say, "Nobody's perfect." I don't get it.
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: nl2br event plugin improved

Post by garvinhicking »

Hi Brendon!

Thanks a lot for having a stab at this MUCH required tuning of the plugin.

I took your help and poured it into a configurable s9y plugin enhancement, and would like to commit it to our repository.

However, the problem is: It doesn't work for me!

I entered a text like this:

Code: Select all

Here
be
linebreaks

<code>
here
be
dragons
</code>

End of topic
I would expect a result like this:

Code: Select all

Here<br />
be<br />
linebreaks<br />
<br />
<code>
here
be
dragons
</code>
<br />
End of topic
But what I get is:

Code: Select all

Here<br />
be<br />
linebreaks<br />
<br />
\0010
<br />
End of topic
So it seems the callback does not work as intended?

Since I don't really understand what your code modification does exactly, maybe you have a clue?

The patched nl2br file is here:

http://rafb.net/paste/results/MiDh4082.html

HTH,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
Brendon K
Regular
Posts: 44
Joined: Thu Feb 23, 2006 10:35 pm
Location: Saratoga Springs, NY, USA
Contact:

Post by Brendon K »

Thanks, Garvin!

I do know that the code, as it was, does work. I'm using it on my blog right now. :) I'm at work right now but will take a look at the current/modified version once I get home.

The code will basically do the following:
1.) Find any string matching the REGEX.
2.) Replace found string with an octal character of \001 plus another digit thereafter which references an array index of where the originally found string will be stored.
3.) We call the nl2br function on the string from step 2.
4.) We once again replace the \001 character(s) with the index(es) found in the array, respectively, successfully bypassing the nl2br call from that string section.

Seems like, as you said, something's not occuring. My initial thought is that the restore function is not being called, but from quickly scanning your code, that doesn't make much sense if the isolate function is (as they both are using the same IF statement to hop into the code section).

Like I said, I'll take a look later on tonight after work (about 8 hours from now).
They say, "Practice makes perfect," yet they also say, "Nobody's perfect." I don't get it.
Brendon K
Regular
Posts: 44
Joined: Thu Feb 23, 2006 10:35 pm
Location: Saratoga Springs, NY, USA
Contact:

Post by Brendon K »

Oh no! My sincerest apologies, Garvin! I didn't double check my copy/paste! I'm having issues with my current install calling strip_slashes one too many times, either because of a rogue plugin, or because I just simply need to upgrade. I must have copied and pasted the code from the backend, which had used too many escape characters in the REGEX's! I've updated my code above (in case someone sees it and wants to use it for something else) and also updated the current code, to which I've created a pastie for (plaintext format):

http://pastie.caboo.se/22586

I made one change in your code:
Rather than use two if statements, I reduced it to one and duplicated a call to nl2br -- one inside the if, one outside. Why use an extra conditional if not necessary? You're more than welcome to change it back. :P

I do have one question: Would it be worth while to separate ignored HTML tags from BBCode tags? My current REGEX acts on them both as if they were the same ([textarea] | <textarea>).

Thanks for the help on adding the editable fields! I really need to learn the plugin system. :D So much more I want to do!

--edit #2--
I just noticed there's a plugin specific forum section...the description of this one says it's also for plugin improvement. What's the difference? :P
They say, "Practice makes perfect," yet they also say, "Nobody's perfect." I don't get it.
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Hi Brendon!

Awesome, great. This is SO cool! I just committed your plugin change, it perfectly works now (after I introduced the custom taglist in your method calls *g*).

Thanks so much!
I do have one question: Would it be worth while to separate ignored HTML tags from BBCode tags? My current REGEX acts on them both as if they were the same ([textarea] | <textarea>).
I think that's perfectly fine, no seperation needed IMHO.
Thanks for the help on adding the editable fields! I really need to learn the plugin system. :D So much more I want to do!
Would be great to have you around for some more cool changes like this :)
I just noticed there's a plugin specific forum section...the description of this one says it's also for plugin improvement. What's the difference? :P
Yeah, uhm, I myself often see that the seperation of our boards is not that intuitive. Plugin was more meant for plugin user-to-developer talk, whereas "development" more means "developer to developer". So actually you posted your topic exactly where I would like to have it :)

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
Boris

Post by Boris »

Brendon,

thanks for these great changes¹. Till now I always had to write a ul-list in one line to get valid code. :)

I just checked out the plugin from svn and it seems to work really great. Perhaps "ul,ol" should be added to the list of examples.

¹) and some credits to Garvin
Last edited by Boris on Tue Nov 14, 2006 11:29 pm, edited 2 times in total.
Brendon K
Regular
Posts: 44
Joined: Thu Feb 23, 2006 10:35 pm
Location: Saratoga Springs, NY, USA
Contact:

Post by Brendon K »

:oops: :P This was my biggest gripe with Serendipity, so I just had to work on it since I loved the system itself so much. Thanks for the credit, Garvin, but you did more work than I did...then again you always do! ;)

To be honest, I don't know why CODE tags are listed as an example, they aren't block level elements (they're for styling purposes on most browsers, causing whatever text is within them to be output with a system-type font).

Either way, with Garvin's work on the ability to add your own tags, you can configure it however you want. I would hope some future suggestions are made on making this much smarter, as I'm sure that adding convenience in one place will cause problems in others.
They say, "Practice makes perfect," yet they also say, "Nobody's perfect." I don't get it.
Post Reply