Update on 2012-04-24 : 看到肖之的 给中英文间加个空格
提到了 Jekyll 的 plugin 机制,因此改成用 plugin 机制避免更新 Jekyll 时需要重新
patch 的麻烦。
在 Vim 里编辑文件时我设置行宽不超过 80 个字符,因此编辑 Markdown 文件时一段话中会有多个换行。我用 Octopress 默认配置的 rdiscount 来生成 HTML 文件,这些换行都会保留在最后生成的 HTML 文件中。
浏览器对换行的处理是转成空格,这对英文来说很自然,但对中文就很讨厌了。我在 Stack
Overflow 上提了这个问题,从这个详细的回答来看 ,这是一个历史遗留问题,短期内不会解决。
所以还是自己动手吧。我的解决方法是在生成 HTML 前把所有连续的中文行转成一行。(修改
Markdown 的实现也可以,但 rdiscount 用了 C 写的 Markdown 实现 discount,hack 起来比较麻烦。) 在 Ruby 1.9 中,连接中文行可以很方便的用正则表达式实现,注意开头的
#encoding: UTF-8
是必须的。
1
2
3
4
5
6
7
8
9
#encoding: UTF-8
class String
han = '\p{Han}|[,。?;:‘’“”、!……()]'
ChineseRegex = /( #{ han } ) *\n *( #{ han } )/m
def join_chinese
gsub ( ChineseRegex , '\1\2' )
end
end
利用 Jekyll 的插件机制可以在它调用 markdown 转换工具前修改需要转换的文本。把下面的代码放在一个文件中,放在 plugins
目录下即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#encoding: UTF-8
require './plugins/post_filters'
class String
han = '\p{Han}|[,。?;:‘’“”、!……()]'
@@chinese_regex = /( #{ han } ) *\n *( #{ han } )/m
def join_chinese!
gsub! ( @@chinese_regex , '\1\2' )
end
end
# Use Jekylly's plugin system to modify the content before invoking rdicount
module Jekyll
class JoinChineseFilter < PostFilter
def pre_render ( post )
post . content . join_chinese!
end
end
end
需要注意的是分类文章的 rss 需要特殊处理一下,我自己的博客分类做得不好,所以分类
rss 应该没什么价值,所以就懒得处理了。需要处理的可以参考肖之的文章。
下面是原来直接修改 Jekyll 的方法,不再推荐。
可以用来转换文件的代码在 gist 上 ,但我不希望把 Markdown 源文件变成有着巨长行的文本,所以我修改了 Jekyll,在调用 rdiscount 前对内容调用 join_chinese
方法。需要修改 lib/jekyll/converters/markdown.rb
,patch 如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
--- bak-markdown.rb 2011-12-23 20:14:24.000000000 +0800
+++ markdown.rb 2011-12-23 20:13:19.000000000 +0800
@@ -1,3 +1,15 @@
+#encoding: UTF-8
+
+class String
+ def join_chinese
+ unless @chinese_regex
+ han = '\p{Han}|[,。?;:‘’“”、!……()]'
+ @chinese_regex = Regexp.new("(#{han})\n(#{han})", Regexp::MULTILINE)
+ end
+ gsub(@chinese_regex, '\1\2')
+ end
+end
+
module Jekyll
class MarkdownConverter < Converter
@@ -115,7 +127,7 @@
}).to_html
end
when 'rdiscount'
- RDiscount.new(content, *@rdiscount_extensions).to_html
+ RDiscount.new(content.join_chinese, *@rdiscount_extensions).to_html
when 'maruku'
Maruku.new(content).to_html
end
用 Markdown 来写这种类型的 blog 真是舒服多了。