防止浏览器将行之间的'\ n'转换为空格(对于中文字符)

时间:2011-12-18 06:03:02

标签: html browser cjk

将换行转换为空格对英语有意义,例如,以下HTML

<p>
This is
a sentence.
</p>

我们在浏览器中将换行符转换为空格后得到以下内容:

This is a sentence.

这对英语有好处,但对汉字不好,因为我们不使用空格分隔中文单词。这是一个例子(中文句子的含义与“这是一个句子”相同):

<p>
这是
一句话。
</p>

我在Chrome,Safari和IE上获得以下结果

这是 一句话。

我想要的是以下内容,没有额外的空间。

这是一句话。

我不知道为什么浏览器不会忽略换行符,如果当前行的最后一个字符和下一行的第一个字符都是中文字符(我觉得更有意义) )。或者他们提供了这种机制但需要特殊处理?

顺便说一句,在Vim中,当使用“J”连接线时,如果2行的最后一个和第一个字符都是中文字符,则不会添加空格。但对于英语,将增加一个空间。所以我觉得Vim为此做了一些特别的处理。

更新

虽然我认为这是浏览器的一个问题,但我必须接受它。因此,目前我会在生成HTML之前预处理我的Markdown文本以加入中文行。以下是我在Ruby中执行此操作的方法,处理中文标点符号的完整代码位于gist

#encoding: UTF-8

# Requires ruby 1.9.x, and assume using UTF-8 encoding

class String
  # The regular expression trick to match CJK characters comes from
  # http://stackoverflow.com/a/4681577/306935
  def join_chinese
    gsub(/(\p{Han})\n(\p{Han})/m, '\1\2')
  end
end

3 个答案:

答案 0 :(得分:9)

浏览器将换行符视为空格,因为自HTML 2.0以来规范就是这样说的。事实上,HTML 2.0比后来的规范更温和;它说:“HTML用户代理应该将其任何变体中的行尾作为所有上下文中的单词空间,除了预先格式化的文本。”(Conventional Representation of Newlines),而较新的规范说这更强(将其描述为发生的事情)在HTML中)。

背景是HTML和Web是以西欧语言为主开发的;这反映在原始规范和早期实现的许多功能中。他们只是慢慢地国际化了。

解析规则不太可能会被更改。更有可能的是,可能发生的是对语言或角色属性渲染的敏感性。这意味着换行符仍然被视为一个空格(并且DOM字符串将包含Ascii空格字符),但像一样的字符串将被呈现,好像空间不是那里。这就是HTML 4.01规范似乎引用的内容(White space)。文本有点混淆,但我认为它试图说这种行为将取决于内容语言,无论是由浏览器推断还是在标记中声明。

但是浏览器还没有这样做。声明内容的语言,例如<html lang=zh>,是一个很好的原则,但在渲染方面几乎没有实际影响,它可能会影响浏览器对默认字体的选择(但有多少作者让浏览器使用其默认字体?)。如果空格字符恰好在浏览器指定语言的默认字体中更宽,它甚至可能导致添加间距。

根据CSS3 Text草案,您可以使用text-spacing属性。值none“关闭所有文本间距功能。所有全角字符都使用全角字形设置。“不幸的是,似乎没有浏览器支持这一点。

答案 1 :(得分:4)

有一种方法可以解决这个问题(经典的解决方法)。为了限制(当前)浏览器将换行符解释为空格,您必须将font-size设置为0。

对于子元素,您必须再次将font-size设置为其初始值。所以对于你的代码,一个例子是:

<p class="nowhitespace">
  <span>这是</span>
  <span>一句话。</span>
</p>

CSS可以包含如下代码:

.nowhitespace { font-size: 0; }
.nowhitespace > span { font-size: 16px; }

答案 2 :(得分:2)

到目前为止,我知道实现这种效果的最短路径是在打开标签后打破。但是您不希望在源中插入额外的标记。如果有一些标签什么都不做,那就太好了。实际上,还有一个评论。

source_file.cpp:11:25: warning: suggest braces around initialization of subobject [-Wmissing-braces]
        std::array<int, 3> a1({1, 2, 3});
                               ^~~~~~~
                               {      }
source_file.cpp:12:24: warning: suggest braces around initialization of subobject [-Wmissing-braces]
        std::array<int, 3> a2{1, 2, 3};
                              ^~~~~~~
                              {      }
source_file.cpp:13:27: warning: suggest braces around initialization of subobject [-Wmissing-braces]
        std::array<int, 3> a3 = {1, 2, 3};
                                 ^~~~~~~
                                 {      }
source_file.cpp:19:16: warning: suggest braces around initialization of subobject [-Wmissing-braces]
        as.push_back({1, 2, 3});
                      ^~~~~~~
                      {      }

这将为您提供以下内容。

<p>
这是<!--
-->一句话。
</p>

灵感来源:No extra space