Varamyr – 让Nook 2也可以轻松阅读中文的epub

2

好啦,这个标题有点标题党的嫌疑,前几天入手了Nook 2,但是苦于Nook对中文支持并不好,看中文的epub直接显示方块或者问号之类的乱码。

网上看了下这个问题的大致解决方法有两个:一个是Root掉Nook;另一个往epub文件中塞入一段CSS,再在Nook中看的时候只需要选择Publisher Defaults就可以正常显示中文。

第一个方法风险太高,可能导致Nook变砖;

第二个方法的话可以用Calibre之类的工具来完成,但是Calibre这个东西本身太重了,每次打开关闭很耗时间,UI又丑,实在不想用。

所以,我需要一个命令行的工具来完成往epub中塞入一段CSS这个任务,这样可以和*nix下的其他工具结合起来使用,检测一个文件夹中如果新加入了epub文件,就直接进行转换,让整个过程完全自动化。现在这个命令行工具就是Varamyr(Varamyr是马丁大爷的冰与火之歌的第五部《魔龙的狂舞》序言里面的一个狼灵,打酱油的角色。)

运行Varamyr你需要

  1. JRE环境
  2. *nix系统,不支持windows也不会支持windows
  3. 下载varamyr.jar

如何使用?

  1. 运行命令:java -jar varamyr.jar <path-to-epub-file><path-to-epub-file>为你需要修改的epub文件的路径
  2. 看看在你修改的epub文件的路径下是不是多了一个类似xxxx-varamyr.epub的文件。

源代码 & 原理

Nook 2 入手记

5

经过了2个多月的挣扎,我终于了入手了一款电子书:Barnes & Noble 出品的 Nook Simple Touch(即Nook 2),之所以选择Nook 2,是因为Kindle 3已经停产,现在价格比较高,Kindle 4和Kindle Touch的外观我实在是不喜欢,一股山寨味,于是在淘宝上找了一个店下单了Nook 2,前天晚上下单,昨天从深圳发货,今天早上就到手上了,快递非常迅速。

image

拿到手以后首先是外包装,白色,很小,右上角有一个THE ALL NEW NOOK的字样,表示是全新的Nook,而不是官翻的机子。

image

打开包装以后里面是就一只Nook和一个USB的连接线,没有其他配件了。首次使用需要充足够的电才能够开机。

image

充电中,虽然屏幕上写着要等15分钟,但是实际上要差不多1个小时。等冲到了足够的电Nook会自己启动,然后就是一堆设置,连接上Wifi去激活Nook。

image

看看背面,Nook的开关键在背后,背面的中间是凹进去的,握起来比较舒服。

现在来看看Nook看书的效果到底如何吧:

image

这个是看英文的epub格式的电子书的照片,可以看到英文字体效果还是非常不错的。

image

这张是看中文的epub格式的电子书,非常坑爹,直接显示方块了,Nook原生并不支持中文,需要用Root的方式去解决。

image

然后是英文的pdf,可以看到Nook已经对pdf的文字进行了重新排列,以适合Nook的显示大小。

image

最后是中文的pdf,看起来效果也还可以。

另外再讲讲操作体验,Nook是红外线触摸屏的,触摸屏的体验非常不错,翻页非常灵敏,触摸屏用来查单词也是非常方便,只要点住单词即可,除了触摸屏以外,Nook在左右两边还提供了4个翻页键,但是遗憾的是按起来需要用点力,感觉不是很好。

屏幕的显示方面,效果还马马虎虎,因为Nook 2采用的是局部刷新,翻了6页以后才全刷,所以翻页后可以看到一些残影,这个非常让人不爽,不知道有没有什么办法可以解决这个问题。

至于和Kindle比较哪个好,哪个差,我也说不上来,总体来说,Nook 2还算是令人满意吧,如果你也要买一个电子书,不妨页考虑下Nook。

2

本来今天早上打算去杭图,但昨天睡得很晚,醒来已经到了中午12点,放了别人的鸽子,心里过意不去,又觉得浪费了早上美好的时间,更觉惭愧,于是想要在下午弥补,打算把《Pro Git》看完,给自己点安慰。大约还有四、五章的样子没看,看了下时间,离下午五点还剩四个小时,得抓紧。被这样一种心思给驱动着,结果却完全无法专注进去看,越想快点看完结果越囫囵吞枣地在看,越囫囵吞枣地在看就越急躁,看了十几分钟以后就看不下去了。想想就算看完,那也只是看完了而已,什么收获都不会有,那么干脆停下来吧。

