这个周末放了3天假,第一天当然是要看盛大的阅兵仪式了,剩下的时间一半多是在折腾博客系统Hugo,剩下的时间在折腾各种工具、IDE,还有学习了一下Unity。
上次给Hugo提了个Pull Request,提供了路径是否转换为小写的配置功能,最后被接受了,走过了一次完整的Pull Request流程,学到不少东西。周末继续折腾Hugo,又发现一个问题,文章的字数统计和70个字的摘要在我的博客里明显是不准确的,而且错的离谱。
于是看了下Hugo的代码实现,发现字数统计只是简单的根据空格统计单词的总数。而我们中文的语言,哪来那么多空格,文字都是一个挨着一个,按照英文的字数统计方法,一个几千字的文章最后被统计出来只有一百字也是经常的事情。
还有摘要的功能,如果没有主动使用``作为摘要的分隔符,Hugo会自动截取文章的前70个单词,并且保证截取的文字最后是一个完整的句子。数多少个单词的方法和字数统计是一样的,截取完整句子是往后找,直到找到下一个句号问号之类的。在中文博客里,这样的摘要截取方法常常导致把整篇文章当做了摘要。这也是不可接受的。
于是,我尝试去修改字数统计和摘要截取算法,让它能适应中文、日文或者其他类似语言。首先是字数统计,比如“Hello 中国”应该被识别为3个词:Hello、中、国。怎么做呢?Golang里unicode/utf8的Package,提供了方法计算有多少个Rune,而Rune并不是Word,只是字符,比如“Hello 中国”调用RuneCountInString的结果会是8。
于是,我借助utf8库里的一些方法,近似的实现了中英文文字的字数统计和摘要截取算法。说近似,因为实现方法不是很严谨,我不懂其他国家的语言,不知道其他国家语言在这样的算法下是否能保证正确。但我还是抱着试一试的态度,将我的修改给Hugo又提了一个Pull Request。
在和Hugo主要维护者之一bep多次沟通之后,他提出,我的实现的确不是很严谨,不能保证所有语言都适用。而且,关于字数统计,他之前已经实现过一个类似的方法:RuneCount。于是我又回去把漏看的代码又看了一遍,果然已经有一个RuneCount的方法,用来统计有多个Rune。对,是Rune,不是Word,所以“Hello 中国”RuneCount的结果是7(空格会被忽略)。而我要的结果是3啊。
后来我仔细一想,我真的这么在意有多少个英文单词和汉字吗?我在意的只是不要简单的根据空格分隔来统计字数,在意的只是说好的70个字的摘要,结果把整篇给做成了摘要。所以,使用RuneCount也OK啊,于是我就把之前的字数统计代码的改动还原了。bep提供了按Rune统计字数,但是没有提供按Rune截取摘要,于是我把之前稍微有些复杂的改动还原,提供了一个简短的按字符截取摘要的方法,并且补充了相应的测试案例。
func TruncateStringByRune(str string, max int) (string, bool) { str = strings.Join(strings.Fields(str), " ") count := 0 for index, rune := range str { if count >= max { return str[:index], true } if !IsWhitespace(rune) { count++ } } return str, false }
做完这次修改后,继续Pull Request啊,可是现在的Pull Request状态显示我有两次commit,而且前一次已经Push了。于是又学了一招如何将新的commit和之前已经Push的commit合并成一个commit。首先我的修改是在单独分支commit和push的,当前的master是并没有这两次commit,这时就可以通过
$ git rebase -i master
然后编辑里面的commits,将需要被合并的pick改成squash,保存退出后再重新编辑commit message,然后就变成了一个commit,这时再来个强制push:
$ git push origin coderzh-hugo -f
于是一开始了和挪威程序员bep的多次交涉,他又提出他开始后悔当初提供了RuneCount方法,他认为Hugo提供的方法应该越少越好,干同样一件事情不应该有多个不同的实现版本。而且他不但不认为我又加了一个RuneSummary方法是对的,他还打算把原来的RuneCount方法也删除,并且他十分确信能提供一个统一的版本,既能处理西方文字也能正确的处理中文、日文等其他语言文字。
我虽然有些沮丧,但还是同意他的,于是我给他回复了我的想法(当然,原回复是英文的)
“我完全同意你的观点。但是我加了个RuneSummary方法也是有我的考虑的:
但是,我还是完全同意你的观点并且期待你的更好的统一的实现方式。”
最后bep有点被我说动了,回了一句:Let me think a little about this.
至少,我的修改版本是适用于我的,所以我自己用着就好啦,至于Hugo官方如何来提供,还是等等吧。
我之前用Unity开发游戏时的版本记得还是4.6,现在已经出了5.1.3版本了。社区免费版本已经几乎提供了所有功能,学习把玩已经足够了。Unity自带的MonoDevelop是很难用的,还是Visual Studio好用,毕竟是世界上最好的IDE(笑~)。在VS里装个UnityVS简直可以走遍天下了。我之前一直用的是Visual Studio 2013,打开UnityVS的下载地址一看,默认只提供了Visual Studio 2015的UnityVS插件。哦?嘿嘿,趁这个机会,我也升个Visual Studio 2015试试。VS2015同样是Community版本提供了所有我需要的功能,所以完全不需要其他版本和破解序列号了。
装完VS2015,装好UnityVS插件,还需要安装另外两个神器啊,没有这两个神器,代码还怎么写?!一个是Visual Assist,一个是Viemu。作为一个Vimer,即使在IDE里也是要开启Vim模式的,毕竟,Vim才是世界上最好的编辑器啊(逃~)。
该装的都装好了,是不是可以愉快的写代码了?字体!对了,听说有一种专门为程序员设置的字体,我一定要试试。于是去下载了 Hack 字体。果然一使用就爱上了这种字体。如果想看效果,在网页里打开这篇博客,上面的代码高亮部分就是Hack字体。
最后,终于可以愉快的玩耍了。
这是另外一个神器,简直要节省我N多N多的编辑排版时间啊。之前我写好的Markdown格式的文章贴到微信公众平台的编辑器里,还要再编辑很久才能达到最终效果。而使用 Markdown Here 这个Chrome插件,只需要在我将Markdown格式的文字拷贝到微信公众平台的编辑器里之后,按CTRL+ALT+M,立即会变成排版精良的有格式文字,而且几乎不需要再加工。其他地方的编辑器里也适用哦,谁用谁知道。
希望我折腾的东西对你有些许帮助,我也心满意足了。