Ben*_*Ben 7 ruby character-encoding sinatra
我有一个非常简单的运行在Ruby 1.9.3上的Sinatra应用程序,它使用ERB和markdown模板.我已经剥离它以证明问题.
这是在Mac OS X Snow Leopard上运行Sinatra 1.3.2.对于降价我使用的是rdiscount 1.6.8.
主要的Ruby文件包含
get '/services' do
erb :services
end
Run Code Online (Sandbox Code Playgroud)
services.erb文件中包含以下内容
<%= markdown :'content/service1' %>
£
Run Code Online (Sandbox Code Playgroud)
在markdown文件中我只有一行
£
Run Code Online (Sandbox Code Playgroud)
当我运行Sinatra应用程序并加载'services'页面时,我Encoding::CompatibilityError at /services incompatible character encodings: UTF-8 and ASCII-8BIT在ERB文件的第二行(仅包含'£'的那一行)上获得了异常.
我做了很多谷歌搜索,我不能为我的生活弄清楚为什么会这样.ERB和markdown文件在我的本地磁盘上是UTF-8,但显然它们被Sinatra加载并变成字符串,我不知道如何判断这些字符串的编码.
如果我强迫Sinatra使用ASCII-8BIT(通过添加settings.default_encoding = 'ASCII-8BIT'到我的主要Sinatra Ruby文件的顶部),则不会抛出任何异常但是'£'字符出现错误.
有什么指针吗?
mat*_*att 15
这是Sintra使用的模板系统Tilt中的一个问题(正在考虑用于Rails).看看问题#75和#107.
问题基本上取决于Tilt如何从磁盘读取模板文件 - 它使用binread.这意味着传递给实际模板引擎的源字符串具有相关的编码ASCII-8BIT,这基本上是说它是未知的.
RDiscount有代码来设置输出的编码以匹配输入,但是当输入编码时,这没有多大帮助ASCII-8BIT; 结果给出相同的编码.Kramdown也会发生同样的事情(或者类似的事情),所以简单的切换不会解决这个问题.
当模板具有非ascii字符(即£)并且您尝试将结果与其他utf-8编码的字符串组合时,这会导致问题.如果模板只包含ascii字符,则它与utf-8兼容,Ruby可以组合两个字符串.如果没有,你得到CompatibilityError你所看到的.
一种可能的解决方法是自己读取模板文件,并使用正确的编码将生成的字符串传递给Tilt:
<%= markdown File.read './views/pound.md' %>
£
Run Code Online (Sandbox Code Playgroud)
通过自己阅读文件read而不是binread,您可以确保它具有正确的编码,因此与erb文件的其余部分兼容.您可能想要一次读取该文件,并在尝试此操作时将内容缓存到某处.
另一种解决方法是捕获markdown方法的输出并force_encoding在其上使用:
<%= markdown(:pound).force_encoding('utf-8') %>
£
Run Code Online (Sandbox Code Playgroud)
这是可能的,因为虽然编码是ASCII-8BIT,但您知道字符串中的字节确实是utf-8编码的,因此您只需更改编码即可.
| 归档时间: |
|
| 查看次数: |
3218 次 |
| 最近记录: |