然后我又拿起了《禅与摩托车维修艺术》(即:《万里任禅游》),奇怪的是看这本书的时候心情总是很平静,也许是从来没有打算在什么时候看完它。刚翻到第二部分,突然又想起了这本书中的一句话:

仓促本身就是20世纪最要不得的态度,当你做某件事的时候,一旦想要求快,就表示你再也不关心它,而想去做别的事。

的确,现在信息的获取速度越来越快,结果却把使人们变得越来越不耐烦,越来越没有耐心去做一件事情,也越来越没有耐心去等待一件事情的结果。

信息时代不仅仅加速了信息获取的方式,也加速地消耗着人们的耐心。所以在这个快速的世界里,我想最重要心态是慢。慢不是囫囵吞枣地去做一件事情,也不是对这件是事情无所谓,三天打鱼,两天晒网,慢是从容,从容地把一件事情做好,做完美,虽然这个世界上没有完美的事情,但是当把一件事情做到接近完美的事情,意想不到的事情就会发生。

说到这里,便想起了那部昨天导致我晚睡的电影《时间规划局》,里面的“时间穷人”因为剩余时间总是不多,所以总是行色匆匆。而”时间富人”因为时间总是很充足,所以步调总是比较慢,也比较从容。想想我们的时代,我们的时间并没有科技的发展而流逝地更快,或者流逝的更慢。相对于以前,因为科技的成就,我们做一件事情的时间也更加充裕,我们应该更加从容地去做事情,而不应该更加急迫。

所以,切记切记,慢慢来,不必着急,不知不觉你可以走得比别人更远。

New Year, New Slash-to-Search

0

大家新年好,赶在2012来临之前,对之前写的一个Chrome小插件Slash-to-Search做了一些小的改进,新年新气象,如果你还在用这个插件,那么来看看吧:

image

What’s New?

  • 选项页面有了新UI,如上图。
  • 规则的添加和显示集成到了一起。
  • 去除了规则到处功能,让插件更小巧。

下载:Slash-to-Search

《精通正则表达式》阅读笔记

2

花了近三周的晚上的时间把《精通正则表达式》这本书看完了,说是看完,其实是只看3,4,5,6四章,前面的和后面的几章按照作者的建议觉得自己没有必要去看了。毕竟对于这本书来说,这四章才是重点,在这四章中,作者就已经把正则表达式的语法,正则表达式引擎的工作原理,以及正则表达式的调优讲完。下面是我在看这四章的过程中的一些笔记和总结。

正则表达式的语法

对于正则表达式的语法,相信大多数人都和我一样知道一些基本的语法,但是对于一些不常见的语法还是非常陌生,这边就把这些比较陌生的正则表达式语法记录一下:

  • 分组且捕获的文本括号:(),文本被捕获以后可以通过反向引用(\1\2等等)来引用。
  • 分组但是不捕获的文本括号:(?:),文本被捕获后不能通过反向引用来引用到。
  • 忽略优先量词:*?+???{min,max}?:量词在正常情况下是“匹配优先”的,会尽量匹配更多的内容(Greedy),忽略优先量词则优先匹配尽量少的内容。
  • 占有优先量词:?+*+++{m,n}+,与匹配优先量词很相似,只是从来不交还已经匹配的字符,即如果已经匹配到了,就放弃该量词表达式内的所有的回溯可能都抛弃。
  • 固化分组:(?>…),使用固化分组的匹配与正常的匹配无差别,但是如果匹配进行到此结构之后,那么此结构体中所有的备用状态都会被放弃。占有优先量词可以看做是固化分组的特殊情况。
  • 条件判断:(?if then|else):测试if条件表达式,如果测试为真,则执行then部分表达式,如果测试失败,则执行else部分表达式,if条件表达式是特殊的表达式,大概有两种情况,一种是对捕获型括号的特殊引用,比如(?(1))这样,会测试第一组捕获型括号是否参与了匹配;另一种是对环视进行匹配,如果环视能够匹配,则返回true。
  • 环视,即零宽断言:(?=…) (?!…) (?<=…) (?<!…),具体的解释可以参考我之前关于零宽断言的一篇文章:使用零宽断言来匹配不包含连续字符串的行
  • 匹配上一次匹配结束的位置:\G,首先出现在Perl中,在用于迭代匹配的时候比较有用。

正则表达式引擎的工作原理

