Shell script for Google TTS on Plasma desktop

My wife has extreme dry eye condition, so she want to avoid looking at the screen as much as possible. She asked me for a solution for Text-to-Speech on linux desktop.

Basically her requirement is to press a key and read out what she selects. I check jovie, but that’s somehow discontinued and the only speech-dispatcher backend available on my distro is espeak, whose voice quality is poor comparing to any modern solution on the desktop.

So I decided to check if there’s any available solution on internet and see if there’s a solution that using Google translate’s TTS service.

So far I found a script from

Which I adjusted a little for my usecase:



say() { local IFS=+;/usr/bin/mplayer -really-quiet -noconsolecontrols "$*&tl=en"; }
say $TEXT

I added xsel for reading string from primary selection, which is exactly what she’s asking for. And then I use plasma’s convenient custom global shortcut to bind a key to this script. Then you can enjoy the google tts with a single key press.

Posted in KDE | Tagged | 1 Comment

A new pinyin input method that might be slightly better than sunpinyin

What do I mean when I say “slightly better”?

First of all, thanks to sunpinyin’s open-gram, I can use its data for free. So, on the pinyin side, libime IS using the exact same data from sunpinyin. So what’s the difference?

  1. By default, it learns user input faster (you can do that by tuning sunpinyin option, though).
  2. As a library, it supports multiple dictionary.
  3. It gives you more “candidate phrase” by default.
    I guess I need to explain this a little. So in sunpinyin, many common multiple character words are not represented as a single phrase, but as an ngram. By default, it seems that sunpinyin does not provide enough phrase in such form, while libime will try to provides more ngram phrases as candidates.
  4. It has less bug when you try to modify pinyin in the middle of your input.
  5. Its data file is smaller in size. Thanks to the highly compressed format provided by kenlm.
    $ ls /usr/share/sunpinyin/lm_sc.t3g -lh
    -rw-r–r– 1 root root 38M 3月  23 19:51 /usr/share/sunpinyin/lm_sc.t3g
    $ ls ~/Develop/build/fcitx5/share/libime/sc.lm -lh
    -rw-r–r– 1 saber saber 17M 5月  19 17:59 /home/saber/Develop/build/fcitx5/share/libime/sc.lm
  6. It does not have problem about upgrade dictionary because history stores word directly instead of word id, which may be a problem across different version of data.

I’m using this new pinyin powered by lining daily right now. It just simply “feels” slightly better.

For those who interested:

Also, FAQ:

– Will I have this with fcitx4 in the future?

No, this is designed to replace the default pinyin and table in fcitx 4 and will only be used for fcitx 5. If you want you can still work on your own solution for fcitx 4.

– How can I use it now?

Build fcitx5 and fcitx5-chinese-addons, you’ll need fcitx5-gtk and fcitx5-qt too, however, I never tried to clean up the optional dependency for it because it’s not the main task right now. So you probably need to have/build everything in dependency. Especially, xcb-imdkit needs to be built. Also please aware that UI of fcitx 5 is still in an extremely poor state. Also you’ll needi to write a config file manually and place it under ~/.config/fcitx5/profile .

# CurrentGroup


# Default Input Method
# Layout
Default Layout=us
# Group Name

# Layout
# Name

# Layout
# Name


Posted in fcitx development | Tagged , | Leave a comment

用 CMake target 来管理依赖库

虽然有越来越多的包提供 CMake config 了,时常还是需要手写一个。但是如果你还活在 cmake 2.8 的时代, 你可能浪费了很多的精力在不必要的地方。

简单来说,如果你还在写 include_directories,link_directories 来给你的依赖添加找头文件和库的目录,那么你大概已经 OUT 了。

比较现代的一种方式是,用 Target 来管理依赖的库的一切。最早我是从 Qt5 的 cmake 那里学到的。简单来说,就是通过 add_library([Library] [TYPE] IMPORTED]) 来把你依赖的库变成一个 cmake target。同时这个 target 就自带了 include_directories 的属性和 library 自身路径。

