-
Notifications
You must be signed in to change notification settings - Fork 2
/
changelog.page
396 lines (281 loc) · 17.5 KB
/
changelog.page
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
---
title: 网站更新记录
created: 2014-01-23
author: 徐栖
subtitle: 本网站的进化过程
status: in progress
importance: 3
type: rational
tags: site
...
<!-- Status choices are: links, notes, draft, in progress, finished -->
<!-- belief tags are: certain, highly likely, likely, possible, unlikely, highly unlikely, remote, impossible -->
![A banner image: lines of code](images/changelog.png)
## 2017年8月
[内容] 添加 [2017年雨果奖--赢家与落选者们](/2017-hugo)
## 2017年6月
[内容] 添加 [卖鸡蛋仔的阿七](/qi-who-sells-eggballs)。
## 2017年4月
[部署] 回到 Hakyll。使用 Amazon CloudFront 进行内容分发。使用 Amazon 提供的 HTTPS 证书。使用 Circle CI 编译和部署。
`circle.yml` 内容见[链接](https://github.com/celadevra/hakyll-site/blob/master/circle.yml)。需要注意的几点:
* 用 `pip` 安装 `s3cmd`,系统 apt 自带的版本太老,且 `--default-mime-type` 的实现有[问题](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=691547)。
* `s3cmd` 使用时要加 `--no-mime-magic` 参数,否则它的依赖 `python-magic` 会影响对文件类型的判断,例如将 CSS 判为 `text/plain`。
[内容] 添加 [AI, VR and space exploration](/ai-and-space-exploration),[Getting started with ... Stats](/getting-started-with-stats),[Dotfile Management and Documentation with Org-Mode](/dotfile-management)。
## 2016年1月
[内容] 添加 [育儿史小考](/history-of-childrearing)。
[部署] 从 S3 搬到 DigitalOcean,使用 Docker 进行自动编译和部署。
## 2015年11月
[部署] 改用 Circle CI 进行自动编译和部署,并将代码打成 cabal 包。
[内容] 添加 [GnuPG 使用简介](/gpg-intro)。
## 2015年10月
[外观] 改用新的样式表。增加在页边显示脚注的功能。
[部署] 恢复使用 Hakyll 作为网站引擎。继续使用 Amazon S3 作为文件存储。
## 2015年9月
[内容] 添加 [不死者与生者](/story-of-the-undead)。
## 2015年4月
[内容] 添加 [与不理想的世界和解](/make-this-not-true-translation)
[内容] 修订 [read-me](read-me)。
[部署] 改用 ikiwiki 并把 host 搬到 DigitalOcean。
## 2015年1月
[内容] 添加新文章 [But I didn't](/but-i-didnt)。
[内容] 恢复原来的 [Changelog](/changelog)。
## 2014年11月
因为偶然的机会接触到 Asciidoc 这种标记语言,被其强大的描述能力吸引,又因为 Awestruct 对 Asciidoc 支持不错,所以决定将网站生成引擎改成 Awestruct。
[部署] [rbenv](https://github.com/sstephenson/rbenv) 是用于管理 Ruby 版本和环境的软件。它允许不同的项目在不同的 Ruby 版本下运行,每个项目可以有自己的 Gem 配置。
安装方法:
~~~~ {.sh}
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ type rbenv
rbenv is a function # <- 说明 rbenv 安装成功了
rbenv ()
{
local command;
command="$1";
if [ "$#" -gt 0 ]; then
shift;
fi;
case "$command" in
rehash | shell)
eval "`rbenv "sh-$command" "$@"`"
;;
*)
command rbenv "$command" "$@"
;;
esac
}
~~~~
rbenv 本身并不自带安装 Ruby 版本的功能。要直接下载、编译 Ruby 并安装到 rbenv 管理的位置,可以使用同一作者提供的 [ruby-build](https://github.com/sstephenson/ruby-build#readme) 脚本。
~~~~ {.sh}
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
~~~~
因为本目录下已经有 `.ruby-versions` 文件,直接运行 `rbenv install` 命令即可启动 Ruby 的下载和安装。
~~~~ {.sh}
$ gem install bundler
~~~~
在我使用的某台 Gentoo 机器上,执行上述命令报错:
~~~~ {.sh }
/home/snakehsu/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:awestruct-in `require': cannot load such file -- auto_gem (LoadError)
from /home/snakehsu/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
~~~~
在网上简单搜索一下就能得到 [答案](http://liuzhe.tk/note/2013/03/07/gentoo_ruby_error.html),这可能是由于 Gentoo 的 `dev-lang/ruby` 安装过程中会设置 `RUBYOPT=-rauto_gem`( https://logstash.jira.com/browse/LOGSTASH-2221 ),因此需要取消这个设置:
~~~~ {.sh }
unset RUBYOPT; sudo env-update
~~~~
安装 Asciidoctor 和 awestruct:
~~~~ {.sh }
$ rbenv rehash
$ bundle install
~~~~
初始化 awestruct,使用 Foundation 框架:
~~~~ {.sh }
$ awestruct -i -f foundation
$ rake setup # 确保环境变量正确设置
~~~~
修改 `.gitignore`:
~~~~ {.sh }
$ cat >> .gitignore << LINES
/.awestruct/
/.ruby-*
/.sass-cache/
/_site/
/_tmp/
LINES
~~~~
将其他文件加入 git 管理:
~~~~ {.sh }
$ git add .
~~~~
配置 `_config/site.yml`。
添加 `movefiles.rb`,使两个目录下生成的文件直接到站点根目录下。
修改 `_ext/pipeline.rb`,调用 `movefiles.rb` 和优化 URL 的扩展。
修改 `_layouts/base.html.haml`,加入 metadata 的展示。
安装 Asciidoctor Style Factory:
~~~~ {.sh }
$ git submodule add -b embedded-stylesheets \
https://github.com/asciidoctor/asciidoctor-stylesheet-factory.git \
stylesheets/_themes
~~~~
修改 `stylesheet/app.scss` 以使用新的主题。
使用 Foundation 5 框架:
这个没有 Awestruct 的官方支持,因此我修改了 `Gemfile`,安装了 Foundation 的命令行工具,并用它生成一个 `_foundation` 目录,里面有 Foundation 5 框架用到的 SCSS 和 JS 文件。
根据 Awesturct 的 [源代码](https://github.com/awestruct/awestruct/blob/8569e1054923883b3a53336a5dda0fdfe464c5d9/lib/awestruct/engine.rb#L328),Compass 的各种选项可以在 `_config/compass.rb` 中配置。
修改 `stylesheet/app.scss` 中的 `@import` 语句,指向 Foundation 5 的 SCSS 组件路径。
[功能] Highlight.js 支持下的语法高亮:
克隆 Highlight.js 代码库并编译:
~~~~ {.sh }
$ git clone git://github.com/isagalaev/highlight.js.git
$ cd highlight.js
$ node tools/build.js -t browser :common
~~~~
又是 Gentoo 的坑。用 Portage 里自带的 nodejs ebuild 安装 node 和 npm 的话,不会设置 `NODE_PATH` 环境变量,因此要先用 npm 安装编译的依赖:
~~~~ {.sh }
$ sudo npm install -g lodash commander gear del gear-lib
~~~~
然后带上环境变量编译
~~~~ {.sh }
$ NODE_PATH=/usr/lib/node_modules:$NODE_PATH node tools/build.js -t browser :common
~~~~
在 Highlight.js 代码树中 `src/styles` 里挑一个合适的样式,拷到网站的 `stylesheets` 目录下并在模板中加入引用语句。最后将编译生成的 `build/highlight.pack.js` 拷贝到网站代码库中,并修改模板使其能在浏览时加载。
[功能] 参考文献生成
Asciidoctor 支持 `<​<key>>` 格式的引用footnote:[注意,前面的两个小于号之间有一个0宽度空白(U+200B),这是我为了阻止 Asciidoctor 把这个例子也识别成一个真正的 cite key 而添加的,直接复制粘贴会有问题。],参考文献信息则以 `[bibliography]` 块中的列表呈现。我添加了一个 extension,用来从一个 BibTeX 文件中根据正文中的 citation key 生成参考文献(使用 citeproc-ruby 和 bibtex-ruby),并改写正文中的 `[bibliography]` 区块。
~~~~ {.ruby }
require 'citeproc'
require 'csl/styles'
require 'bibtex'
class CitationProcess
def execute(site)
site.pages.each do |page|
bib = site.bib
style = site.csl
cp = CiteProc::Processor.new style: style, format: 'text'
cp.import BibTeX.open(bib).to_citeproc
# get list of cited items
cited = page.raw_content.scan(/<<[\w_:]*>>/).collect {|w| w.gsub!(/[<>]*/, '')}.uniq
biblio = Array.new
unless cited.empty?
cited.each do |key|
ref = cp.render( :bibliography, id: key )
page.raw_content.gsub!(Regexp.new("<<#{key}>>", true), "[#cite-#{key}]*<<#{key}>>*")
entry = ". [[#{key}]]link:#cite-#{key}[[#{key}]] " + ref.join()
biblio << entry
end
page.raw_content.gsub!(/\[bibliography\]/, "[bibliography]" + "\n" + "#{biblio.join("\n")}")
end
end
end
end
~~~~
## 2014年8月--11月
由于 Hakyll 遇到 Cabal 的依赖限制问题,这段时间不能在 Travis CI 上自动部署了,于是开始考虑换平台。先后试用了 Middleman,nanoc,Metalsmith,Gulp.js 等等等等,浪费了不少时间。
## 2014年6月
[部署]增添利用 [Travis CI](https://travis-ci.org/) 的自动部署功能。
最近我的生活和工作方式都发生了一些变化:晚上要带孩子,而且工作中使用 iPad 替代笔记本电脑,不能经常使用 MacBook Pro 上的 git repo 来更新网站了。因此我尝试着用 Travis CI 来自动安装依赖、编译 HTML,并上传到 Amazon S3。
1. Amazon IAM 设置:因为这个配置要把 S3 的访问密钥传到 Travis 的环境中,所以最好是使用 Amazon IAM 生成专门的用户和组并分配权限,这样即使用户的密钥泄露也不会对其他 AWS 的服务产生影响。这个用户或组的访问策略可以这样写:
~~~~ {.json}
{
"Statement": [
{
"Action": [
"s3:ListAllMyBuckets"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::*"
},
{
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl",
"S3:DeleteObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::expoundite.net",
"arn:aws:s3:::expoundite.net/*"
]
}
]
}
~~~~
其中 `s3:PutObjectAcl` 在网上介绍使用 S3 备份的教程中很少提到,我因为需要给文件加上 `public-read` 的 ACL 属性,所以需要这句。
2. `.travis.yml`:这个文件是 Travis CI 工作时需要读取的各种设置和测试步骤的描述文件。我的设置如下:
~~~~ {.yaml}
language: haskell
env:
global:
- secure: DDLQi5WYnCAUhKQNBwq4rBnmYATP/OskewKyEwyw6DymjfBKdH+/enf8rdb8C+eSSJbsTgb3mtDYmgWK7fPTBG6rWLqKayC6CgFTrcG0tEF67KaSLpdk3dtezmlwIcR9jRrI2YqyAmMexoS4MW6zDj4Lv2wqAPGJepdTtbvAOHg=
- secure: McmMItOzZxayXsb0Yl/8/cSwU13Dc2BLEwOCldN9yXKUXgL2wOki1Xv9/tWLiWFcJoEnffYXcFyY3H04UcKPeI+y1KJsbXwf0YF6Uz2SsqkwtcEi4eKUHnRNGOb3biFzhwWzwI+8iibZx6yAREUyggJncIC9q/DGg/FMoXklc50=
branches:
only:
- master
install:
- cabal install hakyll
- sudo apt-get install s3cmd
script:
- ghc --make ./site.hs
- echo "access_key = $AWS_ACCESS_KEY_ID" >> .s3cfg
- echo "secret_key = $AWS_SECRET_ACCESS_KEY" >> .s3cfg
- "./retouch.sh"
- "./site build"
- "./travisupload.sh"
~~~~
其中,`secure:` 后面是使用 Travis 命令行工具加密的 AWS Access Key ID 和 Secret Access Key。获得这两行的方法是
~~~~ {.bash}
$ travis encrypt AWS_ACCESS_KEY_ID="MYKEYID" --add
$ travis encrypt AWS_SECRET_ACCESS_KEY="MYSECRETKEY" --add
~~~~
要注意的是运行前先要确定 `.travis.yml` 里没有之前生成的 `secure` 字段;用双引号把 Amazon 那里拷来的 Key ID 和 Key 包起来是可以的,但一定不要把环境变量的名称也用引号包起来,否则解密后会找不到这两个变量。在测试的步骤中,`echo` 的两行用来把这两个环境变量的值放进 .s3cfg。
3. `.s3cfg`:这是 s3cmd 的设置文件。在本机上先用 `s3cmd --configure` 生成默认的配置,这个过程中 s3cmd 会询问 Key ID 和 Key,填第1步中那个专用用户的即可。测试可以访问 Amazon S3 上的 bucket 后,去掉 `access_key = ...` 和 `secret_key = ...` 这两行,再把它放进 repo 里。
4. 修复文件的修改时间。Travis CI 是使用 Git 的 checkout 命令获取需要测试的代码快照的,这个过程得到的代码文件修改时间都是测试发生当时,这样我的文章的修改时间这个属性就没法用了。在 [`retouch.sh`](https://github.com/celadevra/hakyll-site/blob/master/retouch.sh) 这个文件中,我用文件在代码库中最近一次 commit 的时间作为修改时间,并用 `touch` 命令把文件的修改时间改回去。这一步必须在 Hakyll 开始编译站点前完成。
再加上同步到 S3 的命令,将这些改动 commit 到 master 分支,并在 Travis 里打开与这个代码库的 hook 之后,就可以等 Travis 完成安装编译和上传的全过程了。这样,当 Github 上的 master 分支一有改变,约10分钟后,更新的网站就会自动传到 S3。
## 2014年5月
[内容]添加[关于](/about)页面。
## 2014年4月
[外观]在页脚处增加 Ripple 捐助链接。
[部署]修正联系 email。
[部署]使用[七牛云存储](http://www.qiniu.com/)作为图床。
[内容]增加关于[多因素决策](/multi-factor-decision-making)的文章。
[功能]参考 jtanguy@Github 的实现,增加自动从 bib 文件生成参考文献功能。
[内容]增加关于[电影化游戏](/movie-games)的文章。
## 2014年3月
[内容]添加了关于[理财](/money)的文章。
## 2014年2月
[部署]考虑了成本、可用性等因素后,我决定将网站的内容存储在 Amazon S3 上。和大多数虚拟主机和网页托管服务相比[^nfsn],S3 在网站内容总量小于1G,访问量小于2万 PV 和流量不超过10G时的性价比是无人能敌的,而且也不用担心被攻击和系统日常维护的问题。
因为我采用了生成的 HTML 不带扩展名的方案,所以在上传内容到 S3 的时候出了一些麻烦。S3 收到文件后,会利用扩展名来猜测文件的 MIME type。对于不带扩展名的文件,S3 自动当成 `binary/octet-stream` 类型处理,这样就无法访问 HTML 文件中的内容了。
既然生成 HTML 不带扩展名这个做法是从 Gwern 那里学来的,我就在网上搜索他是如何解决这个问题的。很幸运地,他确实在[一篇讨论贴][gwern-s3cmd]中提及了他的解决方法。和 Gwern 的方法不同的是,s3cmd 从1.0.1版本开始,已经支持用 `--mime-type` 参数设置猜不到 MIME type 时的默认 MIME type。所以上传文件时的命令行这样写就可以:
~~~~ {.bash}
s3cmd sync _site/ s3://haoyangwrit.es
--guess-mime-type
--mime-type 'text/html'
--recursive
--delete-removed
--acl-public
~~~~
此外,在 name.com 久觅域名无果后,我在 domain.com 买了 haoyangwrit.es 这个域名,还比较满意。现已用亚马逊官方提供的方法将域名绑定到了存放网站的 bucket。
由于在 domain.com 注册域名比较麻烦(需要回复 ICANN 发出的确认邮件,而我似乎还没有看到这个东西),我还是回到了熟悉的 name.com,并注册了 expoundite.net 这个域名,S3 上的 bucket 也相应地改变了。name.com 改变 NS 记录的速度非常快,几分钟以后,我已经用上了用 Amazon Route 53 管理的新域名。
[内容]开始了新文件,关于[北京的城市更新](/docs/urban-renewal)。我对这个题目还没有太多概念,但我相信只要进行足够多的思考和阅读,我是可以写出有用的东西来的。
[部署]为了节省 S3 的请求和流量费用,我注册了 [CloudFlare][] 的免费 CDN 服务,而这又要求我继续改变 NS 记录。我已经把 Route 53 上的记录删掉,可以每月节省0.5美元,但因为默认的 TTL 是48小时,此刻我还是在通过原有的 DNS 记录解析域名,也就暂时没有用到 CloudFlare 的功能。
[外观]改善了 figure caption 的显示,现在读者能意识到 figure caption 不是正文的一部分了。
[内容]添加关于个人财务决定的讨论[文章](/docs/money)。
[部署]开始使用 CloudFlare CDN,并利用 CF 的功能添加了 Google Analytics。
[内容]添加两篇旧文章:[城市更新背后的逻辑](/logic-behind-urban-renewal)和[作为工作的研究和作为发现的工作](/non-academia-research)。
[功能]使用国产的多说作为评论系统。
## 2014年1月
[功能]我从 gwern.net 和 Danny Su 的 blog 代码中各抄了一点东西,实现了网站的 RSS 和 tags 页面功能。有一点原创性的工作,就是这个网站虽然采用了和 gwern.net 类似的根据页面更新时间而不是创建时间排列 RSS 项目的功能,但我没有像他那样用 Gitit 里的 module 来实现,而是在 fannesposito.com 的代码基础上重写了 `createdFirst` 这个函数,利用 `System.Directory` module 中的 `getModificationTime` 函数来获取文件的更新时间:
``` {.haskell}
createdFirst :: [Item String] -> Compiler [Item String]
createdFirst items =
let itemsWithTime = unsafeCompiler $ forM items $ \item -> do
utc <- getModificationTime $ toFilePath $ itemIdentifier item
return (utc,item);
in liftM (\xs -> reverse . map snd $ sortBy (comparing fst) xs) itemsWithTime
```
然后用类似调用 Hakyll 自带的 `recentFirst` 函数的方式调用 `createdFirst` 获得前10项最新的更新。
[外观]我仿照 gwern.net 的样式写了个很丑但还算能看的 CSS,并利用 Typeplate 和 normalize.css,搭起了网站基本的样子。
用符号字体改善了导航栏。字体用的是来自 fontsquirrel.com 的 [Entypo](http://www.fontsquirrel.com/fonts/entypo),由 Daniel Bruce 设计,按照 Creative Commons BY-SA v3.0 [许可证](http://creativecommons.org/licenses/by-sa/3.0/)发布。
[gwern-s3cmd]: https://groups.google.com/d/topic/hakyll/XewxMLIjRIw "How to link your own posts?"
[CloudFlare]: http://www.cloudflare.com/ "The web performance and security company"
[^nfsn]: 甚至包括以价格低廉著称的 nearlyfreespeech.net 和 Hostigation。