tags:

views:

59

answers:

3

Hi,

I'm not very good at PHP and would like to have a PHP function which turns this (text block indented by four spaces):

    printf("goodbye world!");  /* his suicide note
                                  was in C */

Into this:

<pre><code>    printf("goodbye world!");  /* his suicide note
                              was in C */</code></pre>

Leaving all other lines intact.

This is what Markdown does. I found this PHP port of Markdown (see function doCodeBlocks()), but I don't want to use the entire Markdown file, I just want this one function.

Can someone provide me with the minimal PHP code required to get this to work? So I can do this:

<?php echo markdownPre('Here goes some code:

    var x = 1, y = 2;
    alert(x + y);

That should be a pre block.'); ?>
A: 

I don't understand the problem correctly. Do you want something like -

function markdownPre($str){ return '< pre>< code>'.$str.''; }

this will return

<pre><code>    printf("goodbye world!");  /* his suicide note
                              was in C */</code></pre>

if you pass

echo markdownPre('printf("goodbye world!"); /* his suicide note was in C */')

to it.

pinaki
please note that there is no space in < pre> and < code>, the stupid editor wud not show correctly without spaces (maybe i dont know the proper syntax :) )...
pinaki
Please read my question, there's a very clear example in there. The 'stupid Stack Overflow editor' is using the functionality I described. Just prepend code blocks with four spaces.
Alfonso
+3  A: 

I have not tried, but I think you can preg_replace the regex

/((?:^(?: {4}|\t).*$\n+)+)/m

with <pre><code>$1</code></pre>.

KennyTM
`preg_replace('/((?:^(?: {4}|\t).+$\n+)+)/m', '<pre><code>$1</code></pre>', $str);` kinda seems to work, but it appends two extra line endings inside the `pre`: http://pastie.org/896665 Can this be fixed? Also, how can I use only the `$1` and do things with it (like `str_replace()`, but only inside the `$1`)?
Alfonso
+2  A: 

Although Kenny's expression works, i'd suggest replacing with callback for flexibility:

function markdownPre($in) {
    if(is_array($in)) {
        $code = $in[0];
        // post-process the code, e.g. remove leading spaces
        $code = preg_replace('~^(\x20{4}|\t)~m', '', $code);
        return "<pre>$code</pre>";
    }

    return preg_replace_callback('~(
        ^
        (\x20{4} | \t)
        (.+)
        \n
    )+~mx', __FUNCTION__, $in);
}

In the "post-process" phase you can do interesting things, for example, syntax highlighting.

stereofrog
Hrm, although this regex performs better than the other expression, there are still some small bugs. This example fails, for example: http://pastie.org/896778.txt As you can see, the last lin should be inside the code block, but is left out of it. Any ideas how to fix that?
Alfonso
try `(\n | \z)` instead of `\n`
stereofrog
@stereofrog That keeps the last line inside the pre block, which is good, but still the four initial spaces are preserved. These should be removed. Can that be fixed as well?
Alfonso