2018.org (64814B)
1 #+HUGO_BASE_DIR: ../ 2 #+HUGO_SECTION: ./posts 3 #+OPTIONS: author:nil 4 5 * TODO Review of the Last Jedi 6 :PROPERTIES: 7 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :date 2018-01-03 :slug my-review-of-the-last-jedi 8 :END: 9 10 ** TODO en 11 :PROPERTIES: 12 :EXPORT_TITLE: My Review of the Last Jedi [Spolier Alert] 13 :EXPORT_FILE_NAME: 2018-01-03-my-review-of-the-last-jedi.en.md 14 :END: 15 16 Sadly, unlike Princess Leia, Carrie Fisher could not come back to life. 17 This is dedicated to Carrie Fisher. 18 19 What I hated: 20 1. Starting out, Poe feels nothing about his fellows dying. "But we blew up a 21 Dreadnaught!?" Also the ridiculous conversation btw Poe and Hux makes it 22 really hard to take any of the bad guys seriously, including snoke and hux, 23 they are 24 2. Leia using force: unexpected, but okay. No harm and no gain. 25 3. Why is Luke so OOO? Why would he doubt his own niece if he sees good in his 26 father. I'm okay with this looking just at 7&8, but considering 4-6? 27 unacceptable. 28 4. Where did other jedis following kylo go? 29 5. The burnt jedi classics were in the falcon at the end, wtf luke and yoda? 30 6. Luke squeezing milk from giant female Wattos? 31 7. General snoke been stroke down without much explanation. He can force choke 32 ppl light years away but can't tell Kylo is fooling him? He could read kylo's 33 mind but couldn't stop Kylo from stabbing him? or I guess that's how rules of 34 two work now. 35 8. Why struggle so badly fighting the guards? No point? cut to the next scene already! 36 9. Yoda summoning lightning!? Welcome to see a more puppet like yoda but talk 37 was too cliche. Yoda's lesson: teach her your failures as well. other parts are bad. 38 10.Maz WTF!? who is this rando master code breaker wearing some stupid flower in a casino 39 11.Henikein beer guy as DJ, did he die? No point!? Why was he able to 40 passthrough the shield!? 41 12.Not too old this time around to start training?(i guess that's not the point) 42 13.Kylo long controlled by Snoke, how did he escape? why was he still so unsure 43 14.Hux was never an appropriate enemy 44 15.Snoke just appears after all these buildup? Nothing special? Force lightning? 45 although I guess dooku is guilty of the same stuff but hey at least he fought well. 46 16.Canto Bight casino was pointless, DJ was pointless. Yes I get they are 47 mimicking the bar scene from new hope, but it's not there. 48 17.Structurally, the time line is fucked up. We have three lines of narrative 49 with two different time lines (Rey's one being stretched much forward) and 50 syncing back together (unless there is some GR bullshit about the rebel fleet's 51 time passing slower) etc. Finally they merge into a not so epic fight and another 52 not so epic fight and then another not so epic fight on Crait (red salt version 53 of hoth). 54 18.why the hell deliberately kill off Holdo, just have some droid pilot the 55 ship. "We've used to lose ppl?" you kept 3po for the longest time for god's sake 56 19.If they are going the route of killing of the concept of jedi, which makes 57 sense if they never called snoke sith, just practitioners of dark side, why the 58 hell reviving the concept in Crait fight scene? Otherwise why mentioning Rey has 59 such potential in the dark side? 60 20.owl-penguin toy commercials 61 21.Rey's parentage doesn't really matter anymore since she is so strong with the 62 force. 63 22. Outer rim allies? any followup on this? or is this just another one off 64 thing? 65 23.Luke: yeah, that's pretty much nowhere. Says the farm boy from 66 Tatooine. "Every word you just said was wrong" 67 24.Wtf is this spark speech. And wtf Leia slaps Poe. The resistance is fucked 68 for sure. 69 25.the red guards doesn't make sense 70 26.no real development in Rey 71 27.Luke's story told three times in different fashions!? 72 28.Kylo stroke luke down and yet can't defeat red ninja guards? 73 29.Luke's reaction about Han was only one line 74 75 What I liked: 76 1. Rey and Kylo(Ben) connecting. Kylo's transition, his wounds by 77 Rey. Confrontation of his feelings. Rey said he is a monster yet begs to luke 78 that there is good in him. Rain transfer via force connection. 79 2. The part where Rey and Kylo fighting for Anakin's lightsaber was pretty good, 80 besides we finally get closeups on lightsabers! 81 3. Luke cloaked himself from using the force? can tell from he not owning his 82 light saber anymore 83 4. little boy telling luke's tales and he seems to be using force to get the 84 broom? slave? young force user? ring a bell? 85 5. Kylo didn't pull the trigger, unlike Han 86 6. Luke saying laser sword. 87 7. What Luke really see in Rey was puzzling: dark side of the force? How is this 88 reconciled? He walked away seeing Rey lost in anger wielding light saber to 89 the rock. 90 8. Luke taught Rey two lessons, where is the third? 91 9. Luke never read the jedi classics 92 10.Rose was a likable character, not counting the transition between losing her 93 sister and engaging new plan following Poe, who effectively killed her sister in 94 a suicide mission. 95 11.Solo's dice chains, although now has strange numbers. the real ones were 96 picked up by kylo ren 97 12.Luke winking at 3po 98 13.Hyperspace strike 99 14.Admiral Akabar 100 101 Notable plots 102 1. Leia and the underground hole. Explanation: curiosity and desire to know her 103 parentage are paths to the dark side? maps directly to Cave of Evil/dark 104 force cave. 105 2. Finn kinda knows it was his fault so he wanted to sacrifice himself for the 106 rebels. But what was he doing in the casino!? 107 3. The scene luke passed away, duel sun setting was exactly the same as a new 108 hope. 109 4. fighting for lightsaber btw Kylo and Rey was great 110 5. Kylo didn't have his own lightsaber. ? didn't he have his lightsaber on the 111 belt? at least it was there when he was waken by Hux 112 6. "Why did you stop me" "I saved you", okay cmon it's star wars 113 7. R2 playing the original Leia clip. 114 8. Maybe hinting so many force usages in the film is to emphasize there will be 115 more jedi? 116 * DONE My Very Own Avatar Icon Thingy 117 :PROPERTIES: 118 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :date 2018-01-15 :slug my-very-own-avatar-icon-thingy 119 :END: 120 121 ** DONE en 122 :PROPERTIES: 123 :EXPORT_TITLE: My Very Own Avatar Icon Thingy 124 :EXPORT_FILE_NAME: 2018-01-15-my-very-own-avatar-icon-thingy.en.md 125 :END: 126 127 I have been using the symbol for the Old Republic from Star Wars as my goto profile picture for quite sometime. In my attempt to maintain a consistent social network profile over multiple websites, I gradually come to realize that profile picture is the most intuitive way to establish a identity (I guess this is also why services like Gravatar would +be so popular+ exist ). In this case, using a picture from [[http://starwars.wikia.com/wiki/Old_Republic][Wookiepedia]] that everyone has access to is probably not the brightest idea. Thus, I set out to create my very own avatar icon thingy. 128 129 Since I don't consider myself to have even the least amount of artistic talent, I started out spending quite some time in GeoGebra trying to reconstruct the Old Republic symbol in a systematic way. Filling up my screen with circles and measurements is fun and surprisingly addicting, yet after several hours, I only ended up with a confusing hodgepodge of curves. 130 131 #+CAPTION: One of my failed GeoGebra attempts. 132 [[/img/posts/2018/my-very-own-avatar-icon-thingy-01.png]] 133 134 It is obvious at that point that I won't be able to recreate anything nearly as complicated as the Old Republic symbol, so I started stripping out a more abstract version of it. 135 136 #+CAPTION: My process of streamlining the logo. 137 [[/img/posts/2018/my-very-own-avatar-icon-thingy-02.png]] 138 139 I isolated out the "rising star" part of the original logo and discarded the wing-shaped portions to center the star. Instead of a rising star, I went for the impression of a shooting star and it turned out extremely well (in my opinion at least). With delight, I settled on the logo design a few minutes later. I kept the dark red color scheme (though I actually used =#700000= instead of the original =#710100= because I hate dangling ones) and added a gray background (=#707070=) as using white seemed too bright for me. 140 141 #+CAPTION: Final design as shown on my Twitter profile. 142 [[/img/posts/2018/my-very-own-avatar-icon-thingy-03.png]] 143 144 I also played around with several alternative color schemes, i.e. inverted versions. Maybe I will use these as icons for other projects. So far, I have updated all my actively used social network profiles and changed the favicon of this blog. Hopefully this icon would be unique enough for others to recognize me across different social networks. 145 146 ** DONE zh 147 :PROPERTIES: 148 :EXPORT_TITLE: 自己画头像 149 :EXPORT_FILE_NAME: 2018-01-15-my-very-own-avatar-icon-thingy.zh.md 150 :END: 151 152 我使用星球大战中旧共和国的标志作为头像已经有不短的时间了。不过最近,当我试图统一我所有的“社交网络人格”时,我意识到独特的头像往往是最为直接的在网上认人的方式(这大概就是为何 Gravatar 这类服务 +如此受欢迎+ 会存在)。这么一想,拿 [[http://starwars.wikia.com/wiki/Old_Republic][Wookiepedia]] 上的图片直接作为头像不是什么明智的行为。于是我决定:自己画头像! 153 154 由于我并不觉得自己有多少艺术细胞,我最初尝试的方法是在 GeoGebra 里用尺规作图复制原来的头像。这种作图方式很是让人上瘾,但遗憾的是:在荒废几个小时后,我得到的只是一堆纠缠不清的曲线。 155 156 #+CAPTION: GeoGebra 中的诸多失败作之一。 157 [[/img/posts/2018/my-very-own-avatar-icon-thingy-01.png]] 158 159 事已至此,我开始意识到我是画不出像旧共和国标志的那样复杂的头像的,所以我采取了另外一种策略:从这些失败作中抽取一个更加简练的图样。 160 161 #+CAPTION: 我逐渐简化头像的过程。 162 [[/img/posts/2018/my-very-own-avatar-icon-thingy-02.png]] 163 164 我把原图里六芒星升起的部分提取出来,并舍去了碍事的翅膀形部分使得星形能够居中。经过少许修改后更接近流星的图样看起来(至少对我来说)非常赞。在短短几分钟后,我就完成了我的头像设计。我保留了旧头像的暗红的配色(实际用的是 =#700000= 而不是原图的 =710100= ,因为我有个位数字强迫症)并加上了灰色的背景( =#707070= ,白色背景有点太刺眼了)。 165 166 #+CAPTION: 我推特资料上的完成版头像。 167 [[/img/posts/2018/my-very-own-avatar-icon-thingy-03.png]] 168 169 我还尝试了其他不同的配色,比如反色版本,以后可能会拿来作为我其他项目的图标。我所有还活跃的社交网站都已经换上了新头像,包括网站图标。这下大家应该可以更容易地在不同网站上认出我了XD。 170 171 * DONE Trying Out Mastodon 172 :PROPERTIES: 173 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :date 2018-02-11 :slug trying-out-mastodon 174 :END: 175 176 ** DONE en 177 :PROPERTIES: 178 :EXPORT_TITLE: Trying Out Mastodon 179 :EXPORT_FILE_NAME: 2018-02-11-trying-out-mastodon.en.md 180 :END: 181 182 As mentioned in my [[https://www.shimmy1996.com/en/posts/2017-10-22-no-more-disqusting-disqus/][previous post]], I am not really accustomed to posting on social networks. However, the other day I encountered a term I haven't heard in a long time: micro-blogging. Yes, quite a few social networks, Twitter for instance, is before anything a micro-blogging service. This definition of Twitter makes it immensely more appealing to me: it's a bite-sized blog for random thoughts, funny incidents, and many other pieces of my life that might not fit well with a regular blog post. However, I still find posting on Twitter has the 'broadcasting to the entire Internet' feeling stamped into it. Guess I'll just host my own then. 183 184 [[https://github.com/tootsuite/mastodon][Mastodon]] turned out to be one such solution. Mastodon's federated and decentralized nature makes it ideal for someone like me who struggles between building my online identity while minimizing the number of different companies I expose my information to. If people are willing to give away their personal information for fancy profile pictures, then hosting a Mastodon wouldn't seem like such a bad deal. 185 186 *** Installation on Arch Linux 187 It was kinda surprising that there doesn't exist a Arch Linux specific installation guide for Mastodon. Not that the installation process would be more difficult on Arch Linux than Ubuntu, but installation can be made a lot due simpler to the abundance of packages. Since the [[https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md][official production guide]] is already fairly comprehensive, I'll just document some Arch Linux specific steps here. 188 189 **** Dependencies 190 Here's a table detailing all the dependencies and their corresponding packages in Arch Linux. There really is no need to git clone anything. =npm= was also required in the installation process, but was not listed in the official guide. 191 192 | Dependency | Package | 193 | =node.js= 6.x | [[https://www.archlinux.org/packages/community/x86_64/nodejs-lts-boron/][=nodejs-lts-boron=]] | 194 | =yarn= | [[https://www.archlinux.org/packages/community/any/yarn/][=yarn=]] | 195 | =imagemagick= | [[https://www.archlinux.org/packages/extra/x86_64/imagemagick/][=imagemagick=]] | 196 | =ffmpeg= | [[https://www.archlinux.org/packages/extra/x86_64/ffmpeg/][=ffmpeg=]] | 197 | =libprotobuf= and =protobuf-compiler= | [[https://www.archlinux.org/packages/?sort=&q=protobuf&maintainer=&flagged=][=protobuf=]] | 198 | =nginx= | [[https://www.archlinux.org/packages/extra/x86_64/nginx/][=nginx=]] | 199 | =redis= | [[https://www.archlinux.org/packages/community/x86_64/redis/][=redis=]] | 200 | =postgresql= | [[https://www.archlinux.org/packages/extra/x86_64/postgresql/][=postgresql=]] | 201 | =nodejs= | [[https://www.archlinux.org/packages/community/x86_64/nodejs/][=nodejs=]] | 202 | =rbenv= | [[https://aur.archlinux.org/packages/rbenv/][=rbenv=]] | 203 | =ruby-build= | [[https://aur.archlinux.org/packages/ruby-build/][=ruby-build=]] | 204 | =npm= | [[https://www.archlinux.org/packages/community/any/npm/][=npm=]] | 205 206 For =rbenv=, I needed to add =eval "$(rbenv init -)"= to =.bashrc= or =.zshrc= after installation as prompted by the post installation script. 207 208 **** Mastodon 209 Create user =mastodon= and to =sudoers= using =visudo=. 210 #+BEGIN_SRC sh 211 useradd -m -G wheel -s /bin/bash mastodon 212 #+END_SRC 213 214 Then I can clone the repository and start [[https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md#nodejs-and-ruby-dependencies][installing node.js and ruby dependencies]]. This is where =npm= is required. Besides, I encountered a =ENONT= error when running =yarn= saying =./.config/yarn/global/.yarnclean= is missing, which is resolved by creating the file. 215 216 **** PostgreSQL 217 In addition to installing the =postgresql= package, I followed [[https://wiki.archlinux.org/index.php/PostgreSQL][Arch Wiki]] to initialize the data cluster: 218 219 #+BEGIN_SRC sh 220 $ sudo su postgres 221 [postgres]$ initdb --locale $LANG -E UTF8 -D '/var/lib/postgres/data' 222 #+END_SRC 223 224 After starting and enabling =postgresql= with =systemctl=, I can then start the =psql= shell as the =postgres= user and create user for Mastodon (use =psql= command =\du= to check the user is actually there): 225 226 #+BEGIN_SRC sh 227 $ sudo su postgres 228 [postgres]$ psql 229 [psql]# CREATE USER mastodon CREATEDB; 230 [psql]# \q 231 #+END_SRC 232 233 Port selection is customizable in =postgresql.service= and the port number will be used in =.env.porduction= customization. 234 235 **** Redis 236 Pretty much the same drill as =postgresql=, I installed =redis= and start/enabled =redis.service=. The port selection and address that have access can all be configured from =/etc/redis.conf=. 237 238 **** Nginx & Let's Encrypt 239 The official production guide covers this part pretty well already. 240 241 **** =.env.production= 242 The config file is fairly self-explanatory. The only thing I got wrong the first time is the variable =DB_HOST= for =postgresql=. I then obtained the correct path, =/run/postgresql=, by checking status of =postgresql.service=. 243 244 **** Scheduling Services & Cleanups 245 Again, just follow the official production guide. I installed [[https://www.archlinux.org/packages/core/x86_64/cronie/][=cronie=]] to schedule cron jobs. 246 247 *** My Experience 248 The web interface is fairly good, I like how I can write toots while browsing timelines instead of been forced to stay at the top of the page. I tried out quite a few Mastodon clients on my phone and I settled on [[https://pawoo.net/about][Pawoo]], which is built by Pixiv. So far Mastodon feels like a more comfy twitter to me and a platform where I am actually willing to write on. I'm pushing myself to write something on Mastodon every few days. So far it's been mostly running logs, but I'll come up more stuff to post in the future. 249 250 One thing I would really like to see though is multilingual post support in Mastodon. A workaround I currently use is appending different tags for Chinese vs. English posts, which not only bloats my toots, but also fragmented my timeline so that it's only 50% comprehensible for most people. Regrettably, it seems that out of the various micro-blogging/social networking services, only [[https://code.facebook.com/posts/597373993776783][Facebook]] has something similar to this at the moment. 251 252 In the footer section, I've replaced Twitter with [[https://mstdn.shimmy1996.com/@shimmy1996][my Mastodon profile]]. Feel free to take a peek inside. :P 253 254 ** DONE zh 255 :PROPERTIES: 256 :EXPORT_TITLE: Mastodon 尝鲜 257 :EXPORT_FILE_NAME: 2018-02-11-trying-out-mastodon.zh.md 258 :END: 259 260 我在 [[https://www.shimmy1996.com/zh/posts/2017-10-22-no-more-disqusting-disqus/][上一篇日志]] 里提到过,我并不习惯于在社交网络上发帖子。不过不久之前,我偶然撞见了一个很久没有听到过的词:微型博客。不少社交网络站点,例如 Twitter ,本质上还是一个微型博客服务。这种定义下的 Twitter 对我更加具有吸引力:我可以把一些随想,趣事和生活中其他不大适合写进博客的点点滴滴塞进去。但即使如此,我还是发推有一种“向整个互联网发送座标”的感觉。嗯,那么只好自己搭建一个微型博客了。 261 262 [[https://github.com/tootsuite/mastodon][Mastodon]] 就是一个很好的解决方案。对与在最大化网络人格和最小化个人信息泄露之间进退两难的我来说,存储去中心化、但实例之间又紧密相联的 Mastodon 非常理想。如果人们愿意为了好看的头像将个人信息拱手送出的话,搭建一个 Mastodon 实例可以算得上是一个划算的多的买卖。 263 264 *** 在 Arch Linux 上安装 Mastodon 265 我在一番搜寻后,居然没有找到一篇专门针对 Arch Linux 的 Mastodon 安装指南,这有点让我惊讶。不过得益于丰富的软件包,在 Arch Linux 上安装 Mastodon 其实比在 Ubuntu 上更加简单。 [[https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md][官方指南]] 上有很详尽的步骤说明,我就简单补充一些只适用于 Arch Linux 的部分。 266 267 **** 软件包依赖 268 我把所有依赖以及相对应的 Arch Linux 软件包都列了出来。完全没有手动克隆 git 仓库的必要。 =npm= 会在安装过程中用到,但没有在官方指南中列出。 269 270 | 依赖 | 软件包 | 271 | =node.js= 6.x | [[https://www.archlinux.org/packages/community/x86_64/nodejs-lts-boron/][=nodejs-lts-boron=]] | 272 | =yarn= | [[https://www.archlinux.org/packages/community/any/yarn/][=yarn=]] | 273 | =imagemagick= | [[https://www.archlinux.org/packages/extra/x86_64/imagemagick/][=imagemagick=]] | 274 | =ffmpeg= | [[https://www.archlinux.org/packages/extra/x86_64/ffmpeg/][=ffmpeg=]] | 275 | =libprotobuf= 和 =protobuf-compiler= | [[https://www.archlinux.org/packages/?sort=&q=protobuf&maintainer=&flagged=][=protobuf=]] | 276 | =nginx= | [[https://www.archlinux.org/packages/extra/x86_64/nginx/][=nginx=]] | 277 | =redis= | [[https://www.archlinux.org/packages/community/x86_64/redis/][=redis=]] | 278 | =postgresql= | [[https://www.archlinux.org/packages/extra/x86_64/postgresql/][=postgresql=]] | 279 | =nodejs= | [[https://www.archlinux.org/packages/community/x86_64/nodejs/][=nodejs=]] | 280 | =rbenv= | [[https://aur.archlinux.org/packages/rbenv/][=rbenv=]] | 281 | =ruby-build= | [[https://aur.archlinux.org/packages/ruby-build/][=ruby-build=]] | 282 | =npm= | [[https://www.archlinux.org/packages/community/any/npm/][=npm=]] | 283 284 在安装 =rbenv= 后,我需要把 =eval "$(rbenv init -)"= 加入 =.bashrc= 或 =.zshrc= 中(安装脚本也会提示这一步骤)。 285 286 **** Mastodon 287 创建用户 =mastodon= 并用 =visudo= 把该用户加入 =sudoers= 。 288 #+BEGIN_SRC sh 289 useradd -m -G wheel -s /bin/bash mastodon 290 #+END_SRC 291 292 接下来就可以克隆 Mastodon 的 git 仓库并开始 [[https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md#nodejs-and-ruby-dependencies][安装 node.js 和 ruby 的依赖]] 了。在这一过程中会用到 =npm= 。我在运行 =yarn= 时,遇到了一个 =ENONT= 错误:无法找到 =./.config/yarn/global/.yarnclean= 。手动创建了迷失的文件解决了这个错误。 293 294 **** PostgreSQL 295 除了安装 =postgresql= 软件包外, 我遵循 [[https://wiki.archlinux.org/index.php/PostgreSQL][Arch Wiki]] 里的步骤初始化了数据库集群: 296 297 #+BEGIN_SRC sh 298 $ sudo su postgres 299 [postgres]$ initdb --locale $LANG -E UTF8 -D '/var/lib/postgres/data' 300 #+END_SRC 301 302 在开始并启用 =postgresql.service= 后,我就可以以用户 =postgres= 的身份登录 =psql= 命令行并给 Mastodon 建立用户了(可以使用 =psql= 命令 =\du= 来确认用户列表): 303 304 #+BEGIN_SRC sh 305 $ sudo su postgres 306 [postgres]$ psql 307 [psql]# CREATE USER mastodon CREATEDB; 308 [psql]# \q 309 #+END_SRC 310 311 端口设置可以在 =postgresql.service= 里找到,这会在编辑 =.env.porduction= 时用到。 312 313 **** Redis 314 和 =postgresql= 差不多,我安装了 =redis= ,开始/启用了 =redis.service= 。端口选择和允许连接的地址都可以在 =/etc/redis.conf= 里设置。 315 316 **** Nginx 和 Let's Encrypt 317 官方指南已经提供了很详尽的步骤,这里不再赘述。 318 319 **** =.env.production= 320 照配置文件里的说明做就可以了。我唯一弄错的地方是连接 =postgresql= 所需的 =DB_HOST= 。在查看 =postgresql.service= 的状态后,我找到了正确的路径, =/run/postgresql= 。 321 322 **** 计划进程和缓存清理 323 照官方指南做就好。我安装了 [[https://www.archlinux.org/packages/core/x86_64/cronie/][=cronie=]] 来安排 cron 作业。 324 325 *** 使用感受 326 网页版界面很不错,我很喜欢可以一边刷时间线一边慢慢写嘟文这一点(而不是在被迫停留在页面顶端)。我在尝试了数个 Mastodon 手机客户端后选定了 Pixiv 开发的 [[https://pawoo.net/about][Pawoo]] 。到目前为止, Mastodon 给我的感觉是一个比 Twitter 更加舒适、更能激发我写东西的平台。我试着推动自己每隔几天就写一条嘟文。虽然目前为止我写的大都是跑步的记录,但我会渐渐丰富我的嘟文内容的。 327 328 我很希望看到 Mastodon 对多语言嘟文提供支持。目前我用的办法是给中文和英文的嘟文打上不同的标签,但这么做不仅使嘟文更加臃肿,也使得我的时间线对大部分人来说可读性只有 50% 。可惜的是,目前的诸多社交网络里只看到 [[https://code.facebook.com/posts/597373993776783][Facebook]] 对此提供了支持。 329 330 在网站页脚,我已经把 Twitter 换成了我的[[https://mstdn.shimmy1996.com/@shimmy1996][Mastodon 页面]] ,随时欢迎各位来访。 331 332 * DONE My Keyboards 2018 Edition 333 :PROPERTIES: 334 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :date 2018-03-17 :slug my-keyboards-2018-edition 335 :END: 336 337 ** DONE en 338 :PROPERTIES: 339 :EXPORT_TITLE: My Keyboards 2018 Edition 340 :EXPORT_FILE_NAME: 2018-03-18-my-keyboards-2018-edition.en.md 341 :END: 342 343 As part of my effort to tick off the last remaining item on my site roadmap, I read through some old keyboard-related posts from my WordPress blog and decided to give them an uplift to include more recent experiments. 344 345 *** The First Crispy Clack 346 My very first mechanical keyboard is a WASD v2 104 key with Cherry MX Blue switches that I got in 2014. I picked WASD mainly because of their keyboards' minimal look and keycap customization options. I also got my first 60% in 2014, a Poker II with Cherry MX Brown. Switch selection were more limited back then, seemingly because of potential issues with Cherry's patent. Of course, switch choices is only limited if we restrict ourselves to Cherry MX compatibles, but most alternatives (Matias, Topre, buckling spring to name a few) were even harder to come by in an commonly available package that I liked. 347 348 A GH60 based 60% that I frankensteined together became my main keyboard at first. I used Cherry MX Clear switches with 62g springs (ErgoClear) on them, mostly for the fun factor instead of preference. I also found myself tinkering with the layout a lot more often than when I had the Poker II. As great as Poker II's built-in macros mapping sounds, I could never remember all the steps without taking a moment to peruse the manual. I also found myself setting macros up and yet completely forget about them ever since. With GH60's firmware, at the very least I have the configuration files to remind me of the new bindings I set up. Even with this shiny new toy though, my early experiments with keyboard layouts still had only limited success. The layout of a 60% is too standard in my opinion to justify significant changes (while maintaining QWERTY layout), i.e. there isn't really a good location to move Enter to. The few tweaks I ended up making were numpad/function key mapping and swapping out Caps Lock for Control, which at best makes my GH60 on par with any random keyboard with [[https://www.x.org/wiki/XKB/][xkb]]. 349 350 On a side note, I once aspired to collect keyboards of all form factors, but soon discovered it to be a highly impractical and expansive exercise. Thus far among the more common layouts, I either owned or tried 104 key, 96 key, 87 key, 75 key, 60 key, and 40 key keyboards. Majority of these differs very little experience wise for me, except for 60% or 40%, where a bit of creativity is required to fit all the desired keys. 351 352 *** ErgoDox and Planck 353 The first keyboard ever to trigger me to give deeper thoughts into my keyboard layout is the ErgoDox. The ErgoDox boasts a layout drastically different from traditional keyboards, and because of this, offers great flexibility over key placements: I can immediately spot seven sensible locations for the Enter key (original pinky location, four 2u keys at the thumb clusters and the lower two 1.5u vertical keys in the center). I've been using ErgoDox almost exclusively since 2015, and have grown to like it even more as I started using Emacs - having access to both Control and Alt/Meta key on the home row just feels awesome. 354 355 #+CAPTION: My ErgoDox Base Layer Layout 356 [[/img/posts/2018/my-keyboards-2018-edition-01.png]] 357 358 I still feel I am under-utilizing the keyboard's capabilities though. As you might tell, I don't know what to do with some of the thumb cluster keys. I currently have three extra layers set up: one for function keys, one for numpad, and another for a modified Dvorak layout. I haven't spend too much time on the Dvorak layer yet, but I am curious about potential benefits of decreased finger motion. Speaking of ergonomics, a perhaps uninteded benefit of ErgoDox's design is that it frees up the center of my desk, so that I can still read and write normally without a super deep desk. 359 360 #+CAPTION: My ErgoDox Dvorak Layer Layout 361 [[/img/posts/2018/my-keyboards-2018-edition-02.png]] 362 363 Planck is another keyboard that I've taken some thoughts designing layout for. It is pretty surprising what a 40% board is actually capable of. However, using Planck is a lot less comfortable just because of how small it is - ErgoDox on the other hand allows me to rest my arms in more natural positions, instead of cramming my hands together. That being said, I would imagine a Let's Split - basically a Planck split in halves - to work fairly well. 364 365 #+CAPTION: My Planck Layout 366 [[/img/posts/2018/my-keyboards-2018-edition-03.png]] 367 368 *** Keycap Craze 369 Ever since I discovered Geekhack, I would routinely refresh the groupbuy or interest check section for new keycap sets that other users designed. I gradually went from sets with flashy colors to those with a more muted and uniform look. I also prefer uniform keycap profiles (like DSA) with text legends than those with height gradients and graphical legends, although I find it really hard to appreciate blank keycaps. Getting a full set of keycaps with matching legends for ErgoDox is certainly no easy task (unlike Planck which is almost entirely consisted of 1u keys), and all these quirks I have made keycap shopping increasingly difficult. 370 371 *** My Own Keyboard/Layout 372 I've thought about creating my own keyboard occasionally. As perfect as ErgoDox 373 may seem, it is somewhat bulky, and I find the thumb cluster a bit hard to 374 reach. For quite some time I used ~C-Home~ and ~C-End~ to move to top/bottom of a 375 file in Emacs, and that caused pain in my thumb joint as I need to stretch hard 376 to reach both keys (that went away when I found ~M-<~ and ~M->~ though). A slim down version of ErgoDox with more compact thumb clusters might just be the perfect keyboard. By the way, I have never before find wireless keyboard necessary in any way, but since ErgoDox features a split design, a wireless version of it can be used while lying down Nintendo-Switch-style, which would be pretty awesome. 377 378 Since I started using Emacs as my main editor, I've been taking statistics of my key-presses with =keyfreq=. When I have gathered enough data, I might look into customizing my layout even further to suit my needs. 379 380 *** Pixel Art 381 Like many Geekhackers out there, I made a pixel art of my keyboards and used it as my Geekhack signature. 382 383 #+CAPTION: Pixel Art of My Keyboards I, 2015 384 [[/img/posts/2018/my-keyboards-2018-edition-04.png]] 385 386 #+CAPTION: Pixel Art of My Keyboards II, 2015 387 [[/img/posts/2018/my-keyboards-2018-edition-05.png]] 388 389 Drawing pixel art for keyboard is a fairly interesting exercise, since it is impossible to get the ratios exactly right, I needed to strike a balance between accuracy and simplicity. I will give this a long due update when I have time. 390 391 ** DONE zh 392 :PROPERTIES: 393 :EXPORT_TITLE: 我的键盘 2018 版 394 :EXPORT_FILE_NAME: 2018-03-18-my-keyboards-2018-edition.zh.md 395 :END: 396 397 为了完成主页施工计划上的最后一条项目,我重新浏览了旧博客里关于键盘的日志并决定翻新这些文章,同时加入一些近期的新尝试。 398 399 *** 入门 400 我在 2014 年入手了第一块机械键盘,使用 Cherry MX 青轴的 WASD v2 104 键键盘。我选了 WASD 的主要原因是他们键盘较为简约的外形和客制化键帽的服务。我在 2014 年还入手了第一块 60% 键盘,使用 Cherry MX 茶轴的 Poker II 。在那时候可能由于 Cherry 的专利尚未过期,所以键盘轴的选择要比现在少得多。当然如果不考虑 Cherry MX 兼容性,替代品还是有的( Matias , Topre , IBM 弹簧轴等),但入手更加困难。 401 402 我最初的主力是一块我七拼八凑起来的基于 GH60 的 60% 键盘。我使用的键盘轴是改装了 62 克弹簧的 Cherry MX 白轴( ErgoClear ),这更多的只是想尝试键盘轴改装而不是因为偏好。除此之外,我发觉自己比之前用 Poker II 的时候更经常修改键盘布局了。虽然 Poker II 自带的宏编辑功能听上去很棒,但复杂的步骤使得我从来没有在不看说明书的情况下成功完成过编辑。而就算我废了老大力气完成了宏的设定,我过一段时间就会把宏的存在抛在脑后。相比之下,编辑 GH60 的固件后,至少我还能查看设定文件来回忆自己的设定。我早期修改键盘布局的尝试并不太成功:在我看来, 60% 键盘的键位布局太标准了,以至于(在保持 QWERTY 布局下)任何大范围修改都会让人觉得别扭。举个例子:我完全没法找到第二个适合回车键的位置。我所作的布局修改大多只是数字小键盘和功能键的映射以及交换大写锁定和控制键,完全没发挥出 GH60 的潜能,充其量只不过和使用了 [[https://www.x.org/wiki/XKB/][xkb]] 的普通键盘旗鼓相当。 403 404 顺便一提,我曾经想过要收集所有键数布局的键盘,但很快的发现这是一个不切实际且烧钱的想法。目前为止在常见的键数布局中,我尝试过 104 键, 96 键, 87 键, 75 键, 60 键,和 40 键键盘。这当中的绝大多数对我来说在体验上并没有太大区别,除了 60% 或 40% :要想把所有标准键放上去是需要动一番脑筋的。 405 406 *** ErgoDox 和 Planck 407 ErgoDox 是第一个促使我真正下心思选择键盘布局的键盘。正是由于布局和传统键盘相差甚远, Ergodox 在键位布局选择上提供了很高的自由度:我一眼就能找到七个适合回车键的位置(传统右侧小拇指位,拇指区的四个 2u 键位,以及中心偏下的两个 1.5u 键位)。从 2015 开始,我就几乎只使用 ErgoDox 了。 ErgoDox 的好处在我开始使用 Emacs 后更加明显:能够轻而易举地够到控制键和转换键的感觉非常棒。 408 409 #+CAPTION: 我的 ErgoDox 基本层布局 410 [[/img/posts/2018/my-keyboards-2018-edition-01.png]] 411 412 ErgoDox 还有很多潜力没有被我发掘出来。如你所见,我还没有想出拇指区部分键位的最佳用处。目前除了基本层外,我额外设置了三层键位布局:一层用于功能键,一层用于数字小键盘,最后一层是经过修改的 Dvorak 布局。我还没有在 Dvorak 层上花太多时间,不过我对 Dvorak 减少手指移动次数的功效很有兴趣。说到人体工学, ErgoDox 设计有个额外的好处:我书桌的正中央终于可以从键盘的统治下空出来了,就算没有一张超级深的桌子我也可以不受键盘干扰正常看书。 413 414 #+CAPTION: 我的 ErgoDox Dvorak 层布局 415 [[/img/posts/2018/my-keyboards-2018-edition-02.png]] 416 417 Planck 是另一块让我下心思设计布局的键盘。 40% 键盘所能塞下来的东西其实多的让人吃惊。但是使用 Planck 时的舒适性不可避免地被它的尺寸所妨碍了 - 相比之下,使用 ErgoDox 这种分体键盘时两手可以保持更为自然的姿势,而不是以奇怪的角度挤在一起。我觉得 Let's Split - 基本上就是分体版的 Planck - 会是个不错的选择。 418 419 #+CAPTION: 我的 Planck 布局 420 [[/img/posts/2018/my-keyboards-2018-edition-03.png]] 421 422 *** 键帽狂热期 423 在我发现了 Geekhack 论坛后,我在很长一段时间里都会疯狂刷新团购和兴趣调查版,以收集其他用户所设计的客制键帽情报。我发现自己的兴趣逐渐地从色彩对比强烈的配色转向了更为统一,柔和的设计。在键帽形状的选择上,我也偏好没有高低梯度的类型,比如 DSA 。键帽图样上我更喜欢文字而非图案,有意思的是我并不觉得空白键帽有多么值得欣赏。这些癖好使得我的寻找键帽之旅异常困难:要想给 ErgoDox 配齐一整套图样相称的键帽可不是什么容易的事( Planck 因为全是 1u 键,所以要容易得多)。 424 425 *** 设计自己的键盘/布局 426 我有时会冒出设计自己的键盘的念头。 ErgoDox 已经很接近我理想中的键盘了,但是它还 427 是有点笨重,而且拇指区边缘的键比较难按到。我原先一直在 Emacs 里使用 ~C-Home~ 和 428 ~C-End~ 来移动光标到文件开头/结尾,这两个键位组合使我不得不尽力伸展大拇指,导致 429 关节有些酸痛(直到我发现 ~M-<~ 和 ~M->~ 才是正确的打开方式)。一个更加小巧,拇指区键位更加紧凑的 ErgoDox 应该就是我眼中完美的键盘了。对了,虽然我以前从来没有觉得无线键盘有多么必要,但因为 ErgoDox 的分体式设计,如果它有无线版本,我就可以像使用任天堂 Switch 那样躺在床上打字了。 430 431 自从我开始使用 Emacs 作为主力文本编辑器,我就一直在使用 =keyfreq= 来记录每个键/组合键的使用频率。在我收集了足够多的数据后,我会以此为根据来调整我的键盘布局。 432 433 *** 键盘像素画 434 我之前跟风 Geekhack 众,也给我的键盘画了像素画作为签名。 435 436 #+CAPTION: 我的键盘像素画 I 437 [[/img/posts/2018/my-keyboards-2018-edition-04.png]] 438 439 #+CAPTION: 我的键盘像素画 II 440 [[/img/posts/2018/my-keyboards-2018-edition-05.png]] 441 442 给键盘画像素画其实挺有意思,要想保持精确的比例几乎是不可能的,这就需要在精准和简约之间作微妙的平衡。我有时间时会继续更新这些像素画的。 443 444 * DONE Fun With Fonts In Emacs 445 :PROPERTIES: 446 :EXPORT_DATE: 2018-06-24 447 :EXPORT_HUGO_SLUG: fun-with-fonts-in-emacs 448 :END: 449 450 ** DONE en 451 :PROPERTIES: 452 :EXPORT_FILE_NAME: 2018-06-24-fun-with-fonts-in-emacs.en.md 453 :EXPORT_TITLE: Fun With Fonts in Emacs 454 :END: 455 456 I finally took some time to look at the my font configurations in Emacs and cleaned them up as much as possible. This dive into the rabbit hole have been tiring yet fruitful, revealing the cravat of typesetting that I didn't know before, especially for CJK characters. 457 458 I primarily use Emacs by running a daemon and connecting to it via a graphical 459 =emacsclient= frame, and I am attempting to tackle three major problems: I don't 460 have granular control over font mapping, glyph widths are sometimes inconsistent 461 with character widths, and emoji show up as weird blocks. Terminal Emacs doesn't 462 suffer as much from these problems, yet I don't want to give away the nice perks 463 like system clipboard access and greater key binding options, so here goes 464 nothing. 465 466 *** Font Fallback Using Fontsets 467 Ideally, I want to specify two sets of fonts, a default monospace font and a 468 CJK-specific font. Here's how I originally specified the font in Emacs: 469 #+BEGIN_SRC emacs-lisp 470 (setq default-frame-alist '((font . "Iosevka-13"))) 471 #+END_SRC 472 473 The method above obviously leaves no ground for fallback fonts. However, it 474 turns out I can specify the =font= to be a fontset instead of an individual 475 font. According to [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Fontsets.html][Emacs Manual]], a fontset is essentially a mapping from Unicode 476 range to a font or hierarchy of fonts and I can [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Modifying-Fontsets.html][modify]] one with relative ease. 477 478 Sounds like an easy job now? Not so fast. I don't really know which fontset to 479 modify: fontset behavior is quirky in that the fontset Emacs ends up using seems 480 to differ between =emacsclient= and normal =emacs=, between terminal and 481 graphical frames, and even between different locales. While there is a way to 482 get the current active fontset (=(frame-parameter nil 'font)=), this method is 483 unreliable and may cause errors like [[https://lists.gnu.org/archive/html/emacs-devel/2006-12/msg00285.html][this one]]. 484 485 After all kinds of attempts and DuckDuckGoing (that really rolled right off the 486 tongue, and no, I am [[https://www.reddit.com/r/duckduckgo/comments/8cm51u/what_ing_verb_do_you_use_for_duckduckgo/][not the first one]]), I finally found the [[https://stackoverflow.com/questions/17102692/using-a-list-of-fonts-with-a-daemonized-emacs][answer]]: just define 487 a new fontset instead of modifying existing ones. 488 #+BEGIN_SRC emacs-lisp 489 (defvar user/standard-fontset 490 (create-fontset-from-fontset-spec standard-fontset-spec) 491 "Standard fontset for user.") 492 493 ;; Ensure user/standard-fontset gets used for new frames. 494 (add-to-list 'default-frame-alist (cons 'font user/standard-fontset)) 495 (add-to-list 'initial-frame-alist (cons 'font user/standard-fontset)) 496 #+END_SRC 497 498 I won't bore you with the exact logic just yet, as I also made other changes to 499 the fontset. 500 501 **** Displaying Emoji 502 Solution to emoji display is similar—just specify a fallback font with emoji 503 support—or so I thought. I tried to use Noto Color Emoji as my emoji font, 504 only to find Emacs does not yet support colored emoji font. Emacs used to 505 support colored emoji on macOS, but this functionality was later [[https://github.com/emacs-mirror/emacs/blob/emacs-25.1/etc/NEWS#L1723][removed]]. 506 507 I ended up using [[http://users.teilar.gr/~g1951d/][Symbola]] as my emoji fallback font (actually I used it as a 508 fallback for all Unicode characters), which provided comprehensive coverage over 509 [[https://unicode.org/Public/emoji/11.0/emoji-test.txt][all the emoji]] and special characters. Also note that since Emacs 25, 510 customization to the =symbols= [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Charsets.html][charset]], which contains puncation marks, emoji, 511 etc., requires [[https://github.com/emacs-mirror/emacs/blob/emacs-25/etc/NEWS#L58][some extra work]]: 512 #+BEGIN_SRC emacs-lisp 513 (setq use-default-font-for-symbols nil) 514 #+END_SRC 515 516 There does exist a workaround for colored emoji though, not with fancy fonts, 517 but by replacing Unicode characters with images. [[https://github.com/iqbalansari/emacs-emojify][=emacs-emojify=]] is a package 518 that provides this functionality. I ultimately decided against it as it does 519 slow down Emacs quite noticeably and the colored emoji image library is not as 520 comprehensive. 521 522 **** Quotation Marks 523 I've always used full-width directional curly quotation marks ("“”" and 524 "‘’") when typing in Chinese, and ASCII style ambidextrous straight quotation 525 marks (""" and "'") when typing in English. Little did I know there really is no 526 such thing as full-width curly quotation marks: there is only one set of curly 527 quotation mark codepoints in Unicode (U+2018, U+2019, U+201C, and U+201D) and 528 the difference between alleged full-width and half-width curly quotation marks 529 is caused solely by fonts. There have been [[https://www.unicode.org/L2/L2014/14006-sv-western-vs-cjk.pdf][proposals]] to standardize the two 530 distinct representations, but for now I'm stuck with this ambiguous mess. 531 532 It came as no surprise that these curly quotation marks are listed under 533 =symbols= charset, instead of a CJK one, thus using normal monospace font 534 despite the fact that I want them to show up as full-width characters. I don't 535 have a true solution for this—being consistent is the only thing I can do, so 536 I forced curly quotation marks to display as full width characters by overriding 537 these exact Unicode codepoints in my fontset. I'm not really sure how I feel 538 when I then realized ASCII style quotation marks also suffered from 539 [[https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html][confusion]]—maybe we are just really bad at this. 540 541 My fallback font configurations can be found on both [[https://github.com/shimmy1996/.emacs.d#fontset-with-cjk-and-unicode-fallback][GitHub]] and [[https://git.shimmy1996.com/emacs.d/file/README.org.html#l158][Trantor Holocron]] 542 and I'll list them here just for sake of completeness: 543 #+BEGIN_SRC emacs-lisp 544 (defvar user/cjk-font "Noto Sans CJK SC" 545 "Default font for CJK characters.") 546 547 (defvar user/latin-font "Iosevka Term" 548 "Default font for Latin characters.") 549 550 (defvar user/unicode-font "Symbola" 551 "Default font for Unicode characters, including emojis.") 552 553 (defvar user/font-size 17 554 "Default font size in px.") 555 556 (defun user/set-font () 557 "Set Unicode, Latin and CJK font for user/standard-fontset." 558 ;; Unicode font. 559 (set-fontset-font user/standard-fontset 'unicode 560 (font-spec :family user/unicode-font) 561 nil 'prepend) 562 ;; Latin font. 563 ;; Only specify size here to allow text-scale-adjust work on other fonts. 564 (set-fontset-font user/standard-fontset 'latin 565 (font-spec :family user/latin-font :size user/font-size) 566 nil 'prepend) 567 ;; CJK font. 568 (dolist (charset '(kana han cjk-misc hangul kanbun bopomofo)) 569 (set-fontset-font user/standard-fontset charset 570 (font-spec :family user/cjk-font) 571 nil 'prepend)) 572 ;; Special settings for certain CJK puncuation marks. 573 ;; These are full-width characters but by default uses half-width glyphs. 574 (dolist (charset '((#x2018 . #x2019) ;; Curly single quotes "‘’" 575 (#x201c . #x201d))) ;; Curly double quotes "“”" 576 (set-fontset-font user/standard-fontset charset 577 (font-spec :family user/cjk-font) 578 nil 'prepend))) 579 580 ;; Apply changes. 581 (user/set-font) 582 ;; For emacsclient. 583 (add-hook 'before-make-frame-hook #'user/set-font) 584 #+END_SRC 585 586 *** CJK Font Scaling 587 My other gripe is the width of CJK fonts does not always match up with that of 588 monospace font. Theoretically, full-width CJK characters should be exactly twice 589 of that half-width characters, but this is not the case, at least not in all 590 font sizes. It seems that CJK fonts provide less granularity in size, i.e. 16px 591 and 17px versions of CJK characters in Noto Sans CJK SC are exactly the same, 592 and does not increase until size is bumped up to 18px, while Latin characters 593 always display the expected size increase. This discrepancy means their size 594 would match every couple sizes, but different in between with CJK fonts being a 595 bit too small. 596 597 One solution is to specify a slightly larger default size for CJK fonts in the 598 fontset. However, this method would render =text-scale-adjust= (normally bound 599 to ~C-x C-=~ and ~C-x C--~) ineffective against CJK fonts for some reason. A 600 better way that preserves this functionality is to scale the CJK fonts up by 601 customizing =face-font-rescale-alist=: 602 #+BEGIN_SRC emacs-lisp 603 (defvar user/cjk-font "Noto Sans CJK SC" 604 "Default font for CJK characters.") 605 606 (defvar user/font-size 17 607 "Default font size in px.") 608 609 (defvar user/cjk-font-scale 610 '((16 . 1.0) 611 (17 . 1.1) 612 (18 . 1.0)) 613 "Scaling factor to use for cjk font of given size.") 614 615 ;; Specify scaling factor for CJK font. 616 (setq face-font-rescale-alist 617 (list (cons user/cjk-font 618 (cdr (assoc user/font-size user/cjk-font-scale))))) 619 #+END_SRC 620 621 bWhile the font sizes might still go out of sync after =text-scale-adjust=, I am 622 not too bothered. The exact scaling factor took me a few trial and error to find 623 out. I just kept adjusting the factor until these line up (I found [[https://websemantics.uk/articles/font-size-conversion/][this table]] 624 really useful): 625 #+BEGIN_SRC 626 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 627 云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云 628 雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲 629 ㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞ 630 ああああああああああああああああああああああああああああああああああああああああ 631 가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가 632 #+END_SRC 633 634 Unfortunately, the CJK font I used has narrower Hangul than other full-width CJK 635 characters, so this is still not perfect—the solution would be to specify a 636 Hangul specific font and scaling factor—but good enough for me. 637 638 It took me quite some effort to fix what may seem like a minor annoyance, but at 639 least Emacs did offer the appropriate tools. By the way, I certainly wish I had 640 found [[https://www.emacswiki.org/emacs/FontSets][this article]] on Emacs Wiki sooner, as it also provides a neat write up of 641 similar workarounds. 642 643 ** DONE zh 644 :PROPERTIES: 645 :EXPORT_FILE_NAME: 2018-06-24-fun-with-fonts-in-emacs.zh.md 646 :EXPORT_TITLE: 字体配置 Emacs 篇 647 :END: 648 649 我终于花了些时间清理我 Emacs 里一团糟的字体设定。在折腾这些设定的过程中,我了解到了一些中日韩( CJK )字体排版上的豆知识。 650 651 我主要使用 Emacs 的方式是使用一个图形 =emacsclient= 窗口链接在后台运行的守护进程。 652 我所要解决的主要问题有三个:缺少精细控制字体映射的方法、字形宽度和字符宽度不一致、 653 emoji 时常显示为豆腐块。虽然终端 Emacs 不大受这些问题的影响,但我不想放弃图形 654 Emacs 的其他好处,例如系统剪贴板和更加丰富的键位选择,所以我只好迎难而上着手解决 655 这些问题。 656 657 *** 使用字体集( Fontset )设置后备字体 658 在最理想的状况下,我想指定两套字体,一套默认的等宽字体和一套专门显示中日韩字符的字 659 体。我原来是这么设定 Emacs 字体的: 660 #+BEGIN_SRC emacs-lisp 661 (setq default-frame-alist '((font . "Iosevka-13"))) 662 #+END_SRC 663 664 这种方法显然无法指定后备字体。不过 =font= 除了接受单一字体外,也可以接受字体集。 665 根据 [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Fontsets.html][Emacs手册]] ,字体集可以大致理解为从 Unicode 到字体的映射,并且我可以很容易地 666 [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Modifying-Fontsets.html][修改]] 字体集。 667 668 听上去似乎很容易?且慢。我并不知道应该被修改的是哪一个字体集: Emacs 最终使用的 669 字体集似乎会因语言环境( locale )、使用图形还是终端窗口、使用 =emacsclient= 还 670 是 =emacs= 而变化。尽管有方法可以获得目前使用的字体集( =(frame-parameter nil 671 'font)= ),但这 [[https://lists.gnu.org/archive/html/emacs-devel/2006-12/msg00285.html][并不完全可靠]] 。 672 673 在不少失败的尝试之后,我终于找到了 [[https://stackoverflow.com/questions/17102692/using-a-list-of-fonts-with-a-daemonized-emacs][答案]] :直接定义一个新的字体集。 674 #+BEGIN_SRC emacs-lisp 675 (defvar user/standard-fontset 676 (create-fontset-from-fontset-spec standard-fontset-spec) 677 "Standard fontset for user.") 678 679 ;; Ensure user/standard-fontset gets used for new frames. 680 (add-to-list 'default-frame-alist (cons 'font user/standard-fontset)) 681 (add-to-list 'initial-frame-alist (cons 'font user/standard-fontset)) 682 #+END_SRC 683 684 由于我除了指定中日韩字体外还对字体集做了其他更改,我会在阐明所有改变后再贴出全部 685 设定。 686 687 **** 显示 Emoji 688 解决 emoji 显示的方法与中日韩文字类似——找到一款支持 emoji 的字体不就好了吗——至少 689 我是这么想的。我一开始试图使用 Noto Color Emoji 作为 emoji 用后备字体,但发现 690 Emacs 目前并不支持彩色 emoji 字体。 Emacs 曾经在 macOS 上支持彩色 emoji字体,但 691 后来 [[https://github.com/emacs-mirror/emacs/blob/emacs-25.1/etc/NEWS#L1723][移除]] 了。 692 693 我最后选择了 [[http://users.teilar.gr/~g1951d/][Symbola]] 作为 emoji 后备字体(事实上我把它设为了所有 Unicode 字符的 694 后备字体)。 Symbola 可以显示 [[https://unicode.org/Public/emoji/11.0/emoji-test.txt][所有 emoji]] 和许多特殊符号。还需要注意的一点是,在 695 Emacs 25 之后,要想在字体集中自定义包含了大部分标点、特殊符号、 emoji 的 696 =symbols= [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Charsets.html][字符集( charset )]],需要[[https://github.com/emacs-mirror/emacs/blob/emacs-25/etc/NEWS#L58][一些额外的设置]]: 697 #+BEGIN_SRC emacs-lisp 698 (setq use-default-font-for-symbols nil) 699 #+END_SRC 700 701 如果实在想要显示彩色 emoji 倒也不是完全没有办法,不过不是通过设置字体,而是将 702 Unicode 字符替换为图片。[[https://github.com/iqbalansari/emacs-emojify][=emacs-emojify=]] 就是一个提供这种功能的 Emacs 包。由于这 703 个包会给 Emacs 带来一定的延迟,而且大部分彩色 emoji 图片库并不完整,我最终决定不 704 予采用。 705 706 **** 引号风波 707 我一直习惯在书写中文时使用成对的全角弯引号(““””和“‘’”)以及在书写英文时 708 使用 ASCII 里的对称直引号(“"”和“'”)。然而我并不知道“全角弯引号”其实根本 709 不存在: Unicode 中只存在一组弯引号编码( U+2018 、 U+2019 、 U+201C 、U+201D ), 710 而所谓的全角与半角弯引号之分完全是字体引起的。虽然已经有相关的 [[https://www.unicode.org/L2/L2014/14006-sv-western-vs-cjk.pdf][提案]] 建议将这两种 711 不同的表示方法标准化,但目前弯引号就是这么一个烂摊子。 712 713 了解来龙去脉之后,就不难理解为什么弯引号在 Emacs 里隶属 =symbol= 字符集而非某个 714 中日韩字符集了。这也导致这些弯引号会使用我的默认等宽字体并显示为半角字符。我并没 715 有从根本上解决这一问题的办法,所以为了保证显示风格和书写风格保持一致,我通过为特 716 定的 Unicode 编码指定字体将这些弯引号字符统一显示为全角。当我知道直引号其实也有 717 着 [[https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html][充满误会的过去]] 的时候,我已经不知道应该用什么表情来面对了——也许我们在这方面真 718 的很糟糕。 719 720 我的后备字体设置可以在 [[https://github.com/shimmy1996/.emacs.d#fontset-with-cjk-and-unicode-fallback][GitHub]] 和 [[https://git.shimmy1996.com/emacs.d/file/README.org.html#l158][川陀全息档案馆]] 上找到。为了日志的完整性,我在这里也放 721 一份: 722 #+BEGIN_SRC emacs-lisp 723 (defvar user/cjk-font "Noto Sans CJK SC" 724 "Default font for CJK characters.") 725 726 (defvar user/latin-font "Iosevka Term" 727 "Default font for Latin characters.") 728 729 (defvar user/unicode-font "Symbola" 730 "Default font for Unicode characters, including emojis.") 731 732 (defvar user/font-size 17 733 "Default font size in px.") 734 735 (defun user/set-font () 736 "Set Unicode, Latin and CJK font for user/standard-fontset." 737 ;; Unicode font. 738 (set-fontset-font user/standard-fontset 'unicode 739 (font-spec :family user/unicode-font) 740 nil 'prepend) 741 ;; Latin font. 742 ;; Only specify size here to allow text-scale-adjust work on other fonts. 743 (set-fontset-font user/standard-fontset 'latin 744 (font-spec :family user/latin-font :size user/font-size) 745 nil 'prepend) 746 ;; CJK font. 747 (dolist (charset '(kana han cjk-misc hangul kanbun bopomofo)) 748 (set-fontset-font user/standard-fontset charset 749 (font-spec :family user/cjk-font) 750 nil 'prepend)) 751 ;; Special settings for certain CJK puncuation marks. 752 ;; These are full-width characters but by default uses half-width glyphs. 753 (dolist (charset '((#x2018 . #x2019) ;; Curly single quotes "‘’" 754 (#x201c . #x201d))) ;; Curly double quotes "“”" 755 (set-fontset-font user/standard-fontset charset 756 (font-spec :family user/cjk-font) 757 nil 'prepend))) 758 759 ;; Apply changes. 760 (user/set-font) 761 ;; For emacsclient. 762 (add-hook 'before-make-frame-hook #'user/set-font) 763 #+END_SRC 764 765 *** 中日韩字体大小比例 766 最后需要解决的问题就是中日韩字体字宽和等宽字体比例不一致的问题了。理论上全角的中 767 日韩字符应该是半角字符宽度的两倍,但这并不在所有字号下成立。看起来原因是中日韩字 768 体在字号上其实偷懒了:在使用 Noto Sans CJK SC 时, 16px 和 17px 大小的中日韩字符 769 是没有任何大小区别的,直到 18px 才会出现大一号的字形,不像拉丁字符始终表现出预期 770 的尺寸增幅。这一现象使得中日韩字符和拉丁字符在每隔数个字号后大小比例相称,但使用 771 夹在中间的字号时中日韩字符会略微偏小。 772 773 一种解决方式时在修改字体集时给中日韩字体设置一个稍大一些的默认字号。不过这会导致 774 =text-scale-adjust= (通常被绑定在 ~C-x C-=~ 和 ~C-x C--~ 上)对中日韩字体不生效。 775 一种更好的办法是修改 =face-font-rescale-alist= 设置缩放比例: 776 #+BEGIN_SRC emacs-lisp 777 (defvar user/cjk-font "Noto Sans CJK SC" 778 "Default font for CJK characters.") 779 780 (defvar user/font-size 17 781 "Default font size in px.") 782 783 (defvar user/cjk-font-scale 784 '((16 . 1.0) 785 (17 . 1.1) 786 (18 . 1.0)) 787 "Scaling factor to use for cjk font of given size.") 788 789 ;; Specify scaling factor for CJK font. 790 (setq face-font-rescale-alist 791 (list (cons user/cjk-font 792 (cdr (assoc user/font-size user/cjk-font-scale))))) 793 #+END_SRC 794 795 虽然在使用 =text-scale-adjust= 后字体大小比例依然可能会乱掉,但我只要默认字号下 796 对齐就行。具体的缩放比例只能通过反复测试来确定。我用以下几行字符是否对齐来判断缩 797 放比例是否合适(这张 [[https://websemantics.uk/articles/font-size-conversion/][表格]] 会是很好的帮手): 798 #+BEGIN_SRC 799 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 800 云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云云 801 雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲雲 802 ㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞㄞ 803 ああああああああああああああああああああああああああああああああああああああああ 804 가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가가 805 #+END_SRC 806 807 不巧的是,我所使用中日韩字体的谚文比其他全角字符都要窄,所以最终结果仍不完美——解 808 决方案是再添加一个谚文专用的字体和缩放比例——不过对我来说够用了。 809 810 我在解决这些看似简单的问题上花的精力比想象的多不少,不过值得庆幸的是 Emacs 提供 811 了所需的各项工具。顺便一提, Emacs Wiki 上的 [[https://www.emacswiki.org/emacs/FontSets][这篇文章]] 也提供了一些类似的问题的解 812 决方案:要是我早一些看到,配置过程大概会顺利许多。 813 814 * DONE Construction Finished 815 :PROPERTIES: 816 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :date 2018-05-21 :slug construction-finished :latex true 817 :END: 818 819 ** DONE en 820 :PROPERTIES: 821 :EXPORT_TITLE: Construction Finished 822 :EXPORT_FILE_NAME: 2018-05-21-construction-finished.en.md 823 :END: 824 825 After eight months, my blog have finally reached a place where I feel comfortable taking down the "under heavy construction" notice on my home page. In stead of out right deleting the site road map though, I'm stashing it into a blog post. 826 827 *** Site Road Map 828 - ☑ +Find new hosting location.+ Currently using DigitalOcean. 829 - ☑ Install Arch Linux on server. 830 - ☑ +Search for WP replacement.+ Hugo is pretty good. 831 - ☑ +Find a suitable theme.+ Currently using =hugo-xmin= , may consider forking it and write my own ( =soresu= ). 832 - ☑ Server side config, like =post-receive= for git auto deploy. 833 - ☑ Language switcher that does more than redirecting to home page. 834 - ☑ Enable Disqus. 835 - ☑ Support \(\LaTeX\) expressions via +MathJax+ KaTeX. 836 - ☑ Copy-paste fixed page contents from old site (and translate them). 837 - ☑ Enable https. 838 - ☑ Backup old WP site. 839 - ☑ Transfer domain to Google Domains and ensure DNS works as intended. 840 - ☑ Find out how to write with =org-mode= or R markdown. 841 - ☑ Configure multilingual support, including footer text, title, etc. 842 - ☑ Find out how to make =emacs= work with =fcitx= . 843 - ☑ Use +Google's Noto Sans font+ Oxygen Sans and +Source Code Pro+ Iosevka for code. 844 - ☑ Find a suitable icon/favicon. 845 - ☑ Improve templates for posts to display tags and categories. 846 - ☑ Cosmetic changes, i.e. no underlines for hyperlinks. 847 - ☑ Deal with some nuances in using =org-mode= with =hugo= , like how to get syntax highlighting to work properly. 848 - ☑ Host my own email. 849 - ☑ Customize =hugo new= to make it more useful, i.e. create multilingual versions directly. 850 - ☑ Self-host commenting system as a replacement of Disqus. 851 - ☑ Use Let's Encrypt's wildcard certificate. 852 - ☑ Restore/rewrite and translate some of the more valuable old posts. 853 854 *** What's on Home Page Now? 855 I already have an about page and a contact page for whatever I think people might be interested in knowing about myself, so I have no clue what I should put on home page. Since I found the old site road map to be a great way of reminding myself the stuffs I need to get done, I'll replace the road map with another to-do list: my goals for 2018. I am definitely not the most motivated kind of person, but seeing an unfinished to-do list every once in a while does get on my nerves. Let's see how well this is gonna work. 856 857 ** DONE zh 858 :PROPERTIES: 859 :EXPORT_TITLE: 施工完成 860 :EXPORT_FILE_NAME: 2018-05-21-construction-finished.zh.md 861 :END: 862 863 历时八个月,我的博客终于到达了我觉得可以摘掉施工警告的程度。不过我并没有删除原先的站点施工计划,只不过把它移到了这篇日志里。 864 865 *** 施工计划 866 - ☑ +找一家新的服务器提供商+ 目前使用 DigitalOcean 。 867 - ☑ 在服务器上安装 Arch Linux 。 868 - ☑ +搜寻WP的替代品。+ Hugo 很不错。 869 - ☑ +找一个合适的主题。+ 目前使用 =hugo-xmin= ,考虑fork出来写成自己的主题( =soresu= )。 870 - ☑ 完成服务器端设置,比如添加 =post-receive= 来实现 =git= 自动部署。 871 - ☑ 可以切换 *当前页面* 语言版本的语言切换按钮。 872 - ☑ Disqus 支持。 873 - ☑ 用 +MathJax+ KaTeX 实现 \(\LaTeX\) 表达式支持。 874 - ☑ 把导航页的内容搬过来并翻译。 875 - ☑ https 支持。 876 - ☑ 备份原WP站点。 877 - ☑ 转移域名到 Google Domains ,并完成 DNS 设置。 878 - ☑ 尝试使用 =org-mode= 或者 R markdown 来写博客。 879 - ☑ 解决 =emacs= 不兼容 =fcitx= 的问题。 880 - ☑ 设置多语言支持,添加合适的翻译字符串。 881 - ☑ 使用 Google 的 Noto Sans 字体(拉丁字母使用 Oxygen Sans ),代码则使用 +Source Code Pro+ Iosevka 。 882 - ☑ 为站点和社交网站找一个合适的图标/头像。 883 - ☑ 改善文章页面模板使其显示标签和分类。 884 - ☑ 改善网站外观,比如隐藏超链接的下划线等。 885 - ☑ 架设自己的邮箱。 886 - ☑ 解决 =org-mode= 和 =hugo= 略不兼容的地方,比如代码高亮。 887 - ☑ 尝试把 =hugo new= 变得更有用一些,比如直接创建多语言版本等。 888 - ☑ 抛弃 Disqus 自己搭建评论系统。 889 - ☑ 使用 Let's Encrypt 的通配符证书。 890 - ☑ 把比较有价值的旧文章搬过来。 891 892 *** 现在主页上是啥? 893 大部分我觉得别人会感兴趣的有关我的信息都可以在关于或联系方式页面里找到,所以对于主页应该放些什么,我实在没啥好主意。由于我感觉之前的站点施工计划是个提醒自己的不错方式,我会用另外一个任务清单来取代以完成的施工计划:我在 2018 年想实现的目标。我绝对不是那种最有干劲的人,但每每看到一张未完成的任务清单,我的强迫症神经还是会跳一跳的。那么,就让我试试看这么做效果如何吧。