1

ご存知かもしれませんが、私は CMS を作成していますが、今、小さな問題があります。

言いましょう:私はこれを含むテキストファイルを持っています:

[b]Some bold text[/b]
[i]Italic[/i]
- List item 1
- List item 2
- List item 3
# List item 1
# List item 2
# List item 3

そして、私はそれを次のように変換したい:

<b>Some bold text</b>
<i>Italic</i>
<ul>
    <li>List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
</ul>
<ol>
    <li>List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
</ol>

太字と斜体は (正規表現を使用して) 機能しますが、リストを作成するにはどうすればよいですか?

「-」リストは次のように変換する必要があります

<ul>
    <li>List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
</ul>

そして、「#」リストへ

<ol>
    <li>List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
</ol>

誰もこれを経験していますか?私を助けてください。私はPHP 5.2.9を使用しています

4

3 に答える 3

3

既存の解析ライブラリを使用したくない場合は、ファイルを 1 行ずつ解析し、現在の状態をどこかに保持する必要があります。

行が「 - 」で始まり、まだリストに含まれていないことが状態で示されている場合は、<ul> と <li> を追加します。すでにリストに入っている場合は、<li> を入れてください。

「 # 」で始まる行も同じです。

于 2009-07-23T11:56:22.310 に答える
2

MarkdownTextileなどの別のマークアップ言語の使用を検討することもできます。次に、ライブラリを処理するだけです。

于 2009-07-23T11:56:00.610 に答える
0

OK、Markdown のすべてが必要というわけではありませんが、
必要な機能だけを取り入れてみませんか?

リスト処理関数が手続き的に機能するように調整しました。
ファイル サイズを最小限に抑えるために、詳細な正規表現を圧縮し、
他の Markdown に関連するコメントを削除しました。
3308バイトでクロックインします。

たぶん、あなたの好みにはまだ肥大しすぎているかもしれません... d-: でも
、もっと手抜きをしたり、物を取り除いたりするのは自由です。
たとえば、ネストされたリストは必要ないかもしれません。

変更後のコードは以下です。
最初のライセンスは次のとおりです。

PHP Markdown Copyright (c) 2004-2009 Michel Fortin
http://michelf.com/
無断複写・ 転載を禁じます。

Markdown に基づく
Copyright (c) 2003-2006 John Gruber
http://daringfireball.net/
無断複写・ 転載を禁じます。

次の条件が満たされている場合、ソースおよびバイナリ形式での再配布および使用は、変更の有無にかかわらず許可されます。

  • ソース コードの再配布には、上記の著作権表示、この条件のリスト、および次の免責事項を保持する必要があります。

  • バイナリ形式での再配布では、上記の著作権表示、この条件のリスト、および次の免責事項を、配布と共に提供されるドキュメントおよび/またはその他の資料に再現する必要があります。

  • 「Markdown」という名前もその貢献者の名前も、事前の書面による特定の許可なしに、このソフトウェアから派生した製品を推奨または宣伝するために使用することはできません。

このソフトウェアは、著作権所有者および貢献者によって「現状のまま」提供され、商品性および特定目的への適合性の黙示の保証を含むがこれらに限定されない、明示的または黙示的な保証は否認されます。いかなる場合でも、著作権所有者または貢献者は、直接的、間接的、偶発的、特別、模範的、または結果的な損害 (代替の商品またはサービスの調達、使用、データ、または利益の損失、およびその他の損害を含むがこれらに限定されない) について責任を負わないものとします。契約、厳格責任、不法行為 (過失またはその他を含む) にかかわらず、このソフトウェアの使用から何らかの形で発生した場合、そのような損害の可能性について知らされていた場合でも、責任の理論に基づいています。

<?php
@define('MARKDOWN_TAB_WIDTH', 4);
$tab_width = MARKDOWN_TAB_WIDTH;
$list_level = 0;

function doLists($text) {
# Form HTML ordered (numbered) and unordered (bulleted) lists.
    global $tab_width, $list_level;
    $less_than_tab = $tab_width - 1;
    # Re-usable patterns to match list item bullets and number markers:
    $marker_ul_re  = '[*-]';
    $marker_ol_re  = '\d+[\.]';
    $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
    $markers_relist = array(
        $marker_ul_re => $marker_ol_re,
        $marker_ol_re => $marker_ul_re,
        );
    foreach ($markers_relist as $marker_re => $other_marker_re) {
        # Re-usable pattern to match any entirel ul or ol list:
        $whole_list_re = '((([ ]{0,'.$less_than_tab.'})('.$marker_re.')[ ]+)(?s:.+?)(\z|\n{2,}(?=\S)(?![ ]*'.$marker_re.'[ ]+)|(?=\n\3'.$other_marker_re.'[ ]+)))'; // mx
        # We use a different prefix before nested lists than top-level lists.
        # See extended comment in _ProcessListItems().
        if ($list_level) {
            $text = preg_replace_callback('{
                    ^
                    '.$whole_list_re.'
                }mx',
                '_doLists_callback', $text);
            }
        else {
            $text = preg_replace_callback('{
                    (?:(?<=\n)\n|\A\n?) # Must eat the newline
                    '.$whole_list_re.'
                }mx',
                '_doLists_callback', $text);
            }
        }
    return $text;
    }

function _doLists_callback($matches) {
# Re-usable patterns to match list item bullets and number markers:
    $marker_ul_re  = '[*+-]';
    $marker_ol_re  = '\d+[\.]';
    $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
    $list = $matches[1];
    $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
    $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
    $list .= "\n";
    $result = processListItems($list, $marker_any_re);
    $result = "<$list_type>\n" . $result . "</$list_type>";
    return "\n". $result ."\n\n";
    }

function processListItems($list_str, $marker_any_re) {
#   Process the contents of a single ordered or unordered list, splitting it
#   into individual list items.
# The $list_level global keeps track of when we're inside a list.
# Each time we enter a list, we increment it; when we leave a list,
# we decrement. If it's zero, we're not in a list anymore.
    global $list_level;
    $list_level++;
# trim trailing blank lines:
    $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
    $list_str = preg_replace_callback('{(\n)?(^[ ]*)('.$marker_any_re.'(?:[ ]+|(?=\n)))((?s:.*?))(?:(\n+(?=\n))|\n)(?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))}xm','_processListItems_callback', $list_str);
    $list_level--;
    return $list_str;
    }

function _processListItems_callback($matches) {
    $item = $matches[4];
    $leading_line =& $matches[1];
    $leading_space =& $matches[2];
    $marker_space = $matches[3];
    $tailing_blank_line =& $matches[5];
    if ($leading_line || $tailing_blank_line
    || preg_match('/\n{2,}/', $item))
        { # Replace marker with the appropriate whitespace indentation
        $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
        $item = outdent($item)."\n";
        }
    else { # Recursion for sub-lists:
        $item = doLists(outdent($item));
        $item = preg_replace('/\n+$/', '', $item);
        }
    return "<li>" . $item . "</li>\n";
    }

function outdent($text) {
# Remove one level of line-leading tabs or spaces
    global $tab_width;
    return preg_replace('/^(\t|[ ]{1,'.$tab_width.'})/m', '', $text);
    }
?>
于 2012-08-29T00:36:06.907 に答える