Mr Sunshine

Journey of Peace

给中英文间加个空格

如果你跟我一樣,每次看到網頁上的中文字和英文、數字、符號擠在一塊,就會坐立難安,忍不住想在它們之間加個空格⋯⋯

漢學家稱這個空白字元為「盤古之白」,因為它劈開了全形字和半形字之間的混沌。另有研究顯示,打字的時候不喜歡在中文和英文之間加空格的人,感情路都走得很辛苦,有七成的比例會在 34 歲的時候跟自己不愛的人結婚,而其餘三成的人最後只能把遺產留給自己的貓。畢竟愛情跟書寫都需要適時地留白。

关于中英文字符之间是否应该加入空格已经有过很多讨论。在这之前我也没怎么意识到这个问题,在被指出这点之后,回头看看挤在一起的中英文字块,确实有点别扭。不过我还是不大愿意在写博客的时候人为地去加入空格,因为 1)这很麻烦,尤其是写技术类文章时要夹入不少英文;2)加入空格实际上是一个显示效果的问题,而不是原有文本的语义问题(中英文间有天然的隔阂,不需要再用多余的空格来分离),所以应该在显示层面处理,比如 Word 默认就实现这个功能。

所以我想在 octopress 生成 html 页面时自动插入空格。原来有想过直接修改 markdown 编译工具的,这样的好处是能分析语义,很方便地处理 markdown 的各种语法。考察了下,现在 octopress 默认用的是 rdiscount,因为是用 C 语言实现的,速度遥遥领先其他实现,所以要改也得改 rdiscount 靠谱点。扫了下 rdiscount 代码,发现它并没像我想象那样先解析出一棵 markdown 的语法树再生成 html,而是直接边解析边生成,这样改起来会比较乱。于是只能在 octopress 上打主意。

Octopress 的 post_filter 机制

之前 p 哥在自动连接他的断行中文时是直接修改了 jekyll 代码,这样的缺点是以后升级新的版本得重新再改一次。其实 Ruby 可以随时打开一个现有的 class 或 module 的定义并修改,而 jekyll 在执行前会先加载(require)网站/plugins目录下的所有文件,所以我只要把重新定义的代码放在这个目录下就可以了。

看了下 octopress 和 jekyll 相关代码,发现原来 octopress 已经有类似的扩展:它在/plugins/post_filters.rb中实现了一套在处理页面前后加入 filter/hooker 的机制,/plugins/octopress_filters.rb中定义的ContentFilters就是一个样例实现。所以我现在只要加入一个 hooker 函数,在里面实现空格插入的功能。

Liquid

Liquid 是 jekyll 用到的一套模板系统,我们可以自定义 filter 处理模板的内容。原来我也想过用 filter 来实现自动插入空格的功能,但实现出来才发现博客模板里待处理的文字都是转换后的 html 格式,而不是原始的 markdown 格式,处理 html 实在是太恶心了,于是就没继续做下去。不过后来发现分类 rss 模板中是直接引用 markdown 格式的文字,再调用markdownify这个 filter 转换成 html 格式,我也跟着把我的主体功能实现成 filter(再让 hooker 函数去引用),这样就能在markdownify之前调用我自己实现的insert_ch_en_space

insert_ch_en_space

insert_ch_en_space主要考虑了三种情况,1)汉英之间没有特殊字符;2)汉英之间有_或*等强调字符,这和前一类正则表达式可以合到一起;3)汉英之间有链接标签,这需要分标签左边和右边两种情况。具体见代码及注释:

正则表达式写的比较少,不知道有没更高效的写法。

J1退税小记

我是去年(2011 年)拿 J1 签证去的美国,从 7 月到 10 月。因为我是以访问学生的身份在 rice 参与一个科研项目,每个月 rice 都会给我发工资,根据中美的协定[2][3],我这部分收入是不需要在美国交税的。但是实际上学校给你发工资的时候还是会预扣(withhold)约 13%的税额,而且在你拿到 SSN 之前比例更是达到 30%。我就这个问题咨询过学校的薪资部门(payroll),他们一直坚持说根据系统记录我确实是应该被扣除税额的,我可以在明年跟国税局(IRS)申请退税。当时还跟他们在邮件里争了几个来回,最后还跑到办公室去当面对质,才算弄明白他们确实没搞错。

如果你和我一样在退税之前就回国了,那么退税是比较麻烦的。第一,来回寄材料费时间,有在美国的朋友帮忙操作是最好的了;第二,如果你让 IRS 寄支票给你退税,那当中的手续费也很吃亏,最后拿到手可能就不多钱了。好在 BOA 和建行有合作关系,BOA 的 debit 卡可以在建行的 ATM 上提款免收手续费。所以只要在回国前开个 BOA 的账号,到时让 IRS 直接把退税打到这个账号上就可以了。