那么可以来看看一个我写的新 libintl 的例子:


 add_library(LibIntl::LibIntl UNKNOWN IMPORTED)
 set_target_properties(LibIntl::LibIntl PROPERTIES
 add_library(LibIntl::LibIntl INTERFACE IMPORTED )
 set_target_properties(LibIntl::LibIntl PROPERTIES

也就是说,如果你在你的项目上 target_link_libraries([YourTarget] LibIntl::LibIntl),它就会自动在编译和链接时找到库和头文件,再也不用写 include_directories(…) 了。


 add_library(LibIntl::LibIntl INTERFACE IMPORTED )

通过这个来表示这个 library 是纯头文件的库。对于很多模板库,或者 libc 内置的情况来说是很有用的。

对于多 pc 文件的库,例如 cairo 来说,把它用 package + component 的方式来表示有时会很方便。这里可以请出 KDE 写的 extra-cmake-modules。里面自带的 FindXCB.cmake 可以作参考。

这里有一个我写的 Cairo 的实例:

find_package(Cairo COMPONENTS Cairo XCB EGL)

使用时可以这样,是不是看起来就很高端大气上档次。实际 link 时就只要 target_link_libraries([Target] Cairo::XCB) 就可以了。

实际上,这样引入的 Tagert 也并不只有这一些属性,甚至可以直接指定依赖时需要使用的 C++ 标准之类。

另一方面,如果你想要在编译时支持 third_party 可以使用系统库,或者使用 bundle 的 source,这个方式就可以在不改变你自己 target 的 CMakeLists.txt 的前提下,更加方便的自动变换。

希望有更多的库使用这种方式直接提供 Find[Package].cmake 呢。

另外实际上,如果你采用 cmake 自动 export 的方式,也可以直接获得这样的效果。暂且挖一个坑,下一次再来说一下 install(EXPORT …) 的故事。

Posted in cmake | Tagged | Leave a comment


不要奇怪为什么在这个分类下面。这是一个 fcitx 躺枪的故事。

Continue reading

Posted in fcitx development | Leave a comment


其实就是这个 Thinkpad X1 yoga 了。在这之前,其实也经历了不少笔记本……

最早最早的联想天逸……忘了型号。Gateway I43…Asus Zenbook UX31E,Dell XPS 13 老版本,Ideapad yoga 2 pro,Surface Pro 4……回想起来会觉得太败家了……幸好 Surface Pro 4 是卖了个  6 折回血。


Asus 的问题是妈逼电源线插头太脆弱了,老断啊,断了买了新电源再断,感觉哪天就要被电死了。

Dell 没买一个月换了主板……虽然之后就一直用了,后来给老婆用去了用到现在,但是 wifi 似乎也是有毛病的,而且分辨率是比较惨的 1366×768,之前的 asus 是 1600×900 都能看出明显差距了。

所以后来为了分辨率和屏幕弄了 yoga 2 pro,基本是不错,不过蓝牙和 wifi 同时使用网速网络质量都会大幅下降,家里路由器距离远一些就会经常突发慢到暴走。

后来一时鬼迷心窍看了 M$ 发布会之后想要 SP4。Surface Pro 4 主要是驱动问题,严重的问题……M$ 去掉了待机,然而 Linux 不支持 connected standby,但是换用休眠经常唤醒不能。另外就是 wifi 经常时不常死掉, 最开始我汇报到今天都一年多了……一个小时就要重启电脑也是受不了的。

然后,终于让我遇见了 Linux 驱动都没问题的……这台 Thinkpad X1 yoga。wifi 没问题,wwan 没问题,触摸屏没问题,笔也没问题,待机没问题 ´_>` 这么多年就没遇见这么一个没问题的电脑了。感觉之前都活着什么样的地狱里面……

Posted in Linux | Tagged , , , | 6 Comments