Код PHP для преобразования текстовых блоков с отступом в четыре пробела в блок ‹pre›‹code› [Markdown]

Я не очень хорошо разбираюсь в PHP и хотел бы иметь функцию PHP, которая превращает это (текстовый блок с отступом в четыре пробела):

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

В это:

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

Оставив все остальные линии нетронутыми.

Это то, что делает Markdown. Я нашел это PHP-порт Markdown (см. function doCodeBlocks()), но я не хочу использовать весь файл Markdown, мне нужна только эта функция.

Может ли кто-нибудь предоставить мне минимальный код PHP, необходимый для работы? Итак, я могу сделать это:

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

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

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

person Community    schedule 31.03.2010    source источник


Ответы (3)


Хотя выражение Кенни работает, я бы предложил заменить его обратным вызовом для гибкости:

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);
}

На этапе «постобработки» можно делать интересные вещи, например, подсвечивать синтаксис.

person user187291    schedule 31.03.2010
comment
Хм, хотя это регулярное выражение работает лучше, чем другое выражение, все же есть небольшие ошибки. Этот пример не работает, например: pastie.org/896778.txt Как видите, последняя строка должен находиться внутри блока кода, но не входит в него. Есть идеи, как это исправить? - person ; 31.03.2010
comment
попробуйте (\n | \z) вместо \n - person user187291; 31.03.2010
comment
Это сохраняет последнюю строку внутри блока pre, что хорошо, но все же сохраняются четыре начальных пробела. Их следует удалить. Это тоже можно исправить? - person ; 31.03.2010

Я не пробовал, но я думаю, что вы можете preg_replace регулярное выражение

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

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

person kennytm    schedule 31.03.2010
comment
preg_replace('/((?:^(?: {4}|\t).+$\n+)+)/m', '<pre><code>$1</code></pre>', $str); вроде как работает, но добавляет два дополнительных конца строки внутри pre: pastie.org/896665. быть исправлено? Кроме того, как я могу использовать только $1 и делать с ним что-то (например, str_replace(), но только внутри $1)? - person ; 31.03.2010

Я не правильно понимаю проблему. Вы хотите что-то вроде -

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

это вернется

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

если вы пройдете

echo markdownPre('printf("Прощай, мир!"); /* его предсмертная записка была на C */')

to it.

person pinaki    schedule 31.03.2010
comment
обратите внимание, что в ‹ pre› и ‹ code› нет пробела, глупый редактор не будет правильно отображать без пробелов (может быть, я не знаю правильного синтаксиса :))... - person pinaki; 31.03.2010
comment
Пожалуйста, прочитайте мой вопрос, там есть очень наглядный пример. «Глупый редактор Stack Overflow» использует описанную мной функциональность. Просто добавьте блоки кода с четырьмя пробелами. - person ; 31.03.2010