一般上正则表达式的引擎可以分为两种:NFA和DFA,分别表示非确定性有穷自动机和确定性有穷自动机,这两者背后的理论基础大可不必去了解,只需要知道NFA引擎是在进行匹配的时候是表达式主导的,而DFA引擎在进行匹配的时候是文本主导的,下面具体来拿一个例子来将述下这两者的区别:

NFA引擎工作原理

对于NFA引擎,它会先拿出正则表达式的第一部分,然后看看文本有没有符合这个部分的,如果是,则继续表达式的下一部分进行匹配。

现在假设我们有一个正则表达式是a+b,需要用它去匹配aaaaab这个字符串,它的匹配过程大概如下:

  1. 首先找到正则表达式的第一个部分a+
  2. 然后看文本是否匹配到了这个表达式,在文本中,前面的5个a是能够匹配a+的,那么继续正则表达式的下面部分
  3. 后面是一个b,它能够匹配到文本中5个a后面的b,也匹配成功。
  4. 这样正则表达式的所有部分都能够匹配,所以整个表达式就能够匹配成功。

NFA引擎还有一个重要的特性,这个特性对于理解NFA引擎的原理也是非常关键:回溯。具体来就讲,在遇到两个可能成功的分支时,会先尝试一个可能性,然后记住另一个,如果这个可能性失败了,那么就回溯到之前的可能,回溯的一个重要的原则是,如果需要在“进行尝试”和“跳过尝试”之间选择,对于匹配优先量词,引擎会优先选择“进行尝试”,对于忽略优先量词,引擎会优先选择“跳过尝试”;在进行回溯时,选择回溯的路径是距离最近存储的路径,即基于LIFO原则。

DFA引擎工作原理

对于DFA引擎,DFA引擎会在扫描子字符串时,记录当前有效的所有可能匹配。这个我们就拿书中的tonight的例子来讲。

现在我们拿to(nite|knight|night)来匹配tonight,它的匹配过程大致如下:

  1. 引擎看拿到文本中的t,然后找到了表达式中的t可以与之匹配,这样,表达式就可能能够匹配到文本,这样引擎就会添加这样一种潜在的可能。
  2. 然后引擎继续按照文本往下移动到了n,这个时候,表达式的多选分支里面只有两个分支可以与之匹配,knight这个分支不能匹配,有效的可能就变成了两个。
  3. 继续往下走到文本中的g,这个nite这个分支也不能匹配了,有效的可能变成了一个。
  4. 最后当匹配到之后的t时,night这个分支显然能够匹配,这样引擎发现匹配已经成功。

NFA引擎和DFA引擎的各自优缺点:

  • 从上面的讲解中可以了解到,NFA引擎因为是正则表达式主导的,可能对文本中的同一个部分进行反复的扫描,DFA则只会对文本进行一次扫描,这样NFA引擎的速度就相对DFA要慢。
  • 另外NFA是正则表达式主导的,所以不同的正则表达式对速度的影响比较大,但是DFA因为是文本主导,所以不同的正则表达式对其速度影响不大。
  • 从上面一条我们也可以知道,NFA的可玩性就比较大了,相对来说比DFA要灵活很多。其实后面的调优也都是针对NFA引擎的,因为DFA实在是没有什么好调优。

正则表达式调优

正则表达式的调优是在了解了正则表达式的工作原理的基础上进行的,主要是针对NFA引擎,看完正则表达式的调优这一章以后,我自己总结了一条调优的规律:在正则表达式中尽量使用确定的字符

比较(night|nite|nittt|niasdf)ni(ght|te|ttt|asdf)这两个正则表达式,因为后面一个正则表达式把各个多选分支中的ni提出来了,这样引擎就能够通过字符扫描的方式快速找到匹配文本中的ni部分,然后再开始匹配后面的多选分支;而前面的那个表达式,引擎在文本的每一个位置都要尝试四个分支,显然速度要慢很多。相比而言,后一个正则表达式比前一个要“确定”,匹配的速度就更快。

针对这一条规律,还可以有很多调优的方式,比如能够加锚点就加锚点之类的,具体的大家可以翻看书的第六章。

总结

应该说这本书觉得是一本值得阅读的书,花时间去看绝对是值得的,特别是当你会一点正则表达式后再去看,收获可能更大。不过这书的翻译看起来有点吃力,读起来不是很顺畅,或许是因为正则表达式本身看起来就有点累,所以看这本书的过程中最好保持头脑清醒,保持注意力集中,这样才能跟上作者的思路。

Go to Top