解决Jekyll不支持中文名和路径
解决Jekyll不支持中文名和路径
Jekyll如果在Mac系统中,目录有中文字,生成新文件的时候会报错,主要原因是因为Ruby做字符串连接的时候,不支持中文,这样需要把一些字符,通过.force_encoding(“UTF-8”)转换成中文这样就不出错。 在部署的时候, 不是直接用GitPages的Jekyll服务,而且生成HTML静态文件,所以Github上 Jekyll支持不支持中文字符没关系, 本地Jekyll生成文件的时候不出错就达到目的了。
因为用的是rbenv虚拟的ruby运行环境,有多个ruby运行环境,代码改动的位置,在对应的Ruby版本目录下进行修改。
/Users/username/.rbenv/versions/2.7.2/lib/ruby/2.7.0/webrick/httpservlet/filehandler.rb
在这个文件中有一个,set_filename方法,把base这个变量强制改成base.force_encoding(“UTF-8”)))
Jekyll项目所在的系统路径中出现中文,
def set_filename(req, res)
res.filename = @root.dup
path_info = req.path_info.scan(%r|/[^/]*|)
path_info.unshift("") # dummy for checking @root dir
while base = path_info.first
break if base == "/"
break unless File.directory?(File.expand_path(res.filename + base.force_encoding("UTF-8")))
shift_path_info(req, res, path_info)
call_callback(:DirectoryCallback, req, res)
end
不支持中文的问题, 不限于只有本地路径有中文,还有其他与中文字符连接的时候都有这个问题。比如,文件名, title名,各种属性的设置都有可能不支持中文,基本的解决方法原则,就转成UTF-8字符再进行字符连接。
Jekyll在读取中文目录的时间报错,不能实时的监控文件变化,一遇到变更中文文件名的markdown文件就出错。
根本原因, 在原有英文代码里,没有考虑bit asc与UTF-8数据join连接造成的出错。
出现问题呢的文件是:
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/pathname.rb
解决的方法是直接修改源码:
原始代码:
def children(with_directory=true)
with_directory = false if @path == '.'
result = []
Dir.foreach(@path) {|e|
next if e == '.' || e == '..'
if with_directory
result << self.class.new(File.join(@path, e))
else
result << self.class.new(e)
end
}
result
end
修改代码,如下:
def children(with_directory=true)
with_directory = false if @path == '.'
result = []
Dir.foreach(@path) {|e|
next if e == '.' || e == '..'
if with_directory
#print e, "\n"
#print @path, "\n"
result << self.class.new(File.join(@path.force_encoding("UTF-8"), e))
else
result << self.class.new(e)
end
}
result
end
关键的地方是,是将@path变成 @path.force_encoding(“UTF-8”) , 这样就可以和后面的“e"的UTF-8的内容进行join字符串连接了。
这样修改问题就解决了。
要是出现了“Encoding::CompatibilityError: incompatible character encodings: UTF-8 and GBK”
有可能是之前设置成了:
chcp 850
改回
chcp 936
这个改环境,而不是文件的编码格式,如果不想改文件的编码格式就,可以直接把UTF-8改成GBK,这个问题也解决了。
result << self.class.new(File.join(@path.force_encoding("GBK"), e))
后来又出问题了,在Windows10上用choco装的Jekyll是3.x,用的Ruby也是是3.x但是, Bunlde是 2.2, Bundle install 出来的Jekyll是 4.x,最后运行不起来有,少了webrick,gem install 装了也装不到4.x中,Bundle Update也没用,就把Ruby降级到了2.7好用了,但是,又不支持中文名了。
C:/tools/Ruby27-x64/lib/ruby/gems/2.7.0/gems/liquid-4.0.3/lib/liquid/block_body.rb
直接改了, 和上面的思路一样,强转。
def render(context)
output = []
context.resource_limits.render_score += @nodelist.length
idx = 0
while node = @nodelist[idx]
case node
when String
check_resources(context, node)
output << node
when Variable
render_node_to_output(node, output, context)
when Block
render_node_to_output(node, output, context, node.blank?)
break if context.interrupt? # might have happened in a for-block
when Continue, Break
# If we get an Interrupt that means the block must stop processing. An
# Interrupt is any command that stops block execution such as {% break %}
# or {% continue %}
context.push_interrupt(node.interrupt)
break
else # Other non-Block tags
render_node_to_output(node, output, context)
break if context.interrupt? # might have happened through an include
end
idx += 1
end
output = output.map{ |i| i.dup.force_encoding("UTF-8") }
output.join
end
private
就在
output.join
的前面硬加一句
output = output.map{ |i| i.dup.force_encoding("UTF-8") }
然后就好用了。
在Windows平台上还有一个问题,在WSL1升级成WSL2之后, Jekyll的自动生成功能不好用了,VSC的Jekyll Run插件也不好用,这时候需要加一句。
--force-polling
加全了就是
--watch --trace --incremental --force-polling
这样Jekyll在WSL、PowerShell中,就又可以自动根据文件变更,重新将Markdown自动生成新的HTML文件里。一个是解决是文件名不支持中文,一个是路径不支持中文,以上的修改都是解决这些问题的。后期为了生产速度和便利性,用Node JS的Hexo做博客系统更方便一些。