很快就到了第二年的开春,也就是退税的季节,这时候学校会发 W-2 和 1042S 税表给你。rice 的 W-2 可以选择电子版的方式,1042S 可以自取也可以邮寄。这两张表记录了你被用人单位预扣的收入税。另外你还需要填 1040NR-EZ8843 这两个表,前者计算你的税额,后者记录一些基本信息。1040NR-EZ 看起来很复杂,但它的填表指导非常详细,表里的每一项都会告诉你怎么填。其中J. Income Exempt from Tax这一项要查 Pub. 901,我这种 J1 访问学生是属于 Tax treaty article 19 的情况的。8843 就相对好填多了,它的表后也有详细的填表指导。

填好之后把 W-2, 1042S, 1040NR-EZ 和 8843 这些材料都寄到 IRS 就行了,三周后可以查询退税状态。

主要时间点

2011.11.17 收到 payroll 的信让我选择是否接受电子版 W-2,并更新居住地址
2012.01.31 开始发 W-2
2012.03.13 陈栋帮我到 payroll 拿了 1042S
2012.03.22 陈栋帮我寄出材料
2012.04.14 查询到退税状态
2012.04.18 退税到账

最后要特别鸣谢陈栋同学的鼎力相助:)

参考

[1] Publication 901
[2] Form 1040NR-EZ
[3] Form 1040NR-EZ instruction
[4] Form 8843

攻略

[1] Taxes page from Rice
[2] 杜克中文 F 类签证报税(国税)指南

官方说明

[1] 驻美大使馆关于留学生报税的介绍
[2] 关于《关于〈中华人民共和国政府和美利坚合众国政府关于对所得避免双重征税和防止偷漏税的协定〉第十九条解释的主管当局协议》生效执行的公告
[3] UNITED STATES-THE PEOPLE’S REPUBLIC OF CHINA INCOME TAX CONVENTION

Emacs Desktop Configuration Persistence

之前一直用 Emacs 的 desktop 来保存工作状态,其实主要就是记录打开的 buffer(文件)。desktop 可以保存多个桌面,每个桌面都保存在单独的目录里,但是每次要切换桌面都得填路径这点比较麻烦。my-desktop 在其基础上增加了命名功能,这样保存和读取桌面都只要用名字就可以了。my-desktop 里的路径处理都是用字符串操作来做的,比较丑,我都改了过来,还加了个删除功能,另外还有些小改动。

新的接口如下:
* my-desktop-save 保存当前桌面
* my-desktop-save-as 重命名当前桌面
* my-desktop-save-and-read 加载指定桌面
* my-desktop-new 新建桌面
* my-desktop-destroy 删除桌面
* my-desktop-name 查看当前桌面名

代码:

desktop 虽然能记录打开的 buffer,但是它并不能保存窗口的配置信息。比如我写代码时习惯先垂直划分大窗口,再水平划分右半窗口,而在退出 Emacs 之后 desktop 并没有保存这个配置。

其实 Emacs 的桌面配置可以保存在 Emacs Register 里,不过就是一直没找到很好用的包。后来发现 workgroups 这个扩展能保存窗口状态,封装得也还不错,而且还是有人在维护的。但它的 master 分支没有记录打开的 buffer 的功能,可以配合 desktop 使用,这样做有个问题是保存的 buffer 历史和窗口配置之间没有关联,需要手动分别切换。而 workgroups 的 experimental 分支就支持 buffer 历史和窗口配置的关联,但是kill-buffer似乎有点 bug,关闭最后一个 buffer 之后会出现其他窗口的 buffer,有空再研究下。这些 Emacs 桌面的问题在 workgroups 的文档里都提到了,看来大家遇到的情况都差不多。

重读《量化》多处理器章节

一直对多处理器结构一些基本概念和机制认知有些模糊,这阵子终于抽空看了《量化》的相关章节,清晰许多。画了张脑图,总结了多处理器和缓存一致性的基本问题。

书里提到一个常见的认识误区,也是我平时容易忽视的:

在HP TouchPad上安装Android 4.0

暑假赶上 HP 挥泪甩卖,拼到 TouchPad 一只。TouchPad 的原生系统是 webOS,虽然上面的应用及其稀少,但也有其独到之处:醒目而又不烦人的通知系统,富有操作感的卡片式任务管理,以及对 Flash 的完美支持。而且在后来的一次版本升级里还加入了一个彩蛋,当你以某一个特定方位查看任务卡片时,往下拉卡片会有弹弓被拉紧的声效,松指让卡片飞出的时候就能听到后面有只愤怒的小鸟也欢乐地“hui”出来。

