mirror of
https://github.com/jekyll/jekyll.git
synced 2026-04-28 03:01:03 -04:00
Compare commits
1024 Commits
cache-incl
...
v3.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d842f02b20 | ||
|
|
3dfc0f26e1 | ||
|
|
8e27409029 | ||
|
|
766149cd83 | ||
|
|
f4523cb897 | ||
|
|
805b117238 | ||
|
|
b01b089f69 | ||
|
|
61aff2c547 | ||
|
|
cae8bd31c2 | ||
|
|
ed0c08c7f6 | ||
|
|
1dcb1e9fd7 | ||
|
|
6448c0e6a1 | ||
|
|
2b4a3c008d | ||
|
|
9bc926be3f | ||
|
|
d7dc9d8091 | ||
|
|
6a98ab2a15 | ||
|
|
03d3eb7191 | ||
|
|
f783cc33d6 | ||
|
|
b1f1a5d65f | ||
|
|
7b9e1a8e93 | ||
|
|
1b91e6d89a | ||
|
|
f69c920364 | ||
|
|
5da9333f69 | ||
|
|
fcfc10747f | ||
|
|
c984d8c531 | ||
|
|
eec94cd964 | ||
|
|
e0fb513df4 | ||
|
|
45b40782db | ||
|
|
95f325898f | ||
|
|
1b3cb4515a | ||
|
|
dc14a1ac05 | ||
|
|
55a759357e | ||
|
|
59f80ac371 | ||
|
|
246ff3f9b6 | ||
|
|
294f25b126 | ||
|
|
7678de537c | ||
|
|
5f7df357d4 | ||
|
|
1c515c9789 | ||
|
|
e43db41e80 | ||
|
|
d1cbea8a37 | ||
|
|
4fa7aa2613 | ||
|
|
5e790a6d49 | ||
|
|
455e18624d | ||
|
|
7f1c3d4b7a | ||
|
|
61c8ab662b | ||
|
|
db6103bdee | ||
|
|
6e8fd8cb50 | ||
|
|
bbc2b66a84 | ||
|
|
a0bc843d9f | ||
|
|
b4ae9c6dc6 | ||
|
|
1bfe5a6f95 | ||
|
|
3b42be6e39 | ||
|
|
a5b46821ad | ||
|
|
f5da607792 | ||
|
|
05a982e5bc | ||
|
|
e5279d4773 | ||
|
|
a64a5b9571 | ||
|
|
3a225c2ed6 | ||
|
|
9d1641f163 | ||
|
|
a67adabf98 | ||
|
|
16844d168a | ||
|
|
6e30e177d1 | ||
|
|
121a0471f2 | ||
|
|
e007a14cf1 | ||
|
|
04b2f48bbd | ||
|
|
3b55bd1a51 | ||
|
|
3c60d63f0b | ||
|
|
e6afa6f07a | ||
|
|
48b23858ad | ||
|
|
b50056e8df | ||
|
|
528ec27df0 | ||
|
|
1c4b4ae271 | ||
|
|
0f4aed9ccf | ||
|
|
71f4383d18 | ||
|
|
dfae4669e4 | ||
|
|
a0f3860cfa | ||
|
|
3e5a1af234 | ||
|
|
e5f26b5a36 | ||
|
|
8f5465dfa4 | ||
|
|
86ea57ba58 | ||
|
|
031ff12eaf | ||
|
|
5082e144d8 | ||
|
|
e813e26da4 | ||
|
|
2ca9329a8d | ||
|
|
12225f49ea | ||
|
|
7b81f00137 | ||
|
|
45f69bb8cd | ||
|
|
170d6de8d9 | ||
|
|
f25a4ddfda | ||
|
|
f8dbbb1288 | ||
|
|
e45b6f91e7 | ||
|
|
5e425a99b4 | ||
|
|
7ac05b2b88 | ||
|
|
79c33af3fc | ||
|
|
35ddbe9398 | ||
|
|
05ba1afc29 | ||
|
|
6bcef622f5 | ||
|
|
d6176d6010 | ||
|
|
afd1c21af4 | ||
|
|
2a040fd527 | ||
|
|
ef5e131f53 | ||
|
|
8738a66f9f | ||
|
|
d9b12bc090 | ||
|
|
2e7c471c70 | ||
|
|
74734d46f8 | ||
|
|
7fbe61fc77 | ||
|
|
e9e4a5d21e | ||
|
|
260ad9a3fb | ||
|
|
e58d0ae0ef | ||
|
|
b89f943bf2 | ||
|
|
2f5303dd67 | ||
|
|
58365ae898 | ||
|
|
7330b499f1 | ||
|
|
ae993cbd6a | ||
|
|
c84627b2e1 | ||
|
|
915f8d3eb6 | ||
|
|
36f35bfe00 | ||
|
|
d8f38eef0e | ||
|
|
2cde74c44b | ||
|
|
5d92a90bde | ||
|
|
c2c671641d | ||
|
|
9186345eca | ||
|
|
4e01722941 | ||
|
|
aa9927f073 | ||
|
|
d63acc140d | ||
|
|
62d628c7e0 | ||
|
|
271dc42724 | ||
|
|
ff55da727e | ||
|
|
fb042ef624 | ||
|
|
87f9ed94a9 | ||
|
|
16c0bf8db8 | ||
|
|
18bdfac542 | ||
|
|
14f351fc19 | ||
|
|
d3e4c93163 | ||
|
|
84089f9ebe | ||
|
|
b1125f53de | ||
|
|
20303de60d | ||
|
|
ff504a39ba | ||
|
|
b72556fd03 | ||
|
|
8add5aec4b | ||
|
|
8fec927f83 | ||
|
|
63144fd46d | ||
|
|
7ae044ee44 | ||
|
|
e830e7954c | ||
|
|
8e1dd75312 | ||
|
|
53f975feb4 | ||
|
|
1d9c095b80 | ||
|
|
2410bcc001 | ||
|
|
e7043ac4f3 | ||
|
|
fa2c8d2a96 | ||
|
|
3eb25217ce | ||
|
|
45902b2047 | ||
|
|
611af3f456 | ||
|
|
9b091f8d5d | ||
|
|
6cda306bbf | ||
|
|
bc3e67da62 | ||
|
|
b9bdb85a47 | ||
|
|
4e0a803c01 | ||
|
|
30d82aff5d | ||
|
|
3435d05c2a | ||
|
|
464d4b0254 | ||
|
|
bb9462f12f | ||
|
|
9f4d4bbae0 | ||
|
|
a1fdf830db | ||
|
|
9c9481a8a9 | ||
|
|
ca29e4f585 | ||
|
|
ed7fcf6773 | ||
|
|
25cea4d3d2 | ||
|
|
951c604017 | ||
|
|
269018b011 | ||
|
|
2807b8a012 | ||
|
|
5a765affa3 | ||
|
|
1703b59ce8 | ||
|
|
85b6d936d8 | ||
|
|
abcab4b91f | ||
|
|
e193f5a738 | ||
|
|
51f32502b9 | ||
|
|
c91b622967 | ||
|
|
16eef80539 | ||
|
|
f9925bef2b | ||
|
|
e01c40f575 | ||
|
|
22b59ae793 | ||
|
|
c7bc76269c | ||
|
|
8563f59125 | ||
|
|
1bb8f9cf81 | ||
|
|
38a561a14c | ||
|
|
a82b063d42 | ||
|
|
f3b99ebda7 | ||
|
|
9181d22391 | ||
|
|
bea64a2cf7 | ||
|
|
666df42a28 | ||
|
|
402643435d | ||
|
|
d6b37a1644 | ||
|
|
908bb2e7af | ||
|
|
f1fd89bd8e | ||
|
|
92647c58aa | ||
|
|
b02ae4fad1 | ||
|
|
b732667aea | ||
|
|
1dc2a34252 | ||
|
|
93d282a5c1 | ||
|
|
baafe24e4a | ||
|
|
8ce4ff9060 | ||
|
|
47df90583a | ||
|
|
a7378da16c | ||
|
|
11da2e0d90 | ||
|
|
0340fea808 | ||
|
|
fffb834e63 | ||
|
|
87517af979 | ||
|
|
d35f0a8e16 | ||
|
|
d18d1bc43b | ||
|
|
edcbe99b58 | ||
|
|
f2d31a1b20 | ||
|
|
831eb17b29 | ||
|
|
4169075dd1 | ||
|
|
cd4829d28d | ||
|
|
75007cb26d | ||
|
|
47cb3a8fd7 | ||
|
|
14a5646730 | ||
|
|
7c5eae5ea2 | ||
|
|
1eb1f4ea4d | ||
|
|
12fc4c5ef4 | ||
|
|
34afc7784d | ||
|
|
8927898e1f | ||
|
|
753bdbefbf | ||
|
|
8c509bcf40 | ||
|
|
a446589cdc | ||
|
|
4c1427c400 | ||
|
|
1c767febe5 | ||
|
|
47c9ed0829 | ||
|
|
2db01b9651 | ||
|
|
010038e78a | ||
|
|
44a43b757d | ||
|
|
399606c544 | ||
|
|
8b72f14217 | ||
|
|
63a51df909 | ||
|
|
559cd6c7e7 | ||
|
|
2812341c37 | ||
|
|
ac56e9dd16 | ||
|
|
af3fe0f30d | ||
|
|
571f75ee64 | ||
|
|
d652f6e337 | ||
|
|
aecfe4c160 | ||
|
|
7c8e24a488 | ||
|
|
d1620db235 | ||
|
|
489b9c3639 | ||
|
|
11230718a4 | ||
|
|
7970abebf6 | ||
|
|
1f29e5b5dc | ||
|
|
44f0e5b14a | ||
|
|
d3c327e184 | ||
|
|
a849674f7d | ||
|
|
627af07c3e | ||
|
|
e9b1f6db3d | ||
|
|
585cd268ef | ||
|
|
775645e31c | ||
|
|
86696f6322 | ||
|
|
84ca5780df | ||
|
|
1b88345933 | ||
|
|
76c96fc7ac | ||
|
|
6fee5e3066 | ||
|
|
90586d229c | ||
|
|
b4ac044c29 | ||
|
|
371ca58e69 | ||
|
|
5cfef073a5 | ||
|
|
432ff579d9 | ||
|
|
0b79059310 | ||
|
|
1eba5093bd | ||
|
|
498ad6e83a | ||
|
|
611489aae1 | ||
|
|
14e6809bcd | ||
|
|
7c4f319442 | ||
|
|
3e29aaf785 | ||
|
|
3ab386f1b0 | ||
|
|
8c485155ce | ||
|
|
fe36329004 | ||
|
|
0eee6990d1 | ||
|
|
b0fa2462a6 | ||
|
|
5af105ca71 | ||
|
|
56622c7ab6 | ||
|
|
e164c2194d | ||
|
|
910cab5f84 | ||
|
|
48d6eea9b2 | ||
|
|
dba6df907f | ||
|
|
8bdfdae0ab | ||
|
|
90514b3536 | ||
|
|
eeb6ef46f1 | ||
|
|
32c3089ea9 | ||
|
|
b9f8fc1715 | ||
|
|
f4bbbd6952 | ||
|
|
5bf5c36ce0 | ||
|
|
feb84043dd | ||
|
|
3a49770ce2 | ||
|
|
6d196275fc | ||
|
|
250b6ebb7e | ||
|
|
8c9e9497a2 | ||
|
|
5db3b5d709 | ||
|
|
4dd66e9448 | ||
|
|
0125af80a3 | ||
|
|
2eae07b7d9 | ||
|
|
197dd184f9 | ||
|
|
68c3988861 | ||
|
|
fcb882e791 | ||
|
|
3c656ae2ed | ||
|
|
5647b91689 | ||
|
|
8cecdde288 | ||
|
|
a14f08b2bf | ||
|
|
4b2b5ea8b1 | ||
|
|
d09c4cdf79 | ||
|
|
9c4bf19c71 | ||
|
|
c6ee8a150a | ||
|
|
8b44a7bb42 | ||
|
|
407fc82b2d | ||
|
|
b6e15977de | ||
|
|
32cb87af90 | ||
|
|
137efdc9f4 | ||
|
|
872efb0bcc | ||
|
|
80f63949cd | ||
|
|
649399dcf8 | ||
|
|
83a29e7f4e | ||
|
|
e84a7aadee | ||
|
|
7bc9e1aae6 | ||
|
|
1e9163fdf4 | ||
|
|
6dbb5ac80c | ||
|
|
e9215ec047 | ||
|
|
d2fdac12c2 | ||
|
|
c421a4148a | ||
|
|
f00e217448 | ||
|
|
a134e05fda | ||
|
|
37f373fd38 | ||
|
|
2c0a535801 | ||
|
|
2567c885b0 | ||
|
|
bc806fd2a7 | ||
|
|
bba7870f8b | ||
|
|
bbd32980a1 | ||
|
|
fb716d6b83 | ||
|
|
6f2e3b8238 | ||
|
|
174d2f98ed | ||
|
|
0435871785 | ||
|
|
f04c9bb469 | ||
|
|
e68d18c3cc | ||
|
|
c1d44fc83f | ||
|
|
60bdc7119a | ||
|
|
33fcb0a263 | ||
|
|
f6bc58dd30 | ||
|
|
82bb18176f | ||
|
|
581dee7ba9 | ||
|
|
14ed5cc954 | ||
|
|
981e32d462 | ||
|
|
7a12f32078 | ||
|
|
f6b34f74a9 | ||
|
|
a2ee820609 | ||
|
|
87400f2155 | ||
|
|
376c87b62e | ||
|
|
73db98c244 | ||
|
|
d99f257665 | ||
|
|
b75fb37b4e | ||
|
|
3151aacbad | ||
|
|
498ea4fd24 | ||
|
|
f764ae6a76 | ||
|
|
06777a51c8 | ||
|
|
3474481043 | ||
|
|
5928618de1 | ||
|
|
87829b3da1 | ||
|
|
c61a5adb05 | ||
|
|
d063e6abe7 | ||
|
|
8bb7861162 | ||
|
|
ae11cae659 | ||
|
|
e4e14e8860 | ||
|
|
35a7d94202 | ||
|
|
ee666e319b | ||
|
|
0f447751be | ||
|
|
f054bae503 | ||
|
|
4a0a3dbf39 | ||
|
|
8a289793bb | ||
|
|
60a811d405 | ||
|
|
b90f6f77e8 | ||
|
|
15c4d9bee2 | ||
|
|
b69eaa34dd | ||
|
|
221c0b62b6 | ||
|
|
ba12d28fbe | ||
|
|
f34a00490f | ||
|
|
ce9fcfaebb | ||
|
|
e68609c849 | ||
|
|
5acac3561a | ||
|
|
2b9ce826d6 | ||
|
|
9c5c9d826a | ||
|
|
56c38f87b2 | ||
|
|
f99abc5314 | ||
|
|
015e9570cd | ||
|
|
3b48dd2652 | ||
|
|
46895b46a6 | ||
|
|
cd912b5233 | ||
|
|
b1e984128e | ||
|
|
c19ad411a4 | ||
|
|
a1d78cdea6 | ||
|
|
4b038259c7 | ||
|
|
79a178f7f1 | ||
|
|
736e6a78f1 | ||
|
|
245d9677d7 | ||
|
|
6ca9633354 | ||
|
|
ae584e43ed | ||
|
|
51adebd0db | ||
|
|
95a30fa51d | ||
|
|
f5351f7268 | ||
|
|
bd25c62f55 | ||
|
|
cf778e2be6 | ||
|
|
bda515bfc7 | ||
|
|
e5bbdb1c83 | ||
|
|
6a26907495 | ||
|
|
8546298047 | ||
|
|
eab92d3b96 | ||
|
|
d3e867d4a0 | ||
|
|
ee7f7baef2 | ||
|
|
4e34d2627b | ||
|
|
9ab3c201c8 | ||
|
|
786f6e1985 | ||
|
|
6597bacee8 | ||
|
|
e93e49c269 | ||
|
|
166fdf35a3 | ||
|
|
159dbd0170 | ||
|
|
bac28fcfce | ||
|
|
987309917a | ||
|
|
76c1dcc791 | ||
|
|
7be47c2c48 | ||
|
|
c59d02d6c6 | ||
|
|
6ce345be59 | ||
|
|
095736b5ef | ||
|
|
791b2eccf6 | ||
|
|
4302604c89 | ||
|
|
269662d0f0 | ||
|
|
9c03fc3f27 | ||
|
|
f908051aa4 | ||
|
|
80a921ccfd | ||
|
|
ab83f0bf2e | ||
|
|
701617cb0e | ||
|
|
e3ab992f75 | ||
|
|
a682ca1600 | ||
|
|
fff7bb31f5 | ||
|
|
0072865512 | ||
|
|
da80240fac | ||
|
|
3aaa889218 | ||
|
|
f26cdd8da4 | ||
|
|
00aa2955d8 | ||
|
|
dead70724e | ||
|
|
d15e4a9c8a | ||
|
|
ff3edbc16b | ||
|
|
68907ab833 | ||
|
|
7d3a5f82be | ||
|
|
5a60adb6bd | ||
|
|
4f06ba7884 | ||
|
|
ae039663b9 | ||
|
|
6dcdf06c8a | ||
|
|
e19d6c3f7e | ||
|
|
62cfd45d79 | ||
|
|
ab35d32feb | ||
|
|
d870dfedee | ||
|
|
c916f08aa3 | ||
|
|
059c7c6adf | ||
|
|
7126792d85 | ||
|
|
f645cd3377 | ||
|
|
b718d4ea46 | ||
|
|
ec90210ed4 | ||
|
|
9e86650df2 | ||
|
|
53ca3446eb | ||
|
|
c76c4e478b | ||
|
|
25af3e785f | ||
|
|
0374ad2668 | ||
|
|
66a9e6909b | ||
|
|
2f75ade1b7 | ||
|
|
1b5977c018 | ||
|
|
4b108df3ab | ||
|
|
279fb6af11 | ||
|
|
2c316188fe | ||
|
|
20d48fcfe9 | ||
|
|
70a3156385 | ||
|
|
bf98004843 | ||
|
|
436c98ad9b | ||
|
|
12b16dde52 | ||
|
|
9f55b1ff66 | ||
|
|
eeb13872e3 | ||
|
|
f14af82da5 | ||
|
|
b6ea045e1b | ||
|
|
6d6c15eba2 | ||
|
|
a91775fcfe | ||
|
|
2c373e6fe9 | ||
|
|
f86727c45a | ||
|
|
76416e50e8 | ||
|
|
90793b12e7 | ||
|
|
9c02353b3c | ||
|
|
329ed07405 | ||
|
|
305a22a5bf | ||
|
|
a9dbb0de57 | ||
|
|
28a1d2445e | ||
|
|
f0cac685de | ||
|
|
0e52b83b6f | ||
|
|
1ac7f5cb15 | ||
|
|
397492fa38 | ||
|
|
fa435fae94 | ||
|
|
b2aa8b6e68 | ||
|
|
f75346c799 | ||
|
|
ec7474f55c | ||
|
|
799edabc3d | ||
|
|
6d3fc08a40 | ||
|
|
e82cb3115d | ||
|
|
ebc6dff37e | ||
|
|
017a26457c | ||
|
|
18209ff78c | ||
|
|
d10c46d4fd | ||
|
|
391a672ac4 | ||
|
|
86211a020d | ||
|
|
c6dce1660b | ||
|
|
1f8157022a | ||
|
|
d67ad64335 | ||
|
|
44b13f408e | ||
|
|
d98047ef74 | ||
|
|
8f4194eea5 | ||
|
|
a95b861d69 | ||
|
|
dc617767b3 | ||
|
|
cc3ee868f4 | ||
|
|
407eda8e83 | ||
|
|
e7d0b6c5a5 | ||
|
|
1503ccce7d | ||
|
|
5a702bfe13 | ||
|
|
5960069cd0 | ||
|
|
3a85aa0dac | ||
|
|
dfb5a2f2fc | ||
|
|
55c890f73a | ||
|
|
d39d0cea19 | ||
|
|
d4b8f0d9dd | ||
|
|
f635f3d34b | ||
|
|
db0e1a683c | ||
|
|
eea4a82dc6 | ||
|
|
334cc5a6ea | ||
|
|
e91527058a | ||
|
|
706007ead9 | ||
|
|
fa3a912e89 | ||
|
|
88d9cf4816 | ||
|
|
27d3efecc1 | ||
|
|
ed3fe2e2b4 | ||
|
|
75afac9bc0 | ||
|
|
7edde72523 | ||
|
|
a7dff06175 | ||
|
|
a8b7a224c8 | ||
|
|
6e3bba154c | ||
|
|
a5b9df7287 | ||
|
|
4ef30b3a6f | ||
|
|
f30dba8883 | ||
|
|
780755a8a5 | ||
|
|
2bcfdb9662 | ||
|
|
80bd6d311d | ||
|
|
99a9e0a74d | ||
|
|
8d54eb8f6b | ||
|
|
77a381c542 | ||
|
|
55392fd8d2 | ||
|
|
7630f5408c | ||
|
|
b647037643 | ||
|
|
8d1f8ee7a0 | ||
|
|
63a1ec8949 | ||
|
|
d9958de9d1 | ||
|
|
e82eaa4b0f | ||
|
|
e770a080a7 | ||
|
|
324748a5a6 | ||
|
|
15ebf929e1 | ||
|
|
c96062781d | ||
|
|
adce349d7a | ||
|
|
e268ee0f33 | ||
|
|
b02342312b | ||
|
|
06c4b42a5a | ||
|
|
6988eea9ce | ||
|
|
333b9f5f93 | ||
|
|
6d20525dce | ||
|
|
16a2cfed49 | ||
|
|
767c18e93b | ||
|
|
4835e9317a | ||
|
|
c83b016219 | ||
|
|
778429c6cc | ||
|
|
eb2fc89776 | ||
|
|
fccc02be6f | ||
|
|
506a1db116 | ||
|
|
6a387b45aa | ||
|
|
bb57c80478 | ||
|
|
b6424c9197 | ||
|
|
6a66a3af5a | ||
|
|
10967d8904 | ||
|
|
3c9e43eb36 | ||
|
|
0ca5bd3224 | ||
|
|
0d288c54da | ||
|
|
41fb36a36f | ||
|
|
c6d62828ba | ||
|
|
29853ab46d | ||
|
|
f4a14b60ba | ||
|
|
045f38d467 | ||
|
|
00093b91fa | ||
|
|
2d0d27da73 | ||
|
|
7d93e3fdcd | ||
|
|
d3bd81361c | ||
|
|
06785f2bfd | ||
|
|
d36c3b0073 | ||
|
|
eb064b6684 | ||
|
|
d3e23c2fae | ||
|
|
59add4737b | ||
|
|
b5a73373ff | ||
|
|
dac2b17123 | ||
|
|
007c059315 | ||
|
|
7a7ecbadea | ||
|
|
0d96ad21d2 | ||
|
|
3a3b528014 | ||
|
|
1100ca0782 | ||
|
|
0e10503259 | ||
|
|
9021e98721 | ||
|
|
67ba8ad0cb | ||
|
|
269bcbb7a8 | ||
|
|
50a41100e7 | ||
|
|
b178358cf9 | ||
|
|
00cdcbc184 | ||
|
|
bebd80342e | ||
|
|
013f7edc83 | ||
|
|
c371926e09 | ||
|
|
66785b43ba | ||
|
|
6d9258bcdc | ||
|
|
6b4219f0e2 | ||
|
|
bb4d47b905 | ||
|
|
b41ddbb8a9 | ||
|
|
02e98f238e | ||
|
|
2185339ee0 | ||
|
|
3a4d826852 | ||
|
|
4a89db2102 | ||
|
|
4b8e3cfdbd | ||
|
|
7806f9ed52 | ||
|
|
489da6784a | ||
|
|
117bd8a6f0 | ||
|
|
e229e3285f | ||
|
|
a608494e18 | ||
|
|
f6f2626828 | ||
|
|
252665ddc6 | ||
|
|
51dc0dfcf5 | ||
|
|
c8d23ffee2 | ||
|
|
ced9146c11 | ||
|
|
ca7375a51b | ||
|
|
9e1cb96a7e | ||
|
|
c1562c8997 | ||
|
|
7114380da7 | ||
|
|
1b796354fb | ||
|
|
f252a82afc | ||
|
|
2f88a0c0a1 | ||
|
|
2857350df1 | ||
|
|
9bcad08e3a | ||
|
|
a4adeb446b | ||
|
|
504c9a34ad | ||
|
|
29169aa858 | ||
|
|
67a2369854 | ||
|
|
537235c38b | ||
|
|
5b0e2a294d | ||
|
|
e586105b46 | ||
|
|
ddfecb0f53 | ||
|
|
6e06fd8734 | ||
|
|
05bbcddb29 | ||
|
|
c836ec613d | ||
|
|
bb9d43dff5 | ||
|
|
0d1586a5c4 | ||
|
|
2ef9bae75a | ||
|
|
fa31fcb3bf | ||
|
|
d40b6d6ee0 | ||
|
|
5e9b7343bf | ||
|
|
5d1a24e291 | ||
|
|
d56df7592c | ||
|
|
669c803912 | ||
|
|
8917ef011c | ||
|
|
27a02e163b | ||
|
|
7a31029c79 | ||
|
|
48bf711ec7 | ||
|
|
b3371119fd | ||
|
|
dae5d30096 | ||
|
|
bc2b87ca92 | ||
|
|
f251848283 | ||
|
|
2b1b7b977b | ||
|
|
c2b613d05e | ||
|
|
5ee4e6d9c9 | ||
|
|
92a9582733 | ||
|
|
78af3c5018 | ||
|
|
0565308ce6 | ||
|
|
9437bd4669 | ||
|
|
9b962dc565 | ||
|
|
f1edf9e692 | ||
|
|
fbe52bca85 | ||
|
|
60f0977a50 | ||
|
|
7d6d29b4ca | ||
|
|
6b09d1818d | ||
|
|
50a4b2824b | ||
|
|
6c073ec476 | ||
|
|
8e87e9ebec | ||
|
|
e777c9b213 | ||
|
|
d79c0fc4dd | ||
|
|
dae77e9a63 | ||
|
|
e4b1382bfd | ||
|
|
cd7b3f54f1 | ||
|
|
a25f2d7dd6 | ||
|
|
ed953e6e1f | ||
|
|
5a84d1960e | ||
|
|
e56f2414ae | ||
|
|
531d0fb261 | ||
|
|
14fa3287b7 | ||
|
|
8997212222 | ||
|
|
a621752425 | ||
|
|
90c974c4e2 | ||
|
|
3f3b203992 | ||
|
|
4da6bfd81a | ||
|
|
21fa47f92b | ||
|
|
03d21b0cd1 | ||
|
|
c1f7684b92 | ||
|
|
7fb71871cf | ||
|
|
b75db477e0 | ||
|
|
9e0bad7255 | ||
|
|
bebb75ff0e | ||
|
|
a43d3d1dc8 | ||
|
|
5d97ec9174 | ||
|
|
929d18fefc | ||
|
|
422fd7d304 | ||
|
|
a4db7ec63c | ||
|
|
e2306ed79b | ||
|
|
13f8227877 | ||
|
|
5c388309b2 | ||
|
|
faa5a446ba | ||
|
|
0903515c39 | ||
|
|
6cc298d615 | ||
|
|
7a93ca6f6c | ||
|
|
1923fc39df | ||
|
|
e888a41b2d | ||
|
|
6bc3dee98d | ||
|
|
7db9397a9d | ||
|
|
ae244c4425 | ||
|
|
c40272cebd | ||
|
|
26acb3f9d9 | ||
|
|
7ad0597bff | ||
|
|
ace1b6b8d2 | ||
|
|
52c4ce2a5a | ||
|
|
8186873e27 | ||
|
|
4b59eb4175 | ||
|
|
d2b19963c1 | ||
|
|
47ee5db5fc | ||
|
|
3e030ea784 | ||
|
|
e240bbb1bf | ||
|
|
04430b2c17 | ||
|
|
80f64dea89 | ||
|
|
29534469c3 | ||
|
|
705fdfb23d | ||
|
|
cd1326d457 | ||
|
|
1beee0d59d | ||
|
|
4d0cb3345f | ||
|
|
9a0db42436 | ||
|
|
dbead70168 | ||
|
|
e9638fa6a2 | ||
|
|
9caa47d164 | ||
|
|
05dc4df7e4 | ||
|
|
7fb3b096c3 | ||
|
|
32cc745142 | ||
|
|
17e4c8ab42 | ||
|
|
5fa1aadf7f | ||
|
|
edb50b81a3 | ||
|
|
a2bf106c47 | ||
|
|
ae0b13b531 | ||
|
|
f2696c1c4c | ||
|
|
ac7c1d0cd6 | ||
|
|
e81b020d7e | ||
|
|
9f22749ebb | ||
|
|
6e89c1c02b | ||
|
|
fa6981fb8c | ||
|
|
5f38430304 | ||
|
|
22759edf3e | ||
|
|
00ec13c11b | ||
|
|
9b50fc9f3b | ||
|
|
58dc1f77e9 | ||
|
|
461ea2f147 | ||
|
|
30b42c4700 | ||
|
|
c6d5a913f1 | ||
|
|
712d8d617d | ||
|
|
7c9ad82b2a | ||
|
|
491cce7a99 | ||
|
|
e99a9e5821 | ||
|
|
249249f76b | ||
|
|
0d602018bd | ||
|
|
a907addbe2 | ||
|
|
7a5a90de82 | ||
|
|
a64b7e7a62 | ||
|
|
f933164a2a | ||
|
|
0914948099 | ||
|
|
c96abf7e82 | ||
|
|
8fe9561f64 | ||
|
|
83ad59841b | ||
|
|
33c3b41f69 | ||
|
|
c08c794801 | ||
|
|
b81f6ed38c | ||
|
|
1f503b24b3 | ||
|
|
bf149a0b97 | ||
|
|
a0134dea4f | ||
|
|
c625b94bc0 | ||
|
|
72e297366d | ||
|
|
11b38568fa | ||
|
|
4ce60741d9 | ||
|
|
56102ce50c | ||
|
|
4d20462da5 | ||
|
|
571800c8ad | ||
|
|
d795113e94 | ||
|
|
dbc8530068 | ||
|
|
90370c0d0b | ||
|
|
dc9db9cbe2 | ||
|
|
bee4d93114 | ||
|
|
7858f80823 | ||
|
|
2b95fb924e | ||
|
|
ea9b959c23 | ||
|
|
a87bf521c8 | ||
|
|
20bfdbb794 | ||
|
|
6a74c09185 | ||
|
|
943070aac6 | ||
|
|
1fa428c6e4 | ||
|
|
fdc0e33ebc | ||
|
|
aec5ceb184 | ||
|
|
6d4a1ec4e6 | ||
|
|
e3d2578230 | ||
|
|
fbb766becc | ||
|
|
85a89d3e22 | ||
|
|
1df8801957 | ||
|
|
7abc8c8025 | ||
|
|
77216b61dc | ||
|
|
4f078ee2e8 | ||
|
|
6521b84aac | ||
|
|
120d3e07ca | ||
|
|
0bf17923b5 | ||
|
|
5e541b5eb0 | ||
|
|
128427cc87 | ||
|
|
2bec317a2a | ||
|
|
2745be736e | ||
|
|
32c48bb78d | ||
|
|
d24ea66933 | ||
|
|
e71c23981d | ||
|
|
403aade8c1 | ||
|
|
8e1b9fcdf5 | ||
|
|
c8602d7af7 | ||
|
|
9e717a61e7 | ||
|
|
9ba9c47cd6 | ||
|
|
8f9d3c9647 | ||
|
|
9815a7b0ee | ||
|
|
8da7d1a5bc | ||
|
|
0154c580cd | ||
|
|
3318c38eec | ||
|
|
f55eb1f3fb | ||
|
|
3d843d81e6 | ||
|
|
a87cda4b12 | ||
|
|
65d43ef398 | ||
|
|
057b8cae7f | ||
|
|
336bb44750 | ||
|
|
18e0d2fe75 | ||
|
|
63792ad322 | ||
|
|
6883a0b397 | ||
|
|
922a92d67a | ||
|
|
ec397e1629 | ||
|
|
ec7d2ed5b6 | ||
|
|
aceb5b5d53 | ||
|
|
32a2e8b4ef | ||
|
|
9f4aeaddea | ||
|
|
a2b19c1d2b | ||
|
|
01f7b9ccef | ||
|
|
c6166ab485 | ||
|
|
18893b828b | ||
|
|
3bac8a2034 | ||
|
|
51d8d5e267 | ||
|
|
0c624eb11b | ||
|
|
b100b3b121 | ||
|
|
e2e6e7dc22 | ||
|
|
dcd3dafdbc | ||
|
|
fe08405ae1 | ||
|
|
bfe28cbead | ||
|
|
63bca94bde | ||
|
|
e1e60499b1 | ||
|
|
ff646738fc | ||
|
|
aa44c7f53d | ||
|
|
368b862ebb | ||
|
|
69e8f1923c | ||
|
|
5e0341c9b3 | ||
|
|
382c54e057 | ||
|
|
3e609b1cd9 | ||
|
|
97797cb241 | ||
|
|
31b03e9b86 | ||
|
|
317e2f460e | ||
|
|
980dbdbcc4 | ||
|
|
a94ffd8eb9 | ||
|
|
d20df4120d | ||
|
|
b360154973 | ||
|
|
4bcb0a322c | ||
|
|
ef54bfe5a1 | ||
|
|
cecd974d8e | ||
|
|
3be90c7822 | ||
|
|
d2c717c3c6 | ||
|
|
ef426cd490 | ||
|
|
053ba68a15 | ||
|
|
51e2cb3629 | ||
|
|
b951696114 | ||
|
|
5d750f5a71 | ||
|
|
5ed24cfd71 | ||
|
|
88348ae0ee | ||
|
|
c4255ebc58 | ||
|
|
53a59544e8 | ||
|
|
018f333973 | ||
|
|
c2f0b9a799 | ||
|
|
58e231ce40 | ||
|
|
29aabd84bd | ||
|
|
90eecc5da6 | ||
|
|
3d60299ea9 | ||
|
|
382049d558 | ||
|
|
fe5f0d124c | ||
|
|
589919d58a | ||
|
|
e58f8776b9 | ||
|
|
c378f741a8 | ||
|
|
6f440f55e0 | ||
|
|
cbe5f8e4dd | ||
|
|
dec27bc166 | ||
|
|
2b29e09177 | ||
|
|
9d547f74cc | ||
|
|
c1da91cf5c | ||
|
|
877cba9811 | ||
|
|
2547d8adf3 | ||
|
|
091e86aa22 | ||
|
|
f11837dd7b | ||
|
|
d28fb07bb9 | ||
|
|
aaf0ba15cc | ||
|
|
ef2d558874 | ||
|
|
f7271a6ef9 | ||
|
|
10659e1eef | ||
|
|
aaea08e094 | ||
|
|
6081fcd75a | ||
|
|
18fb1bafa0 | ||
|
|
cf2f439db1 | ||
|
|
87500addd5 | ||
|
|
5868ba1691 | ||
|
|
3fe80929ad | ||
|
|
57b43e2229 | ||
|
|
b2099ac763 | ||
|
|
c7d92c4e6d | ||
|
|
7f44500b4b | ||
|
|
6d9b4c2aba | ||
|
|
1715956baa | ||
|
|
a312115a5a | ||
|
|
3d69582d36 | ||
|
|
84cfc1ceff | ||
|
|
153db8a230 | ||
|
|
18f3d76603 | ||
|
|
8692822631 | ||
|
|
07ccbd9fac | ||
|
|
1fc3887d4f | ||
|
|
ba2e1390ad | ||
|
|
a1ea8b9798 | ||
|
|
f5fbf4ffd1 | ||
|
|
02aa2a1c33 | ||
|
|
60da4ef010 | ||
|
|
b1fd7377fd | ||
|
|
5d6fe236b2 | ||
|
|
3cb0f4f590 | ||
|
|
2547df81a1 | ||
|
|
8e7d40ed90 | ||
|
|
99ae1023b4 | ||
|
|
59e1e2dd84 | ||
|
|
ce78ea7818 | ||
|
|
b2e114ed5b | ||
|
|
06b6e86d52 | ||
|
|
5b50687e22 | ||
|
|
763118a381 | ||
|
|
80465efff7 | ||
|
|
588bba39ad | ||
|
|
936c737a32 | ||
|
|
b31d8a1ecd | ||
|
|
e13c800b3a | ||
|
|
e724622a92 | ||
|
|
e378b2efd3 | ||
|
|
12cbfa8cf4 | ||
|
|
aedff733e0 | ||
|
|
fa7d4cde67 | ||
|
|
7be49c99c1 | ||
|
|
d2b33144a7 | ||
|
|
60921132c6 | ||
|
|
e7dcc2424a | ||
|
|
7439d303c4 | ||
|
|
e7feae98f5 | ||
|
|
c26f040bcf | ||
|
|
5e9706e2aa | ||
|
|
965e3a1173 | ||
|
|
09230cde50 | ||
|
|
312717b56d | ||
|
|
f228b31c2e | ||
|
|
244310fbaa | ||
|
|
6816b5ea76 | ||
|
|
7c8e4d46eb | ||
|
|
585a31d8aa | ||
|
|
e2a5a9dbc1 | ||
|
|
f2650e7b0f | ||
|
|
8b6a9d66ec | ||
|
|
0bf82e9cf7 | ||
|
|
4e9b0663be | ||
|
|
b9542c5426 | ||
|
|
0a4bd99e6b | ||
|
|
5536f950f9 | ||
|
|
989639256d | ||
|
|
9a52d56b5a | ||
|
|
a6238c36d5 | ||
|
|
730aedd0a3 | ||
|
|
4cbd814546 | ||
|
|
cae9d96cc4 | ||
|
|
8a9c48c7b4 | ||
|
|
faccf8f802 | ||
|
|
a0f2b5f944 | ||
|
|
bce4680182 | ||
|
|
b92274b101 | ||
|
|
e7c0e313a3 | ||
|
|
54d0bf47e8 | ||
|
|
b6c197d312 | ||
|
|
1062fdf89f | ||
|
|
a2b6aa263e | ||
|
|
004f923644 | ||
|
|
d7e3d4df8f | ||
|
|
ae57f693e4 | ||
|
|
3c5e9f5334 | ||
|
|
46e76bde3f | ||
|
|
3b7091aab7 | ||
|
|
c8d1c3d264 | ||
|
|
3768d90278 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -12,6 +12,9 @@ gh-pages/
|
||||
site/_site/
|
||||
coverage
|
||||
.ruby-version
|
||||
.ruby-gemset
|
||||
.sass-cache
|
||||
tmp/stackprof-*
|
||||
tmp/*
|
||||
.jekyll-metadata
|
||||
/vendor
|
||||
/test/source/file_name.txt
|
||||
|
||||
6
.jrubyrc
Normal file
6
.jrubyrc
Normal file
@@ -0,0 +1,6 @@
|
||||
backtrace.mask=true
|
||||
compile.invokedynamic=true
|
||||
objectspace.enabled=true
|
||||
backtrace.color=true
|
||||
compat.version=2.2
|
||||
backtrace.style=mri
|
||||
17
.travis.yml
17
.travis.yml
@@ -5,10 +5,19 @@ rvm:
|
||||
- 2.2
|
||||
- 2.1
|
||||
- 2.0
|
||||
- ruby-head
|
||||
- jruby-9.0.3.0
|
||||
matrix:
|
||||
allow_failures:
|
||||
- rvm: ruby-head
|
||||
- rvm: jruby-9.0.3.0
|
||||
exclude:
|
||||
- rvm: jruby-9.0.3.0
|
||||
env: TEST_SUITE=cucumber
|
||||
env:
|
||||
matrix:
|
||||
- TEST_SUITE=test
|
||||
- TEST_SUITE=cucumber
|
||||
- TEST_SUITE=test
|
||||
- TEST_SUITE=cucumber
|
||||
before_script: bundle update
|
||||
script: script/cibuild
|
||||
notifications:
|
||||
@@ -16,9 +25,9 @@ notifications:
|
||||
on_success: change
|
||||
on_failure: change
|
||||
channels:
|
||||
- irc.freenode.org#jekyll
|
||||
- irc.freenode.org#jekyll
|
||||
template:
|
||||
- "%{repository}#%{build_number} (%{branch}) %{message} %{build_url}"
|
||||
- "%{repository}#%{build_number} (%{branch}) %{message} %{build_url}"
|
||||
email:
|
||||
on_success: never
|
||||
on_failure: never
|
||||
|
||||
22
CONDUCT.md
Normal file
22
CONDUCT.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
||||
@@ -4,18 +4,19 @@ Contribute
|
||||
So you've got an awesome idea to throw into Jekyll. Great! Please keep the
|
||||
following in mind:
|
||||
|
||||
* **Use https://talk.jekyllrb.com for non-technical or indirect Jekyll questions that are not bugs.**
|
||||
* **Contributions will not be accepted without tests or necessary documentation updates.**
|
||||
* If you're creating a small fix or patch to an existing feature, just a simple
|
||||
test will do. Please stay in the confines of the current test suite and use
|
||||
[Shoulda](https://github.com/thoughtbot/shoulda/tree/master) and
|
||||
[RR](https://github.com/rr/rr).
|
||||
[RSpec-Mocks](https://github.com/rspec/rspec-mocks).
|
||||
* If it's a brand new feature, make sure to create a new
|
||||
[Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
|
||||
where appropriate. Also, whipping up some documentation in your fork's `site`
|
||||
would be appreciated, and once merged it will be transferred over to the main
|
||||
`site`, jekyllrb.com.
|
||||
* If your contribution changes any Jekyll behavior, make sure to update the
|
||||
documentation. It lives in `site/docs`. If the docs are missing information,
|
||||
documentation. It lives in `site/_docs`. If the docs are missing information,
|
||||
please feel free to add it in. Great docs make a great project!
|
||||
* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
||||
when modifying Ruby code.
|
||||
@@ -30,16 +31,25 @@ Test Dependencies
|
||||
-----------------
|
||||
|
||||
To run the test suite and build the gem you'll need to install Jekyll's
|
||||
dependencies. Jekyll uses Bundler, so a quick run of the bundle command and
|
||||
you're all set!
|
||||
dependencies. Simply run this command to get all setup:
|
||||
|
||||
$ bundle
|
||||
$ script/bootstrap
|
||||
|
||||
Before you start, run the tests and make sure that they pass (to confirm your
|
||||
environment is configured properly):
|
||||
|
||||
$ bundle exec rake test
|
||||
$ bundle exec rake features
|
||||
$ script/cibuild
|
||||
|
||||
If you are only updating a file in `test/`, you can use the command:
|
||||
|
||||
$ script/test test/blah_test.rb
|
||||
|
||||
If you are only updating a `.feature` file, you can use the command:
|
||||
|
||||
$ script/cucumber features/blah.feature
|
||||
|
||||
Both `script/test` and `script/cucumber` can be run without arguments to
|
||||
run its entire respective suite.
|
||||
|
||||
Workflow
|
||||
--------
|
||||
@@ -47,10 +57,10 @@ Workflow
|
||||
Here's the most direct way to get your work merged into the project:
|
||||
|
||||
* Fork the project.
|
||||
* Clone down your fork ( `git clone git@github.com:<username>/jekyll.git` ).
|
||||
* Clone down your fork ( `git clone git@github.com:[username]/jekyll.git` ).
|
||||
* Create a topic branch to contain your change ( `git checkout -b my_awesome_feature` ).
|
||||
* Hack away, add tests. Not necessarily in that order.
|
||||
* Make sure everything still passes by running `rake`.
|
||||
* Make sure everything still passes by running `script/cibuild`.
|
||||
* If necessary, rebase your commits into logical chunks, without errors.
|
||||
* Push the branch up ( `git push origin my_awesome_feature` ).
|
||||
* Create a pull request against jekyll/jekyll and describe what your change
|
||||
@@ -67,17 +77,22 @@ You can find the documentation for jekyllrb.com in the
|
||||
[site](https://github.com/jekyll/jekyll/tree/master/site) directory of
|
||||
Jekyll's repo on GitHub.com.
|
||||
|
||||
All documentation pull requests should be directed at `master`. Pull
|
||||
All documentation pull requests should be directed at `master`. Pull
|
||||
requests directed at another branch will not be accepted.
|
||||
|
||||
The [Jekyll wiki](https://github.com/jekyll/jekyll/wiki) on GitHub
|
||||
can be freely updated without a pull request as all GitHub users have access.
|
||||
|
||||
If you want to add your plugin to the
|
||||
[list of plugins](http://jekyllrb.com/docs/plugins/#available-plugins),
|
||||
please submit a pull request modifying the
|
||||
[plugins page source file](site/_docs/plugins.md) by adding a
|
||||
link to your plugin under the proper subheading depending upon its type.
|
||||
|
||||
Gotchas
|
||||
-------
|
||||
|
||||
* If you want to bump the gem version, please put that in a separate commit.
|
||||
This way, the maintainers can control when the gem gets released.
|
||||
* Please do not bump the gem version in your pull requests.
|
||||
* Try to keep your patch(es) based from the latest commit on jekyll/jekyll.
|
||||
The easier it is to apply your work, the less work the maintainers have to do,
|
||||
which is always a good thing.
|
||||
|
||||
75
Gemfile
75
Gemfile
@@ -1,28 +1,55 @@
|
||||
source 'https://rubygems.org'
|
||||
gemspec
|
||||
gemspec name: 'jekyll'
|
||||
|
||||
gem 'rake', '~> 10.1'
|
||||
gem 'rdoc', '~> 3.11'
|
||||
gem 'redgreen', '~> 1.2'
|
||||
gem 'shoulda', '~> 3.5'
|
||||
gem 'rr', '~> 1.1'
|
||||
gem 'cucumber', '1.3.18'
|
||||
gem 'RedCloth', '~> 4.2'
|
||||
gem 'maruku', '~> 0.7.0'
|
||||
gem 'rdiscount', '~> 1.6'
|
||||
gem 'launchy', '~> 2.3'
|
||||
gem 'simplecov', '~> 0.9'
|
||||
gem 'simplecov-gem-adapter', '~> 1.0.1'
|
||||
gem 'mime-types', '~> 1.5'
|
||||
gem 'activesupport', '~> 3.2.13'
|
||||
gem 'jekyll_test_plugin'
|
||||
gem 'jekyll_test_plugin_malicious'
|
||||
gem 'rouge', '~> 1.7'
|
||||
gem 'liquid-c', '~> 0.0.3'
|
||||
gem 'minitest' if RUBY_PLATFORM =~ /cygwin/
|
||||
gem 'test-unit' if RUBY_PLATFORM =~ /cygwin/ || RUBY_VERSION.start_with?("2.2")
|
||||
|
||||
if ENV['BENCHMARK']
|
||||
gem 'rbtrace'
|
||||
gem 'stackprof'
|
||||
group :development do
|
||||
gem 'rdoc', '~> 4.2'
|
||||
gem 'launchy', '~> 2.3'
|
||||
gem 'toml', '~> 0.1.0'
|
||||
gem 'pry'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'redgreen', '~> 1.2'
|
||||
gem 'shoulda', '~> 3.5'
|
||||
gem 'cucumber', '~> 2.0', '< 2.1'
|
||||
gem 'simplecov', '~> 0.9'
|
||||
gem 'jekyll_test_plugin'
|
||||
gem 'jekyll_test_plugin_malicious'
|
||||
gem 'minitest-reporters'
|
||||
gem 'minitest-profile'
|
||||
gem 'minitest'
|
||||
gem 'rspec-mocks'
|
||||
|
||||
if RUBY_PLATFORM =~ /cygwin/ || RUBY_VERSION.start_with?("2.2")
|
||||
gem 'test-unit'
|
||||
end
|
||||
|
||||
if ENV['PROOF']
|
||||
gem 'html-proofer', '~> 2.0'
|
||||
end
|
||||
end
|
||||
|
||||
group :benchmark do
|
||||
if ENV['BENCHMARK']
|
||||
gem 'ruby-prof'
|
||||
gem 'rbtrace'
|
||||
gem 'stackprof'
|
||||
gem 'benchmark-ips'
|
||||
end
|
||||
end
|
||||
|
||||
gem 'jekyll-paginate', '~> 1.0'
|
||||
gem 'jekyll-coffeescript', '~> 1.0'
|
||||
gem 'jekyll-feed'
|
||||
gem 'jekyll-gist', '~> 1.0'
|
||||
gem 'mime-types', '~> 2.6'
|
||||
gem 'kramdown', '~> 1.9'
|
||||
|
||||
platform :ruby, :mswin, :mingw do
|
||||
gem 'rdiscount', '~> 2.0'
|
||||
gem 'pygments.rb', '~> 0.6.0'
|
||||
gem 'redcarpet', '~> 3.2', '>= 3.2.3'
|
||||
gem 'classifier-reborn', '~> 2.0'
|
||||
gem 'liquid-c', '~> 3.0'
|
||||
end
|
||||
|
||||
283
History.markdown
283
History.markdown
@@ -1,14 +1,72 @@
|
||||
## HEAD
|
||||
## 3.0.2 / 2016-01-20
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Document: throw a useful error when an invalid date is given (#4378)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* `jekyll-docs` should be easily release-able (#4152)
|
||||
|
||||
## 3.0.1 / 2015-11-17
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Document: only superdirectories of the collection are categories (#4110)
|
||||
* `Convertible#render_liquid` should use `render!` to cause failure on bad Liquid (#4077)
|
||||
* Don't generate `.jekyll-metadata` in non-incremental build (#4079)
|
||||
* Set `highlighter` config val to `kramdown.syntax_highlighter` (#4090)
|
||||
* Align hooks implementation with documentation (#4104)
|
||||
* Fix the deprecation warning in the doctor command (#4114)
|
||||
* Fix case in `:title` and add `:slug` which is downcased (#4100)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Fix test warnings when doing rake {test,spec} or script/test (#4078)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Update normalize.css to v3.0.3. (#4085)
|
||||
* Update Font Awesome to v4.4.0. (#4086)
|
||||
* Adds a note about installing the jekyll-gist gem to make gist tag work (#4101)
|
||||
* Align hooks documentation with implementation (#4104)
|
||||
* Add Jekyll Flickr Plugin to the list of third party plugins (#4111)
|
||||
* Remove link to now-deleted blog post (#4125)
|
||||
* Update the liquid syntax in the pagination docs (#4130)
|
||||
* Add jekyll-language-plugin to plugins.md (#4134)
|
||||
* Updated to reflect feedback in #4129 (#4137)
|
||||
* Clarify assets.md based on feedback of #4129 (#4142)
|
||||
* Re-correct the liquid syntax in the pagination docs (#4140)
|
||||
|
||||
## 3.0.0 / 2015-10-26
|
||||
|
||||
### Major Enhancements
|
||||
|
||||
* Liquid profiler (i.e. know how fast or slow your templates render) (#3762)
|
||||
* Incremental regeneration (#3116)
|
||||
* Drop support for Ruby 1.9.3. (#3235)
|
||||
* Add Hooks: a new kind of plugin (#3553)
|
||||
* Upgrade to Liquid 3.0.0 (#3002)
|
||||
* `site.posts` is now a Collection instead of an Array (#4055)
|
||||
* Add basic support for JRuby (commit: 0f4477)
|
||||
* Drop support for Ruby 1.9.3. (#3235)
|
||||
* Support Ruby v2.2 (#3234)
|
||||
* Support RDiscount 2 (#2767)
|
||||
* Remove most runtime deps (#3323)
|
||||
* Move to Rouge as default highlighter (#3323)
|
||||
* Mimic GitHub Pages `.html` extension stripping behavior in WEBrick (#3452)
|
||||
* Always include file extension on output files (#3490)
|
||||
* Improved permalinks for pages and collections (#3538)
|
||||
* Sunset (i.e. remove) Maruku (#3655)
|
||||
* Remove support for relative permalinks (#3679)
|
||||
* Iterate over `site.collections` as an array instead of a hash. (#3670)
|
||||
* Adapt StaticFile for collections, config defaults (#3823)
|
||||
* Add a Code of Conduct for the Jekyll project (#3925)
|
||||
* Added permalink time variables (#3990)
|
||||
* Add `--incremental` flag to enable incremental regen (disabled by default) (#4059)
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Deprecate access to Document#data properties and Collection#docs methods (#4058)
|
||||
* Sort static files just once, and call `site_payload` once for all collections (#3204)
|
||||
* Separate `jekyll docs` and optimize external gem handling (#3241)
|
||||
* Improve `Site#getConverterImpl` and call it `Site#find_converter_instance` (#3240)
|
||||
@@ -17,29 +75,248 @@
|
||||
* Added basic microdata to post template in site template (#3189)
|
||||
* Store log messages in an array of messages. (#3244)
|
||||
* Allow collection documents to override `output` property in front matter (#3172)
|
||||
* Keep file modification times between builds for static files (#3220)
|
||||
* Only downcase mixed-case categories for the URL (#2571)
|
||||
* Added per post `excerpt_separator` functionality (#3274)
|
||||
* Allow collections YAML to end with three dots (#3134)
|
||||
* Add mode parameter to `slugify` Liquid filter (#2918)
|
||||
* Perf: `Markdown#matches` should avoid regexp (#3321)
|
||||
* Perf: Use frozen regular expressions for `Utils#slugify` (#3321)
|
||||
* Split off Textile support into jekyll-textile-converter (#3319)
|
||||
* Improve the navigation menu alignment in the site template on small
|
||||
screens (#3331)
|
||||
* Show the regeneration time after the initial generation (#3378)
|
||||
* Site template: Switch default font to Helvetica Neue (#3376)
|
||||
* Make the `include` tag a teensy bit faster. (#3391)
|
||||
* Add `pkill -f jekyll` to ways to kill. (#3397)
|
||||
* Site template: collapsed, variable-driven font declaration (#3360)
|
||||
* Site template: Don't always show the scrollbar in code blocks (#3419)
|
||||
* Site template: Remove undefined `text` class from `p` element (#3440)
|
||||
* Site template: Optimize text rendering for legibility (#3382)
|
||||
* Add `draft?` method to identify if Post is a Draft & expose to Liquid (#3456)
|
||||
* Write regeneration metadata even on full rebuild (#3464)
|
||||
* Perf: Use `String#end_with?("/")` instead of regexp when checking paths (#3516)
|
||||
* Docs: document 'ordinal' built-in permalink style (#3532)
|
||||
* Upgrade liquid-c to 3.x (#3531)
|
||||
* Use consistent syntax for deprecation warning (#3535)
|
||||
* Added build --destination and --source flags (#3418)
|
||||
* Site template: remove unused `page.meta` attribute (#3537)
|
||||
* Improve the error message when sorting null objects (#3520)
|
||||
* Added liquid-md5 plugin (#3598)
|
||||
* Documentation: RR replaced with RSpec Mocks (#3600)
|
||||
* Documentation: Fix subpath. (#3599)
|
||||
* Create 'tmp' dir for test_tags if it doesn't exist (#3609)
|
||||
* Extract reading of data from `Site` to reduce responsibilities. (#3545)
|
||||
* Removed the word 'Jekyll' a few times from the comments (#3617)
|
||||
* `bin/jekyll`: with no args, exit with exit code 1 (#3619)
|
||||
* Incremental build if destination file missing (#3614)
|
||||
* Static files `mtime` liquid should return a `Time` obj (#3596)
|
||||
* Use `Jekyll::Post`s for both LSI indexing and lookup. (#3629)
|
||||
* Add `charset=utf-8` for HTML and XML pages in WEBrick (#3649)
|
||||
* Set log level to debug when verbose flag is set (#3665)
|
||||
* Added a mention on the Gemfile to complete the instructions (#3671)
|
||||
* Perf: Cache `Document#to_liquid` and invalidate where necessary (#3693)
|
||||
* Perf: `Jekyll::Cleaner#existing_files`: Call `keep_file_regex` and
|
||||
`keep_dirs` only once, not once per iteration (#3696)
|
||||
* Omit jekyll/jekyll-help from list of resources. (#3698)
|
||||
* Add basic `jekyll doctor` test to detect fsnotify (OSX) anomalies. (#3704)
|
||||
* Added talk.jekyllrb.com to "Have questions?" (#3694)
|
||||
* Performance: Sort files only once (#3707)
|
||||
* Performance: Marshal metadata (#3706)
|
||||
* Upgrade highlight wrapper from `div` to `figure` (#3779)
|
||||
* Upgrade mime-types to `~> 2.6` (#3795)
|
||||
* Update windows.md with Ruby version info (#3818)
|
||||
* Make the directory for includes configurable (#3782)
|
||||
* Rename directory configurations to match `*_dir` convention for consistency (#3782)
|
||||
* Internal: trigger hooks by owner symbol (#3871)
|
||||
* Update MIME types from mime-db (#3933)
|
||||
* Add header to site template `_config.yml` for clarity & direction (#3997)
|
||||
* Site template: add timezone offset to post date frontmatter (#4001)
|
||||
* Make a constant for the regex to find hidden files (#4032)
|
||||
* Site template: refactor github & twitter icons into includes (#4049)
|
||||
* Site template: add background to Kramdown Rouge-ified backtick code blocks (#4053)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `post_url`: fix access deprecation warning & fix deprecation msg (#4060)
|
||||
* Perform jekyll-paginate deprecation warning correctly. (#3580)
|
||||
* Make permalink parsing consistent with pages (#3014)
|
||||
* `time()`pre-filter method should accept a `Date` object (#3299)
|
||||
* Remove unneeded end tag for `link` in site template (#3236)
|
||||
* Kramdown: Use `enable_coderay` key instead of `use_coderay` (#3237)
|
||||
* Unescape `Document` output path (#2924)
|
||||
* Fix nav items alignment when on multiple rows (#3264)
|
||||
* Highlight: Only Strip Newlines/Carriage Returns, not Spaces (#3278)
|
||||
* Find variables in front matter defaults by searching with relative file path. (#2774)
|
||||
* Allow variables (e.g `:categories`) in YAML front matter permalinks (#3320)
|
||||
* Handle nil URL placeholders in permalinks (#3325)
|
||||
* Template: Fix nav items alignment when in "burger" mode (#3329)
|
||||
* Template: Remove `!important` from nav SCSS introduced in #3329 (#3375)
|
||||
* The `:title` URL placeholder for collections should be the filename slug. (#3383)
|
||||
* Trim the generate time diff to just 3 places past the decimal place (#3415)
|
||||
* The highlight tag should only clip the newlines before and after the *entire* block, not in between (#3401)
|
||||
* highlight: fix problem with linenos and rouge. (#3436)
|
||||
* `Site#read_data_file`: read CSV's with proper file encoding (#3455)
|
||||
* Ignore `.jekyll-metadata` in site template (#3496)
|
||||
* Template: Point documentation link to the documentation pages (#3502)
|
||||
* Removed the trailing slash from the example `/blog` baseurl comment (#3485)
|
||||
* Clear the regenerator cache every time we process (#3592)
|
||||
* Readd (bring back) minitest-profile (#3628)
|
||||
* Add WOFF2 font MIME type to Jekyll server MIME types (#3647)
|
||||
* Be smarter about extracting the extname in `StaticFile` (#3632)
|
||||
* Process metadata for all dependencies (#3608)
|
||||
* Show error message if the YAML front matter on a page/post is invalid. (#3643)
|
||||
* Upgrade redcarpet to 3.2 (Security fix: OSVDB-120415) (#3652)
|
||||
* Create #mock_expects that goes directly to RSpec Mocks. (#3658)
|
||||
* Open `.jekyll-metadata` in binary mode to read binary Marshal data (#3713)
|
||||
* Incremental regeneration: handle deleted, renamed, and moved dependencies (#3717)
|
||||
* Fix typo on line 19 of pagination.md (#3760)
|
||||
* Fix it so that 'blog.html' matches 'blog.html' (#3732)
|
||||
* Remove occasionally-problematic `ensure` in `LiquidRenderer` (#3811)
|
||||
* Fixed an unclear code comment in site template SCSS (#3837)
|
||||
* Fix reading of binary metadata file (#3845)
|
||||
* Remove var collision with site template header menu iteration variable (#3838)
|
||||
* Change non-existent `hl_linenos` to `hl_lines` to allow passthrough in safe mode (#3787)
|
||||
* Add missing flag to disable the watcher (#3820)
|
||||
* Update CI guide to include more direct explanations of the flow (#3891)
|
||||
* Set `future` to `false` in the default config (#3892)
|
||||
* filters: `where` should compare stringified versions of input & comparator (#3935)
|
||||
* Read build options for `jekyll clean` command (#3828)
|
||||
* Fix #3970: Use Gem::Version to compare versions, not `>`.
|
||||
* Abort if no subcommand. Fixes confusing message. (#3992)
|
||||
* Whole-post excerpts should match the post content (#4004)
|
||||
* Change default font weight to 400 to fix bold/strong text issues (#4050)
|
||||
* Document: Only auto-generate the excerpt if it's not overridden (#4062)
|
||||
* Utils: `deep_merge_hashes` should also merge `default_proc` (45f69bb)
|
||||
* Defaults: compare paths in `applies_path?` as `String`s to avoid confusion (7b81f00)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Remove loader.rb and "modernize" `script/test`. (#3574)
|
||||
* Improve the grammar in the documentation (#3233)
|
||||
* Update the LICENSE text to match the MIT license exactly (#3253)
|
||||
* Update rake task `site:publish` to fix minor bugs. (#3254)
|
||||
* Switch to shields.io for the README badges. (#3255)
|
||||
* Use `FileList` instead of `Dir.glob` in `site:publish` rake task (#3261)
|
||||
* Fix test script to be platform-independent (#3279)
|
||||
* Instead of symlinking `/tmp`, create and symlink a local `tmp` in the tests (#3258)
|
||||
* Fix some spacing (#3312)
|
||||
* Fix comment typo in `lib/jekyll/frontmatter_defaults.rb` (#3322)
|
||||
* Move all `regenerate?` checking to `Regenerator` (#3326)
|
||||
* Factor out a `read_data_file` call to keep things clean (#3380)
|
||||
* Proof the site with CircleCI. (#3427)
|
||||
* Update LICENSE to 2015. (#3477)
|
||||
* Upgrade tests to use Minitest (#3492)
|
||||
* Remove trailing whitespace (#3497)
|
||||
* Use `fixture_site` for Document tests (#3511)
|
||||
* Remove adapters deprecation warning (#3529)
|
||||
* Minor fixes to `url.rb` to follow GitHub style guide (#3544)
|
||||
* Minor changes to resolve deprecation warnings (#3547)
|
||||
* Convert remaining textile test documents to markdown (#3528)
|
||||
* Migrate the tests to use rspec-mocks (#3552)
|
||||
* Remove `activesupport` (#3612)
|
||||
* Added tests for `Jekyll:StaticFile` (#3633)
|
||||
* Force minitest version to 5.5.1 (#3657)
|
||||
* Update the way cucumber accesses Minitest assertions (#3678)
|
||||
* Add `script/rubyprof` to generate cachegrind callgraphs (#3692)
|
||||
* Upgrade cucumber to 2.x (#3795)
|
||||
* Update Kramdown. (#3853)
|
||||
* Updated the scripts shebang for portability (#3858)
|
||||
* Update JRuby testing to 9K ([3ab386f](https://github.com/jekyll/jekyll/commit/3ab386f1b096be25a24fe038fc70fd0fb08d545d))
|
||||
* Organize dependencies into dev and test groups. (#3852)
|
||||
* Contributing.md should refer to `script/cucumber` (#3894)
|
||||
* Update contributing documentation to reflect workflow updates (#3895)
|
||||
* Add script to vendor mime types (#3933)
|
||||
* Ignore .bundle dir in SimpleCov (#4033)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Add 'info' labels to certain notes in collections docs (#3601)
|
||||
* Remove extra spaces, make the last sentence less awkward in permalink docs (#3603)
|
||||
* Update the permalinks documentation to reflect the updates for 3.0 (#3556)
|
||||
* Add blog post announcing Jekyll Help (#3523)
|
||||
* Add Jekyll Talk to Help page on site (#3518)
|
||||
* Change Ajax pagination resource link to use HTTPS (#3570)
|
||||
* Fixing the default host on docs (#3229)
|
||||
* Add `jekyll-thumbnail-filter` to list of third-party plugins (#2790)
|
||||
* Add link to 'Adding Ajax pagination to Jekyll' to Resources page (#3186)
|
||||
* Add a Resources link to tutorial on building dynamic navbars (#3185)
|
||||
* Semantic structure improvements to the post and page layouts (#3251)
|
||||
* Add new AsciiDoc plugin to list of third-party plugins. (#3277)
|
||||
* Specify that all transformable collection documents must contain YAML front matter (#3271)
|
||||
* Assorted accessibility fixes (#3256)
|
||||
* Update configuration docs to mention `keep_files` for `destination` (#3288, #3296)
|
||||
* Break when we successfully generate nav link to save CPU cycles. (#3291)
|
||||
* Update usage docs to mention `keep_files` and a warning about `destination` cleaning (#3295)
|
||||
* Add logic to automatically generate the `next_section` and `prev_section` navigation items (#3292)
|
||||
* Some small fixes for the Plugins TOC. (#3306)
|
||||
* Added versioning comment to configuration file (#3314)
|
||||
* Add `jekyll-minifier` to list of third-party plugins (#3333)
|
||||
* Add blog post about the Jekyll meet-up (#3332)
|
||||
* Use `highlight` Liquid tag instead of the four-space tabs for code (#3336)
|
||||
* 3.0.0.beta1 release post (#3346)
|
||||
* Add `twa` to the list of third-party plugins (#3384)
|
||||
* Remove extra spaces (#3388)
|
||||
* Fix small grammar errors on a couple pages (#3396)
|
||||
* Fix typo on Templates docs page (#3420)
|
||||
* s/three/four for plugin type list (#3424)
|
||||
* Release jekyllrb.com as a locally-compiled site. (#3426)
|
||||
* Add a jekyllrb.com/help page which elucidates places from which to get help (#3428)
|
||||
* Remove extraneous dash on Plugins doc page which caused a formatting error (#3431)
|
||||
* Fix broken link to Jordan Thornquest's website. (#3438)
|
||||
* Change the link to an extension (#3457)
|
||||
* Fix Twitter link on the help page (#3466)
|
||||
* Fix wording in code snippet highlighting section (#3475)
|
||||
* Add a `/` to `paginate_path` in the Pagination documentation (#3479)
|
||||
* Add a link on all the docs pages to "Improve this page". (#3510)
|
||||
* Add jekyll-auto-image generator to the list of third-party plugins (#3489)
|
||||
* Replace link to the proposed `picture` element spec (#3530)
|
||||
* Add frontmatter date formatting information (#3469)
|
||||
* Improve consistency and clarity of plugins options note (#3546)
|
||||
* Add permalink warning to pagination docs (#3551)
|
||||
* Fix grammar in Collections docs API stability warning (#3560)
|
||||
* Restructure `excerpt_separator` documentation for clarity (#3550)
|
||||
* Fix accidental line break in collections docs (#3585)
|
||||
* Add information about the `.jekyll-metadata` file (#3597)
|
||||
* Document addition of variable parameters to an include (#3581)
|
||||
* Add `jekyll-files` to the list of third-party plugins. (#3586)
|
||||
* Define the `install` step in the CI example `.travis.yml` (#3622)
|
||||
* Expand collections documentation. (#3638)
|
||||
* Add the "warning" note label to excluding `vendor` in the CI docs page (#3623)
|
||||
* Upgrade pieces of the Ugrading guide for Jekyll 3 (#3607)
|
||||
* Showing how to access specific data items (#3468)
|
||||
* Clarify pagination works from within HTML files (#3467)
|
||||
* Add note to `excerpt_separator` documentation that it can be set globally (#3667)
|
||||
* Fix some names on Troubleshooting page (#3683)
|
||||
* Add `remote_file_content` tag plugin to list of third-party plugins (#3691)
|
||||
* Update the Redcarpet version on the Configuration page. (#3743)
|
||||
* Update the link in the welcome post to point to Jekyll Talk (#3745)
|
||||
* Update link for navbars with data attributes tutorial (#3728)
|
||||
* Add `jekyll-asciinema` to list of third-party plugins (#3750)
|
||||
* Update pagination example to be agnostic to first pagination dir (#3763)
|
||||
* Detailed instructions for rsync deployment method (#3848)
|
||||
* Add Jekyll Portfolio Generator to list of plugins (#3883)
|
||||
* Add `site.html_files` to variables docs (#3880)
|
||||
* Add Static Publisher tool to list of deployment methods (#3865)
|
||||
* Fix a few typos. (#3897)
|
||||
* Add `jekyll-youtube` to the list of third-party plugins (#3931)
|
||||
* Add Views Router plugin (#3950)
|
||||
* Update install docs (Core dependencies, Windows reqs, etc) (#3769)
|
||||
* Use Jekyll Feed for jekyllrb.com (#3736)
|
||||
* Add jekyll-umlauts to plugins.md ($3966)
|
||||
* Troubleshooting: fix broken link, add other mac-specific info (#3968)
|
||||
* Add a new site for learning purposes (#3917)
|
||||
* Added documentation for Jekyll environment variables (#3989)
|
||||
* Fix broken configuration documentation page (#3994)
|
||||
* Add troubleshooting docs for installing on El Capitan (#3999)
|
||||
* Add Lazy Tweet Embedding to the list of third-party plugins (#4015)
|
||||
* Add installation instructions for 2 of 3 options for plugins (#4013)
|
||||
* Add alternative jekyll gem installation instructions (#4018)
|
||||
* Fix a few typos and formatting problems. (#4022)
|
||||
* Fix pretty permalink example (#4029)
|
||||
* Note that `_config.yml` is not reloaded during regeneration (#4034)
|
||||
* Apply code block figure syntax to blocks in CONTRIBUTING (#4046)
|
||||
* Add jekyll-smartify to the list of third-party plugins (#3572)
|
||||
|
||||
## 2.5.3 / 2014-12-22
|
||||
|
||||
@@ -524,7 +801,7 @@
|
||||
* Add `Jekyll::LiquidExtensions` with `.lookup_variable` method for easy
|
||||
looking up of variable values in a Liquid context. (#2253)
|
||||
* Remove literal lang name from class (#2292)
|
||||
* Return `utf-8` encoding in header for webrick error page response (#2289)
|
||||
* Return `utf-8` encoding in header for webrick error page response (#2289)
|
||||
* Make template site easier to customize (#2268)
|
||||
* Add two-digit year to permalink template option (#2301)
|
||||
* Add `site.documents` to Liquid payload (list of all docs) (#2295)
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2008-2014 Tom Preston-Werner
|
||||
Copyright (c) 2008-2015 Tom Preston-Werner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -14,13 +14,29 @@ Jekyll is a simple, blog-aware, static site generator perfect for personal, proj
|
||||
|
||||
Jekyll does what you tell it to do — no more, no less. It doesn't try to outsmart users by making bold assumptions, nor does it burden them with needless complexity and configuration. Put simply, Jekyll gets out of your way and allows you to concentrate on what truly matters: your content.
|
||||
|
||||
## Having trouble with OS X El Capitan?
|
||||
|
||||
See: http://jekyllrb.com/docs/troubleshooting/#jekyll-amp-mac-os-x-1011
|
||||
|
||||
## Getting Started
|
||||
|
||||
* [Install](http://jekyllrb.com/docs/installation/) the gem
|
||||
* Read up about its [Usage](http://jekyllrb.com/docs/usage/) and [Configuration](http://jekyllrb.com/docs/configuration/)
|
||||
* Take a gander at some existing [Sites](https://wiki.github.com/jekyll/jekyll/sites)
|
||||
* Fork and [Contribute](http://jekyllrb.com/docs/contributing/) your own modifications
|
||||
* Have questions? Check out [`#jekyll` on irc.freenode.net](https://botbot.me/freenode/jekyll/).
|
||||
* Have questions? Check out our official forum community [Jekyll Talk](https://talk.jekyllrb.com/) or [`#jekyll` on irc.freenode.net](https://botbot.me/freenode/jekyll/)
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
In order to have a more open and welcoming community, Jekyll adheres to a
|
||||
[code of conduct](CONDUCT.md) adapted from the Ruby on Rails code of
|
||||
conduct.
|
||||
|
||||
Please adhere to this code of conduct in any interactions you have in the
|
||||
Jekyll community. It is strictly enforced on all official Jekyll
|
||||
repositories, websites, and resources. If you encounter someone violating
|
||||
these terms, please let a maintainer (@parkr, @envygeeks, or @mattr-) know
|
||||
and we will address it as soon as possible.
|
||||
|
||||
## Diving In
|
||||
|
||||
|
||||
70
Rakefile
70
Rakefile
@@ -14,19 +14,23 @@ require 'jekyll/version'
|
||||
#############################################################################
|
||||
|
||||
def name
|
||||
@name ||= File.basename(Dir['*.gemspec'].first, ".*")
|
||||
"jekyll"
|
||||
end
|
||||
|
||||
def version
|
||||
Jekyll::VERSION
|
||||
end
|
||||
|
||||
def docs_name
|
||||
"#{name}-docs"
|
||||
end
|
||||
|
||||
def gemspec_file
|
||||
"#{name}.gemspec"
|
||||
end
|
||||
|
||||
def gem_file
|
||||
"#{name}-#{version}.gem"
|
||||
"#{name}-#{Gem::Version.new(version).to_s}.gem"
|
||||
end
|
||||
|
||||
def normalize_bullets(markdown)
|
||||
@@ -89,6 +93,7 @@ end
|
||||
|
||||
multitask :default => [:test, :features]
|
||||
|
||||
task :spec => :test
|
||||
require 'rake/testtask'
|
||||
Rake::TestTask.new(:test) do |test|
|
||||
test.libs << 'lib' << 'test'
|
||||
@@ -132,7 +137,7 @@ end
|
||||
|
||||
namespace :site do
|
||||
desc "Generate and view the site locally"
|
||||
task :preview do
|
||||
task :preview => [:history, :version_file] do
|
||||
require "launchy"
|
||||
require "jekyll"
|
||||
|
||||
@@ -195,31 +200,27 @@ namespace :site do
|
||||
gh-pages/.
|
||||
gh-pages/..
|
||||
gh-pages/.git
|
||||
gh-pages/.gitignore
|
||||
]
|
||||
FileList["gh-pages/{*,.*}"].exclude(*purge_exclude).each do |path|
|
||||
sh "rm -rf #{path}"
|
||||
end
|
||||
|
||||
# Copy site to gh-pages dir.
|
||||
puts "Copying site to gh-pages branch..."
|
||||
copy_exclude = %w[
|
||||
site/.
|
||||
site/..
|
||||
site/.jekyll-metadata
|
||||
site/_site
|
||||
]
|
||||
FileList["site/{*,.*}"].exclude(*copy_exclude).each do |path|
|
||||
sh "cp -R #{path} gh-pages/"
|
||||
end
|
||||
puts "Building site into gh-pages branch..."
|
||||
ENV['JEKYLL_ENV'] = 'production'
|
||||
require "jekyll"
|
||||
Jekyll::Commands::Build.process({
|
||||
"source" => File.expand_path("site"),
|
||||
"destination" => File.expand_path("gh-pages"),
|
||||
"sass" => { "style" => "compressed" }
|
||||
})
|
||||
|
||||
# Change any configuration settings for production.
|
||||
config = YAML.load_file("gh-pages/_config.yml")
|
||||
config.merge!({'sass' => {'style' => 'compressed'}})
|
||||
File.write('gh-pages/_config.yml', YAML.dump(config))
|
||||
File.open('gh-pages/.nojekyll', 'wb') { |f| f.puts(":dog: food.") }
|
||||
|
||||
# Commit and push.
|
||||
puts "Committing and pushing to GitHub Pages..."
|
||||
sha = `git log`.match(/[a-z0-9]{40}/)[0]
|
||||
sha = `git rev-parse HEAD`.strip
|
||||
Dir.chdir('gh-pages') do
|
||||
sh "git add ."
|
||||
sh "git commit --allow-empty -m 'Updating to #{sha}.'"
|
||||
@@ -235,8 +236,7 @@ namespace :site do
|
||||
front_matter = {
|
||||
"layout" => "docs",
|
||||
"title" => "History",
|
||||
"permalink" => "/docs/history/",
|
||||
"prev_section" => "contributing"
|
||||
"permalink" => "/docs/history/"
|
||||
}
|
||||
Dir.chdir('site/_docs/') do
|
||||
File.open("history.md", "w") do |file|
|
||||
@@ -251,7 +251,7 @@ namespace :site do
|
||||
|
||||
desc "Write the site latest_version.txt file"
|
||||
task :version_file do
|
||||
File.open('site/latest_version.txt', 'wb') { |f| f.write(version) }
|
||||
File.open('site/latest_version.txt', 'wb') { |f| f.puts(version) } unless version =~ /(beta|rc|alpha)/i
|
||||
end
|
||||
|
||||
namespace :releases do
|
||||
@@ -288,8 +288,8 @@ end
|
||||
|
||||
desc "Release #{name} v#{version}"
|
||||
task :release => :build do
|
||||
unless `git branch` =~ /^\* master$/
|
||||
puts "You must be on the master branch to release!"
|
||||
unless `git branch` =~ /^\* 3\.0-stable$/
|
||||
puts "You must be on the 3.0-stable branch to release!"
|
||||
exit!
|
||||
end
|
||||
sh "git commit --allow-empty -m 'Release :gem: #{version}'"
|
||||
@@ -305,3 +305,27 @@ task :build do
|
||||
sh "gem build #{gemspec_file}"
|
||||
sh "mv #{gem_file} pkg"
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# Packaging tasks for jekyll-docs
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
namespace :docs do
|
||||
desc "Release #{docs_name} v#{version}"
|
||||
task :release => :build do
|
||||
unless `git branch` =~ /^\* master$/
|
||||
puts "You must be on the master branch to release!"
|
||||
exit!
|
||||
end
|
||||
sh "gem push pkg/#{docs_name}-#{version}.gem"
|
||||
end
|
||||
|
||||
desc "Build #{docs_name} v#{version} into pkg/"
|
||||
task :build do
|
||||
mkdir_p "pkg"
|
||||
sh "gem build #{docs_name}.gemspec"
|
||||
sh "mv #{docs_name}-#{version}.gem pkg"
|
||||
end
|
||||
end
|
||||
|
||||
13
benchmark/end-with-vs-regexp
Normal file
13
benchmark/end-with-vs-regexp
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'benchmark/ips'
|
||||
|
||||
Benchmark.ips do |x|
|
||||
path_without_ending_slash = '/some/very/very/long/path/to/a/file/i/like'
|
||||
x.report('no slash regexp') { path_without_ending_slash =~ /\/$/ }
|
||||
x.report('no slash end_with?') { path_without_ending_slash.end_with?("/") }
|
||||
end
|
||||
|
||||
Benchmark.ips do |x|
|
||||
path_with_ending_slash = '/some/very/very/long/path/to/a/file/i/like/'
|
||||
x.report('slash regexp') { path_with_ending_slash =~ /\/$/ }
|
||||
x.report('slash end_with?') { path_with_ending_slash.end_with?("/") }
|
||||
end
|
||||
@@ -14,4 +14,3 @@ Benchmark.ips do |x|
|
||||
x.report('.map.flatten with no nested arrays') { enum.map { |i| do_thing(i) }.flatten(1) }
|
||||
x.report('.flat_map with no nested arrays') { enum.flat_map { |i| do_thing(i) } }
|
||||
end
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@ Benchmark.ips do |x|
|
||||
x.report('#tr') { str.tr('some', 'a') }
|
||||
x.report('#gsub') { str.gsub('some', 'a') }
|
||||
x.report('#gsub!') { str.gsub!('some', 'a') }
|
||||
x.report('#sub') { str.sub('some', 'a') }
|
||||
x.report('#sub!') { str.sub!('some', 'a') }
|
||||
x.report('#sub') { str.sub('some', 'a') }
|
||||
x.report('#sub!') { str.sub!('some', 'a') }
|
||||
end
|
||||
|
||||
@@ -22,8 +22,9 @@ Mercenary.program(:jekyll) do |p|
|
||||
p.option 'source', '-s', '--source [DIR]', 'Source directory (defaults to ./)'
|
||||
p.option 'destination', '-d', '--destination [DIR]', 'Destination directory (defaults to ./_site)'
|
||||
p.option 'safe', '--safe', 'Safe mode (defaults to false)'
|
||||
p.option 'plugins', '-p', '--plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]', Array, 'Plugins directory (defaults to ./_plugins)'
|
||||
p.option 'layouts', '--layouts DIR', String, 'Layouts directory (defaults to ./_layouts)'
|
||||
p.option 'plugins_dir', '-p', '--plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]', Array, 'Plugins directory (defaults to ./_plugins)'
|
||||
p.option 'layouts_dir', '--layouts DIR', String, 'Layouts directory (defaults to ./_layouts)'
|
||||
p.option 'profile', '--profile', 'Generate a Liquid rendering profile'
|
||||
|
||||
Jekyll::Command.subclasses.each { |c| c.init_with_program(p) }
|
||||
|
||||
@@ -31,6 +32,7 @@ Mercenary.program(:jekyll) do |p|
|
||||
if args.empty?
|
||||
Jekyll.logger.error "A subcommand is required."
|
||||
puts p
|
||||
abort
|
||||
else
|
||||
unless p.has_command?(args.first)
|
||||
Jekyll.logger.abort_with "Invalid command. Use --help for more information"
|
||||
|
||||
@@ -9,12 +9,12 @@ Feature: Collections
|
||||
And I have a configuration file with "collections" set to "['methods']"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: <p>Use <code>Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>\n<p>Signs are nice</p>\n<p><code>Jekyll.sanitized_path</code> is used to make sure your path is in your source.</p>\n<p>Run your generators! default</p>\n<p>Page without title.</p>\n<p>Run your generators! default</p>" in "_site/index.html"
|
||||
And I should see "Collections: <p>Use <code class=\"highlighter-rouge\">Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>\n<p>Signs are nice</p>\n<p><code class=\"highlighter-rouge\">Jekyll.sanitized_path</code> is used to make sure your path is in your source.</p>\n<p>Run your generators! default</p>\n<p>Page without title.</p>\n<p>Run your generators! default</p>" in "_site/index.html"
|
||||
And the "_site/methods/configuration.html" file should not exist
|
||||
|
||||
Scenario: Rendered collection
|
||||
Given I have an "index.html" page that contains "Collections: {{ site.collections }}"
|
||||
And I have an "collection_metadata.html" page that contains "Methods metadata: {{ site.collections.methods.foo }} {{ site.collections.methods }}"
|
||||
And I have an "collection_metadata.html" page that contains "Methods metadata: {{ site.collections[0].foo }} {{ site.collections[0] }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
@@ -25,7 +25,8 @@ Feature: Collections
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: {\"methods" in "_site/index.html"
|
||||
And I should see "Collections: {\"output\"=>true" in "_site/index.html"
|
||||
And I should see "\"label\"=>\"methods\"," in "_site/index.html"
|
||||
And I should see "Methods metadata: bar" in "_site/collection_metadata.html"
|
||||
And I should see "<p>Whatever: foo.bar</p>" in "_site/methods/configuration.html"
|
||||
|
||||
@@ -56,7 +57,8 @@ Feature: Collections
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: {\"methods" in "_site/index.html"
|
||||
And I should see "Collections: {\"output\"=>true" in "_site/index.html"
|
||||
And I should see "\"label\"=>\"methods\"," in "_site/index.html"
|
||||
And I should see "<p>Run your generators! default</p>" in "_site/methods/site/generate.html"
|
||||
And I should see "<div class='title'>Tom Preston-Werner</div>" in "_site/methods/site/generate.html"
|
||||
|
||||
@@ -106,7 +108,7 @@ Feature: Collections
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "First document's output: <p>Use <code>Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>" in "_site/index.html"
|
||||
And I should see "First document's output: <p>Use <code class=\"highlighter-rouge\">Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>" in "_site/index.html"
|
||||
|
||||
Scenario: Filter documents by where
|
||||
Given I have an "index.html" page that contains "{% assign items = site.methods | where: 'whatever','foo.bar' %}Item count: {{ items.size }}"
|
||||
@@ -118,7 +120,7 @@ Feature: Collections
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Item count: 1" in "_site/index.html"
|
||||
And I should see "Item count: 2" in "_site/index.html"
|
||||
|
||||
Scenario: Sort by title
|
||||
Given I have an "index.html" page that contains "{% assign items = site.methods | sort: 'title' %}1. of {{ items.size }}: {{ items.first.output }}"
|
||||
@@ -130,7 +132,7 @@ Feature: Collections
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "1. of 6: <p>Page without title.</p>" in "_site/index.html"
|
||||
And I should see "1. of 7: <p>Page without title.</p>" in "_site/index.html"
|
||||
|
||||
Scenario: Sort by relative_path
|
||||
Given I have an "index.html" page that contains "Collections: {% assign methods = site.methods | sort: 'relative_path' %}{% for method in methods %}{{ method.title }}, {% endfor %}"
|
||||
|
||||
@@ -112,16 +112,16 @@ Feature: Create sites
|
||||
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with internal post linking
|
||||
Given I have an "index.html" page that contains "URL: {% post_url 2020-01-31-entry2 %}"
|
||||
Given I have an "index.html" page that contains "URL: {% post_url 2008-01-01-entry2 %}"
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
| entry2 | 2020-01-31 | post | content for entry2. |
|
||||
| entry2 | 2008-01-01 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "URL: /2020/01/31/entry2/" in "_site/index.html"
|
||||
And I should see "URL: /2008/01/01/entry2/" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with whitelisted dotfile
|
||||
Given I have an ".htaccess" file that contains "SomeDirective"
|
||||
@@ -156,3 +156,17 @@ Feature: Create sites
|
||||
And the "_site/index.html" file should exist
|
||||
And the "_site/public.html" file should exist
|
||||
And the "_site/secret.html" file should exist
|
||||
|
||||
Scenario: Basic site with page with future date
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2020-12-31 | post | content for entry1. |
|
||||
| entry2 | 2007-12-31 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "content for entry2" in "_site/2007/12/31/entry2.html"
|
||||
And the "_site/2020/12/31/entry1.html" file should not exist
|
||||
When I run jekyll build --future
|
||||
Then the _site directory should exist
|
||||
And the "_site/2020/12/31/entry1.html" file should exist
|
||||
|
||||
@@ -43,4 +43,4 @@ Feature: Draft Posts
|
||||
| Recipe | 2009-03-27 | simple | Post path: {{ page.path }} |
|
||||
When I run jekyll build --drafts
|
||||
Then the _site directory should exist
|
||||
And I should see "Post path: _drafts/recipe.textile" in "_site/recipe.html"
|
||||
And I should see "Post path: _drafts/recipe.markdown" in "_site/recipe.html"
|
||||
|
||||
@@ -20,8 +20,6 @@ Feature: Embed filters
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| Star & Wars | 2009-03-27 | default | These aren't the droids you're looking for. |
|
||||
|
||||
|
||||
And I have a default layout that contains "{{ page.title | xml_escape }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
@@ -33,7 +31,7 @@ Feature: Embed filters
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | default | These aren't the droids you're looking for. |
|
||||
And I have a default layout that contains "{{ content | xml_escape }}"
|
||||
And I have a default layout that contains "{{ content | number_of_words }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "7" in "_site/2009/03/27/star-wars.html"
|
||||
@@ -49,13 +47,13 @@ Feature: Embed filters
|
||||
Then the _site directory should exist
|
||||
And I should see "scifi, movies, and force" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Textilize a given string
|
||||
Scenario: Markdownify a given string
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | default | These aren't the droids you're looking for. |
|
||||
And I have a default layout that contains "By {{ '_Obi-wan_' | textilize }}"
|
||||
And I have a default layout that contains "By {{ '_Obi-wan_' | markdownify }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "By <p><em>Obi-wan</em></p>" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -25,7 +25,7 @@ Feature: frontmatter defaults
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: ""}, values: {custom: "some special data", author: "Ben"}}]"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "<p>some special data</p><div>Ben</div>" in "_site/2013/09/11/default-data.html"
|
||||
And I should see "<p>some special data</p>\n<div>Ben</div>" in "_site/2013/09/11/default-data.html"
|
||||
And I should see "just some special data by Ben" in "_site/index.html"
|
||||
|
||||
Scenario: Override frontmatter defaults by path
|
||||
@@ -54,6 +54,28 @@ Feature: frontmatter defaults
|
||||
And I should see "root: Overview for the webpage" in "_site/index.html"
|
||||
And I should see "subfolder: Overview for the special section" in "_site/special/index.html"
|
||||
|
||||
Scenario: Use frontmatter variables by relative path
|
||||
Given I have a _layouts directory
|
||||
And I have a main layout that contains "main: {{ content }}"
|
||||
|
||||
And I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| about | 2013-10-14 | content of site/2013/10/14/about.html |
|
||||
And I have a special/_posts directory
|
||||
And I have the following post in "special":
|
||||
| title | date | path | content |
|
||||
| about1 | 2013-10-14 | local | content of site/special/2013/10/14/about1.html |
|
||||
| about2 | 2013-10-14 | local | content of site/special/2013/10/14/about2.html |
|
||||
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: "special"}, values: {layout: "main"}}, {scope: {path: "special/_posts"}, values: {layout: "main"}}, {scope: {path: "_posts"}, values: {layout: "main"}}]"
|
||||
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "main: <p>content of site/2013/10/14/about.html</p>" in "_site/2013/10/14/about.html"
|
||||
And I should see "main: <p>content of site/special/2013/10/14/about1.html</p>" in "_site/special/2013/10/14/about1.html"
|
||||
And I should see "main: <p>content of site/special/2013/10/14/about2.html</p>" in "_site/special/2013/10/14/about2.html"
|
||||
|
||||
Scenario: Override frontmatter defaults by type
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
@@ -78,10 +100,19 @@ Feature: frontmatter defaults
|
||||
And I should see "nothing" in "_site/override.html"
|
||||
But the "_site/perma.html" file should not exist
|
||||
|
||||
Scenario: Define permalink default for posts
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | category | content |
|
||||
| testpost | 2013-10-14 | blog | blabla |
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: "", type: "posts"}, values: {permalink: "/:categories/:title/"}}]"
|
||||
When I run jekyll build
|
||||
Then I should see "blabla" in "_site/blog/testpost/index.html"
|
||||
|
||||
Scenario: Use frontmatter defaults in collections
|
||||
Given I have a _slides directory
|
||||
And I have a "index.html" file that contains "nothing"
|
||||
And I have a "_slides/slide1.html" file with content:
|
||||
And I have a "_slides/slide1.html" file with content:
|
||||
"""
|
||||
---
|
||||
---
|
||||
@@ -107,7 +138,7 @@ Feature: frontmatter defaults
|
||||
Scenario: Override frontmatter defaults inside a collection
|
||||
Given I have a _slides directory
|
||||
And I have a "index.html" file that contains "nothing"
|
||||
And I have a "_slides/slide2.html" file with content:
|
||||
And I have a "_slides/slide2.html" file with content:
|
||||
"""
|
||||
---
|
||||
myval: Override
|
||||
|
||||
326
features/hooks.feature
Normal file
326
features/hooks.feature
Normal file
@@ -0,0 +1,326 @@
|
||||
Feature: Hooks
|
||||
As a plugin author
|
||||
I want to be able to run code during various stages of the build process
|
||||
|
||||
Scenario: Run some code after site reset
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :site, :after_reset do |site|
|
||||
pageklass = Class.new(Jekyll::Page) do
|
||||
def initialize(site, base)
|
||||
@site = site
|
||||
@base = base
|
||||
@data = {}
|
||||
@dir = '/'
|
||||
@name = 'foo.html'
|
||||
@content = 'mytinypage'
|
||||
|
||||
self.process(@name)
|
||||
end
|
||||
end
|
||||
|
||||
site.pages << pageklass.new(site, site.source)
|
||||
end
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "mytinypage" in "_site/foo.html"
|
||||
|
||||
Scenario: Modify the payload before rendering the site
|
||||
Given I have a _plugins directory
|
||||
And I have a "index.html" page that contains "{{ site.injected }}!"
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :site, :pre_render do |site, payload|
|
||||
payload['site']['injected'] = 'myparam'
|
||||
end
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "myparam!" in "_site/index.html"
|
||||
|
||||
Scenario: Modify the site contents after reading
|
||||
Given I have a _plugins directory
|
||||
And I have a "page1.html" page that contains "page1"
|
||||
And I have a "page2.html" page that contains "page2"
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :site, :post_read do |site|
|
||||
site.pages.delete_if { |p| p.name == 'page1.html' }
|
||||
end
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the "_site/page1.html" file should not exist
|
||||
And I should see "page2" in "_site/page2.html"
|
||||
|
||||
Scenario: Work with the site files after they've been written to disk
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :site, :post_write do |site|
|
||||
firstpage = site.pages.first
|
||||
content = File.read firstpage.destination(site.dest)
|
||||
File.write(File.join(site.dest, 'firstpage.html'), content)
|
||||
end
|
||||
"""
|
||||
And I have a "page1.html" page that contains "page1"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "page1" in "_site/firstpage.html"
|
||||
|
||||
Scenario: Alter a page right after it is initialized
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :pages, :post_init do |page|
|
||||
page.name = 'renamed.html'
|
||||
page.process(page.name)
|
||||
end
|
||||
"""
|
||||
And I have a "page1.html" page that contains "page1"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "page1" in "_site/renamed.html"
|
||||
|
||||
Scenario: Alter the payload for one page but not another
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :pages, :pre_render do |page, payload|
|
||||
payload['myparam'] = 'special' if page.name == 'page1.html'
|
||||
end
|
||||
"""
|
||||
And I have a "page1.html" page that contains "{{ myparam }}"
|
||||
And I have a "page2.html" page that contains "{{ myparam }}"
|
||||
When I run jekyll build
|
||||
Then I should see "special" in "_site/page1.html"
|
||||
And I should not see "special" in "_site/page2.html"
|
||||
|
||||
Scenario: Modify page contents before writing to disk
|
||||
Given I have a _plugins directory
|
||||
And I have a "index.html" page that contains "WRAP ME"
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :pages, :post_render do |page|
|
||||
page.output = "{{{{{ #{page.output.chomp} }}}}}"
|
||||
end
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then I should see "{{{{{ WRAP ME }}}}}" in "_site/index.html"
|
||||
|
||||
Scenario: Work with a page after writing it to disk
|
||||
Given I have a _plugins directory
|
||||
And I have a "index.html" page that contains "HELLO FROM A PAGE"
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :pages, :post_write do |page|
|
||||
require 'fileutils'
|
||||
filename = page.destination(page.site.dest)
|
||||
FileUtils.mv(filename, "#{filename}.moved")
|
||||
end
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then I should see "HELLO FROM A PAGE" in "_site/index.html.moved"
|
||||
|
||||
Scenario: Alter a post right after it is initialized
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :posts, :post_init do |post|
|
||||
post.data['harold'] = "content for entry1.".tr!('abcdefghijklmnopqrstuvwxyz',
|
||||
'nopqrstuvwxyzabcdefghijklm')
|
||||
end
|
||||
"""
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2015-03-14 | nil | {{ page.harold }} |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "pbagrag sbe ragel1." in "_site/2015/03/14/entry1.html"
|
||||
|
||||
Scenario: Alter the payload for certain posts
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
# Add myvar = 'old' to posts before 2015-03-15, and myvar = 'new' for
|
||||
# others
|
||||
Jekyll::Hooks.register :posts, :pre_render do |post, payload|
|
||||
if post.date < Time.new(2015, 3, 15)
|
||||
payload['myvar'] = 'old'
|
||||
else
|
||||
payload['myvar'] = 'new'
|
||||
end
|
||||
end
|
||||
"""
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2015-03-14 | nil | {{ myvar }} post |
|
||||
| entry2 | 2015-03-15 | nil | {{ myvar }} post |
|
||||
When I run jekyll build
|
||||
Then I should see "old post" in "_site/2015/03/14/entry1.html"
|
||||
And I should see "new post" in "_site/2015/03/15/entry2.html"
|
||||
|
||||
Scenario: Modify post contents before writing to disk
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
# Replace content after rendering
|
||||
Jekyll::Hooks.register :posts, :post_render do |post|
|
||||
post.output.gsub! /42/, 'the answer to life, the universe and everything'
|
||||
end
|
||||
"""
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2015-03-14 | nil | {{ 6 \| times: 7 }} |
|
||||
| entry2 | 2015-03-15 | nil | {{ 6 \| times: 8 }} |
|
||||
When I run jekyll build
|
||||
Then I should see "the answer to life, the universe and everything" in "_site/2015/03/14/entry1.html"
|
||||
And I should see "48" in "_site/2015/03/15/entry2.html"
|
||||
|
||||
Scenario: Work with a post after writing it to disk
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
# Log all post filesystem writes
|
||||
Jekyll::Hooks.register :posts, :post_write do |post|
|
||||
filename = post.destination(post.site.dest)
|
||||
open('_site/post-build.log', 'a') do |f|
|
||||
f.puts "Wrote #{filename} at #{Time.now}"
|
||||
end
|
||||
end
|
||||
"""
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2015-03-14 | nil | entry one |
|
||||
| entry2 | 2015-03-15 | nil | entry two |
|
||||
When I run jekyll build
|
||||
Then I should see "_site/2015/03/14/entry1.html at" in "_site/post-build.log"
|
||||
Then I should see "_site/2015/03/15/entry2.html at" in "_site/post-build.log"
|
||||
|
||||
Scenario: Register a hook on multiple owners at the same time
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register [:pages, :posts], :post_render do |owner|
|
||||
owner.output = "{{{{{ #{owner.output.chomp} }}}}}"
|
||||
end
|
||||
"""
|
||||
And I have a "index.html" page that contains "WRAP ME"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2015-03-14 | nil | entry one |
|
||||
When I run jekyll build
|
||||
Then I should see "{{{{{ WRAP ME }}}}}" in "_site/index.html"
|
||||
And I should see "{{{{{ <p>entry one</p> }}}}}" in "_site/2015/03/14/entry1.html"
|
||||
|
||||
Scenario: Allow hooks to have a named priority
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :pages, :post_render, priority: :normal do |owner|
|
||||
# first normal runs second
|
||||
owner.output = "1 #{owner.output.chomp}"
|
||||
end
|
||||
Jekyll::Hooks.register :pages, :post_render, priority: :high do |owner|
|
||||
# high runs last
|
||||
owner.output = "2 #{owner.output.chomp}"
|
||||
end
|
||||
Jekyll::Hooks.register :pages, :post_render do |owner|
|
||||
# second normal runs third (normal is default)
|
||||
owner.output = "3 #{owner.output.chomp}"
|
||||
end
|
||||
Jekyll::Hooks.register :pages, :post_render, priority: :low do |owner|
|
||||
# low runs first
|
||||
owner.output = "4 #{owner.output.chomp}"
|
||||
end
|
||||
"""
|
||||
And I have a "index.html" page that contains "WRAP ME"
|
||||
When I run jekyll build
|
||||
Then I should see "2 3 1 4 WRAP ME" in "_site/index.html"
|
||||
|
||||
Scenario: Alter a document right after it is initialized
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :documents, :pre_render do |doc, payload|
|
||||
doc.data['text'] = doc.data['text'] << ' are belong to us'
|
||||
end
|
||||
"""
|
||||
And I have a "_config.yml" file that contains "collections: [ memes ]"
|
||||
And I have a _memes directory
|
||||
And I have a "_memes/doc1.md" file with content:
|
||||
"""
|
||||
---
|
||||
text: all your base
|
||||
---
|
||||
"""
|
||||
And I have an "index.md" file with content:
|
||||
"""
|
||||
---
|
||||
---
|
||||
{{ site.memes.first.text }}
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "all your base are belong to us" in "_site/index.html"
|
||||
|
||||
Scenario: Update a document after rendering it, but before writing it to disk
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :documents, :post_render do |doc|
|
||||
doc.output.gsub! /<p>/, '<p class="meme">'
|
||||
end
|
||||
"""
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
memes:
|
||||
output: true
|
||||
"""
|
||||
And I have a _memes directory
|
||||
And I have a "_memes/doc1.md" file with content:
|
||||
"""
|
||||
---
|
||||
text: all your base are belong to us
|
||||
---
|
||||
{{ page.text }}
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "<p class=\"meme\">all your base are belong to us" in "_site/memes/doc1.html"
|
||||
|
||||
Scenario: Perform an action after every document is written
|
||||
Given I have a _plugins directory
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :documents, :post_write do |doc|
|
||||
open('_site/document-build.log', 'a') do |f|
|
||||
f.puts "Wrote document #{doc.collection.docs.index doc} at #{Time.now}"
|
||||
end
|
||||
end
|
||||
"""
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
memes:
|
||||
output: true
|
||||
"""
|
||||
And I have a _memes directory
|
||||
And I have a "_memes/doc1.md" file with content:
|
||||
"""
|
||||
---
|
||||
text: all your base are belong to us
|
||||
---
|
||||
{{ page.text }}
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Wrote document 0" in "_site/document-build.log"
|
||||
@@ -9,15 +9,15 @@ Feature: Include tags
|
||||
And I have an "_includes/params.html" file that contains "Parameters:<ul>{% for param in include %}<li>{{param[0]}} = {{param[1]}}</li>{% endfor %}</ul>"
|
||||
And I have an "_includes/ignore.html" file that contains "<footer>My blog footer</footer>"
|
||||
And I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| Include Files | 2013-03-21 | default | {% include header.html param="myparam" %} |
|
||||
| Ignore params if unused | 2013-03-21 | default | {% include ignore.html date="today" %} |
|
||||
| List multiple parameters | 2013-03-21 | default | {% include params.html date="today" start="tomorrow" %} |
|
||||
| Dont keep parameters | 2013-03-21 | default | {% include ignore.html param="test" %}\n{% include header.html %} |
|
||||
| Allow params with spaces and quotes | 2013-04-07 | default | {% include params.html cool="param with spaces" super="\"quoted\"" single='has "quotes"' escaped='\'single\' quotes' %} |
|
||||
| Parameter syntax | 2013-04-12 | default | {% include params.html param1_or_2="value" %} |
|
||||
| Pass a variable | 2013-06-22 | default | {% assign var = 'some text' %}{% include params.html local=var layout=page.layout %} |
|
||||
And I have the following posts:
|
||||
| title | date | type | content |
|
||||
| Include Files | 2013-03-21 | html | {% include header.html param="myparam" %} |
|
||||
| Ignore params if unused | 2013-03-21 | html | {% include ignore.html date="today" %} |
|
||||
| List multiple parameters | 2013-03-21 | html | {% include params.html date="today" start="tomorrow" %} |
|
||||
| Dont keep parameters | 2013-03-21 | html | {% include ignore.html param="test" %}\n{% include header.html %} |
|
||||
| Allow params with spaces and quotes | 2013-04-07 | html | {% include params.html cool="param with spaces" super="\"quoted\"" single='has "quotes"' escaped='\'single\' quotes' %} |
|
||||
| Parameter syntax | 2013-04-12 | html | {% include params.html param1_or_2="value" %} |
|
||||
| Pass a variable | 2013-06-22 | html | {% assign var = 'some text' %}{% include params.html local=var title=page.title %} |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "<header>My awesome blog header: myparam</header>" in "_site/2013/03/21/include-files.html"
|
||||
@@ -27,12 +27,12 @@ Feature: Include tags
|
||||
And I should not see "<header>My awesome blog header: myparam</header>" in "_site/2013/03/21/dont-keep-parameters.html"
|
||||
But I should see "<header>My awesome blog header: </header>" in "_site/2013/03/21/dont-keep-parameters.html"
|
||||
And I should see "<li>cool = param with spaces</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
|
||||
And I should see "<li>super = “quoted”</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
|
||||
And I should see "<li>single = has “quotes”</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
|
||||
And I should see "<li>escaped = ‘single’ quotes</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
|
||||
And I should see "<li>super = \"quoted\"</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
|
||||
And I should see "<li>single = has \"quotes\"</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
|
||||
And I should see "<li>escaped = 'single' quotes</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html"
|
||||
And I should see "<li>param1_or_2 = value</li>" in "_site/2013/04/12/parameter-syntax.html"
|
||||
And I should see "<li>local = some text</li>" in "_site/2013/06/22/pass-a-variable.html"
|
||||
And I should see "<li>layout = default</li>" in "_site/2013/06/22/pass-a-variable.html"
|
||||
And I should see "<li>title = Pass a variable</li>" in "_site/2013/06/22/pass-a-variable.html"
|
||||
|
||||
Scenario: Include a file from a variable
|
||||
Given I have an _includes directory
|
||||
|
||||
@@ -10,26 +10,26 @@ Feature: Incremental rebuild
|
||||
| title | date | layout | content |
|
||||
| Wargames | 2009-03-27 | default | The only winning move is not to play. |
|
||||
And I have a default layout that contains "Post Layout: {{ content }}"
|
||||
When I run jekyll build
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
||||
When I run jekyll build
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
||||
|
||||
Scenario: Generate a metadata file
|
||||
Given I have an "index.html" file that contains "Basic Site"
|
||||
When I run jekyll build
|
||||
When I run jekyll build -I
|
||||
Then the ".jekyll-metadata" file should exist
|
||||
|
||||
Scenario: Rebuild when content is changed
|
||||
Given I have an "index.html" file that contains "Basic Site"
|
||||
When I run jekyll build
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
And I should see "Basic Site" in "_site/index.html"
|
||||
When I wait 1 second
|
||||
Then I have an "index.html" file that contains "Bacon Site"
|
||||
When I run jekyll build
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
And I should see "Bacon Site" in "_site/index.html"
|
||||
|
||||
@@ -37,12 +37,12 @@ Feature: Incremental rebuild
|
||||
Given I have a _layouts directory
|
||||
And I have an "index.html" page with layout "default" that contains "Basic Site with Layout"
|
||||
And I have a default layout that contains "Page Layout: {{ content }}"
|
||||
When I run jekyll build
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: Basic Site with Layout" in "_site/index.html"
|
||||
When I wait 1 second
|
||||
Then I have a default layout that contains "Page Layout Changed: {{ content }}"
|
||||
When I run jekyll build --full-rebuild
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout Changed: Basic Site with Layout" in "_site/index.html"
|
||||
|
||||
@@ -50,11 +50,11 @@ Feature: Incremental rebuild
|
||||
Given I have a _includes directory
|
||||
And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}"
|
||||
And I have an "_includes/about.textile" file that contains "Generated by Jekyll"
|
||||
When I run jekyll build
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
|
||||
When I wait 1 second
|
||||
Then I have an "_includes/about.textile" file that contains "Regenerated by Jekyll"
|
||||
When I run jekyll build
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Regenerated by Jekyll" in "_site/index.html"
|
||||
|
||||
@@ -17,7 +17,10 @@ Feature: Markdown
|
||||
And I should see "<h1 id=\"my-title\">My Title</h1>" in "_site/index.html"
|
||||
|
||||
Scenario: Markdown in pagination on index
|
||||
Given I have a configuration file with "paginate" set to "5"
|
||||
Given I have a configuration file with:
|
||||
| key | value |
|
||||
| paginate | 5 |
|
||||
| gems | [jekyll-paginate] |
|
||||
And I have an "index.html" page that contains "Index - {% for post in paginator.posts %} {{ post.content }} {% endfor %}"
|
||||
And I have a _posts directory
|
||||
And I have the following post:
|
||||
@@ -27,41 +30,3 @@ Feature: Markdown
|
||||
Then the _site directory should exist
|
||||
And I should see "Index" in "_site/index.html"
|
||||
And I should see "<h1 id=\"my-title\">My Title</h1>" in "_site/index.html"
|
||||
|
||||
Scenario: Maruku fenced codeblocks
|
||||
Given I have a configuration file with "markdown" set to "maruku"
|
||||
And I have an "index.markdown" file with content:
|
||||
"""
|
||||
---
|
||||
title: My title
|
||||
---
|
||||
|
||||
# My title
|
||||
|
||||
```
|
||||
My awesome code
|
||||
```
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "My awesome code" in "_site/index.html"
|
||||
And I should see "<pre><code>My awesome code</code></pre>" in "_site/index.html"
|
||||
|
||||
Scenario: Maruku fenced codeblocks with syntax highlighting
|
||||
Given I have a configuration file with "markdown" set to "maruku"
|
||||
And I have an "index.markdown" file with content:
|
||||
"""
|
||||
---
|
||||
title: My title
|
||||
---
|
||||
|
||||
# My title
|
||||
|
||||
```ruby
|
||||
puts "My awesome string"
|
||||
```
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "My awesome string" in "_site/index.html"
|
||||
And I should see "<pre class="ruby"><code class="ruby">puts "My awesome string"</code></pre>" in "_site/index.html"
|
||||
|
||||
@@ -4,7 +4,10 @@ Feature: Site pagination
|
||||
I want divide the posts in several pages
|
||||
|
||||
Scenario Outline: Paginate with N posts per page
|
||||
Given I have a configuration file with "paginate" set to "<num>"
|
||||
Given I have a configuration file with:
|
||||
| key | value |
|
||||
| paginate | <num> |
|
||||
| gems | [jekyll-paginate] |
|
||||
And I have a _layouts directory
|
||||
And I have an "index.html" page that contains "{{ paginator.posts.size }}"
|
||||
And I have a _posts directory
|
||||
@@ -32,6 +35,7 @@ Feature: Site pagination
|
||||
| paginate | 1 |
|
||||
| paginate_path | /blog/page-:num |
|
||||
| permalink | /blog/:year/:month/:day/:title |
|
||||
| gems | [jekyll-paginate] |
|
||||
And I have a blog directory
|
||||
And I have an "blog/index.html" page that contains "{{ paginator.posts.size }}"
|
||||
And I have a _posts directory
|
||||
@@ -59,6 +63,7 @@ Feature: Site pagination
|
||||
| paginate | 1 |
|
||||
| paginate_path | /blog/page/:num |
|
||||
| permalink | /blog/:year/:month/:day/:title |
|
||||
| gems | [jekyll-paginate] |
|
||||
And I have a blog directory
|
||||
And I have an "blog/index.html" page that contains "{{ paginator.posts.size }}"
|
||||
And I have an "index.html" page that contains "Don't pick me!"
|
||||
|
||||
@@ -39,7 +39,7 @@ Feature: Fancy permalinks
|
||||
And I have the following post:
|
||||
| title | category | date | content |
|
||||
| Custom Permalink Schema | stuff | 2009-03-27 | Totally custom. |
|
||||
And I have a configuration file with "permalink" set to "/blog/:year/:month/:day/:title"
|
||||
And I have a configuration file with "permalink" set to "/blog/:year/:month/:day/:title/"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally custom." in "_site/blog/2009/03/27/custom-permalink-schema/index.html"
|
||||
@@ -64,11 +64,24 @@ Feature: Fancy permalinks
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-schema.html"
|
||||
|
||||
Scenario: Use custom permalink schema with date and time
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | category | date | content |
|
||||
| Custom Permalink Schema | stuff | 2009-03-27 22:31:07 | Totally custom. |
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| permalink | "/:year:month:day:hour:minute:second.html" |
|
||||
| timezone | UTC |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally custom." in "_site/20090327223107.html"
|
||||
|
||||
Scenario: Use per-post permalink
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | permalink | content |
|
||||
| Some post | 2013-04-14 | /custom/posts/1 | bla bla |
|
||||
| Some post | 2013-04-14 | /custom/posts/1/ | bla bla |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the _site/custom/posts/1 directory should exist
|
||||
@@ -84,12 +97,26 @@ Feature: Fancy permalinks
|
||||
And the _site/custom/posts directory should exist
|
||||
And I should see "bla bla" in "_site/custom/posts/some.html"
|
||||
|
||||
Scenario: Use per-post ending in .htm
|
||||
Scenario: Use pretty permalink schema with cased file name
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | permalink | content |
|
||||
| Some post | 2013-04-14 | /custom/posts/some.htm | bla bla |
|
||||
And I have an "_posts/2009-03-27-Pretty-Permalink-Schema.md" page that contains "Totally wordpress"
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the _site/custom/posts directory should exist
|
||||
And I should see "bla bla" in "_site/custom/posts/some.htm"
|
||||
And I should see "Totally wordpress." in "_site/2009/03/27/Pretty-Permalink-Schema/index.html"
|
||||
|
||||
Scenario: Use custom permalink schema with cased file name
|
||||
Given I have a _posts directory
|
||||
And I have an "_posts/2009-03-27-Custom-Schema.md" page with title "Custom Schema" that contains "Totally awesome"
|
||||
And I have a configuration file with "permalink" set to "/:year/:month/:day/:slug/"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally awesome" in "_site/2009/03/27/custom-schema/index.html"
|
||||
|
||||
Scenario: Use pretty permalink schema with title containing underscore
|
||||
Given I have a _posts directory
|
||||
And I have an "_posts/2009-03-27-Custom_Schema.md" page with title "Custom Schema" that contains "Totally awesome"
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally awesome" in "_site/2009/03/27/Custom_Schema/index.html"
|
||||
|
||||
@@ -36,6 +36,20 @@ Feature: Post data
|
||||
Then the _site directory should exist
|
||||
And I should see "Post date: 27 Mar 2009" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.date variable with invalid
|
||||
Given I have a _posts directory
|
||||
And I have a "_posts/2016-01-01-test.md" page with date "tuesday" that contains "I have a bad date."
|
||||
When I run jekyll build
|
||||
Then the _site directory should not exist
|
||||
And I should see "Document '_posts/2016-01-01-test.md' does not have a valid date in the YAML front matter." in the build output
|
||||
|
||||
Scenario: Invalid date in filename
|
||||
Given I have a _posts directory
|
||||
And I have a "_posts/2016-22-01-test.md" page that contains "I have a bad date."
|
||||
When I run jekyll build
|
||||
Then the _site directory should not exist
|
||||
And I should see "Document '_posts/2016-22-01-test.md' does not have a valid date in the filename." in the build output
|
||||
|
||||
Scenario: Use post.id variable
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
@@ -141,7 +155,7 @@ Feature: Post data
|
||||
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
|
||||
And I should see "Post categories: scifi and Movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when category is in YAML
|
||||
Given I have a _posts directory
|
||||
@@ -163,7 +177,7 @@ Feature: Post data
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
And I should see "Post category: Movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in YAML
|
||||
Given I have a _posts directory
|
||||
@@ -187,6 +201,24 @@ Feature: Post data
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Superdirectories of _posts applied to post.categories
|
||||
Given I have a movies/_posts directory
|
||||
And I have a "movies/_posts/2009-03-27-star-wars.html" page with layout "simple" that contains "hi"
|
||||
And I have a _layouts directory
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Subdirectories of _posts not applied to post.categories
|
||||
Given I have a movies/_posts/scifi directory
|
||||
And I have a "movies/_posts/scifi/2009-03-27-star-wars.html" page with layout "simple" that contains "hi"
|
||||
And I have a _layouts directory
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in YAML with mixed case
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
@@ -197,8 +229,8 @@ Feature: Post data
|
||||
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
|
||||
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2013/03/17/star-trek.html"
|
||||
And I should see "Post categories: scifi and Movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
|
||||
And I should see "Post categories: SciFi and movies" in "_site/scifi/movies/2013/03/17/star-trek.html"
|
||||
|
||||
Scenario Outline: Use page.path variable
|
||||
Given I have a <dir>/_posts directory
|
||||
|
||||
@@ -46,5 +46,5 @@ Feature: Post excerpts
|
||||
And the _site/2007/12 directory should exist
|
||||
And the _site/2007/12/31 directory should exist
|
||||
And the "_site/2007/12/31/entry1.html" file should exist
|
||||
And I should see exactly "<p>content for entry1.</p>" in "_site/index.html"
|
||||
And I should see exactly "<html><head></head><body><p>content for entry1.</p></body></html>" in "_site/2007/12/31/entry1.html"
|
||||
And I should see "<p>content for entry1.</p>" in "_site/index.html"
|
||||
And I should see "<html><head></head><body><p>content for entry1.</p>\n</body></html>" in "_site/2007/12/31/entry1.html"
|
||||
|
||||
@@ -5,6 +5,13 @@ Feature: Rendering
|
||||
But I want to make it as simply as possible
|
||||
So render with Liquid and place in Layouts
|
||||
|
||||
Scenario: When receiving bad Liquid
|
||||
Given I have a "index.html" page with layout "simple" that contains "{% include invalid.html %}"
|
||||
And I have a simple layout that contains "{{ content }}"
|
||||
When I run jekyll build
|
||||
Then I should get a non-zero exit-status
|
||||
And I should see "Liquid Exception" in the build output
|
||||
|
||||
Scenario: Render Liquid and place in layout
|
||||
Given I have a "index.html" page with layout "simple" that contains "Hi there, Jekyll {{ jekyll.environment }}!"
|
||||
And I have a simple layout that contains "{{ content }}Ahoy, indeed!"
|
||||
@@ -15,6 +22,7 @@ Feature: Rendering
|
||||
Scenario: Don't place asset files in layout
|
||||
Given I have an "index.scss" page with layout "simple" that contains ".foo-bar { color:black; }"
|
||||
And I have an "index.coffee" page with layout "simple" that contains "whatever()"
|
||||
And I have a configuration file with "gems" set to "[jekyll-coffeescript]"
|
||||
And I have a simple layout that contains "{{ content }}Ahoy, indeed!"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
@@ -28,8 +36,15 @@ Feature: Rendering
|
||||
Then the _site directory should exist
|
||||
And I should see ".foo-bar {\n color: red; }" in "_site/index.css"
|
||||
|
||||
Scenario: Render liquid in CoffeeScript
|
||||
Scenario: Not render liquid in CoffeeScript without explicitly including jekyll-coffeescript
|
||||
Given I have an "index.coffee" page with animal "cicada" that contains "hey='for {{page.animal}}'"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the "_site/index.js" file should not exist
|
||||
|
||||
Scenario: Render liquid in CoffeeScript with jekyll-coffeescript enabled
|
||||
Given I have an "index.coffee" page with animal "cicada" that contains "hey='for {{page.animal}}'"
|
||||
And I have a configuration file with "gems" set to "[jekyll-coffeescript]"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "hey = 'for cicada';" in "_site/index.js"
|
||||
|
||||
@@ -83,13 +83,6 @@ Feature: Site configuration
|
||||
Then the _site directory should exist
|
||||
And I should see "<a href=\"http://google.com\">Google</a>" in "_site/index.html"
|
||||
|
||||
Scenario: Use Maruku for markup
|
||||
Given I have an "index.markdown" page that contains "[Google](http://google.com)"
|
||||
And I have a configuration file with "markdown" set to "maruku"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "<a href=\"http://google.com\">Google</a>" in "_site/index.html"
|
||||
|
||||
Scenario: Highlight code with pygments
|
||||
Given I have an "index.html" page that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
|
||||
When I run jekyll build
|
||||
@@ -170,8 +163,8 @@ Feature: Site configuration
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: 2" in "_site/index.html"
|
||||
And I should see "Post Layout: <p>content for entry1.</p> built at 2013-04-09T23:22:00-04:00" in "_site/2013/04/09/entry1.html"
|
||||
And I should see "Post Layout: <p>content for entry2.</p> built at 2013-04-10T03:14:00-04:00" in "_site/2013/04/10/entry2.html"
|
||||
And I should see "Post Layout: <p>content for entry1.</p>\n built at 2013-04-09T23:22:00-04:00" in "_site/2013/04/09/entry1.html"
|
||||
And I should see "Post Layout: <p>content for entry2.</p>\n built at 2013-04-10T03:14:00-04:00" in "_site/2013/04/10/entry2.html"
|
||||
|
||||
Scenario: Generate proper dates with explicitly set timezone (different than posts' time)
|
||||
Given I have a _layouts directory
|
||||
@@ -180,19 +173,19 @@ Feature: Site configuration
|
||||
And I have an "index.html" page with layout "page" that contains "site index page"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| timezone | Australia/Melbourne |
|
||||
| timezone | Pacific/Honolulu |
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2013-04-09 23:22 -0400 | post | content for entry1. |
|
||||
| entry2 | 2013-04-10 03:14 -0400 | post | content for entry2. |
|
||||
| entry1 | 2013-04-09 23:22 +0400 | post | content for entry1. |
|
||||
| entry2 | 2013-04-10 03:14 +0400 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: 2" in "_site/index.html"
|
||||
And the "_site/2013/04/10/entry1.html" file should exist
|
||||
And the "_site/2013/04/10/entry2.html" file should exist
|
||||
And I should see escaped "Post Layout: <p>content for entry1.</p> built at 2013-04-10T13:22:00+10:00" in "_site/2013/04/10/entry1.html"
|
||||
And I should see escaped "Post Layout: <p>content for entry2.</p> built at 2013-04-10T17:14:00+10:00" in "_site/2013/04/10/entry2.html"
|
||||
And the "_site/2013/04/09/entry1.html" file should exist
|
||||
And the "_site/2013/04/09/entry2.html" file should exist
|
||||
And I should see "Post Layout: <p>content for entry1.</p>\n built at 2013-04-09T09:22:00-10:00" in "_site/2013/04/09/entry1.html"
|
||||
And I should see "Post Layout: <p>content for entry2.</p>\n built at 2013-04-09T13:14:00-10:00" in "_site/2013/04/09/entry2.html"
|
||||
|
||||
Scenario: Limit the number of posts generated by most recent date
|
||||
Given I have a _posts directory
|
||||
@@ -231,7 +224,7 @@ Feature: Site configuration
|
||||
| key | value |
|
||||
| time | 2010-01-01 |
|
||||
| future | true |
|
||||
| layouts | _theme |
|
||||
| layouts_dir | _theme |
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
|
||||
@@ -8,7 +8,7 @@ def file_content_from_hash(input_hash)
|
||||
input_hash['content']
|
||||
end
|
||||
|
||||
<<EOF
|
||||
<<-EOF
|
||||
---
|
||||
#{matter}
|
||||
---
|
||||
@@ -24,10 +24,13 @@ end
|
||||
After do
|
||||
FileUtils.rm_rf(TEST_DIR) if File.exist?(TEST_DIR)
|
||||
FileUtils.rm(JEKYLL_COMMAND_OUTPUT_FILE) if File.exist?(JEKYLL_COMMAND_OUTPUT_FILE)
|
||||
FileUtils.rm(JEKYLL_COMMAND_STATUS_FILE) if File.exist?(JEKYLL_COMMAND_STATUS_FILE)
|
||||
Dir.chdir(File.dirname(TEST_DIR))
|
||||
end
|
||||
|
||||
World(Test::Unit::Assertions)
|
||||
World do
|
||||
MinitestWorld.new
|
||||
end
|
||||
|
||||
Given /^I have a blank site in "(.*)"$/ do |path|
|
||||
FileUtils.mkdir_p(path) unless File.exist?(path)
|
||||
@@ -40,7 +43,7 @@ end
|
||||
# Like "I have a foo file" but gives a yaml front matter so jekyll actually processes it
|
||||
Given /^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$/ do |file, key, value, text|
|
||||
File.open(file, 'w') do |f|
|
||||
f.write <<EOF
|
||||
f.write <<-EOF
|
||||
---
|
||||
#{key || 'layout'}: #{value || 'nil'}
|
||||
---
|
||||
@@ -84,7 +87,7 @@ end
|
||||
Given /^I have the following (draft|page|post)s?(?: (in|under) "([^"]+)")?:$/ do |status, direction, folder, table|
|
||||
table.hashes.each do |input_hash|
|
||||
title = slug(input_hash['title'])
|
||||
ext = input_hash['type'] || 'textile'
|
||||
ext = input_hash['type'] || 'markdown'
|
||||
before, after = location(folder, direction)
|
||||
|
||||
case status
|
||||
@@ -168,6 +171,12 @@ When /^I delete the file "(.*)"$/ do |file|
|
||||
File.delete(file)
|
||||
end
|
||||
|
||||
##################
|
||||
#
|
||||
# Checking stuff
|
||||
#
|
||||
##################
|
||||
|
||||
Then /^the (.*) directory should +exist$/ do |dir|
|
||||
assert File.directory?(dir), "The directory \"#{dir}\" does not exist"
|
||||
end
|
||||
@@ -185,7 +194,7 @@ Then /^I should see exactly "(.*)" in "(.*)"$/ do |text, file|
|
||||
end
|
||||
|
||||
Then /^I should not see "(.*)" in "(.*)"$/ do |text, file|
|
||||
assert_no_match Regexp.new(text, Regexp::MULTILINE), file_contents(file)
|
||||
refute_match Regexp.new(text, Regexp::MULTILINE), file_contents(file)
|
||||
end
|
||||
|
||||
Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file|
|
||||
@@ -219,3 +228,7 @@ end
|
||||
Then /^I should see "(.*)" in the build output$/ do |text|
|
||||
assert_match Regexp.new(text), jekyll_run_output
|
||||
end
|
||||
|
||||
Then /^I should get a non-zero exit(?:\-| )status$/ do
|
||||
assert jekyll_run_status > 0
|
||||
end
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
require 'fileutils'
|
||||
require 'posix-spawn'
|
||||
require 'rr'
|
||||
require 'test/unit'
|
||||
require 'minitest/spec'
|
||||
require 'time'
|
||||
|
||||
class MinitestWorld
|
||||
extend Minitest::Assertions
|
||||
attr_accessor :assertions
|
||||
|
||||
def initialize
|
||||
self.assertions = 0
|
||||
end
|
||||
end
|
||||
|
||||
JEKYLL_SOURCE_DIR = File.dirname(File.dirname(File.dirname(__FILE__)))
|
||||
TEST_DIR = File.expand_path(File.join('..', '..', 'tmp', 'jekyll'), File.dirname(__FILE__))
|
||||
JEKYLL_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll'))
|
||||
JEKYLL_COMMAND_OUTPUT_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_output.txt')
|
||||
JEKYLL_COMMAND_STATUS_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_status.txt')
|
||||
|
||||
def source_dir(*files)
|
||||
File.join(TEST_DIR, *files)
|
||||
@@ -28,12 +37,20 @@ def jekyll_output_file
|
||||
JEKYLL_COMMAND_OUTPUT_FILE
|
||||
end
|
||||
|
||||
def jekyll_status_file
|
||||
JEKYLL_COMMAND_STATUS_FILE
|
||||
end
|
||||
|
||||
def jekyll_run_output
|
||||
File.read(jekyll_output_file) if File.file?(jekyll_output_file)
|
||||
end
|
||||
|
||||
def jekyll_run_status
|
||||
(File.read(jekyll_status_file) rescue 0).to_i
|
||||
end
|
||||
|
||||
def run_bundle(args)
|
||||
child = run_in_shell('bundle', *args.strip.split(' '))
|
||||
run_in_shell('bundle', *args.strip.split(' '))
|
||||
end
|
||||
|
||||
def run_jekyll(args)
|
||||
@@ -41,8 +58,21 @@ def run_jekyll(args)
|
||||
child.status.exitstatus == 0
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# XXX: POSIX::Spawn::Child does not write output when the exit status is > 0
|
||||
# for example when doing [:out, :err] => [file, "w"] it will skip
|
||||
# writing the file entirely, we sould switch to Open.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def run_in_shell(*args)
|
||||
POSIX::Spawn::Child.new *args, :out => [JEKYLL_COMMAND_OUTPUT_FILE, "w"]
|
||||
spawned = POSIX::Spawn::Child.new(*args)
|
||||
status = spawned.status.exitstatus
|
||||
File.write(JEKYLL_COMMAND_STATUS_FILE, status)
|
||||
File.open(JEKYLL_COMMAND_OUTPUT_FILE, "w+") do |file|
|
||||
status == 0 ? file.write(spawned.out) : file.write(spawned.err)
|
||||
end
|
||||
|
||||
spawned
|
||||
end
|
||||
|
||||
def slug(title)
|
||||
|
||||
22
jekyll-docs.gemspec
Normal file
22
jekyll-docs.gemspec
Normal file
@@ -0,0 +1,22 @@
|
||||
# coding: utf-8
|
||||
lib = File.expand_path('../lib', __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'jekyll/version'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = 'jekyll-docs'
|
||||
spec.version = Jekyll::VERSION
|
||||
spec.authors = ['Parker Moore']
|
||||
spec.email = ['parkrmoore@gmail.com']
|
||||
spec.summary = %q{Offline usage documentation for Jekyll.}
|
||||
spec.homepage = 'http://jekyllrb.com'
|
||||
spec.license = 'MIT'
|
||||
|
||||
spec.files = `git ls-files -z`.split("\x0").grep(%r{^site/})
|
||||
spec.require_paths = ['lib']
|
||||
|
||||
spec.add_dependency 'jekyll', Jekyll::VERSION
|
||||
|
||||
spec.add_development_dependency 'bundler', '~> 1.7'
|
||||
spec.add_development_dependency 'rake', '~> 10.0'
|
||||
end
|
||||
@@ -33,16 +33,7 @@ Gem::Specification.new do |s|
|
||||
s.add_runtime_dependency('mercenary', '~> 0.3.3')
|
||||
s.add_runtime_dependency('safe_yaml', '~> 1.0')
|
||||
s.add_runtime_dependency('colorator', '~> 0.1')
|
||||
|
||||
# Before 3.0 drops, phase the following gems out as dev dependencies
|
||||
# and gracefully handle their absence.
|
||||
s.add_runtime_dependency('pygments.rb', '~> 0.6.0')
|
||||
s.add_runtime_dependency('redcarpet', '~> 3.1')
|
||||
s.add_runtime_dependency('toml', '~> 0.1.0')
|
||||
s.add_runtime_dependency('jekyll-paginate', '~> 1.0')
|
||||
s.add_runtime_dependency('jekyll-gist', '~> 1.0')
|
||||
s.add_runtime_dependency('jekyll-coffeescript', '~> 1.0')
|
||||
s.add_runtime_dependency('rouge', '~> 1.7')
|
||||
s.add_runtime_dependency('jekyll-sass-converter', '~> 1.0')
|
||||
s.add_runtime_dependency('jekyll-watch', '~> 1.1')
|
||||
s.add_runtime_dependency('classifier-reborn', '~> 2.0')
|
||||
end
|
||||
|
||||
@@ -30,7 +30,6 @@ require 'kramdown'
|
||||
require 'colorator'
|
||||
|
||||
SafeYAML::OPTIONS[:suppress_warnings] = true
|
||||
Liquid::Template.error_mode = :strict
|
||||
|
||||
module Jekyll
|
||||
|
||||
@@ -48,16 +47,23 @@ module Jekyll
|
||||
autoload :External, 'jekyll/external'
|
||||
autoload :Filters, 'jekyll/filters'
|
||||
autoload :FrontmatterDefaults, 'jekyll/frontmatter_defaults'
|
||||
autoload :Hooks, 'jekyll/hooks'
|
||||
autoload :Layout, 'jekyll/layout'
|
||||
autoload :LayoutReader, 'jekyll/layout_reader'
|
||||
autoload :CollectionReader, 'jekyll/readers/collection_reader'
|
||||
autoload :DataReader, 'jekyll/readers/data_reader'
|
||||
autoload :LayoutReader, 'jekyll/readers/layout_reader'
|
||||
autoload :PostReader, 'jekyll/readers/post_reader'
|
||||
autoload :PageReader, 'jekyll/readers/page_reader'
|
||||
autoload :StaticFileReader, 'jekyll/readers/static_file_reader'
|
||||
autoload :LogAdapter, 'jekyll/log_adapter'
|
||||
autoload :Metadata, 'jekyll/metadata'
|
||||
autoload :Page, 'jekyll/page'
|
||||
autoload :PluginManager, 'jekyll/plugin_manager'
|
||||
autoload :Post, 'jekyll/post'
|
||||
autoload :Publisher, 'jekyll/publisher'
|
||||
autoload :Reader, 'jekyll/reader'
|
||||
autoload :Regenerator, 'jekyll/regenerator'
|
||||
autoload :RelatedPosts, 'jekyll/related_posts'
|
||||
autoload :Renderer, 'jekyll/renderer'
|
||||
autoload :LiquidRenderer, 'jekyll/liquid_renderer'
|
||||
autoload :Site, 'jekyll/site'
|
||||
autoload :StaticFile, 'jekyll/static_file'
|
||||
autoload :Stevenson, 'jekyll/stevenson'
|
||||
@@ -127,7 +133,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the new logger.
|
||||
def logger=(writer)
|
||||
@logger = LogAdapter.new(writer)
|
||||
@logger = LogAdapter.new(writer, (ENV["JEKYLL_LOG_LEVEL"] || :info).to_sym)
|
||||
end
|
||||
|
||||
# Public: An array of sites
|
||||
@@ -169,11 +175,4 @@ require_all 'jekyll/converters/markdown'
|
||||
require_all 'jekyll/generators'
|
||||
require_all 'jekyll/tags'
|
||||
|
||||
# Eventually remove these for 3.0 as non-core
|
||||
Jekyll::External.require_with_graceful_fail(%w[
|
||||
toml
|
||||
jekyll-paginate
|
||||
jekyll-gist
|
||||
jekyll-coffeescript
|
||||
jekyll-sass-converter
|
||||
])
|
||||
require 'jekyll-sass-converter'
|
||||
|
||||
@@ -1,103 +1,105 @@
|
||||
require 'set'
|
||||
|
||||
module Jekyll
|
||||
class Site
|
||||
# Handles the cleanup of a site's destination before it is built.
|
||||
class Cleaner
|
||||
attr_reader :site
|
||||
# Handles the cleanup of a site's destination before it is built.
|
||||
class Cleaner
|
||||
HIDDEN_FILE_REGEX = /\/\.{1,2}$/
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Cleans up the site's destination directory
|
||||
def cleanup!
|
||||
FileUtils.rm_rf(obsolete_files)
|
||||
FileUtils.rm_rf(metadata_file) if !@site.incremental?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Private: The list of files and directories to be deleted during cleanup process
|
||||
#
|
||||
# Returns an Array of the file and directory paths
|
||||
def obsolete_files
|
||||
(existing_files - new_files - new_dirs + replaced_files).to_a
|
||||
end
|
||||
|
||||
# Private: The metadata file storing dependency tree and build history
|
||||
#
|
||||
# Returns an Array with the metdata file as the only item
|
||||
def metadata_file
|
||||
[site.regenerator.metadata_file]
|
||||
end
|
||||
|
||||
# Private: The list of existing files, apart from those included in keep_files and hidden files.
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def existing_files
|
||||
files = Set.new
|
||||
regex = keep_file_regex
|
||||
dirs = keep_dirs
|
||||
|
||||
Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file|
|
||||
next if file =~ HIDDEN_FILE_REGEX || file =~ regex || dirs.include?(file)
|
||||
files << file
|
||||
end
|
||||
|
||||
# Cleans up the site's destination directory
|
||||
def cleanup!
|
||||
FileUtils.rm_rf(obsolete_files)
|
||||
FileUtils.rm_rf(metadata_file) if @site.full_rebuild?
|
||||
end
|
||||
files
|
||||
end
|
||||
|
||||
private
|
||||
# Private: The list of files to be created when site is built.
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def new_files
|
||||
files = Set.new
|
||||
site.each_site_file { |item| files << item.destination(site.dest) }
|
||||
files
|
||||
end
|
||||
|
||||
# Private: The list of files and directories to be deleted during cleanup process
|
||||
#
|
||||
# Returns an Array of the file and directory paths
|
||||
def obsolete_files
|
||||
(existing_files - new_files - new_dirs + replaced_files).to_a
|
||||
end
|
||||
# Private: The list of directories to be created when site is built.
|
||||
# These are the parent directories of the files in #new_files.
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
def new_dirs
|
||||
new_files.map { |file| parent_dirs(file) }.flatten.to_set
|
||||
end
|
||||
|
||||
# Private: The metadata file storing dependency tree and build history
|
||||
#
|
||||
# Returns an Array with the metdata file as the only item
|
||||
def metadata_file
|
||||
[site.metadata.metadata_file]
|
||||
# Private: The list of parent directories of a given file
|
||||
#
|
||||
# Returns an Array with the directory paths
|
||||
def parent_dirs(file)
|
||||
parent_dir = File.dirname(file)
|
||||
if parent_dir == site.dest
|
||||
[]
|
||||
else
|
||||
[parent_dir] + parent_dirs(parent_dir)
|
||||
end
|
||||
end
|
||||
|
||||
# Private: The list of existing files, apart from those included in keep_files and hidden files.
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def existing_files
|
||||
files = Set.new
|
||||
Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file|
|
||||
files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex || keep_dirs.include?(file)
|
||||
end
|
||||
files
|
||||
end
|
||||
# Private: The list of existing files that will be replaced by a directory during build
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def replaced_files
|
||||
new_dirs.select { |dir| File.file?(dir) }.to_set
|
||||
end
|
||||
|
||||
# Private: The list of files to be created when site is built.
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def new_files
|
||||
files = Set.new
|
||||
site.each_site_file { |item| files << item.destination(site.dest) }
|
||||
files
|
||||
end
|
||||
# Private: The list of directories that need to be kept because they are parent directories
|
||||
# of files specified in keep_files
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
def keep_dirs
|
||||
site.keep_files.map { |file| parent_dirs(site.in_dest_dir(file)) }.flatten.to_set
|
||||
end
|
||||
|
||||
# Private: The list of directories to be created when site is built.
|
||||
# These are the parent directories of the files in #new_files.
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
def new_dirs
|
||||
new_files.map { |file| parent_dirs(file) }.flatten.to_set
|
||||
end
|
||||
|
||||
# Private: The list of parent directories of a given file
|
||||
#
|
||||
# Returns an Array with the directory paths
|
||||
def parent_dirs(file)
|
||||
parent_dir = File.dirname(file)
|
||||
if parent_dir == site.dest
|
||||
[]
|
||||
else
|
||||
[parent_dir] + parent_dirs(parent_dir)
|
||||
end
|
||||
end
|
||||
|
||||
# Private: The list of existing files that will be replaced by a directory during build
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def replaced_files
|
||||
new_dirs.select { |dir| File.file?(dir) }.to_set
|
||||
end
|
||||
|
||||
# Private: The list of directories that need to be kept because they are parent directories
|
||||
# of files specified in keep_files
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
def keep_dirs
|
||||
site.keep_files.map { |file| parent_dirs(site.in_dest_dir(file)) }.flatten.to_set
|
||||
end
|
||||
|
||||
# Private: Creates a regular expression from the config's keep_files array
|
||||
#
|
||||
# Examples
|
||||
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
||||
#
|
||||
# Returns the regular expression
|
||||
def keep_file_regex
|
||||
or_list = site.keep_files.join("|")
|
||||
pattern = "\/(#{or_list.gsub(".", "\.")})"
|
||||
Regexp.new pattern
|
||||
end
|
||||
# Private: Creates a regular expression from the config's keep_files array
|
||||
#
|
||||
# Examples
|
||||
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
||||
#
|
||||
# Returns the regular expression
|
||||
def keep_file_regex
|
||||
Regexp.union(site.keep_files)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module Jekyll
|
||||
class Collection
|
||||
attr_reader :site, :label, :metadata
|
||||
attr_writer :docs
|
||||
|
||||
# Create a new Collection.
|
||||
#
|
||||
@@ -22,6 +23,23 @@ module Jekyll
|
||||
@docs ||= []
|
||||
end
|
||||
|
||||
# Override of normal respond_to? to match method_missing's logic for
|
||||
# looking in @data.
|
||||
def respond_to?(method, include_private = false)
|
||||
docs.respond_to?(method.to_sym, include_private) || super
|
||||
end
|
||||
|
||||
# Override of method_missing to check in @data for the key.
|
||||
def method_missing(method, *args, &blck)
|
||||
if docs.respond_to?(method.to_sym)
|
||||
Jekyll.logger.warn "Deprecation:", "Collection##{method} should be called on the #docs array directly."
|
||||
Jekyll.logger.warn "", "Called by #{caller.first}."
|
||||
docs.public_send(method.to_sym, *args, &blck)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
# Fetch the static files in this collection.
|
||||
# Defaults to an empty array if no static files have been read in.
|
||||
#
|
||||
@@ -40,7 +58,7 @@ module Jekyll
|
||||
if Utils.has_yaml_header? full_path
|
||||
doc = Jekyll::Document.new(full_path, { site: site, collection: self })
|
||||
doc.read
|
||||
docs << doc if site.publisher.publish?(doc)
|
||||
docs << doc if site.publisher.publish?(doc) || !write?
|
||||
else
|
||||
relative_dir = Jekyll.sanitized_path(relative_directory, File.dirname(file_path)).chomp("/.")
|
||||
files << StaticFile.new(site, site.source, relative_dir, File.basename(full_path), self)
|
||||
@@ -163,14 +181,16 @@ module Jekyll
|
||||
#
|
||||
# Returns true if the 'write' metadata is true, false otherwise.
|
||||
def write?
|
||||
!!metadata['output']
|
||||
!!metadata.fetch('output', false)
|
||||
end
|
||||
|
||||
# The URL template to render collection's documents at.
|
||||
#
|
||||
# Returns the URL template to render collection's documents at.
|
||||
def url_template
|
||||
metadata.fetch('permalink', "/:collection/:path:output_ext")
|
||||
metadata.fetch('permalink') do
|
||||
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
||||
end
|
||||
end
|
||||
|
||||
# Extract options for this collection from the site configuration.
|
||||
|
||||
@@ -49,6 +49,8 @@ module Jekyll
|
||||
# Returns nothing
|
||||
def add_build_options(c)
|
||||
c.option 'config', '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
c.option 'destination', '-d', '--destination DESTINATION', 'The current folder will be generated into DESTINATION'
|
||||
c.option 'source', '-s', '--source SOURCE', 'Custom source directory'
|
||||
c.option 'future', '--future', 'Publishes posts with a future date'
|
||||
c.option 'limit_posts', '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish'
|
||||
c.option 'watch', '-w', '--[no-]watch', 'Watch for changes and rebuild'
|
||||
@@ -58,7 +60,7 @@ module Jekyll
|
||||
c.option 'unpublished', '--unpublished', 'Render posts that were marked as unpublished'
|
||||
c.option 'quiet', '-q', '--quiet', 'Silence output.'
|
||||
c.option 'verbose', '-V', '--verbose', 'Print verbose output.'
|
||||
c.option 'full_rebuild', '-f', '--full-rebuild', 'Disable incremental rebuild.'
|
||||
c.option 'incremental', '-I', '--incremental', 'Enable incremental rebuild.'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -23,7 +23,8 @@ module Jekyll
|
||||
# Build your jekyll site
|
||||
# Continuously watch if `watch` is set to true in the config.
|
||||
def process(options)
|
||||
Jekyll.logger.log_level = :error if options['quiet']
|
||||
# Adjust verbosity quickly
|
||||
Jekyll.logger.adjust_verbosity(options)
|
||||
|
||||
options = configuration_from_options(options)
|
||||
site = Jekyll::Site.new(options)
|
||||
@@ -48,15 +49,16 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def build(site, options)
|
||||
t = Time.now
|
||||
source = options['source']
|
||||
destination = options['destination']
|
||||
full_build = options['full_rebuild']
|
||||
incremental = options['incremental']
|
||||
Jekyll.logger.info "Source:", source
|
||||
Jekyll.logger.info "Destination:", destination
|
||||
Jekyll.logger.info "Incremental build:", (full_build ? "disabled" : "enabled")
|
||||
Jekyll.logger.info "Incremental build:", (incremental ? "enabled" : "disabled. Enable with --incremental")
|
||||
Jekyll.logger.info "Generating..."
|
||||
process_site(site)
|
||||
Jekyll.logger.info "", "done."
|
||||
Jekyll.logger.info "", "done in #{(Time.now - t).round(3)} seconds."
|
||||
end
|
||||
|
||||
# Private: Watch for file changes and rebuild the site.
|
||||
|
||||
@@ -8,6 +8,8 @@ module Jekyll
|
||||
c.syntax 'clean [subcommand]'
|
||||
c.description 'Clean the site (removes site output and metadata file) without building.'
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
c.action do |args, _|
|
||||
Jekyll::Commands::Clean.process({})
|
||||
end
|
||||
|
||||
@@ -30,29 +30,26 @@ module Jekyll
|
||||
|
||||
def healthy?(site)
|
||||
[
|
||||
fsnotify_buggy?(site),
|
||||
!deprecated_relative_permalinks(site),
|
||||
!conflicting_urls(site)
|
||||
].all?
|
||||
end
|
||||
|
||||
def deprecated_relative_permalinks(site)
|
||||
contains_deprecated_pages = false
|
||||
site.pages.each do |page|
|
||||
if page.uses_relative_permalinks
|
||||
Jekyll.logger.warn "Deprecation:", "'#{page.path}' uses relative" +
|
||||
" permalinks which will be deprecated in" +
|
||||
" Jekyll v2.0.0 and beyond."
|
||||
contains_deprecated_pages = true
|
||||
end
|
||||
if site.config['relative_permalinks']
|
||||
Jekyll::Deprecator.deprecation_message "Your site still uses relative" +
|
||||
" permalinks, which was removed in" +
|
||||
" Jekyll v3.0.0."
|
||||
return true
|
||||
end
|
||||
contains_deprecated_pages
|
||||
end
|
||||
|
||||
def conflicting_urls(site)
|
||||
conflicting_urls = false
|
||||
urls = {}
|
||||
urls = collect_urls(urls, site.pages, site.dest)
|
||||
urls = collect_urls(urls, site.posts, site.dest)
|
||||
urls = collect_urls(urls, site.posts.docs, site.dest)
|
||||
urls.each do |url, paths|
|
||||
if paths.size > 1
|
||||
conflicting_urls = true
|
||||
@@ -63,8 +60,23 @@ module Jekyll
|
||||
conflicting_urls
|
||||
end
|
||||
|
||||
private
|
||||
def fsnotify_buggy?(site)
|
||||
return true if !Utils::Platforms.osx?
|
||||
if Dir.pwd != `pwd`.strip
|
||||
Jekyll.logger.error " " + <<-STR.strip.gsub(/\n\s+/, "\n ")
|
||||
We have detected that there might be trouble using fsevent on your
|
||||
operating system, you can read https://github.com/thibaudgg/rb-fsevent/wiki/no-fsevents-fired-(OSX-bug)
|
||||
for possible work arounds or you can work around it immediately
|
||||
with `--force-polling`.
|
||||
STR
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
def collect_urls(urls, things, destination)
|
||||
things.each do |thing|
|
||||
dest = thing.destination(destination)
|
||||
|
||||
@@ -3,7 +3,7 @@ require 'erb'
|
||||
module Jekyll
|
||||
module Commands
|
||||
class New < Command
|
||||
class << self
|
||||
class << self
|
||||
def init_with_program(prog)
|
||||
prog.command(:new) do |c|
|
||||
c.syntax 'new PATH'
|
||||
@@ -11,7 +11,7 @@ module Jekyll
|
||||
|
||||
c.option 'force', '--force', 'Force creation even if PATH already exists'
|
||||
c.option 'blank', '--blank', 'Creates scaffolding but with empty files'
|
||||
|
||||
|
||||
c.action do |args, options|
|
||||
Jekyll::Commands::New.process(args, options)
|
||||
end
|
||||
@@ -76,7 +76,7 @@ module Jekyll
|
||||
def scaffold_path
|
||||
"_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ module Jekyll
|
||||
|
||||
s.mount(
|
||||
options['baseurl'],
|
||||
WEBrick::HTTPServlet::FileHandler,
|
||||
custom_file_handler,
|
||||
destination,
|
||||
file_handler_options
|
||||
)
|
||||
@@ -50,7 +50,7 @@ module Jekyll
|
||||
if options['detach'] # detach the server
|
||||
pid = Process.fork { s.start }
|
||||
Process.detach(pid)
|
||||
Jekyll.logger.info "Server detached with pid '#{pid}'.", "Run `kill -9 #{pid}' to stop the server."
|
||||
Jekyll.logger.info "Server detached with pid '#{pid}'.", "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
|
||||
else # create a new server thread, then join it with current terminal
|
||||
t = Thread.new { s.start }
|
||||
trap("INT") { s.shutdown }
|
||||
@@ -99,6 +99,21 @@ module Jekyll
|
||||
opts
|
||||
end
|
||||
|
||||
# Custom WEBrick FileHandler servlet for serving "/file.html" at "/file"
|
||||
# when no exact match is found. This mirrors the behavior of GitHub
|
||||
# Pages and many static web server configs.
|
||||
def custom_file_handler
|
||||
Class.new WEBrick::HTTPServlet::FileHandler do
|
||||
def search_file(req, res, basename)
|
||||
if file = super
|
||||
file
|
||||
else
|
||||
super(req, res, "#{basename}.html")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def start_callback(detached)
|
||||
unless detached
|
||||
Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
|
||||
|
||||
@@ -5,14 +5,15 @@ module Jekyll
|
||||
|
||||
# Default options. Overridden by values in _config.yml.
|
||||
# Strings rather than symbols are used for compatibility with YAML.
|
||||
DEFAULTS = {
|
||||
DEFAULTS = Configuration[{
|
||||
# Where things are
|
||||
'source' => Dir.pwd,
|
||||
'destination' => File.join(Dir.pwd, '_site'),
|
||||
'plugins' => '_plugins',
|
||||
'layouts' => '_layouts',
|
||||
'data_source' => '_data',
|
||||
'collections' => nil,
|
||||
'plugins_dir' => '_plugins',
|
||||
'layouts_dir' => '_layouts',
|
||||
'data_dir' => '_data',
|
||||
'includes_dir' => '_includes',
|
||||
'collections' => {},
|
||||
|
||||
# Handling Reading
|
||||
'safe' => false,
|
||||
@@ -21,13 +22,11 @@ module Jekyll
|
||||
'keep_files' => ['.git','.svn'],
|
||||
'encoding' => 'utf-8',
|
||||
'markdown_ext' => 'markdown,mkdown,mkdn,mkd,md',
|
||||
'textile_ext' => 'textile',
|
||||
'full_rebuild' => false,
|
||||
|
||||
# Filtering Content
|
||||
'show_drafts' => nil,
|
||||
'limit_posts' => 0,
|
||||
'future' => true, # remove and make true just default
|
||||
'future' => false,
|
||||
'unpublished' => false,
|
||||
|
||||
# Plugins
|
||||
@@ -36,9 +35,10 @@ module Jekyll
|
||||
|
||||
# Conversion
|
||||
'markdown' => 'kramdown',
|
||||
'highlighter' => 'pygments',
|
||||
'highlighter' => 'rouge',
|
||||
'lsi' => false,
|
||||
'excerpt_separator' => "\n\n",
|
||||
'incremental' => false,
|
||||
|
||||
# Serving
|
||||
'detach' => false, # default to not detaching the server
|
||||
@@ -46,26 +46,15 @@ module Jekyll
|
||||
'host' => '127.0.0.1',
|
||||
'baseurl' => '',
|
||||
|
||||
# Backwards-compatibility options
|
||||
'relative_permalinks' => false,
|
||||
|
||||
# Output Configuration
|
||||
'permalink' => 'date',
|
||||
'paginate_path' => '/page:num',
|
||||
'timezone' => nil, # use the local timezone
|
||||
|
||||
'quiet' => false,
|
||||
'verbose' => false,
|
||||
'defaults' => [],
|
||||
|
||||
'maruku' => {
|
||||
'use_tex' => false,
|
||||
'use_divs' => false,
|
||||
'png_engine' => 'blahtex',
|
||||
'png_dir' => 'images/latex',
|
||||
'png_url' => '/images/latex',
|
||||
'fenced_code_blocks' => true
|
||||
},
|
||||
|
||||
'rdiscount' => {
|
||||
'extensions' => []
|
||||
},
|
||||
@@ -90,12 +79,8 @@ module Jekyll
|
||||
'coderay_bold_every' => 10,
|
||||
'coderay_css' => 'style'
|
||||
}
|
||||
},
|
||||
|
||||
'redcloth' => {
|
||||
'hard_breaks' => true
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
# Public: Turn all keys into string
|
||||
#
|
||||
@@ -104,22 +89,33 @@ module Jekyll
|
||||
reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
|
||||
end
|
||||
|
||||
def get_config_value_with_override(config_key, override)
|
||||
override[config_key] || self[config_key] || DEFAULTS[config_key]
|
||||
end
|
||||
|
||||
# Public: Directory of the Jekyll source folder
|
||||
#
|
||||
# override - the command-line options hash
|
||||
#
|
||||
# Returns the path to the Jekyll source directory
|
||||
def source(override)
|
||||
override['source'] || self['source'] || DEFAULTS['source']
|
||||
get_config_value_with_override('source', override)
|
||||
end
|
||||
|
||||
def quiet?(override = {})
|
||||
override['quiet'] || self['quiet'] || DEFAULTS['quiet']
|
||||
def quiet(override = {})
|
||||
get_config_value_with_override('quiet', override)
|
||||
end
|
||||
alias_method :quiet?, :quiet
|
||||
|
||||
def verbose(override = {})
|
||||
get_config_value_with_override('verbose', override)
|
||||
end
|
||||
alias_method :verbose?, :verbose
|
||||
|
||||
def safe_load_file(filename)
|
||||
case File.extname(filename)
|
||||
when /\.toml/i
|
||||
Jekyll::External.require_with_graceful_fail('toml') unless defined?(TOML)
|
||||
TOML.load_file(filename)
|
||||
when /\.ya?ml/i
|
||||
SafeYAML.load_file(filename)
|
||||
@@ -134,14 +130,14 @@ module Jekyll
|
||||
#
|
||||
# Returns an Array of config files
|
||||
def config_files(override)
|
||||
# Be quiet quickly.
|
||||
Jekyll.logger.log_level = :error if quiet?(override)
|
||||
# Adjust verbosity quickly
|
||||
Jekyll.logger.adjust_verbosity(:quiet => quiet?(override), :verbose => verbose?(override))
|
||||
|
||||
# Get configuration from <source>/_config.yml or <source>/<config_file>
|
||||
config_files = override.delete('config')
|
||||
if config_files.to_s.empty?
|
||||
default = %w[yml yaml].find(Proc.new { 'yml' }) do |ext|
|
||||
File.exists? Jekyll.sanitized_path(source(override), "_config.#{ext}")
|
||||
File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}"))
|
||||
end
|
||||
config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
|
||||
@default_config_file = true
|
||||
@@ -190,7 +186,7 @@ module Jekyll
|
||||
$stderr.puts "#{err}"
|
||||
end
|
||||
|
||||
configuration.fix_common_issues.backwards_compatibilize
|
||||
configuration.fix_common_issues.backwards_compatibilize.add_default_collections
|
||||
end
|
||||
|
||||
# Public: Split a CSV string into an array containing its values
|
||||
@@ -210,7 +206,7 @@ module Jekyll
|
||||
config = clone
|
||||
# Provide backwards-compatibility
|
||||
if config.key?('auto') || config.key?('watch')
|
||||
Jekyll.logger.warn "Deprecation:", "Auto-regeneration can no longer" +
|
||||
Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" +
|
||||
" be set from your configuration file(s). Use the"+
|
||||
" --[no-]watch/-w command-line option instead."
|
||||
config.delete('auto')
|
||||
@@ -218,23 +214,19 @@ module Jekyll
|
||||
end
|
||||
|
||||
if config.key? 'server'
|
||||
Jekyll.logger.warn "Deprecation:", "The 'server' configuration option" +
|
||||
Jekyll::Deprecator.deprecation_message "The 'server' configuration option" +
|
||||
" is no longer accepted. Use the 'jekyll serve'" +
|
||||
" subcommand to serve your site with WEBrick."
|
||||
config.delete('server')
|
||||
end
|
||||
|
||||
if config.key? 'server_port'
|
||||
Jekyll.logger.warn "Deprecation:", "The 'server_port' configuration option" +
|
||||
" has been renamed to 'port'. Please update your config" +
|
||||
" file accordingly."
|
||||
# copy but don't overwrite:
|
||||
config['port'] = config['server_port'] unless config.key?('port')
|
||||
config.delete('server_port')
|
||||
end
|
||||
renamed_key 'server_port', 'port', config
|
||||
renamed_key 'plugins', 'plugins_dir', config
|
||||
renamed_key 'layouts', 'layouts_dir', config
|
||||
renamed_key 'data_source', 'data_dir', config
|
||||
|
||||
if config.key? 'pygments'
|
||||
Jekyll.logger.warn "Deprecation:", "The 'pygments' configuration option" +
|
||||
Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" +
|
||||
" has been renamed to 'highlighter'. Please update your" +
|
||||
" config file accordingly. The allowed values are 'rouge', " +
|
||||
"'pygments' or null."
|
||||
@@ -245,7 +237,7 @@ module Jekyll
|
||||
|
||||
%w[include exclude].each do |option|
|
||||
if config.fetch(option, []).is_a?(String)
|
||||
Jekyll.logger.warn "Deprecation:", "The '#{option}' configuration option" +
|
||||
Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" +
|
||||
" must now be specified as an array, but you specified" +
|
||||
" a string. For now, we've treated the string you provided" +
|
||||
" as a list of comma-separated values."
|
||||
@@ -261,10 +253,13 @@ module Jekyll
|
||||
end
|
||||
|
||||
if config.fetch('markdown', 'kramdown').to_s.downcase.eql?("maruku")
|
||||
Jekyll::Deprecator.deprecation_message "You're using the 'maruku' " +
|
||||
"Markdown processor. Maruku support has been deprecated and will " +
|
||||
"be removed in 3.0.0. We recommend you switch to Kramdown."
|
||||
Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " +
|
||||
"Markdown processor, which has been removed as of 3.0.0. " +
|
||||
"We recommend you switch to Kramdown. To do this, replace " +
|
||||
"`markdown: maruku` with `markdown: kramdown` in your " +
|
||||
"`_config.yml` file."
|
||||
end
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
@@ -279,5 +274,45 @@ module Jekyll
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
def add_default_collections
|
||||
config = clone
|
||||
|
||||
return config if config['collections'].nil?
|
||||
|
||||
if config['collections'].is_a?(Array)
|
||||
config['collections'] = Hash[config['collections'].map{|c| [c, {}]}]
|
||||
end
|
||||
config['collections']['posts'] ||= {}
|
||||
config['collections']['posts']['output'] = true
|
||||
config['collections']['posts']['permalink'] = style_to_permalink(config['permalink'])
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
def renamed_key(old, new, config, allowed_values = nil)
|
||||
if config.key?(old)
|
||||
Jekyll::Deprecator.deprecation_message "The '#{old}' configuration" +
|
||||
"option has been renamed to '#{new}'. Please update your config " +
|
||||
"file accordingly."
|
||||
config[new] = config.delete(old)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def style_to_permalink(permalink_style)
|
||||
case permalink_style.to_sym
|
||||
when :pretty
|
||||
"/:categories/:year/:month/:day/:title/"
|
||||
when :none
|
||||
"/:categories/:title.html"
|
||||
when :date
|
||||
"/:categories/:year/:month/:day/:title.html"
|
||||
when :ordinal
|
||||
"/:categories/:year/:y_day/:title.html"
|
||||
else
|
||||
permalink_style.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,7 +13,6 @@ module Jekyll
|
||||
when 'redcarpet' then RedcarpetParser.new(@config)
|
||||
when 'kramdown' then KramdownParser.new(@config)
|
||||
when 'rdiscount' then RDiscountParser.new(@config)
|
||||
when 'maruku' then MarukuParser.new(@config)
|
||||
else
|
||||
# So they can't try some tricky bullshit or go down the ancestor chain, I hope.
|
||||
if allowed_custom_class?(@config['markdown'])
|
||||
@@ -29,7 +28,6 @@ module Jekyll
|
||||
|
||||
def valid_processors
|
||||
%w[
|
||||
maruku
|
||||
rdiscount
|
||||
kramdown
|
||||
redcarpet
|
||||
@@ -39,22 +37,18 @@ module Jekyll
|
||||
def third_party_processors
|
||||
self.class.constants - %w[
|
||||
KramdownParser
|
||||
MarukuParser
|
||||
RDiscountParser
|
||||
RedcarpetParser
|
||||
PRIORITIES
|
||||
].map(&:to_sym)
|
||||
end
|
||||
|
||||
def extname_matches_regexp
|
||||
@extname_matches_regexp ||= Regexp.new(
|
||||
'^\.(' + @config['markdown_ext'].gsub(',','|') +')$',
|
||||
Regexp::IGNORECASE
|
||||
)
|
||||
def extname_list
|
||||
@extname_list ||= @config['markdown_ext'].split(',').map { |e| ".#{e.downcase}" }
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
ext =~ extname_matches_regexp
|
||||
extname_list.include? ext.downcase
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
|
||||
@@ -5,6 +5,11 @@ module Jekyll
|
||||
def initialize(config)
|
||||
require 'kramdown'
|
||||
@config = config
|
||||
# If kramdown supported highlighter enabled, use that
|
||||
highlighter = @config['highlighter']
|
||||
if highlighter == 'rouge' || highlighter == 'coderay'
|
||||
@config['kramdown']['syntax_highlighter'] ||= highlighter
|
||||
end
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install kramdown'
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown
|
||||
class MarukuParser
|
||||
def initialize(config)
|
||||
require 'maruku'
|
||||
@config = config
|
||||
@errors = []
|
||||
load_divs_library if @config['maruku']['use_divs']
|
||||
load_blahtext_library if @config['maruku']['use_tex']
|
||||
|
||||
# allow fenced code blocks (new in Maruku 0.7.0)
|
||||
MaRuKu::Globals[:fenced_code_blocks] = !!@config['maruku']['fenced_code_blocks']
|
||||
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install maruku'
|
||||
raise Errors::FatalException.new("Missing dependency: maruku")
|
||||
end
|
||||
|
||||
def load_divs_library
|
||||
require 'maruku/ext/div'
|
||||
STDERR.puts 'Maruku: Using extended syntax for div elements.'
|
||||
end
|
||||
|
||||
def load_blahtext_library
|
||||
require 'maruku/ext/math'
|
||||
STDERR.puts "Maruku: Using LaTeX extension. Images in `#{@config['maruku']['png_dir']}`."
|
||||
|
||||
# Switch off MathML output
|
||||
MaRuKu::Globals[:html_math_output_mathml] = false
|
||||
MaRuKu::Globals[:html_math_engine] = 'none'
|
||||
|
||||
# Turn on math to PNG support with blahtex
|
||||
# Resulting PNGs stored in `images/latex`
|
||||
MaRuKu::Globals[:html_math_output_png] = true
|
||||
MaRuKu::Globals[:html_png_engine] = @config['maruku']['png_engine']
|
||||
MaRuKu::Globals[:html_png_dir] = @config['maruku']['png_dir']
|
||||
MaRuKu::Globals[:html_png_url] = @config['maruku']['png_url']
|
||||
end
|
||||
|
||||
def print_errors_and_fail
|
||||
print @errors.join
|
||||
raise MaRuKu::Exception, "MaRuKu encountered problem(s) while converting your markup."
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
converted = Maruku.new(content, :error_stream => @errors).to_html.strip
|
||||
print_errors_and_fail unless @errors.empty?
|
||||
converted
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -29,7 +29,7 @@ module Jekyll
|
||||
include CommonMethods
|
||||
|
||||
def code_wrap(code)
|
||||
"<div class=\"highlight\"><pre>#{CGI::escapeHTML(code)}</pre></div>"
|
||||
"<figure class=\"highlight\"><pre>#{CGI::escapeHTML(code)}</pre></figure>"
|
||||
end
|
||||
|
||||
def block_code(code, lang)
|
||||
@@ -76,7 +76,7 @@ module Jekyll
|
||||
rouge/plugins/redcarpet
|
||||
])
|
||||
|
||||
if Rouge.version < '1.3.0'
|
||||
unless Gem::Version.new(Rouge.version) > Gem::Version.new("1.3.0")
|
||||
abort "Please install Rouge 1.3.0 or greater and try running Jekyll again."
|
||||
end
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Textile < Converter
|
||||
safe true
|
||||
|
||||
highlighter_prefix '<notextile>'
|
||||
highlighter_suffix '</notextile>'
|
||||
|
||||
def setup
|
||||
return if @setup
|
||||
require 'redcloth'
|
||||
@setup = true
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Textile. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install RedCloth'
|
||||
raise Errors::FatalException.new("Missing dependency: RedCloth")
|
||||
end
|
||||
|
||||
def extname_matches_regexp
|
||||
@extname_matches_regexp ||= Regexp.new(
|
||||
'(' + @config['textile_ext'].gsub(',','|') +')$',
|
||||
Regexp::IGNORECASE
|
||||
)
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
ext =~ extname_matches_regexp
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
setup
|
||||
|
||||
# Shortcut if config doesn't contain RedCloth section
|
||||
return RedCloth.new(content).to_html if @config['redcloth'].nil?
|
||||
|
||||
# List of attributes defined on RedCloth
|
||||
# (from https://github.com/jgarber/redcloth/blob/master/lib/redcloth/textile_doc.rb)
|
||||
attrs = ['filter_classes', 'filter_html', 'filter_ids', 'filter_styles',
|
||||
'hard_breaks', 'lite_mode', 'no_span_caps', 'sanitize_html']
|
||||
|
||||
r = RedCloth.new(content)
|
||||
|
||||
# Set attributes in r if they are NOT nil in the config
|
||||
attrs.each do |attr|
|
||||
r.instance_variable_set("@#{attr}".to_sym, @config['redcloth'][attr]) unless @config['redcloth'][attr].nil?
|
||||
end
|
||||
|
||||
r.to_html
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -56,6 +56,12 @@ module Jekyll
|
||||
end
|
||||
|
||||
self.data ||= {}
|
||||
|
||||
unless self.data.is_a?(Hash)
|
||||
Jekyll.logger.abort_with "Fatal:", "Invalid YAML front matter in #{File.join(base, name)}"
|
||||
end
|
||||
|
||||
self.data
|
||||
end
|
||||
|
||||
# Transform the contents based on the content type.
|
||||
@@ -102,8 +108,8 @@ module Jekyll
|
||||
# info - the info for Liquid
|
||||
#
|
||||
# Returns the converted content
|
||||
def render_liquid(content, payload, info, path = nil)
|
||||
Liquid::Template.parse(content).render!(payload, info)
|
||||
def render_liquid(content, payload, info, path)
|
||||
site.liquid_renderer.file(path).parse(content).render!(payload, info)
|
||||
rescue Tags::IncludeTagError => e
|
||||
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{e.path}, included in #{path || self.path}"
|
||||
raise e
|
||||
@@ -129,11 +135,14 @@ module Jekyll
|
||||
#
|
||||
# Returns the type of self.
|
||||
def type
|
||||
if is_a?(Draft)
|
||||
:drafts
|
||||
elsif is_a?(Post)
|
||||
:posts
|
||||
elsif is_a?(Page)
|
||||
if is_a?(Page)
|
||||
:pages
|
||||
end
|
||||
end
|
||||
|
||||
# returns the owner symbol for hook triggering
|
||||
def hook_owner
|
||||
if is_a?(Page)
|
||||
:pages
|
||||
end
|
||||
end
|
||||
@@ -168,15 +177,6 @@ module Jekyll
|
||||
true
|
||||
end
|
||||
|
||||
# Determine whether to regenerate the file based on metadata.
|
||||
#
|
||||
# Returns true if file needs to be regenerated
|
||||
def regenerate?
|
||||
asset_file? ||
|
||||
data['regenerate'] ||
|
||||
site.metadata.regenerate?(site.in_source_dir(relative_path))
|
||||
end
|
||||
|
||||
# Determine whether the file should be placed into layouts.
|
||||
#
|
||||
# Returns false if the document is an asset file.
|
||||
@@ -209,15 +209,16 @@ module Jekyll
|
||||
used = Set.new([layout])
|
||||
|
||||
while layout
|
||||
Jekyll.logger.debug "Rendering Layout:", path
|
||||
payload = Utils.deep_merge_hashes(payload, {"content" => output, "page" => layout.data})
|
||||
|
||||
self.output = render_liquid(layout.content,
|
||||
payload,
|
||||
info,
|
||||
File.join(site.config['layouts'], layout.name))
|
||||
File.join(site.config['layouts_dir'], layout.name))
|
||||
|
||||
# Add layout to dependency tree
|
||||
site.metadata.add_dependency(
|
||||
site.regenerator.add_dependency(
|
||||
site.in_source_dir(path),
|
||||
site.in_source_dir(layout.path)
|
||||
)
|
||||
@@ -239,19 +240,29 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def do_layout(payload, layouts)
|
||||
Jekyll.logger.debug "Rendering:", self.relative_path
|
||||
|
||||
Jekyll.logger.debug "Pre-Render Hooks:", self.relative_path
|
||||
Jekyll::Hooks.trigger hook_owner, :pre_render, self, payload
|
||||
info = { :filters => [Jekyll::Filters], :registers => { :site => site, :page => payload['page'] } }
|
||||
|
||||
# render and transform content (this becomes the final content of the object)
|
||||
payload["highlighter_prefix"] = converters.first.highlighter_prefix
|
||||
payload["highlighter_suffix"] = converters.first.highlighter_suffix
|
||||
|
||||
self.content = render_liquid(content, payload, info) if render_with_liquid?
|
||||
if render_with_liquid?
|
||||
Jekyll.logger.debug "Rendering Liquid:", self.relative_path
|
||||
self.content = render_liquid(content, payload, info, path)
|
||||
end
|
||||
Jekyll.logger.debug "Rendering Markup:", self.relative_path
|
||||
self.content = transform
|
||||
|
||||
# output keeps track of what will finally be written
|
||||
self.output = content
|
||||
|
||||
render_all_layouts(layouts, payload, info) if place_in_layout?
|
||||
Jekyll.logger.debug "Post-Render Hooks:", self.relative_path
|
||||
Jekyll::Hooks.trigger hook_owner, :post_render, self
|
||||
end
|
||||
|
||||
# Write the generated page file to the destination directory.
|
||||
@@ -265,6 +276,7 @@ module Jekyll
|
||||
File.open(path, 'wb') do |f|
|
||||
f.write(output)
|
||||
end
|
||||
Jekyll::Hooks.trigger hook_owner, :post_write, self
|
||||
end
|
||||
|
||||
# Accessor for data properties by Liquid.
|
||||
|
||||
@@ -3,9 +3,10 @@ module Jekyll
|
||||
extend self
|
||||
|
||||
def process(args)
|
||||
no_subcommand(args)
|
||||
arg_is_present? args, "--server", "The --server command has been replaced by the \
|
||||
'serve' subcommand."
|
||||
arg_is_present? args, "--serve", "The --server command has been replaced by the \
|
||||
'serve' subcommand."
|
||||
arg_is_present? args, "--no-server", "To build Jekyll without launching a server, \
|
||||
use the 'build' subcommand."
|
||||
arg_is_present? args, "--auto", "The switch '--auto' has been replaced with '--watch'."
|
||||
@@ -16,12 +17,13 @@ module Jekyll
|
||||
arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in your \
|
||||
config files."
|
||||
arg_is_present? args, "--url", "The 'url' setting can only be set in your config files."
|
||||
no_subcommand(args)
|
||||
end
|
||||
|
||||
def no_subcommand(args)
|
||||
if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first)
|
||||
deprecation_message "Jekyll now uses subcommands instead of just \
|
||||
switches. Run `jekyll --help' to find out more."
|
||||
deprecation_message "Jekyll now uses subcommands instead of just switches. Run `jekyll --help` to find out more."
|
||||
abort
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -4,8 +4,11 @@ module Jekyll
|
||||
class Document
|
||||
include Comparable
|
||||
|
||||
attr_reader :path, :site, :extname
|
||||
attr_accessor :content, :collection, :output
|
||||
attr_reader :path, :site, :extname, :output_ext, :content, :output, :collection
|
||||
|
||||
YAML_FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
|
||||
DATELESS_FILENAME_MATCHER = /^(.*)(\.[^.]+)$/
|
||||
DATE_FILENAME_MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
||||
|
||||
# Create a new Document.
|
||||
#
|
||||
@@ -17,8 +20,31 @@ module Jekyll
|
||||
@site = relations[:site]
|
||||
@path = path
|
||||
@extname = File.extname(path)
|
||||
@output_ext = Jekyll::Renderer.new(site, self).output_ext
|
||||
@collection = relations[:collection]
|
||||
@has_yaml_header = nil
|
||||
|
||||
if draft?
|
||||
categories_from_path("_drafts")
|
||||
else
|
||||
categories_from_path(collection.relative_directory)
|
||||
end
|
||||
|
||||
data.default_proc = proc do |hash, key|
|
||||
site.frontmatter_defaults.find(relative_path, collection.label, key)
|
||||
end
|
||||
|
||||
trigger_hooks(:post_init)
|
||||
end
|
||||
|
||||
def output=(output)
|
||||
@to_liquid = nil
|
||||
@output = output
|
||||
end
|
||||
|
||||
def content=(content)
|
||||
@to_liquid = nil
|
||||
@content = content
|
||||
end
|
||||
|
||||
# Fetch the Document's data.
|
||||
@@ -29,6 +55,36 @@ module Jekyll
|
||||
@data ||= Hash.new
|
||||
end
|
||||
|
||||
# Merge some data in with this document's data.
|
||||
#
|
||||
# Returns the merged data.
|
||||
def merge_data!(other, source: "YAML front matter")
|
||||
if other.key?('categories') && !other['categories'].nil?
|
||||
if other['categories'].is_a?(String)
|
||||
other['categories'] = other['categories'].split(" ").map(&:strip)
|
||||
end
|
||||
other['categories'] = (data['categories'] || []) | other['categories']
|
||||
end
|
||||
Utils.deep_merge_hashes!(data, other)
|
||||
if data.key?('date') && !data['date'].is_a?(Time)
|
||||
data['date'] = Utils.parse_date(data['date'].to_s, "Document '#{relative_path}' does not have a valid date in the #{source}.")
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
def date
|
||||
data['date'] ||= site.time
|
||||
end
|
||||
|
||||
# Returns whether the document is a draft. This is only the case if
|
||||
# the document is in the 'posts' collection but in a different
|
||||
# directory than '_posts'.
|
||||
#
|
||||
# Returns whether the document is a draft.
|
||||
def draft?
|
||||
data['draft'] ||= relative_path.index(collection.relative_directory).nil? && collection.label == "posts"
|
||||
end
|
||||
|
||||
# The path to the document, relative to the site source.
|
||||
#
|
||||
# Returns a String path which represents the relative path
|
||||
@@ -105,13 +161,6 @@ module Jekyll
|
||||
!(coffeescript_file? || yaml_file?)
|
||||
end
|
||||
|
||||
# Determine whether the document should be regenerated based on metadata.
|
||||
#
|
||||
# Returns true if the document needs to be regenerated.
|
||||
def regenerate?
|
||||
data['regenerate'] || site.metadata.regenerate?(path, write?)
|
||||
end
|
||||
|
||||
# Determine whether the file should be placed into layouts.
|
||||
#
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
@@ -133,11 +182,25 @@ module Jekyll
|
||||
# Returns the Hash of key-value pairs for replacement in the URL.
|
||||
def url_placeholders
|
||||
{
|
||||
collection: collection.label,
|
||||
path: cleaned_relative_path,
|
||||
output_ext: Jekyll::Renderer.new(site, self).output_ext,
|
||||
name: Utils.slugify(basename_without_ext),
|
||||
title: Utils.slugify(data['title']) || Utils.slugify(basename_without_ext)
|
||||
collection: collection.label,
|
||||
path: cleaned_relative_path,
|
||||
output_ext: output_ext,
|
||||
name: Utils.slugify(basename_without_ext),
|
||||
title: Utils.slugify(data['slug'], mode: "pretty", cased: true) || Utils
|
||||
.slugify(basename_without_ext, mode: "pretty", cased: true),
|
||||
slug: Utils.slugify(data['slug']) || Utils.slugify(basename_without_ext),
|
||||
year: date.strftime("%Y"),
|
||||
month: date.strftime("%m"),
|
||||
day: date.strftime("%d"),
|
||||
hour: date.strftime("%H"),
|
||||
minute: date.strftime("%M"),
|
||||
second: date.strftime("%S"),
|
||||
i_day: date.strftime("%-d"),
|
||||
i_month: date.strftime("%-m"),
|
||||
categories: (data['categories'] || []).map { |c| c.to_s.downcase }.uniq.join('/'),
|
||||
short_month: date.strftime("%b"),
|
||||
short_year: date.strftime("%y"),
|
||||
y_day: date.strftime("%j"),
|
||||
}
|
||||
end
|
||||
|
||||
@@ -160,6 +223,10 @@ module Jekyll
|
||||
}).to_s
|
||||
end
|
||||
|
||||
def [](key)
|
||||
data[key]
|
||||
end
|
||||
|
||||
# The full path to the output file.
|
||||
#
|
||||
# base_directory - the base path of the output directory
|
||||
@@ -168,7 +235,8 @@ module Jekyll
|
||||
def destination(base_directory)
|
||||
dest = site.in_dest_dir(base_directory)
|
||||
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if url =~ /\/$/
|
||||
path = File.join(path, "index.html") if url.end_with?("/")
|
||||
path << output_ext unless path.end_with?(output_ext)
|
||||
path
|
||||
end
|
||||
|
||||
@@ -183,6 +251,8 @@ module Jekyll
|
||||
File.open(path, 'wb') do |f|
|
||||
f.write(output)
|
||||
end
|
||||
|
||||
trigger_hooks(:post_write)
|
||||
end
|
||||
|
||||
# Returns merged option hash for File.read of self.site (if exists)
|
||||
@@ -208,43 +278,98 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read(opts = {})
|
||||
@to_liquid = nil
|
||||
|
||||
Jekyll.logger.debug "Reading:", relative_path
|
||||
|
||||
if yaml_file?
|
||||
@data = SafeYAML.load_file(path)
|
||||
else
|
||||
begin
|
||||
defaults = @site.frontmatter_defaults.all(url, collection.label.to_sym)
|
||||
unless defaults.empty?
|
||||
@data = defaults
|
||||
end
|
||||
@content = File.read(path, merged_file_read_opts(opts))
|
||||
if content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
||||
@content = $POSTMATCH
|
||||
merge_data!(defaults, source: "front matter defaults") unless defaults.empty?
|
||||
|
||||
self.content = File.read(path, merged_file_read_opts(opts))
|
||||
if content =~ YAML_FRONT_MATTER_REGEXP
|
||||
self.content = $POSTMATCH
|
||||
data_file = SafeYAML.load($1)
|
||||
unless data_file.nil?
|
||||
@data = Utils.deep_merge_hashes(defaults, data_file)
|
||||
end
|
||||
merge_data!(data_file, source: "YAML front matter") if data_file
|
||||
end
|
||||
|
||||
post_read
|
||||
rescue SyntaxError => e
|
||||
puts "YAML Exception reading #{path}: #{e.message}"
|
||||
Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{e.message}"
|
||||
rescue Exception => e
|
||||
puts "Error reading file #{path}: #{e.message}"
|
||||
if e.is_a? Jekyll::Errors::FatalException
|
||||
raise e
|
||||
end
|
||||
Jekyll.logger.error "Error:", "could not read file #{path}: #{e.message}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def post_read
|
||||
if DATE_FILENAME_MATCHER =~ relative_path
|
||||
m, cats, date, slug, ext = *relative_path.match(DATE_FILENAME_MATCHER)
|
||||
merge_data!({
|
||||
"slug" => slug,
|
||||
"ext" => ext
|
||||
}, source: "filename")
|
||||
if data['date'].nil? || data['date'].to_i == site.time.to_i
|
||||
merge_data!({"date" => date}, source: "filename")
|
||||
end
|
||||
data['title'] ||= slug.split('-').select {|w| w.capitalize! || w }.join(' ')
|
||||
end
|
||||
populate_categories
|
||||
populate_tags
|
||||
|
||||
if generate_excerpt?
|
||||
data['excerpt'] ||= Jekyll::Excerpt.new(self)
|
||||
end
|
||||
end
|
||||
|
||||
# Add superdirectories of the special_dir to categories.
|
||||
# In the case of es/_posts, 'es' is added as a category.
|
||||
# In the case of _posts/es, 'es' is NOT added as a category.
|
||||
#
|
||||
# Returns nothing.
|
||||
def categories_from_path(special_dir)
|
||||
superdirs = relative_path.sub(/#{special_dir}(.*)/, '').split(File::SEPARATOR).reject do |c|
|
||||
c.empty? || c.eql?(special_dir) || c.eql?(basename)
|
||||
end
|
||||
merge_data!({ 'categories' => superdirs }, source: "file path")
|
||||
end
|
||||
|
||||
def populate_categories
|
||||
merge_data!({
|
||||
'categories' => (
|
||||
Array(data['categories']) + Utils.pluralized_array_from_hash(data, 'category', 'categories')
|
||||
).map { |c| c.to_s }.flatten.uniq
|
||||
})
|
||||
end
|
||||
|
||||
def populate_tags
|
||||
merge_data!({
|
||||
"tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
|
||||
})
|
||||
end
|
||||
|
||||
# Create a Liquid-understandable version of this Document.
|
||||
#
|
||||
# Returns a Hash representing this Document's data.
|
||||
def to_liquid
|
||||
if data.is_a?(Hash)
|
||||
Utils.deep_merge_hashes data, {
|
||||
@to_liquid ||= if data.is_a?(Hash)
|
||||
Utils.deep_merge_hashes Utils.deep_merge_hashes({
|
||||
"output" => output,
|
||||
"content" => content,
|
||||
"relative_path" => relative_path,
|
||||
"path" => relative_path,
|
||||
"url" => url,
|
||||
"collection" => collection.label
|
||||
}
|
||||
"collection" => collection.label,
|
||||
"next" => next_doc,
|
||||
"previous" => previous_doc,
|
||||
"id" => id,
|
||||
}, data), { 'excerpt' => data['excerpt'].to_s }
|
||||
else
|
||||
data
|
||||
end
|
||||
@@ -262,7 +387,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the content of the document
|
||||
def to_s
|
||||
content || ''
|
||||
output || content || 'NO CONTENT'
|
||||
end
|
||||
|
||||
# Compare this document against another document.
|
||||
@@ -270,8 +395,11 @@ module Jekyll
|
||||
#
|
||||
# Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
|
||||
# equal or greater than the other doc's path. See String#<=> for more details.
|
||||
def <=>(anotherDocument)
|
||||
path <=> anotherDocument.path
|
||||
def <=>(other)
|
||||
return nil if !other.respond_to?(:data)
|
||||
cmp = data['date'] <=> other.data['date']
|
||||
cmp = path <=> other.path if cmp == 0
|
||||
cmp
|
||||
end
|
||||
|
||||
# Determine whether this document should be written.
|
||||
@@ -283,5 +411,70 @@ module Jekyll
|
||||
collection && collection.write?
|
||||
end
|
||||
|
||||
# The Document excerpt_separator, from the YAML Front-Matter or site
|
||||
# default excerpt_separator value
|
||||
#
|
||||
# Returns the document excerpt_separator
|
||||
def excerpt_separator
|
||||
(data['excerpt_separator'] || site.config['excerpt_separator']).to_s
|
||||
end
|
||||
|
||||
# Whether to generate an excerpt
|
||||
#
|
||||
# Returns true if the excerpt separator is configured.
|
||||
def generate_excerpt?
|
||||
!excerpt_separator.empty?
|
||||
end
|
||||
|
||||
def next_doc
|
||||
pos = collection.docs.index {|post| post.equal?(self) }
|
||||
if pos && pos < collection.docs.length - 1
|
||||
collection.docs[pos + 1]
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def previous_doc
|
||||
pos = collection.docs.index {|post| post.equal?(self) }
|
||||
if pos && pos > 0
|
||||
collection.docs[pos - 1]
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def trigger_hooks(hook_name, *args)
|
||||
Jekyll::Hooks.trigger collection.label.to_sym, hook_name, self, *args if collection
|
||||
Jekyll::Hooks.trigger :documents, hook_name, self, *args
|
||||
end
|
||||
|
||||
def id
|
||||
@id ||= File.join(File.dirname(url), (data['slug'] || basename_without_ext).to_s)
|
||||
end
|
||||
|
||||
# Calculate related posts.
|
||||
#
|
||||
# Returns an Array of related Posts.
|
||||
def related_posts
|
||||
Jekyll::RelatedPosts.new(self).build
|
||||
end
|
||||
|
||||
# Override of normal respond_to? to match method_missing's logic for
|
||||
# looking in @data.
|
||||
def respond_to?(method, include_private = false)
|
||||
data.key?(method.to_s) || super
|
||||
end
|
||||
|
||||
# Override of method_missing to check in @data for the key.
|
||||
def method_missing(method, *args, &blck)
|
||||
if data.key?(method.to_s)
|
||||
Jekyll.logger.warn "Deprecation:", "Document##{method} is now a key in the #data hash."
|
||||
Jekyll.logger.warn "", "Called by #{caller.first}."
|
||||
data[method.to_s]
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
module Jekyll
|
||||
|
||||
class Draft < Post
|
||||
|
||||
# Valid post name regex (no date)
|
||||
MATCHER = /^(.*)(\.[^.]+)$/
|
||||
|
||||
# Draft name validator. Draft filenames must be like:
|
||||
# my-awesome-post.textile
|
||||
#
|
||||
# Returns true if valid, false if not.
|
||||
def self.valid?(name)
|
||||
name =~ MATCHER
|
||||
end
|
||||
|
||||
# Get the full path to the directory containing the draft files
|
||||
def containing_dir(dir)
|
||||
site.in_source_dir(dir, '_drafts')
|
||||
end
|
||||
|
||||
# The path to the draft source file, relative to the site source
|
||||
def relative_path
|
||||
File.join(@dir, '_drafts', @name)
|
||||
end
|
||||
|
||||
# Extract information from the post filename.
|
||||
#
|
||||
# name - The String filename of the post file.
|
||||
#
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
m, slug, ext = *name.match(MATCHER)
|
||||
self.date = File.mtime(File.join(@base, name))
|
||||
self.slug = slug
|
||||
self.ext = ext
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -2,46 +2,43 @@ require 'forwardable'
|
||||
|
||||
module Jekyll
|
||||
class Excerpt
|
||||
include Convertible
|
||||
extend Forwardable
|
||||
|
||||
attr_accessor :post
|
||||
attr_accessor :content, :output, :ext
|
||||
attr_accessor :doc
|
||||
attr_accessor :content, :ext
|
||||
attr_writer :output
|
||||
|
||||
def_delegator :@post, :site, :site
|
||||
def_delegator :@post, :name, :name
|
||||
def_delegator :@post, :ext, :ext
|
||||
def_delegators :@doc, :site, :name, :ext, :relative_path, :extname,
|
||||
:render_with_liquid?, :collection, :related_posts
|
||||
|
||||
# Initialize this Post instance.
|
||||
# Initialize this Excerpt instance.
|
||||
#
|
||||
# site - The Site.
|
||||
# base - The String path to the dir containing the post file.
|
||||
# name - The String filename of the post file.
|
||||
# doc - The Document.
|
||||
#
|
||||
# Returns the new Post.
|
||||
def initialize(post)
|
||||
self.post = post
|
||||
self.content = extract_excerpt(post.content)
|
||||
# Returns the new Excerpt.
|
||||
def initialize(doc)
|
||||
self.doc = doc
|
||||
self.content = extract_excerpt(doc.content)
|
||||
end
|
||||
|
||||
def to_liquid
|
||||
post.to_liquid(post.class::EXCERPT_ATTRIBUTES_FOR_LIQUID)
|
||||
end
|
||||
|
||||
# Fetch YAML front-matter data from related post, without layout key
|
||||
# Fetch YAML front-matter data from related doc, without layout key
|
||||
#
|
||||
# Returns Hash of post data
|
||||
# Returns Hash of doc data
|
||||
def data
|
||||
@data ||= post.data.dup
|
||||
@data ||= doc.data.dup
|
||||
@data.delete("layout")
|
||||
@data.delete("excerpt")
|
||||
@data
|
||||
end
|
||||
|
||||
def trigger_hooks(*)
|
||||
end
|
||||
|
||||
# 'Path' of the excerpt.
|
||||
#
|
||||
# Returns the path for the post this excerpt belongs to with #excerpt appended
|
||||
# Returns the path for the doc this excerpt belongs to with #excerpt appended
|
||||
def path
|
||||
File.join(post.path, "#excerpt")
|
||||
File.join(doc.path, "#excerpt")
|
||||
end
|
||||
|
||||
# Check if excerpt includes a string
|
||||
@@ -51,28 +48,43 @@ module Jekyll
|
||||
(output && output.include?(something)) || content.include?(something)
|
||||
end
|
||||
|
||||
# The UID for this post (useful in feeds).
|
||||
# e.g. /2008/11/05/my-awesome-post
|
||||
# The UID for this doc (useful in feeds).
|
||||
# e.g. /2008/11/05/my-awesome-doc
|
||||
#
|
||||
# Returns the String UID.
|
||||
def id
|
||||
File.join(post.dir, post.slug, "#excerpt")
|
||||
"#{doc.id}#excerpt"
|
||||
end
|
||||
|
||||
def to_s
|
||||
output || content
|
||||
end
|
||||
|
||||
# Returns the shorthand String identifier of this Post.
|
||||
def to_liquid
|
||||
doc.data['excerpt'] = nil
|
||||
@to_liquid ||= doc.to_liquid
|
||||
doc.data['excerpt'] = self
|
||||
@to_liquid
|
||||
end
|
||||
|
||||
# Returns the shorthand String identifier of this doc.
|
||||
def inspect
|
||||
"<Excerpt: #{self.id}>"
|
||||
end
|
||||
|
||||
def output
|
||||
@output ||= Renderer.new(doc.site, self, site.site_payload).run
|
||||
end
|
||||
|
||||
def place_in_layout?
|
||||
false
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Internal: Extract excerpt from the content
|
||||
#
|
||||
# By default excerpt is your first paragraph of a post: everything before
|
||||
# By default excerpt is your first paragraph of a doc: everything before
|
||||
# the first two new lines:
|
||||
#
|
||||
# ---
|
||||
@@ -86,16 +98,16 @@ module Jekyll
|
||||
# [1]: http://example.com/
|
||||
#
|
||||
# This is fairly good option for Markdown and Textile files. But might cause
|
||||
# problems for HTML posts (which is quite unusual for Jekyll). If default
|
||||
# problems for HTML docs (which is quite unusual for Jekyll). If default
|
||||
# excerpt delimiter is not good for you, you might want to set your own via
|
||||
# configuration option `excerpt_separator`. For example, following is a good
|
||||
# alternative for HTML posts:
|
||||
# alternative for HTML docs:
|
||||
#
|
||||
# # file: _config.yml
|
||||
# excerpt_separator: "<!-- more -->"
|
||||
#
|
||||
# Notice that all markdown-style link references will be appended to the
|
||||
# excerpt. So the example post above will have this excerpt source:
|
||||
# excerpt. So the example doc above will have this excerpt source:
|
||||
#
|
||||
# First paragraph with [link][1].
|
||||
#
|
||||
@@ -104,11 +116,14 @@ module Jekyll
|
||||
# Excerpts are rendered same time as content is rendered.
|
||||
#
|
||||
# Returns excerpt String
|
||||
def extract_excerpt(post_content)
|
||||
separator = site.config['excerpt_separator']
|
||||
head, _, tail = post_content.to_s.partition(separator)
|
||||
def extract_excerpt(doc_content)
|
||||
head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
|
||||
|
||||
"" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
|
||||
if tail.empty?
|
||||
head
|
||||
else
|
||||
"" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
require 'uri'
|
||||
require 'json'
|
||||
require 'date'
|
||||
|
||||
module Jekyll
|
||||
module Filters
|
||||
# Convert a Textile string into HTML output.
|
||||
#
|
||||
# input - The Textile String to convert.
|
||||
#
|
||||
# Returns the HTML formatted String.
|
||||
def textilize(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.find_converter_instance(Jekyll::Converters::Textile)
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Convert a Markdown string into HTML output.
|
||||
#
|
||||
# input - The Markdown String to convert.
|
||||
@@ -50,12 +40,12 @@ module Jekyll
|
||||
# Slugify a filename or title.
|
||||
#
|
||||
# input - The filename or title to slugify.
|
||||
# mode - how string is slugified
|
||||
#
|
||||
# Returns the given filename or title as a lowercase String, with every
|
||||
# sequence of spaces and non-alphanumeric characters replaced with a
|
||||
# hyphen.
|
||||
def slugify(input)
|
||||
Utils.slugify(input)
|
||||
# Returns the given filename or title as a lowercase URL String.
|
||||
# See Utils.slugify for more detail.
|
||||
def slugify(input, mode=nil)
|
||||
Utils.slugify(input, mode: mode)
|
||||
end
|
||||
|
||||
# Format a date in short format e.g. "27 Jan 2011".
|
||||
@@ -221,7 +211,7 @@ module Jekyll
|
||||
def where(input, property, value)
|
||||
return input unless input.is_a?(Enumerable)
|
||||
input = input.values if input.is_a?(Hash)
|
||||
input.select { |object| item_property(object, property) == value }
|
||||
input.select { |object| item_property(object, property).to_s == value.to_s }
|
||||
end
|
||||
|
||||
# Sort an array of objects
|
||||
@@ -232,6 +222,9 @@ module Jekyll
|
||||
#
|
||||
# Returns the filtered array of objects
|
||||
def sort(input, property = nil, nils = "first")
|
||||
if input.nil?
|
||||
raise ArgumentError.new("Cannot sort a null object.")
|
||||
end
|
||||
if property.nil?
|
||||
input.sort
|
||||
else
|
||||
@@ -302,6 +295,8 @@ module Jekyll
|
||||
case input
|
||||
when Time
|
||||
input
|
||||
when Date
|
||||
input.to_time
|
||||
when String
|
||||
Time.parse(input) rescue Time.at(input.to_i)
|
||||
when Numeric
|
||||
|
||||
@@ -87,7 +87,7 @@ module Jekyll
|
||||
|
||||
scope_path = Pathname.new(scope['path'])
|
||||
Pathname.new(sanitize_path(path)).ascend do |path|
|
||||
if path == scope_path
|
||||
if path.to_s == scope_path.to_s
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -168,12 +168,12 @@ module Jekyll
|
||||
end.compact
|
||||
end
|
||||
|
||||
# Sanitizes the given path by removing a leading and addding a trailing slash
|
||||
# Sanitizes the given path by removing a leading and adding a trailing slash
|
||||
def sanitize_path(path)
|
||||
if path.nil? || path.empty?
|
||||
""
|
||||
else
|
||||
path.gsub(/\A\//, '').gsub(/([^\/])\z/, '\1/')
|
||||
path.gsub(/\A\//, '').gsub(/([^\/])\z/, '\1')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
101
lib/jekyll/hooks.rb
Normal file
101
lib/jekyll/hooks.rb
Normal file
@@ -0,0 +1,101 @@
|
||||
module Jekyll
|
||||
module Hooks
|
||||
DEFAULT_PRIORITY = 20
|
||||
|
||||
# compatibility layer for octopress-hooks users
|
||||
PRIORITY_MAP = {
|
||||
low: 10,
|
||||
normal: 20,
|
||||
high: 30,
|
||||
}.freeze
|
||||
|
||||
# initial empty hooks
|
||||
@registry = {
|
||||
:site => {
|
||||
after_reset: [],
|
||||
post_read: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
},
|
||||
:pages => {
|
||||
post_init: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
},
|
||||
:posts => {
|
||||
post_init: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
},
|
||||
:documents => {
|
||||
post_init: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
},
|
||||
}
|
||||
|
||||
# map of all hooks and their priorities
|
||||
@hook_priority = {}
|
||||
|
||||
NotAvailable = Class.new(RuntimeError)
|
||||
Uncallable = Class.new(RuntimeError)
|
||||
|
||||
# register hook(s) to be called later, public API
|
||||
def self.register(owners, event, priority: DEFAULT_PRIORITY, &block)
|
||||
Array(owners).each do |owner|
|
||||
register_one(owner, event, priority_value(priority), &block)
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure the priority is a Fixnum
|
||||
def self.priority_value(priority)
|
||||
return priority if priority.is_a?(Fixnum)
|
||||
PRIORITY_MAP[priority] || DEFAULT_PRIORITY
|
||||
end
|
||||
|
||||
# register a single hook to be called later, internal API
|
||||
def self.register_one(owner, event, priority, &block)
|
||||
@registry[owner] ||={
|
||||
post_init: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
}
|
||||
|
||||
unless @registry[owner][event]
|
||||
raise NotAvailable, "Invalid hook. #{owner} supports only the " <<
|
||||
"following hooks #{@registry[owner].keys.inspect}"
|
||||
end
|
||||
|
||||
unless block.respond_to? :call
|
||||
raise Uncallable, "Hooks must respond to :call"
|
||||
end
|
||||
|
||||
insert_hook owner, event, priority, &block
|
||||
end
|
||||
|
||||
def self.insert_hook(owner, event, priority, &block)
|
||||
@hook_priority[block] = "#{priority}.#{@hook_priority.size}".to_f
|
||||
@registry[owner][event] << block
|
||||
end
|
||||
|
||||
# interface for Jekyll core components to trigger hooks
|
||||
def self.trigger(owner, event, *args)
|
||||
# proceed only if there are hooks to call
|
||||
return unless @registry[owner]
|
||||
return unless @registry[owner][event]
|
||||
|
||||
# hooks to call for this owner and event
|
||||
hooks = @registry[owner][event]
|
||||
|
||||
# sort and call hooks according to priority and load order
|
||||
hooks.sort_by { |h| @hook_priority[h] }.each do |hook|
|
||||
hook.call(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
39
lib/jekyll/liquid_renderer.rb
Normal file
39
lib/jekyll/liquid_renderer.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
require 'jekyll/liquid_renderer/file'
|
||||
require 'jekyll/liquid_renderer/table'
|
||||
|
||||
module Jekyll
|
||||
class LiquidRenderer
|
||||
def initialize(site)
|
||||
@site = site
|
||||
reset
|
||||
end
|
||||
|
||||
def reset
|
||||
@stats = {}
|
||||
end
|
||||
|
||||
def file(filename)
|
||||
filename = @site.in_source_dir(filename).sub(/\A#{Regexp.escape(@site.source)}\//, '')
|
||||
|
||||
LiquidRenderer::File.new(self, filename).tap do |file|
|
||||
@stats[filename] ||= {}
|
||||
@stats[filename][:count] ||= 0
|
||||
@stats[filename][:count] += 1
|
||||
end
|
||||
end
|
||||
|
||||
def increment_bytes(filename, bytes)
|
||||
@stats[filename][:bytes] ||= 0
|
||||
@stats[filename][:bytes] += bytes
|
||||
end
|
||||
|
||||
def increment_time(filename, time)
|
||||
@stats[filename][:time] ||= 0.0
|
||||
@stats[filename][:time] += time
|
||||
end
|
||||
|
||||
def stats_table(n = 50)
|
||||
LiquidRenderer::Table.new(@stats).to_s(n)
|
||||
end
|
||||
end
|
||||
end
|
||||
50
lib/jekyll/liquid_renderer/file.rb
Normal file
50
lib/jekyll/liquid_renderer/file.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
module Jekyll
|
||||
class LiquidRenderer
|
||||
class File
|
||||
def initialize(renderer, filename)
|
||||
@renderer = renderer
|
||||
@filename = filename
|
||||
end
|
||||
|
||||
def parse(content)
|
||||
measure_time do
|
||||
@template = Liquid::Template.parse(content)
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def render(*args)
|
||||
measure_time do
|
||||
measure_bytes do
|
||||
@template.render(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render!(*args)
|
||||
measure_time do
|
||||
measure_bytes do
|
||||
@template.render!(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def measure_bytes
|
||||
yield.tap do |str|
|
||||
@renderer.increment_bytes(@filename, str.bytesize)
|
||||
end
|
||||
end
|
||||
|
||||
def measure_time
|
||||
before = Time.now
|
||||
yield
|
||||
ensure
|
||||
after = Time.now
|
||||
@renderer.increment_time(@filename, after - before)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
94
lib/jekyll/liquid_renderer/table.rb
Normal file
94
lib/jekyll/liquid_renderer/table.rb
Normal file
@@ -0,0 +1,94 @@
|
||||
module Jekyll
|
||||
class LiquidRenderer::Table
|
||||
def initialize(stats)
|
||||
@stats = stats
|
||||
end
|
||||
|
||||
def to_s(n = 50)
|
||||
data = data_for_table(n)
|
||||
widths = table_widths(data)
|
||||
generate_table(data, widths)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_table(data, widths)
|
||||
str = "\n"
|
||||
|
||||
table_head = data.shift
|
||||
str << generate_row(table_head, widths)
|
||||
str << generate_table_head_border(table_head, widths)
|
||||
|
||||
data.each do |row_data|
|
||||
str << generate_row(row_data, widths)
|
||||
end
|
||||
|
||||
str << "\n"
|
||||
str
|
||||
end
|
||||
|
||||
def generate_table_head_border(row_data, widths)
|
||||
str = ""
|
||||
|
||||
row_data.each_index do |cell_index|
|
||||
str << '-' * widths[cell_index]
|
||||
str << '-+-' unless cell_index == row_data.length-1
|
||||
end
|
||||
|
||||
str << "\n"
|
||||
str
|
||||
end
|
||||
|
||||
def generate_row(row_data, widths)
|
||||
str = ''
|
||||
|
||||
row_data.each_with_index do |cell_data, cell_index|
|
||||
if cell_index == 0
|
||||
str << cell_data.ljust(widths[cell_index], ' ')
|
||||
else
|
||||
str << cell_data.rjust(widths[cell_index], ' ')
|
||||
end
|
||||
|
||||
str << ' | ' unless cell_index == row_data.length-1
|
||||
end
|
||||
|
||||
str << "\n"
|
||||
str
|
||||
end
|
||||
|
||||
def table_widths(data)
|
||||
widths = []
|
||||
|
||||
data.each do |row|
|
||||
row.each_with_index do |cell, index|
|
||||
widths[index] = [ cell.length, widths[index] ].compact.max
|
||||
end
|
||||
end
|
||||
|
||||
widths
|
||||
end
|
||||
|
||||
def data_for_table(n)
|
||||
sorted = @stats.sort_by{ |filename, file_stats| -file_stats[:time] }
|
||||
sorted = sorted.slice(0, n)
|
||||
|
||||
table = [[ 'Filename', 'Count', 'Bytes', 'Time' ]]
|
||||
|
||||
sorted.each do |filename, file_stats|
|
||||
row = []
|
||||
row << filename
|
||||
row << file_stats[:count].to_s
|
||||
row << format_bytes(file_stats[:bytes])
|
||||
row << "%.3f" % file_stats[:time]
|
||||
table << row
|
||||
end
|
||||
|
||||
table
|
||||
end
|
||||
|
||||
def format_bytes(bytes)
|
||||
bytes /= 1024.0
|
||||
"%.2fK" % bytes
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,7 +9,7 @@ module Jekyll
|
||||
:error => ::Logger::ERROR
|
||||
}
|
||||
|
||||
# Public: Create a new instance of Jekyll's log writer
|
||||
# Public: Create a new instance of a log writer
|
||||
#
|
||||
# writer - Logger compatible instance
|
||||
# log_level - (optional, symbol) the log level
|
||||
@@ -30,7 +30,17 @@ module Jekyll
|
||||
writer.level = LOG_LEVELS.fetch(level)
|
||||
end
|
||||
|
||||
# Public: Print a jekyll debug message
|
||||
def adjust_verbosity(options = {})
|
||||
# Quiet always wins.
|
||||
if options[:quiet]
|
||||
self.log_level = :error
|
||||
elsif options[:verbose]
|
||||
self.log_level = :debug
|
||||
end
|
||||
debug "Logging at level:", LOG_LEVELS.key(writer.level).to_s
|
||||
end
|
||||
|
||||
# Public: Print a debug message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
@@ -40,7 +50,7 @@ module Jekyll
|
||||
writer.debug(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message
|
||||
# Public: Print a message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
@@ -50,7 +60,7 @@ module Jekyll
|
||||
writer.info(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message
|
||||
# Public: Print a message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
@@ -60,7 +70,7 @@ module Jekyll
|
||||
writer.warn(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll error message
|
||||
# Public: Print an error message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
@@ -70,7 +80,7 @@ module Jekyll
|
||||
writer.error(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a Jekyll error message and immediately abort the process
|
||||
# Public: Print an error message and immediately abort the process
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail (can be omitted)
|
||||
@@ -81,7 +91,7 @@ module Jekyll
|
||||
abort
|
||||
end
|
||||
|
||||
# Internal: Build a Jekyll topic method
|
||||
# Internal: Build a topic method
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
module Jekyll
|
||||
class Metadata
|
||||
attr_reader :site, :metadata, :cache
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
|
||||
# Read metadata from file
|
||||
read_metadata
|
||||
|
||||
# Initialize cache to an empty hash
|
||||
@cache = {}
|
||||
end
|
||||
|
||||
# Add a path to the metadata
|
||||
#
|
||||
# Returns true, also on failure.
|
||||
def add(path)
|
||||
return true unless File.exist?(path)
|
||||
|
||||
metadata[path] = {
|
||||
"mtime" => File.mtime(path),
|
||||
"deps" => []
|
||||
}
|
||||
cache[path] = true
|
||||
end
|
||||
|
||||
# Force a path to regenerate
|
||||
#
|
||||
# Returns true.
|
||||
def force(path)
|
||||
cache[path] = true
|
||||
end
|
||||
|
||||
# Clear the metadata and cache
|
||||
#
|
||||
# Returns nothing
|
||||
def clear
|
||||
@metadata = {}
|
||||
@cache = {}
|
||||
end
|
||||
|
||||
# Checks if a path should be regenerated
|
||||
#
|
||||
# Returns a boolean.
|
||||
def regenerate?(path, add = true)
|
||||
return true if disabled?
|
||||
|
||||
# Check for path in cache
|
||||
if cache.has_key? path
|
||||
return cache[path]
|
||||
end
|
||||
|
||||
# Check path that exists in metadata
|
||||
data = metadata[path]
|
||||
if data
|
||||
data["deps"].each do |dependency|
|
||||
if regenerate?(dependency)
|
||||
return cache[dependency] = cache[path] = true
|
||||
end
|
||||
end
|
||||
if data["mtime"].eql? File.mtime(path)
|
||||
return cache[path] = false
|
||||
else
|
||||
return !add || add(path)
|
||||
end
|
||||
end
|
||||
|
||||
# Path does not exist in metadata, add it
|
||||
return !add || add(path)
|
||||
end
|
||||
|
||||
# Add a dependency of a path
|
||||
#
|
||||
# Returns nothing.
|
||||
def add_dependency(path, dependency)
|
||||
return if (metadata[path].nil? || @disabled)
|
||||
|
||||
metadata[path]["deps"] << dependency unless metadata[path]["deps"].include? dependency
|
||||
regenerate? dependency
|
||||
end
|
||||
|
||||
# Write the metadata to disk
|
||||
#
|
||||
# Returns nothing.
|
||||
def write
|
||||
File.open(metadata_file, 'w') do |f|
|
||||
f.write(metadata.to_yaml)
|
||||
end
|
||||
end
|
||||
|
||||
# Produce the absolute path of the metadata file
|
||||
#
|
||||
# Returns the String path of the file.
|
||||
def metadata_file
|
||||
site.in_source_dir('.jekyll-metadata')
|
||||
end
|
||||
|
||||
# Check if metadata has been disabled
|
||||
#
|
||||
# Returns a Boolean (true for disabled, false for enabled).
|
||||
def disabled?
|
||||
@disabled = site.full_rebuild? if @disabled.nil?
|
||||
@disabled
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Read metadata from the metadata file, if no file is found,
|
||||
# initialize with an empty hash
|
||||
#
|
||||
# Returns the read metadata.
|
||||
def read_metadata
|
||||
@metadata = if !disabled? && File.file?(metadata_file)
|
||||
SafeYAML.load(File.read(metadata_file))
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,95 +1,800 @@
|
||||
-# These are the same MIME types that GitHub Pages uses as of 26 January 2014
|
||||
# Woah there. Do not edit this file directly.
|
||||
# This file is generated automatically by script/vendor-mimes.
|
||||
|
||||
text/html html htm shtml
|
||||
text/css css
|
||||
text/xml xml rss xsl xsd
|
||||
image/gif gif
|
||||
image/jpeg jpeg jpg
|
||||
application/x-javascript js
|
||||
application/atom+xml atom
|
||||
application/json json geojson topojson
|
||||
|
||||
text/mathml mml
|
||||
text/plain txt
|
||||
text/vnd.sun.j2me.app-descriptor jad
|
||||
text/vnd.wap.wml wml
|
||||
text/x-component htc
|
||||
text/cache-manifest manifest appcache
|
||||
text/coffeescript coffee
|
||||
text/plain pde
|
||||
text/plain md markdown
|
||||
text/vcard vcf vcard
|
||||
|
||||
image/png png
|
||||
image/svg+xml svg
|
||||
image/svg+xml svgz
|
||||
image/tiff tif tiff
|
||||
image/vnd.wap.wbmp wbmp
|
||||
image/x-icon ico
|
||||
image/x-jng jng
|
||||
image/x-ms-bmp bmp
|
||||
|
||||
application/vnd.ms-fontobject eot
|
||||
application/x-font-ttf ttf
|
||||
application/x-font-woff woff
|
||||
font/opentype otf
|
||||
|
||||
application/java-archive jar ear
|
||||
application/mac-binhex40 hqx
|
||||
application/msword doc
|
||||
application/pdf pdf
|
||||
application/postscript ps eps ai
|
||||
application/rdf+xml rdf
|
||||
application/rtf rtf
|
||||
application/vnd.apple.pkpass pkpass
|
||||
application/vnd.ms-excel xls
|
||||
application/vnd.ms-powerpoint ppt
|
||||
application/vnd.wap.wmlc wmlc
|
||||
application/xhtml+xml xhtml
|
||||
application/x-cocoa cco
|
||||
application/x-chrome-extension crx
|
||||
application/x-java-archive-diff jardiff
|
||||
application/x-java-jnlp-file jnlp
|
||||
application/x-makeself run
|
||||
application/x-ms-application application
|
||||
application/x-ms-manifest manifest
|
||||
application/x-ms-vsto vsto
|
||||
application/x-ns-proxy-autoconfig pac
|
||||
application/x-perl pl pm
|
||||
application/x-pilot prc pdb
|
||||
application/x-rar-compressed rar
|
||||
application/x-redhat-package-manager rpm
|
||||
application/x-sea sea
|
||||
application/x-shockwave-flash swf
|
||||
application/x-stuffit sit
|
||||
application/x-tcl tcl tk
|
||||
application/x-web-app-manifest+json webapp
|
||||
application/x-x509-ca-cert der pem crt
|
||||
application/x-xpinstall xpi
|
||||
application/x-zip war
|
||||
application/zip zip
|
||||
|
||||
application/octet-stream bin exe dll
|
||||
application/octet-stream deb
|
||||
application/octet-stream deploy
|
||||
application/octet-stream dmg
|
||||
application/octet-stream iso img
|
||||
application/octet-stream msi msp msm
|
||||
|
||||
audio/midi mid midi kar
|
||||
audio/mpeg mp3
|
||||
audio/x-realaudio ra
|
||||
audio/ogg ogg
|
||||
|
||||
video/3gpp 3gpp 3gp
|
||||
video/m4v m4v
|
||||
video/mp4 mp4
|
||||
video/mpeg mpeg mpg
|
||||
video/ogg ogg ogv
|
||||
video/quicktime mov
|
||||
video/webm webm
|
||||
video/x-flv flv
|
||||
video/x-mng mng
|
||||
video/x-ms-asf asx asf
|
||||
video/x-ms-wmv wmv
|
||||
video/x-msvideo avi
|
||||
application/andrew-inset ez
|
||||
application/applixware aw
|
||||
application/atom+xml atom
|
||||
application/atomcat+xml atomcat
|
||||
application/atomsvc+xml atomsvc
|
||||
application/bdoc bdoc
|
||||
application/ccxml+xml ccxml
|
||||
application/cdmi-capability cdmia
|
||||
application/cdmi-container cdmic
|
||||
application/cdmi-domain cdmid
|
||||
application/cdmi-object cdmio
|
||||
application/cdmi-queue cdmiq
|
||||
application/cu-seeme cu
|
||||
application/dash+xml mdp
|
||||
application/davmount+xml davmount
|
||||
application/docbook+xml dbk
|
||||
application/dssc+der dssc
|
||||
application/dssc+xml xdssc
|
||||
application/ecmascript ecma
|
||||
application/emma+xml emma
|
||||
application/epub+zip epub
|
||||
application/exi exi
|
||||
application/font-tdpfr pfr
|
||||
application/font-woff woff
|
||||
application/font-woff2 woff2
|
||||
application/gml+xml gml
|
||||
application/gpx+xml gpx
|
||||
application/gxf gxf
|
||||
application/hyperstudio stk
|
||||
application/inkml+xml ink inkml
|
||||
application/ipfix ipfix
|
||||
application/java-archive jar war ear
|
||||
application/java-serialized-object ser
|
||||
application/java-vm class
|
||||
application/javascript js
|
||||
application/json json map
|
||||
application/json5 json5
|
||||
application/jsonml+json jsonml
|
||||
application/ld+json jsonld
|
||||
application/lost+xml lostxml
|
||||
application/mac-binhex40 hqx
|
||||
application/mac-compactpro cpt
|
||||
application/mads+xml mads
|
||||
application/manifest+json webmanifest
|
||||
application/marc mrc
|
||||
application/marcxml+xml mrcx
|
||||
application/mathematica ma nb mb
|
||||
application/mathml+xml mathml
|
||||
application/mbox mbox
|
||||
application/mediaservercontrol+xml mscml
|
||||
application/metalink+xml metalink
|
||||
application/metalink4+xml meta4
|
||||
application/mets+xml mets
|
||||
application/mods+xml mods
|
||||
application/mp21 m21 mp21
|
||||
application/mp4 mp4s m4p
|
||||
application/msword doc dot
|
||||
application/mxf mxf
|
||||
application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy exe dll deb dmg iso img msi msp msm buffer
|
||||
application/oda oda
|
||||
application/oebps-package+xml opf
|
||||
application/ogg ogx
|
||||
application/omdoc+xml omdoc
|
||||
application/onenote onetoc onetoc2 onetmp onepkg
|
||||
application/oxps oxps
|
||||
application/patch-ops-error+xml xer
|
||||
application/pdf pdf
|
||||
application/pgp-encrypted pgp
|
||||
application/pgp-signature asc sig
|
||||
application/pics-rules prf
|
||||
application/pkcs10 p10
|
||||
application/pkcs7-mime p7m p7c
|
||||
application/pkcs7-signature p7s
|
||||
application/pkcs8 p8
|
||||
application/pkix-attr-cert ac
|
||||
application/pkix-cert cer
|
||||
application/pkix-crl crl
|
||||
application/pkix-pkipath pkipath
|
||||
application/pkixcmp pki
|
||||
application/pls+xml pls
|
||||
application/postscript ai eps ps
|
||||
application/prs.cww cww
|
||||
application/pskc+xml pskcxml
|
||||
application/rdf+xml rdf
|
||||
application/reginfo+xml rif
|
||||
application/relax-ng-compact-syntax rnc
|
||||
application/resource-lists+xml rl
|
||||
application/resource-lists-diff+xml rld
|
||||
application/rls-services+xml rs
|
||||
application/rpki-ghostbusters gbr
|
||||
application/rpki-manifest mft
|
||||
application/rpki-roa roa
|
||||
application/rsd+xml rsd
|
||||
application/rss+xml rss
|
||||
application/rtf rtf
|
||||
application/sbml+xml sbml
|
||||
application/scvp-cv-request scq
|
||||
application/scvp-cv-response scs
|
||||
application/scvp-vp-request spq
|
||||
application/scvp-vp-response spp
|
||||
application/sdp sdp
|
||||
application/set-payment-initiation setpay
|
||||
application/set-registration-initiation setreg
|
||||
application/shf+xml shf
|
||||
application/smil+xml smi smil
|
||||
application/sparql-query rq
|
||||
application/sparql-results+xml srx
|
||||
application/srgs gram
|
||||
application/srgs+xml grxml
|
||||
application/sru+xml sru
|
||||
application/ssdl+xml ssdl
|
||||
application/ssml+xml ssml
|
||||
application/tei+xml tei teicorpus
|
||||
application/thraud+xml tfi
|
||||
application/timestamped-data tsd
|
||||
application/vnd.3gpp.pic-bw-large plb
|
||||
application/vnd.3gpp.pic-bw-small psb
|
||||
application/vnd.3gpp.pic-bw-var pvb
|
||||
application/vnd.3gpp2.tcap tcap
|
||||
application/vnd.3m.post-it-notes pwn
|
||||
application/vnd.accpac.simply.aso aso
|
||||
application/vnd.accpac.simply.imp imp
|
||||
application/vnd.acucobol acu
|
||||
application/vnd.acucorp atc acutc
|
||||
application/vnd.adobe.air-application-installer-package+zip air
|
||||
application/vnd.adobe.formscentral.fcdt fcdt
|
||||
application/vnd.adobe.fxp fxp fxpl
|
||||
application/vnd.adobe.xdp+xml xdp
|
||||
application/vnd.adobe.xfdf xfdf
|
||||
application/vnd.ahead.space ahead
|
||||
application/vnd.airzip.filesecure.azf azf
|
||||
application/vnd.airzip.filesecure.azs azs
|
||||
application/vnd.amazon.ebook azw
|
||||
application/vnd.americandynamics.acc acc
|
||||
application/vnd.amiga.ami ami
|
||||
application/vnd.android.package-archive apk
|
||||
application/vnd.anser-web-certificate-issue-initiation cii
|
||||
application/vnd.anser-web-funds-transfer-initiation fti
|
||||
application/vnd.antix.game-component atx
|
||||
application/vnd.apple.installer+xml mpkg
|
||||
application/vnd.apple.mpegurl m3u8
|
||||
application/vnd.aristanetworks.swi swi
|
||||
application/vnd.astraea-software.iota iota
|
||||
application/vnd.audiograph aep
|
||||
application/vnd.blueice.multipass mpm
|
||||
application/vnd.bmi bmi
|
||||
application/vnd.businessobjects rep
|
||||
application/vnd.chemdraw+xml cdxml
|
||||
application/vnd.chipnuts.karaoke-mmd mmd
|
||||
application/vnd.cinderella cdy
|
||||
application/vnd.claymore cla
|
||||
application/vnd.cloanto.rp9 rp9
|
||||
application/vnd.clonk.c4group c4g c4d c4f c4p c4u
|
||||
application/vnd.cluetrust.cartomobile-config c11amc
|
||||
application/vnd.cluetrust.cartomobile-config-pkg c11amz
|
||||
application/vnd.commonspace csp
|
||||
application/vnd.contact.cmsg cdbcmsg
|
||||
application/vnd.cosmocaller cmc
|
||||
application/vnd.crick.clicker clkx
|
||||
application/vnd.crick.clicker.keyboard clkk
|
||||
application/vnd.crick.clicker.palette clkp
|
||||
application/vnd.crick.clicker.template clkt
|
||||
application/vnd.crick.clicker.wordbank clkw
|
||||
application/vnd.criticaltools.wbs+xml wbs
|
||||
application/vnd.ctc-posml pml
|
||||
application/vnd.cups-ppd ppd
|
||||
application/vnd.curl.car car
|
||||
application/vnd.curl.pcurl pcurl
|
||||
application/vnd.dart dart
|
||||
application/vnd.data-vision.rdz rdz
|
||||
application/vnd.dece.data uvf uvvf uvd uvvd
|
||||
application/vnd.dece.ttml+xml uvt uvvt
|
||||
application/vnd.dece.unspecified uvx uvvx
|
||||
application/vnd.dece.zip uvz uvvz
|
||||
application/vnd.denovo.fcselayout-link fe_launch
|
||||
application/vnd.dna dna
|
||||
application/vnd.dolby.mlp mlp
|
||||
application/vnd.dpgraph dpg
|
||||
application/vnd.dreamfactory dfac
|
||||
application/vnd.ds-keypoint kpxx
|
||||
application/vnd.dvb.ait ait
|
||||
application/vnd.dvb.service svc
|
||||
application/vnd.dynageo geo
|
||||
application/vnd.ecowin.chart mag
|
||||
application/vnd.enliven nml
|
||||
application/vnd.epson.esf esf
|
||||
application/vnd.epson.msf msf
|
||||
application/vnd.epson.quickanime qam
|
||||
application/vnd.epson.salt slt
|
||||
application/vnd.epson.ssf ssf
|
||||
application/vnd.eszigno3+xml es3 et3
|
||||
application/vnd.ezpix-album ez2
|
||||
application/vnd.ezpix-package ez3
|
||||
application/vnd.fdf fdf
|
||||
application/vnd.fdsn.mseed mseed
|
||||
application/vnd.fdsn.seed seed dataless
|
||||
application/vnd.flographit gph
|
||||
application/vnd.fluxtime.clip ftc
|
||||
application/vnd.framemaker fm frame maker book
|
||||
application/vnd.frogans.fnc fnc
|
||||
application/vnd.frogans.ltf ltf
|
||||
application/vnd.fsc.weblaunch fsc
|
||||
application/vnd.fujitsu.oasys oas
|
||||
application/vnd.fujitsu.oasys2 oa2
|
||||
application/vnd.fujitsu.oasys3 oa3
|
||||
application/vnd.fujitsu.oasysgp fg5
|
||||
application/vnd.fujitsu.oasysprs bh2
|
||||
application/vnd.fujixerox.ddd ddd
|
||||
application/vnd.fujixerox.docuworks xdw
|
||||
application/vnd.fujixerox.docuworks.binder xbd
|
||||
application/vnd.fuzzysheet fzs
|
||||
application/vnd.genomatix.tuxedo txd
|
||||
application/vnd.geogebra.file ggb
|
||||
application/vnd.geogebra.tool ggt
|
||||
application/vnd.geometry-explorer gex gre
|
||||
application/vnd.geonext gxt
|
||||
application/vnd.geoplan g2w
|
||||
application/vnd.geospace g3w
|
||||
application/vnd.gmx gmx
|
||||
application/vnd.google-earth.kml+xml kml
|
||||
application/vnd.google-earth.kmz kmz
|
||||
application/vnd.grafeq gqf gqs
|
||||
application/vnd.groove-account gac
|
||||
application/vnd.groove-help ghf
|
||||
application/vnd.groove-identity-message gim
|
||||
application/vnd.groove-injector grv
|
||||
application/vnd.groove-tool-message gtm
|
||||
application/vnd.groove-tool-template tpl
|
||||
application/vnd.groove-vcard vcg
|
||||
application/vnd.hal+xml hal
|
||||
application/vnd.handheld-entertainment+xml zmm
|
||||
application/vnd.hbci hbci
|
||||
application/vnd.hhe.lesson-player les
|
||||
application/vnd.hp-hpgl hpgl
|
||||
application/vnd.hp-hpid hpid
|
||||
application/vnd.hp-hps hps
|
||||
application/vnd.hp-jlyt jlt
|
||||
application/vnd.hp-pcl pcl
|
||||
application/vnd.hp-pclxl pclxl
|
||||
application/vnd.hydrostatix.sof-data sfd-hdstx
|
||||
application/vnd.ibm.minipay mpy
|
||||
application/vnd.ibm.modcap afp listafp list3820
|
||||
application/vnd.ibm.rights-management irm
|
||||
application/vnd.ibm.secure-container sc
|
||||
application/vnd.iccprofile icc icm
|
||||
application/vnd.igloader igl
|
||||
application/vnd.immervision-ivp ivp
|
||||
application/vnd.immervision-ivu ivu
|
||||
application/vnd.insors.igm igm
|
||||
application/vnd.intercon.formnet xpw xpx
|
||||
application/vnd.intergeo i2g
|
||||
application/vnd.intu.qbo qbo
|
||||
application/vnd.intu.qfx qfx
|
||||
application/vnd.ipunplugged.rcprofile rcprofile
|
||||
application/vnd.irepository.package+xml irp
|
||||
application/vnd.is-xpr xpr
|
||||
application/vnd.isac.fcs fcs
|
||||
application/vnd.jam jam
|
||||
application/vnd.jcp.javame.midlet-rms rms
|
||||
application/vnd.jisp jisp
|
||||
application/vnd.joost.joda-archive joda
|
||||
application/vnd.kahootz ktz ktr
|
||||
application/vnd.kde.karbon karbon
|
||||
application/vnd.kde.kchart chrt
|
||||
application/vnd.kde.kformula kfo
|
||||
application/vnd.kde.kivio flw
|
||||
application/vnd.kde.kontour kon
|
||||
application/vnd.kde.kpresenter kpr kpt
|
||||
application/vnd.kde.kspread ksp
|
||||
application/vnd.kde.kword kwd kwt
|
||||
application/vnd.kenameaapp htke
|
||||
application/vnd.kidspiration kia
|
||||
application/vnd.kinar kne knp
|
||||
application/vnd.koan skp skd skt skm
|
||||
application/vnd.kodak-descriptor sse
|
||||
application/vnd.las.las+xml lasxml
|
||||
application/vnd.llamagraphics.life-balance.desktop lbd
|
||||
application/vnd.llamagraphics.life-balance.exchange+xml lbe
|
||||
application/vnd.lotus-1-2-3 123
|
||||
application/vnd.lotus-approach apr
|
||||
application/vnd.lotus-freelance pre
|
||||
application/vnd.lotus-notes nsf
|
||||
application/vnd.lotus-organizer org
|
||||
application/vnd.lotus-screencam scm
|
||||
application/vnd.lotus-wordpro lwp
|
||||
application/vnd.macports.portpkg portpkg
|
||||
application/vnd.mcd mcd
|
||||
application/vnd.medcalcdata mc1
|
||||
application/vnd.mediastation.cdkey cdkey
|
||||
application/vnd.mfer mwf
|
||||
application/vnd.mfmp mfm
|
||||
application/vnd.micrografx.flo flo
|
||||
application/vnd.micrografx.igx igx
|
||||
application/vnd.mif mif
|
||||
application/vnd.mobius.daf daf
|
||||
application/vnd.mobius.dis dis
|
||||
application/vnd.mobius.mbk mbk
|
||||
application/vnd.mobius.mqy mqy
|
||||
application/vnd.mobius.msl msl
|
||||
application/vnd.mobius.plc plc
|
||||
application/vnd.mobius.txf txf
|
||||
application/vnd.mophun.application mpn
|
||||
application/vnd.mophun.certificate mpc
|
||||
application/vnd.mozilla.xul+xml xul
|
||||
application/vnd.ms-artgalry cil
|
||||
application/vnd.ms-cab-compressed cab
|
||||
application/vnd.ms-excel xls xlm xla xlc xlt xlw
|
||||
application/vnd.ms-excel.addin.macroenabled.12 xlam
|
||||
application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
|
||||
application/vnd.ms-excel.sheet.macroenabled.12 xlsm
|
||||
application/vnd.ms-excel.template.macroenabled.12 xltm
|
||||
application/vnd.ms-fontobject eot
|
||||
application/vnd.ms-htmlhelp chm
|
||||
application/vnd.ms-ims ims
|
||||
application/vnd.ms-lrm lrm
|
||||
application/vnd.ms-officetheme thmx
|
||||
application/vnd.ms-pki.seccat cat
|
||||
application/vnd.ms-pki.stl stl
|
||||
application/vnd.ms-powerpoint ppt pps pot
|
||||
application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
|
||||
application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
|
||||
application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
|
||||
application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
|
||||
application/vnd.ms-powerpoint.template.macroenabled.12 potm
|
||||
application/vnd.ms-project mpp mpt
|
||||
application/vnd.ms-word.document.macroenabled.12 docm
|
||||
application/vnd.ms-word.template.macroenabled.12 dotm
|
||||
application/vnd.ms-works wps wks wcm wdb
|
||||
application/vnd.ms-wpl wpl
|
||||
application/vnd.ms-xpsdocument xps
|
||||
application/vnd.mseq mseq
|
||||
application/vnd.musician mus
|
||||
application/vnd.muvee.style msty
|
||||
application/vnd.mynfc taglet
|
||||
application/vnd.neurolanguage.nlu nlu
|
||||
application/vnd.nitf ntf nitf
|
||||
application/vnd.noblenet-directory nnd
|
||||
application/vnd.noblenet-sealer nns
|
||||
application/vnd.noblenet-web nnw
|
||||
application/vnd.nokia.n-gage.data ngdat
|
||||
application/vnd.nokia.n-gage.symbian.install n-gage
|
||||
application/vnd.nokia.radio-preset rpst
|
||||
application/vnd.nokia.radio-presets rpss
|
||||
application/vnd.novadigm.edm edm
|
||||
application/vnd.novadigm.edx edx
|
||||
application/vnd.novadigm.ext ext
|
||||
application/vnd.oasis.opendocument.chart odc
|
||||
application/vnd.oasis.opendocument.chart-template otc
|
||||
application/vnd.oasis.opendocument.database odb
|
||||
application/vnd.oasis.opendocument.formula odf
|
||||
application/vnd.oasis.opendocument.formula-template odft
|
||||
application/vnd.oasis.opendocument.graphics odg
|
||||
application/vnd.oasis.opendocument.graphics-template otg
|
||||
application/vnd.oasis.opendocument.image odi
|
||||
application/vnd.oasis.opendocument.image-template oti
|
||||
application/vnd.oasis.opendocument.presentation odp
|
||||
application/vnd.oasis.opendocument.presentation-template otp
|
||||
application/vnd.oasis.opendocument.spreadsheet ods
|
||||
application/vnd.oasis.opendocument.spreadsheet-template ots
|
||||
application/vnd.oasis.opendocument.text odt
|
||||
application/vnd.oasis.opendocument.text-master odm
|
||||
application/vnd.oasis.opendocument.text-template ott
|
||||
application/vnd.oasis.opendocument.text-web oth
|
||||
application/vnd.olpc-sugar xo
|
||||
application/vnd.oma.dd2+xml dd2
|
||||
application/vnd.openofficeorg.extension oxt
|
||||
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.slide sldx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.template potx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
|
||||
application/vnd.osgeo.mapguide.package mgp
|
||||
application/vnd.osgi.dp dp
|
||||
application/vnd.osgi.subsystem esa
|
||||
application/vnd.palm pdb pqa oprc
|
||||
application/vnd.pawaafile paw
|
||||
application/vnd.pg.format str
|
||||
application/vnd.pg.osasli ei6
|
||||
application/vnd.picsel efif
|
||||
application/vnd.pmi.widget wg
|
||||
application/vnd.pocketlearn plf
|
||||
application/vnd.powerbuilder6 pbd
|
||||
application/vnd.previewsystems.box box
|
||||
application/vnd.proteus.magazine mgz
|
||||
application/vnd.publishare-delta-tree qps
|
||||
application/vnd.pvi.ptid1 ptid
|
||||
application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
|
||||
application/vnd.realvnc.bed bed
|
||||
application/vnd.recordare.musicxml mxl
|
||||
application/vnd.recordare.musicxml+xml musicxml
|
||||
application/vnd.rig.cryptonote cryptonote
|
||||
application/vnd.rim.cod cod
|
||||
application/vnd.rn-realmedia rm
|
||||
application/vnd.rn-realmedia-vbr rmvb
|
||||
application/vnd.route66.link66+xml link66
|
||||
application/vnd.sailingtracker.track st
|
||||
application/vnd.seemail see
|
||||
application/vnd.sema sema
|
||||
application/vnd.semd semd
|
||||
application/vnd.semf semf
|
||||
application/vnd.shana.informed.formdata ifm
|
||||
application/vnd.shana.informed.formtemplate itp
|
||||
application/vnd.shana.informed.interchange iif
|
||||
application/vnd.shana.informed.package ipk
|
||||
application/vnd.simtech-mindmapper twd twds
|
||||
application/vnd.smaf mmf
|
||||
application/vnd.smart.teacher teacher
|
||||
application/vnd.solent.sdkm+xml sdkm sdkd
|
||||
application/vnd.spotfire.dxp dxp
|
||||
application/vnd.spotfire.sfs sfs
|
||||
application/vnd.stardivision.calc sdc
|
||||
application/vnd.stardivision.draw sda
|
||||
application/vnd.stardivision.impress sdd
|
||||
application/vnd.stardivision.math smf
|
||||
application/vnd.stardivision.writer sdw vor
|
||||
application/vnd.stardivision.writer-global sgl
|
||||
application/vnd.stepmania.package smzip
|
||||
application/vnd.stepmania.stepchart sm
|
||||
application/vnd.sun.xml.calc sxc
|
||||
application/vnd.sun.xml.calc.template stc
|
||||
application/vnd.sun.xml.draw sxd
|
||||
application/vnd.sun.xml.draw.template std
|
||||
application/vnd.sun.xml.impress sxi
|
||||
application/vnd.sun.xml.impress.template sti
|
||||
application/vnd.sun.xml.math sxm
|
||||
application/vnd.sun.xml.writer sxw
|
||||
application/vnd.sun.xml.writer.global sxg
|
||||
application/vnd.sun.xml.writer.template stw
|
||||
application/vnd.sus-calendar sus susp
|
||||
application/vnd.svd svd
|
||||
application/vnd.symbian.install sis sisx
|
||||
application/vnd.syncml+xml xsm
|
||||
application/vnd.syncml.dm+wbxml bdm
|
||||
application/vnd.syncml.dm+xml xdm
|
||||
application/vnd.tao.intent-module-archive tao
|
||||
application/vnd.tcpdump.pcap pcap cap dmp
|
||||
application/vnd.tmobile-livetv tmo
|
||||
application/vnd.trid.tpt tpt
|
||||
application/vnd.triscape.mxs mxs
|
||||
application/vnd.trueapp tra
|
||||
application/vnd.ufdl ufd ufdl
|
||||
application/vnd.uiq.theme utz
|
||||
application/vnd.umajin umj
|
||||
application/vnd.unity unityweb
|
||||
application/vnd.uoml+xml uoml
|
||||
application/vnd.vcx vcx
|
||||
application/vnd.visio vsd vst vss vsw
|
||||
application/vnd.visionary vis
|
||||
application/vnd.vsf vsf
|
||||
application/vnd.wap.wbxml wbxml
|
||||
application/vnd.wap.wmlc wmlc
|
||||
application/vnd.wap.wmlscriptc wmlsc
|
||||
application/vnd.webturbo wtb
|
||||
application/vnd.wolfram.player nbp
|
||||
application/vnd.wordperfect wpd
|
||||
application/vnd.wqd wqd
|
||||
application/vnd.wt.stf stf
|
||||
application/vnd.xara xar
|
||||
application/vnd.xfdl xfdl
|
||||
application/vnd.yamaha.hv-dic hvd
|
||||
application/vnd.yamaha.hv-script hvs
|
||||
application/vnd.yamaha.hv-voice hvp
|
||||
application/vnd.yamaha.openscoreformat osf
|
||||
application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
|
||||
application/vnd.yamaha.smaf-audio saf
|
||||
application/vnd.yamaha.smaf-phrase spf
|
||||
application/vnd.yellowriver-custom-menu cmp
|
||||
application/vnd.zul zir zirz
|
||||
application/vnd.zzazz.deck+xml zaz
|
||||
application/voicexml+xml vxml
|
||||
application/widget wgt
|
||||
application/winhlp hlp
|
||||
application/wsdl+xml wsdl
|
||||
application/wspolicy+xml wspolicy
|
||||
application/x-7z-compressed 7z
|
||||
application/x-abiword abw
|
||||
application/x-ace-compressed ace
|
||||
application/x-authorware-bin aab x32 u32 vox
|
||||
application/x-authorware-map aam
|
||||
application/x-authorware-seg aas
|
||||
application/x-bcpio bcpio
|
||||
application/x-bittorrent torrent
|
||||
application/x-blorb blb blorb
|
||||
application/x-bzip bz
|
||||
application/x-bzip2 bz2 boz
|
||||
application/x-cbr cbr cba cbt cbz cb7
|
||||
application/x-cdlink vcd
|
||||
application/x-cfs-compressed cfs
|
||||
application/x-chat chat
|
||||
application/x-chess-pgn pgn
|
||||
application/x-chrome-extension crx
|
||||
application/x-cocoa cco
|
||||
application/x-conference nsc
|
||||
application/x-cpio cpio
|
||||
application/x-csh csh
|
||||
application/x-debian-package udeb
|
||||
application/x-dgc-compressed dgc
|
||||
application/x-director dir dcr dxr cst cct cxt w3d fgd swa
|
||||
application/x-doom wad
|
||||
application/x-dtbncx+xml ncx
|
||||
application/x-dtbook+xml dtb
|
||||
application/x-dtbresource+xml res
|
||||
application/x-dvi dvi
|
||||
application/x-envoy evy
|
||||
application/x-eva eva
|
||||
application/x-font-bdf bdf
|
||||
application/x-font-ghostscript gsf
|
||||
application/x-font-linux-psf psf
|
||||
application/x-font-otf otf
|
||||
application/x-font-pcf pcf
|
||||
application/x-font-snf snf
|
||||
application/x-font-ttf ttf ttc
|
||||
application/x-font-type1 pfa pfb pfm afm
|
||||
application/x-freearc arc
|
||||
application/x-futuresplash spl
|
||||
application/x-gca-compressed gca
|
||||
application/x-glulx ulx
|
||||
application/x-gnumeric gnumeric
|
||||
application/x-gramps-xml gramps
|
||||
application/x-gtar gtar
|
||||
application/x-hdf hdf
|
||||
application/x-httpd-php php
|
||||
application/x-install-instructions install
|
||||
application/x-java-archive-diff jardiff
|
||||
application/x-java-jnlp-file jnlp
|
||||
application/x-latex latex
|
||||
application/x-lua-bytecode luac
|
||||
application/x-lzh-compressed lzh lha
|
||||
application/x-makeself run
|
||||
application/x-mie mie
|
||||
application/x-mobipocket-ebook prc mobi
|
||||
application/x-ms-application application
|
||||
application/x-ms-shortcut lnk
|
||||
application/x-ms-wmd wmd
|
||||
application/x-ms-wmz wmz
|
||||
application/x-ms-xbap xbap
|
||||
application/x-msaccess mdb
|
||||
application/x-msbinder obd
|
||||
application/x-mscardfile crd
|
||||
application/x-msclip clp
|
||||
application/x-msdownload com bat
|
||||
application/x-msmediaview mvb m13 m14
|
||||
application/x-msmetafile wmf emf emz
|
||||
application/x-msmoney mny
|
||||
application/x-mspublisher pub
|
||||
application/x-msschedule scd
|
||||
application/x-msterminal trm
|
||||
application/x-mswrite wri
|
||||
application/x-netcdf nc cdf
|
||||
application/x-ns-proxy-autoconfig pac
|
||||
application/x-nzb nzb
|
||||
application/x-perl pl pm
|
||||
application/x-pkcs12 p12 pfx
|
||||
application/x-pkcs7-certificates p7b spc
|
||||
application/x-pkcs7-certreqresp p7r
|
||||
application/x-rar-compressed rar
|
||||
application/x-redhat-package-manager rpm
|
||||
application/x-research-info-systems ris
|
||||
application/x-sea sea
|
||||
application/x-sh sh
|
||||
application/x-shar shar
|
||||
application/x-shockwave-flash swf
|
||||
application/x-silverlight-app xap
|
||||
application/x-sql sql
|
||||
application/x-stuffit sit
|
||||
application/x-stuffitx sitx
|
||||
application/x-subrip srt
|
||||
application/x-sv4cpio sv4cpio
|
||||
application/x-sv4crc sv4crc
|
||||
application/x-t3vm-image t3
|
||||
application/x-tads gam
|
||||
application/x-tar tar
|
||||
application/x-tcl tcl tk
|
||||
application/x-tex tex
|
||||
application/x-tex-tfm tfm
|
||||
application/x-texinfo texinfo texi
|
||||
application/x-tgif obj
|
||||
application/x-ustar ustar
|
||||
application/x-wais-source src
|
||||
application/x-web-app-manifest+json webapp
|
||||
application/x-x509-ca-cert der crt pem
|
||||
application/x-xfig fig
|
||||
application/x-xliff+xml xlf
|
||||
application/x-xpinstall xpi
|
||||
application/x-xz xz
|
||||
application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8
|
||||
application/xaml+xml xaml
|
||||
application/xcap-diff+xml xdf
|
||||
application/xenc+xml xenc
|
||||
application/xhtml+xml xhtml xht
|
||||
application/xml xml xsl xsd
|
||||
application/xml-dtd dtd
|
||||
application/xop+xml xop
|
||||
application/xproc+xml xpl
|
||||
application/xslt+xml xslt
|
||||
application/xspf+xml xspf
|
||||
application/xv+xml mxml xhvml xvml xvm
|
||||
application/yang yang
|
||||
application/yin+xml yin
|
||||
application/zip zip
|
||||
audio/adpcm adp
|
||||
audio/basic au snd
|
||||
audio/midi mid midi kar rmi
|
||||
audio/mp4 mp4a m4a
|
||||
audio/mpeg mpga mp2 mp2a mp3 m2a m3a
|
||||
audio/ogg oga ogg spx
|
||||
audio/s3m s3m
|
||||
audio/silk sil
|
||||
audio/vnd.dece.audio uva uvva
|
||||
audio/vnd.digital-winds eol
|
||||
audio/vnd.dra dra
|
||||
audio/vnd.dts dts
|
||||
audio/vnd.dts.hd dtshd
|
||||
audio/vnd.lucent.voice lvp
|
||||
audio/vnd.ms-playready.media.pya pya
|
||||
audio/vnd.nuera.ecelp4800 ecelp4800
|
||||
audio/vnd.nuera.ecelp7470 ecelp7470
|
||||
audio/vnd.nuera.ecelp9600 ecelp9600
|
||||
audio/vnd.rip rip
|
||||
audio/wav wav
|
||||
audio/webm weba
|
||||
audio/x-aac aac
|
||||
audio/x-aiff aif aiff aifc
|
||||
audio/x-caf caf
|
||||
audio/x-flac flac
|
||||
audio/x-matroska mka
|
||||
audio/x-mpegurl m3u
|
||||
audio/x-ms-wax wax
|
||||
audio/x-ms-wma wma
|
||||
audio/x-pn-realaudio ram ra
|
||||
audio/x-pn-realaudio-plugin rmp
|
||||
audio/xm xm
|
||||
chemical/x-cdx cdx
|
||||
chemical/x-cif cif
|
||||
chemical/x-cmdf cmdf
|
||||
chemical/x-cml cml
|
||||
chemical/x-csml csml
|
||||
chemical/x-xyz xyz
|
||||
image/bmp bmp
|
||||
image/cgm cgm
|
||||
image/g3fax g3
|
||||
image/gif gif
|
||||
image/ief ief
|
||||
image/jpeg jpeg jpg jpe
|
||||
image/ktx ktx
|
||||
image/png png
|
||||
image/prs.btif btif
|
||||
image/sgi sgi
|
||||
image/svg+xml svg svgz
|
||||
image/tiff tiff tif
|
||||
image/vnd.adobe.photoshop psd
|
||||
image/vnd.dece.graphic uvi uvvi uvg uvvg
|
||||
image/vnd.djvu djvu djv
|
||||
image/vnd.dvb.subtitle sub
|
||||
image/vnd.dwg dwg
|
||||
image/vnd.dxf dxf
|
||||
image/vnd.fastbidsheet fbs
|
||||
image/vnd.fpx fpx
|
||||
image/vnd.fst fst
|
||||
image/vnd.fujixerox.edmics-mmr mmr
|
||||
image/vnd.fujixerox.edmics-rlc rlc
|
||||
image/vnd.ms-modi mdi
|
||||
image/vnd.ms-photo wdp
|
||||
image/vnd.net-fpx npx
|
||||
image/vnd.wap.wbmp wbmp
|
||||
image/vnd.xiff xif
|
||||
image/webp webp
|
||||
image/x-3ds 3ds
|
||||
image/x-cmu-raster ras
|
||||
image/x-cmx cmx
|
||||
image/x-freehand fh fhc fh4 fh5 fh7
|
||||
image/x-icon ico
|
||||
image/x-jng jng
|
||||
image/x-mrsid-image sid
|
||||
image/x-pcx pcx
|
||||
image/x-pict pic pct
|
||||
image/x-portable-anymap pnm
|
||||
image/x-portable-bitmap pbm
|
||||
image/x-portable-graymap pgm
|
||||
image/x-portable-pixmap ppm
|
||||
image/x-rgb rgb
|
||||
image/x-tga tga
|
||||
image/x-xbitmap xbm
|
||||
image/x-xpixmap xpm
|
||||
image/x-xwindowdump xwd
|
||||
message/rfc822 eml mime
|
||||
model/iges igs iges
|
||||
model/mesh msh mesh silo
|
||||
model/vnd.collada+xml dae
|
||||
model/vnd.dwf dwf
|
||||
model/vnd.gdl gdl
|
||||
model/vnd.gtw gtw
|
||||
model/vnd.mts mts
|
||||
model/vnd.vtu vtu
|
||||
model/vrml wrl vrml
|
||||
model/x3d+binary x3db x3dbz
|
||||
model/x3d+vrml x3dv x3dvz
|
||||
model/x3d+xml x3d x3dz
|
||||
text/cache-manifest appcache manifest
|
||||
text/calendar ics ifb
|
||||
text/coffeescript coffee litcoffee
|
||||
text/css css
|
||||
text/csv csv
|
||||
text/hjson hjson
|
||||
text/html html htm shtml
|
||||
text/jade jade
|
||||
text/jsx jsx
|
||||
text/less less
|
||||
text/mathml mml
|
||||
text/n3 n3
|
||||
text/plain txt text conf def list log in ini
|
||||
text/prs.lines.tag dsc
|
||||
text/richtext rtx
|
||||
text/sgml sgml sgm
|
||||
text/stylus stylus styl
|
||||
text/tab-separated-values tsv
|
||||
text/troff t tr roff man me ms
|
||||
text/turtle ttl
|
||||
text/uri-list uri uris urls
|
||||
text/vcard vcard
|
||||
text/vnd.curl curl
|
||||
text/vnd.curl.dcurl dcurl
|
||||
text/vnd.curl.mcurl mcurl
|
||||
text/vnd.curl.scurl scurl
|
||||
text/vnd.fly fly
|
||||
text/vnd.fmi.flexstor flx
|
||||
text/vnd.graphviz gv
|
||||
text/vnd.in3d.3dml 3dml
|
||||
text/vnd.in3d.spot spot
|
||||
text/vnd.sun.j2me.app-descriptor jad
|
||||
text/vnd.wap.wml wml
|
||||
text/vnd.wap.wmlscript wmls
|
||||
text/vtt vtt
|
||||
text/x-asm s asm
|
||||
text/x-c c cc cxx cpp h hh dic
|
||||
text/x-component htc
|
||||
text/x-fortran f for f77 f90
|
||||
text/x-handlebars-template hbs
|
||||
text/x-java-source java
|
||||
text/x-lua lua
|
||||
text/x-markdown markdown md mkd
|
||||
text/x-nfo nfo
|
||||
text/x-opml opml
|
||||
text/x-pascal p pas
|
||||
text/x-processing pde
|
||||
text/x-sass sass
|
||||
text/x-scss scss
|
||||
text/x-setext etx
|
||||
text/x-sfv sfv
|
||||
text/x-uuencode uu
|
||||
text/x-vcalendar vcs
|
||||
text/x-vcard vcf
|
||||
text/yaml yaml yml
|
||||
video/3gpp 3gp 3gpp
|
||||
video/3gpp2 3g2
|
||||
video/h261 h261
|
||||
video/h263 h263
|
||||
video/h264 h264
|
||||
video/jpeg jpgv
|
||||
video/jpm jpm jpgm
|
||||
video/mj2 mj2 mjp2
|
||||
video/mp2t ts
|
||||
video/mp4 mp4 mp4v mpg4
|
||||
video/mpeg mpeg mpg mpe m1v m2v
|
||||
video/ogg ogv
|
||||
video/quicktime qt mov
|
||||
video/vnd.dece.hd uvh uvvh
|
||||
video/vnd.dece.mobile uvm uvvm
|
||||
video/vnd.dece.pd uvp uvvp
|
||||
video/vnd.dece.sd uvs uvvs
|
||||
video/vnd.dece.video uvv uvvv
|
||||
video/vnd.dvb.file dvb
|
||||
video/vnd.fvt fvt
|
||||
video/vnd.mpegurl mxu m4u
|
||||
video/vnd.ms-playready.media.pyv pyv
|
||||
video/vnd.uvvu.mp4 uvu uvvu
|
||||
video/vnd.vivo viv
|
||||
video/webm webm
|
||||
video/x-f4v f4v
|
||||
video/x-fli fli
|
||||
video/x-flv flv
|
||||
video/x-m4v m4v
|
||||
video/x-matroska mkv mk3d mks
|
||||
video/x-mng mng
|
||||
video/x-ms-asf asf asx
|
||||
video/x-ms-vob vob
|
||||
video/x-ms-wm wm
|
||||
video/x-ms-wmv wmv
|
||||
video/x-ms-wmx wmx
|
||||
video/x-ms-wvx wvx
|
||||
video/x-msvideo avi
|
||||
video/x-sgi-movie movie
|
||||
video/x-smv smv
|
||||
x-conference/x-cooltalk ice
|
||||
@@ -35,6 +35,8 @@ module Jekyll
|
||||
data.default_proc = proc do |hash, key|
|
||||
site.frontmatter_defaults.find(File.join(dir, name), type, key)
|
||||
end
|
||||
|
||||
Jekyll::Hooks.trigger :pages, :post_init, self
|
||||
end
|
||||
|
||||
# The generated directory into which the page will be placed
|
||||
@@ -52,27 +54,19 @@ module Jekyll
|
||||
# Returns the String permalink or nil if none has been set.
|
||||
def permalink
|
||||
return nil if data.nil? || data['permalink'].nil?
|
||||
if site.config['relative_permalinks']
|
||||
File.join(@dir, data['permalink'])
|
||||
else
|
||||
data['permalink']
|
||||
end
|
||||
data['permalink']
|
||||
end
|
||||
|
||||
# The template of the permalink.
|
||||
#
|
||||
# Returns the template String.
|
||||
def template
|
||||
if site.permalink_style == :pretty
|
||||
if index? && html?
|
||||
"/:path/"
|
||||
elsif html?
|
||||
"/:path/:basename/"
|
||||
else
|
||||
"/:path/:basename:output_ext"
|
||||
end
|
||||
else
|
||||
if !html?
|
||||
"/:path/:basename:output_ext"
|
||||
elsif index?
|
||||
"/:path/"
|
||||
else
|
||||
Utils.add_permalink_suffix("/:path/:basename", site.permalink_style)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -141,7 +135,8 @@ module Jekyll
|
||||
# Returns the destination file path String.
|
||||
def destination(dest)
|
||||
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if url =~ /\/$/
|
||||
path = File.join(path, "index.html") if url.end_with?("/")
|
||||
path << output_ext unless path.end_with?(output_ext)
|
||||
path
|
||||
end
|
||||
|
||||
@@ -159,9 +154,5 @@ module Jekyll
|
||||
def index?
|
||||
basename == 'index'
|
||||
end
|
||||
|
||||
def uses_relative_permalinks
|
||||
permalink && !@dir.empty? && site.config['relative_permalinks']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,6 +17,7 @@ module Jekyll
|
||||
def conscientious_require
|
||||
require_plugin_files
|
||||
require_gems
|
||||
deprecation_checks
|
||||
end
|
||||
|
||||
# Require each of the gem plugins specified.
|
||||
@@ -81,10 +82,19 @@ module Jekyll
|
||||
#
|
||||
# Returns an Array of plugin search paths
|
||||
def plugins_path
|
||||
if (site.config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
|
||||
[site.in_source_dir(site.config['plugins'])]
|
||||
if (site.config['plugins_dir'] == Jekyll::Configuration::DEFAULTS['plugins_dir'])
|
||||
[site.in_source_dir(site.config['plugins_dir'])]
|
||||
else
|
||||
Array(site.config['plugins']).map { |d| File.expand_path(d) }
|
||||
Array(site.config['plugins_dir']).map { |d| File.expand_path(d) }
|
||||
end
|
||||
end
|
||||
|
||||
def deprecation_checks
|
||||
pagination_included = (site.config['gems'] || []).include?('jekyll-paginate') || defined?(Jekyll::Paginate)
|
||||
if site.config['paginate'] && !pagination_included
|
||||
Jekyll::Deprecator.deprecation_message "You appear to have pagination " +
|
||||
"turned on, but you haven't included the `jekyll-paginate` gem. " +
|
||||
"Ensure you have `gems: [jekyll-paginate]` in your configuration file."
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
module Jekyll
|
||||
class Post
|
||||
include Comparable
|
||||
include Convertible
|
||||
|
||||
# Valid post name regex.
|
||||
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
||||
|
||||
EXCERPT_ATTRIBUTES_FOR_LIQUID = %w[
|
||||
title
|
||||
url
|
||||
dir
|
||||
date
|
||||
id
|
||||
categories
|
||||
next
|
||||
previous
|
||||
tags
|
||||
path
|
||||
]
|
||||
|
||||
# Attributes for Liquid templates
|
||||
ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID + %w[
|
||||
content
|
||||
excerpt
|
||||
]
|
||||
|
||||
# Post name validator. Post filenames must be like:
|
||||
# 2008-11-05-my-awesome-post.textile
|
||||
#
|
||||
# Returns true if valid, false if not.
|
||||
def self.valid?(name)
|
||||
name =~ MATCHER
|
||||
end
|
||||
|
||||
attr_accessor :site
|
||||
attr_accessor :data, :extracted_excerpt, :content, :output, :ext
|
||||
attr_accessor :date, :slug, :tags, :categories
|
||||
|
||||
attr_reader :name
|
||||
|
||||
# Initialize this Post instance.
|
||||
#
|
||||
# site - The Site.
|
||||
# base - The String path to the dir containing the post file.
|
||||
# name - The String filename of the post file.
|
||||
#
|
||||
# Returns the new Post.
|
||||
def initialize(site, source, dir, name)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@base = containing_dir(dir)
|
||||
@name = name
|
||||
|
||||
self.categories = dir.downcase.split('/').reject { |x| x.empty? }
|
||||
process(name)
|
||||
read_yaml(@base, name)
|
||||
|
||||
data.default_proc = proc do |hash, key|
|
||||
site.frontmatter_defaults.find(File.join(dir, name), type, key)
|
||||
end
|
||||
|
||||
if data.key?('date')
|
||||
self.date = Utils.parse_date(data["date"].to_s, "Post '#{relative_path}' does not have a valid date in the YAML front matter.")
|
||||
end
|
||||
|
||||
populate_categories
|
||||
populate_tags
|
||||
end
|
||||
|
||||
def published?
|
||||
if data.key?('published') && data['published'] == false
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def populate_categories
|
||||
categories_from_data = Utils.pluralized_array_from_hash(data, 'category', 'categories')
|
||||
self.categories = (
|
||||
Array(categories) + categories_from_data
|
||||
).map {|c| c.to_s.downcase}.flatten.uniq
|
||||
end
|
||||
|
||||
def populate_tags
|
||||
self.tags = Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
|
||||
end
|
||||
|
||||
# Get the full path to the directory containing the post files
|
||||
def containing_dir(dir)
|
||||
site.in_source_dir(dir, '_posts')
|
||||
end
|
||||
|
||||
# Read the YAML frontmatter.
|
||||
#
|
||||
# base - The String path to the dir containing the file.
|
||||
# name - The String filename of the file.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_yaml(base, name)
|
||||
super(base, name)
|
||||
self.extracted_excerpt = extract_excerpt
|
||||
end
|
||||
|
||||
# The post excerpt. This is either a custom excerpt
|
||||
# set in YAML front matter or the result of extract_excerpt.
|
||||
#
|
||||
# Returns excerpt string.
|
||||
def excerpt
|
||||
data.fetch('excerpt') { extracted_excerpt.to_s }
|
||||
end
|
||||
|
||||
# Public: the Post title, from the YAML Front-Matter or from the slug
|
||||
#
|
||||
# Returns the post title
|
||||
def title
|
||||
data.fetch('title') { titleized_slug }
|
||||
end
|
||||
|
||||
# Turns the post slug into a suitable title
|
||||
def titleized_slug
|
||||
slug.split('-').select {|w| w.capitalize! || w }.join(' ')
|
||||
end
|
||||
|
||||
# Public: the path to the post relative to the site source,
|
||||
# from the YAML Front-Matter or from a combination of
|
||||
# the directory it's in, "_posts", and the name of the
|
||||
# post file
|
||||
#
|
||||
# Returns the path to the file relative to the site source
|
||||
def path
|
||||
data.fetch('path') { relative_path.sub(/\A\//, '') }
|
||||
end
|
||||
|
||||
# The path to the post source file, relative to the site source
|
||||
def relative_path
|
||||
File.join(*[@dir, "_posts", @name].map(&:to_s).reject(&:empty?))
|
||||
end
|
||||
|
||||
# Compares Post objects. First compares the Post date. If the dates are
|
||||
# equal, it compares the Post slugs.
|
||||
#
|
||||
# other - The other Post we are comparing to.
|
||||
#
|
||||
# Returns -1, 0, 1
|
||||
def <=>(other)
|
||||
cmp = self.date <=> other.date
|
||||
if 0 == cmp
|
||||
cmp = self.slug <=> other.slug
|
||||
end
|
||||
return cmp
|
||||
end
|
||||
|
||||
# Extract information from the post filename.
|
||||
#
|
||||
# name - The String filename of the post file.
|
||||
#
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
m, cats, date, slug, ext = *name.match(MATCHER)
|
||||
self.date = Utils.parse_date(date, "Post '#{relative_path}' does not have a valid date in the filename.")
|
||||
self.slug = slug
|
||||
self.ext = ext
|
||||
end
|
||||
|
||||
# The generated directory into which the post will be placed
|
||||
# upon generation. This is derived from the permalink or, if
|
||||
# permalink is absent, set to the default date
|
||||
# e.g. "/2008/11/05/" if the permalink style is :date, otherwise nothing.
|
||||
#
|
||||
# Returns the String directory.
|
||||
def dir
|
||||
File.dirname(url)
|
||||
end
|
||||
|
||||
# The full path and filename of the post. Defined in the YAML of the post
|
||||
# body (optional).
|
||||
#
|
||||
# Returns the String permalink.
|
||||
def permalink
|
||||
data && data['permalink']
|
||||
end
|
||||
|
||||
def template
|
||||
case site.permalink_style
|
||||
when :pretty
|
||||
"/:categories/:year/:month/:day/:title/"
|
||||
when :none
|
||||
"/:categories/:title.html"
|
||||
when :date
|
||||
"/:categories/:year/:month/:day/:title.html"
|
||||
when :ordinal
|
||||
"/:categories/:year/:y_day/:title.html"
|
||||
else
|
||||
site.permalink_style.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# The generated relative url of this post.
|
||||
#
|
||||
# Returns the String url.
|
||||
def url
|
||||
@url ||= URL.new({
|
||||
:template => template,
|
||||
:placeholders => url_placeholders,
|
||||
:permalink => permalink
|
||||
}).to_s
|
||||
end
|
||||
|
||||
# Returns a hash of URL placeholder names (as symbols) mapping to the
|
||||
# desired placeholder replacements. For details see "url.rb"
|
||||
def url_placeholders
|
||||
{
|
||||
:year => date.strftime("%Y"),
|
||||
:month => date.strftime("%m"),
|
||||
:day => date.strftime("%d"),
|
||||
:title => slug,
|
||||
:i_day => date.strftime("%-d"),
|
||||
:i_month => date.strftime("%-m"),
|
||||
:categories => (categories || []).map { |c| c.to_s }.join('/'),
|
||||
:short_month => date.strftime("%b"),
|
||||
:short_year => date.strftime("%y"),
|
||||
:y_day => date.strftime("%j"),
|
||||
:output_ext => output_ext
|
||||
}
|
||||
end
|
||||
|
||||
# The UID for this post (useful in feeds).
|
||||
# e.g. /2008/11/05/my-awesome-post
|
||||
#
|
||||
# Returns the String UID.
|
||||
def id
|
||||
File.join(dir, slug)
|
||||
end
|
||||
|
||||
# Calculate related posts.
|
||||
#
|
||||
# Returns an Array of related Posts.
|
||||
def related_posts(posts)
|
||||
Jekyll::RelatedPosts.new(self).build
|
||||
end
|
||||
|
||||
# Add any necessary layouts to this post.
|
||||
#
|
||||
# layouts - A Hash of {"name" => "layout"}.
|
||||
# site_payload - The site payload hash.
|
||||
#
|
||||
# Returns nothing.
|
||||
def render(layouts, site_payload)
|
||||
# construct payload
|
||||
payload = Utils.deep_merge_hashes({
|
||||
"site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
|
||||
"page" => to_liquid(self.class::EXCERPT_ATTRIBUTES_FOR_LIQUID)
|
||||
}, site_payload)
|
||||
|
||||
if generate_excerpt?
|
||||
extracted_excerpt.do_layout(payload, {})
|
||||
end
|
||||
|
||||
do_layout(payload.merge({"page" => to_liquid}), layouts)
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns destination file path String.
|
||||
def destination(dest)
|
||||
# The url needs to be unescaped in order to preserve the correct filename
|
||||
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if path[/\.html?$/].nil?
|
||||
path
|
||||
end
|
||||
|
||||
# Returns the shorthand String identifier of this Post.
|
||||
def inspect
|
||||
"<Post: #{id}>"
|
||||
end
|
||||
|
||||
def next
|
||||
pos = site.posts.index {|post| post.equal?(self) }
|
||||
if pos && pos < site.posts.length - 1
|
||||
site.posts[pos + 1]
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def previous
|
||||
pos = site.posts.index {|post| post.equal?(self) }
|
||||
if pos && pos > 0
|
||||
site.posts[pos - 1]
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def extract_excerpt
|
||||
if generate_excerpt?
|
||||
Jekyll::Excerpt.new(self)
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def generate_excerpt?
|
||||
!(site.config['excerpt_separator'].to_s.empty?)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -15,7 +15,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
def hidden_in_the_future?(thing)
|
||||
thing.is_a?(Post) && !@site.future && thing.date > @site.time
|
||||
thing.respond_to?(:date) && !@site.future && thing.date.to_i > @site.time.to_i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
126
lib/jekyll/reader.rb
Normal file
126
lib/jekyll/reader.rb
Normal file
@@ -0,0 +1,126 @@
|
||||
# encoding: UTF-8
|
||||
require 'csv'
|
||||
|
||||
module Jekyll
|
||||
class Reader
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Read Site data from disk and load it into internal data structures.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read
|
||||
@site.layouts = LayoutReader.new(site).read
|
||||
read_directories
|
||||
sort_files!
|
||||
@site.data = DataReader.new(site).read(site.config['data_dir'])
|
||||
CollectionReader.new(site).read
|
||||
end
|
||||
|
||||
# Sorts posts, pages, and static files.
|
||||
def sort_files!
|
||||
site.collections.values.each{|c| c.docs.sort!}
|
||||
site.pages.sort_by!(&:name)
|
||||
site.static_files.sort_by!(&:relative_path)
|
||||
end
|
||||
|
||||
# Recursively traverse directories to find pages and static files
|
||||
# that will become part of the site according to the rules in
|
||||
# filter_entries.
|
||||
#
|
||||
# dir - The String relative path of the directory to read. Default: ''.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_directories(dir = '')
|
||||
base = site.in_source_dir(dir)
|
||||
|
||||
dot = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
|
||||
dot_dirs = dot.select{ |file| File.directory?(@site.in_source_dir(base,file)) }
|
||||
dot_files = (dot - dot_dirs)
|
||||
dot_pages = dot_files.select{ |file| Utils.has_yaml_header?(@site.in_source_dir(base,file)) }
|
||||
dot_static_files = dot_files - dot_pages
|
||||
|
||||
retrieve_posts(dir)
|
||||
retrieve_dirs(base, dir, dot_dirs)
|
||||
retrieve_pages(dir, dot_pages)
|
||||
retrieve_static_files(dir, dot_static_files)
|
||||
end
|
||||
|
||||
# Retrieves all the posts(posts/drafts) from the given directory
|
||||
# and add them to the site and sort them.
|
||||
#
|
||||
# dir - The String representing the directory to retrieve the posts from.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_posts(dir)
|
||||
site.posts.docs.concat(PostReader.new(site).read_posts(dir))
|
||||
site.posts.docs.concat(PostReader.new(site).read_drafts(dir)) if site.show_drafts
|
||||
end
|
||||
|
||||
# Recursively traverse directories with the read_directories function.
|
||||
#
|
||||
# base - The String representing the site's base directory.
|
||||
# dir - The String representing the directory to traverse down.
|
||||
# dot_dirs - The Array of subdirectories in the dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_dirs(base, dir, dot_dirs)
|
||||
dot_dirs.map { |file|
|
||||
dir_path = site.in_source_dir(dir,file)
|
||||
rel_path = File.join(dir, file)
|
||||
@site.reader.read_directories(rel_path) unless @site.dest.sub(/\/$/, '') == dir_path
|
||||
}
|
||||
end
|
||||
|
||||
# Retrieve all the pages from the current directory,
|
||||
# add them to the site and sort them.
|
||||
#
|
||||
# dir - The String representing the directory retrieve the pages from.
|
||||
# dot_pages - The Array of pages in the dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_pages(dir, dot_pages)
|
||||
site.pages.concat(PageReader.new(site, dir).read(dot_pages))
|
||||
end
|
||||
|
||||
# Retrieve all the static files from the current directory,
|
||||
# add them to the site and sort them.
|
||||
#
|
||||
# dir - The directory retrieve the static files from.
|
||||
# dot_static_files - The static files in the dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_static_files(dir, dot_static_files)
|
||||
site.static_files.concat(StaticFileReader.new(site, dir).read(dot_static_files))
|
||||
end
|
||||
|
||||
# Filter out any files/directories that are hidden or backup files (start
|
||||
# with "." or "#" or end with "~"), or contain site content (start with "_"),
|
||||
# or are excluded in the site configuration, unless they are web server
|
||||
# files such as '.htaccess'.
|
||||
#
|
||||
# entries - The Array of String file/directory entries to filter.
|
||||
# base_directory - The string representing the optional base directory.
|
||||
#
|
||||
# Returns the Array of filtered entries.
|
||||
def filter_entries(entries, base_directory = nil)
|
||||
EntryFilter.new(site, base_directory).filter(entries)
|
||||
end
|
||||
|
||||
# Read the entries from a particular directory for processing
|
||||
#
|
||||
# dir - The String representing the relative path of the directory to read.
|
||||
# subfolder - The String representing the directory to read.
|
||||
#
|
||||
# Returns the list of entries to process
|
||||
def get_entries(dir, subfolder)
|
||||
base = site.in_source_dir(dir, subfolder)
|
||||
return [] unless File.exist?(base)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir['**/*'], base) }
|
||||
entries.delete_if { |e| File.directory?(site.in_source_dir(base, e)) }
|
||||
end
|
||||
end
|
||||
end
|
||||
21
lib/jekyll/readers/collection_reader.rb
Normal file
21
lib/jekyll/readers/collection_reader.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
module Jekyll
|
||||
class CollectionReader
|
||||
SPECIAL_COLLECTIONS = %w{posts data}.freeze
|
||||
|
||||
attr_reader :site, :content
|
||||
def initialize(site)
|
||||
@site = site
|
||||
@content = {}
|
||||
end
|
||||
|
||||
# Read in all collections specified in the configuration
|
||||
#
|
||||
# Returns nothing.
|
||||
def read
|
||||
site.collections.each do |_, collection|
|
||||
collection.read unless SPECIAL_COLLECTIONS.include?(collection.label)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
69
lib/jekyll/readers/data_reader.rb
Normal file
69
lib/jekyll/readers/data_reader.rb
Normal file
@@ -0,0 +1,69 @@
|
||||
module Jekyll
|
||||
class DataReader
|
||||
attr_reader :site, :content
|
||||
def initialize(site)
|
||||
@site = site
|
||||
@content = {}
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_drafts and create a new Draft
|
||||
# object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read(dir)
|
||||
base = site.in_source_dir(dir)
|
||||
read_data_to(base, @content)
|
||||
@content
|
||||
end
|
||||
|
||||
# Read and parse all yaml files under <dir> and add them to the
|
||||
# <data> variable.
|
||||
#
|
||||
# dir - The string absolute path of the directory to read.
|
||||
# data - The variable to which data will be added.
|
||||
#
|
||||
# Returns nothing
|
||||
def read_data_to(dir, data)
|
||||
return unless File.directory?(dir) && (!site.safe || !File.symlink?(dir))
|
||||
|
||||
entries = Dir.chdir(dir) do
|
||||
Dir['*.{yaml,yml,json,csv}'] + Dir['*'].select { |fn| File.directory?(fn) }
|
||||
end
|
||||
|
||||
entries.each do |entry|
|
||||
path = @site.in_source_dir(dir, entry)
|
||||
next if File.symlink?(path) && site.safe
|
||||
|
||||
key = sanitize_filename(File.basename(entry, '.*'))
|
||||
if File.directory?(path)
|
||||
read_data_to(path, data[key] = {})
|
||||
else
|
||||
data[key] = read_data_file(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Determines how to read a data file.
|
||||
#
|
||||
# Returns the contents of the data file.
|
||||
def read_data_file(path)
|
||||
case File.extname(path).downcase
|
||||
when '.csv'
|
||||
CSV.read(path, {
|
||||
:headers => true,
|
||||
:encoding => site.config['encoding']
|
||||
}).map(&:to_hash)
|
||||
else
|
||||
SafeYAML.load_file(path)
|
||||
end
|
||||
end
|
||||
|
||||
def sanitize_filename(name)
|
||||
name.gsub!(/[^\w\s-]+/, '')
|
||||
name.gsub!(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
||||
name.gsub(/\s+/, '_')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -38,11 +38,11 @@ module Jekyll
|
||||
end
|
||||
|
||||
def layout_directory_inside_source
|
||||
site.in_source_dir(site.config['layouts'])
|
||||
site.in_source_dir(site.config['layouts_dir'])
|
||||
end
|
||||
|
||||
def layout_directory_in_cwd
|
||||
dir = Jekyll.sanitized_path(Dir.pwd, site.config['layouts'])
|
||||
dir = Jekyll.sanitized_path(Dir.pwd, site.config['layouts_dir'])
|
||||
if File.directory?(dir) && !site.safe
|
||||
dir
|
||||
else
|
||||
21
lib/jekyll/readers/page_reader.rb
Normal file
21
lib/jekyll/readers/page_reader.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
module Jekyll
|
||||
class PageReader
|
||||
attr_reader :site, :dir, :unfiltered_content
|
||||
def initialize(site, dir)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@unfiltered_content = Array.new
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/ for Yaml header and create a new Page
|
||||
# object for each file.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns an array of static pages.
|
||||
def read(files)
|
||||
files.map{ |page| @unfiltered_content << Page.new(@site, @site.source, @dir, page) }
|
||||
@unfiltered_content.select{ |page| site.publisher.publish?(page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
62
lib/jekyll/readers/post_reader.rb
Normal file
62
lib/jekyll/readers/post_reader.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
module Jekyll
|
||||
class PostReader
|
||||
attr_reader :site, :unfiltered_content
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_drafts and create a new
|
||||
# Document object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_drafts(dir)
|
||||
read_publishable(dir, '_drafts', Document::DATELESS_FILENAME_MATCHER)
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_posts and create a new Document
|
||||
# object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_posts(dir)
|
||||
read_publishable(dir, '_posts', Document::DATE_FILENAME_MATCHER)
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/<magic_dir> and create a new
|
||||
# Document object with each one insofar as it matches the regexp matcher.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_publishable(dir, magic_dir, matcher)
|
||||
read_content(dir, magic_dir, matcher).tap do |docs|
|
||||
docs.each(&:read)
|
||||
end.select do |doc|
|
||||
site.publisher.publish?(doc)
|
||||
end
|
||||
end
|
||||
|
||||
# Read all the content files from <source>/<dir>/magic_dir
|
||||
# and return them with the type klass.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
# magic_dir - The String relative directory to <dir>,
|
||||
# looks for content here.
|
||||
# klass - The return type of the content.
|
||||
#
|
||||
# Returns klass type of content files
|
||||
def read_content(dir, magic_dir, matcher)
|
||||
@site.reader.get_entries(dir, magic_dir).map do |entry|
|
||||
next unless entry =~ matcher
|
||||
path = @site.in_source_dir(File.join(dir, magic_dir, entry))
|
||||
Document.new(path, {
|
||||
site: @site,
|
||||
collection: @site.posts
|
||||
})
|
||||
end.reject(&:nil?)
|
||||
end
|
||||
end
|
||||
end
|
||||
21
lib/jekyll/readers/static_file_reader.rb
Normal file
21
lib/jekyll/readers/static_file_reader.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
module Jekyll
|
||||
class StaticFileReader
|
||||
attr_reader :site, :dir, :unfiltered_content
|
||||
def initialize(site, dir)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@unfiltered_content = Array.new
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/ for Yaml header and create a new Page
|
||||
# object for each file.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns an array of static files.
|
||||
def read(files)
|
||||
files.map{ |file| @unfiltered_content << StaticFile.new(@site, @site.source, @dir, file)}
|
||||
@unfiltered_content
|
||||
end
|
||||
end
|
||||
end
|
||||
176
lib/jekyll/regenerator.rb
Normal file
176
lib/jekyll/regenerator.rb
Normal file
@@ -0,0 +1,176 @@
|
||||
module Jekyll
|
||||
class Regenerator
|
||||
attr_reader :site, :metadata, :cache
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
|
||||
# Read metadata from file
|
||||
read_metadata
|
||||
|
||||
# Initialize cache to an empty hash
|
||||
clear_cache
|
||||
end
|
||||
|
||||
# Checks if a renderable object needs to be regenerated
|
||||
#
|
||||
# Returns a boolean.
|
||||
def regenerate?(document)
|
||||
case document
|
||||
when Page
|
||||
document.asset_file? || document.data['regenerate'] ||
|
||||
source_modified_or_dest_missing?(
|
||||
site.in_source_dir(document.relative_path), document.destination(@site.dest)
|
||||
)
|
||||
when Document
|
||||
!document.write? || document.data['regenerate'] ||
|
||||
source_modified_or_dest_missing?(
|
||||
document.path, document.destination(@site.dest)
|
||||
)
|
||||
else
|
||||
source_path = document.respond_to?(:path) ? document.path : nil
|
||||
dest_path = document.respond_to?(:destination) ? document.destination(@site.dest) : nil
|
||||
source_modified_or_dest_missing?(source_path, dest_path)
|
||||
end
|
||||
end
|
||||
|
||||
# Add a path to the metadata
|
||||
#
|
||||
# Returns true, also on failure.
|
||||
def add(path)
|
||||
return true unless File.exist?(path)
|
||||
|
||||
metadata[path] = {
|
||||
"mtime" => File.mtime(path),
|
||||
"deps" => []
|
||||
}
|
||||
cache[path] = true
|
||||
end
|
||||
|
||||
# Force a path to regenerate
|
||||
#
|
||||
# Returns true.
|
||||
def force(path)
|
||||
cache[path] = true
|
||||
end
|
||||
|
||||
# Clear the metadata and cache
|
||||
#
|
||||
# Returns nothing
|
||||
def clear
|
||||
@metadata = {}
|
||||
clear_cache
|
||||
end
|
||||
|
||||
|
||||
# Clear just the cache
|
||||
#
|
||||
# Returns nothing
|
||||
def clear_cache
|
||||
@cache = {}
|
||||
end
|
||||
|
||||
|
||||
# Checks if the source has been modified or the
|
||||
# destination is missing
|
||||
#
|
||||
# returns a boolean
|
||||
def source_modified_or_dest_missing?(source_path, dest_path)
|
||||
modified?(source_path) || (dest_path and !File.exist?(dest_path))
|
||||
end
|
||||
|
||||
# Checks if a path's (or one of its dependencies)
|
||||
# mtime has changed
|
||||
#
|
||||
# Returns a boolean.
|
||||
def modified?(path)
|
||||
return true if disabled?
|
||||
|
||||
# objects that don't have a path are always regenerated
|
||||
return true if path.nil?
|
||||
|
||||
# Check for path in cache
|
||||
if cache.has_key? path
|
||||
return cache[path]
|
||||
end
|
||||
|
||||
# Check path that exists in metadata
|
||||
data = metadata[path]
|
||||
if data
|
||||
data["deps"].each do |dependency|
|
||||
if modified?(dependency)
|
||||
return cache[dependency] = cache[path] = true
|
||||
end
|
||||
end
|
||||
if File.exist?(path) && data["mtime"].eql?(File.mtime(path))
|
||||
return cache[path] = false
|
||||
else
|
||||
return add(path)
|
||||
end
|
||||
end
|
||||
|
||||
# Path does not exist in metadata, add it
|
||||
return add(path)
|
||||
end
|
||||
|
||||
# Add a dependency of a path
|
||||
#
|
||||
# Returns nothing.
|
||||
def add_dependency(path, dependency)
|
||||
return if (metadata[path].nil? || @disabled)
|
||||
|
||||
if !metadata[path]["deps"].include? dependency
|
||||
metadata[path]["deps"] << dependency
|
||||
add(dependency) unless metadata.include?(dependency)
|
||||
end
|
||||
regenerate? dependency
|
||||
end
|
||||
|
||||
# Write the metadata to disk
|
||||
#
|
||||
# Returns nothing.
|
||||
def write_metadata
|
||||
unless disabled?
|
||||
File.binwrite(metadata_file, Marshal.dump(metadata))
|
||||
end
|
||||
end
|
||||
|
||||
# Produce the absolute path of the metadata file
|
||||
#
|
||||
# Returns the String path of the file.
|
||||
def metadata_file
|
||||
site.in_source_dir('.jekyll-metadata')
|
||||
end
|
||||
|
||||
# Check if metadata has been disabled
|
||||
#
|
||||
# Returns a Boolean (true for disabled, false for enabled).
|
||||
def disabled?
|
||||
@disabled = !site.incremental? if @disabled.nil?
|
||||
@disabled
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Read metadata from the metadata file, if no file is found,
|
||||
# initialize with an empty hash
|
||||
#
|
||||
# Returns the read metadata.
|
||||
def read_metadata
|
||||
@metadata = if !disabled? && File.file?(metadata_file)
|
||||
content = File.binread(metadata_file)
|
||||
|
||||
begin
|
||||
Marshal.load(content)
|
||||
rescue TypeError
|
||||
SafeYAML.load(content)
|
||||
rescue ArgumentError => e
|
||||
Jekyll.logger.warn("Failed to load #{metadata_file}: #{e}")
|
||||
{}
|
||||
end
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,11 +10,11 @@ module Jekyll
|
||||
def initialize(post)
|
||||
@post = post
|
||||
@site = post.site
|
||||
require 'classifier-reborn' if site.lsi
|
||||
Jekyll::External.require_with_graceful_fail('classifier-reborn') if site.lsi
|
||||
end
|
||||
|
||||
def build
|
||||
return [] unless site.posts.size > 1
|
||||
return [] unless site.posts.docs.size > 1
|
||||
|
||||
if site.lsi
|
||||
build_index
|
||||
@@ -30,7 +30,7 @@ module Jekyll
|
||||
lsi = ClassifierReborn::LSI.new(:auto_rebuild => false)
|
||||
display("Populating LSI...")
|
||||
|
||||
site.posts.each do |x|
|
||||
site.posts.docs.each do |x|
|
||||
lsi.add_item(x)
|
||||
end
|
||||
|
||||
@@ -42,11 +42,11 @@ module Jekyll
|
||||
end
|
||||
|
||||
def lsi_related_posts
|
||||
self.class.lsi.find_related(post.content, 11) - [post]
|
||||
self.class.lsi.find_related(post, 11)
|
||||
end
|
||||
|
||||
def most_recent_posts
|
||||
@most_recent_posts ||= (site.posts.reverse - [post]).first(10)
|
||||
@most_recent_posts ||= (site.posts.docs.reverse - [post]).first(10)
|
||||
end
|
||||
|
||||
def display(output)
|
||||
|
||||
@@ -23,7 +23,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the output extname including the leading period.
|
||||
def output_ext
|
||||
converters.first.output_ext(document.extname)
|
||||
@output_ext ||= converters.first.output_ext(document.extname)
|
||||
end
|
||||
|
||||
######################
|
||||
@@ -31,10 +31,19 @@ module Jekyll
|
||||
######################
|
||||
|
||||
def run
|
||||
Jekyll.logger.debug "Rendering:", document.relative_path
|
||||
|
||||
payload = Utils.deep_merge_hashes({
|
||||
"page" => document.to_liquid
|
||||
}, site_payload || site.site_payload)
|
||||
|
||||
if document.collection.label == 'posts' && document.is_a?(Document)
|
||||
payload['site']['related_posts'] = document.related_posts
|
||||
end
|
||||
|
||||
Jekyll.logger.debug "Pre-Render Hooks:", document.relative_path
|
||||
document.trigger_hooks(:pre_render, payload)
|
||||
|
||||
info = {
|
||||
filters: [Jekyll::Filters],
|
||||
registers: { :site => site, :page => payload['page'] }
|
||||
@@ -47,13 +56,16 @@ module Jekyll
|
||||
output = document.content
|
||||
|
||||
if document.render_with_liquid?
|
||||
output = render_liquid(output, payload, info)
|
||||
Jekyll.logger.debug "Rendering Liquid:", document.relative_path
|
||||
output = render_liquid(output, payload, info, document.path)
|
||||
end
|
||||
|
||||
Jekyll.logger.debug "Rendering Markup:", document.relative_path
|
||||
output = convert(output)
|
||||
document.content = output
|
||||
|
||||
if document.place_in_layout?
|
||||
Jekyll.logger.debug "Rendering Layout:", document.relative_path
|
||||
place_in_layouts(
|
||||
output,
|
||||
payload,
|
||||
@@ -90,7 +102,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the content, rendered by Liquid.
|
||||
def render_liquid(content, payload, info, path = nil)
|
||||
Liquid::Template.parse(content).render!(payload, info)
|
||||
site.liquid_renderer.file(path).parse(content).render!(payload, info)
|
||||
rescue Tags::IncludeTagError => e
|
||||
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{e.path}, included in #{path || document.relative_path}"
|
||||
raise e
|
||||
@@ -136,11 +148,11 @@ module Jekyll
|
||||
layout.content,
|
||||
payload,
|
||||
info,
|
||||
File.join(site.config['layouts'], layout.name)
|
||||
File.join(site.config['layouts_dir'], layout.name)
|
||||
)
|
||||
|
||||
# Add layout to dependency tree
|
||||
site.metadata.add_dependency(
|
||||
site.regenerator.add_dependency(
|
||||
site.in_source_dir(document.path),
|
||||
site.in_source_dir(layout.path)
|
||||
) if document.write?
|
||||
|
||||
@@ -4,14 +4,14 @@ require 'csv'
|
||||
module Jekyll
|
||||
class Site
|
||||
attr_reader :source, :dest, :config
|
||||
attr_accessor :layouts, :posts, :pages, :static_files,
|
||||
attr_accessor :layouts, :pages, :static_files, :drafts,
|
||||
:exclude, :include, :lsi, :highlighter, :permalink_style,
|
||||
:time, :future, :unpublished, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts,
|
||||
:gems, :plugin_manager
|
||||
|
||||
attr_accessor :converters, :generators
|
||||
attr_reader :metadata
|
||||
attr_accessor :converters, :generators, :reader
|
||||
attr_reader :regenerator, :liquid_renderer
|
||||
|
||||
# Public: Initialize a new Site.
|
||||
#
|
||||
@@ -28,8 +28,12 @@ module Jekyll
|
||||
@source = File.expand_path(config['source']).freeze
|
||||
@dest = File.expand_path(config['destination']).freeze
|
||||
|
||||
# Build metadata
|
||||
@metadata = Metadata.new(self)
|
||||
@reader = Jekyll::Reader.new(self)
|
||||
|
||||
# Initialize incremental regenerator
|
||||
@regenerator = Regenerator.new(self)
|
||||
|
||||
@liquid_renderer = LiquidRenderer.new(self)
|
||||
|
||||
self.plugin_manager = Jekyll::PluginManager.new(self)
|
||||
self.plugins = plugin_manager.plugins_path
|
||||
@@ -55,6 +59,13 @@ module Jekyll
|
||||
render
|
||||
cleanup
|
||||
write
|
||||
print_stats
|
||||
end
|
||||
|
||||
def print_stats
|
||||
if @config['profile']
|
||||
puts @liquid_renderer.stats_table
|
||||
end
|
||||
end
|
||||
|
||||
# Reset Site details.
|
||||
@@ -63,15 +74,18 @@ module Jekyll
|
||||
def reset
|
||||
self.time = (config['time'] ? Utils.parse_date(config['time'].to_s, "Invalid time in _config.yml.") : Time.now)
|
||||
self.layouts = {}
|
||||
self.posts = []
|
||||
self.pages = []
|
||||
self.static_files = []
|
||||
self.data = {}
|
||||
@collections = nil
|
||||
@regenerator.clear_cache
|
||||
@liquid_renderer.reset
|
||||
|
||||
if limit_posts < 0
|
||||
raise ArgumentError, "limit_posts must be a non-negative number"
|
||||
end
|
||||
|
||||
Jekyll::Hooks.trigger :site, :after_reset, self
|
||||
end
|
||||
|
||||
# Load necessary libraries, plugins, converters, and generators.
|
||||
@@ -97,30 +111,6 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the source directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# source directory
|
||||
#
|
||||
# Returns a path which is prefixed with the source directory.
|
||||
def in_source_dir(*paths)
|
||||
paths.reduce(source) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the destination directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# destination directory
|
||||
#
|
||||
# Returns a path which is prefixed with the destination directory.
|
||||
def in_dest_dir(*paths)
|
||||
paths.reduce(dest) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# The list of collections and their corresponding Jekyll::Collection instances.
|
||||
# If config['collections'] is set, a new instance is created for each item in the collection.
|
||||
# If config['collections'] is not set, a new hash is returned.
|
||||
@@ -151,130 +141,9 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read
|
||||
self.layouts = LayoutReader.new(self).read
|
||||
read_directories
|
||||
read_data(config['data_source'])
|
||||
read_collections
|
||||
end
|
||||
|
||||
# Recursively traverse directories to find posts, pages and static files
|
||||
# that will become part of the site according to the rules in
|
||||
# filter_entries.
|
||||
#
|
||||
# dir - The String relative path of the directory to read. Default: ''.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_directories(dir = '')
|
||||
base = in_source_dir(dir)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
|
||||
|
||||
read_posts(dir)
|
||||
read_drafts(dir) if show_drafts
|
||||
posts.sort!
|
||||
limit_posts! if limit_posts > 0 # limit the posts if :limit_posts option is set
|
||||
|
||||
entries.each do |f|
|
||||
f_abs = in_source_dir(base, f)
|
||||
if File.directory?(f_abs)
|
||||
f_rel = File.join(dir, f)
|
||||
read_directories(f_rel) unless dest.sub(/\/$/, '') == f_abs
|
||||
elsif Utils.has_yaml_header?(f_abs)
|
||||
page = Page.new(self, source, dir, f)
|
||||
pages << page if publisher.publish?(page)
|
||||
else
|
||||
static_files << StaticFile.new(self, source, dir, f)
|
||||
end
|
||||
end
|
||||
|
||||
pages.sort_by!(&:name)
|
||||
static_files.sort_by!(&:relative_path)
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_posts and create a new Post
|
||||
# object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_posts(dir)
|
||||
posts = read_content(dir, '_posts', Post)
|
||||
|
||||
posts.each do |post|
|
||||
aggregate_post_info(post) if publisher.publish?(post)
|
||||
end
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_drafts and create a new Post
|
||||
# object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_drafts(dir)
|
||||
drafts = read_content(dir, '_drafts', Draft)
|
||||
|
||||
drafts.each do |draft|
|
||||
if draft.published?
|
||||
aggregate_post_info(draft)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def read_content(dir, magic_dir, klass)
|
||||
get_entries(dir, magic_dir).map do |entry|
|
||||
klass.new(self, source, dir, entry) if klass.valid?(entry)
|
||||
end.reject do |entry|
|
||||
entry.nil?
|
||||
end
|
||||
end
|
||||
|
||||
# Read and parse all yaml files under <source>/<dir>
|
||||
#
|
||||
# Returns nothing
|
||||
def read_data(dir)
|
||||
base = in_source_dir(dir)
|
||||
read_data_to(base, self.data)
|
||||
end
|
||||
|
||||
# Read and parse all yaml files under <dir> and add them to the
|
||||
# <data> variable.
|
||||
#
|
||||
# dir - The string absolute path of the directory to read.
|
||||
# data - The variable to which data will be added.
|
||||
#
|
||||
# Returns nothing
|
||||
def read_data_to(dir, data)
|
||||
return unless File.directory?(dir) && (!safe || !File.symlink?(dir))
|
||||
|
||||
entries = Dir.chdir(dir) do
|
||||
Dir['*.{yaml,yml,json,csv}'] + Dir['*'].select { |fn| File.directory?(fn) }
|
||||
end
|
||||
|
||||
entries.each do |entry|
|
||||
path = in_source_dir(dir, entry)
|
||||
next if File.symlink?(path) && safe
|
||||
|
||||
key = sanitize_filename(File.basename(entry, '.*'))
|
||||
if File.directory?(path)
|
||||
read_data_to(path, data[key] = {})
|
||||
else
|
||||
case File.extname(path).downcase
|
||||
when '.csv'
|
||||
data[key] = CSV.read(path, :headers => true).map(&:to_hash)
|
||||
else
|
||||
data[key] = SafeYAML.load_file(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Read in all collections specified in the configuration
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_collections
|
||||
collections.each do |_, collection|
|
||||
collection.read unless collection.label.eql?("data")
|
||||
end
|
||||
reader.read
|
||||
limit_posts!
|
||||
Jekyll::Hooks.trigger :site, :post_read, self
|
||||
end
|
||||
|
||||
# Run each of the Generators.
|
||||
@@ -290,20 +159,29 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def render
|
||||
relative_permalinks_deprecation_method
|
||||
relative_permalinks_are_deprecated
|
||||
|
||||
payload = site_payload
|
||||
|
||||
Jekyll::Hooks.trigger :site, :pre_render, self, payload
|
||||
|
||||
collections.each do |label, collection|
|
||||
collection.docs.each do |document|
|
||||
document.output = Jekyll::Renderer.new(self, document, payload).run if document.regenerate?
|
||||
if regenerator.regenerate?(document)
|
||||
document.output = Jekyll::Renderer.new(self, document, payload).run
|
||||
document.trigger_hooks(:post_render)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
payload = site_payload
|
||||
[posts, pages].flatten.each do |page_or_post|
|
||||
page_or_post.render(layouts, payload) if page_or_post.regenerate?
|
||||
pages.flatten.each do |page|
|
||||
if regenerator.regenerate?(page)
|
||||
page.render(layouts, payload)
|
||||
end
|
||||
end
|
||||
rescue Errno::ENOENT => e
|
||||
|
||||
Jekyll::Hooks.trigger :site, :post_render, self, payload
|
||||
rescue Errno::ENOENT
|
||||
# ignore missing layout dir
|
||||
end
|
||||
|
||||
@@ -319,9 +197,14 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def write
|
||||
each_site_file { |item|
|
||||
item.write(dest) if item.regenerate?
|
||||
item.write(dest) if regenerator.regenerate?(item)
|
||||
}
|
||||
metadata.write unless full_rebuild?
|
||||
regenerator.write_metadata
|
||||
Jekyll::Hooks.trigger :site, :post_write, self
|
||||
end
|
||||
|
||||
def posts
|
||||
collections['posts'] ||= Collection.new(self, 'posts')
|
||||
end
|
||||
|
||||
# Construct a Hash of Posts indexed by the specified Post attribute.
|
||||
@@ -341,7 +224,7 @@ module Jekyll
|
||||
# Build a hash map based on the specified post attribute ( post attr =>
|
||||
# array of posts ) then sort each array in reverse order.
|
||||
hash = Hash.new { |h, key| h[key] = [] }
|
||||
posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
|
||||
posts.docs.each { |p| p.data[post_attr].each { |t| hash[t] << p } if p.data[post_attr] }
|
||||
hash.values.each { |posts| posts.sort!.reverse! }
|
||||
hash
|
||||
end
|
||||
@@ -384,31 +267,19 @@ module Jekyll
|
||||
"site" => Utils.deep_merge_hashes(config,
|
||||
Utils.deep_merge_hashes(Hash[collections.map{|label, coll| [label, coll.docs]}], {
|
||||
"time" => time,
|
||||
"posts" => posts.sort { |a, b| b <=> a },
|
||||
"posts" => posts.docs.sort { |a, b| b <=> a },
|
||||
"pages" => pages,
|
||||
"static_files" => static_files,
|
||||
"html_pages" => pages.select { |page| page.html? || page.url.end_with?("/") },
|
||||
"categories" => post_attr_hash('categories'),
|
||||
"tags" => post_attr_hash('tags'),
|
||||
"collections" => collections,
|
||||
"collections" => collections.values.map(&:to_liquid),
|
||||
"documents" => documents,
|
||||
"data" => site_data
|
||||
}))
|
||||
}
|
||||
end
|
||||
|
||||
# Filter out any files/directories that are hidden or backup files (start
|
||||
# with "." or "#" or end with "~"), or contain site content (start with "_"),
|
||||
# or are excluded in the site configuration, unless they are web server
|
||||
# files such as '.htaccess'.
|
||||
#
|
||||
# entries - The Array of String file/directory entries to filter.
|
||||
#
|
||||
# Returns the Array of filtered entries.
|
||||
def filter_entries(entries, base_directory = nil)
|
||||
EntryFilter.new(self, base_directory).filter(entries)
|
||||
end
|
||||
|
||||
# Get the implementation class for the given Converter.
|
||||
#
|
||||
# klass - The Class of the Converter to fetch.
|
||||
@@ -433,42 +304,30 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
# Read the entries from a particular directory for processing
|
||||
# Warns the user if permanent links are relative to the parent
|
||||
# directory. As this is a deprecated function of Jekyll.
|
||||
#
|
||||
# dir - The String relative path of the directory to read
|
||||
# subfolder - The String directory to read
|
||||
#
|
||||
# Returns the list of entries to process
|
||||
def get_entries(dir, subfolder)
|
||||
base = in_source_dir(dir, subfolder)
|
||||
return [] unless File.exist?(base)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir['**/*'], base) }
|
||||
entries.delete_if { |e| File.directory?(in_source_dir(base, e)) }
|
||||
end
|
||||
|
||||
# Aggregate post information
|
||||
#
|
||||
# post - The Post object to aggregate information for
|
||||
#
|
||||
# Returns nothing
|
||||
def aggregate_post_info(post)
|
||||
posts << post
|
||||
end
|
||||
|
||||
def relative_permalinks_deprecation_method
|
||||
if config['relative_permalinks'] && has_relative_page?
|
||||
Jekyll.logger.warn "Deprecation:", "Since v2.0, permalinks for pages" +
|
||||
" in subfolders must be relative to the" +
|
||||
" site source directory, not the parent" +
|
||||
" directory. Check http://jekyllrb.com/docs/upgrading/"+
|
||||
" for more info."
|
||||
# Returns
|
||||
def relative_permalinks_are_deprecated
|
||||
if config['relative_permalinks']
|
||||
Jekyll.logger.abort_with "Since v3.0, permalinks for pages" +
|
||||
" in subfolders must be relative to the" +
|
||||
" site source directory, not the parent" +
|
||||
" directory. Check http://jekyllrb.com/docs/upgrading/"+
|
||||
" for more info."
|
||||
end
|
||||
end
|
||||
|
||||
# Get the to be written documents
|
||||
#
|
||||
# Returns an Array of Documents which should be written
|
||||
def docs_to_write
|
||||
documents.select(&:write?)
|
||||
end
|
||||
|
||||
# Get all the documents
|
||||
#
|
||||
# Returns an Array of all Documents
|
||||
def documents
|
||||
collections.reduce(Set.new) do |docs, (_, collection)|
|
||||
docs + collection.docs + collection.files
|
||||
@@ -476,47 +335,78 @@ module Jekyll
|
||||
end
|
||||
|
||||
def each_site_file
|
||||
%w(posts pages static_files docs_to_write).each do |type|
|
||||
%w(pages static_files docs_to_write).each do |type|
|
||||
send(type).each do |item|
|
||||
yield item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the FrontmatterDefaults or creates a new FrontmatterDefaults
|
||||
# if it doesn't already exist.
|
||||
#
|
||||
# Returns The FrontmatterDefaults
|
||||
def frontmatter_defaults
|
||||
@frontmatter_defaults ||= FrontmatterDefaults.new(self)
|
||||
end
|
||||
|
||||
# Whether to perform a full rebuild without metadata
|
||||
# Whether to perform a full rebuild without incremental regeneration
|
||||
#
|
||||
# Returns a Boolean: true for a full rebuild, false for normal build
|
||||
def full_rebuild?(override = {})
|
||||
override['full_rebuild'] || config['full_rebuild']
|
||||
def incremental?(override = {})
|
||||
override['incremental'] || config['incremental']
|
||||
end
|
||||
|
||||
# Returns the publisher or creates a new publisher if it doesn't
|
||||
# already exist.
|
||||
#
|
||||
# Returns The Publisher
|
||||
def publisher
|
||||
@publisher ||= Publisher.new(self)
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the source directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# source directory
|
||||
#
|
||||
# Returns a path which is prefixed with the source directory.
|
||||
def in_source_dir(*paths)
|
||||
paths.reduce(source) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the destination directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# destination directory
|
||||
#
|
||||
# Returns a path which is prefixed with the destination directory.
|
||||
def in_dest_dir(*paths)
|
||||
paths.reduce(dest) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def has_relative_page?
|
||||
pages.any? { |page| page.uses_relative_permalinks }
|
||||
end
|
||||
|
||||
# Limits the current posts; removes the posts which exceed the limit_posts
|
||||
#
|
||||
# Returns nothing
|
||||
def limit_posts!
|
||||
limit = posts.length < limit_posts ? posts.length : limit_posts
|
||||
self.posts = posts[-limit, limit]
|
||||
if limit_posts > 0
|
||||
limit = posts.docs.length < limit_posts ? posts.docs.length : limit_posts
|
||||
self.posts.docs = posts.docs[-limit, limit]
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the Cleaner or creates a new Cleaner if it doesn't
|
||||
# already exist.
|
||||
#
|
||||
# Returns The Cleaner
|
||||
def site_cleaner
|
||||
@site_cleaner ||= Cleaner.new(self)
|
||||
end
|
||||
|
||||
def sanitize_filename(name)
|
||||
name.gsub!(/[^\w\s_-]+/, '')
|
||||
name.gsub!(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
||||
name.gsub(/\s+/, '_')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ module Jekyll
|
||||
# The cache of last modification times [path] -> mtime.
|
||||
@@mtimes = Hash.new
|
||||
|
||||
attr_reader :relative_path
|
||||
attr_reader :relative_path, :extname
|
||||
|
||||
# Initialize a new StaticFile.
|
||||
#
|
||||
@@ -18,6 +18,7 @@ module Jekyll
|
||||
@name = name
|
||||
@collection = collection
|
||||
@relative_path = File.join(*[@dir, @name].compact)
|
||||
@extname = File.extname(@name)
|
||||
end
|
||||
|
||||
# Returns source file path.
|
||||
@@ -25,10 +26,6 @@ module Jekyll
|
||||
File.join(*[@base, @dir, @name].compact)
|
||||
end
|
||||
|
||||
def extname
|
||||
File.extname(path)
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
@@ -40,15 +37,19 @@ module Jekyll
|
||||
|
||||
def destination_rel_dir
|
||||
if @collection
|
||||
@dir.gsub(/\A_/, '')
|
||||
File.dirname(url)
|
||||
else
|
||||
@dir
|
||||
end
|
||||
end
|
||||
|
||||
def modified_time
|
||||
@modified_time ||= File.stat(path).mtime
|
||||
end
|
||||
|
||||
# Returns last modification time for this file.
|
||||
def mtime
|
||||
File.stat(path).mtime.to_i
|
||||
modified_time.to_i
|
||||
end
|
||||
|
||||
# Is source path modified?
|
||||
@@ -60,13 +61,12 @@ module Jekyll
|
||||
|
||||
# Whether to write the file to the filesystem
|
||||
#
|
||||
# Returns true.
|
||||
# Returns true unless the defaults for the destination path from
|
||||
# _config.yml contain `published: false`.
|
||||
def write?
|
||||
true
|
||||
defaults.fetch('published', true)
|
||||
end
|
||||
|
||||
alias_method :regenerate?, :write?
|
||||
|
||||
# Write the static file to the destination directory (if modified).
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
@@ -81,6 +81,7 @@ module Jekyll
|
||||
FileUtils.mkdir_p(File.dirname(dest_path))
|
||||
FileUtils.rm(dest_path) if File.exist?(dest_path)
|
||||
FileUtils.cp(path, dest_path)
|
||||
File.utime(@@mtimes[path], @@mtimes[path], dest_path)
|
||||
|
||||
true
|
||||
end
|
||||
@@ -95,10 +96,46 @@ module Jekyll
|
||||
|
||||
def to_liquid
|
||||
{
|
||||
"path" => File.join("", relative_path),
|
||||
"modified_time" => mtime.to_s,
|
||||
"extname" => File.extname(relative_path)
|
||||
"extname" => extname,
|
||||
"modified_time" => modified_time,
|
||||
"path" => File.join("", relative_path)
|
||||
}
|
||||
end
|
||||
|
||||
def placeholders
|
||||
{
|
||||
collection: @collection.label,
|
||||
path: relative_path[
|
||||
@collection.relative_directory.size..relative_path.size],
|
||||
output_ext: '',
|
||||
name: '',
|
||||
title: '',
|
||||
}
|
||||
end
|
||||
|
||||
# Applies a similar URL-building technique as Jekyll::Document that takes
|
||||
# the collection's URL template into account. The default URL template can
|
||||
# be overriden in the collection's configuration in _config.yml.
|
||||
def url
|
||||
@url ||= if @collection.nil?
|
||||
relative_path
|
||||
else
|
||||
::Jekyll::URL.new({
|
||||
template: @collection.url_template,
|
||||
placeholders: placeholders,
|
||||
})
|
||||
end.to_s.gsub /\/$/, ''
|
||||
end
|
||||
|
||||
# Returns the type of the collection if present, nil otherwise.
|
||||
def type
|
||||
@type ||= @collection.nil? ? nil : @collection.label.to_sym
|
||||
end
|
||||
|
||||
# Returns the front matter defaults defined for the file's URL and/or type
|
||||
# as defined in _config.yml.
|
||||
def defaults
|
||||
@defaults ||= @site.frontmatter_defaults.all url, type
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,19 +42,19 @@ eos
|
||||
def render(context)
|
||||
prefix = context["highlighter_prefix"] || ""
|
||||
suffix = context["highlighter_suffix"] || ""
|
||||
code = super.to_s.strip
|
||||
code = super.to_s.gsub(/\A(\n|\r)+|(\n|\r)+\z/, '')
|
||||
|
||||
is_safe = !!context.registers[:site].safe
|
||||
|
||||
output =
|
||||
case context.registers[:site].highlighter
|
||||
when 'pygments'
|
||||
render_pygments(code, is_safe)
|
||||
when 'rouge'
|
||||
render_rouge(code)
|
||||
else
|
||||
render_codehighlighter(code)
|
||||
end
|
||||
when 'pygments'
|
||||
render_pygments(code, is_safe)
|
||||
when 'rouge'
|
||||
render_rouge(code)
|
||||
else
|
||||
render_codehighlighter(code)
|
||||
end
|
||||
|
||||
rendered_output = add_code_tag(output)
|
||||
prefix + rendered_output + suffix
|
||||
@@ -64,7 +64,7 @@ eos
|
||||
if is_safe
|
||||
Hash[[
|
||||
[:startinline, opts.fetch(:startinline, nil)],
|
||||
[:hl_linenos, opts.fetch(:hl_linenos, nil)],
|
||||
[:hl_lines, opts.fetch(:hl_lines, nil)],
|
||||
[:linenos, opts.fetch(:linenos, nil)],
|
||||
[:encoding, opts.fetch(:encoding, 'utf-8')],
|
||||
[:cssclass, opts.fetch(:cssclass, nil)]
|
||||
@@ -75,9 +75,7 @@ eos
|
||||
end
|
||||
|
||||
def render_pygments(code, is_safe)
|
||||
require 'pygments'
|
||||
|
||||
@options[:encoding] = 'utf-8'
|
||||
Jekyll::External.require_with_graceful_fail('pygments')
|
||||
|
||||
highlighted_code = Pygments.highlight(
|
||||
code,
|
||||
@@ -96,26 +94,26 @@ eos
|
||||
raise ArgumentError.new("Pygments.rb returned an unacceptable value when attempting to highlight some code.")
|
||||
end
|
||||
|
||||
highlighted_code
|
||||
highlighted_code.sub('<div class="highlight"><pre>', '').sub('</pre></div>', '')
|
||||
end
|
||||
|
||||
def render_rouge(code)
|
||||
require 'rouge'
|
||||
Jekyll::External.require_with_graceful_fail('rouge')
|
||||
formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false)
|
||||
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
||||
code = formatter.format(lexer.lex(code))
|
||||
"<div class=\"highlight\"><pre>#{code}</pre></div>"
|
||||
formatter.format(lexer.lex(code))
|
||||
end
|
||||
|
||||
def render_codehighlighter(code)
|
||||
"<div class=\"highlight\"><pre>#{h(code).strip}</pre></div>"
|
||||
h(code).strip
|
||||
end
|
||||
|
||||
def add_code_tag(code)
|
||||
# Add nested <code> tags to code blocks
|
||||
code = code.sub(/<pre>\n*/,'<pre><code class="language-' + @lang.to_s.gsub("+", "-") + '" data-lang="' + @lang.to_s + '">')
|
||||
code = code.sub(/\n*<\/pre>/,"</code></pre>")
|
||||
code.strip
|
||||
code_attributes = [
|
||||
"class=\"language-#{@lang.to_s.gsub('+', '-')}\"",
|
||||
"data-lang=\"#{@lang.to_s}\""
|
||||
].join(" ")
|
||||
"<figure class=\"highlight\"><pre><code #{code_attributes}>#{code.chomp}</code></pre></figure>"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -20,7 +20,6 @@ module Jekyll
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
@includes_dir = tag_includes_dir
|
||||
matched = markup.strip.match(VARIABLE_SYNTAX)
|
||||
if matched
|
||||
@file = matched['variable'].strip
|
||||
@@ -95,17 +94,18 @@ eos
|
||||
# Render the variable if required
|
||||
def render_variable(context)
|
||||
if @file.match(VARIABLE_SYNTAX)
|
||||
partial = Liquid::Template.parse(@file)
|
||||
partial = context.registers[:site].liquid_renderer.file("(variable)").parse(@file)
|
||||
partial.render!(context)
|
||||
end
|
||||
end
|
||||
|
||||
def tag_includes_dir
|
||||
'_includes'
|
||||
def tag_includes_dir(context)
|
||||
context.registers[:site].config['includes_dir'].freeze
|
||||
end
|
||||
|
||||
def render(context)
|
||||
site = context.registers[:site]
|
||||
@includes_dir = tag_includes_dir(context)
|
||||
dir = resolved_includes_dir(context)
|
||||
|
||||
file = render_variable(context) || @file
|
||||
@@ -116,14 +116,14 @@ eos
|
||||
|
||||
# Add include to dependency tree
|
||||
if context.registers[:page] and context.registers[:page].has_key? "path"
|
||||
site.metadata.add_dependency(
|
||||
site.regenerator.add_dependency(
|
||||
site.in_source_dir(context.registers[:page]["path"]),
|
||||
path
|
||||
)
|
||||
end
|
||||
|
||||
begin
|
||||
partial = Liquid::Template.parse(source(path, context))
|
||||
partial = site.liquid_renderer.file(path).parse(read_file(path, context))
|
||||
|
||||
context.stack do
|
||||
context['include'] = parse_params(context) if @params
|
||||
@@ -135,7 +135,7 @@ eos
|
||||
end
|
||||
|
||||
def resolved_includes_dir(context)
|
||||
File.join(File.realpath(context.registers[:site].source), @includes_dir)
|
||||
context.registers[:site].in_source_dir(@includes_dir)
|
||||
end
|
||||
|
||||
def validate_path(path, dir, safe)
|
||||
@@ -155,14 +155,14 @@ eos
|
||||
end
|
||||
|
||||
# This method allows to modify the file content by inheriting from the class.
|
||||
def source(file, context)
|
||||
def read_file(file, context)
|
||||
File.read(file, file_read_opts(context))
|
||||
end
|
||||
end
|
||||
|
||||
class IncludeRelativeTag < IncludeTag
|
||||
def tag_includes_dir
|
||||
'.'
|
||||
def tag_includes_dir(context)
|
||||
'.'.freeze
|
||||
end
|
||||
|
||||
def page_path(context)
|
||||
|
||||
@@ -14,7 +14,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
other.name.match(@name_regex)
|
||||
other.basename.match(@name_regex)
|
||||
end
|
||||
|
||||
def deprecated_equality(other)
|
||||
@@ -32,11 +32,11 @@ module Jekyll
|
||||
#
|
||||
# Returns the post slug with the subdirectory (relative to _posts)
|
||||
def post_slug(other)
|
||||
path = other.name.split("/")[0...-1].join("/")
|
||||
path = other.basename.split("/")[0...-1].join("/")
|
||||
if path.nil? || path == ""
|
||||
other.slug
|
||||
other.data['slug']
|
||||
else
|
||||
path + '/' + other.slug
|
||||
path + '/' + other.data['slug']
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -59,7 +59,7 @@ eos
|
||||
def render(context)
|
||||
site = context.registers[:site]
|
||||
|
||||
site.posts.each do |p|
|
||||
site.posts.docs.each do |p|
|
||||
if @post == p
|
||||
return p.url
|
||||
end
|
||||
@@ -68,9 +68,9 @@ eos
|
||||
# New matching method did not match, fall back to old method
|
||||
# with deprecation warning if this matches
|
||||
|
||||
site.posts.each do |p|
|
||||
site.posts.docs.each do |p|
|
||||
if @post.deprecated_equality p
|
||||
Jekyll::Deprecator.deprecation_message "A call to '{{ post_url #{name} }}' did not match " +
|
||||
Jekyll::Deprecator.deprecation_message "A call to '{{ post_url #{@post.name} }}' did not match " +
|
||||
"a post using the new matching method of checking name " +
|
||||
"(path-date-slug) equality. Please make sure that you " +
|
||||
"change this tag to match the post's name exactly."
|
||||
|
||||
@@ -44,12 +44,12 @@ module Jekyll
|
||||
#
|
||||
# Returns the _unsanitized String URL
|
||||
def generated_permalink
|
||||
(@generated_permlink ||= generate_url(@permalink)) if @permalink
|
||||
(@generated_permalink ||= generate_url(@permalink)) if @permalink
|
||||
end
|
||||
|
||||
# Generates a URL from the template
|
||||
#
|
||||
# Returns the _unsanitized String URL
|
||||
# Returns the unsanitized String URL
|
||||
def generated_url
|
||||
@generated_url ||= generate_url(@template)
|
||||
end
|
||||
@@ -57,11 +57,16 @@ module Jekyll
|
||||
# Internal: Generate the URL by replacing all placeholders with their
|
||||
# respective values in the given template
|
||||
#
|
||||
# Returns the _unsanitizied_ String URL
|
||||
# Returns the unsanitized String URL
|
||||
def generate_url(template)
|
||||
@placeholders.inject(template) do |result, token|
|
||||
break result if result.index(':').nil?
|
||||
result.gsub(/:#{token.first}/, self.class.escape_path(token.last))
|
||||
if token.last.nil?
|
||||
# Remove leading '/' to avoid generating urls with `//`
|
||||
result.gsub(/\/:#{token.first}/, '')
|
||||
else
|
||||
result.gsub(/:#{token.first}/, self.class.escape_path(token.last))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -76,7 +81,7 @@ module Jekyll
|
||||
.gsub(/\A([^\/])/, '/\1')
|
||||
|
||||
# Append a trailing slash to the URL if the unsanitized URL had one
|
||||
url << "/" if in_url[-1].eql?('/')
|
||||
url << "/" if in_url.end_with?("/")
|
||||
|
||||
url
|
||||
end
|
||||
@@ -102,7 +107,7 @@ module Jekyll
|
||||
# pct-encoded = "%" HEXDIG HEXDIG
|
||||
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
# / "*" / "+" / "," / ";" / "="
|
||||
URI.escape(path, /[^a-zA-Z\d\-._~!$&\'()*+,;=:@\/]/).encode('utf-8')
|
||||
URI.escape(path, /[^a-zA-Z\d\-._~!$&'()*+,;=:@\/]/).encode('utf-8')
|
||||
end
|
||||
|
||||
# Unescapes a URL path segment
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
module Jekyll
|
||||
module Utils
|
||||
extend self
|
||||
module Utils extend self
|
||||
autoload :Platforms, 'jekyll/utils/platforms'
|
||||
|
||||
# Constants for use in #slugify
|
||||
SLUGIFY_MODES = %w{raw default pretty}
|
||||
SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
|
||||
SLUGIFY_DEFAULT_REGEXP = Regexp.new('[^[:alnum:]]+').freeze
|
||||
SLUGIFY_PRETTY_REGEXP = Regexp.new("[^[:alnum:]._~!$&'()+,;=@]+").freeze
|
||||
|
||||
# Non-destructive version of deep_merge_hashes! See that method.
|
||||
#
|
||||
# Returns the merged hashes.
|
||||
def deep_merge_hashes(master_hash, other_hash)
|
||||
deep_merge_hashes!(master_hash.dup, other_hash)
|
||||
end
|
||||
|
||||
# Merges a master hash with another hash, recursively.
|
||||
#
|
||||
@@ -11,16 +24,18 @@ module Jekyll
|
||||
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
|
||||
#
|
||||
# Thanks to whoever made it.
|
||||
def deep_merge_hashes(master_hash, other_hash)
|
||||
target = master_hash.dup
|
||||
|
||||
other_hash.each_key do |key|
|
||||
if other_hash[key].is_a? Hash and target[key].is_a? Hash
|
||||
target[key] = Utils.deep_merge_hashes(target[key], other_hash[key])
|
||||
def deep_merge_hashes!(target, overwrite)
|
||||
overwrite.each_key do |key|
|
||||
if overwrite[key].is_a? Hash and target[key].is_a? Hash
|
||||
target[key] = Utils.deep_merge_hashes(target[key], overwrite[key])
|
||||
next
|
||||
end
|
||||
|
||||
target[key] = other_hash[key]
|
||||
target[key] = overwrite[key]
|
||||
end
|
||||
|
||||
if target.default_proc.nil?
|
||||
target.default_proc = overwrite.default_proc
|
||||
end
|
||||
|
||||
target
|
||||
@@ -104,21 +119,103 @@ module Jekyll
|
||||
|
||||
# Slugify a filename or title.
|
||||
#
|
||||
# name - the filename or title to slugify
|
||||
# string - the filename or title to slugify
|
||||
# mode - how string is slugified
|
||||
# cased - whether to replace all uppercase letters with their
|
||||
# lowercase counterparts
|
||||
#
|
||||
# Returns the given filename or title in lowercase, with every
|
||||
# sequence of spaces and non-alphanumeric characters replaced with a
|
||||
# hyphen.
|
||||
def slugify(string)
|
||||
unless string.nil?
|
||||
string \
|
||||
# Replace each non-alphanumeric character sequence with a hyphen
|
||||
.gsub(/[^[:alnum:]]+/i, '-') \
|
||||
# Remove leading/trailing hyphen
|
||||
.gsub(/^\-|\-$/i, '') \
|
||||
# Downcase it
|
||||
.downcase
|
||||
# When mode is "none", return the given string.
|
||||
#
|
||||
# When mode is "raw", return the given string,
|
||||
# with every sequence of spaces characters replaced with a hyphen.
|
||||
#
|
||||
# When mode is "default" or nil, non-alphabetic characters are
|
||||
# replaced with a hyphen too.
|
||||
#
|
||||
# When mode is "pretty", some non-alphabetic characters (._~!$&'()+,;=@)
|
||||
# are not replaced with hyphen.
|
||||
#
|
||||
# If cased is true, all uppercase letters in the result string are
|
||||
# replaced with their lowercase counterparts.
|
||||
#
|
||||
# Examples:
|
||||
# slugify("The _config.yml file")
|
||||
# # => "the-config-yml-file"
|
||||
#
|
||||
# slugify("The _config.yml file", "pretty")
|
||||
# # => "the-_config.yml-file"
|
||||
#
|
||||
# slugify("The _config.yml file", "pretty", true)
|
||||
# # => "The-_config.yml file"
|
||||
#
|
||||
# Returns the slugified string.
|
||||
def slugify(string, mode: nil, cased: false)
|
||||
mode ||= 'default'
|
||||
return nil if string.nil?
|
||||
|
||||
unless SLUGIFY_MODES.include?(mode)
|
||||
return cased ? string : string.downcase
|
||||
end
|
||||
|
||||
# Replace each character sequence with a hyphen
|
||||
re = case mode
|
||||
when 'raw'
|
||||
SLUGIFY_RAW_REGEXP
|
||||
when 'default'
|
||||
SLUGIFY_DEFAULT_REGEXP
|
||||
when 'pretty'
|
||||
# "._~!$&'()+,;=@" is human readable (not URI-escaped) in URL
|
||||
# and is allowed in both extN and NTFS.
|
||||
SLUGIFY_PRETTY_REGEXP
|
||||
end
|
||||
|
||||
slug = string.
|
||||
# Strip according to the mode
|
||||
gsub(re, '-').
|
||||
# Remove leading/trailing hyphen
|
||||
gsub(/^\-|\-$/i, '')
|
||||
|
||||
cased ? slug : slug.downcase
|
||||
end
|
||||
|
||||
# Add an appropriate suffix to template so that it matches the specified
|
||||
# permalink style.
|
||||
#
|
||||
# template - permalink template without trailing slash or file extension
|
||||
# permalink_style - permalink style, either built-in or custom
|
||||
#
|
||||
# The returned permalink template will use the same ending style as
|
||||
# specified in permalink_style. For example, if permalink_style contains a
|
||||
# trailing slash (or is :pretty, which indirectly has a trailing slash),
|
||||
# then so will the returned template. If permalink_style has a trailing
|
||||
# ":output_ext" (or is :none, :date, or :ordinal) then so will the returned
|
||||
# template. Otherwise, template will be returned without modification.
|
||||
#
|
||||
# Examples:
|
||||
# add_permalink_suffix("/:basename", :pretty)
|
||||
# # => "/:basename/"
|
||||
#
|
||||
# add_permalink_suffix("/:basename", :date)
|
||||
# # => "/:basename:output_ext"
|
||||
#
|
||||
# add_permalink_suffix("/:basename", "/:year/:month/:title/")
|
||||
# # => "/:basename/"
|
||||
#
|
||||
# add_permalink_suffix("/:basename", "/:year/:month/:title")
|
||||
# # => "/:basename"
|
||||
#
|
||||
# Returns the updated permalink template
|
||||
def add_permalink_suffix(template, permalink_style)
|
||||
case permalink_style
|
||||
when :pretty
|
||||
template << "/"
|
||||
when :date, :ordinal, :none
|
||||
template << ":output_ext"
|
||||
else
|
||||
template << "/" if permalink_style.to_s.end_with?("/")
|
||||
template << ":output_ext" if permalink_style.to_s.end_with?(":output_ext")
|
||||
end
|
||||
template
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
30
lib/jekyll/utils/platforms.rb
Normal file
30
lib/jekyll/utils/platforms.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Platforms extend self
|
||||
|
||||
# Provides jruby? and mri? which respectively detect these two types of
|
||||
# tested Engines we support, in the future we might probably support the
|
||||
# other one that everyone used to talk about.
|
||||
|
||||
{ :jruby? => "jruby", :mri? => "ruby" }.each do |k, v|
|
||||
define_method k do
|
||||
::RUBY_ENGINE == v
|
||||
end
|
||||
end
|
||||
|
||||
# Provides windows?, linux?, osx?, unix? so that we can detect
|
||||
# platforms. This is mostly useful for `jekyll doctor` and for testing
|
||||
# where we kick off certain tests based on the platform.
|
||||
|
||||
{ :windows? => /mswin|mingw|cygwin/, :linux? => /linux/, \
|
||||
:osx? => /darwin|mac os/, :unix? => /solaris|bsd/ }.each do |k, v|
|
||||
|
||||
define_method k do
|
||||
!!(
|
||||
RbConfig::CONFIG["host_os"] =~ v
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,3 @@
|
||||
module Jekyll
|
||||
VERSION = '2.5.3'
|
||||
VERSION = '3.0.2'
|
||||
end
|
||||
|
||||
1
lib/site_template/.gitignore
vendored
1
lib/site_template/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
_site
|
||||
.sass-cache
|
||||
.jekyll-metadata
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# Welcome to Jekyll!
|
||||
#
|
||||
# This config file is meant for settings that affect your whole blog, values
|
||||
# which you are expected to set up once and rarely need to edit after that.
|
||||
# For technical reasons, this file is *NOT* reloaded automatically when you use
|
||||
# 'jekyll serve'. If you change this file, please restart the server process.
|
||||
|
||||
# Site settings
|
||||
title: Your awesome title
|
||||
email: your-email@domain.com
|
||||
@@ -5,7 +12,7 @@ description: > # this means to ignore newlines until "baseurl:"
|
||||
Write an awesome description for your new site here. You can edit this
|
||||
line in _config.yml. It will appear in your document head meta (for
|
||||
Google search results) and in your feed.xml site description.
|
||||
baseurl: "" # the subpath of your site, e.g. /blog/
|
||||
baseurl: "" # the subpath of your site, e.g. /blog
|
||||
url: "http://yourdomain.com" # the base hostname & protocol for your site
|
||||
twitter_username: jekyllrb
|
||||
github_username: jekyll
|
||||
|
||||
@@ -5,48 +5,31 @@
|
||||
<h2 class="footer-heading">{{ site.title }}</h2>
|
||||
|
||||
<div class="footer-col-wrapper">
|
||||
<div class="footer-col footer-col-1">
|
||||
<div class="footer-col footer-col-1">
|
||||
<ul class="contact-list">
|
||||
<li>{{ site.title }}</li>
|
||||
<li><a href="mailto:{{ site.email }}">{{ site.email }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-2">
|
||||
<div class="footer-col footer-col-2">
|
||||
<ul class="social-media-list">
|
||||
{% if site.github_username %}
|
||||
<li>
|
||||
<a href="https://github.com/{{ site.github_username }}">
|
||||
<span class="icon icon--github">
|
||||
<svg viewBox="0 0 16 16">
|
||||
<path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
<span class="username">{{ site.github_username }}</span>
|
||||
</a>
|
||||
{% include icon-github.html username=site.github_username %}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if site.twitter_username %}
|
||||
<li>
|
||||
<a href="https://twitter.com/{{ site.twitter_username }}">
|
||||
<span class="icon icon--twitter">
|
||||
<svg viewBox="0 0 16 16">
|
||||
<path fill="#828282" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809
|
||||
c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
<span class="username">{{ site.twitter_username }}</span>
|
||||
</a>
|
||||
{% include icon-twitter.html username=site.twitter_username %}
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-3">
|
||||
<p class="text">{{ site.description }}</p>
|
||||
<div class="footer-col footer-col-3">
|
||||
<p>{{ site.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
</a>
|
||||
|
||||
<div class="trigger">
|
||||
{% for page in site.pages %}
|
||||
{% if page.title %}
|
||||
<a class="page-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>
|
||||
{% for my_page in site.pages %}
|
||||
{% if my_page.title %}
|
||||
<a class="page-link" href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
1
lib/site_template/_includes/icon-github.html
Normal file
1
lib/site_template/_includes/icon-github.html
Normal file
@@ -0,0 +1 @@
|
||||
<a href="https://github.com/{{ include.username }}"><span class="icon icon--github">{% include icon-github.svg %}</span><span class="username">{{ include.username }}</span></a>
|
||||
1
lib/site_template/_includes/icon-github.svg
Normal file
1
lib/site_template/_includes/icon-github.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 16 16"><path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/></svg>
|
||||
|
After Width: | Height: | Size: 926 B |
1
lib/site_template/_includes/icon-twitter.html
Normal file
1
lib/site_template/_includes/icon-twitter.html
Normal file
@@ -0,0 +1 @@
|
||||
<a href="https://twitter.com/{{ include.username }}"><span class="icon icon--twitter">{% include icon-twitter.svg %}</span><span class="username">{{ include.username }}</span></a>
|
||||
1
lib/site_template/_includes/icon-twitter.svg
Normal file
1
lib/site_template/_includes/icon-twitter.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 16 16"><path fill="#828282" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/></svg>
|
||||
|
After Width: | Height: | Size: 787 B |
@@ -1,11 +1,11 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title" itemprop="name headline">{{ page.title }}</h1>
|
||||
<p class="post-meta"><time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">{{ page.date | date: "%b %-d, %Y" }}</time>{% if page.author %} • <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">{{ page.author }}</span></span>{% endif %}{% if page.meta %} • {{ page.meta }}{% endif %}</p>
|
||||
<p class="post-meta"><time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">{{ page.date | date: "%b %-d, %Y" }}</time>{% if page.author %} • <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">{{ page.author }}</span></span>{% endif %}</p>
|
||||
</header>
|
||||
|
||||
<div class="post-content" itemprop="articleBody">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: post
|
||||
title: "Welcome to Jekyll!"
|
||||
date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S') %>
|
||||
date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>
|
||||
categories: jekyll update
|
||||
---
|
||||
You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
|
||||
@@ -18,8 +18,8 @@ print_hi('Tom')
|
||||
#=> prints 'Hi, Tom' to STDOUT.
|
||||
{% endhighlight %}
|
||||
|
||||
Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll’s dedicated Help repository][jekyll-help].
|
||||
Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
|
||||
|
||||
[jekyll]: http://jekyllrb.com
|
||||
[jekyll-docs]: http://jekyllrb.com/docs/home
|
||||
[jekyll-gh]: https://github.com/jekyll/jekyll
|
||||
[jekyll-help]: https://github.com/jekyll/jekyll-help
|
||||
[jekyll-talk]: https://talk.jekyllrb.com/
|
||||
|
||||
@@ -14,13 +14,15 @@ dl, dd, ol, ul, figure {
|
||||
* Basic styling
|
||||
*/
|
||||
body {
|
||||
font-family: $base-font-family;
|
||||
font-size: $base-font-size;
|
||||
line-height: $base-line-height;
|
||||
font-weight: 300;
|
||||
font: $base-font-weight #{$base-font-size}/#{$base-line-height} $base-font-family;
|
||||
color: $text-color;
|
||||
background-color: $background-color;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-font-feature-settings: "kern" 1;
|
||||
-moz-font-feature-settings: "kern" 1;
|
||||
-o-font-feature-settings: "kern" 1;
|
||||
font-feature-settings: "kern" 1;
|
||||
font-kerning: normal;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +82,7 @@ li {
|
||||
* Headings
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 300;
|
||||
font-weight: $base-font-weight;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +141,7 @@ code {
|
||||
|
||||
pre {
|
||||
padding: 8px 12px;
|
||||
overflow-x: scroll;
|
||||
overflow-x: auto;
|
||||
|
||||
> code {
|
||||
border: 0;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
.site-title {
|
||||
font-size: 26px;
|
||||
font-weight: 300;
|
||||
line-height: 56px;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 0;
|
||||
@@ -44,7 +45,7 @@
|
||||
@include media-query($on-palm) {
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
right: 30px;
|
||||
right: $spacing-unit / 2;
|
||||
background-color: $background-color;
|
||||
border: 1px solid $grey-color-light;
|
||||
border-radius: 5px;
|
||||
@@ -82,6 +83,11 @@
|
||||
.page-link {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 0;
|
||||
}
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
background: #fff;
|
||||
@extend %vertical-rhythm;
|
||||
|
||||
.highlighter-rouge & {
|
||||
background: #eef;
|
||||
}
|
||||
|
||||
.c { color: #998; font-style: italic } // Comment
|
||||
.err { color: #a61717; background-color: #e3d2d2 } // Error
|
||||
.k { font-weight: bold } // Keyword
|
||||
|
||||
@@ -6,6 +6,10 @@ permalink: /about/
|
||||
|
||||
This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](http://jekyllrb.com/)
|
||||
|
||||
You can find the source code for the Jekyll new theme at: [github.com/jglovier/jekyll-new](https://github.com/jglovier/jekyll-new)
|
||||
You can find the source code for the Jekyll new theme at:
|
||||
{% include icon-github.html username="jglovier" %} /
|
||||
[jekyll-new](https://github.com/jglovier/jekyll-new)
|
||||
|
||||
You can find the source code for Jekyll at [github.com/jekyll/jekyll](https://github.com/jekyll/jekyll)
|
||||
You can find the source code for Jekyll at
|
||||
{% include icon-github.html username="jekyll" %} /
|
||||
[jekyll](https://github.com/jekyll/jekyll)
|
||||
|
||||
5
lib/site_template/css/main.scss
Executable file → Normal file
5
lib/site_template/css/main.scss
Executable file → Normal file
@@ -6,8 +6,9 @@
|
||||
|
||||
|
||||
// Our variables
|
||||
$base-font-family: Helvetica, Arial, sans-serif;
|
||||
$base-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
$base-font-size: 16px;
|
||||
$base-font-weight: 400;
|
||||
$small-font-size: $base-font-size * 0.875;
|
||||
$base-line-height: 1.5;
|
||||
|
||||
@@ -29,7 +30,7 @@ $on-laptop: 800px;
|
||||
|
||||
|
||||
|
||||
// Using media queries with like this:
|
||||
// Use media queries like this:
|
||||
// @include media-query($on-palm) {
|
||||
// .wrapper {
|
||||
// padding-right: $spacing-unit / 2;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user