如何处理bbcode中的换行符?

时间:2015-02-28 06:34:40

标签: css whitespace bbcode pecl nl2br

我使用PECL bbcode扩展来定义一组我允许论坛的标签。我已经实现了http://www.bbcode.org中描述的几乎所有标记。

论坛用户已经开始期望当他们在输入字段中添加新行时,他们的帖子也将采用新行。我试图让这件事发生。

nl2br()方式

nl2br()非常适合在用户输入浏览器时使用换行符,因为它会在其中找到换行符并抛出<br />标记,以使浏览器也使用换行符。但这会给一些更复杂的标记带来麻烦。

例如:

[ul]
[li]list item 1[/li]
[li]list item 2[/li]
[/ul]

结果

<ul><br />
<li>list item 1</li><br />
<li>list item 2</li><br />
<ul>

每个地方都会抛出空白。出于同样的原因,表也有类似的问题。此外,任何实际显示空格的标记(例如<pre><code>code goes here</code></pre>)都会得到双倍行距。恶心。

CSS方式

CSS有white-space个规则,在这些情况下可以派上用场。如果我们将所有论坛帖子放在.bbcode元素中,然后只包含样式表规则

.bbcode {
    white-space: pre-line;
}

然后浏览器将保留换行符,折叠其他空格并包装单词。这听起来很理想。但是,列表项等仍会出现此双倍间距问题,因为浏览器会在每个</li>之后显示换行符。

我们可以通过定义:

来解决的一些
.bbcode {
    white-space: pre-line;
}
.bbcode * {
    white-space: normal;
}

缓解了列表和表格中的问题。但是,现在新行仅出现在帖子的根元素中,因此请在换行符中添加换行符。表格单元格不起作用。

我该怎么做?方式

我真正想要的是两种效果的组合:

  • 当源在所有标记之外采用换行符时,浏览器会使用换行符
  • 如果在关闭或打开块级或结构标记之后源不采用换行符,则浏览器会使用换行符

理想情况下,我认为[li]some\ntext[/li]应该产生两行,[li]sometext[/li]\n应该只产生一行,[i]sometext[/i]\n应该产生两行。

这样的事情怎么样?或者更确切地说,人们通常在使用bbcode的论坛中做些什么?我可能会编写一个函数,在其中我定义了应该插入<br />的所有情况,这很有可能重新发明许多轮子。

2 个答案:

答案 0 :(得分:1)

我现在解决的是

nl2br-str_replace方式

$html = nl2br(bbcode_parse($handler, htmlentities($bbcode_string)));
$html = str_replace(
    array('</div><br />', '<tr><br />', '</tr><br />', '<th><br />', '</th><br />', '<td><br />', '</td><br />', '<ul><br />', '</ul><br />', '<ol><br />', '</ol><br />', '<li><br />', '</li><br />', '</pre><br />'),
    array('</div>', '<tr>', '</tr>', '<th>', '</th>', '<td>', '</td>', '<ul>', '</ul>', '<ol>', '</ol>', '<li>', '</li>', '</pre>'), $html);
return $html;

和CSS:

.bbcode pre br {
    display: none;
}

这里发生了什么?我不是定义我想要换行符的位置,而是定义我知道它们的位置,而我想要它们。

CSS可以防止pre元素中的双倍间距(并且您需要添加从空白处获取换行符的任何其他元素)。 PHP消除了由用户将换行符放在例如新行之间的换行符。 [li]stuff[/li]元素。

这很脆弱:如果用户在[/ li]之后和换行符之前键入空格,则<br />不会被删除。我可以使用正则表达式来查找[tag][whitespace]<br />,但我不认为这是一个很大的问题。


我现在接受这个答案,因为这是我在过去几天能够提出或找到的最好的答案。如果其他人知道更好的解决方案,请发布它,我会很乐意接受它。

答案 1 :(得分:0)

如果有其他人有解决方案,我很乐意听取并接受它,但在此期间,我能够提出的最佳解决方案就是我所说的:

Sneaky(但无效的HTML)CSS Way

只需使用PHP的nl2br()函数,保留white-space: normal,但添加以下CSS规则:

.bbcode ul > br,
.bbcode ol > br,
.bbcode table > br,
.bbcode tr > br,
.bbcode pre br {
    display: none;
}

基本上,这可以让您定义不应显示的“br”实例。特别是,当我们在列表中而不是列表项,在表中但不在单元格中,以及在pre(已经保留了空格)的情况下,我隐藏它们。

然后我们需要隐藏块级元素的尾随换行符:

.bbcode table + br,
.bbcode ul + br,
.bbcode ol + br,
.bbcode div + br,
.bbcode iframe + br,
.bbcode pre + br,
.bbcode blockquote + br {
    display: none;
}

就是这样!我们可以使用一个包含大量elem + br规则的规则来制作,但是因为我在使用选择符号(我知道的话)之前我从未听说过这种选择器,所以我可以安全地播放它相当)我可以跨浏览器兼容。

我希望这有助于某人!