无奈应用确实少得可怜,前天终于抽空把它刷成 webOS 和 Android 双系统。目前移植得比较成功的是 CyanogenMod(CM)这个发行版,最新版本是 CM9,基于 Android 4.0。网上的教程大多很啰嗦,中文的也都还是 CM7(Android 2.3)版本,所以简单记录下。我是在 Mac OS X 10.7.3 下刷机的,Windows 和 Linux 的步骤也都类似。

博客跟风改用octopress

前几天把博客从 WordPress 搬到 Octopress。为什么要用 Octopress 以及如何迁移小 zp 哥的博客基本都讲得差不多了,这里只做点补充。

整个迁移过程很简单:

MacBook Air进水遭遇+攻略

前阵子不小心把一整杯水泼到 air 的键盘上,刚倒下瞬间还没事,结果一慌张又把杯口推到电源附近,当场就自动关机。当时手忙脚乱的,把机器擦干之后就迫不及待的按了电源键,还是没任何反应。后来才知道这是一个很致命的错误,这样子是很容易烧坏主板的。正确的做法应该是:

  • 立刻关机,断开外接电源,能拔电池的赶紧拔电池(air 悲剧)。切断电源后至少能保证不会有短路带来的后续伤害。
  • 能拆机器的拆开来,用吹风筒猛吹。有些人说不要用吹风筒吹,可能是考虑到温度过高;其实高级点的吹风筒可以让它吹冷风的,但我觉得应该没啥关系,因为本本工作温度比吹风筒吹出来的风温高多了。这里 air 再次悲剧了,苹果用的螺丝是专门定制的,得用苹果专用的梅花螺丝刀才能拧开。作为一个自行拆过机的苹果用户,这里我要吐个槽:苹果既然要自己设计螺丝,为什么不干脆做成六角这样不容易滑丝的呢?苹果的梅花螺丝有五个点,每个点都是圆的,这样很难受力,很容易就滑丝。我当时自己拆开装上后,想再拆一次,就发现有一颗螺丝已经滑了,怎么也拧不出来。
  • 如果拆不了机,或者觉得有些地方吹不到,那可以把整只本本插到米堆里搁上几天,觉得不给力可以在米袋里再放点茶叶或干燥剂。

人类为什么需要宽容?

这里的宽容不是讲个人的宽容。个人不宽容只能以大多数人不介意为极限,而官方不宽容则可以权力浩大。宽容如同自由,只是乞求是得不到的,只有永远保持警惕才能保住它。《宽容》讲述的就是千百年来欧洲文明如何在宽容事业上的一点一滴前进的故事。直到现在,“不宽容”仍在向我们进军,我们不能再坐以待毙。虽然历史并不能告诉我们如何建立一个宽容的社会,但至少我们多少可以学到如何避免这些悲剧的发生。

故事从原始时代讲起。原始人把一切事情都归为生灵操纵,为让社会维持下去,就要靠专横的制度,使所有人绝对服从能平息上帝怒火的律法。那时没有军队和警察,靠的是忌讳来保护这些条例。这对他们来说也是理所当然的事。那时候还没有什么宽容的概念。

Hadoop的下一代MapReduce框架

最近雅虎开发者博客发了一篇介绍Hadoop 重构计划的文章。他们发现当集群的规模达到 4000 台机器的时候,Hadoop 遭遇到伸缩性的瓶颈。目前 Hadoop 各个模块的紧耦合使得在现有设计的基础上的继续改进举步维艰。这一点早已在社区内达成共识,目前他们正准备开始对 Hadoop 进行重构。

新架构的主要思想是把原来 JobTracker 的功能一分为二:ResourceManager 管理资源的分配,ApplicationMaster 管理任务监控和调度。ResourceManager 与原有的 JobTracker 类似,作为整个集群的控制中心;而 ApplicationMaster 则是每个 application 都有一个单独的实例,application 是用户提交的一组任务,它可以由一个或多个 job 组成。每台 slave 运行一个 NodeManager 实例,功能类似于原来的 TaskTracker。

Linux全系统复制

千盼万盼,终于盼来实验室的 7 台 R715 集群,捣腾了两天好不容易才把机器和交换机都安上机架。机器有点多,我们不想每台机器都重新配置一遍环境,所以准备先配好一台机器再复制到其他机器的硬盘上。

方案 1 – 全盘复制

直接复制整个硬盘,这样包括 boot loader 和分区表在内的硬盘所有信息都能完整的复制过去。不过目标盘的容量不能比复制源低,否则文件系统就悲剧了。这种方法需要拷贝整个硬盘,即使你什么文件也没写,所以速度非常慢。