mirror of
https://github.com/jekyll/jekyll.git
synced 2026-04-28 03:01:03 -04:00
Compare commits
1716 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f6b1dd458 | ||
|
|
bc954683cb | ||
|
|
1f877fde1e | ||
|
|
d70f9d4a29 | ||
|
|
17a4d15d3b | ||
|
|
135c5f313b | ||
|
|
72cfee7ea6 | ||
|
|
7c266e0fb9 | ||
|
|
a97659a4a1 | ||
|
|
4e7dd8a563 | ||
|
|
038baa12c7 | ||
|
|
e5306284ff | ||
|
|
c4abe6ec8f | ||
|
|
4d8e335da1 | ||
|
|
f84cd4e4ed | ||
|
|
adb6d4d2d7 | ||
|
|
9738ea452f | ||
|
|
839501e012 | ||
|
|
59b32626a8 | ||
|
|
fac5a2eb02 | ||
|
|
566d3718b0 | ||
|
|
2b81e5ed19 | ||
|
|
315cc386e5 | ||
|
|
10cc45fc45 | ||
|
|
141ce32382 | ||
|
|
56b9238af5 | ||
|
|
5031dfa3b9 | ||
|
|
c0df4b1047 | ||
|
|
530e049d2d | ||
|
|
f16a5cbae1 | ||
|
|
bcc539999b | ||
|
|
7b1763a124 | ||
|
|
b0e144065c | ||
|
|
eabde41267 | ||
|
|
14b73667b8 | ||
|
|
707278f099 | ||
|
|
a330bb0801 | ||
|
|
5c9eb324e8 | ||
|
|
ba63a2c6d1 | ||
|
|
8ff9074ce5 | ||
|
|
db34c48927 | ||
|
|
5367bc3416 | ||
|
|
871e425fa0 | ||
|
|
90ec93373b | ||
|
|
2fd155615f | ||
|
|
e36d433100 | ||
|
|
9c090c862f | ||
|
|
60c29561f2 | ||
|
|
d57c4f1c01 | ||
|
|
f190a960a1 | ||
|
|
1dcf241677 | ||
|
|
1de1ab9303 | ||
|
|
7b9d392d6f | ||
|
|
1666bbc52e | ||
|
|
ebb4a4c1b6 | ||
|
|
fd2d7df9b7 | ||
|
|
8c0cd10b07 | ||
|
|
6f8b8816f5 | ||
|
|
6470804a51 | ||
|
|
47b38cf9ee | ||
|
|
e4b829da3b | ||
|
|
3ad202429c | ||
|
|
fb02ce1e33 | ||
|
|
11373acb15 | ||
|
|
9b3ccee3dd | ||
|
|
f0e91b3667 | ||
|
|
966b22488c | ||
|
|
67da09e5e0 | ||
|
|
e5463b41f2 | ||
|
|
68fb130fd0 | ||
|
|
45a347c022 | ||
|
|
b2eae2e676 | ||
|
|
29254150b1 | ||
|
|
d74b179ecd | ||
|
|
69cc414c1b | ||
|
|
533ed6eb38 | ||
|
|
3264766762 | ||
|
|
c7c1eddd47 | ||
|
|
d0d8759c10 | ||
|
|
1261c1cd66 | ||
|
|
5a0c066845 | ||
|
|
d4fbf5c056 | ||
|
|
a2dfd6eddc | ||
|
|
d452fa65ba | ||
|
|
939c67222a | ||
|
|
23515acc31 | ||
|
|
a0f449d613 | ||
|
|
565bbada08 | ||
|
|
a0b30a9cc7 | ||
|
|
311f3be63b | ||
|
|
f29884593b | ||
|
|
d0ac4915cb | ||
|
|
d004bc4ea5 | ||
|
|
b00c5e9587 | ||
|
|
229cedfc50 | ||
|
|
5796690827 | ||
|
|
cb671acd0c | ||
|
|
85bd3836d0 | ||
|
|
a959c06e44 | ||
|
|
99a48499c7 | ||
|
|
21b6a01980 | ||
|
|
df91299550 | ||
|
|
5eacc9e831 | ||
|
|
9e679e7d4a | ||
|
|
f0105158bf | ||
|
|
8999df2f46 | ||
|
|
441a2496b8 | ||
|
|
e5a7f842be | ||
|
|
7f92e7ce00 | ||
|
|
b3069c0802 | ||
|
|
f39c2610ee | ||
|
|
4c4f803df2 | ||
|
|
a27313b1d0 | ||
|
|
9fd872e7b8 | ||
|
|
6ca8baa572 | ||
|
|
018390cf64 | ||
|
|
13425266eb | ||
|
|
738dd502b4 | ||
|
|
0594adb8fd | ||
|
|
83f726f503 | ||
|
|
36006fa68a | ||
|
|
a49244f4dd | ||
|
|
020f684093 | ||
|
|
101d614351 | ||
|
|
af1cc06184 | ||
|
|
d1b9dfc6c9 | ||
|
|
d8c330b215 | ||
|
|
e4029426de | ||
|
|
7d865269fd | ||
|
|
b24b870ec6 | ||
|
|
74974979ba | ||
|
|
4336e8e4b9 | ||
|
|
c7f8c70935 | ||
|
|
4cfbdb07bb | ||
|
|
3e98860241 | ||
|
|
81807cb5af | ||
|
|
d5322a73bf | ||
|
|
bd59fa14f3 | ||
|
|
5fdf637c6a | ||
|
|
9a6dc7b520 | ||
|
|
e75dc74bb1 | ||
|
|
ea7e8951d8 | ||
|
|
b906bff832 | ||
|
|
e44cfe29a8 | ||
|
|
989d5d357b | ||
|
|
f8c19df79a | ||
|
|
02b60d6d00 | ||
|
|
cfe9983741 | ||
|
|
4ca3fe5137 | ||
|
|
8db8b19ea0 | ||
|
|
503e54779a | ||
|
|
fd0c1f2273 | ||
|
|
36996107e1 | ||
|
|
cf2fe606a6 | ||
|
|
27f2d75d88 | ||
|
|
a902fefed5 | ||
|
|
274c6d3667 | ||
|
|
99f99169a4 | ||
|
|
1c8ae63ec3 | ||
|
|
da98869327 | ||
|
|
cf44052b0f | ||
|
|
febf2ea3cf | ||
|
|
df9c2f8371 | ||
|
|
b63d113fe0 | ||
|
|
7f5e04980c | ||
|
|
bc3b82850d | ||
|
|
89e45afcc1 | ||
|
|
7e2298b8d0 | ||
|
|
96b1778434 | ||
|
|
5fc3361720 | ||
|
|
d8bb7f7ad7 | ||
|
|
ff14d7b853 | ||
|
|
650d78c2cf | ||
|
|
0ed02e9c1e | ||
|
|
33cd956e4e | ||
|
|
413e22ce2b | ||
|
|
579a18c93b | ||
|
|
f6682de390 | ||
|
|
470d3a2a23 | ||
|
|
1d669ed34b | ||
|
|
8dd54b9ec3 | ||
|
|
cf94820e1a | ||
|
|
3f6b8468f2 | ||
|
|
d050fd11b5 | ||
|
|
9ccbfa0bae | ||
|
|
f57f1c7eef | ||
|
|
d8a7d770b4 | ||
|
|
6d62dbbafc | ||
|
|
9437a7abcd | ||
|
|
2642bd7415 | ||
|
|
30da34358b | ||
|
|
ab4b05127e | ||
|
|
2953a7c663 | ||
|
|
b53b4a5e5a | ||
|
|
e57cd0031d | ||
|
|
03bca72af6 | ||
|
|
2d3d65a930 | ||
|
|
5767346e9d | ||
|
|
dc894e41af | ||
|
|
5f828c6c2e | ||
|
|
2045984cee | ||
|
|
4df274f96d | ||
|
|
ee5828b2f7 | ||
|
|
3cb2e74b5c | ||
|
|
a4c9925e99 | ||
|
|
502f7991ad | ||
|
|
592afc270e | ||
|
|
2785d702e2 | ||
|
|
0fbdc69440 | ||
|
|
c99af68967 | ||
|
|
56a82b1e8a | ||
|
|
e9ae079fc3 | ||
|
|
fab2b1d3a0 | ||
|
|
18c033dc5c | ||
|
|
592630d48c | ||
|
|
d2aa8dcc43 | ||
|
|
9b107a129a | ||
|
|
10d6dcc4a9 | ||
|
|
16dbe54560 | ||
|
|
812c0e9281 | ||
|
|
7c021657e1 | ||
|
|
5dff30d90c | ||
|
|
3cc1b56810 | ||
|
|
fea4af0e63 | ||
|
|
a776fdabb9 | ||
|
|
2eb57279fe | ||
|
|
863ae5652f | ||
|
|
d0faba12a3 | ||
|
|
63991822e7 | ||
|
|
1404e041e8 | ||
|
|
55d78f3c9f | ||
|
|
e9f427c75b | ||
|
|
a661cd8295 | ||
|
|
1be83e4e33 | ||
|
|
9109495894 | ||
|
|
7586538432 | ||
|
|
4bd5614f4c | ||
|
|
c8e0fcfcdf | ||
|
|
7fa30c0dec | ||
|
|
a0d679439f | ||
|
|
072ddb799f | ||
|
|
ac744a6313 | ||
|
|
c8b22a19ad | ||
|
|
a262ea02d9 | ||
|
|
de9c591ffc | ||
|
|
70e535bee3 | ||
|
|
749def2ef5 | ||
|
|
c0750c1a3f | ||
|
|
475e08bba3 | ||
|
|
2a1e7cb5c9 | ||
|
|
c4ae4aee2b | ||
|
|
8e3ad082e2 | ||
|
|
b48123c1e1 | ||
|
|
aa3b001a04 | ||
|
|
c0707844e6 | ||
|
|
bf465cd904 | ||
|
|
d8140f4142 | ||
|
|
e6698fc65a | ||
|
|
ab66326f97 | ||
|
|
9d07a97945 | ||
|
|
86cbffbae0 | ||
|
|
10d4e023c8 | ||
|
|
51c7757543 | ||
|
|
27f307b428 | ||
|
|
a92fe17ae0 | ||
|
|
275a2e79ee | ||
|
|
7f48331ed4 | ||
|
|
e511550c91 | ||
|
|
7f68b471aa | ||
|
|
73893a921c | ||
|
|
70ca41dd44 | ||
|
|
22af1f07bf | ||
|
|
cfecc151d9 | ||
|
|
fde3a02b71 | ||
|
|
56b0582272 | ||
|
|
b67dae1f65 | ||
|
|
d1057e821a | ||
|
|
5314bbf952 | ||
|
|
c7cc36abdb | ||
|
|
a97ae67552 | ||
|
|
4cc6a0f263 | ||
|
|
04d744fda3 | ||
|
|
4b67c31277 | ||
|
|
84e0b1c904 | ||
|
|
61a8512805 | ||
|
|
08a4c02d38 | ||
|
|
1cbff6b771 | ||
|
|
9df9edc4c7 | ||
|
|
685cdbe124 | ||
|
|
2716f65010 | ||
|
|
8006024715 | ||
|
|
2616a4cf5e | ||
|
|
57a9deb98d | ||
|
|
ece22497dd | ||
|
|
fb170007c8 | ||
|
|
36c5017300 | ||
|
|
e8e245e20f | ||
|
|
2141ea6564 | ||
|
|
d3959d5899 | ||
|
|
cbb4b10ce6 | ||
|
|
861c81b590 | ||
|
|
28131624b8 | ||
|
|
ce1f01c494 | ||
|
|
a13a4ca532 | ||
|
|
f830120044 | ||
|
|
7645a72b2f | ||
|
|
ff8a8b8302 | ||
|
|
a7cc026e2c | ||
|
|
c78bf2775f | ||
|
|
0082bb22fb | ||
|
|
febf80cccd | ||
|
|
4d8dab6e33 | ||
|
|
f385fd9efd | ||
|
|
a66d96ce0a | ||
|
|
05f1fac2a7 | ||
|
|
03ae38a41e | ||
|
|
fbb8c056d4 | ||
|
|
0e68d34e1b | ||
|
|
a62027d5f3 | ||
|
|
db38498d06 | ||
|
|
af11f66646 | ||
|
|
2a422e1d83 | ||
|
|
f463aea399 | ||
|
|
f93da3cfb1 | ||
|
|
253b10818c | ||
|
|
2c0e086761 | ||
|
|
8882f4dd14 | ||
|
|
2cf76cb701 | ||
|
|
bb9517b73f | ||
|
|
f681b35b65 | ||
|
|
8c5d36f0ee | ||
|
|
08d0ff0922 | ||
|
|
e5683b1da5 | ||
|
|
3dffa8284f | ||
|
|
e332197660 | ||
|
|
8b36b71833 | ||
|
|
7eb5e07e9d | ||
|
|
0b9eb3c111 | ||
|
|
5f7a3f2b69 | ||
|
|
02676572dd | ||
|
|
404661fc72 | ||
|
|
5c3f013325 | ||
|
|
ea4aa4f149 | ||
|
|
0c8fc63b33 | ||
|
|
c239746363 | ||
|
|
12b47cc037 | ||
|
|
2c636086bd | ||
|
|
6a7386e6ba | ||
|
|
21ab9f8b9e | ||
|
|
eab113e4f5 | ||
|
|
bd4a8c1ce2 | ||
|
|
e2de7ab0c7 | ||
|
|
a6e80b2bc1 | ||
|
|
3f5a55e240 | ||
|
|
b79be6d320 | ||
|
|
60bb78e25b | ||
|
|
281fb549f8 | ||
|
|
d16f62cb38 | ||
|
|
912bd84629 | ||
|
|
d77078518d | ||
|
|
e310af00b4 | ||
|
|
cedbdf43ca | ||
|
|
911559fe05 | ||
|
|
c958eae551 | ||
|
|
053ba9a9ca | ||
|
|
c5aa74f823 | ||
|
|
20180923cf | ||
|
|
6e104c3ed0 | ||
|
|
880a503094 | ||
|
|
edbc273829 | ||
|
|
5f807e7421 | ||
|
|
579d9fc813 | ||
|
|
dc074fcc50 | ||
|
|
5d95267c4a | ||
|
|
69fdd45459 | ||
|
|
d3370bf596 | ||
|
|
d359c63018 | ||
|
|
a9376f0a41 | ||
|
|
e75dcc18f1 | ||
|
|
7da0cfd0d8 | ||
|
|
b0e51e2cba | ||
|
|
a762956000 | ||
|
|
e58c1ee306 | ||
|
|
fd3ceb60c8 | ||
|
|
4c04420a51 | ||
|
|
e345ceb01a | ||
|
|
f3e4157698 | ||
|
|
1a99b241ca | ||
|
|
74f0f27d18 | ||
|
|
5846cc7b70 | ||
|
|
b202b508f2 | ||
|
|
a7d20df95a | ||
|
|
674b540c6f | ||
|
|
8b860d3f0e | ||
|
|
35ed101651 | ||
|
|
99cc12cc0a | ||
|
|
21c7f2298a | ||
|
|
9da73b5222 | ||
|
|
db97d40f5e | ||
|
|
a78b5c2f8d | ||
|
|
df33ff7462 | ||
|
|
f589e11419 | ||
|
|
db462a181c | ||
|
|
b42e29c5a7 | ||
|
|
cc734930c6 | ||
|
|
11f9c22e56 | ||
|
|
d59b2c3ef6 | ||
|
|
116c00595c | ||
|
|
8fb29a3af3 | ||
|
|
202c459413 | ||
|
|
dd3e9806af | ||
|
|
411cdb29a1 | ||
|
|
1005976a22 | ||
|
|
504f30e045 | ||
|
|
808f5dc452 | ||
|
|
b7d7f6d877 | ||
|
|
df334e809e | ||
|
|
ade601ab81 | ||
|
|
50b04cdf92 | ||
|
|
ccee1b6a55 | ||
|
|
27c9fce15b | ||
|
|
c2fd35c687 | ||
|
|
7e0bbf8161 | ||
|
|
35f5bb0039 | ||
|
|
ffd960ca4e | ||
|
|
c881d24553 | ||
|
|
290b0ea14b | ||
|
|
ccf97a62f1 | ||
|
|
d7d8dabb40 | ||
|
|
9d8b32c935 | ||
|
|
19532cae88 | ||
|
|
37e4a5ddae | ||
|
|
8792e509d7 | ||
|
|
b5b1ca068d | ||
|
|
ecdf6c2213 | ||
|
|
8b272b0bf0 | ||
|
|
6684a8f914 | ||
|
|
50fee0275c | ||
|
|
4e26874298 | ||
|
|
b126159360 | ||
|
|
dc622470c9 | ||
|
|
63eba6c634 | ||
|
|
2f70dd7015 | ||
|
|
441ac3742c | ||
|
|
90bc9314f1 | ||
|
|
3ee02c1433 | ||
|
|
ff02e12389 | ||
|
|
69aae64133 | ||
|
|
00ab79b7cf | ||
|
|
467945bedb | ||
|
|
460d9c1c44 | ||
|
|
ae67940544 | ||
|
|
497c10897f | ||
|
|
e868a8437f | ||
|
|
c8786b7b28 | ||
|
|
7a9bc641ee | ||
|
|
781e606e5a | ||
|
|
3c1c8c397f | ||
|
|
ed87454ff8 | ||
|
|
7977769d91 | ||
|
|
879abc0949 | ||
|
|
f9bbe8ed58 | ||
|
|
46c99e6c87 | ||
|
|
d34d4cbc37 | ||
|
|
4dd208a2b3 | ||
|
|
bce2d5242c | ||
|
|
83fb1fd0f6 | ||
|
|
39ee223ef8 | ||
|
|
4e37b51749 | ||
|
|
85c07ce47b | ||
|
|
041f727fe3 | ||
|
|
3f8ee8dc93 | ||
|
|
6849d6a5e5 | ||
|
|
2d0ba26497 | ||
|
|
e9ac432e0f | ||
|
|
42cc3cac21 | ||
|
|
a324eafac4 | ||
|
|
6203224f3e | ||
|
|
df40dc46bb | ||
|
|
8f9b0424b6 | ||
|
|
c4434f27af | ||
|
|
6ba077cf37 | ||
|
|
3893004f5e | ||
|
|
ba5922f468 | ||
|
|
72c410363c | ||
|
|
3b41a44050 | ||
|
|
04baeefaa8 | ||
|
|
4dcb877ff9 | ||
|
|
a68fb9d0b6 | ||
|
|
671a62e0fe | ||
|
|
0f7d4f57d8 | ||
|
|
6b9a443c05 | ||
|
|
4414c70b87 | ||
|
|
9e4ef3cbff | ||
|
|
62129d9a2f | ||
|
|
4bdf4197db | ||
|
|
e5b7373298 | ||
|
|
c2fcf53e53 | ||
|
|
e6345f39a9 | ||
|
|
4a73e099b7 | ||
|
|
a0595a00e8 | ||
|
|
bd836d88af | ||
|
|
43074632b3 | ||
|
|
2e2aac5988 | ||
|
|
f623404b89 | ||
|
|
8d65c9c92f | ||
|
|
6b971f7200 | ||
|
|
eaf02f5a79 | ||
|
|
b9c3d8ba03 | ||
|
|
c0e333af53 | ||
|
|
f416c686af | ||
|
|
581f34dced | ||
|
|
3c6377d665 | ||
|
|
b178960704 | ||
|
|
65275e5841 | ||
|
|
e37b3ca8e1 | ||
|
|
1241f2debd | ||
|
|
5aefaa1c48 | ||
|
|
c7fb38b606 | ||
|
|
7e05b6e0b3 | ||
|
|
879184fe37 | ||
|
|
cbe7e3e80e | ||
|
|
ebd87bfb78 | ||
|
|
beeca433ae | ||
|
|
d3f9427e37 | ||
|
|
c76e41d157 | ||
|
|
f695603dec | ||
|
|
5bb7c7eb9a | ||
|
|
395d65454c | ||
|
|
27381b7f07 | ||
|
|
e7c4fa0e5f | ||
|
|
7ce849a2b6 | ||
|
|
a07f690509 | ||
|
|
54fba9af4b | ||
|
|
2a1054b1a8 | ||
|
|
77cef764d6 | ||
|
|
2f3390750d | ||
|
|
936a00a974 | ||
|
|
658a4d0b47 | ||
|
|
5b281a06d6 | ||
|
|
45c9b82fb3 | ||
|
|
755088dbf0 | ||
|
|
9932eb667b | ||
|
|
921dbe0547 | ||
|
|
ab679cbe26 | ||
|
|
4147e92561 | ||
|
|
3413c96845 | ||
|
|
780cff46b3 | ||
|
|
5d6f6b0571 | ||
|
|
04b0fe0160 | ||
|
|
4d1c84aa2b | ||
|
|
1c11afd78d | ||
|
|
8b5fe24cb2 | ||
|
|
ba905a2c18 | ||
|
|
bd51b250be | ||
|
|
996bf25aee | ||
|
|
2a5336b93a | ||
|
|
b54f4e830a | ||
|
|
a38ea51994 | ||
|
|
7053e468cf | ||
|
|
5ea62443f4 | ||
|
|
8fc1e4b5ea | ||
|
|
da6d781768 | ||
|
|
11e3217ec1 | ||
|
|
12a8be0b98 | ||
|
|
6286b6cd76 | ||
|
|
e7b8123141 | ||
|
|
fc7f724529 | ||
|
|
418c978b91 | ||
|
|
89c782051b | ||
|
|
31d7afc987 | ||
|
|
2f1138cd11 | ||
|
|
8068702c15 | ||
|
|
604fb3286c | ||
|
|
a5b3104b0c | ||
|
|
a79279b1cc | ||
|
|
8f90ba82a4 | ||
|
|
9bd6c98320 | ||
|
|
6465cd6446 | ||
|
|
5e2c03635f | ||
|
|
a9cf8c4c04 | ||
|
|
3233005a0a | ||
|
|
d34f1d2c1a | ||
|
|
c68d83bce7 | ||
|
|
7cd95734df | ||
|
|
06cebb0816 | ||
|
|
b2f30f5bee | ||
|
|
ab990933a2 | ||
|
|
9a635f0ce3 | ||
|
|
7756adc75c | ||
|
|
5e9b22fbb2 | ||
|
|
01c09fd7fa | ||
|
|
af53111070 | ||
|
|
cba586f06f | ||
|
|
af9f1e6f48 | ||
|
|
53b2e1372c | ||
|
|
aee7d7327f | ||
|
|
03291eb5f4 | ||
|
|
0371b69952 | ||
|
|
6c22ae3759 | ||
|
|
56b64d688d | ||
|
|
50065a2781 | ||
|
|
1315112ab5 | ||
|
|
d3f9da7645 | ||
|
|
5129a3ccc3 | ||
|
|
bf3a20b2d7 | ||
|
|
fb523722b5 | ||
|
|
ab3aaebe6d | ||
|
|
5dcd84b71b | ||
|
|
6c48e9bbdf | ||
|
|
7f1b916f32 | ||
|
|
df3c163eeb | ||
|
|
d96f39360b | ||
|
|
fd1778203d | ||
|
|
9ba89b9ab1 | ||
|
|
d8e68bc0e1 | ||
|
|
9f6965c1b5 | ||
|
|
ae7e485474 | ||
|
|
4f20d7ab24 | ||
|
|
68a39a1d92 | ||
|
|
7d31d44047 | ||
|
|
f95aba2f73 | ||
|
|
f93de58f3b | ||
|
|
4e8ddd5fa3 | ||
|
|
5a0eb41d19 | ||
|
|
036823cd06 | ||
|
|
2326c509c3 | ||
|
|
8ba2f770e9 | ||
|
|
2d040c1aaa | ||
|
|
81ff5ed7aa | ||
|
|
70a06c9b59 | ||
|
|
b2f3a07708 | ||
|
|
fb33f55670 | ||
|
|
53454a370b | ||
|
|
c503424b42 | ||
|
|
38e9dd1fd9 | ||
|
|
2014d21dd2 | ||
|
|
ee021a6a5d | ||
|
|
e278997750 | ||
|
|
cd3f630fc5 | ||
|
|
c3b4ca7135 | ||
|
|
77e73d15af | ||
|
|
dd9e5668c2 | ||
|
|
f68098c7fc | ||
|
|
a5c1a01965 | ||
|
|
6a9db38006 | ||
|
|
db5fa3d15e | ||
|
|
edfa1c8ecd | ||
|
|
08a87ae4a0 | ||
|
|
6580374c4f | ||
|
|
803e4ecc93 | ||
|
|
d30a2db1e8 | ||
|
|
106e323205 | ||
|
|
228d2c4c44 | ||
|
|
24ed3e6e41 | ||
|
|
72cb5cae1e | ||
|
|
8641722b52 | ||
|
|
4835bbbdb4 | ||
|
|
9df239f2fd | ||
|
|
348bcae763 | ||
|
|
a6af5e26bc | ||
|
|
23a9db1e4d | ||
|
|
77c0249d72 | ||
|
|
daaae974b3 | ||
|
|
60f8f1477c | ||
|
|
fba56f2601 | ||
|
|
8f0146c564 | ||
|
|
f2f2ebfa4f | ||
|
|
cdb46f03f7 | ||
|
|
0022e5a67e | ||
|
|
8ad4dd332a | ||
|
|
8e5392e9d9 | ||
|
|
ac220ad38a | ||
|
|
da9b28d35c | ||
|
|
000880837e | ||
|
|
06bcd411d8 | ||
|
|
31ee99ea3e | ||
|
|
21f84e1548 | ||
|
|
0614d2f966 | ||
|
|
47649066b5 | ||
|
|
8aadecf3ff | ||
|
|
e6a750204a | ||
|
|
0905b2c1e4 | ||
|
|
216f1150cd | ||
|
|
c71a4717dd | ||
|
|
ac666490d2 | ||
|
|
3cc439a1cc | ||
|
|
92eaf42cad | ||
|
|
97e9fb29b0 | ||
|
|
832860bcb5 | ||
|
|
2dec333910 | ||
|
|
3498cc9947 | ||
|
|
b5dc628357 | ||
|
|
0fc990423b | ||
|
|
0dffe26cfe | ||
|
|
0a0d7858c6 | ||
|
|
64cce065e6 | ||
|
|
25b5651f9d | ||
|
|
d4bc707ba0 | ||
|
|
759ffb7b53 | ||
|
|
0a5ca5aaf0 | ||
|
|
41b69d6c8a | ||
|
|
aef2134128 | ||
|
|
13f19ea21a | ||
|
|
344906deb9 | ||
|
|
e7e67ad235 | ||
|
|
5c109ee8dc | ||
|
|
1e0d9f899b | ||
|
|
4f17080929 | ||
|
|
b6cfb8aa4f | ||
|
|
21ab72b4da | ||
|
|
875718f40c | ||
|
|
19b0fe9781 | ||
|
|
c2d3f9d5b5 | ||
|
|
3a1c18ede2 | ||
|
|
2ee7e73531 | ||
|
|
dc0e577b44 | ||
|
|
7c1709fab4 | ||
|
|
ea054ef149 | ||
|
|
14e0abc4e2 | ||
|
|
558d0e8ac9 | ||
|
|
fa27132025 | ||
|
|
00f21ee93c | ||
|
|
2468b9f45c | ||
|
|
1f94ca786d | ||
|
|
6c1bb76316 | ||
|
|
9d205fe43c | ||
|
|
d2c5668baa | ||
|
|
857bcf924a | ||
|
|
0d85592085 | ||
|
|
72bb9b3d0a | ||
|
|
7a9c77fad7 | ||
|
|
5614942c60 | ||
|
|
3440fb86c8 | ||
|
|
b2c62c4b4d | ||
|
|
a00b031cd9 | ||
|
|
5d827ac40e | ||
|
|
ba8783190b | ||
|
|
4c55c77c04 | ||
|
|
a7776f8279 | ||
|
|
2aa8908948 | ||
|
|
3120414e10 | ||
|
|
63e959e4e1 | ||
|
|
fda3461c5a | ||
|
|
067b137ed9 | ||
|
|
413de3a0ee | ||
|
|
e4c3a8d0df | ||
|
|
9da5e74287 | ||
|
|
caeca36a40 | ||
|
|
a854a6a709 | ||
|
|
1a38207faf | ||
|
|
3eafb29eb8 | ||
|
|
c8a715d09b | ||
|
|
79fb587135 | ||
|
|
6f336c182c | ||
|
|
b2d7938cec | ||
|
|
5bf4098356 | ||
|
|
0087143b88 | ||
|
|
9c9e96cfa7 | ||
|
|
3755437d08 | ||
|
|
d002ebd373 | ||
|
|
851d17e028 | ||
|
|
581b07d096 | ||
|
|
2f660674c3 | ||
|
|
f1a00a01cf | ||
|
|
7056da079d | ||
|
|
6b54b715d7 | ||
|
|
4c3c3a3f90 | ||
|
|
fe69699146 | ||
|
|
cc80aab191 | ||
|
|
12d9f8b02b | ||
|
|
367a818c26 | ||
|
|
3517b9f4e2 | ||
|
|
19e704f408 | ||
|
|
491b3f8b1a | ||
|
|
7f88f80d8e | ||
|
|
bcb88a4bc5 | ||
|
|
cb22320ae6 | ||
|
|
d42ced5aa4 | ||
|
|
fc98f06ed7 | ||
|
|
54b74fafba | ||
|
|
a2169bf0c4 | ||
|
|
a0bbf7703b | ||
|
|
693d1b84a8 | ||
|
|
e04e11c84d | ||
|
|
7360f90e5e | ||
|
|
94ccd42c73 | ||
|
|
f2849ac269 | ||
|
|
8cad40a124 | ||
|
|
3af22f12bf | ||
|
|
adfd9091f8 | ||
|
|
9cd648a262 | ||
|
|
c0fa8702af | ||
|
|
98f9902839 | ||
|
|
c48da38b14 | ||
|
|
cf4304ab2b | ||
|
|
c3e858443f | ||
|
|
3d948a3624 | ||
|
|
4ae8fefb95 | ||
|
|
c17bdf951d | ||
|
|
eade742b32 | ||
|
|
e4b4b6e103 | ||
|
|
ddda89c33e | ||
|
|
11dcdf4fef | ||
|
|
bae479972f | ||
|
|
346820d626 | ||
|
|
10f85eb856 | ||
|
|
63b45a993d | ||
|
|
0463399389 | ||
|
|
ecdeea22eb | ||
|
|
7fdcc1af18 | ||
|
|
5e85163b57 | ||
|
|
a884a8a880 | ||
|
|
267b8a037f | ||
|
|
bf924a7664 | ||
|
|
359d9ea439 | ||
|
|
76f71b6b37 | ||
|
|
1b1e85c0b8 | ||
|
|
6be3084eac | ||
|
|
3e6a6ffb52 | ||
|
|
b5b55c90de | ||
|
|
c546269485 | ||
|
|
cf81331b39 | ||
|
|
446ca8f73d | ||
|
|
d6bd735aff | ||
|
|
494dd97775 | ||
|
|
49dd67432d | ||
|
|
4a40187f8e | ||
|
|
513e77635b | ||
|
|
619772b5c8 | ||
|
|
bac4075128 | ||
|
|
3a610882f6 | ||
|
|
cdeaa154cd | ||
|
|
4e6d268ef3 | ||
|
|
068d921ef6 | ||
|
|
f45b597e61 | ||
|
|
1d8fff706b | ||
|
|
6225073095 | ||
|
|
2ccf7f1cfb | ||
|
|
a619ce3e9b | ||
|
|
38276abe78 | ||
|
|
03a3a1a261 | ||
|
|
7ef857a0bc | ||
|
|
d2b1d538bf | ||
|
|
c906dfdf71 | ||
|
|
dd4fe87f69 | ||
|
|
fb39b41ffb | ||
|
|
764dc88832 | ||
|
|
b74c90dc20 | ||
|
|
0dc680df0b | ||
|
|
3a6ad0737c | ||
|
|
7be78de93a | ||
|
|
f1a422dfff | ||
|
|
a27e5825b9 | ||
|
|
fd98d5b1e6 | ||
|
|
330005d932 | ||
|
|
d379e3c012 | ||
|
|
bb079d6b39 | ||
|
|
f9375d5660 | ||
|
|
73cba00687 | ||
|
|
0c3285ced7 | ||
|
|
54d0c63956 | ||
|
|
4de2be8c5f | ||
|
|
68d491c40d | ||
|
|
9db5a1a6ce | ||
|
|
49c0f9cccc | ||
|
|
8389e78ff3 | ||
|
|
6ba375401e | ||
|
|
3c94b4d408 | ||
|
|
5b5065d293 | ||
|
|
4da060ca52 | ||
|
|
702d5520d4 | ||
|
|
fae267f72d | ||
|
|
1e16ab4d26 | ||
|
|
e91a90899c | ||
|
|
fa9c933773 | ||
|
|
810c160e4d | ||
|
|
b07835b35c | ||
|
|
4f7b1f3306 | ||
|
|
6f0bebdfda | ||
|
|
1c8fef69aa | ||
|
|
0b0d3b43a1 | ||
|
|
22f7380abe | ||
|
|
571fb95cc1 | ||
|
|
29fdc0946a | ||
|
|
5d6a07e060 | ||
|
|
b0cf022983 | ||
|
|
2a9c1a2cd2 | ||
|
|
cb4a7a52da | ||
|
|
5a6f1d42a9 | ||
|
|
696aea211a | ||
|
|
ee29bf3939 | ||
|
|
a1af95c34e | ||
|
|
ad7efb23e6 | ||
|
|
af61451f87 | ||
|
|
2f99e1d5c1 | ||
|
|
62551b5ff9 | ||
|
|
aa502348e5 | ||
|
|
323ea0ef73 | ||
|
|
f0e68d7d86 | ||
|
|
00ca09a2ea | ||
|
|
a307aff858 | ||
|
|
5ae1c34857 | ||
|
|
45120ad3eb | ||
|
|
be769dcf00 | ||
|
|
d84cde1f7a | ||
|
|
aa2fb685d9 | ||
|
|
77bb678a3d | ||
|
|
37a7236e20 | ||
|
|
a15a584136 | ||
|
|
75f49a751e | ||
|
|
7fef0302a7 | ||
|
|
f082eca791 | ||
|
|
c1c5cc78a5 | ||
|
|
cefe99bed2 | ||
|
|
90807ac6e7 | ||
|
|
08162dbb50 | ||
|
|
50b46d7bee | ||
|
|
a77c92aebe | ||
|
|
f0d4fefb6a | ||
|
|
6be33cf6ef | ||
|
|
91aa8e7637 | ||
|
|
3f03c7a9d6 | ||
|
|
4f66db6c38 | ||
|
|
658f418400 | ||
|
|
b666ac787b | ||
|
|
387cf2181a | ||
|
|
5068be3c27 | ||
|
|
02c668fa5d | ||
|
|
89b3bec1b0 | ||
|
|
77d938065f | ||
|
|
ecc6bbb028 | ||
|
|
09da544145 | ||
|
|
2804e08908 | ||
|
|
1997281449 | ||
|
|
46a5ab99f9 | ||
|
|
3a330dc7fc | ||
|
|
26663a6cf9 | ||
|
|
91e9ecfa63 | ||
|
|
eded314bb1 | ||
|
|
6c0f40385c | ||
|
|
75854b5d0b | ||
|
|
b4a669ad76 | ||
|
|
5f2709b410 | ||
|
|
c345dcdbc4 | ||
|
|
fec6b59950 | ||
|
|
e15fb54cc6 | ||
|
|
823c863a53 | ||
|
|
955dc38400 | ||
|
|
c0358cb7b4 | ||
|
|
51bb98c03a | ||
|
|
09c6ff4f9c | ||
|
|
6bd07501e8 | ||
|
|
69a9ce214f | ||
|
|
f3c54fcf50 | ||
|
|
a096f9af50 | ||
|
|
9ace48c835 | ||
|
|
1863057b7e | ||
|
|
4a4c8846f4 | ||
|
|
0540a3351c | ||
|
|
122b2233b1 | ||
|
|
9fe22546be | ||
|
|
795d240379 | ||
|
|
1437fb2621 | ||
|
|
8ccdee4035 | ||
|
|
56f895db09 | ||
|
|
e9a7eff13f | ||
|
|
2a3f0c0ec3 | ||
|
|
781e257298 | ||
|
|
806f43cdbc | ||
|
|
c2dff6bbf7 | ||
|
|
d579840870 | ||
|
|
31443e978d | ||
|
|
52ac2b3850 | ||
|
|
21ea105a82 | ||
|
|
293d675523 | ||
|
|
d951ed6f0d | ||
|
|
1304f5ad6a | ||
|
|
48e1f23b86 | ||
|
|
ad86d063e4 | ||
|
|
f68e4eeb72 | ||
|
|
f3e80267da | ||
|
|
2267f81632 | ||
|
|
14d9902586 | ||
|
|
04666cd0cf | ||
|
|
5d761a1c2b | ||
|
|
e2d95975f6 | ||
|
|
f418ea5fc3 | ||
|
|
9603d8a013 | ||
|
|
8158c81377 | ||
|
|
664ad0a32d | ||
|
|
eea8ed330b | ||
|
|
8f9f804b58 | ||
|
|
e20491759d | ||
|
|
c3b327dbe7 | ||
|
|
f2ed30dff5 | ||
|
|
14470b8bc6 | ||
|
|
769d8bf52b | ||
|
|
33acbec9ee | ||
|
|
ba2bd08d10 | ||
|
|
0435f618f6 | ||
|
|
8cfa93872f | ||
|
|
a6ab3abbf9 | ||
|
|
116f41d162 | ||
|
|
34cc0b2b8b | ||
|
|
bc7aed290a | ||
|
|
8c0e5d8d98 | ||
|
|
9f60dfc92d | ||
|
|
10669e80b3 | ||
|
|
215477f139 | ||
|
|
e277855eee | ||
|
|
0859c1d1ad | ||
|
|
840ef35be9 | ||
|
|
24e4c2706a | ||
|
|
875d92c387 | ||
|
|
fa769b5ac6 | ||
|
|
30ae727e6e | ||
|
|
e627799623 | ||
|
|
626cb9aa95 | ||
|
|
c7b93603d1 | ||
|
|
4017325981 | ||
|
|
302bc46914 | ||
|
|
adcfde14ed | ||
|
|
4c5dfa1391 | ||
|
|
009e2c200d | ||
|
|
4aec01e3ba | ||
|
|
0fb737516a | ||
|
|
bc920f00a2 | ||
|
|
859a615e93 | ||
|
|
57049b8e78 | ||
|
|
ed6e1c7f0b | ||
|
|
6706ce9ee7 | ||
|
|
17329a1090 | ||
|
|
efe5b5c824 | ||
|
|
e051c732a0 | ||
|
|
11db020124 | ||
|
|
a63b8af505 | ||
|
|
722892cd96 | ||
|
|
b5b4ebfb88 | ||
|
|
fe5de64fb2 | ||
|
|
d227fa6302 | ||
|
|
11f609c3a6 | ||
|
|
0d70d97eeb | ||
|
|
76e89dae32 | ||
|
|
f0ed1c37a4 | ||
|
|
dcb8192c29 | ||
|
|
314d1be443 | ||
|
|
2c87f82ca7 | ||
|
|
19f6eab14e | ||
|
|
f8e0cc8fe4 | ||
|
|
939ff2337f | ||
|
|
5745eb9be8 | ||
|
|
81e4e1d8f4 | ||
|
|
862b69c640 | ||
|
|
2f93fcd8a5 | ||
|
|
c56ce248c9 | ||
|
|
e3e1c11509 | ||
|
|
eebb6414bf | ||
|
|
a9adb22fed | ||
|
|
93700f91e7 | ||
|
|
92f6b1648a | ||
|
|
f9b94bbefb | ||
|
|
c658f9172c | ||
|
|
cf37591200 | ||
|
|
96bb687fcc | ||
|
|
987eedba84 | ||
|
|
5f2d37a6d0 | ||
|
|
1b8205245e | ||
|
|
63e977721a | ||
|
|
32676e9062 | ||
|
|
04d38ad9c0 | ||
|
|
53c42d000f | ||
|
|
744fb2865d | ||
|
|
d3f12c84ad | ||
|
|
d80471c0a3 | ||
|
|
4aa2b34182 | ||
|
|
df8458275d | ||
|
|
de9ce3437d | ||
|
|
698d828a41 | ||
|
|
a23da65c4f | ||
|
|
8af2a9ade3 | ||
|
|
a581bc158b | ||
|
|
8e9644a8a2 | ||
|
|
e746b3bd5f | ||
|
|
7288176f65 | ||
|
|
aa7e9594e8 | ||
|
|
72438dbdaa | ||
|
|
428638b37a | ||
|
|
46e79c1f9f | ||
|
|
765020f4d7 | ||
|
|
d8b30f8169 | ||
|
|
98109d2e39 | ||
|
|
ac37b8acee | ||
|
|
84a911f145 | ||
|
|
215e91cade | ||
|
|
fd1a95ac87 | ||
|
|
76313dfd99 | ||
|
|
553338636b | ||
|
|
22ccfba8c4 | ||
|
|
19dc855551 | ||
|
|
37c2da5062 | ||
|
|
48d5f79d9a | ||
|
|
f50fd77694 | ||
|
|
0a403c744b | ||
|
|
05664acd36 | ||
|
|
2985758136 | ||
|
|
ed30920984 | ||
|
|
7787d64bce | ||
|
|
5e8643d855 | ||
|
|
e2af1b547b | ||
|
|
171452095f | ||
|
|
5ffbdd8cdc | ||
|
|
5cfbeeb5d9 | ||
|
|
76ad86667b | ||
|
|
6eef4b65ff | ||
|
|
2f79262f80 | ||
|
|
e2308eb7f4 | ||
|
|
f3dfe1dd09 | ||
|
|
f1380b6a32 | ||
|
|
0633cbf8fa | ||
|
|
80c39cf670 | ||
|
|
9ffb984f37 | ||
|
|
bbcd5bc8c7 | ||
|
|
41c33601f3 | ||
|
|
b93a5ed509 | ||
|
|
12375846c8 | ||
|
|
6973a33519 | ||
|
|
6ea5df34fc | ||
|
|
495ba2510b | ||
|
|
f24a3c67ed | ||
|
|
5daf987c8b | ||
|
|
d21ab37abd | ||
|
|
d6c82943f2 | ||
|
|
644f012c42 | ||
|
|
aa9500434b | ||
|
|
d7598ee9d2 | ||
|
|
77f26d5681 | ||
|
|
2988bb6a32 | ||
|
|
f5890e343f | ||
|
|
f58e9e1de2 | ||
|
|
6a52f77656 | ||
|
|
83e3c0f7ba | ||
|
|
c8667b8ddb | ||
|
|
e58748bcf7 | ||
|
|
61397cd302 | ||
|
|
16441610c9 | ||
|
|
89328ff03f | ||
|
|
8a0d036b87 | ||
|
|
63b76c0ad1 | ||
|
|
ed5670eb48 | ||
|
|
b6f006c152 | ||
|
|
e2c67e0239 | ||
|
|
2c100a8e87 | ||
|
|
7fbc636824 | ||
|
|
87a3208df2 | ||
|
|
8282424532 | ||
|
|
de7a944601 | ||
|
|
3072a16b86 | ||
|
|
57d07469d3 | ||
|
|
d737ede7f0 | ||
|
|
89e914b160 | ||
|
|
8ae69763dc | ||
|
|
d6ecb5025a | ||
|
|
3ef5ce690d | ||
|
|
53ad55a1b2 | ||
|
|
788a3f7c8d | ||
|
|
f1c4e247a5 | ||
|
|
d54764924b | ||
|
|
bdd35789db | ||
|
|
05ea209d5f | ||
|
|
c36a759de9 | ||
|
|
276b400a86 | ||
|
|
55059a6f0a | ||
|
|
95afec6977 | ||
|
|
5021c7faf8 | ||
|
|
e1fa657f2b | ||
|
|
019b0537f6 | ||
|
|
768a47dcfb | ||
|
|
f5c76e2253 | ||
|
|
a0017b5c72 | ||
|
|
aa801efce9 | ||
|
|
e491afe294 | ||
|
|
b051936ff4 | ||
|
|
5423f02c3c | ||
|
|
d203554e84 | ||
|
|
1c4974f6ea | ||
|
|
b6c42adc53 | ||
|
|
6ca67bfbf4 | ||
|
|
de3570714f | ||
|
|
c0c06bfc8a | ||
|
|
b82a93872b | ||
|
|
0d1fcc0691 | ||
|
|
27be7e2e6a | ||
|
|
88b66858ff | ||
|
|
e0166682da | ||
|
|
e3dd908d55 | ||
|
|
33490e4efc | ||
|
|
d96e62c50f | ||
|
|
b5a398bdff | ||
|
|
9659cfe876 | ||
|
|
949aa3fc32 | ||
|
|
6e40338f9e | ||
|
|
407b9b577b | ||
|
|
45a5671c55 | ||
|
|
de40d5fbe3 | ||
|
|
b0b8bebe6c | ||
|
|
b1812e7711 | ||
|
|
9414280aa7 | ||
|
|
6a6e66bf9e | ||
|
|
0c7a26f68b | ||
|
|
b68229aa2c | ||
|
|
6bc4776199 | ||
|
|
aa4280904a | ||
|
|
1c5ed75e72 | ||
|
|
893b664f34 | ||
|
|
7706231f16 | ||
|
|
e5bcddfbe0 | ||
|
|
3e6f2d8cef | ||
|
|
cf14bc6ab6 | ||
|
|
1a879a04ab | ||
|
|
47babef79a | ||
|
|
84471ba202 | ||
|
|
3e91030c81 | ||
|
|
ab0ebadee3 | ||
|
|
264dfc164d | ||
|
|
594e2a94c7 | ||
|
|
fb8e562123 | ||
|
|
c4f5415ece | ||
|
|
effe84cd56 | ||
|
|
c47751148c | ||
|
|
28554fd307 | ||
|
|
bd80ce4c61 | ||
|
|
cac15574e7 | ||
|
|
1e28eee0c7 | ||
|
|
6773307237 | ||
|
|
a11f01784a | ||
|
|
e5cf3cbbc1 | ||
|
|
3d464688fc | ||
|
|
8d05a54590 | ||
|
|
e398c3b16c | ||
|
|
287851ebb4 | ||
|
|
b3a2ea4e3e | ||
|
|
240bbf4abb | ||
|
|
53ae5a7b0f | ||
|
|
1687f0855d | ||
|
|
16d8d05172 | ||
|
|
fcd2383de3 | ||
|
|
1b54afe67a | ||
|
|
d5ea6e47dd | ||
|
|
8fa48b492e | ||
|
|
6d4e3f8c72 | ||
|
|
d52b9b7e5b | ||
|
|
a1b60430d6 | ||
|
|
b9875b7bc8 | ||
|
|
7b0bf0d85c | ||
|
|
3b97799837 | ||
|
|
c6b4c41aab | ||
|
|
d36d1f3cc0 | ||
|
|
8d39bf3850 | ||
|
|
51f367b5e0 | ||
|
|
7115bfbf3d | ||
|
|
699066ef85 | ||
|
|
7b1321d002 | ||
|
|
da446c0f19 | ||
|
|
c77ef87b05 | ||
|
|
41325ab308 | ||
|
|
49606cb509 | ||
|
|
1482c8aecc | ||
|
|
611145e712 | ||
|
|
36b2963343 | ||
|
|
ad9250d106 | ||
|
|
86208d8c33 | ||
|
|
1671d34e15 | ||
|
|
88e35f0852 | ||
|
|
729b6db7c2 | ||
|
|
d43341fab0 | ||
|
|
ac7bed335a | ||
|
|
ec93743659 | ||
|
|
54e5e660db | ||
|
|
83f5b4d93b | ||
|
|
8929d1bd63 | ||
|
|
3b5f6494f2 | ||
|
|
69dc96dc9f | ||
|
|
933590b6ba | ||
|
|
c58c5b8782 | ||
|
|
18279558da | ||
|
|
56a633ae95 | ||
|
|
f607aefeb8 | ||
|
|
b6c8b39899 | ||
|
|
dd3018ce02 | ||
|
|
22f2001ff5 | ||
|
|
c17ed7ec93 | ||
|
|
1176fc6f57 | ||
|
|
2e2563fab9 | ||
|
|
41401ef126 | ||
|
|
71b2257829 | ||
|
|
00ac5ff3d4 | ||
|
|
a63e62f643 | ||
|
|
8f3e3e04d8 | ||
|
|
ac8d8a7cb8 | ||
|
|
c36a6d3e0d | ||
|
|
833b40095f | ||
|
|
fd92820b03 | ||
|
|
facf115c04 | ||
|
|
70ecef0094 | ||
|
|
c5b81d580b | ||
|
|
f581940c71 | ||
|
|
f638fb1784 | ||
|
|
67a54547ed | ||
|
|
5dc7a6c7be | ||
|
|
95a2c74f12 | ||
|
|
182a49fcff | ||
|
|
5849da358c | ||
|
|
ed12ad930a | ||
|
|
487e7a7137 | ||
|
|
272ba86ae4 | ||
|
|
f8d6ff42ff | ||
|
|
ce2b4ae963 | ||
|
|
9e4dea14e4 | ||
|
|
8e0a826cc7 | ||
|
|
e36f9d7da8 | ||
|
|
1e6847c43f | ||
|
|
5edb4c6bfd | ||
|
|
780485a98c | ||
|
|
37dbc646a1 | ||
|
|
1470a8a997 | ||
|
|
8e758f1e4d | ||
|
|
e940afdf00 | ||
|
|
03ba5d8d18 | ||
|
|
901fd31a30 | ||
|
|
49b7fdb62f | ||
|
|
baabe7eb7e | ||
|
|
669cc496cd | ||
|
|
2b973468bf | ||
|
|
645baf3353 | ||
|
|
9bd160dd8e | ||
|
|
1d014edca2 | ||
|
|
0c6d798dc6 | ||
|
|
dbd3d15f29 | ||
|
|
088a1db74d | ||
|
|
a02123bee4 | ||
|
|
2d6bd741d0 | ||
|
|
c9a732c4f9 | ||
|
|
aa6cee83af | ||
|
|
509e2181de | ||
|
|
fdbfd719ca | ||
|
|
ea397d0946 | ||
|
|
7d6defabf9 | ||
|
|
710e0e5a3c | ||
|
|
ecc05e57ae | ||
|
|
edf9b7bf1d | ||
|
|
37b587168f | ||
|
|
d2e22eda28 | ||
|
|
2e1ab7e6fe | ||
|
|
4d45b4d950 | ||
|
|
4a769dbf5f | ||
|
|
b2c45aafdc | ||
|
|
5b7a53b543 | ||
|
|
c9a3c40f83 | ||
|
|
774bf96c61 | ||
|
|
fafacef0a0 | ||
|
|
4f0b1bdf6d | ||
|
|
8114ae6552 | ||
|
|
98857832cd | ||
|
|
606c525099 | ||
|
|
30d8743853 | ||
|
|
05df50f929 | ||
|
|
f2fadd6562 | ||
|
|
a82f0d4e6e | ||
|
|
9210d4ebd8 | ||
|
|
5f26bb5031 | ||
|
|
e2258403ee | ||
|
|
d37ea10cf8 | ||
|
|
be95eb5a44 | ||
|
|
a859c4509a | ||
|
|
a640402005 | ||
|
|
f05da3db03 | ||
|
|
90fe9ec055 | ||
|
|
22e1e5f28c | ||
|
|
e42c1aa02b | ||
|
|
d8a2be3eb7 | ||
|
|
ded6350c80 | ||
|
|
09a5d66b3e | ||
|
|
82bee23bd0 | ||
|
|
e7139cbd85 | ||
|
|
6aa2fc0094 | ||
|
|
8337cbb31f | ||
|
|
ebc95274b9 | ||
|
|
3b485b4497 | ||
|
|
10e5ecfe53 | ||
|
|
824d9f6ca8 | ||
|
|
0be62fa2e0 | ||
|
|
5dc4c67344 | ||
|
|
4c140efba8 | ||
|
|
7f3b35191c | ||
|
|
ea94e5dd1c | ||
|
|
b3064a9b7d | ||
|
|
dc599121a0 | ||
|
|
45c0523e55 | ||
|
|
245597c2db | ||
|
|
e87cd8d53c | ||
|
|
edc9ffcb65 | ||
|
|
e3be74e376 | ||
|
|
a8dd34420b | ||
|
|
c84cb5c007 | ||
|
|
a799e41b70 | ||
|
|
4e318cd192 | ||
|
|
323d14845f | ||
|
|
ce425eec8b | ||
|
|
f570a9339d | ||
|
|
dfec551cc4 | ||
|
|
0acbe95797 | ||
|
|
f49ee21136 | ||
|
|
9b3068c15d | ||
|
|
9e796d0627 | ||
|
|
750a56d1fe | ||
|
|
15ea6eecf9 | ||
|
|
5aeb2733a1 | ||
|
|
2c2beb9c1f | ||
|
|
f9263b6fdf | ||
|
|
2966606b1a | ||
|
|
4afe39e461 | ||
|
|
6b92126fd8 | ||
|
|
66732b91c1 | ||
|
|
ecf85a9cfa | ||
|
|
8ecd2d9218 | ||
|
|
4784d1de18 | ||
|
|
22d4e2aa90 | ||
|
|
daa0b76484 | ||
|
|
4da7223831 | ||
|
|
824a84ef2a | ||
|
|
0d6db1613f | ||
|
|
f23952c8ab | ||
|
|
21cef96b5d | ||
|
|
f8c904908a | ||
|
|
b053a1edf1 | ||
|
|
e5f1a400ee | ||
|
|
8bc51fdb5c | ||
|
|
dd2fa1e82d | ||
|
|
6f394e82b5 | ||
|
|
f3e9eb92a9 | ||
|
|
cc2ac99487 | ||
|
|
d96165e3c4 | ||
|
|
60524a1b6c | ||
|
|
9b0c09ebfb | ||
|
|
649e5a156a | ||
|
|
d31efc7984 | ||
|
|
5a52986db0 | ||
|
|
331c7adc08 | ||
|
|
20a6bdf5ec | ||
|
|
459a4c1e55 | ||
|
|
4ef9f9e6d2 | ||
|
|
3d67cdc150 | ||
|
|
366f9268ee | ||
|
|
35868807c1 | ||
|
|
42fc5e9ee7 | ||
|
|
437693e744 | ||
|
|
17d19146de | ||
|
|
52a36fefdc | ||
|
|
b05a44cb2a | ||
|
|
883e16acde | ||
|
|
6184c4e44b | ||
|
|
a33e86630d | ||
|
|
bbcd94e7fa | ||
|
|
7d8c01dbf4 | ||
|
|
bdda3a8ef6 | ||
|
|
a5f1bc0341 | ||
|
|
b4383a5c42 | ||
|
|
6ca731c13b | ||
|
|
39e4d6b3ba | ||
|
|
60a231f16d | ||
|
|
32b952803e | ||
|
|
35948fa55c | ||
|
|
eb67894e0f | ||
|
|
2c81d25c72 | ||
|
|
c574ac6670 | ||
|
|
716b8ede0e | ||
|
|
99b36c7c30 | ||
|
|
c8dacbadc0 | ||
|
|
b273ac38a6 | ||
|
|
986f9aa640 | ||
|
|
c7e5c3f8d8 | ||
|
|
c7b649f792 | ||
|
|
64b42d0431 | ||
|
|
fdcf1f4526 | ||
|
|
36495487a3 | ||
|
|
c00c8c208c | ||
|
|
29720674dc | ||
|
|
c437d8ec38 | ||
|
|
b0ca19c67b | ||
|
|
60dec88882 | ||
|
|
10235aeb66 | ||
|
|
cb80a849e4 | ||
|
|
d11b6d7ffd | ||
|
|
012387396a | ||
|
|
47e4e81053 | ||
|
|
a2fd8ba7c3 | ||
|
|
7c276c6f64 | ||
|
|
a8a7f032ef | ||
|
|
dd919751ac | ||
|
|
ac9bca80c8 | ||
|
|
a50a858c86 | ||
|
|
1da8f04aaa | ||
|
|
9652b7ef80 | ||
|
|
3a0733deb9 | ||
|
|
f59895425e | ||
|
|
3489b43cb8 | ||
|
|
95fdc2c2c5 | ||
|
|
5cb38dc4d7 | ||
|
|
60541437e3 | ||
|
|
95e4707fd1 | ||
|
|
8e9437199c | ||
|
|
ee8d509d39 | ||
|
|
3744e70128 | ||
|
|
194109d677 | ||
|
|
3e4d47c21d | ||
|
|
9d5683dc71 | ||
|
|
f3a422852e | ||
|
|
9833880709 | ||
|
|
da8571beec | ||
|
|
c53e8dbd6c | ||
|
|
d2314d360a | ||
|
|
7093d3aa82 | ||
|
|
5f2e8b8ae4 | ||
|
|
0e444b7843 | ||
|
|
a2853456b6 | ||
|
|
791c6d815d | ||
|
|
46e47e6713 | ||
|
|
1a3a607fcf | ||
|
|
92c3d6d3fd | ||
|
|
6e8f31f406 | ||
|
|
a60852df19 | ||
|
|
fbf2b5734e | ||
|
|
ebaa484294 | ||
|
|
0ebec0b03f | ||
|
|
5c4831af49 | ||
|
|
58ae137945 | ||
|
|
88612bf7ce | ||
|
|
ab95cca434 | ||
|
|
7b9984699c | ||
|
|
60b43104ee | ||
|
|
a206dc1a8f | ||
|
|
c70350e275 | ||
|
|
31bebf0f9e | ||
|
|
c759a7a75f | ||
|
|
626d54a812 | ||
|
|
4d017b4fed | ||
|
|
036cbda2f6 | ||
|
|
1550c60278 | ||
|
|
9d5785cead | ||
|
|
169e526f2f | ||
|
|
ec68acf958 | ||
|
|
5491da9511 | ||
|
|
88686e759e | ||
|
|
5647a902de | ||
|
|
3ca2cb0119 | ||
|
|
cab9047de1 | ||
|
|
42aef79ab3 | ||
|
|
3d09b144f9 | ||
|
|
9d7c524530 | ||
|
|
fa8618879d | ||
|
|
e17f997e75 | ||
|
|
bd442680ea | ||
|
|
4bf716c2ad | ||
|
|
0831d2b0f8 | ||
|
|
92064134d6 | ||
|
|
903cce2745 | ||
|
|
2bfafb3b33 | ||
|
|
354b4b9c54 | ||
|
|
8c2da13096 | ||
|
|
c2b750448e | ||
|
|
c79f170687 | ||
|
|
c29ffb9dd9 | ||
|
|
8cb1dc47d9 | ||
|
|
94e96d325b | ||
|
|
45ee9f814a | ||
|
|
412fe8b8de | ||
|
|
10ee83d680 | ||
|
|
f9ffbe0d6a | ||
|
|
8c1706b66e | ||
|
|
35712dcadc | ||
|
|
396aa16f99 | ||
|
|
5b2480c8ba | ||
|
|
a6e1c40051 | ||
|
|
3c1d45f45f | ||
|
|
22017d085b | ||
|
|
43ef9a2e4f | ||
|
|
ecab2eb473 | ||
|
|
12a55b86ac | ||
|
|
eaa8c8de29 | ||
|
|
cb31e9c2db | ||
|
|
f6e7e5cc76 | ||
|
|
8690edcae4 | ||
|
|
6b5ce3a9f0 | ||
|
|
d362faea3b | ||
|
|
1ebce26881 | ||
|
|
9d259fe315 | ||
|
|
a5545d5bad | ||
|
|
62bda6076b | ||
|
|
b7bdcb19ca | ||
|
|
53721dce03 | ||
|
|
c295060f69 | ||
|
|
3e2c229e97 | ||
|
|
6d0a168d6d | ||
|
|
6195192bcf | ||
|
|
379093f940 | ||
|
|
85fcd0e757 | ||
|
|
827c4b9bda | ||
|
|
7b23fca86e | ||
|
|
1c22b3f751 | ||
|
|
1b8e6facd3 | ||
|
|
e5c8c94cd1 | ||
|
|
39b6fe732f | ||
|
|
fc760c1604 | ||
|
|
58159389b8 | ||
|
|
b49c6508f5 | ||
|
|
6efb726e2b | ||
|
|
48834891ac | ||
|
|
a7d4ee8bfb | ||
|
|
b18f6505dd | ||
|
|
8d44fa913b | ||
|
|
a1efc105d2 | ||
|
|
1033b4c1e7 | ||
|
|
01ee2ada7c | ||
|
|
8ebe19b835 | ||
|
|
b91ab3b334 | ||
|
|
59eaeed6e7 | ||
|
|
288d2a8c6b | ||
|
|
6e74ec2f71 | ||
|
|
a70726e554 | ||
|
|
afe9387578 | ||
|
|
c669d1519d | ||
|
|
a81479adbf | ||
|
|
812d55f843 | ||
|
|
8ebd5852cd | ||
|
|
10e350d47b | ||
|
|
ed82098162 | ||
|
|
df1a999031 | ||
|
|
3b90f8b53c | ||
|
|
5495e0b21a | ||
|
|
7de78d469b | ||
|
|
695e5bbc40 | ||
|
|
28ca5d71ee | ||
|
|
470abf46e2 | ||
|
|
ea244e507c | ||
|
|
063111737c | ||
|
|
bf9cf5340d | ||
|
|
4fb6022113 | ||
|
|
3a3d6500bc | ||
|
|
585e074cda | ||
|
|
345ed97cb7 | ||
|
|
caefd7b85f | ||
|
|
71e625e02c | ||
|
|
14418f74ae | ||
|
|
3fe261f91c | ||
|
|
381ab4e71b | ||
|
|
d2e948600f | ||
|
|
d2dc52bcb0 | ||
|
|
6c23751a4a | ||
|
|
d089923271 | ||
|
|
601f89d4d1 | ||
|
|
f14c9db282 | ||
|
|
b4b6df5b6c | ||
|
|
d130fd13dc | ||
|
|
6ad0be7c6e | ||
|
|
fa3476dd2a | ||
|
|
b58cd5c132 | ||
|
|
1297ed5c1d | ||
|
|
96ecfb30ef | ||
|
|
c5ff3fec39 | ||
|
|
e91db82d26 | ||
|
|
5591ff2a6b | ||
|
|
bce2c2efb4 | ||
|
|
f0fbc8f356 | ||
|
|
249b13a98a | ||
|
|
5c9f9a4de8 | ||
|
|
8d898dafde | ||
|
|
be5966a2ec | ||
|
|
6187861e91 | ||
|
|
f1869cda98 | ||
|
|
960e01cba8 | ||
|
|
4786cfcb5e | ||
|
|
35ef90ac66 | ||
|
|
b923df0c01 | ||
|
|
b61534d260 | ||
|
|
2299e996d2 | ||
|
|
d1856b40f8 | ||
|
|
cbdadc83a1 | ||
|
|
752a862c67 | ||
|
|
e974370cf1 | ||
|
|
12fcdd9bfa | ||
|
|
435d0bc4ab | ||
|
|
615d49ed66 | ||
|
|
a4b9bab1dc | ||
|
|
480e35037b | ||
|
|
2b275ef192 | ||
|
|
96a37ac1ab | ||
|
|
dd851943c0 | ||
|
|
32b4de3ea6 | ||
|
|
20ea0c8d56 | ||
|
|
699eeba9f0 | ||
|
|
1c52657d7d | ||
|
|
67a451ea84 | ||
|
|
8091029329 | ||
|
|
1cb67932f6 | ||
|
|
299cb93147 | ||
|
|
8060cb60a2 | ||
|
|
5775603f49 | ||
|
|
0874c14b2c | ||
|
|
accea6648c | ||
|
|
2ba26f1bb6 | ||
|
|
fb911af2cd | ||
|
|
9d44d3290b | ||
|
|
b3fdaa9792 | ||
|
|
3ccd8dad31 | ||
|
|
a38902b5a7 |
26
.travis.yml
26
.travis.yml
@@ -1,23 +1,27 @@
|
||||
language: ruby
|
||||
cache: bundler
|
||||
before_install:
|
||||
- gem install bundler
|
||||
install:
|
||||
- script/rebund download
|
||||
- travis_retry bundle install --path vendor/bundle
|
||||
rvm:
|
||||
- 2.0.0
|
||||
- 1.9.3
|
||||
- 1.9.2
|
||||
- 1.8.7
|
||||
script: bundle exec rake
|
||||
- 2.1
|
||||
- 2.0
|
||||
- 1.9.3
|
||||
script: script/cibuild
|
||||
after_script:
|
||||
- script/rebund upload
|
||||
notifications:
|
||||
irc:
|
||||
on_success: change
|
||||
on_failure: change
|
||||
channels:
|
||||
- "irc.freenode.org#jekyll"
|
||||
#on_success: change
|
||||
#on_failure: change
|
||||
- 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
|
||||
env:
|
||||
global:
|
||||
- secure: bt5nglPTdsc0N5fB1dOJz2WbM81dGpDuVD8PnhEsxgUfoo6xavhU4+pNrUADlSUqQ1aJrdU+MKW4x+JZ2ZnJS8vOpNzRymuMZSbFaljK4pgFGiKFgBdMKxVikvoYcxKCjLAl7NJZ11W6hUw+JtJScClDZwrJJAQB6I7Isp/LsdM=
|
||||
- secure: Ym8nx7nbfGYGo47my92M+deJykaiMkdZdb615EO51liv/xy/0aQ919Jpfieugc9d3zVnm+zFGPbpv4YzRpsik6OlVBNa4lP+BnQ27ptf5YcLWD8Hksi7845WFLecXMoaTCoYer/TvYZsIWJb2nSDMH9qbfZhnd1YZKuvUpK0rEU=
|
||||
|
||||
@@ -4,11 +4,11 @@ Contribute
|
||||
So you've got an awesome idea to throw into Jekyll. Great! Please keep the
|
||||
following in mind:
|
||||
|
||||
* **Contributions will not be accepted without tests.**
|
||||
* **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](http://github.com/thoughtbot/shoulda/tree/master) and
|
||||
[RR](http://github.com/btakita/rr/tree/master).
|
||||
[Shoulda](https://github.com/thoughtbot/shoulda/tree/master) and
|
||||
[RR](https://github.com/rr/rr).
|
||||
* 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`
|
||||
@@ -53,7 +53,7 @@ Here's the most direct way to get your work merged into the project:
|
||||
* Make sure everything still passes by running `rake`.
|
||||
* 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 mojombo/jekyll and describe what your change
|
||||
* Create a pull request against jekyll/jekyll and describe what your change
|
||||
does and the why you think it should be merged.
|
||||
|
||||
Updating Documentation
|
||||
@@ -63,14 +63,14 @@ We want the Jekyll documentation to be the best it can be. We've
|
||||
open-sourced our docs and we welcome any pull requests if you find it
|
||||
lacking.
|
||||
|
||||
You can find the documentation for jekyllrb.com in the
|
||||
[site](https://github.com/mojombo/jekyll/tree/master/site) directory of
|
||||
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
|
||||
requests directed at another branch will not be accepted.
|
||||
requests directed at another branch will not be accepted.
|
||||
|
||||
The [Jekyll wiki](https://github.com/mojombo/jekyll/wiki) on GitHub
|
||||
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.
|
||||
|
||||
Gotchas
|
||||
@@ -78,7 +78,7 @@ 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.
|
||||
* Try to keep your patch(es) based from the latest commit on mojombo/jekyll.
|
||||
* 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.
|
||||
* Please don't tag your GitHub issue with [fix], [feature], etc. The maintainers
|
||||
|
||||
595
History.markdown
595
History.markdown
@@ -10,6 +10,503 @@
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
## 2.3.0 / 2014-08-10
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Allow Convertibles to be converted by >= 1 converters (#2704)
|
||||
* Allow Sass files to be rendered in Liquid, but never place them in layouts. (#2733)
|
||||
* Add `jekyll help` command (#2707)
|
||||
* Use `.scss` for `site_template` styles. (#2667)
|
||||
* Don't require the `scope` key in front matter defaults (#2659)
|
||||
* No longer set `permalink: pretty` in the `_config.yml` for the site template (#2680)
|
||||
* Rework site template to utilize Sass (#2687)
|
||||
* Notify the user when auto-regeneration is disabled. (#2696)
|
||||
* Allow partial variables in include tag filename argument (#2693)
|
||||
* Move instances of `Time.parse` into a Utils method (#2682)
|
||||
* Ignore subfolders in the `_posts` folder (#2705) REVERTS (#2633)
|
||||
* Front Matter default types should always be pluralized (#2732)
|
||||
* Read in static files into `collection.files` as `StaticFile`s (#2737)
|
||||
* Add `sassify` and `scssify` Liquid filters (#2739)
|
||||
* Replace `classifier` gem with `classifier-reborn` (#2721)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use only the last extname when multiple converters exist (#2722)
|
||||
* Call `#to_liquid` before calling `#to_json` in jsonify filter (#2729)
|
||||
* Use non padded config in `strftime` to avoid parse string twice (#2673)
|
||||
* Replace deprecated Ruby methods with undeprecated ones (#2664)
|
||||
* Catch errors when parsing Post `date` front matter value & produce nice error message (#2649)
|
||||
* Allow static files in Collections (#2615)
|
||||
* Fixed typo in `Deprecator#gracefully_require` error message (#2694)
|
||||
* Remove preemptive loading of the 'classifier' gem. (#2697)
|
||||
* Use case-insensitive checking for the file extensions when loading config files (#2718)
|
||||
* When Reading Documents, Respect `encoding` Option (#2720)
|
||||
* Refactor based on jekyll-watch clean-up. (#2716)
|
||||
* `Document#to_s` should produce just the content of the document (#2731)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Only include lib files in the gem (#2671)
|
||||
* Fix `git diff` command in `proof` script (#2672)
|
||||
* Make default rake task a multitask so tests run in parallel (#2735)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Use Sass and a Docs Collection (#2651)
|
||||
* Add `latest_version.txt` file to the site (#2740)
|
||||
* Be more ambiguous about `page.content`. But more transparent. (#2522)
|
||||
* Streamlining front matter wording (instead of front-matter/frontmatter) (#2674)
|
||||
* Add note that source directory cannot be modified in GitHub Pages (#2669)
|
||||
* Fix links from #2669 to be actual HTML. Whoops. (#2679)
|
||||
* Add link to `jekyll-slim` in list of third-party plugins (#2689)
|
||||
* Add Barry Clark's Smashing Magazine tutorial to resources page (#2688)
|
||||
* Reorganize and update default configuration settings (#2456)
|
||||
* Fixing indentation in the configuration docs about Redcarpet exts (#2717)
|
||||
* Use `null` in YAML instead of `nil` in default config list (#2719)
|
||||
* Fix typo in Continuous Integration docs (#2708)
|
||||
|
||||
## 2.2.0 / 2014-07-29
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Throw a warning if the specified layout does not exist (#2620)
|
||||
* Whitelist Pygments options in safe mode (#2642)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Remove unnecessary `Jekyll::Tags::IncludeTag#blank?` method (#2625)
|
||||
* Categories in the path are ignored (#2633)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Refactoring Errors & Requires of Third-Party stuff (#2591)
|
||||
* Add further tests for categories (#2584)
|
||||
* Proof site with html-proofer on change (#2605)
|
||||
* Fix up bug in #2605 which caused proofing the site not to function (#2608)
|
||||
* Use `bundle exec` in `script/proof` (#2610)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Update Kramdown urls (#2588)
|
||||
* Add `Jekyll::AutolinkEmail` and `Jekyll::GitMetadata` to the list of
|
||||
third-party plugins (#2596)
|
||||
* Fix a bunch of broken links in the site (#2601)
|
||||
* Replace dead links with working links (#2611)
|
||||
* Add jekyll-hook to deployment methods (#2617)
|
||||
* Added kramdown-with-pygments plugin to the list of third-party plugins (#2623)
|
||||
* Update outdated "Extras" page and remove duplicate documentation (#2622)
|
||||
* Add co2 plugin to list of third-party plugins (#2639)
|
||||
* Attempt to clarify the way Sass imports happen (#2642)
|
||||
|
||||
## 2.1.1 / 2014-07-01
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Patch read vulnerabilities for data & confirm none for layouts (#2563)
|
||||
* Update Maruku dependency to allow use of the latest version (#2576)
|
||||
* Remove conditional assignment from document URL to prevent stale urls (#2575)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Add vertical margin to `highlight` to separate code blocks (#2558)
|
||||
* Add `html_pages` to Variables docs (#2567)
|
||||
* Fixed broken link to Permalinks page (#2572)
|
||||
* Update link to Windows installation guide (#2578)
|
||||
|
||||
## 2.1.0 / 2014-06-28
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Bump to the latest Liquid version, 2.6.1 (#2495)
|
||||
* Add support for JSON files in the `_data` directory (#2369)
|
||||
* Allow subclasses to override `EXCERPT_ATTRIBUTES_FOR_LIQUID` (#2408)
|
||||
* Add `Jekyll.env` and `jekyll.environment` (the Liquid var) (#2417)
|
||||
* Use `_config.yaml` or `_config.yml` (`.yml` takes precedence) (#2406)
|
||||
* Override collection url template (#2418)
|
||||
* Allow subdirectories in `_data` (#2395)
|
||||
* Extract Pagination Generator into gem: `jekyll-paginate` (#2455)
|
||||
* Utilize `date_to_rfc822` filter in site template (#2437)
|
||||
* Add categories, last build datetime, and generator to site template
|
||||
feed (#2438)
|
||||
* Configurable, replaceable Logger-compliant logger (#2444)
|
||||
* Extract `gist` tag into a separate gem (#2469)
|
||||
* Add `collection` attribute to `Document#to_liquid` to access the
|
||||
document's collection label. (#2436)
|
||||
* Upgrade listen to `2.7.6 <= x < 3.0.0` (#2492)
|
||||
* Allow configuration of different Twitter and GitHub usernames in site template (#2485)
|
||||
* Bump Pygments to v0.6.0 (#2504)
|
||||
* Front matter defaults for documents in collections (#2419)
|
||||
* Include files with a url which ends in `/` in the `site.html_pages` list (#2524)
|
||||
* Make `highlight` tag use `language-` prefix in CSS class (#2511)
|
||||
* Lookup item property via `item#to_liquid` before `#data` or `#[]` in filters (#2493)
|
||||
* Skip initial build of site on serve with flag (#2477)
|
||||
* Add support for `hl_lines` in `highlight` tag (#2532)
|
||||
* Spike out `--watch` flag into a separate gem (#2550)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Liquid `sort` filter should sort even if one of the values is `nil` (#2345)
|
||||
* Remove padding on `pre code` in the site template CSS (#2383)
|
||||
* Set `log_level` earlier to silence info level configuration output (#2393)
|
||||
* Only list pages which have `title` in site template (#2411)
|
||||
* Accept `Numeric` values for dates, not `Number` values (#2377)
|
||||
* Prevent code from overflowing container in site template (#2429)
|
||||
* Encode URLs in UTF-8 when escaping and unescaping (#2420)
|
||||
* No Layouts or Liquid for Asset Files (#2431)
|
||||
* Allow front matter defaults to set post categories (#2373)
|
||||
* Fix command in subcommand deprecation warning (#2457)
|
||||
* Keep all parent directories of files/dirs in `keep_files` (#2458)
|
||||
* When using RedCarpet and Rouge without Rouge installed, fixed erroneous
|
||||
error which stated that redcarpet was missing, not rouge. (#2464)
|
||||
* Ignore *all* directories and files that merit it on auto-generation (#2459)
|
||||
* Before copying file, explicitly remove the old one (#2535)
|
||||
* Merge file system categories with categories from YAML. (#2531)
|
||||
* Deep merge front matter defaults (#2490)
|
||||
* Ensure exclude and include arrays are arrays of strings (#2542)
|
||||
* Allow collections to have dots in their filenames (#2552)
|
||||
* Collections shouldn't try to read in directories as files (#2552)
|
||||
* Be quiet very quickly. (#2520)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Test Ruby 2.1.2 instead of 2.1.1 (#2374)
|
||||
* Add test for sorting UTF-8 characters (#2384)
|
||||
* Use `https` for GitHub links in documentation (#2470)
|
||||
* Remove coverage reporting with Coveralls (#2494)
|
||||
* Fix a bit of missing TomDoc to `Jekyll::Commands::Build#build` (#2554)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Set `timezone` to `America/Los_Angeles` (#2394)
|
||||
* Improve JavaScript in `anchor_links.html` (#2368)
|
||||
* Remove note on Quickstart page about default markdown converter (#2387)
|
||||
* Remove broken link in extras.md to a Maruku fork (#2401)
|
||||
* Update Font Awesome to v4.1.0. (#2410)
|
||||
* Fix broken link on Installation page to Templates page (#2421)
|
||||
* Prevent table from extending parent width in permalink style table (#2424)
|
||||
* Add collections to info about pagination support (#2389)
|
||||
* Add `jekyll_github_sample` plugin to list of third-party plugins (#2463)
|
||||
* Clarify documentation around front matter defaults and add details
|
||||
about defaults for collections. (#2439)
|
||||
* Add Jekyll Project Version Tag to list of third-party plugins (#2468)
|
||||
* Use `https` for GitHub links across whole site (#2470)
|
||||
* Add StickerMule + Jekyll post (#2476)
|
||||
* Add Jekyll Asset Pipeline Reborn to list of third-party plugins (#2479)
|
||||
* Add link to jekyll-compress-html to list of third-party plugins (#2514)
|
||||
* Add Piwigo Gallery to list of third-party plugins (#2526)
|
||||
* Set `show_drafts` to `false` in default configuration listing (#2536)
|
||||
* Provide an updated link for Windows installation instructions (#2544)
|
||||
* Remove `url` from configuration docs (#2547)
|
||||
* Documentation for Continuous Integration for your Jekyll Site (#2432)
|
||||
|
||||
## 2.0.3 / 2014-05-08
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Properly prefix links in site template with URL or baseurl depending upon
|
||||
need. (#2319)
|
||||
* Update gist tag comments and error message to require username (#2326)
|
||||
* Fix `permalink` setting in site template (#2331)
|
||||
* Don't fail if any of the path objects are nil (#2325)
|
||||
* Instantiate all descendants for converters and generators, not just
|
||||
direct subclasses (#2334)
|
||||
* Replace all instances of `site.name` with `site.title` in site template (#2324)
|
||||
* `Jekyll::Filters#time` now accepts UNIX timestamps in string or number form (#2339)
|
||||
* Use `item_property` for `where` filter so it doesn't break on collections (#2359)
|
||||
* Rescue errors thrown so `--watch` doesn't fail (#2364)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Add missing "as" to assets docs page (#2337)
|
||||
* Update docs to reflect new `baseurl` default (#2341)
|
||||
* Add links to headers who have an ID. (#2342)
|
||||
* Use symbol instead of HTML number in `upgrading.md` (#2351)
|
||||
* Fix link to front matter defaults docs (#2353)
|
||||
* Fix for `History.markdown` in order to fix history page in docs (#2363)
|
||||
|
||||
## 2.0.2 / 2014-05-07
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Correct use of `url` and `baseurl` in the site template. (#2317)
|
||||
* Default `baseurl` to `""` (#2317)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Correct docs for the `gist` plugin so it always includes the username. (#2314)
|
||||
* Clarify new (defaults, `where` filter) features in docs (#2316)
|
||||
|
||||
## 2.0.1 / 2014-05-06
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Require `kramdown` gem instead of `maruku` gem
|
||||
|
||||
## 2.0.0 / 2014-05-06
|
||||
|
||||
### Major Enhancements
|
||||
* Add "Collections" feature (#2199)
|
||||
* Add gem-based plugin whitelist to safe mode (#1657)
|
||||
* Replace the commander command line parser with a more robust
|
||||
solution for our needs called `mercenary` (#1706)
|
||||
* Remove support for Ruby 1.8.x (#1780)
|
||||
* Move to jekyll/jekyll from mojombo/jekyll (#1817)
|
||||
* Allow custom markdown processors (#1872)
|
||||
* Provide support for the Rouge syntax highlighter (#1859)
|
||||
* Provide support for Sass (#1932)
|
||||
* Provide a 300% improvement when generating sites that use
|
||||
`Post#next` or `Post#previous` (#1983)
|
||||
* Provide support for CoffeeScript (#1991)
|
||||
* Replace Maruku with Kramdown as Default Markdown Processor (#1988)
|
||||
* Expose `site.static_files` to Liquid (#2075)
|
||||
* Complete redesign of the template site generated by `jekyll new` (#2050)
|
||||
* Update Listen from 1.x to 2.x (#2097)
|
||||
* Front matter defaults (#2205)
|
||||
* Deprecate `relative_permalinks` configuration option (default to `false`) (#2307)
|
||||
* Exclude files based on prefix as well as `fnmatch?` (#2303)
|
||||
|
||||
### Minor Enhancements
|
||||
* Move the EntryFilter class into the Jekyll module to avoid polluting the
|
||||
global namespace (#1800)
|
||||
* Add `group_by` Liquid filter create lists of items grouped by a common
|
||||
property's value (#1788)
|
||||
* Add support for Maruku's `fenced_code_blocks` option (#1799)
|
||||
* Update Redcarpet dependency to ~> 3.0 (#1815)
|
||||
* Automatically sort all pages by name (#1848)
|
||||
* Better error message when time is not parseable (#1847)
|
||||
* Allow `include` tag variable arguments to use filters (#1841)
|
||||
* `post_url` tag should raise `ArgumentError` for invalid name (#1825)
|
||||
* Bump dependency `mercenary` to `~> 0.2.0` (#1879)
|
||||
* Bump dependency `safe_yaml` to `~> 1.0` (#1886)
|
||||
* Allow sorting of content by custom properties (#1849)
|
||||
* Add `--quiet` flag to silence output during build and serve (#1898)
|
||||
* Add a `where` filter to filter arrays based on a key/value pair
|
||||
(#1875)
|
||||
* Route 404 errors to a custom 404 page in development (#1899)
|
||||
* Excludes are now relative to the site source (#1916)
|
||||
* Bring MIME Types file for `jekyll serve` to complete parity with GH Pages
|
||||
servers (#1993)
|
||||
* Adding Breakpoint to make new site template more responsive (#2038)
|
||||
* Default to using the UTF-8 encoding when reading files. (#2031)
|
||||
* Update Redcarpet dependency to ~> 3.1 (#2044)
|
||||
* Remove support for Ruby 1.9.2 (#2045)
|
||||
* Add `.mkdown` as valid Markdown extension (#2048)
|
||||
* Add `index.xml` to the list of WEBrick directory index files (#2041)
|
||||
* Make the `layouts` config key relative to CWD or to source (#2058)
|
||||
* Update Kramdown to `~> 1.3` (#1894)
|
||||
* Remove unnecessary references to `self` (#2090)
|
||||
* Update to Mercenary v0.3.x (#2085)
|
||||
* Ship Sass support as a separate gem (#2098)
|
||||
* Extract core extensions into a Utils module (#2112)
|
||||
* Refactor CLI & Commands For Greater Happiness (#2143)
|
||||
* Provide useful error when Pygments returns `nil` and error out (#2148)
|
||||
* Add support for unpublished drafts (#2164)
|
||||
* Add `force_polling` option to the `serve` command (#2165)
|
||||
* Clean up the `<head>` in the site template (#2186)
|
||||
* Permit YAML blocks to end with three dots to better conform with the
|
||||
YAML spec (#2110)
|
||||
* Use `File.exist?` instead of deprecated `File.exists?` (#2214)
|
||||
* Require newline after start of YAML Front Matter header (#2211)
|
||||
* Add the ability for pages to be marked as `published: false` (#1492)
|
||||
* 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)
|
||||
* 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)
|
||||
* Take into account missing values in the Liquid sort filter (#2299)
|
||||
|
||||
### Bug Fixes
|
||||
* Don't allow nil entries when loading posts (#1796)
|
||||
* Remove the scrollbar that's always displayed in new sites generated
|
||||
from the site template (#1805)
|
||||
* Add `#path` to required methods in `Jekyll::Convertible` (#1866)
|
||||
* Default Maruku fenced code blocks to ON for 2.0.0-dev (#1831)
|
||||
* Change short opts for host and port for `jekyll docs` to be consistent with
|
||||
other subcommands (#1877)
|
||||
* Fix typos (#1910)
|
||||
* Lock Maruku at 0.7.0 to prevent bugs caused by Maruku 0.7.1 (#1958)
|
||||
* Fixes full path leak to source directory when using include tag (#1951)
|
||||
* Don't generate pages that aren't being published (#1931)
|
||||
* Use `SafeYAML.load` to avoid conflicts with other projects (#1982)
|
||||
* Relative posts should never fail to build (#1976)
|
||||
* Remove executable bits of non executable files (#2056)
|
||||
* `#path` for a draft is now `_drafts` instead of `_posts` (#2042)
|
||||
* Patch a couple show-stopping security vulnerabilities (#1946)
|
||||
* Sanitize paths uniformly, in a Windows-friendly way (#2065, #2109)
|
||||
* Update gem build steps to work correctly on Windows (#2118)
|
||||
* Remove obsolete `normalize_options` method call from `bin/jekyll` (#2121).
|
||||
* Remove `+` characters from Pygments lexer names when adding as a CSS
|
||||
class (#994)
|
||||
* Remove some code that caused Ruby interpreter warnings (#2178)
|
||||
* Only strip the drive name if it begins the string (#2175)
|
||||
* Remove default post with invalid date from site template (#2200)
|
||||
* Fix `Post#url` and `Page#url` escape (#1568)
|
||||
* Strip newlines from the `{% highlight %}` block content (#1823)
|
||||
* Load in `rouge` only when it's been requested as the highlighter (#2189)
|
||||
* Convert input to string before XML escaping (`xml_escape` liquid filter) (#2244)
|
||||
* Modify configuration key for Collections and reset properly. (#2238)
|
||||
* Avoid duplicated output using `highlight` tag (#2264)
|
||||
* Only use Jekyll.logger for output (#2307)
|
||||
* Close the file descriptor in `has_yaml_header?` (#2310)
|
||||
* Add `output` to `Document` liquid output hash (#2309)
|
||||
|
||||
### Development Fixes
|
||||
* Add a link to the site in the README.md file (#1795)
|
||||
* Add in History and site changes from `v1-stable` branch (#1836)
|
||||
* Testing additions on the Excerpt class (#1893)
|
||||
* Fix the `highlight` tag feature (#1859)
|
||||
* Test Jekyll under Ruby 2.1.0 (#1900)
|
||||
* Add script/cibuild for fun and profit (#1912)
|
||||
* Use `Forwardable` for delegation between `Excerpt` and `Post`
|
||||
(#1927)
|
||||
* Rename `read_things` to `read_content` (#1928)
|
||||
* Add `script/branding` script for ASCII art lovin' (#1936)
|
||||
* Update the README to reflect the repo move (#1943)
|
||||
* Add the project vision to the README (#1935)
|
||||
* Speed up Travis CI builds by using Rebund (#1985)
|
||||
* Use Yarp as a Gem proxy for Travis CI (#1984)
|
||||
* Remove Yarp as a Gem proxy for Travis CI (#2004)
|
||||
* Move the reading of layouts into its own class (#2020)
|
||||
* Test Sass import (#2009)
|
||||
* Switch Maruku and Kramdown in lists of Runtime vs. Development dependencies (#2049)
|
||||
* Clean up the gemspec for the project (#2095)
|
||||
* Add Japanese translation of README and CONTRIBUTING docs. (#2081)
|
||||
* Re-align the tables in Cucumber (#2108)
|
||||
* Trim trailing spaces and convert tabs to spaces (#2122)
|
||||
* Fix the failing Travis scenarios due to Cucumber issues (#2155)
|
||||
* Wrap `bundle install` in `travis_retry` to retry when RubyGems fails (#2160)
|
||||
* Refactor tags and categories (#1639)
|
||||
* Extract plugin management into its own class (#2197)
|
||||
* Add missing tests for `Command` (#2216)
|
||||
* Update `rr` link in CONTRIBUTING doc (#2247)
|
||||
* Streamline Cucumber execution of `jekyll` subcommands (#2258)
|
||||
* Refactor `Commands::Serve`. (#2269)
|
||||
* Refactor `highlight` tag (#2154)
|
||||
* Update `Util` hash functions with latest from Rails (#2273)
|
||||
* Workaround for Travis bug (#2290)
|
||||
|
||||
### Site Enhancements
|
||||
* Document Kramdown's GFM parser option (#1791)
|
||||
* Move CSS to includes & update normalize.css to v2.1.3 (#1787)
|
||||
* Minify CSS only in production (#1803)
|
||||
* Fix broken link to installation of Ruby on Mountain Lion blog post on
|
||||
Troubleshooting docs page (#1797)
|
||||
* Fix issues with 1.4.1 release blog post (#1804)
|
||||
* Add note about deploying to OpenShift (#1812)
|
||||
* Collect all Windows-related docs onto one page (#1818)
|
||||
* Fixed typo in datafiles doc page (#1854)
|
||||
* Clarify how to access `site` in docs (#1864)
|
||||
* Add closing `<code>` tag to `context.registers[:site]` note (#1867)
|
||||
* Fix link to @mojombo's site source (#1897)
|
||||
* Add `paginate: nil` to default configuration in docs (#1896)
|
||||
* Add link to our License in the site footer (#1889)
|
||||
* Add a charset note in "Writing Posts" doc page (#1902)
|
||||
* Disallow selection of path and prompt in bash examples
|
||||
* Add jekyll-compass to the plugin list (#1923)
|
||||
* Add note in Posts docs about stripping `<p>` tags from excerpt (#1933)
|
||||
* Add additional info about the new exclude behavior (#1938)
|
||||
* Linkify 'awesome contributors' to point to the contributors graph on
|
||||
GitHub (#1940)
|
||||
* Update `docs/sites.md` link to GitHub Training materials (#1949)
|
||||
* Update `master` with the release info from 1.4.3 (#1947)
|
||||
* Define docs nav in datafile (#1953)
|
||||
* Clarify the docs around the naming convention for posts (#1971)
|
||||
* Add missing `next` and `previous` docs for post layouts and templates (#1970)
|
||||
* Add note to `Writing posts` page about how to strip html from excerpt (#1962)
|
||||
* Add `jekyll-humanize` plugin to plugin list (#1998)
|
||||
* Add `jekyll-font-awesome` plugin to plugin list (#1999)
|
||||
* Add `sublime-jekyll` to list of Editor plugins (#2001)
|
||||
* Add `vim-jekyll` to the list of Editor plugins (#2005)
|
||||
* Fix non-semantic nesting of `p` tags in `news_item` layout (#2013)
|
||||
* Document destination folder cleaning (#2016)
|
||||
* Updated instructions for NearlyFreeSpeech.NET installation (#2015)
|
||||
* Update link to rack-jekyll on "Deployment Methods" page (#2047)
|
||||
* Fix typo in /docs/configuration (#2073)
|
||||
* Fix count in docs for `site.static_files` (#2077)
|
||||
* Update configuration docs to indicate utf-8 is the default for 2.0.0
|
||||
and ASCII for 1.9.3 (#2074)
|
||||
* Add info about unreleased feature to the site (#2061)
|
||||
* Add whitespace to liquid example in GitHub Pages docs (#2084)
|
||||
* Clarify the way Sass and CoffeeScript files are read in and output (#2067)
|
||||
* Add lyche gallery tag plugin link to list of plugins (#2094)
|
||||
* Add Jekyll Pages Directory plugin to list of plugins (#2096)
|
||||
* Update Configuration docs page with new markdown extension (#2102)
|
||||
* Add `jekyll-image-set` to the list of third-party plugins (#2105)
|
||||
* Losslessly compress images (#2128)
|
||||
* Update normalize.css to 3.0.0 (#2126)
|
||||
* Update modernizr to v2.7.1 (#2129)
|
||||
* Add `jekyll-ordinal` to list of third-party plugins (#2150)
|
||||
* Add `jekyll_figure` to list of third-party plugins (#2158)
|
||||
* Clarify the documentation for safe mode (#2163)
|
||||
* Some HTML tidying (#2130)
|
||||
* Remove modernizr and use html5shiv.js directly for IE less than v9 (#2131)
|
||||
* Remove unused images (#2187)
|
||||
* Use `array_to_sentence_string` filter when outputting news item
|
||||
categories (#2191)
|
||||
* Add link to Help repo in primary navigation bar (#2177)
|
||||
* Switch to using an ico file for the shortcut icon (#2193)
|
||||
* Use numbers to specify font weights and only bring in font weights used (#2185)
|
||||
* Add a link to the list of all tz database time zones (#1824)
|
||||
* Clean-up and improve documentation `feed.xml` (#2192)
|
||||
* Remove duplicate entry in list of third-party plugins (#2206)
|
||||
* Reduce the whitespace in the favicon. (#2213)
|
||||
* Add `jekyll-page-collections` to list of third-party plugins (#2215)
|
||||
* Add a cross-reference about `post_url` (#2243)
|
||||
* Add `jekyll-live-tiles` to list of third-party plugins (#2250)
|
||||
* Fixed broken link to GitHub training material site source (#2257)
|
||||
* Update link to help repo, now called `jekyll-help` (#2277)
|
||||
* Fix capitalization of 'Jekyll' on Deployment Methods page (#2291)
|
||||
* Include plugins by sonnym in list of third-party plugins (#2297)
|
||||
* Add deprecated articles keeper filter to list of third-party plugins (#2300)
|
||||
* Simplify and improve our CSS. (#2127)
|
||||
* Use black text color for the mobile navbar (#2306)
|
||||
* Use the built in date filter and `site.time` for the copyright year. (#2305)
|
||||
* Update html5shiv to v3.7.2 (#2304)
|
||||
* Add 2.0.0 release post (#2298)
|
||||
* Add docs for custom markdown processors (#2298)
|
||||
* Add docs for `where` and `group_by` Liquid filters (#2298)
|
||||
* Remove notes in docs for unreleased features (#2309)
|
||||
|
||||
## 1.5.1 / 2014-03-27
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Only strip the drive name if it begins the string (#2176)
|
||||
|
||||
## 1.5.0 / 2014-03-24
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Loosen `safe_yaml` dependency to `~> 1.0` (#2167)
|
||||
* Bump `safe_yaml` dependency to `~> 1.0.0` (#1942)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fix issue where filesystem traversal restriction broke Windows (#2167)
|
||||
* Lock `maruku` at `0.7.0` (#2167)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Lock `cucumber` at `1.3.11` (#2167)
|
||||
|
||||
## 1.4.3 / 2014-01-13
|
||||
|
||||
### Bug Fixes
|
||||
* Patch show-stopping security vulnerabilities (#1944)
|
||||
|
||||
## 1.4.2 / 2013-12-16
|
||||
|
||||
### Bug Fixes
|
||||
* Turn on Maruku fenced code blocks by default (#1830)
|
||||
|
||||
## 1.4.1 / 2013-12-09
|
||||
|
||||
### Bug Fixes
|
||||
* Don't allow nil entries when loading posts (#1796)
|
||||
|
||||
## 1.4.0 / 2013-12-07
|
||||
|
||||
### Major Enhancements
|
||||
@@ -117,7 +614,7 @@
|
||||
* Refactor Site#render (#1638)
|
||||
* Remove duplication in command line options (#1637)
|
||||
* Add tests for all the coderay options (#1543)
|
||||
* Improve some of the cucumber test code (#1493)
|
||||
* Improve some of the Cucumber test code (#1493)
|
||||
* Improve comparisons of timestamps by ignoring the seconds (#1582)
|
||||
|
||||
### Site Enhancements
|
||||
@@ -287,7 +784,7 @@
|
||||
* Latest posts first in non-LSI `related_posts` (#1271)
|
||||
|
||||
### Development Fixes
|
||||
* Merge the theme and layout cucumber steps into one step (#1151)
|
||||
* Merge the theme and layout Cucumber steps into one step (#1151)
|
||||
* Restrict activesupport dependency to pre-4.0.0 to maintain compatibility with `<= 1.9.2`
|
||||
* Include/exclude deprecation handling simplification (#1284)
|
||||
* Convert README to Markdown. (#1267)
|
||||
@@ -317,7 +814,7 @@
|
||||
* Update contributor information (#1192)
|
||||
* Update URL of article about Blogger migration (#1242)
|
||||
* Specify that RedCarpet is the default for new Jekyll sites on Quickstart page (#1247)
|
||||
* Added site.pages to Variables page in docs (#1251)
|
||||
* Added `site.pages` to Variables page in docs (#1251)
|
||||
* Add Youku and Tudou Embed link on Plugins page. (#1250)
|
||||
* Add note that `gist` tag supports private gists. (#1248)
|
||||
* Add `jekyll-timeago` to list of third-party plugins. (#1260)
|
||||
@@ -335,7 +832,7 @@
|
||||
|
||||
### Minor Enhancements
|
||||
* Add support to gist tag for private gists. (#1189)
|
||||
* Fail loudly when MaRuKu errors out (#1190)
|
||||
* Fail loudly when Maruku errors out (#1190)
|
||||
* Move the building of related posts into their own class (#1057)
|
||||
* Removed trailing spaces in several places throughout the code (#1116)
|
||||
* Add a `--force` option to `jekyll new` (#1115)
|
||||
@@ -401,7 +898,7 @@
|
||||
## 1.0.1 / 2013-05-08
|
||||
|
||||
### Minor Enhancements
|
||||
* Do not force use of toc_token when using generate_tok in RDiscount (#1048)
|
||||
* Do not force use of `toc_token` when using `generate_tok` in RDiscount (#1048)
|
||||
* Add newer `language-` class name prefix to code blocks (#1037)
|
||||
* Commander error message now preferred over process abort with incorrect args (#1040)
|
||||
|
||||
@@ -424,15 +921,15 @@
|
||||
## 1.0.0 / 2013-05-06
|
||||
|
||||
### Major Enhancements
|
||||
* Add `jekyll new` subcommand: generate a jekyll scaffold (#764)
|
||||
* Refactored jekyll commands into subcommands: build, serve, and migrate. (#690)
|
||||
* Add `jekyll new` subcommand: generate a Jekyll scaffold (#764)
|
||||
* Refactored Jekyll commands into subcommands: build, serve, and migrate. (#690)
|
||||
* Removed importers/migrators from main project, migrated to jekyll-import sub-gem (#793)
|
||||
* Added ability to render drafts in `_drafts` folder via command line (#833)
|
||||
* Add ordinal date permalink style (/:categories/:year/:y_day/:title.html) (#928)
|
||||
|
||||
### Minor Enhancements
|
||||
* Site template HTML5-ified (#964)
|
||||
* Use post's directory path when matching for the post_url tag (#998)
|
||||
* Use post's directory path when matching for the `post_url` tag (#998)
|
||||
* Loosen dependency on Pygments so it's only required when it's needed (#1015)
|
||||
* Parse strings into Time objects for date-related Liquid filters (#1014)
|
||||
* Tell the user if there is no subcommand specified (#1008)
|
||||
@@ -446,7 +943,7 @@
|
||||
* Expose new attribute to Liquid via `page`: `page.path` (#951)
|
||||
* Accept multiple config files from command line (#945)
|
||||
* Add page variable to liquid custom tags and blocks (#413)
|
||||
* Add paginator.previous_page_path and paginator.next_page_path (#942)
|
||||
* Add `paginator.previous_page_path` and `paginator.next_page_path` (#942)
|
||||
* Backwards compatibility for 'auto' (#821, #934)
|
||||
* Added date_to_rfc822 used on RSS feeds (#892)
|
||||
* Upgrade version of pygments.rb to 0.4.2 (#927)
|
||||
@@ -465,7 +962,7 @@
|
||||
* Relaxed Kramdown version to 0.14 (#808)
|
||||
* Aliased `jekyll server` to `jekyll serve`. (#792)
|
||||
* Updated gem versions for Kramdown, Rake, Shoulda, Cucumber, and RedCarpet. (#744)
|
||||
* Refactored jekyll subcommands into Jekyll::Commands submodule, which now contains them (#768)
|
||||
* Refactored Jekyll subcommands into Jekyll::Commands submodule, which now contains them (#768)
|
||||
* Rescue from import errors in Wordpress.com migrator (#671)
|
||||
* Massively accelerate LSI performance (#664)
|
||||
* Truncate post slugs when importing from Tumblr (#496)
|
||||
@@ -480,10 +977,10 @@
|
||||
* Paginate in subdirectories properly (#1016)
|
||||
* Ensure post and page URLs have a leading slash (#992)
|
||||
* Catch all exceptions, not just StandardError descendents (#1007)
|
||||
* Bullet-proof limit_posts option (#1004)
|
||||
* Bullet-proof `limit_posts` option (#1004)
|
||||
* Read in YAML as UTF-8 to accept non-ASCII chars (#836)
|
||||
* Fix the CLI option `--plugins` to actually accept dirs and files (#993)
|
||||
* Allow 'excerpt' in YAML Front-Matter to override the extracted excerpt (#946)
|
||||
* Allow 'excerpt' in YAML front matter to override the extracted excerpt (#946)
|
||||
* Fix cascade problem with site.baseurl, site.port and site.host. (#935)
|
||||
* Filter out directories with valid post names (#875)
|
||||
* Fix symlinked static files not being correctly built in unsafe mode (#909)
|
||||
@@ -492,10 +989,10 @@
|
||||
* Force usage of older directory_watcher gem as 1.5 is broken (#883)
|
||||
* Ensure all Post categories are downcase (#842, #872)
|
||||
* Force encoding of the rdiscount TOC to UTF8 to avoid conversion errors (#555)
|
||||
* Patch for multibyte URI problem with jekyll serve (#723)
|
||||
* Patch for multibyte URI problem with `jekyll serve` (#723)
|
||||
* Order plugin execution by priority (#864)
|
||||
* Fixed Page#dir and Page#url for edge cases (#536)
|
||||
* Fix broken post_url with posts with a time in their YAML Front-Matter (#831)
|
||||
* Fix broken `post_url` with posts with a time in their YAML front matter (#831)
|
||||
* Look for plugins under the source directory (#654)
|
||||
* Tumblr Migrator: finds `_posts` dir correctly, fixes truncation of long
|
||||
post names (#775)
|
||||
@@ -517,7 +1014,7 @@
|
||||
### Development Fixes
|
||||
* Exclude Cucumber 1.2.4, which causes tests to fail in 1.9.2 (#938)
|
||||
* Added "features:html" rake task for debugging purposes, cleaned up
|
||||
cucumber profiles (#832)
|
||||
Cucumber profiles (#832)
|
||||
* Explicitly require HTTPS rubygems source in Gemfile (#826)
|
||||
* Changed Ruby version for development to 1.9.3-p374 from p362 (#801)
|
||||
* Including a link to the GitHub Ruby style guide in CONTRIBUTING.md (#806)
|
||||
@@ -527,6 +1024,7 @@
|
||||
* Switch to Simplecov for coverage report (#765)
|
||||
|
||||
## 0.12.1 / 2013-02-19
|
||||
|
||||
### Minor Enhancements
|
||||
* Update Kramdown version to 0.14.1 (#744)
|
||||
* Test Enhancements
|
||||
@@ -535,11 +1033,12 @@
|
||||
* Update Redcarpet version to 2.2.2 (#744)
|
||||
|
||||
## 0.12.0 / 2012-12-22
|
||||
|
||||
### Minor Enhancements
|
||||
* Add ability to explicitly specify included files (#261)
|
||||
* Add --default-mimetype option (#279)
|
||||
* Add `--default-mimetype` option (#279)
|
||||
* Allow setting of RedCloth options (#284)
|
||||
* Add post_url Liquid tag for internal post linking (#369)
|
||||
* Add `post_url` Liquid tag for internal post linking (#369)
|
||||
* Allow multiple plugin dirs to be specified (#438)
|
||||
* Inline TOC token support for RDiscount (#333)
|
||||
* Add the option to specify the paginated url format (#342)
|
||||
@@ -549,10 +1048,10 @@
|
||||
* Bug Fixes
|
||||
* Allow some special characters in highlight names
|
||||
* URL escape category names in URL generation (#360)
|
||||
* Fix error with limit_posts (#442)
|
||||
* Fix error with `limit_posts` (#442)
|
||||
* Properly select dotfile during directory scan (#363, #431, #377)
|
||||
* Allow setting of Kramdown smart_quotes (#482)
|
||||
* Ensure front-matter is at start of file (#562)
|
||||
* Allow setting of Kramdown `smart_quotes` (#482)
|
||||
* Ensure front matter is at start of file (#562)
|
||||
|
||||
## 0.11.2 / 2011-12-27
|
||||
* Bug Fixes
|
||||
@@ -564,6 +1063,7 @@
|
||||
* Update dependencies
|
||||
|
||||
## 0.11.0 / 2011-07-10
|
||||
|
||||
### Major Enhancements
|
||||
* Add command line importer functionality (#253)
|
||||
* Add Redcarpet Markdown support (#318)
|
||||
@@ -585,9 +1085,10 @@
|
||||
|
||||
## 0.10.0 / 2010-12-16
|
||||
* Bug Fixes
|
||||
* Add --no-server option.
|
||||
* Add `--no-server` option.
|
||||
|
||||
## 0.9.0 / 2010-12-15
|
||||
|
||||
### Minor Enhancements
|
||||
* Use OptionParser's `[no-]` functionality for better boolean parsing.
|
||||
* Add Drupal migrator (#245)
|
||||
@@ -596,11 +1097,12 @@
|
||||
* Add Marley migrator (#28)
|
||||
|
||||
## 0.8.0 / 2010-11-22
|
||||
|
||||
### Minor Enhancements
|
||||
* Add wordpress.com importer (#207)
|
||||
* Add --limit-posts cli option (#212)
|
||||
* Add uri_escape filter (#234)
|
||||
* Add --base-url cli option (#235)
|
||||
* Add `--limit-posts` cli option (#212)
|
||||
* Add `uri_escape` filter (#234)
|
||||
* Add `--base-url` cli option (#235)
|
||||
* Improve MT migrator (#238)
|
||||
* Add kramdown support (#239)
|
||||
* Bug Fixes
|
||||
@@ -609,6 +1111,7 @@
|
||||
* Prevent `_includes` dir from being a symlink
|
||||
|
||||
## 0.7.0 / 2010-08-24
|
||||
|
||||
### Minor Enhancements
|
||||
* Add support for rdiscount extensions (#173)
|
||||
* Bug Fixes
|
||||
@@ -620,13 +1123,14 @@
|
||||
* Fix Rakefile 'release' task (tag pushing was missing origin)
|
||||
* Ensure that RedCloth is loaded when textilize filter is used (#183)
|
||||
* Expand source, destination, and plugin paths (#180)
|
||||
* Fix page.url to include full relative path (#181)
|
||||
* Fix `page.url` to include full relative path (#181)
|
||||
|
||||
## 0.6.1 / 2010-06-24
|
||||
* Bug Fixes
|
||||
* Fix Markdown Pygments prefix and suffix (#178)
|
||||
|
||||
## 0.6.0 / 2010-06-23
|
||||
|
||||
### Major Enhancements
|
||||
* Proper plugin system (#19, #100)
|
||||
* Add safe mode so unsafe converters/generators can be added
|
||||
@@ -637,9 +1141,9 @@
|
||||
### Minor Enhancements
|
||||
* Inclusion/exclusion of future dated posts (#59)
|
||||
* Generation for a specific time (#59)
|
||||
* Allocate site.time on render not per site_payload invocation (#59)
|
||||
* Allocate `site.time` on render not per site_payload invocation (#59)
|
||||
* Pages now present in the site payload and can be used through the
|
||||
site.pages and site.html_pages variables
|
||||
`site.pages` and `site.html_pages` variables
|
||||
* Generate phase added to site#process and pagination is now a generator
|
||||
* Switch to RakeGem for build/test process
|
||||
* Only regenerate static files when they have changed (#142)
|
||||
@@ -651,9 +1155,10 @@
|
||||
* Fix extension munging when pretty permalinks are enabled (#64)
|
||||
* Stop sorting categories (#33)
|
||||
* Preserve generated attributes over front matter (#119)
|
||||
* Fix source directory binding using Dir.pwd (#75)
|
||||
* Fix source directory binding using `Dir.pwd` (#75)
|
||||
|
||||
## 0.5.7 / 2010-01-12
|
||||
|
||||
### Minor Enhancements
|
||||
* Allow overriding of post date in the front matter (#62, #38)
|
||||
* Bug Fixes
|
||||
@@ -661,13 +1166,13 @@
|
||||
* Empty tags causes error in read_posts (#84)
|
||||
* Fix pagination to adhere to read/render/write paradigm
|
||||
* Test Enhancement
|
||||
* cucumber features no longer use site.posts.first where a better
|
||||
* Cucumber features no longer use site.posts.first where a better
|
||||
alternative is available
|
||||
|
||||
## 0.5.6 / 2010-01-08
|
||||
* Bug Fixes
|
||||
* Require redcloth >= 4.2.1 in tests (#92)
|
||||
* Don't break on triple dashes in yaml frontmatter (#93)
|
||||
* Don't break on triple dashes in yaml front matter (#93)
|
||||
|
||||
### Minor Enhancements
|
||||
* Allow .mkd as markdown extension
|
||||
@@ -702,9 +1207,9 @@
|
||||
* Configuration options set in config.yml are now available through the
|
||||
site payload (@vilcans)
|
||||
* Posts can now have an empty YAML front matter or none at all
|
||||
(@bahuvrihi)
|
||||
(@ bahuvrihi)
|
||||
* Bug Fixes
|
||||
* Fixing Ruby 1.9 issue that requires to_s on the err object
|
||||
* Fixing Ruby 1.9 issue that requires `#to_s` on the err object
|
||||
(@Chrononaut)
|
||||
* Fixes for pagination and ordering posts on the same day (@ujh)
|
||||
* Made pages respect permalinks style and permalinks in yml front matter
|
||||
@@ -714,11 +1219,12 @@
|
||||
* Added trailing slash to pretty permalink style so Apache is happy
|
||||
(@eugenebolshakov)
|
||||
* Bad markdown processor in config fails sooner and with better message
|
||||
(@gcnovus)
|
||||
* Allow CRLFs in yaml frontmatter (@juretta)
|
||||
(@ gcnovus)
|
||||
* Allow CRLFs in yaml front matter (@juretta)
|
||||
* Added Date#xmlschema for Ruby versions < 1.9
|
||||
|
||||
## 0.5.1 / 2009-05-06
|
||||
|
||||
### Major Enhancements
|
||||
* Next/previous posts in site payload (@pantulis, @tomo)
|
||||
* Permalink templating system
|
||||
@@ -733,6 +1239,7 @@
|
||||
* CGI escaped post titles (@Chrononaut)
|
||||
|
||||
## 0.5.0 / 2009-04-07
|
||||
|
||||
### Minor Enhancements
|
||||
* Ability to set post categories via YAML (@qrush)
|
||||
* Ability to set prevent a post from publishing via YAML (@qrush)
|
||||
@@ -751,18 +1258,20 @@
|
||||
* Add Cucumber acceptance test suite (@qrush, @technicalpickles)
|
||||
|
||||
## 0.4.1
|
||||
|
||||
### Minor Enhancements
|
||||
* Changed date format on wordpress converter (zeropadding) (@dysinger)
|
||||
* Bug Fixes
|
||||
* Add jekyll binary as executable to gemspec (@dysinger)
|
||||
* Add Jekyll binary as executable to gemspec (@dysinger)
|
||||
|
||||
## 0.4.0 / 2009-02-03
|
||||
|
||||
### Major Enhancements
|
||||
* Switch to Jeweler for packaging tasks
|
||||
|
||||
### Minor Enhancements
|
||||
* Type importer (@codeslinger)
|
||||
* site.topics accessor (@baz)
|
||||
* `site.topics` accessor (@baz)
|
||||
* Add `array_to_sentence_string` filter (@mchung)
|
||||
* Add a converter for textpattern (@PerfectlyNormal)
|
||||
* Add a working Mephisto / MySQL converter (@ivey)
|
||||
@@ -777,8 +1286,9 @@
|
||||
* Fix site payload available to files (@matrix9180)
|
||||
|
||||
## 0.3.0 / 2008-12-24
|
||||
|
||||
### Major Enhancements
|
||||
* Added --server option to start a simple WEBrick server on destination
|
||||
* Added `--server` option to start a simple WEBrick server on destination
|
||||
directory (@johnreilly and @mchung)
|
||||
|
||||
### Minor Enhancements
|
||||
@@ -797,23 +1307,24 @@
|
||||
## 0.2.1 / 2008-12-15
|
||||
* Major Changes
|
||||
* Use Maruku (pure Ruby) for Markdown by default (@mreid)
|
||||
* Allow use of RDiscount with --rdiscount flag
|
||||
* Allow use of RDiscount with `--rdiscount` flag
|
||||
|
||||
### Minor Enhancements
|
||||
* Don't load directory_watcher unless it's needed (@pjhyett)
|
||||
|
||||
## 0.2.0 / 2008-12-14
|
||||
* Major Changes
|
||||
* related_posts is now found in site.related_posts
|
||||
* related_posts is now found in `site.related_posts`
|
||||
|
||||
## 0.1.6 / 2008-12-13
|
||||
* Major Features
|
||||
* Include files in `_includes` with `{% include x.textile %}`
|
||||
|
||||
## 0.1.5 / 2008-12-12
|
||||
|
||||
### Major Enhancements
|
||||
* Code highlighting with Pygments if --pygments is specified
|
||||
* Disable true LSI by default, enable with --lsi
|
||||
* Code highlighting with Pygments if `--pygments` is specified
|
||||
* Disable true LSI by default, enable with `--lsi`
|
||||
|
||||
### Minor Enhancements
|
||||
* Output informative message if RDiscount is not available (@JackDanger)
|
||||
@@ -832,7 +1343,7 @@
|
||||
* Code hilighting (@vanpelt)
|
||||
* Autobuild
|
||||
* Bug Fixes
|
||||
* Accept both \r\n and \n in YAML header (@vanpelt)
|
||||
* Accept both `\r\n` and `\n` in YAML header (@vanpelt)
|
||||
|
||||
## 0.1.2 / 2008-11-22
|
||||
* Major Features
|
||||
|
||||
4
LICENSE
4
LICENSE
@@ -1,6 +1,6 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2008 Tom Preston-Werner
|
||||
Copyright (c) 2008-2014 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
|
||||
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,56 +1,35 @@
|
||||
# Jekyll
|
||||
# [Jekyll](http://jekyllrb.com/)
|
||||
|
||||
[](http://badge.fury.io/rb/jekyll)
|
||||
[](https://rubygems.org/gems/jekyll)
|
||||
[](https://travis-ci.org/jekyll/jekyll)
|
||||
[](https://codeclimate.com/github/jekyll/jekyll)
|
||||
[](https://gemnasium.com/jekyll/jekyll)
|
||||
|
||||
[](https://travis-ci.org/mojombo/jekyll)
|
||||
[](https://codeclimate.com/github/mojombo/jekyll)
|
||||
[](https://gemnasium.com/mojombo/jekyll)
|
||||
[](https://coveralls.io/r/mojombo/jekyll)
|
||||
By Tom Preston-Werner, Nick Quaranto, Parker Moore, and many [awesome contributors](https://github.com/jekyll/jekyll/graphs/contributors)!
|
||||
|
||||
By Tom Preston-Werner, Nick Quaranto, and many awesome contributors!
|
||||
Jekyll is a simple, blog-aware, static site generator perfect for personal, project, or organization sites. Think of it like a file-based CMS, without all the complexity. Jekyll takes your content, renders Markdown and Liquid templates, and spits out a complete, static website ready to be served by Apache, Nginx or another web server. Jekyll is the engine behind [GitHub Pages](http://pages.github.com), which you can use to host sites right from your GitHub repositories.
|
||||
|
||||
Jekyll is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind [GitHub Pages](http://pages.github.com), which you can use to host your project's page or blog right here from GitHub.
|
||||
## Philosophy
|
||||
|
||||
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.
|
||||
|
||||
## 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](http://wiki.github.com/mojombo/jekyll/sites)
|
||||
* 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.
|
||||
* Have questions? Check out [`#jekyll` on irc.freenode.net](https://botbot.me/freenode/jekyll/).
|
||||
|
||||
## Diving In
|
||||
|
||||
* [Migrate](http://jekyllrb.com/docs/migrations/) from your previous system
|
||||
* [Migrate](http://import.jekyllrb.com/docs/home/) from your previous system
|
||||
* Learn how the [YAML Front Matter](http://jekyllrb.com/docs/frontmatter/) works
|
||||
* Put information on your site with [Variables](http://jekyllrb.com/docs/variables/)
|
||||
* Customize the [Permalinks](http://jekyllrb.com/docs/permalinks/) your posts are generated with
|
||||
* Use the built-in [Liquid Extensions](http://jekyllrb.com/docs/templates/) to make your life easier
|
||||
* Use custom [Plugins](http://jekyllrb.com/docs/plugins/) to generate content specific to your site
|
||||
|
||||
## Runtime Dependencies
|
||||
|
||||
* Commander: Command-line interface constructor (Ruby)
|
||||
* Colorator: Colorizes command line output (Ruby)
|
||||
* Classifier: Generating related posts (Ruby)
|
||||
* Directory Watcher: Auto-regeneration of sites (Ruby)
|
||||
* Liquid: Templating system (Ruby)
|
||||
* Maruku: Default markdown engine (Ruby)
|
||||
* Pygments.rb: Syntax highlighting (Ruby/Python)
|
||||
* RedCarpet: Markdown engine (Ruby)
|
||||
* Safe YAML: YAML Parser built for security (Ruby)
|
||||
|
||||
## Developer Dependencies
|
||||
|
||||
* Kramdown: Markdown-superset converter (Ruby)
|
||||
* Launchy: Cross-platform file launcher (Ruby)
|
||||
* RDiscount: Discount Markdown Processor (Ruby)
|
||||
* RedCloth: Textile support (Ruby)
|
||||
* RedGreen: Nicer test output (Ruby)
|
||||
* RR: Mocking (Ruby)
|
||||
* Shoulda: Test framework (Ruby)
|
||||
* SimpleCov: Coverage framework (Ruby)
|
||||
|
||||
## License
|
||||
|
||||
See [LICENSE](https://github.com/mojombo/jekyll/blob/master/LICENSE).
|
||||
See [LICENSE](https://github.com/jekyll/jekyll/blob/master/LICENSE).
|
||||
|
||||
107
Rakefile
107
Rakefile
@@ -5,6 +5,7 @@ require 'date'
|
||||
require 'yaml'
|
||||
|
||||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
||||
require 'jekyll/version'
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
@@ -13,24 +14,11 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
||||
#############################################################################
|
||||
|
||||
def name
|
||||
@name ||= Dir['*.gemspec'].first.split('.').first
|
||||
@name ||= File.basename(Dir['*.gemspec'].first, ".*")
|
||||
end
|
||||
|
||||
def version
|
||||
line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
|
||||
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
||||
end
|
||||
|
||||
def date
|
||||
Date.today.to_s
|
||||
end
|
||||
|
||||
def file_date
|
||||
Date.today.strftime("%F")
|
||||
end
|
||||
|
||||
def rubyforge_project
|
||||
name
|
||||
Jekyll::VERSION
|
||||
end
|
||||
|
||||
def gemspec_file
|
||||
@@ -41,12 +29,8 @@ def gem_file
|
||||
"#{name}-#{version}.gem"
|
||||
end
|
||||
|
||||
def replace_header(head, header_name)
|
||||
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
||||
end
|
||||
|
||||
def normalize_bullets(markdown)
|
||||
markdown.gsub(/\s{2}\*{1}/, "-")
|
||||
markdown.gsub(/\n\s{2}\*{1}/, "\n-")
|
||||
end
|
||||
|
||||
def linkify_prs(markdown)
|
||||
@@ -69,13 +53,32 @@ def liquid_escape(markdown)
|
||||
markdown.gsub(/(`{[{%].+[}%]}`)/, "{% raw %}\\1{% endraw %}")
|
||||
end
|
||||
|
||||
def custom_release_header_anchors(markdown)
|
||||
header_regexp = /^(\d{1,2})\.(\d{1,2})\.(\d{1,2}) \/ \d{4}-\d{2}-\d{2}/
|
||||
section_regexp = /^### \w+ \w+$/
|
||||
markdown.split(/^##\s/).map do |release_notes|
|
||||
_, major, minor, patch = *release_notes.match(header_regexp)
|
||||
release_notes
|
||||
.gsub(header_regexp, "\\0\n{: #v\\1-\\2-\\3}")
|
||||
.gsub(section_regexp) { |section| "#{section}\n{: ##{sluffigy(section)}-v#{major}-#{minor}-#{patch}}" }
|
||||
end.join("\n## ")
|
||||
end
|
||||
|
||||
def sluffigy(header)
|
||||
header.gsub(/#/, '').strip.downcase.gsub(/\s+/, '-')
|
||||
end
|
||||
|
||||
def remove_head_from_history(markdown)
|
||||
index = markdown =~ /^##\s+\d+\.\d+\.\d+/
|
||||
markdown[index..-1]
|
||||
end
|
||||
|
||||
def converted_history(markdown)
|
||||
remove_head_from_history(liquid_escape(linkify(normalize_bullets(markdown))))
|
||||
remove_head_from_history(
|
||||
custom_release_header_anchors(
|
||||
liquid_escape(
|
||||
linkify(
|
||||
normalize_bullets(markdown)))))
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
@@ -84,14 +87,7 @@ end
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
if RUBY_VERSION > '1.9' && ENV["TRAVIS"] == "true"
|
||||
require 'coveralls/rake/task'
|
||||
Coveralls::RakeTask.new
|
||||
|
||||
task :default => [:test, :features, 'coveralls:push']
|
||||
else
|
||||
task :default => [:test, :features]
|
||||
end
|
||||
multitask :default => [:test, :features]
|
||||
|
||||
require 'rake/testtask'
|
||||
Rake::TestTask.new(:test) do |test|
|
||||
@@ -156,7 +152,7 @@ namespace :site do
|
||||
|
||||
desc "Update normalize.css library to the latest version and minify"
|
||||
task :update_normalize_css do
|
||||
Dir.chdir("site/css") do
|
||||
Dir.chdir("site/_includes/css") do
|
||||
sh 'curl "http://necolas.github.io/normalize.css/latest/normalize.css" -o "normalize.scss"'
|
||||
sh 'sass "normalize.scss":"normalize.css" --style compressed'
|
||||
sh 'rm "normalize.scss"'
|
||||
@@ -164,12 +160,12 @@ namespace :site do
|
||||
end
|
||||
|
||||
desc "Commit the local site to the gh-pages branch and publish to GitHub Pages"
|
||||
task :publish => [:history] do
|
||||
task :publish => [:history, :version_file] do
|
||||
# Ensure the gh-pages dir exists so we can generate into it.
|
||||
puts "Checking for gh-pages dir..."
|
||||
unless File.exist?("./gh-pages")
|
||||
puts "No gh-pages directory found. Run the following commands first:"
|
||||
puts " `git clone git@github.com:mojombo/jekyll gh-pages"
|
||||
puts " `git clone git@github.com:jekyll/jekyll gh-pages"
|
||||
puts " `cd gh-pages"
|
||||
puts " `git checkout gh-pages`"
|
||||
exit(1)
|
||||
@@ -192,7 +188,7 @@ namespace :site do
|
||||
sha = `git log`.match(/[a-z0-9]{40}/)[0]
|
||||
Dir.chdir('gh-pages') do
|
||||
sh "git add ."
|
||||
sh "git commit -m 'Updating to #{sha}.'"
|
||||
sh "git commit --allow-empty -m 'Updating to #{sha}.'"
|
||||
sh "git push origin gh-pages"
|
||||
end
|
||||
puts 'Done.'
|
||||
@@ -208,7 +204,7 @@ namespace :site do
|
||||
"permalink" => "/docs/history/",
|
||||
"prev_section" => "contributing"
|
||||
}
|
||||
Dir.chdir('site/docs/') do
|
||||
Dir.chdir('site/_docs/') do
|
||||
File.open("history.md", "w") do |file|
|
||||
file.write("#{front_matter.to_yaml}---\n\n")
|
||||
file.write(converted_history(history_file))
|
||||
@@ -219,6 +215,11 @@ namespace :site do
|
||||
end
|
||||
end
|
||||
|
||||
desc "Write the site latest_version.txt file"
|
||||
task :version_file do
|
||||
File.open('site/latest_version.txt', 'wb') { |f| f.write(version) }
|
||||
end
|
||||
|
||||
namespace :releases do
|
||||
desc "Create new release post"
|
||||
task :new, :version do |t, args|
|
||||
@@ -233,7 +234,7 @@ namespace :site do
|
||||
post.puts("title: 'Jekyll #{release} Released'")
|
||||
post.puts("date: #{Time.new.strftime('%Y-%m-%d %H:%M:%S %z')}")
|
||||
post.puts("author: ")
|
||||
post.puts("version: #{version}")
|
||||
post.puts("version: #{release}")
|
||||
post.puts("categories: [release]")
|
||||
post.puts("---")
|
||||
post.puts
|
||||
@@ -251,48 +252,22 @@ end
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
desc "Release #{name} v#{version}"
|
||||
task :release => :build do
|
||||
unless `git branch` =~ /^\* master$/
|
||||
puts "You must be on the master branch to release!"
|
||||
exit!
|
||||
end
|
||||
sh "git commit --allow-empty -m 'Release #{version}'"
|
||||
sh "git commit --allow-empty -m 'Release :gem: #{version}'"
|
||||
sh "git tag v#{version}"
|
||||
sh "git push origin master"
|
||||
sh "git push origin v#{version}"
|
||||
sh "gem push pkg/#{name}-#{version}.gem"
|
||||
end
|
||||
|
||||
task :build => :gemspec do
|
||||
sh "mkdir -p pkg"
|
||||
desc "Build #{name} v#{version} into pkg/"
|
||||
task :build do
|
||||
mkdir_p "pkg"
|
||||
sh "gem build #{gemspec_file}"
|
||||
sh "mv #{gem_file} pkg"
|
||||
end
|
||||
|
||||
task :gemspec do
|
||||
# read spec file and split out manifest section
|
||||
spec = File.read(gemspec_file)
|
||||
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
||||
|
||||
# replace name version and date
|
||||
replace_header(head, :name)
|
||||
replace_header(head, :version)
|
||||
replace_header(head, :date)
|
||||
#comment this out if your rubyforge_project has a different name
|
||||
replace_header(head, :rubyforge_project)
|
||||
|
||||
# determine file list from git ls-files
|
||||
files = `git ls-files`.
|
||||
split("\n").
|
||||
sort.
|
||||
reject { |file| file =~ /^\./ }.
|
||||
reject { |file| file =~ /^(rdoc|pkg|coverage)/ }.
|
||||
map { |file| " #{file}" }.
|
||||
join("\n")
|
||||
|
||||
# piece file back together and write
|
||||
manifest = " s.files = %w[\n#{files}\n ]\n"
|
||||
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
||||
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
||||
puts "Updated #{gemspec_file}"
|
||||
end
|
||||
|
||||
164
bin/jekyll
164
bin/jekyll
@@ -3,156 +3,38 @@ STDOUT.sync = true
|
||||
|
||||
$:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
|
||||
|
||||
require 'commander/import'
|
||||
require 'jekyll'
|
||||
require 'mercenary'
|
||||
|
||||
%w[jekyll-import].each do |blessed_gem|
|
||||
begin
|
||||
require blessed_gem
|
||||
rescue LoadError
|
||||
end
|
||||
end
|
||||
|
||||
Jekyll::Deprecator.process(ARGV)
|
||||
|
||||
program :name, 'jekyll'
|
||||
program :version, Jekyll::VERSION
|
||||
program :description, 'Jekyll is a blog-aware, static site generator in Ruby'
|
||||
Mercenary.program(:jekyll) do |p|
|
||||
p.version Jekyll::VERSION
|
||||
p.description 'Jekyll is a blog-aware, static site generator in Ruby'
|
||||
p.syntax 'jekyll <subcommand> [options]'
|
||||
|
||||
default_command :default
|
||||
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)'
|
||||
|
||||
global_option '-s', '--source [DIR]', 'Source directory (defaults to ./)'
|
||||
global_option '-d', '--destination [DIR]', 'Destination directory (defaults to ./_site)'
|
||||
global_option '--safe', 'Safe mode (defaults to false)'
|
||||
global_option '-p', '--plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]', Array, 'Plugins directory (defaults to ./_plugins)'
|
||||
global_option '--layouts DIR', String, 'Layouts directory (defaults to ./_layouts)'
|
||||
Jekyll::Command.subclasses.each { |c| c.init_with_program(p) }
|
||||
|
||||
# Option names don't always directly match the configuration value we'd like.
|
||||
# This method will rename options to match what Jekyll configuration expects.
|
||||
#
|
||||
# options - The Hash of options from Commander.
|
||||
#
|
||||
# Returns the normalized Hash.
|
||||
def normalize_options(options)
|
||||
if drafts_state = options.delete(:drafts)
|
||||
options[:show_drafts] = drafts_state
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
def add_build_options(c)
|
||||
c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
c.option '--future', 'Publishes posts with a future date'
|
||||
c.option '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish'
|
||||
c.option '-w', '--watch', 'Watch for changes and rebuild'
|
||||
c.option '--lsi', 'Use LSI for improved related posts'
|
||||
c.option '-D', '--drafts', 'Render posts in the _drafts folder'
|
||||
c.option '-V', '--verbose', 'Print verbose output.'
|
||||
end
|
||||
|
||||
command :default do |c|
|
||||
c.action do |args, options|
|
||||
p.action do |args, options|
|
||||
if args.empty?
|
||||
command(:help).run
|
||||
puts p
|
||||
else
|
||||
Jekyll.logger.abort_with "Invalid command. Use --help for more information"
|
||||
unless p.has_command?(args.first)
|
||||
Jekyll.logger.abort_with "Invalid command. Use --help for more information"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
command :new do |c|
|
||||
c.syntax = 'jekyll new PATH'
|
||||
c.description = 'Creates a new Jekyll site scaffold in PATH'
|
||||
|
||||
c.option '--force', 'Force creation even if PATH already exists'
|
||||
c.option '--blank', 'Creates scaffolding but with empty files'
|
||||
|
||||
c.action do |args, options|
|
||||
Jekyll::Commands::New.process(args, options.__hash__)
|
||||
end
|
||||
end
|
||||
|
||||
command :build do |c|
|
||||
c.syntax = 'jekyll build [options]'
|
||||
c.description = 'Build your site'
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
c.action do |args, options|
|
||||
options = normalize_options(options.__hash__)
|
||||
options = Jekyll.configuration(options)
|
||||
Jekyll::Commands::Build.process(options)
|
||||
end
|
||||
end
|
||||
|
||||
command :serve do |c|
|
||||
c.syntax = 'jekyll serve [options]'
|
||||
c.description = 'Serve your site locally'
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
c.option '-B', '--detach', 'Run the server in the background (detach)'
|
||||
c.option '-P', '--port [PORT]', 'Port to listen on'
|
||||
c.option '-H', '--host [HOST]', 'Host to bind to'
|
||||
c.option '-b', '--baseurl [URL]', 'Base URL'
|
||||
|
||||
c.action do |args, options|
|
||||
options.default :serving => true
|
||||
|
||||
options = normalize_options(options.__hash__)
|
||||
options = Jekyll.configuration(options)
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
end
|
||||
end
|
||||
alias_command :server, :serve
|
||||
|
||||
command :doctor do |c|
|
||||
c.syntax = 'jekyll doctor'
|
||||
c.description = 'Search site and print specific deprecation warnings'
|
||||
|
||||
c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
|
||||
c.action do |args, options|
|
||||
options = normalize_options(options.__hash__)
|
||||
options = Jekyll.configuration(options)
|
||||
Jekyll::Commands::Doctor.process(options)
|
||||
end
|
||||
end
|
||||
alias_command :hyde, :doctor
|
||||
|
||||
command :docs do |c|
|
||||
c.syntax = 'jekyll docs'
|
||||
c.description = "Launch local server with docs for Jekyll v#{Jekyll::VERSION}"
|
||||
|
||||
c.option '-p', '--port [PORT]', 'Port to listen on'
|
||||
c.option '-u', '--host [HOST]', 'Host to bind to'
|
||||
|
||||
c.action do |args, options|
|
||||
options = normalize_options(options.__hash__)
|
||||
options = Jekyll.configuration(options.merge!({
|
||||
'source' => File.expand_path("../site", File.dirname(__FILE__)),
|
||||
'destination' => File.expand_path("../site/_site", File.dirname(__FILE__))
|
||||
}))
|
||||
puts options
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
end
|
||||
end
|
||||
|
||||
command :import do |c|
|
||||
c.syntax = 'jekyll import <platform> [options]'
|
||||
c.description = 'Import your old blog to Jekyll'
|
||||
|
||||
c.option '--source STRING', 'Source file or URL to migrate from'
|
||||
c.option '--file STRING', 'File to migrate from'
|
||||
c.option '--dbname STRING', 'Database name to migrate from'
|
||||
c.option '--user STRING', 'Username to use when migrating'
|
||||
c.option '--pass STRING', 'Password to use when migrating'
|
||||
c.option '--host STRING', 'Host address to use when migrating'
|
||||
c.option '--prefix STRING', 'Database table prefix to use when migrating'
|
||||
|
||||
c.action do |args, options|
|
||||
begin
|
||||
require 'jekyll-import'
|
||||
rescue LoadError
|
||||
msg = "You must install the 'jekyll-import' gem before continuing.\n"
|
||||
msg += "* Please see the documentation at http://jekyllrb.com/docs/migrations/ for instructions.\n"
|
||||
abort msg
|
||||
end
|
||||
Jekyll::Commands::Import.process(args.first, options)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
default: --format pretty
|
||||
travis: --format progress
|
||||
html_report: --format progress --format html --out=features_report.html
|
||||
93
docs/jp/CONTRIBUTING.jp.markdown
Normal file
93
docs/jp/CONTRIBUTING.jp.markdown
Normal file
@@ -0,0 +1,93 @@
|
||||
コントリビュート
|
||||
==========
|
||||
|
||||
あなたは Jekyll に投じるすばらしいアイディアを持っています。
|
||||
すばらしいことです!次の事柄を心に留めてください。
|
||||
|
||||
* **テストなしではコントリビュートはできません。**
|
||||
* もし、既存の機能への小さな修正やパッチを作成したなら、シンプルなテストを行います。
|
||||
現在のテストスイートの範囲にとどまり、そして
|
||||
[Shoulda](https://github.com/thoughtbot/shoulda/tree/master) や
|
||||
[RR](https://github.com/btakita/rr/tree/master) を使用してください。
|
||||
* もし、それが新しい機能の場合は、必ず新しい
|
||||
[Cucumber](https://github.com/cucumber/cucumber/) の機能を作成し、
|
||||
必要に応じて手順を再利用します。
|
||||
また、あなたがフォークした `site` に
|
||||
急ぎいくつかのドキュメントを用意し、一度マージを行い
|
||||
メイン `site` の jekyllrb.com に転送していただければ幸いです。
|
||||
* あなたのコントリビュートによって Jekyll の振る舞いが変わった場合、ドキュメントを更新すべきです。
|
||||
それは `site/docs` にあります。
|
||||
もし、 docs に情報の誤りがあった場合、遠慮なく追加してください。
|
||||
すばらしいドキュメントはすばらしいプロジェクトを作ります!
|
||||
* Ruby のコードを変更するときは、 [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
||||
に従ってください。
|
||||
* **小さなプルリクエスト** に最善を尽くしてください。
|
||||
簡単に提案された変更はレビューされ、マージされる可能性が高いです。
|
||||
* プルリクエストを送信するとき、プルリクエストのボディを賢明に使用してください。
|
||||
変更されたかどうかの記述、変更の背後にある動機、 [完了したかどうかのタスクリスト](http://git.io/gfm-tasks)
|
||||
もレビュー時間を早めます。
|
||||
|
||||
テストの依存関係
|
||||
-----------------
|
||||
|
||||
テストスイートの実行や gem のビルドのために、
|
||||
Jekyll の依存ツールをインストールする必要があります。
|
||||
Jekyll は Bundler を使用しており、 `bundle` コマンドを実行すると全ての設定が迅速に行われます!
|
||||
|
||||
$ bundle
|
||||
|
||||
はじめる前に、テストを実行し、必ずテストが通ることを
|
||||
確認してください(あなたの環境が適切に設定されているかを確認するために):
|
||||
|
||||
$ bundle exec rake test
|
||||
$ bundle exec rake features
|
||||
|
||||
ワークフロー
|
||||
--------
|
||||
|
||||
これは、あなたの作業がプロジェクトにマージされるもっとも直接的な方法です:
|
||||
|
||||
* プロジェクトをフォークします。
|
||||
* あなたのフォークプロジェクトをクローンします ( `git clone git@github.com:<username>/jekyll.git` )。
|
||||
* トピックブランチを作成し、あなたの変更を含んでください ( `git checkout -b my_awesome_feature` )。
|
||||
* ハックし、テストを追加します。必ずしもこの順番でなくてかまいません
|
||||
* `rake` を実行し、テストが必ず全て通ることを確認してください
|
||||
* 必要に応じて、エラーがないようにコミットを論理的な塊にリベースしてください
|
||||
* ブランチをプッシュしてください ( `git push origin my_awesome_feature` ).
|
||||
* jekyll/jekyll プロジェクトの master ブランチに対してプルリクエストを作成し、
|
||||
あなたの変更内容と、なぜそれをマージすべきかを記述してください
|
||||
|
||||
ドキュメントの更新
|
||||
----------------------
|
||||
|
||||
私たちは Jekyll のドキュメントについて最善を尽くしたいです。
|
||||
私たちはドキュメントをオープンソース化しました、そして
|
||||
あなたが Jekyll に欠けているものを見つけた場合、私たちはプルリクエストを歓迎しています。
|
||||
|
||||
あなたは、 GitHub.com 上の Jekyll リポジトリの [site]({{ site.repository }}/tree/master/site) で
|
||||
jekyllrb.comのドキュメントを見つけることができます。
|
||||
|
||||
全てのドキュメントのプルリクエストは `master` に向けられる必要があります。
|
||||
他のブランチに向けたプルリクエストは受け入れられません。
|
||||
|
||||
GitHub の [Jekyll wiki](https://github.com/jekyll/jekyll/wiki) は、
|
||||
自由に更新することができるように、プルリクエストなしで
|
||||
全ての GitHub ユーザがアクセス権を持つことができます。
|
||||
|
||||
落とし穴
|
||||
-------
|
||||
|
||||
* もし、 gem のバージョンがかちあった場合、コミットを分けてください。
|
||||
この方法だと、メンテナが gem をリリースするときに制御できます。
|
||||
* jekyll/jekyll の最新コミットに基づいて(複数の)パッチを維持してください。
|
||||
それは適用するためのあなたの仕事で、メンテナがしなければならないことを少なくするのは
|
||||
とてもよいことです。
|
||||
* あなたの GitHub issue で [fix], [feature] などのタグをつけないでください。
|
||||
メンテナは積極的に issue を読み、彼らが問題に出くわしたらラベルをつけるでしょう。
|
||||
|
||||
最後に…
|
||||
----------
|
||||
|
||||
ありがとう! Jekyll のハックは楽しいものでなければなりません。
|
||||
もし、あなたがこのハードを理解するための何かを発見した場合、知らせてください。
|
||||
我々のプロセスやドキュメントを改善することができます!
|
||||
68
docs/jp/README.jp.markdown
Normal file
68
docs/jp/README.jp.markdown
Normal file
@@ -0,0 +1,68 @@
|
||||
# [Jekyll](http://jekyllrb.com/)
|
||||
|
||||
[](http://badge.fury.io/rb/jekyll)
|
||||
|
||||
[](https://travis-ci.org/jekyll/jekyll)
|
||||
[](https://codeclimate.com/github/jekyll/jekyll)
|
||||
[](https://gemnasium.com/jekyll/jekyll)
|
||||
|
||||
Tom Preston-Werner, Nick Quaranto や多くの[素晴らしいコントリビュータ](https://github.com/jekyll/jekyll/graphs/contributors)によって作成されています!
|
||||
|
||||
Jekyll は個人プロジェクトや組織のサイトに最適な、シンプルで、ブログを意識した静的サイトジェネレータです。
|
||||
複雑さを排除したファイルベースのCMSのようなものと考えてください。
|
||||
Jekyll はコンテンツを受け取り、 Markdown や Liquid テンプレート をレンダリングし、
|
||||
Apache や Nginx やその他の Web サーバに提供する準備ができた静的な Web サイトを完全に出力してくれます。
|
||||
Jekyll は [GitHub Pages](http://pages.github.com) の背後にあるエンジンなので、
|
||||
あなたの GitHub リポジトリからサイトをホストするために使用する事ができます。
|
||||
|
||||
## 原理
|
||||
|
||||
Jekyll あなたがするように伝えたことをします ― それ以上でもそれ以下でもありません。
|
||||
それは、大胆な仮定によってユーザの裏をかこうとせず、
|
||||
また、不必要な複雑さや設定をユーザに負担しません。
|
||||
簡単に言えば、 Jekyll はあなたの道を開け、
|
||||
真に重要なもの: コンテンツに集中することができます。
|
||||
|
||||
## 開始方法
|
||||
|
||||
* gem を[インストール](http://jekyllrb.com/docs/installation/)します
|
||||
* [使用方法](http://jekyllrb.com/docs/usage/) と [設定方法](http://jekyllrb.com/docs/configuration/) を読みます
|
||||
* 既存の [Jekyll で作られたサイト](https://wiki.github.com/jekyll/jekyll/sites) をチラッと見ます
|
||||
* Fork し、あなたの変更を [コントリビュート](http://jekyllrb.com/docs/contributing/) します
|
||||
* 質問があったら? irc.freenode.net の `#jekyll` チャンネルをチェックしてください
|
||||
|
||||
## より深く
|
||||
|
||||
* 以前のシステムからの[移行](http://jekyllrb.com/docs/migrations/)
|
||||
* [YAML Front Matter](http://jekyllrb.com/docs/frontmatter/) がどのように働くかを学ぶ
|
||||
* [変数](http://jekyllrb.com/docs/variables/)を使ってサイトに情報を表示する
|
||||
* posts が生成される時の[パーマリンク](http://jekyllrb.com/docs/permalinks/)をカスタマイズ
|
||||
* 人生を容易にするために、組み込みの [Liquid 拡張](http://jekyllrb.com/docs/templates/)を使用する
|
||||
* あなたのサイト固有のコンテンツを生成するために、カスタム[プラグイン](http://jekyllrb.com/docs/plugins/)を使用する
|
||||
|
||||
## 実行時の依存関係
|
||||
|
||||
* Commander: コマンドラインインターフェース構築 (Ruby)
|
||||
* Colorator: コマンドライン出力に色付け (Ruby)
|
||||
* Classifier: posts の関連を生成 (Ruby)
|
||||
* Directory Watcher: サイトの自動再生成 (Ruby)
|
||||
* Kramdown: デフォルトの Markdown エンジン (Ruby)
|
||||
* Liquid: テンプレートシステム (Ruby)
|
||||
* Pygments.rb: シンタックスハイライト (Ruby/Python)
|
||||
* RedCarpet: Markdown エンジン (Ruby)
|
||||
* Safe YAML: セキュリティのために構築された YAML パーサ (Ruby)
|
||||
|
||||
## 開発時の依存関係
|
||||
|
||||
* Launchy: クロスプラットフォーム ファイルランチャ (Ruby)
|
||||
* Maruku: Markdown スーパーセット インタプリタ (Ruby)
|
||||
* RDiscount: Discount Markdown プロセッサ (Ruby)
|
||||
* RedCloth: Textile サポート (Ruby)
|
||||
* RedGreen: よりよいテスト出力 (Ruby)
|
||||
* RR: モック (Ruby)
|
||||
* Shoulda: テストフレームワーク (Ruby)
|
||||
* SimpleCov: カバレッジフレームワーク (Ruby)
|
||||
|
||||
## ライセンス
|
||||
|
||||
[ライセンス](https://github.com/jekyll/jekyll/blob/master/LICENSE)を見てください。
|
||||
145
features/collections.feature
Normal file
145
features/collections.feature
Normal file
@@ -0,0 +1,145 @@
|
||||
Feature: Collections
|
||||
As a hacker who likes to structure content
|
||||
I want to be able to create collections of similar information
|
||||
And render them
|
||||
|
||||
Scenario: Unrendered collection
|
||||
Given I have an "index.html" page that contains "Collections: {{ site.methods }}"
|
||||
And I have fixture 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><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 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 fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
methods:
|
||||
output: true
|
||||
foo: bar
|
||||
"""
|
||||
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 "Methods metadata: bar" in "_site/collection_metadata.html"
|
||||
And I should see "<p>Whatever: foo.bar</p>" in "_site/methods/configuration.html"
|
||||
|
||||
Scenario: Rendered collection at a custom URL
|
||||
Given I have an "index.html" page that contains "Collections: {{ site.collections }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
methods:
|
||||
output: true
|
||||
permalink: /:collection/:path/
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "<p>Whatever: foo.bar</p>" in "_site/methods/configuration/index.html"
|
||||
|
||||
Scenario: Rendered document in a layout
|
||||
Given I have an "index.html" page that contains "Collections: {{ site.collections }}"
|
||||
And I have a default layout that contains "<div class='title'>Tom Preston-Werner</div> {{content}}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
methods:
|
||||
output: true
|
||||
foo: bar
|
||||
"""
|
||||
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 "<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"
|
||||
|
||||
Scenario: Collections specified as an array
|
||||
Given I have an "index.html" page that contains "Collections: {% for method in site.methods %}{{ method.relative_path }} {% endfor %}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: _methods/configuration.md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
|
||||
|
||||
Scenario: Collections specified as an hash
|
||||
Given I have an "index.html" page that contains "Collections: {% for method in site.methods %}{{ method.relative_path }} {% endfor %}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: _methods/configuration.md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
|
||||
|
||||
Scenario: All the documents
|
||||
Given I have an "index.html" page that contains "All documents: {% for doc in site.documents %}{{ doc.relative_path }} {% endfor %}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "All documents: _methods/configuration.md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
|
||||
|
||||
Scenario: Documents have an output attribute, which is the converted HTML
|
||||
Given I have an "index.html" page that contains "First document's output: {{ site.documents.first.output }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
- methods
|
||||
"""
|
||||
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"
|
||||
|
||||
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 }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Item count: 1" 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 }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "1. of 5: <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 %}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: Jekyll.configuration, Jekyll.sanitized_path, Site#generate, , Site#generate," in "_site/index.html"
|
||||
@@ -5,23 +5,23 @@ Feature: Create sites
|
||||
|
||||
Scenario: Blank site
|
||||
Given I do not have a "test_blank" directory
|
||||
When I call jekyll new with test_blank --blank
|
||||
When I run jekyll new test_blank --blank
|
||||
Then the test_blank/_layouts directory should exist
|
||||
And the test_blank/_posts directory should exist
|
||||
And the "test_blank/index.html" file should exist
|
||||
|
||||
Scenario: Basic site
|
||||
Given I have an "index.html" file that contains "Basic Site"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Basic Site" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with a post
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| title | date | content |
|
||||
| Hackers | 2009-03-27 | My First Exploit |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "My First Exploit" in "_site/2009/03/27/hackers.html"
|
||||
|
||||
@@ -29,7 +29,7 @@ Feature: Create sites
|
||||
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
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: Basic Site with Layout" in "_site/index.html"
|
||||
|
||||
@@ -37,10 +37,10 @@ Feature: Create sites
|
||||
Given I have a _layouts directory
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| 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
|
||||
When I run jekyll build
|
||||
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"
|
||||
|
||||
@@ -48,10 +48,10 @@ Feature: Create sites
|
||||
Given I have a _layouts directory
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Wargames | 2009-03-27 | post/simple | The only winning move is not to play. |
|
||||
And I have a post/simple layout that contains "Post Layout: {{ content }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
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"
|
||||
|
||||
@@ -66,15 +66,15 @@ Feature: Create sites
|
||||
And I have an "another_file" file that contains ""
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2009-03-27 | post | content for entry1. |
|
||||
| entry2 | 2009-04-27 | post | content for entry2. |
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2009-03-27 | post | content for entry1. |
|
||||
| entry2 | 2009-04-27 | post | content for entry2. |
|
||||
And I have a category/_posts directory
|
||||
And I have the following posts in "category":
|
||||
| title | date | layout | content |
|
||||
| entry3 | 2009-05-27 | post | content for entry3. |
|
||||
| entry4 | 2009-06-27 | post | content for entry4. |
|
||||
When I run jekyll
|
||||
| title | date | layout | content |
|
||||
| entry3 | 2009-05-27 | post | content for entry3. |
|
||||
| entry4 | 2009-06-27 | post | content for entry4. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Page : Site contains 2 pages and 4 posts" in "_site/index.html"
|
||||
And I should see "No replacement \{\{ site.posts.size \}\}" in "_site/about.html"
|
||||
@@ -89,7 +89,7 @@ Feature: Create sites
|
||||
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
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
|
||||
|
||||
@@ -98,7 +98,7 @@ Feature: Create sites
|
||||
And I have an "_includes/about.textile" file that contains "Generated by Jekyll"
|
||||
And I have an info directory
|
||||
And I have an "info/index.html" page that contains "Basic Site with subdir include tag: {% include about.textile %}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Basic Site with subdir include tag: Generated by Jekyll" in "_site/info/index.html"
|
||||
|
||||
@@ -107,7 +107,7 @@ Feature: Create sites
|
||||
And I have an "_includes/about.textile" file that contains "Generated by {% include jekyll.textile %}"
|
||||
And I have an "_includes/jekyll.textile" file that contains "Jekyll"
|
||||
And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
|
||||
|
||||
@@ -116,26 +116,43 @@ Feature: Create sites
|
||||
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. |
|
||||
When I run jekyll
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
| entry2 | 2020-01-31 | 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"
|
||||
|
||||
Scenario: Basic site with whitelisted dotfile
|
||||
Given I have an ".htaccess" file that contains "SomeDirective"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "SomeDirective" in "_site/.htaccess"
|
||||
|
||||
Scenario: File was replaced by a directory
|
||||
Given I have a "test" file that contains "some stuff"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
When I delete the file "test"
|
||||
Given I have a test directory
|
||||
And I have a "test/index.html" file that contains "some other stuff"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site/test directory should exist
|
||||
And I should see "some other stuff" in "_site/test/index.html"
|
||||
|
||||
Scenario: Basic site with unpublished page
|
||||
Given I have an "index.html" page with title "index" that contains "Published page"
|
||||
And I have a "public.html" page with published "true" that contains "Explicitly published page"
|
||||
And I have a "secret.html" page with published "false" that contains "Unpublished page"
|
||||
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the "_site/index.html" file should exist
|
||||
And the "_site/public.html" file should exist
|
||||
But the "_site/secret.html" file should not exist
|
||||
|
||||
When I run jekyll build --unpublished
|
||||
Then the _site directory should exist
|
||||
And the "_site/index.html" file should exist
|
||||
And the "_site/public.html" file should exist
|
||||
And the "_site/secret.html" file should exist
|
||||
|
||||
@@ -13,7 +13,7 @@ Feature: Data
|
||||
price: 2.5
|
||||
"""
|
||||
And I have an "index.html" page that contains "{% for product in site.data.products %}{{product.name}}{% endfor %}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "sugar" in "_site/index.html"
|
||||
And I should see "salt" in "_site/index.html"
|
||||
@@ -28,7 +28,19 @@ Feature: Data
|
||||
age: 34
|
||||
"""
|
||||
And I have an "index.html" page that contains "{% for member in site.data.members %}{{member.name}}{% endfor %}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "Jack" in "_site/index.html"
|
||||
And I should see "Leon" in "_site/index.html"
|
||||
|
||||
Scenario: autoload *.json files in _data directory
|
||||
Given I have a _data directory
|
||||
And I have a "_data/members.json" file with content:
|
||||
"""
|
||||
[{"name": "Jack", "age": 28},{"name": "Leon", "age": 34}]
|
||||
"""
|
||||
And I have an "index.html" page that contains "{% for member in site.data.members %}{{member.name}}{% endfor %}"
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "Jack" in "_site/index.html"
|
||||
And I should see "Leon" in "_site/index.html"
|
||||
@@ -43,11 +55,40 @@ Feature: Data
|
||||
age: 34
|
||||
"""
|
||||
And I have an "index.html" page that contains "{% for member in site.data.team_members %}{{member.name}}{% endfor %}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "Jack" in "_site/index.html"
|
||||
And I should see "Leon" in "_site/index.html"
|
||||
|
||||
Scenario: autoload *.yaml files in subdirectories in _data directory
|
||||
Given I have a _data directory
|
||||
And I have a _data/categories directory
|
||||
And I have a "_data/categories/dairy.yaml" file with content:
|
||||
"""
|
||||
name: Dairy Products
|
||||
"""
|
||||
And I have an "index.html" page that contains "{{ site.data.categories.dairy.name }}"
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "Dairy Products" in "_site/index.html"
|
||||
|
||||
Scenario: folders should have precedence over files with the same name
|
||||
Given I have a _data directory
|
||||
And I have a _data/categories directory
|
||||
And I have a "_data/categories/dairy.yaml" file with content:
|
||||
"""
|
||||
name: Dairy Products
|
||||
"""
|
||||
And I have a "_data/categories.yaml" file with content:
|
||||
"""
|
||||
dairy:
|
||||
name: Should not display this
|
||||
"""
|
||||
And I have an "index.html" page that contains "{{ site.data.categories.dairy.name }}"
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "Dairy Products" in "_site/index.html"
|
||||
|
||||
Scenario: should be backward compatible with site.data in _config.yml
|
||||
Given I have a "_config.yml" file with content:
|
||||
"""
|
||||
@@ -58,8 +99,7 @@ Feature: Data
|
||||
age: 34
|
||||
"""
|
||||
And I have an "index.html" page that contains "{% for member in site.data %}{{member.name}}{% endfor %}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "Jack" in "_site/index.html"
|
||||
And I should see "Leon" in "_site/index.html"
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ Feature: Draft Posts
|
||||
Given I have a configuration file with "permalink" set to "none"
|
||||
And I have a _drafts directory
|
||||
And I have the following draft:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Recipe | 2009-03-27 | default | Not baked yet. |
|
||||
When I run jekyll with drafts
|
||||
When I run jekyll build --drafts
|
||||
Then the _site directory should exist
|
||||
And I should see "Not baked yet." in "_site/recipe.html"
|
||||
|
||||
@@ -18,8 +18,29 @@ Feature: Draft Posts
|
||||
And I have an "index.html" page that contains "Totally index"
|
||||
And I have a _drafts directory
|
||||
And I have the following draft:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Recipe | 2009-03-27 | default | Not baked yet. |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the "_site/recipe.html" file should not exist
|
||||
|
||||
Scenario: Don't preview a draft that is not published
|
||||
Given I have a configuration file with "permalink" set to "none"
|
||||
And I have an "index.html" page that contains "Totally index"
|
||||
And I have a _drafts directory
|
||||
And I have the following draft:
|
||||
| title | date | layout | published | content |
|
||||
| Recipe | 2009-03-27 | default | false | Not baked yet. |
|
||||
When I run jekyll build --drafts
|
||||
Then the _site directory should exist
|
||||
And the "_site/recipe.html" file should not exist
|
||||
|
||||
Scenario: Use page.path variable
|
||||
Given I have a configuration file with "permalink" set to "none"
|
||||
And I have a _drafts directory
|
||||
And I have the following draft:
|
||||
| title | date | layout | content |
|
||||
| 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"
|
||||
|
||||
@@ -7,10 +7,10 @@ Feature: Embed filters
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| 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 "{{ site.time | date_to_xmlschema }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see today's date in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -18,10 +18,12 @@ Feature: Embed filters
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| 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
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Star & Wars" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -29,10 +31,10 @@ Feature: Embed filters
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| 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 }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "7" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -40,10 +42,10 @@ Feature: Embed filters
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | tags | content |
|
||||
| title | date | layout | tags | content |
|
||||
| Star Wars | 2009-03-27 | default | [scifi, movies, force] | These aren't the droids you're looking for. |
|
||||
And I have a default layout that contains "{{ page.tags | array_to_sentence_string }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "scifi, movies, and force" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -51,10 +53,55 @@ Feature: Embed filters
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| 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 }}"
|
||||
When I run jekyll
|
||||
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"
|
||||
|
||||
Scenario: Sort by an arbitrary variable
|
||||
Given I have a _layouts directory
|
||||
And I have the following page:
|
||||
| title | layout | value | content |
|
||||
| Page-1 | default | 8 | Something |
|
||||
And I have the following page:
|
||||
| title | layout | value | content |
|
||||
| Page-2 | default | 6 | Something |
|
||||
And I have a default layout that contains "{{ site.pages | sort:'value' | map:'title' | join:', ' }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see exactly "Page-2, Page-1" in "_site/page-1.html"
|
||||
And I should see exactly "Page-2, Page-1" in "_site/page-2.html"
|
||||
|
||||
Scenario: Sort pages by the title
|
||||
Given I have a _layouts directory
|
||||
And I have the following page:
|
||||
| title | layout | content |
|
||||
| Dog | default | Run |
|
||||
And I have the following page:
|
||||
| title | layout | content |
|
||||
| Bird | default | Fly |
|
||||
And I have the following page:
|
||||
| layout | content |
|
||||
| default | Jump |
|
||||
And I have a default layout that contains "{% assign sorted_pages = site.pages | sort: 'title' %}The rule of {{ sorted_pages.size }}: {% for p in sorted_pages %}{{ p.content | strip_html | strip_newlines }}, {% endfor %}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see exactly "The rule of 3: Jump, Fly, Run," in "_site/bird.html"
|
||||
|
||||
Scenario: Sort pages by the title ordering pages without title last
|
||||
Given I have a _layouts directory
|
||||
And I have the following page:
|
||||
| title | layout | content |
|
||||
| Dog | default | Run |
|
||||
And I have the following page:
|
||||
| title | layout | content |
|
||||
| Bird | default | Fly |
|
||||
And I have the following page:
|
||||
| layout | content |
|
||||
| default | Jump |
|
||||
And I have a default layout that contains "{% assign sorted_pages = site.pages | sort: 'title', 'last' %}The rule of {{ sorted_pages.size }}: {% for p in sorted_pages %}{{ p.content | strip_html | strip_newlines }}, {% endfor %}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see exactly "The rule of 3: Fly, Run, Jump," in "_site/bird.html"
|
||||
|
||||
138
features/frontmatter_defaults.feature
Normal file
138
features/frontmatter_defaults.feature
Normal file
@@ -0,0 +1,138 @@
|
||||
Feature: frontmatter defaults
|
||||
Scenario: Use default for frontmatter variables internally
|
||||
Given I have a _layouts directory
|
||||
And I have a pretty layout that contains "THIS IS THE LAYOUT: {{content}}"
|
||||
|
||||
And I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| default layout | 2013-09-11 | just some post |
|
||||
And I have an "index.html" page with title "some title" that contains "just some page"
|
||||
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: ""}, values: {layout: "pretty"}}]"
|
||||
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "THIS IS THE LAYOUT: <p>just some post</p>" in "_site/2013/09/11/default-layout.html"
|
||||
And I should see "THIS IS THE LAYOUT: just some page" in "_site/index.html"
|
||||
|
||||
Scenario: Use default for frontmatter variables in Liquid
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| default data | 2013-09-11 | <p>{{page.custom}}</p><div>{{page.author}}</div> |
|
||||
And I have an "index.html" page that contains "just {{page.custom}} by {{page.author}}"
|
||||
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 "just some special data by Ben" in "_site/index.html"
|
||||
|
||||
Scenario: Override frontmatter defaults by path
|
||||
Given I have a _layouts directory
|
||||
And I have a root layout that contains "root: {{ content }}"
|
||||
And I have a subfolder layout that contains "subfolder: {{ content }}"
|
||||
|
||||
And I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| about | 2013-10-14 | info on {{page.description}} |
|
||||
And I have a special/_posts directory
|
||||
And I have the following post in "special":
|
||||
| title | date | path | content |
|
||||
| about | 2013-10-14 | local | info on {{page.description}} |
|
||||
|
||||
And I have an "index.html" page with title "overview" that contains "Overview for {{page.description}}"
|
||||
And I have an "special/index.html" page with title "section overview" that contains "Overview for {{page.description}}"
|
||||
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: "special"}, values: {layout: "subfolder", description: "the special section"}}, {scope: {path: ""}, values: {layout: "root", description: "the webpage"}}]"
|
||||
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "root: <p>info on the webpage</p>" in "_site/2013/10/14/about.html"
|
||||
And I should see "subfolder: <p>info on the special section</p>" in "_site/special/2013/10/14/about.html"
|
||||
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: Override frontmatter defaults by type
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| this is a post | 2013-10-14 | blabla |
|
||||
And I have an "index.html" page that contains "interesting stuff"
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: "", type: "post"}, values: {permalink: "/post.html"}}, {scope: {path: "", type: "page"}, values: {permalink: "/page.html"}}, {scope: {path: ""}, values: {permalink: "/perma.html"}}]"
|
||||
When I run jekyll build
|
||||
Then I should see "blabla" in "_site/post.html"
|
||||
And I should see "interesting stuff" in "_site/page.html"
|
||||
But the "_site/perma.html" file should not exist
|
||||
|
||||
Scenario: Actual frontmatter overrides defaults
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | permalink | author | content |
|
||||
| override | 2013-10-14 | /frontmatter.html | some guy | a blog by {{page.author}} |
|
||||
And I have an "index.html" page with permalink "override.html" that contains "nothing"
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: ""}, values: {permalink: "/perma.html", author: "Chris"}}]"
|
||||
When I run jekyll build
|
||||
Then I should see "a blog by some guy" in "_site/frontmatter.html"
|
||||
And I should see "nothing" in "_site/override.html"
|
||||
But the "_site/perma.html" file should not exist
|
||||
|
||||
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:
|
||||
"""
|
||||
---
|
||||
---
|
||||
Value: {{ page.myval }}
|
||||
"""
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
slides:
|
||||
output: true
|
||||
defaults:
|
||||
-
|
||||
scope:
|
||||
path: ""
|
||||
type: slides
|
||||
values:
|
||||
myval: "Test"
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Value: Test" in "_site/slides/slide1.html"
|
||||
|
||||
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:
|
||||
"""
|
||||
---
|
||||
myval: Override
|
||||
---
|
||||
Value: {{ page.myval }}
|
||||
"""
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
slides:
|
||||
output: true
|
||||
defaults:
|
||||
-
|
||||
scope:
|
||||
path: ""
|
||||
type: slides
|
||||
values:
|
||||
myval: "Test"
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Value: Override" in "_site/slides/slide2.html"
|
||||
|
||||
Scenario: Deep merge frontmatter defaults
|
||||
Given I have an "index.html" page with fruit "{orange: 1}" that contains "Fruits: {{ page.fruit.orange | plus: page.fruit.apple }}"
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: ""}, values: {fruit: {apple: 2}}}]"
|
||||
When I run jekyll build
|
||||
Then I should see "Fruits: 3" in "_site/index.html"
|
||||
@@ -10,15 +10,15 @@ Feature: Include tags
|
||||
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 %} |
|
||||
| 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 %} |
|
||||
When I run jekyll
|
||||
| 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 %} |
|
||||
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"
|
||||
And I should not see "myparam" in "_site/2013/03/21/ignore-params-if-unused.html"
|
||||
@@ -43,7 +43,7 @@ Feature: Include tags
|
||||
| include_file1 | snippet.html |
|
||||
| include_file2 | parametrized.html |
|
||||
And I have an "index.html" page that contains "{% include {{site.include_file1}} %} that {% include {{site.include_file2}} what='parameters' %}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "a snippet that works with parameters" in "_site/index.html"
|
||||
|
||||
@@ -52,6 +52,28 @@ Feature: Include tags
|
||||
And I have an "_includes/one.html" file that contains "one"
|
||||
And I have an "_includes/two.html" file that contains "two"
|
||||
And I have an "index.html" page with files "[one.html, two.html]" that contains "{% for file in page.files %}{% include {{file}} %} {% endfor %}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "one two" in "_site/index.html"
|
||||
|
||||
Scenario: Include a file with variables and filters
|
||||
Given I have an _includes directory
|
||||
And I have an "_includes/one.html" file that contains "one included"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| include_file | one |
|
||||
And I have an "index.html" page that contains "{% include {{ site.include_file | append: '.html' }} %}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "one included" in "_site/index.html"
|
||||
|
||||
Scenario: Include a file with partial variables
|
||||
Given I have an _includes directory
|
||||
And I have an "_includes/one.html" file that contains "one included"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| include_file | one |
|
||||
And I have an "index.html" page that contains "{% include {{ site.include_file }}.html %}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "one included" in "_site/index.html"
|
||||
|
||||
@@ -8,23 +8,60 @@ Feature: Markdown
|
||||
And I have an "index.html" page that contains "Index - {% for post in site.posts %} {{ post.content }} {% endfor %}"
|
||||
And I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content | type |
|
||||
| title | date | content | type |
|
||||
| Hackers | 2009-03-27 | # My Title | markdown |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
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/2009/03/27/hackers.html"
|
||||
And I should see "<h1 id=\"my_title\">My Title</h1>" in "_site/index.html"
|
||||
And I should see "<h1 id=\"my-title\">My Title</h1>" in "_site/2009/03/27/hackers.html"
|
||||
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"
|
||||
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:
|
||||
| title | date | content | type |
|
||||
| title | date | content | type |
|
||||
| Hackers | 2009-03-27 | # My Title | markdown |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
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"
|
||||
|
||||
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
|
||||
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"
|
||||
|
||||
@@ -9,12 +9,12 @@ Feature: Site pagination
|
||||
And I have an "index.html" page that contains "{{ paginator.posts.size }}"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Wargames | 2009-03-27 | default | The only winning move is not to play. |
|
||||
| Wargames2 | 2009-04-27 | default | The only winning move is not to play2. |
|
||||
| Wargames3 | 2009-05-27 | default | The only winning move is not to play3. |
|
||||
| Wargames4 | 2009-06-27 | default | The only winning move is not to play4. |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site/page<exist> directory should exist
|
||||
And the "_site/page<exist>/index.html" file should exist
|
||||
And I should see "<posts>" in "_site/page<exist>/index.html"
|
||||
@@ -36,12 +36,12 @@ Feature: Site pagination
|
||||
And I have an "blog/index.html" page that contains "{{ paginator.posts.size }}"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Wargames | 2009-03-27 | default | The only winning move is not to play. |
|
||||
| Wargames2 | 2009-04-27 | default | The only winning move is not to play2. |
|
||||
| Wargames3 | 2009-05-27 | default | The only winning move is not to play3. |
|
||||
| Wargames4 | 2009-06-27 | default | The only winning move is not to play4. |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site/blog/page-<exist> directory should exist
|
||||
And the "_site/blog/page-<exist>/index.html" file should exist
|
||||
And I should see "<posts>" in "_site/blog/page-<exist>/index.html"
|
||||
@@ -69,7 +69,7 @@ Feature: Site pagination
|
||||
| Wargames2 | 2009-04-27 | default | The only winning move is not to play2. |
|
||||
| Wargames3 | 2009-05-27 | default | The only winning move is not to play3. |
|
||||
| Wargames4 | 2009-06-27 | default | The only winning move is not to play4. |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site/blog/page/<exist> directory should exist
|
||||
And the "_site/blog/page/<exist>/index.html" file should exist
|
||||
And I should see "<posts>" in "_site/blog/page/<exist>/index.html"
|
||||
|
||||
@@ -6,20 +6,20 @@ Feature: Fancy permalinks
|
||||
Scenario: Use none permalink schema
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| title | date | content |
|
||||
| None Permalink Schema | 2009-03-27 | Totally nothing. |
|
||||
And I have a configuration file with "permalink" set to "none"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally nothing." in "_site/none-permalink-schema.html"
|
||||
|
||||
Scenario: Use pretty permalink schema
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| title | date | content |
|
||||
| Pretty Permalink Schema | 2009-03-27 | Totally wordpress. |
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally wordpress." in "_site/2009/03/27/pretty-permalink-schema/index.html"
|
||||
|
||||
@@ -28,7 +28,7 @@ Feature: Fancy permalinks
|
||||
And I have an "awesome.html" page that contains "Totally awesome"
|
||||
And I have an "sitemap.xml" page that contains "Totally uhm, sitemap"
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally index" in "_site/index.html"
|
||||
And I should see "Totally awesome" in "_site/awesome/index.html"
|
||||
@@ -37,39 +37,39 @@ Feature: Fancy permalinks
|
||||
Scenario: Use custom permalink schema with prefix
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | category | date | content |
|
||||
| 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"
|
||||
When I run jekyll
|
||||
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"
|
||||
|
||||
Scenario: Use custom permalink schema with category
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | category | date | content |
|
||||
| title | category | date | content |
|
||||
| Custom Permalink Schema | stuff | 2009-03-27 | Totally custom. |
|
||||
And I have a configuration file with "permalink" set to "/:categories/:title.html"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally custom." in "_site/stuff/custom-permalink-schema.html"
|
||||
|
||||
Scenario: Use custom permalink schema with squished date
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | category | date | content |
|
||||
| title | category | date | content |
|
||||
| Custom Permalink Schema | stuff | 2009-03-27 | Totally custom. |
|
||||
And I have a configuration file with "permalink" set to "/:month-:day-:year/:title.html"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-schema.html"
|
||||
|
||||
Scenario: Use per-post permalink
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | permalink | content |
|
||||
| title | date | permalink | content |
|
||||
| Some post | 2013-04-14 | /custom/posts/1 | bla bla |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the _site/custom/posts/1 directory should exist
|
||||
And I should see "bla bla" in "_site/custom/posts/1/index.html"
|
||||
@@ -77,9 +77,9 @@ Feature: Fancy permalinks
|
||||
Scenario: Use per-post ending in .html
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | permalink | content |
|
||||
| title | date | permalink | content |
|
||||
| Some post | 2013-04-14 | /custom/posts/some.html | bla bla |
|
||||
When I run jekyll
|
||||
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.html"
|
||||
|
||||
@@ -7,10 +7,10 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post title: {{ page.title }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post title: Star Wars" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -18,10 +18,10 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post url: {{ page.url }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post url: /2009/03/27/star-wars.html" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -29,10 +29,10 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post date: {{ page.date | date_to_string }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post date: 27 Mar 2009" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -40,10 +40,10 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post id: {{ page.id }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post id: /2009/03/27/star-wars" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -51,10 +51,10 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post content: {{ content }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post content: <p>Luke, I am your father.</p>" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -63,10 +63,46 @@ Feature: Post data
|
||||
And I have a movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "movies":
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll
|
||||
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 category is in a folder and has category in YAML
|
||||
Given I have a movies directory
|
||||
And I have a movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "movies":
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 2009-03-27 | simple | film | Luke, I am your father. |
|
||||
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/film/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when category is in a folder and has categories in YAML
|
||||
Given I have a movies directory
|
||||
And I have a movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "movies":
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 2009-03-27 | simple | [film, scifi] | Luke, I am your father. |
|
||||
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/film/scifi/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when category is in a folder and duplicated category is in YAML
|
||||
Given I have a movies directory
|
||||
And I have a movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "movies":
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 2009-03-27 | simple | movies | Luke, I am your father. |
|
||||
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"
|
||||
|
||||
@@ -74,10 +110,10 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | tag | content |
|
||||
| title | date | layout | tag | content |
|
||||
| Star Wars | 2009-05-18 | simple | twist | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post tags: {{ page.tags }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post tags: twist" in "_site/2009/05/18/star-wars.html"
|
||||
|
||||
@@ -87,10 +123,10 @@ Feature: Post data
|
||||
And I have a scifi/movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "scifi/movies":
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
|
||||
When I run jekyll
|
||||
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"
|
||||
|
||||
@@ -100,10 +136,10 @@ Feature: Post data
|
||||
And I have a scifi/Movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "scifi/Movies":
|
||||
| title | date | layout | content |
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 2009-03-27 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
|
||||
When I run jekyll
|
||||
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"
|
||||
|
||||
@@ -111,10 +147,10 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | category | content |
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 2009-03-27 | simple | movies | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll
|
||||
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"
|
||||
|
||||
@@ -122,21 +158,32 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | category | content |
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 2009-03-27 | simple | Movies | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll
|
||||
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 category is in YAML
|
||||
Scenario: Use post.categories variable when categories are in YAML
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 2009-03-27 | simple | movies | Luke, I am your father. |
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 2009-03-27 | simple | ['scifi', 'movies'] | Luke, I am your father. |
|
||||
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"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in YAML and are duplicated
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 2009-03-27 | simple | ['movies', 'movies'] | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll
|
||||
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"
|
||||
|
||||
@@ -144,11 +191,11 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | categories | content |
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 2009-03-27 | simple | ['scifi', 'Movies'] | Luke, I am your father. |
|
||||
| Star Trek | 2013-03-17 | simple | ['SciFi', 'movies'] | Jean Luc, I am your father. |
|
||||
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
|
||||
When I run jekyll
|
||||
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"
|
||||
@@ -156,24 +203,24 @@ Feature: Post data
|
||||
Scenario Outline: Use page.path variable
|
||||
Given I have a <dir>/_posts directory
|
||||
And I have the following post in "<dir>":
|
||||
| title | type | date | content |
|
||||
| title | type | date | content |
|
||||
| my-post | html | 2013-04-12 | Source path: {{ page.path }} |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Source path: <path_prefix>_posts/2013-04-12-my-post.html" in "_site/<dir>/2013/04/12/my-post.html"
|
||||
|
||||
Examples:
|
||||
| dir | path_prefix |
|
||||
| . | |
|
||||
| dir | dir/ |
|
||||
| dir | path_prefix |
|
||||
| . | |
|
||||
| dir | dir/ |
|
||||
| dir/nested | dir/nested/ |
|
||||
|
||||
Scenario: Override page.path variable
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | path | content |
|
||||
| title | date | path | content |
|
||||
| override | 2013-04-12 | override-path.html | Custom path: {{ page.path }} |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Custom path: override-path.html" in "_site/2013/04/12/override.html"
|
||||
|
||||
@@ -181,9 +228,9 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have an "index.html" file that contains "Published!"
|
||||
And I have the following post:
|
||||
| title | date | layout | published | content |
|
||||
| title | date | layout | published | content |
|
||||
| Star Wars | 2009-03-27 | simple | false | Luke, I am your father. |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the "_site/2009/03/27/star-wars.html" file should not exist
|
||||
And I should see "Published!" in "_site/index.html"
|
||||
@@ -192,10 +239,10 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | author | content |
|
||||
| title | date | layout | author | content |
|
||||
| Star Wars | 2009-03-27 | simple | Darth Vader | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post author: {{ page.author }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post author: Darth Vader" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
@@ -203,12 +250,12 @@ Feature: Post data
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | author | content |
|
||||
| title | date | layout | author | content |
|
||||
| Star Wars | 2009-03-27 | ordered | Darth Vader | Luke, I am your father. |
|
||||
| Some like it hot | 2009-04-27 | ordered | Osgood | Nobody is perfect. |
|
||||
| Terminator | 2009-05-27 | ordered | Arnold | Sayonara, baby |
|
||||
And I have a ordered layout that contains "Previous post: {{ page.previous.title }} and next post: {{ page.next.title }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "next post: Some like it hot" in "_site/2009/03/27/star-wars.html"
|
||||
And I should see "Previous post: Some like it hot" in "_site/2009/05/27/terminator.html"
|
||||
|
||||
@@ -9,9 +9,9 @@ Feature: Post excerpts
|
||||
Given I have an "index.html" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see exactly "<p>content for entry1.</p>" in "_site/index.html"
|
||||
|
||||
@@ -21,9 +21,9 @@ Feature: Post excerpts
|
||||
And I have a _layouts directory
|
||||
And I have a post layout that contains "{{ page.excerpt }}"
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the _site/2007 directory should exist
|
||||
And the _site/2007/12 directory should exist
|
||||
@@ -38,9 +38,9 @@ Feature: Post excerpts
|
||||
And I have a _layouts directory
|
||||
And I have a post layout that contains "<html><head></head><body>{{ page.excerpt }}</body></html>"
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the _site/2007 directory should exist
|
||||
And the _site/2007/12 directory should exist
|
||||
|
||||
34
features/rendering.feature
Normal file
34
features/rendering.feature
Normal file
@@ -0,0 +1,34 @@
|
||||
Feature: Rendering
|
||||
As a hacker who likes to blog
|
||||
I want to be able to make a static site
|
||||
In order to share my awesome ideas with the interwebs
|
||||
But I want to make it as simply as possible
|
||||
So render with Liquid and place in Layouts
|
||||
|
||||
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!"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Hi there, Jekyll development!\nAhoy, indeed" in "_site/index.html"
|
||||
|
||||
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 simple layout that contains "{{ content }}Ahoy, indeed!"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should not see "Ahoy, indeed!" in "_site/index.css"
|
||||
And I should not see "Ahoy, indeed!" in "_site/index.js"
|
||||
|
||||
Scenario: Don't render liquid in Sass
|
||||
Given I have an "index.scss" page that contains ".foo-bar { color:{{site.color}}; }"
|
||||
When I run jekyll build
|
||||
Then the _site directory should not exist
|
||||
And I should see "Invalid CSS after" in the build output
|
||||
|
||||
Scenario: Don't render liquid in CoffeeScript
|
||||
Given I have an "index.coffee" page that contains "hey='for {{site.animal}}'"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "hey = 'for {{site.animal}}';" in "_site/index.js"
|
||||
@@ -7,14 +7,14 @@ Feature: Site configuration
|
||||
Given I have a blank site in "_sourcedir"
|
||||
And I have an "_sourcedir/index.html" file that contains "Changing source directory"
|
||||
And I have a configuration file with "source" set to "_sourcedir"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Changing source directory" in "_site/index.html"
|
||||
|
||||
Scenario: Change destination directory
|
||||
Given I have an "index.html" file that contains "Changing destination directory"
|
||||
And I have a configuration file with "destination" set to "_mysite"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _mysite directory should exist
|
||||
And I should see "Changing destination directory" in "_mysite/index.html"
|
||||
|
||||
@@ -25,7 +25,7 @@ Feature: Site configuration
|
||||
| key | value |
|
||||
| source | <source> |
|
||||
| destination | <dest> |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the <source> directory should exist
|
||||
And the "<dest>/index.html" file should <file_exist> exist
|
||||
And I should see "markdown" in "<source>/index.md"
|
||||
@@ -44,7 +44,7 @@ Feature: Site configuration
|
||||
And I have an "README" file that contains "I want to be excluded"
|
||||
And I have an "index.html" file that contains "I want to be included"
|
||||
And I have a configuration file with "exclude" set to "['Rakefile', 'README']"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then I should see "I want to be included" in "_site/index.html"
|
||||
And the "_site/Rakefile" file should not exist
|
||||
And the "_site/README" file should not exist
|
||||
@@ -57,7 +57,7 @@ Feature: Site configuration
|
||||
| value |
|
||||
| README |
|
||||
| Rakefile |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then I should see "I want to be included" in "_site/index.html"
|
||||
And the "_site/Rakefile" file should not exist
|
||||
And the "_site/README" file should not exist
|
||||
@@ -65,37 +65,54 @@ Feature: Site configuration
|
||||
Scenario: Use RDiscount 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 "rdiscount"
|
||||
When I run jekyll
|
||||
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: Use Kramdown 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 "kramdown"
|
||||
When I run jekyll
|
||||
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: Use Redcarpet 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 "redcarpet"
|
||||
When I run jekyll
|
||||
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: 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
|
||||
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" file that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
|
||||
And I have a configuration file with "pygments" set to "true"
|
||||
When I run jekyll
|
||||
Given I have an "index.html" page that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "puts 'Hello world!'" in "_site/index.html"
|
||||
And I should see "Hello world!" in "_site/index.html"
|
||||
And I should see "class=\"highlight\"" in "_site/index.html"
|
||||
|
||||
Scenario: Highlight code with rouge
|
||||
Given I have an "index.html" page that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
|
||||
And I have a configuration file with "highlighter" set to "rouge"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Hello world!" in "_site/index.html"
|
||||
And I should see "class=\"highlight\"" in "_site/index.html"
|
||||
|
||||
Scenario: Rouge renders code block once
|
||||
Given I have a configuration file with "highlighter" set to "rouge"
|
||||
And I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| foo | 2014-04-27 11:34 | default | {% highlight text %} test {% endhighlight %} |
|
||||
When I run jekyll build
|
||||
Then I should not see "highlight(.*)highlight" in "_site/2014/04/27/foo.html"
|
||||
|
||||
Scenario: Set time and no future dated posts
|
||||
Given I have a _layouts directory
|
||||
@@ -108,10 +125,10 @@ Feature: Site configuration
|
||||
| future | false |
|
||||
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. |
|
||||
When I run jekyll
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
| entry2 | 2020-01-31 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: 1 on 2010-01-01" in "_site/index.html"
|
||||
And I should see "Post Layout: <p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
|
||||
@@ -128,10 +145,10 @@ Feature: Site configuration
|
||||
| future | true |
|
||||
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. |
|
||||
When I run jekyll
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
| entry2 | 2020-01-31 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: 2 on 2010-01-01" in "_site/index.html"
|
||||
And I should see "Post Layout: <p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
|
||||
@@ -150,7 +167,7 @@ Feature: Site configuration
|
||||
| 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. |
|
||||
When I run jekyll
|
||||
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"
|
||||
@@ -169,7 +186,7 @@ Feature: Site configuration
|
||||
| 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. |
|
||||
When I run jekyll
|
||||
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
|
||||
@@ -183,11 +200,11 @@ Feature: Site configuration
|
||||
| key | value |
|
||||
| limit_posts | 2 |
|
||||
And I have the following posts:
|
||||
| title | date | content |
|
||||
| Apples | 2009-03-27 | An article about apples |
|
||||
| Oranges | 2009-04-01 | An article about oranges |
|
||||
| Bananas | 2009-04-05 | An article about bananas |
|
||||
When I run jekyll
|
||||
| title | date | content |
|
||||
| Apples | 2009-03-27 | An article about apples |
|
||||
| Oranges | 2009-04-01 | An article about oranges |
|
||||
| Bananas | 2009-04-05 | An article about bananas |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the "_site/2009/04/05/bananas.html" file should exist
|
||||
And the "_site/2009/04/01/oranges.html" file should exist
|
||||
@@ -200,7 +217,7 @@ Feature: Site configuration
|
||||
| value |
|
||||
| .gitignore |
|
||||
| .foo |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see ".DS_Store" in "_site/.gitignore"
|
||||
And the "_site/.htaccess" file should not exist
|
||||
@@ -217,10 +234,10 @@ Feature: Site configuration
|
||||
| layouts | _theme |
|
||||
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. |
|
||||
When I run jekyll
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
| entry2 | 2020-01-31 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: 2 on 2010-01-01" in "_site/index.html"
|
||||
And I should see "Post Layout: <p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
|
||||
@@ -229,7 +246,38 @@ Feature: Site configuration
|
||||
Scenario: Add a gem-based plugin
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with "gems" set to "[jekyll_test_plugin]"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And I should see "this is a test" in "_site/test.txt"
|
||||
|
||||
Scenario: Add an empty whitelist to restrict all gems
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| gems | [jekyll_test_plugin] |
|
||||
| whitelist | [] |
|
||||
When I run jekyll build --safe
|
||||
Then the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And the "_site/test.txt" file should not exist
|
||||
|
||||
Scenario: Add a whitelist to restrict some gems but allow others
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| gems | [jekyll_test_plugin, jekyll_test_plugin_malicious] |
|
||||
| whitelist | [jekyll_test_plugin] |
|
||||
When I run jekyll build --safe
|
||||
Then the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And the "_site/test.txt" file should exist
|
||||
And I should see "this is a test" in "_site/test.txt"
|
||||
|
||||
Scenario: arbitrary file reads via layouts
|
||||
Given I have an "index.html" page with layout "page" that contains "FOO"
|
||||
And I have a "_config.yml" file that contains "layouts: '../../../../../../../../../../../../../../usr/include'"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "FOO" in "_site/index.html"
|
||||
And I should not see " " in "_site/index.html"
|
||||
|
||||
@@ -5,32 +5,32 @@ Feature: Site data
|
||||
|
||||
Scenario: Use page variable in a page
|
||||
Given I have an "contact.html" page with title "Contact" that contains "{{ page.title }}: email@example.com"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Contact: email@example.com" in "_site/contact.html"
|
||||
|
||||
Scenario Outline: Use page.path variable in a page
|
||||
Given I have a <dir> directory
|
||||
And I have a "<path>" page that contains "Source path: {{ page.path }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Source path: <path>" in "_site/<path>"
|
||||
|
||||
Examples:
|
||||
| dir | path |
|
||||
| . | index.html |
|
||||
| dir | dir/about.html |
|
||||
| dir | path |
|
||||
| . | index.html |
|
||||
| dir | dir/about.html |
|
||||
| dir/nested | dir/nested/page.html |
|
||||
|
||||
Scenario: Override page.path
|
||||
Given I have an "override.html" page with path "custom-override.html" that contains "Custom path: {{ page.path }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Custom path: custom-override.html" in "_site/override.html"
|
||||
|
||||
Scenario: Use site.time variable
|
||||
Given I have an "index.html" page that contains "{{ site.time }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see today's time in "_site/index.html"
|
||||
|
||||
@@ -38,11 +38,11 @@ Feature: Site data
|
||||
Given I have a _posts directory
|
||||
And I have an "index.html" page that contains "{{ site.posts.first.title }}: {{ site.posts.first.url }}"
|
||||
And I have the following posts:
|
||||
| title | date | content |
|
||||
| First Post | 2009-03-25 | My First Post |
|
||||
| Second Post | 2009-03-26 | My Second Post |
|
||||
| Third Post | 2009-03-27 | My Third Post |
|
||||
When I run jekyll
|
||||
| title | date | content |
|
||||
| First Post | 2009-03-25 | My First Post |
|
||||
| Second Post | 2009-03-26 | My Second Post |
|
||||
| Third Post | 2009-03-27 | My Third Post |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Third Post: /2009/03/27/third-post.html" in "_site/index.html"
|
||||
|
||||
@@ -50,11 +50,11 @@ Feature: Site data
|
||||
Given I have a _posts directory
|
||||
And I have an "index.html" page that contains "{% for post in site.posts %} {{ post.title }} {% endfor %}"
|
||||
And I have the following posts:
|
||||
| title | date | content |
|
||||
| First Post | 2009-03-25 | My First Post |
|
||||
| Second Post | 2009-03-26 | My Second Post |
|
||||
| Third Post | 2009-03-27 | My Third Post |
|
||||
When I run jekyll
|
||||
| title | date | content |
|
||||
| First Post | 2009-03-25 | My First Post |
|
||||
| Second Post | 2009-03-26 | My Second Post |
|
||||
| Third Post | 2009-03-27 | My Third Post |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Third Post Second Post First Post" in "_site/index.html"
|
||||
|
||||
@@ -62,10 +62,10 @@ Feature: Site data
|
||||
Given I have a _posts directory
|
||||
And I have an "index.html" page that contains "{% for post in site.categories.code %} {{ post.title }} {% endfor %}"
|
||||
And I have the following posts:
|
||||
| title | date | category | content |
|
||||
| title | date | category | content |
|
||||
| Awesome Hack | 2009-03-26 | code | puts 'Hello World' |
|
||||
| Delicious Beer | 2009-03-26 | food | 1) Yuengling |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Awesome Hack" in "_site/index.html"
|
||||
|
||||
@@ -73,9 +73,9 @@ Feature: Site data
|
||||
Given I have a _posts directory
|
||||
And I have an "index.html" page that contains "{% for post in site.tags.beer %} {{ post.content }} {% endfor %}"
|
||||
And I have the following posts:
|
||||
| title | date | tag | content |
|
||||
| Delicious Beer | 2009-03-26 | beer | 1) Yuengling |
|
||||
When I run jekyll
|
||||
| title | date | tag | content |
|
||||
| Delicious Beer | 2009-03-26 | beer | 1) Yuengling |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Yuengling" in "_site/index.html"
|
||||
|
||||
@@ -83,25 +83,25 @@ Feature: Site data
|
||||
Given I have a _posts directory
|
||||
And I have an "index.html" page that contains "{% for post in site.posts %}{{ post.title }}:{{ post.previous.title}},{{ post.next.title}} {% endfor %}"
|
||||
And I have the following posts:
|
||||
| title | date | content |
|
||||
| title | date | content |
|
||||
| first | 2009-02-26 | first |
|
||||
| A | 2009-03-26 | A |
|
||||
| B | 2009-03-26 | B |
|
||||
| C | 2009-03-26 | C |
|
||||
| last | 2009-04-26 | last |
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "last:C, C:B,last B:A,C A:first,B first:,A" in "_site/index.html"
|
||||
|
||||
Scenario: Use configuration date in site payload
|
||||
Given I have an "index.html" page that contains "{{ site.url }}"
|
||||
And I have a configuration file with "url" set to "http://example.com"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "http://example.com" in "_site/index.html"
|
||||
|
||||
Scenario: Access Jekyll version via jekyll.version
|
||||
Given I have an "index.html" page that contains "{{ jekyll.version }}"
|
||||
When I run jekyll
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "\d+\.\d+\.\d+" in "_site/index.html"
|
||||
|
||||
@@ -1,13 +1,35 @@
|
||||
def file_content_from_hash(input_hash)
|
||||
matter_hash = input_hash.reject { |k, v| k == "content" }
|
||||
matter = matter_hash.map { |k, v| "#{k}: #{v}\n" }.join.chomp
|
||||
|
||||
content = if input_hash['input'] && input_hash['filter']
|
||||
"{{ #{input_hash['input']} | #{input_hash['filter']} }}"
|
||||
else
|
||||
input_hash['content']
|
||||
end
|
||||
|
||||
<<EOF
|
||||
---
|
||||
#{matter}
|
||||
---
|
||||
#{content}
|
||||
EOF
|
||||
end
|
||||
|
||||
Before do
|
||||
FileUtils.rm_rf(TEST_DIR)
|
||||
FileUtils.mkdir(TEST_DIR)
|
||||
FileUtils.mkdir_p(TEST_DIR) unless File.exist?(TEST_DIR)
|
||||
Dir.chdir(TEST_DIR)
|
||||
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)
|
||||
end
|
||||
|
||||
World(Test::Unit::Assertions)
|
||||
|
||||
Given /^I have a blank site in "(.*)"$/ do |path|
|
||||
FileUtils.mkdir_p(path)
|
||||
FileUtils.mkdir_p(path) unless File.exist?(path)
|
||||
end
|
||||
|
||||
Given /^I do not have a "(.*)" directory$/ do |path|
|
||||
@@ -58,42 +80,28 @@ Given /^I have an? (.*) directory$/ do |dir|
|
||||
FileUtils.mkdir_p(dir)
|
||||
end
|
||||
|
||||
Given /^I have the following (draft|post)s?(?: (in|under) "([^"]+)")?:$/ do |status, direction, folder, table|
|
||||
table.hashes.each do |post|
|
||||
title = slug(post['title'])
|
||||
ext = post['type'] || 'textile'
|
||||
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'
|
||||
before, after = location(folder, direction)
|
||||
|
||||
if "draft" == status
|
||||
folder_post = '_drafts'
|
||||
case status
|
||||
when "draft"
|
||||
dest_folder = '_drafts'
|
||||
filename = "#{title}.#{ext}"
|
||||
elsif "post" == status
|
||||
parsed_date = Time.xmlschema(post['date']) rescue Time.parse(post['date'])
|
||||
folder_post = '_posts'
|
||||
when "page"
|
||||
dest_folder = ''
|
||||
filename = "#{title}.#{ext}"
|
||||
when "post"
|
||||
parsed_date = Time.xmlschema(input_hash['date']) rescue Time.parse(input_hash['date'])
|
||||
dest_folder = '_posts'
|
||||
filename = "#{parsed_date.strftime('%Y-%m-%d')}-#{title}.#{ext}"
|
||||
end
|
||||
|
||||
path = File.join(before, folder_post, after, filename)
|
||||
|
||||
matter_hash = {}
|
||||
%w(title layout tag tags category categories published author path date permalink).each do |key|
|
||||
matter_hash[key] = post[key] if post[key]
|
||||
end
|
||||
matter = matter_hash.map { |k, v| "#{k}: #{v}\n" }.join.chomp
|
||||
|
||||
content = if post['input'] && post['filter']
|
||||
"{{ #{post['input']} | #{post['filter']} }}"
|
||||
else
|
||||
post['content']
|
||||
end
|
||||
|
||||
path = File.join(before, dest_folder, after, filename)
|
||||
File.open(path, 'w') do |f|
|
||||
f.write <<EOF
|
||||
---
|
||||
#{matter}
|
||||
---
|
||||
#{content}
|
||||
EOF
|
||||
f.write file_content_from_hash(input_hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -121,21 +129,21 @@ Given /^I have a configuration file with "([^\"]*)" set to:$/ do |key, table|
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
When /^I run jekyll$/ do
|
||||
run_jekyll
|
||||
Given /^I have fixture collections$/ do
|
||||
FileUtils.cp_r File.join(JEKYLL_SOURCE_DIR, "test", "source", "_methods"), source_dir
|
||||
end
|
||||
|
||||
When /^I run jekyll with drafts$/ do
|
||||
run_jekyll(:drafts => true)
|
||||
end
|
||||
##################
|
||||
#
|
||||
# Changing stuff
|
||||
#
|
||||
##################
|
||||
|
||||
When /^I call jekyll new with test_blank --blank$/ do
|
||||
call_jekyll_new(:path => "test_blank", :blank => true)
|
||||
end
|
||||
|
||||
When /^I debug jekyll$/ do
|
||||
run_jekyll(:debug => true)
|
||||
When /^I run jekyll(.*)$/ do |args|
|
||||
status = run_jekyll(args)
|
||||
if args.include?("--verbose") || ENV['DEBUG']
|
||||
puts jekyll_run_output
|
||||
end
|
||||
end
|
||||
|
||||
When /^I change "(.*)" to contain "(.*)"$/ do |file, text|
|
||||
@@ -157,7 +165,7 @@ Then /^the (.*) directory should not exist$/ do |dir|
|
||||
end
|
||||
|
||||
Then /^I should see "(.*)" in "(.*)"$/ do |text, file|
|
||||
assert_match Regexp.new(text), file_contents(file)
|
||||
assert_match Regexp.new(text, Regexp::MULTILINE), file_contents(file)
|
||||
end
|
||||
|
||||
Then /^I should see exactly "(.*)" in "(.*)"$/ do |text, file|
|
||||
@@ -165,7 +173,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), file_contents(file)
|
||||
assert_no_match Regexp.new(text, Regexp::MULTILINE), file_contents(file)
|
||||
end
|
||||
|
||||
Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file|
|
||||
@@ -177,7 +185,7 @@ Then /^the "(.*)" file should +exist$/ do |file|
|
||||
end
|
||||
|
||||
Then /^the "(.*)" file should not exist$/ do |file|
|
||||
assert !File.exists?(file), "The file \"#{file}\" exists"
|
||||
assert !File.exist?(file), "The file \"#{file}\" exists"
|
||||
end
|
||||
|
||||
Then /^I should see today's time in "(.*)"$/ do |file|
|
||||
@@ -187,3 +195,7 @@ end
|
||||
Then /^I should see today's date in "(.*)"$/ do |file|
|
||||
assert_match Regexp.new(Date.today.to_s), file_contents(file)
|
||||
end
|
||||
|
||||
Then /^I should see "(.*)" in the build output$/ do |text|
|
||||
assert_match Regexp.new(text), jekyll_run_output
|
||||
end
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
if RUBY_VERSION > '1.9'
|
||||
require 'coveralls'
|
||||
Coveralls.wear_merged!
|
||||
end
|
||||
|
||||
require 'fileutils'
|
||||
require 'rr'
|
||||
require 'test/unit'
|
||||
require 'time'
|
||||
|
||||
TEST_DIR = File.join('/', 'tmp', 'jekyll')
|
||||
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.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll')
|
||||
JEKYLL_COMMAND_OUTPUT_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_output.txt')
|
||||
|
||||
def run_jekyll(opts = {})
|
||||
command = JEKYLL_PATH.clone
|
||||
command << " build"
|
||||
command << " --drafts" if opts[:drafts]
|
||||
command << " >> /dev/null 2>&1" if opts[:debug].nil?
|
||||
system command
|
||||
def source_dir(*files)
|
||||
File.join(TEST_DIR, *files)
|
||||
end
|
||||
|
||||
def call_jekyll_new(opts = {})
|
||||
command = JEKYLL_PATH.clone
|
||||
command << " new"
|
||||
command << " #{opts[:path]}" if opts[:path]
|
||||
command << " --blank" if opts[:blank]
|
||||
command << " >> /dev/null 2>&1" if opts[:debug].nil?
|
||||
system command
|
||||
def jekyll_output_file
|
||||
JEKYLL_COMMAND_OUTPUT_FILE
|
||||
end
|
||||
|
||||
def jekyll_run_output
|
||||
File.read(jekyll_output_file)
|
||||
end
|
||||
|
||||
def run_jekyll(args)
|
||||
system "#{JEKYLL_PATH} #{args} --trace > #{jekyll_output_file} 2>&1"
|
||||
end
|
||||
|
||||
def slug(title)
|
||||
title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
|
||||
if title
|
||||
title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
|
||||
else
|
||||
Time.now.strftime("%s%9N") # nanoseconds since the Epoch
|
||||
end
|
||||
end
|
||||
|
||||
def location(folder, direction)
|
||||
@@ -47,15 +47,8 @@ def file_contents(path)
|
||||
end
|
||||
|
||||
def seconds_agnostic_datetime(datetime = Time.now)
|
||||
pieces = datetime.to_s.split(" ")
|
||||
if pieces.size == 6 # Ruby 1.8.7
|
||||
date = pieces[0..2].join(" ")
|
||||
time = seconds_agnostic_time(pieces[3])
|
||||
zone = pieces[4..5].join(" ")
|
||||
else # Ruby 1.9.1 or greater
|
||||
date, time, zone = pieces
|
||||
time = seconds_agnostic_time(time)
|
||||
end
|
||||
date, time, zone = datetime.to_s.split(" ")
|
||||
time = seconds_agnostic_time(time)
|
||||
[
|
||||
Regexp.escape(date),
|
||||
"#{time}:\\d{2}",
|
||||
@@ -70,6 +63,3 @@ def seconds_agnostic_time(time)
|
||||
hour, minutes, _ = time.split(":")
|
||||
"#{hour}:#{minutes}"
|
||||
end
|
||||
|
||||
# work around "invalid option: --format" cucumber bug (see #296)
|
||||
Test::Unit.run = true if RUBY_VERSION < '1.9'
|
||||
|
||||
183
features/support/overview.rb
Normal file
183
features/support/overview.rb
Normal file
@@ -0,0 +1,183 @@
|
||||
require 'fileutils'
|
||||
require 'colorator'
|
||||
require 'cucumber/formatter/console'
|
||||
require 'cucumber/formatter/io'
|
||||
require 'gherkin/formatter/escaping'
|
||||
|
||||
module Features
|
||||
module Support
|
||||
# The formatter used for <tt>--format pretty</tt> (the default formatter).
|
||||
#
|
||||
# This formatter prints features to plain text - exactly how they were parsed,
|
||||
# just prettier. That means with proper indentation and alignment of table columns.
|
||||
#
|
||||
# If the output is STDOUT (and not a file), there are bright colours to watch too.
|
||||
#
|
||||
class Overview
|
||||
include FileUtils
|
||||
include Cucumber::Formatter::Console
|
||||
include Cucumber::Formatter::Io
|
||||
include Gherkin::Formatter::Escaping
|
||||
attr_writer :indent
|
||||
attr_reader :runtime
|
||||
|
||||
def initialize(runtime, path_or_io, options)
|
||||
@runtime, @io, @options = runtime, ensure_io(path_or_io, "pretty"), options
|
||||
@exceptions = []
|
||||
@indent = 0
|
||||
@prefixes = options[:prefixes] || {}
|
||||
@delayed_messages = []
|
||||
end
|
||||
|
||||
def before_features(features)
|
||||
print_profile_information
|
||||
end
|
||||
|
||||
def after_features(features)
|
||||
print_summary(features)
|
||||
end
|
||||
|
||||
def before_feature(feature)
|
||||
@exceptions = []
|
||||
@indent = 0
|
||||
end
|
||||
|
||||
def comment_line(comment_line)
|
||||
end
|
||||
|
||||
def after_tags(tags)
|
||||
end
|
||||
|
||||
def tag_name(tag_name)
|
||||
end
|
||||
|
||||
def before_feature_element(feature_element)
|
||||
@indent = 2
|
||||
@scenario_indent = 2
|
||||
end
|
||||
|
||||
def after_feature_element(feature_element)
|
||||
end
|
||||
|
||||
def before_background(background)
|
||||
@indent = 2
|
||||
@scenario_indent = 2
|
||||
@in_background = true
|
||||
end
|
||||
|
||||
def after_background(background)
|
||||
@in_background = nil
|
||||
end
|
||||
|
||||
def background_name(keyword, name, file_colon_line, source_indent)
|
||||
print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
||||
end
|
||||
|
||||
def before_examples_array(examples_array)
|
||||
end
|
||||
|
||||
def examples_name(keyword, name)
|
||||
end
|
||||
|
||||
def before_outline_table(outline_table)
|
||||
end
|
||||
|
||||
def after_outline_table(outline_table)
|
||||
end
|
||||
|
||||
def scenario_name(keyword, name, file_colon_line, source_indent)
|
||||
print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
||||
end
|
||||
|
||||
def before_step(step)
|
||||
@current_step = step
|
||||
end
|
||||
|
||||
def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
|
||||
@hide_this_step = false
|
||||
if exception
|
||||
if @exceptions.include?(exception)
|
||||
@hide_this_step = true
|
||||
return
|
||||
end
|
||||
@exceptions << exception
|
||||
end
|
||||
if status != :failed && @in_background ^ background
|
||||
@hide_this_step = true
|
||||
return
|
||||
end
|
||||
@status = status
|
||||
end
|
||||
|
||||
CHARS = {
|
||||
:failed => "x".red,
|
||||
:pending => "?".yellow,
|
||||
:undefined => "x".red,
|
||||
:passed => ".".green,
|
||||
:skipped => "-".blue
|
||||
}
|
||||
|
||||
def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
|
||||
@io.print CHARS[status]
|
||||
end
|
||||
|
||||
def doc_string(string)
|
||||
return if @options[:no_multiline] || @hide_this_step
|
||||
s = %{"""\n#{string}\n"""}.indent(@indent)
|
||||
s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}.join("\n")
|
||||
@io.puts(format_string(s, @current_step.status))
|
||||
@io.flush
|
||||
end
|
||||
|
||||
def exception(exception, status)
|
||||
return if @hide_this_step
|
||||
print_exception(exception, status, @indent)
|
||||
@io.flush
|
||||
end
|
||||
|
||||
def before_multiline_arg(multiline_arg)
|
||||
end
|
||||
|
||||
def after_multiline_arg(multiline_arg)
|
||||
end
|
||||
|
||||
def before_table_row(table_row)
|
||||
end
|
||||
|
||||
def after_table_row(table_row)
|
||||
end
|
||||
|
||||
def after_table_cell(cell)
|
||||
end
|
||||
|
||||
def table_cell_value(value, status)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
||||
@io.puts
|
||||
names = name.empty? ? [name] : name.split("\n")
|
||||
line = " #{keyword}: #{names[0]}"
|
||||
if @options[:source]
|
||||
line_comment = "#{file_colon_line}"
|
||||
@io.print(line_comment)
|
||||
end
|
||||
@io.print(line)
|
||||
@io.print " "
|
||||
@io.flush
|
||||
end
|
||||
|
||||
def cell_prefix(status)
|
||||
@prefixes[status]
|
||||
end
|
||||
|
||||
def print_summary(features)
|
||||
@io.puts
|
||||
print_stats(features, @options)
|
||||
print_snippets(@options)
|
||||
print_passing_wip(@options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
301
jekyll.gemspec
301
jekyll.gemspec
@@ -1,301 +1,66 @@
|
||||
# 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 |s|
|
||||
s.specification_version = 2 if s.respond_to? :specification_version=
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||
s.rubygems_version = '1.3.5'
|
||||
s.rubygems_version = '2.2.2'
|
||||
s.required_ruby_version = '>= 1.9.3'
|
||||
|
||||
s.name = 'jekyll'
|
||||
s.version = '1.4.0'
|
||||
s.version = Jekyll::VERSION
|
||||
s.license = 'MIT'
|
||||
s.date = '2013-12-07'
|
||||
s.rubyforge_project = 'jekyll'
|
||||
|
||||
s.summary = "A simple, blog aware, static site generator."
|
||||
s.description = "Jekyll is a simple, blog aware, static site generator."
|
||||
|
||||
s.authors = ["Tom Preston-Werner"]
|
||||
s.email = 'tom@mojombo.com'
|
||||
s.homepage = 'http://github.com/mojombo/jekyll'
|
||||
s.homepage = 'https://github.com/jekyll/jekyll'
|
||||
|
||||
s.require_paths = %w[lib]
|
||||
|
||||
s.executables = ["jekyll"]
|
||||
all_files = `git ls-files -z`.split("\x0")
|
||||
s.files = all_files.grep(%r{^(bin|lib)/})
|
||||
s.executables = all_files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||
s.require_paths = ["lib"]
|
||||
|
||||
s.rdoc_options = ["--charset=UTF-8"]
|
||||
s.extra_rdoc_files = %w[README.markdown LICENSE]
|
||||
|
||||
s.add_runtime_dependency('liquid', "~> 2.5.2")
|
||||
s.add_runtime_dependency('classifier', "~> 1.3")
|
||||
s.add_runtime_dependency('listen', "~> 1.3")
|
||||
s.add_runtime_dependency('maruku', "~> 0.7.0")
|
||||
s.add_runtime_dependency('pygments.rb', "~> 0.5.0")
|
||||
s.add_runtime_dependency('commander', "~> 4.1.3")
|
||||
s.add_runtime_dependency('safe_yaml', "~> 0.9.7")
|
||||
s.add_runtime_dependency('liquid', "~> 2.6.1")
|
||||
s.add_runtime_dependency('kramdown', "~> 1.3")
|
||||
s.add_runtime_dependency('mercenary', "~> 0.3.3")
|
||||
s.add_runtime_dependency('safe_yaml', "~> 1.0")
|
||||
s.add_runtime_dependency('colorator', "~> 0.1")
|
||||
s.add_runtime_dependency('redcarpet', "~> 2.3.0")
|
||||
|
||||
# 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('jekyll-sass-converter', '~> 1.0')
|
||||
s.add_runtime_dependency('jekyll-watch', '~> 1.1')
|
||||
s.add_runtime_dependency('classifier-reborn', "~> 2.0")
|
||||
|
||||
s.add_development_dependency('rake', "~> 10.1")
|
||||
s.add_development_dependency('rdoc', "~> 3.11")
|
||||
s.add_development_dependency('redgreen', "~> 1.2")
|
||||
s.add_development_dependency('shoulda', "~> 3.3.2")
|
||||
s.add_development_dependency('shoulda', "~> 3.5")
|
||||
s.add_development_dependency('rr', "~> 1.1")
|
||||
s.add_development_dependency('cucumber', "~> 1.3")
|
||||
s.add_development_dependency('cucumber', "1.3.11")
|
||||
s.add_development_dependency('RedCloth', "~> 4.2")
|
||||
s.add_development_dependency('kramdown', "~> 1.2")
|
||||
s.add_development_dependency('maruku', "~> 0.7.0")
|
||||
s.add_development_dependency('rdiscount', "~> 1.6")
|
||||
s.add_development_dependency('launchy', "~> 2.3")
|
||||
s.add_development_dependency('simplecov', "~> 0.7")
|
||||
s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
|
||||
s.add_development_dependency('coveralls', "~> 0.7.0")
|
||||
s.add_development_dependency('mime-types', "~> 1.5")
|
||||
s.add_development_dependency('activesupport', '~> 3.2.13')
|
||||
s.add_development_dependency('jekyll_test_plugin')
|
||||
|
||||
# = MANIFEST =
|
||||
s.files = %w[
|
||||
CONTRIBUTING.markdown
|
||||
Gemfile
|
||||
History.markdown
|
||||
LICENSE
|
||||
README.markdown
|
||||
Rakefile
|
||||
bin/jekyll
|
||||
cucumber.yml
|
||||
features/create_sites.feature
|
||||
features/data.feature
|
||||
features/drafts.feature
|
||||
features/embed_filters.feature
|
||||
features/include_tag.feature
|
||||
features/markdown.feature
|
||||
features/pagination.feature
|
||||
features/permalinks.feature
|
||||
features/post_data.feature
|
||||
features/post_excerpts.feature
|
||||
features/site_configuration.feature
|
||||
features/site_data.feature
|
||||
features/step_definitions/jekyll_steps.rb
|
||||
features/support/env.rb
|
||||
jekyll.gemspec
|
||||
lib/jekyll.rb
|
||||
lib/jekyll/cleaner.rb
|
||||
lib/jekyll/command.rb
|
||||
lib/jekyll/commands/build.rb
|
||||
lib/jekyll/commands/doctor.rb
|
||||
lib/jekyll/commands/new.rb
|
||||
lib/jekyll/commands/serve.rb
|
||||
lib/jekyll/configuration.rb
|
||||
lib/jekyll/converter.rb
|
||||
lib/jekyll/converters/identity.rb
|
||||
lib/jekyll/converters/markdown.rb
|
||||
lib/jekyll/converters/markdown/kramdown_parser.rb
|
||||
lib/jekyll/converters/markdown/maruku_parser.rb
|
||||
lib/jekyll/converters/markdown/rdiscount_parser.rb
|
||||
lib/jekyll/converters/markdown/redcarpet_parser.rb
|
||||
lib/jekyll/converters/textile.rb
|
||||
lib/jekyll/convertible.rb
|
||||
lib/jekyll/core_ext.rb
|
||||
lib/jekyll/deprecator.rb
|
||||
lib/jekyll/draft.rb
|
||||
lib/jekyll/entry_filter.rb
|
||||
lib/jekyll/errors.rb
|
||||
lib/jekyll/excerpt.rb
|
||||
lib/jekyll/filters.rb
|
||||
lib/jekyll/generator.rb
|
||||
lib/jekyll/generators/pagination.rb
|
||||
lib/jekyll/layout.rb
|
||||
lib/jekyll/mime.types
|
||||
lib/jekyll/page.rb
|
||||
lib/jekyll/plugin.rb
|
||||
lib/jekyll/post.rb
|
||||
lib/jekyll/related_posts.rb
|
||||
lib/jekyll/site.rb
|
||||
lib/jekyll/static_file.rb
|
||||
lib/jekyll/stevenson.rb
|
||||
lib/jekyll/tags/gist.rb
|
||||
lib/jekyll/tags/highlight.rb
|
||||
lib/jekyll/tags/include.rb
|
||||
lib/jekyll/tags/post_url.rb
|
||||
lib/jekyll/url.rb
|
||||
lib/site_template/.gitignore
|
||||
lib/site_template/_config.yml
|
||||
lib/site_template/_layouts/default.html
|
||||
lib/site_template/_layouts/post.html
|
||||
lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb
|
||||
lib/site_template/css/main.css
|
||||
lib/site_template/css/syntax.css
|
||||
lib/site_template/index.html
|
||||
script/bootstrap
|
||||
site/.gitignore
|
||||
site/CNAME
|
||||
site/README
|
||||
site/_config.yml
|
||||
site/_includes/analytics.html
|
||||
site/_includes/docs_contents.html
|
||||
site/_includes/docs_contents_mobile.html
|
||||
site/_includes/docs_option.html
|
||||
site/_includes/docs_ul.html
|
||||
site/_includes/footer.html
|
||||
site/_includes/header.html
|
||||
site/_includes/news_contents.html
|
||||
site/_includes/news_contents_mobile.html
|
||||
site/_includes/news_item.html
|
||||
site/_includes/primary-nav-items.html
|
||||
site/_includes/section_nav.html
|
||||
site/_includes/top.html
|
||||
site/_layouts/default.html
|
||||
site/_layouts/docs.html
|
||||
site/_layouts/news.html
|
||||
site/_layouts/news_item.html
|
||||
site/_posts/2013-05-06-jekyll-1-0-0-released.markdown
|
||||
site/_posts/2013-05-08-jekyll-1-0-1-released.markdown
|
||||
site/_posts/2013-05-12-jekyll-1-0-2-released.markdown
|
||||
site/_posts/2013-06-07-jekyll-1-0-3-released.markdown
|
||||
site/_posts/2013-07-14-jekyll-1-1-0-released.markdown
|
||||
site/_posts/2013-07-24-jekyll-1-1-1-released.markdown
|
||||
site/_posts/2013-07-25-jekyll-1-0-4-released.markdown
|
||||
site/_posts/2013-07-25-jekyll-1-1-2-released.markdown
|
||||
site/_posts/2013-09-06-jekyll-1-2-0-released.markdown
|
||||
site/_posts/2013-09-14-jekyll-1-2-1-released.markdown
|
||||
site/_posts/2013-10-28-jekyll-1-3-0-rc1-released.markdown
|
||||
site/_posts/2013-11-04-jekyll-1-3-0-released.markdown
|
||||
site/_posts/2013-11-26-jekyll-1-3-1-released.markdown
|
||||
site/_posts/2013-12-07-jekyll-1-4-0-released.markdown
|
||||
site/css/gridism.css
|
||||
site/css/normalize.css
|
||||
site/css/pygments.css
|
||||
site/css/style.css
|
||||
site/docs/configuration.md
|
||||
site/docs/contributing.md
|
||||
site/docs/datafiles.md
|
||||
site/docs/deployment-methods.md
|
||||
site/docs/drafts.md
|
||||
site/docs/extras.md
|
||||
site/docs/frontmatter.md
|
||||
site/docs/github-pages.md
|
||||
site/docs/heroku.md
|
||||
site/docs/history.md
|
||||
site/docs/index.md
|
||||
site/docs/installation.md
|
||||
site/docs/migrations.md
|
||||
site/docs/pages.md
|
||||
site/docs/pagination.md
|
||||
site/docs/permalinks.md
|
||||
site/docs/plugins.md
|
||||
site/docs/posts.md
|
||||
site/docs/quickstart.md
|
||||
site/docs/resources.md
|
||||
site/docs/sites.md
|
||||
site/docs/structure.md
|
||||
site/docs/templates.md
|
||||
site/docs/troubleshooting.md
|
||||
site/docs/upgrading.md
|
||||
site/docs/usage.md
|
||||
site/docs/variables.md
|
||||
site/favicon.png
|
||||
site/feed.xml
|
||||
site/freenode.txt
|
||||
site/img/article-footer.png
|
||||
site/img/footer-arrow.png
|
||||
site/img/footer-logo.png
|
||||
site/img/logo-2x.png
|
||||
site/img/octojekyll.png
|
||||
site/img/tube.png
|
||||
site/img/tube1x.png
|
||||
site/index.html
|
||||
site/js/modernizr-2.5.3.min.js
|
||||
site/news/index.html
|
||||
site/news/releases/index.html
|
||||
test/fixtures/broken_front_matter1.erb
|
||||
test/fixtures/broken_front_matter2.erb
|
||||
test/fixtures/broken_front_matter3.erb
|
||||
test/fixtures/exploit_front_matter.erb
|
||||
test/fixtures/front_matter.erb
|
||||
test/helper.rb
|
||||
test/source/+/foo.md
|
||||
test/source/.htaccess
|
||||
test/source/_config.dev.toml
|
||||
test/source/_data/languages.yml
|
||||
test/source/_data/members.yaml
|
||||
test/source/_data/products.yml
|
||||
test/source/_includes/params.html
|
||||
test/source/_includes/sig.markdown
|
||||
test/source/_layouts/default.html
|
||||
test/source/_layouts/post/simple.html
|
||||
test/source/_layouts/simple.html
|
||||
test/source/_plugins/dummy.rb
|
||||
test/source/_posts/2008-02-02-not-published.textile
|
||||
test/source/_posts/2008-02-02-published.textile
|
||||
test/source/_posts/2008-10-18-foo-bar.textile
|
||||
test/source/_posts/2008-11-21-complex.textile
|
||||
test/source/_posts/2008-12-03-permalinked-post.textile
|
||||
test/source/_posts/2008-12-13-include.markdown
|
||||
test/source/_posts/2009-01-27-array-categories.textile
|
||||
test/source/_posts/2009-01-27-categories.textile
|
||||
test/source/_posts/2009-01-27-category.textile
|
||||
test/source/_posts/2009-01-27-empty-categories.textile
|
||||
test/source/_posts/2009-01-27-empty-category.textile
|
||||
test/source/_posts/2009-03-12-hash-#1.markdown
|
||||
test/source/_posts/2009-05-18-empty-tag.textile
|
||||
test/source/_posts/2009-05-18-empty-tags.textile
|
||||
test/source/_posts/2009-05-18-tag.textile
|
||||
test/source/_posts/2009-05-18-tags.textile
|
||||
test/source/_posts/2009-06-22-empty-yaml.textile
|
||||
test/source/_posts/2009-06-22-no-yaml.textile
|
||||
test/source/_posts/2010-01-08-triple-dash.markdown
|
||||
test/source/_posts/2010-01-09-date-override.textile
|
||||
test/source/_posts/2010-01-09-time-override.textile
|
||||
test/source/_posts/2010-01-09-timezone-override.textile
|
||||
test/source/_posts/2010-01-16-override-data.textile
|
||||
test/source/_posts/2011-04-12-md-extension.md
|
||||
test/source/_posts/2011-04-12-text-extension.text
|
||||
test/source/_posts/2013-01-02-post-excerpt.markdown
|
||||
test/source/_posts/2013-01-12-nil-layout.textile
|
||||
test/source/_posts/2013-01-12-no-layout.textile
|
||||
test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep
|
||||
test/source/_posts/2013-04-11-custom-excerpt.markdown
|
||||
test/source/_posts/2013-05-10-number-category.textile
|
||||
test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown
|
||||
test/source/_posts/2013-08-01-mkdn-extension.mkdn
|
||||
test/source/_posts/es/2008-11-21-nested.textile
|
||||
test/source/about.html
|
||||
test/source/category/_posts/2008-9-23-categories.textile
|
||||
test/source/contacts.html
|
||||
test/source/contacts/bar.html
|
||||
test/source/contacts/index.html
|
||||
test/source/css/screen.css
|
||||
test/source/deal.with.dots.html
|
||||
test/source/foo/_posts/bar/2008-12-12-topical-post.textile
|
||||
test/source/index.html
|
||||
test/source/products.yml
|
||||
test/source/sitemap.xml
|
||||
test/source/symlink-test/_data
|
||||
test/source/symlink-test/symlinked-dir
|
||||
test/source/symlink-test/symlinked-file
|
||||
test/source/win/_posts/2009-05-24-yaml-linebreak.markdown
|
||||
test/source/z_category/_posts/2008-9-23-categories.textile
|
||||
test/suite.rb
|
||||
test/test_command.rb
|
||||
test/test_configuration.rb
|
||||
test/test_convertible.rb
|
||||
test/test_core_ext.rb
|
||||
test/test_entry_filter.rb
|
||||
test/test_excerpt.rb
|
||||
test/test_filters.rb
|
||||
test/test_generated_site.rb
|
||||
test/test_kramdown.rb
|
||||
test/test_new_command.rb
|
||||
test/test_page.rb
|
||||
test/test_pager.rb
|
||||
test/test_post.rb
|
||||
test/test_rdiscount.rb
|
||||
test/test_redcarpet.rb
|
||||
test/test_redcloth.rb
|
||||
test/test_related_posts.rb
|
||||
test/test_site.rb
|
||||
test/test_tags.rb
|
||||
test/test_url.rb
|
||||
]
|
||||
# = MANIFEST =
|
||||
|
||||
s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
|
||||
s.add_development_dependency('jekyll_test_plugin_malicious')
|
||||
s.add_development_dependency('rouge', '~> 1.3')
|
||||
end
|
||||
|
||||
123
lib/jekyll.rb
123
lib/jekyll.rb
@@ -18,52 +18,63 @@ require 'rubygems'
|
||||
# stdlib
|
||||
require 'fileutils'
|
||||
require 'time'
|
||||
require 'safe_yaml'
|
||||
require 'English'
|
||||
require 'pathname'
|
||||
require 'logger'
|
||||
|
||||
# 3rd party
|
||||
require 'safe_yaml/load'
|
||||
require 'liquid'
|
||||
require 'maruku'
|
||||
require 'kramdown'
|
||||
require 'colorator'
|
||||
require 'toml'
|
||||
|
||||
# internal requires
|
||||
require 'jekyll/core_ext'
|
||||
require 'jekyll/stevenson'
|
||||
require 'jekyll/deprecator'
|
||||
require 'jekyll/configuration'
|
||||
require 'jekyll/site'
|
||||
require 'jekyll/convertible'
|
||||
require 'jekyll/url'
|
||||
require 'jekyll/layout'
|
||||
require 'jekyll/page'
|
||||
require 'jekyll/post'
|
||||
require 'jekyll/excerpt'
|
||||
require 'jekyll/draft'
|
||||
require 'jekyll/filters'
|
||||
require 'jekyll/static_file'
|
||||
require 'jekyll/errors'
|
||||
require 'jekyll/related_posts'
|
||||
require 'jekyll/cleaner'
|
||||
require 'jekyll/entry_filter'
|
||||
|
||||
# extensions
|
||||
require 'jekyll/plugin'
|
||||
require 'jekyll/converter'
|
||||
require 'jekyll/generator'
|
||||
require 'jekyll/command'
|
||||
|
||||
require_all 'jekyll/commands'
|
||||
require_all 'jekyll/converters'
|
||||
require_all 'jekyll/converters/markdown'
|
||||
require_all 'jekyll/generators'
|
||||
require_all 'jekyll/tags'
|
||||
|
||||
SafeYAML::OPTIONS[:suppress_warnings] = true
|
||||
|
||||
module Jekyll
|
||||
VERSION = '1.4.0'
|
||||
|
||||
# internal requires
|
||||
autoload :Cleaner, 'jekyll/cleaner'
|
||||
autoload :Collection, 'jekyll/collection'
|
||||
autoload :Configuration, 'jekyll/configuration'
|
||||
autoload :Convertible, 'jekyll/convertible'
|
||||
autoload :Deprecator, 'jekyll/deprecator'
|
||||
autoload :Document, 'jekyll/document'
|
||||
autoload :Draft, 'jekyll/draft'
|
||||
autoload :EntryFilter, 'jekyll/entry_filter'
|
||||
autoload :Errors, 'jekyll/errors'
|
||||
autoload :Excerpt, 'jekyll/excerpt'
|
||||
autoload :Filters, 'jekyll/filters'
|
||||
autoload :FrontmatterDefaults, 'jekyll/frontmatter_defaults'
|
||||
autoload :Layout, 'jekyll/layout'
|
||||
autoload :LayoutReader, 'jekyll/layout_reader'
|
||||
autoload :LogAdapter, 'jekyll/log_adapter'
|
||||
autoload :Page, 'jekyll/page'
|
||||
autoload :PluginManager, 'jekyll/plugin_manager'
|
||||
autoload :Post, 'jekyll/post'
|
||||
autoload :Publisher, 'jekyll/publisher'
|
||||
autoload :RelatedPosts, 'jekyll/related_posts'
|
||||
autoload :Renderer, 'jekyll/renderer'
|
||||
autoload :Site, 'jekyll/site'
|
||||
autoload :StaticFile, 'jekyll/static_file'
|
||||
autoload :Stevenson, 'jekyll/stevenson'
|
||||
autoload :URL, 'jekyll/url'
|
||||
autoload :Utils, 'jekyll/utils'
|
||||
autoload :VERSION, 'jekyll/version'
|
||||
|
||||
# extensions
|
||||
require 'jekyll/plugin'
|
||||
require 'jekyll/converter'
|
||||
require 'jekyll/generator'
|
||||
require 'jekyll/command'
|
||||
require 'jekyll/liquid_extensions'
|
||||
|
||||
# Public: Tells you which Jekyll environment you are building in so you can skip tasks
|
||||
# if you need to. This is useful when doing expensive compression tasks on css and
|
||||
# images and allows you to skip that when working in development.
|
||||
|
||||
def self.env
|
||||
ENV["JEKYLL_ENV"] || "development"
|
||||
end
|
||||
|
||||
# Public: Generate a Jekyll configuration Hash by merging the default
|
||||
# options with anything in _config.yml, and adding the given options on top.
|
||||
@@ -79,7 +90,7 @@ module Jekyll
|
||||
config = config.read_config_files(config.config_files(override))
|
||||
|
||||
# Merge DEFAULTS < _config.yml < override
|
||||
config = config.deep_merge(override).stringify_keys
|
||||
config = Utils.deep_merge_hashes(config, override).stringify_keys
|
||||
set_timezone(config['timezone']) if config['timezone']
|
||||
|
||||
config
|
||||
@@ -95,6 +106,42 @@ module Jekyll
|
||||
end
|
||||
|
||||
def self.logger
|
||||
@logger ||= Stevenson.new
|
||||
@logger ||= LogAdapter.new(Stevenson.new)
|
||||
end
|
||||
|
||||
def self.logger=(writer)
|
||||
@logger = LogAdapter.new(writer)
|
||||
end
|
||||
|
||||
# Public: File system root
|
||||
#
|
||||
# Returns the root of the filesystem as a Pathname
|
||||
def self.fs_root
|
||||
@fs_root ||= "/"
|
||||
end
|
||||
|
||||
def self.sanitized_path(base_directory, questionable_path)
|
||||
clean_path = File.expand_path(questionable_path, fs_root)
|
||||
clean_path.gsub!(/\A\w\:\//, '/')
|
||||
unless clean_path.start_with?(base_directory)
|
||||
File.join(base_directory, clean_path)
|
||||
else
|
||||
clean_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require_all 'jekyll/commands'
|
||||
require_all 'jekyll/converters'
|
||||
require_all 'jekyll/converters/markdown'
|
||||
require_all 'jekyll/generators'
|
||||
require_all 'jekyll/tags'
|
||||
|
||||
# Eventually remove these for 3.0 as non-core
|
||||
Jekyll::Deprecator.gracefully_require(%w[
|
||||
toml
|
||||
jekyll-paginate
|
||||
jekyll-gist
|
||||
jekyll-coffeescript
|
||||
jekyll-sass-converter
|
||||
])
|
||||
|
||||
@@ -4,6 +4,8 @@ module Jekyll
|
||||
class Site
|
||||
# Handles the cleanup of a site's destination before it is built.
|
||||
class Cleaner
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
@@ -27,8 +29,8 @@ module Jekyll
|
||||
# Returns a Set with the file paths
|
||||
def existing_files
|
||||
files = Set.new
|
||||
Dir.glob(File.join(@site.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
|
||||
files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
|
||||
Dir.glob(File.join(site.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
|
||||
files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex || keep_dirs.include?(file)
|
||||
end
|
||||
files
|
||||
end
|
||||
@@ -38,7 +40,7 @@ module Jekyll
|
||||
# Returns a Set with the file paths
|
||||
def new_files
|
||||
files = Set.new
|
||||
@site.each_site_file { |item| files << item.destination(@site.dest) }
|
||||
site.each_site_file { |item| files << item.destination(site.dest) }
|
||||
files
|
||||
end
|
||||
|
||||
@@ -47,7 +49,19 @@ module Jekyll
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
def new_dirs
|
||||
new_files.map { |file| File.dirname(file) }.to_set
|
||||
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
|
||||
@@ -57,6 +71,14 @@ module Jekyll
|
||||
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(File.join(site.dest, file))}.flatten.to_set
|
||||
end
|
||||
|
||||
# Private: Creates a regular expression from the config's keep_files array
|
||||
#
|
||||
# Examples
|
||||
@@ -64,7 +86,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the regular expression
|
||||
def keep_file_regex
|
||||
or_list = @site.keep_files.join("|")
|
||||
or_list = site.keep_files.join("|")
|
||||
pattern = "\/(#{or_list.gsub(".", "\.")})"
|
||||
Regexp.new pattern
|
||||
end
|
||||
|
||||
169
lib/jekyll/collection.rb
Normal file
169
lib/jekyll/collection.rb
Normal file
@@ -0,0 +1,169 @@
|
||||
module Jekyll
|
||||
class Collection
|
||||
attr_reader :site, :label, :metadata
|
||||
|
||||
# Create a new Collection.
|
||||
#
|
||||
# site - the site to which this collection belongs.
|
||||
# label - the name of the collection
|
||||
#
|
||||
# Returns nothing.
|
||||
def initialize(site, label)
|
||||
@site = site
|
||||
@label = sanitize_label(label)
|
||||
@metadata = extract_metadata
|
||||
end
|
||||
|
||||
# Fetch the Documents in this collection.
|
||||
# Defaults to an empty array if no documents have been read in.
|
||||
#
|
||||
# Returns an array of Jekyll::Document objects.
|
||||
def docs
|
||||
@docs ||= []
|
||||
end
|
||||
|
||||
# Fetch the static files in this collection.
|
||||
# Defaults to an empty array if no static files have been read in.
|
||||
#
|
||||
# Returns an array of Jekyll::StaticFile objects.
|
||||
def files
|
||||
@files ||= []
|
||||
end
|
||||
|
||||
# Read the allowed documents into the collection's array of docs.
|
||||
#
|
||||
# Returns the sorted array of docs.
|
||||
def read
|
||||
filtered_entries.each do |file_path|
|
||||
full_path = Jekyll.sanitized_path(directory, file_path)
|
||||
if Utils.has_yaml_header? full_path
|
||||
doc = Jekyll::Document.new(full_path, { site: site, collection: self })
|
||||
doc.read
|
||||
docs << doc
|
||||
else
|
||||
relative_dir = File.join(relative_directory, File.dirname(file_path)).chomp("/.")
|
||||
files << StaticFile.new(site, site.source, relative_dir, File.basename(full_path), self)
|
||||
end
|
||||
end
|
||||
docs.sort!
|
||||
end
|
||||
|
||||
# All the entries in this collection.
|
||||
#
|
||||
# Returns an Array of file paths to the documents in this collection
|
||||
# relative to the collection's directory
|
||||
def entries
|
||||
return Array.new unless exists?
|
||||
Dir.glob(File.join(directory, "**", "*.*")).map do |entry|
|
||||
entry[File.join(directory, "")] = ''; entry
|
||||
end
|
||||
end
|
||||
|
||||
# Filtered version of the entries in this collection.
|
||||
# See `Jekyll::EntryFilter#filter` for more information.
|
||||
#
|
||||
# Returns a list of filtered entry paths.
|
||||
def filtered_entries
|
||||
return Array.new unless exists?
|
||||
Dir.chdir(directory) do
|
||||
entry_filter.filter(entries).reject { |f| File.directory?(f) }
|
||||
end
|
||||
end
|
||||
|
||||
# The directory for this Collection, relative to the site source.
|
||||
#
|
||||
# Returns a String containing the directory name where the collection
|
||||
# is stored on the filesystem.
|
||||
def relative_directory
|
||||
"_#{label}"
|
||||
end
|
||||
|
||||
# The full path to the directory containing the
|
||||
#
|
||||
# Returns a String containing th directory name where the collection
|
||||
# is stored on the filesystem.
|
||||
def directory
|
||||
Jekyll.sanitized_path(site.source, relative_directory)
|
||||
end
|
||||
|
||||
# Checks whether the directory "exists" for this collection.
|
||||
# The directory must exist on the filesystem and must not be a symlink
|
||||
# if in safe mode.
|
||||
#
|
||||
# Returns false if the directory doesn't exist or if it's a symlink
|
||||
# and we're in safe mode.
|
||||
def exists?
|
||||
File.directory?(directory) && !(File.symlink?(directory) && site.safe)
|
||||
end
|
||||
|
||||
# The entry filter for this collection.
|
||||
# Creates an instance of Jekyll::EntryFilter.
|
||||
#
|
||||
# Returns the instance of Jekyll::EntryFilter for this collection.
|
||||
def entry_filter
|
||||
@entry_filter ||= Jekyll::EntryFilter.new(site, relative_directory)
|
||||
end
|
||||
|
||||
# An inspect string.
|
||||
#
|
||||
# Returns the inspect string
|
||||
def inspect
|
||||
"#<Jekyll::Collection @label=#{label} docs=#{docs}>"
|
||||
end
|
||||
|
||||
# Produce a sanitized label name
|
||||
# Label names may not contain anything but alphanumeric characters,
|
||||
# underscores, and hyphens.
|
||||
#
|
||||
# label - the possibly-unsafe label
|
||||
#
|
||||
# Returns a sanitized version of the label.
|
||||
def sanitize_label(label)
|
||||
label.gsub(/[^a-z0-9_\-\.]/i, '')
|
||||
end
|
||||
|
||||
# Produce a representation of this Collection for use in Liquid.
|
||||
# Exposes two attributes:
|
||||
# - label
|
||||
# - docs
|
||||
#
|
||||
# Returns a representation of this collection for use in Liquid.
|
||||
def to_liquid
|
||||
metadata.merge({
|
||||
"label" => label,
|
||||
"docs" => docs,
|
||||
"files" => files,
|
||||
"directory" => directory,
|
||||
"output" => write?,
|
||||
"relative_directory" => relative_directory
|
||||
})
|
||||
end
|
||||
|
||||
# Whether the collection's documents ought to be written as individual
|
||||
# files in the output.
|
||||
#
|
||||
# Returns true if the 'write' metadata is true, false otherwise.
|
||||
def write?
|
||||
!!metadata['output']
|
||||
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")
|
||||
end
|
||||
|
||||
# Extract options for this collection from the site configuration.
|
||||
#
|
||||
# Returns the metadata for this collection
|
||||
def extract_metadata
|
||||
if site.config['collections'].is_a?(Hash)
|
||||
site.config['collections'][label] || Hash.new
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,27 +1,66 @@
|
||||
module Jekyll
|
||||
class Command
|
||||
def self.globs(source, destination)
|
||||
Dir.chdir(source) do
|
||||
dirs = Dir['*'].select { |x| File.directory?(x) }
|
||||
dirs -= [destination, File.expand_path(destination), File.basename(destination)]
|
||||
dirs = dirs.map { |x| "#{x}/**/*" }
|
||||
dirs += ['*']
|
||||
|
||||
class << self
|
||||
|
||||
# A list of subclasses of Jekyll::Command
|
||||
def subclasses
|
||||
@subclasses ||= []
|
||||
end
|
||||
|
||||
# Keep a list of subclasses of Jekyll::Command every time it's inherited
|
||||
# Called automatically.
|
||||
#
|
||||
# base - the subclass
|
||||
#
|
||||
# Returns nothing
|
||||
def inherited(base)
|
||||
subclasses << base
|
||||
super(base)
|
||||
end
|
||||
|
||||
# Run Site#process and catch errors
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
#
|
||||
# Returns nothing
|
||||
def process_site(site)
|
||||
site.process
|
||||
rescue Jekyll::Errors::FatalException => e
|
||||
Jekyll.logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:"
|
||||
Jekyll.logger.error "", "------------------------------------"
|
||||
Jekyll.logger.error "", e.message
|
||||
exit(1)
|
||||
end
|
||||
|
||||
# Create a full Jekyll configuration with the options passed in as overrides
|
||||
#
|
||||
# options - the configuration overrides
|
||||
#
|
||||
# Returns a full Jekyll configuration
|
||||
def configuration_from_options(options)
|
||||
Jekyll.configuration(options)
|
||||
end
|
||||
|
||||
# Add common options to a command for building configuration
|
||||
#
|
||||
# c - the Jekyll::Command to add these options to
|
||||
#
|
||||
# Returns nothing
|
||||
def add_build_options(c)
|
||||
c.option 'config', '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
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', '--watch', 'Watch for changes and rebuild'
|
||||
c.option 'force_polling', '--force_polling', 'Force watch to use polling'
|
||||
c.option 'lsi', '--lsi', 'Use LSI for improved related posts'
|
||||
c.option 'show_drafts', '-D', '--drafts', 'Render posts in the _drafts folder'
|
||||
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.'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Static: Run Site#process and catch errors
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
#
|
||||
# Returns nothing
|
||||
def self.process_site(site)
|
||||
site.process
|
||||
rescue Jekyll::FatalException => e
|
||||
puts
|
||||
Jekyll.logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:"
|
||||
Jekyll.logger.error "", "------------------------------------"
|
||||
Jekyll.logger.error "", e.message
|
||||
exit(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,70 +1,74 @@
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Build < Command
|
||||
def self.process(options)
|
||||
site = Jekyll::Site.new(options)
|
||||
|
||||
self.build(site, options)
|
||||
self.watch(site, options) if options['watch']
|
||||
end
|
||||
class << self
|
||||
|
||||
# Private: Build the site from source into destination.
|
||||
#
|
||||
# site - A Jekyll::Site instance
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.build(site, options)
|
||||
source = options['source']
|
||||
destination = options['destination']
|
||||
Jekyll.logger.info "Source:", source
|
||||
Jekyll.logger.info "Destination:", destination
|
||||
print Jekyll.logger.formatted_topic "Generating..."
|
||||
self.process_site(site)
|
||||
puts "done."
|
||||
end
|
||||
# Create the Mercenary command for the Jekyll CLI for this Command
|
||||
def init_with_program(prog)
|
||||
prog.command(:build) do |c|
|
||||
c.syntax 'build [options]'
|
||||
c.description 'Build your site'
|
||||
|
||||
# Private: Watch for file changes and rebuild the site.
|
||||
#
|
||||
# site - A Jekyll::Site instance
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.watch(site, options)
|
||||
require 'listen'
|
||||
add_build_options(c)
|
||||
|
||||
source = options['source']
|
||||
destination = options['destination']
|
||||
|
||||
begin
|
||||
dest = Pathname.new(destination).relative_path_from(Pathname.new(source)).to_s
|
||||
ignored = Regexp.new(Regexp.escape(dest))
|
||||
rescue ArgumentError
|
||||
# Destination is outside the source, no need to ignore it.
|
||||
ignored = nil
|
||||
c.action do |args, options|
|
||||
options["serving"] = false
|
||||
Jekyll::Commands::Build.process(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Jekyll.logger.info "Auto-regeneration:", "enabled"
|
||||
# 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']
|
||||
|
||||
listener = Listen::Listener.new(source, :ignore => ignored) do |modified, added, removed|
|
||||
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
||||
n = modified.length + added.length + removed.length
|
||||
print Jekyll.logger.formatted_topic("Regenerating:") + "#{n} files at #{t} "
|
||||
self.process_site(site)
|
||||
puts "...done."
|
||||
end
|
||||
listener.start
|
||||
options = configuration_from_options(options)
|
||||
site = Jekyll::Site.new(options)
|
||||
|
||||
unless options['serving']
|
||||
trap("INT") do
|
||||
listener.stop
|
||||
puts " Halting auto-regeneration."
|
||||
exit 0
|
||||
if options.fetch('skip_initial_build', false)
|
||||
Jekyll.logger.warn "Build Warning:", "Skipping the initial build. This may result in an out-of-date site."
|
||||
else
|
||||
build(site, options)
|
||||
end
|
||||
|
||||
loop { sleep 1000 }
|
||||
if options.fetch('watch', false)
|
||||
watch(site, options)
|
||||
else
|
||||
Jekyll.logger.info "Auto-regeneration:", "disabled. Use --watch to enable."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Build your Jekyll site.
|
||||
#
|
||||
# site - the Jekyll::Site instance to build
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def build(site, options)
|
||||
source = options['source']
|
||||
destination = options['destination']
|
||||
Jekyll.logger.info "Source:", source
|
||||
Jekyll.logger.info "Destination:", destination
|
||||
Jekyll.logger.info "Generating..."
|
||||
process_site(site)
|
||||
Jekyll.logger.info "", "done."
|
||||
end
|
||||
|
||||
# Private: Watch for file changes and rebuild the site.
|
||||
#
|
||||
# site - A Jekyll::Site instance
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def watch(site, options)
|
||||
Deprecator.gracefully_require 'jekyll-watch'
|
||||
Jekyll::Watcher.watch(options)
|
||||
end
|
||||
|
||||
end # end of class << self
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
30
lib/jekyll/commands/docs.rb
Normal file
30
lib/jekyll/commands/docs.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Docs < Command
|
||||
|
||||
class << self
|
||||
|
||||
def init_with_program(prog)
|
||||
prog.command(:docs) do |c|
|
||||
c.syntax 'docs'
|
||||
c.description "Launch local server with docs for Jekyll v#{Jekyll::VERSION}"
|
||||
|
||||
c.option 'port', '-P', '--port [PORT]', 'Port to listen on'
|
||||
c.option 'host', '-H', '--host [HOST]', 'Host to bind to'
|
||||
|
||||
c.action do |args, options|
|
||||
options.merge!({
|
||||
'source' => File.expand_path("../../../site", File.dirname(__FILE__)),
|
||||
'destination' => File.expand_path("../../../site/_site", File.dirname(__FILE__))
|
||||
})
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,8 +2,23 @@ module Jekyll
|
||||
module Commands
|
||||
class Doctor < Command
|
||||
class << self
|
||||
|
||||
def init_with_program(prog)
|
||||
prog.command(:doctor) do |c|
|
||||
c.syntax 'doctor'
|
||||
c.description 'Search site and print specific deprecation warnings'
|
||||
c.alias(:hyde)
|
||||
|
||||
c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
|
||||
c.action do |args, options|
|
||||
Jekyll::Commands::Doctor.process(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process(options)
|
||||
site = Jekyll::Site.new(options)
|
||||
site = Jekyll::Site.new(configuration_from_options(options))
|
||||
site.read
|
||||
|
||||
if healthy?(site)
|
||||
@@ -26,7 +41,7 @@ module Jekyll
|
||||
if page.uses_relative_permalinks
|
||||
Jekyll.logger.warn "Deprecation:", "'#{page.path}' uses relative" +
|
||||
" permalinks which will be deprecated in" +
|
||||
" Jekyll v1.2 and beyond."
|
||||
" Jekyll v2.0.0 and beyond."
|
||||
contains_deprecated_pages = true
|
||||
end
|
||||
end
|
||||
@@ -61,7 +76,9 @@ module Jekyll
|
||||
end
|
||||
urls
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
33
lib/jekyll/commands/help.rb
Normal file
33
lib/jekyll/commands/help.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Help < Command
|
||||
class << self
|
||||
|
||||
def init_with_program(prog)
|
||||
prog.command(:help) do |c|
|
||||
c.syntax 'help [subcommand]'
|
||||
c.description 'Show the help message, optionally for a given subcommand.'
|
||||
|
||||
c.action do |args, _|
|
||||
cmd = (args.first || "").to_sym
|
||||
if args.empty?
|
||||
puts prog
|
||||
elsif prog.has_command? cmd
|
||||
puts prog.commands[cmd]
|
||||
else
|
||||
invalid_command(prog, cmd)
|
||||
abort
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def invalid_command(prog, cmd)
|
||||
Jekyll.logger.error "Error:", "Hmm... we don't know what the '#{cmd}' command is."
|
||||
Jekyll.logger.info "Valid commands:", prog.commands.keys.join(", ")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,27 +3,40 @@ require 'erb'
|
||||
module Jekyll
|
||||
module Commands
|
||||
class New < Command
|
||||
def self.init_with_program(prog)
|
||||
prog.command(:new) do |c|
|
||||
c.syntax 'new PATH'
|
||||
c.description 'Creates a new Jekyll site scaffold in PATH'
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
def self.process(args, options = {})
|
||||
raise ArgumentError.new('You must specify a path.') if args.empty?
|
||||
|
||||
new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
|
||||
FileUtils.mkdir_p new_blog_path
|
||||
if preserve_source_location?(new_blog_path, options)
|
||||
Jekyll.logger.error "Conflict:", "#{new_blog_path} exists and is not empty."
|
||||
exit(1)
|
||||
Jekyll.logger.abort_with "Conflict:", "#{new_blog_path} exists and is not empty."
|
||||
end
|
||||
|
||||
if options[:blank]
|
||||
if options["blank"]
|
||||
create_blank_site new_blog_path
|
||||
else
|
||||
create_sample_files new_blog_path
|
||||
|
||||
File.open(File.expand_path(self.initialized_post_name, new_blog_path), "w") do |f|
|
||||
f.write(self.scaffold_post_content)
|
||||
File.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
|
||||
f.write(scaffold_post_content)
|
||||
end
|
||||
end
|
||||
|
||||
puts "New jekyll site installed in #{new_blog_path}."
|
||||
Jekyll.logger.info "New jekyll site installed in #{new_blog_path}."
|
||||
end
|
||||
|
||||
def self.create_blank_site(path)
|
||||
@@ -47,7 +60,7 @@ module Jekyll
|
||||
private
|
||||
|
||||
def self.preserve_source_location?(path, options)
|
||||
!options[:force] && !Dir["#{path}/**/*"].empty?
|
||||
!options["force"] && !Dir["#{path}/**/*"].empty?
|
||||
end
|
||||
|
||||
def self.create_sample_files(path)
|
||||
|
||||
@@ -2,64 +2,128 @@
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve < Command
|
||||
def self.process(options)
|
||||
require 'webrick'
|
||||
include WEBrick
|
||||
|
||||
destination = options['destination']
|
||||
class << self
|
||||
|
||||
FileUtils.mkdir_p(destination)
|
||||
def init_with_program(prog)
|
||||
prog.command(:serve) do |c|
|
||||
c.syntax 'serve [options]'
|
||||
c.description 'Serve your site locally'
|
||||
c.alias :server
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
c.option 'detach', '-B', '--detach', 'Run the server in the background (detach)'
|
||||
c.option 'port', '-P', '--port [PORT]', 'Port to listen on'
|
||||
c.option 'host', '-H', '--host [HOST]', 'Host to bind to'
|
||||
c.option 'baseurl', '-b', '--baseurl [URL]', 'Base URL'
|
||||
c.option 'skip_initial_build', '--skip-initial-build', 'Skips the initial site build which occurs before the server is started.'
|
||||
|
||||
c.action do |args, options|
|
||||
options["serving"] ||= true
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Boot up a WEBrick server which points to the compiled site's root.
|
||||
def process(options)
|
||||
options = configuration_from_options(options)
|
||||
destination = options['destination']
|
||||
setup(destination)
|
||||
|
||||
s = WEBrick::HTTPServer.new(webrick_options(options))
|
||||
s.unmount("")
|
||||
|
||||
s.mount(
|
||||
options['baseurl'],
|
||||
WEBrick::HTTPServlet::FileHandler,
|
||||
destination,
|
||||
file_handler_options
|
||||
)
|
||||
|
||||
Jekyll.logger.info "Server address:", server_address(s, options)
|
||||
|
||||
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."
|
||||
else # create a new server thread, then join it with current terminal
|
||||
t = Thread.new { s.start }
|
||||
trap("INT") { s.shutdown }
|
||||
t.join
|
||||
end
|
||||
end
|
||||
|
||||
def setup(destination)
|
||||
require 'webrick'
|
||||
|
||||
FileUtils.mkdir_p(destination)
|
||||
|
||||
# monkey patch WEBrick using custom 404 page (/404.html)
|
||||
if File.exist?(File.join(destination, '404.html'))
|
||||
WEBrick::HTTPResponse.class_eval do
|
||||
def create_error_page
|
||||
@header['content-type'] = "text/html; charset=UTF-8"
|
||||
@body = IO.read(File.join(@config[:DocumentRoot], '404.html'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def webrick_options(config)
|
||||
opts = {
|
||||
:DocumentRoot => config['destination'],
|
||||
:Port => config['port'],
|
||||
:BindAddress => config['host'],
|
||||
:MimeTypes => mime_types,
|
||||
:DoNotReverseLookup => true,
|
||||
:StartCallback => start_callback(config['detach']),
|
||||
:DirectoryIndex => %w(index.html index.htm index.cgi index.rhtml index.xml)
|
||||
}
|
||||
|
||||
if !config['verbose']
|
||||
opts.merge!({
|
||||
:AccessLog => [],
|
||||
:Logger => WEBrick::Log.new([], WEBrick::Log::WARN)
|
||||
})
|
||||
end
|
||||
|
||||
opts
|
||||
end
|
||||
|
||||
def start_callback(detached)
|
||||
unless detached
|
||||
Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
|
||||
end
|
||||
end
|
||||
|
||||
def mime_types
|
||||
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
||||
WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
||||
end
|
||||
|
||||
def server_address(server, options)
|
||||
baseurl = "#{options['baseurl']}/" if options['baseurl']
|
||||
[
|
||||
"http://",
|
||||
server.config[:BindAddress],
|
||||
":",
|
||||
server.config[:Port],
|
||||
baseurl || ""
|
||||
].map(&:to_s).join("")
|
||||
end
|
||||
|
||||
# recreate NondisclosureName under utf-8 circumstance
|
||||
fh_option = WEBrick::Config::FileHandler
|
||||
fh_option[:NondisclosureName] = ['.ht*','~*']
|
||||
|
||||
s = HTTPServer.new(webrick_options(options))
|
||||
|
||||
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
|
||||
|
||||
Jekyll.logger.info "Server address:", "http://#{s.config[:BindAddress]}:#{s.config[:Port]}"
|
||||
|
||||
if options['detach'] # detach the server
|
||||
pid = Process.fork { s.start }
|
||||
Process.detach(pid)
|
||||
Jekyll.logger.info "Server detatched with pid '#{pid}'.", "Run `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 }
|
||||
t.join()
|
||||
end
|
||||
end
|
||||
|
||||
def self.webrick_options(config)
|
||||
opts = {
|
||||
:Port => config['port'],
|
||||
:BindAddress => config['host'],
|
||||
:MimeTypes => self.mime_types,
|
||||
:DoNotReverseLookup => true,
|
||||
:StartCallback => start_callback(config['detach'])
|
||||
}
|
||||
|
||||
if !config['verbose']
|
||||
opts.merge!({
|
||||
:AccessLog => [],
|
||||
:Logger => Log::new([], Log::WARN)
|
||||
})
|
||||
def file_handler_options
|
||||
fh_option = WEBrick::Config::FileHandler
|
||||
fh_option[:NondisclosureName] = ['.ht*','~*']
|
||||
fh_option
|
||||
end
|
||||
|
||||
opts
|
||||
end
|
||||
|
||||
def self.start_callback(detached)
|
||||
unless detached
|
||||
Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
|
||||
end
|
||||
end
|
||||
|
||||
def self.mime_types
|
||||
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
||||
WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,50 +6,63 @@ module Jekyll
|
||||
# Default options. Overridden by values in _config.yml.
|
||||
# Strings rather than symbols are used for compatibility with YAML.
|
||||
DEFAULTS = {
|
||||
# Where things are
|
||||
'source' => Dir.pwd,
|
||||
'destination' => File.join(Dir.pwd, '_site'),
|
||||
'plugins' => '_plugins',
|
||||
'layouts' => '_layouts',
|
||||
'data_source' => '_data',
|
||||
'keep_files' => ['.git','.svn'],
|
||||
'gems' => [],
|
||||
|
||||
'timezone' => nil, # use the local timezone
|
||||
|
||||
'encoding' => nil, # use the system encoding
|
||||
'collections' => nil,
|
||||
|
||||
# Handling Reading
|
||||
'safe' => false,
|
||||
'detach' => false, # default to not detaching the server
|
||||
'show_drafts' => nil,
|
||||
'limit_posts' => 0,
|
||||
'lsi' => false,
|
||||
'future' => true, # remove and make true just default
|
||||
'pygments' => true,
|
||||
|
||||
'relative_permalinks' => true, # backwards-compatibility with < 1.0
|
||||
# will be set to false once 2.0 hits
|
||||
|
||||
'markdown' => 'maruku',
|
||||
'permalink' => 'date',
|
||||
'baseurl' => '/',
|
||||
'include' => ['.htaccess'],
|
||||
'exclude' => [],
|
||||
'paginate_path' => '/page:num',
|
||||
|
||||
'markdown_ext' => 'markdown,mkd,mkdn,md',
|
||||
'keep_files' => ['.git','.svn'],
|
||||
'encoding' => 'utf-8',
|
||||
'markdown_ext' => 'markdown,mkdown,mkdn,mkd,md',
|
||||
'textile_ext' => 'textile',
|
||||
|
||||
# Filtering Content
|
||||
'show_drafts' => nil,
|
||||
'limit_posts' => 0,
|
||||
'future' => true, # remove and make true just default
|
||||
'unpublished' => false,
|
||||
|
||||
# Plugins
|
||||
'whitelist' => [],
|
||||
'gems' => [],
|
||||
|
||||
# Conversion
|
||||
'markdown' => 'kramdown',
|
||||
'highlighter' => 'pygments',
|
||||
'lsi' => false,
|
||||
'excerpt_separator' => "\n\n",
|
||||
|
||||
# Serving
|
||||
'detach' => false, # default to not detaching the server
|
||||
'port' => '4000',
|
||||
'host' => '0.0.0.0',
|
||||
'baseurl' => '',
|
||||
|
||||
'excerpt_separator' => "\n\n",
|
||||
# Backwards-compatibility options
|
||||
'relative_permalinks' => false,
|
||||
|
||||
# Output Configuration
|
||||
'permalink' => 'date',
|
||||
'paginate_path' => '/page:num',
|
||||
'timezone' => nil, # use the local timezone
|
||||
|
||||
'quiet' => false,
|
||||
'defaults' => [],
|
||||
|
||||
'maruku' => {
|
||||
'use_tex' => false,
|
||||
'use_divs' => false,
|
||||
'png_engine' => 'blahtex',
|
||||
'png_dir' => 'images/latex',
|
||||
'png_url' => '/images/latex'
|
||||
'png_url' => '/images/latex',
|
||||
'fenced_code_blocks' => true
|
||||
},
|
||||
|
||||
'rdiscount' => {
|
||||
@@ -99,12 +112,16 @@ module Jekyll
|
||||
override['source'] || self['source'] || DEFAULTS['source']
|
||||
end
|
||||
|
||||
def quiet?(override = {})
|
||||
override['quiet'] || self['quiet'] || DEFAULTS['quiet']
|
||||
end
|
||||
|
||||
def safe_load_file(filename)
|
||||
case File.extname(filename)
|
||||
when '.toml'
|
||||
when /\.toml/i
|
||||
TOML.load_file(filename)
|
||||
when /\.y(a)?ml/
|
||||
YAML.safe_load_file(filename)
|
||||
when /\.ya?ml/i
|
||||
SafeYAML.load_file(filename)
|
||||
else
|
||||
raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
|
||||
end
|
||||
@@ -116,10 +133,16 @@ module Jekyll
|
||||
#
|
||||
# Returns an Array of config files
|
||||
def config_files(override)
|
||||
# Be quiet quickly.
|
||||
Jekyll.logger.log_level = :error if quiet?(override)
|
||||
|
||||
# Get configuration from <source>/_config.yml or <source>/<config_file>
|
||||
config_files = override.delete('config')
|
||||
if config_files.to_s.empty?
|
||||
config_files = File.join(source(override), "_config.yml")
|
||||
default = %w[yml yaml].find(Proc.new { 'yml' }) do |ext|
|
||||
File.exists? Jekyll.sanitized_path(source(override), "_config.#{ext}")
|
||||
end
|
||||
config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
|
||||
@default_config_file = true
|
||||
end
|
||||
config_files = [config_files] unless config_files.is_a? Array
|
||||
@@ -158,7 +181,7 @@ module Jekyll
|
||||
begin
|
||||
files.each do |config_file|
|
||||
new_config = read_config_file(config_file)
|
||||
configuration = configuration.deep_merge(new_config)
|
||||
configuration = Utils.deep_merge_hashes(configuration, new_config)
|
||||
end
|
||||
rescue ArgumentError => err
|
||||
Jekyll.logger.warn "WARNING:", "Error reading configuration. " +
|
||||
@@ -185,7 +208,7 @@ module Jekyll
|
||||
def backwards_compatibilize
|
||||
config = clone
|
||||
# Provide backwards-compatibility
|
||||
if config.has_key?('auto') || config.has_key?('watch')
|
||||
if config.key?('auto') || config.key?('watch')
|
||||
Jekyll.logger.warn "Deprecation:", "Auto-regeneration can no longer" +
|
||||
" be set from your configuration file(s). Use the"+
|
||||
" --watch/-w command-line option instead."
|
||||
@@ -193,22 +216,32 @@ module Jekyll
|
||||
config.delete('watch')
|
||||
end
|
||||
|
||||
if config.has_key? 'server'
|
||||
if config.key? 'server'
|
||||
Jekyll.logger.warn "Deprecation:", "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.has_key? 'server_port'
|
||||
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.has_key?('port')
|
||||
config['port'] = config['server_port'] unless config.key?('port')
|
||||
config.delete('server_port')
|
||||
end
|
||||
|
||||
if config.key? 'pygments'
|
||||
Jekyll.logger.warn "Deprecation:", "The 'pygments' configuration option" +
|
||||
" has been renamed to 'highlighter'. Please update your" +
|
||||
" config file accordingly. The allowed values are 'rouge', " +
|
||||
"'pygments' or null."
|
||||
|
||||
config['highlighter'] = 'pygments' if config['pygments']
|
||||
config.delete('pygments')
|
||||
end
|
||||
|
||||
%w[include exclude].each do |option|
|
||||
if config.fetch(option, []).is_a?(String)
|
||||
Jekyll.logger.warn "Deprecation:", "The '#{option}' configuration option" +
|
||||
@@ -217,6 +250,13 @@ module Jekyll
|
||||
" as a list of comma-separated values."
|
||||
config[option] = csv_to_array(config[option])
|
||||
end
|
||||
config[option].map!(&:to_s)
|
||||
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."
|
||||
end
|
||||
config
|
||||
end
|
||||
@@ -224,7 +264,7 @@ module Jekyll
|
||||
def fix_common_issues
|
||||
config = clone
|
||||
|
||||
if config.has_key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
|
||||
if config.key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
|
||||
Jekyll.logger.warn "Config Warning:", "The `paginate` key must be a" +
|
||||
" positive integer or nil. It's currently set to '#{config['paginate'].inspect}'."
|
||||
config['paginate'] = nil
|
||||
@@ -232,6 +272,5 @@ module Jekyll
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
module Jekyll
|
||||
class Converter < Plugin
|
||||
# Public: Get or set the pygments prefix. When an argument is specified,
|
||||
# Public: Get or set the highlighter prefix. When an argument is specified,
|
||||
# the prefix will be set. If no argument is specified, the current prefix
|
||||
# will be returned.
|
||||
#
|
||||
# pygments_prefix - The String prefix (default: nil).
|
||||
# highlighter_prefix - The String prefix (default: nil).
|
||||
#
|
||||
# Returns the String prefix.
|
||||
def self.pygments_prefix(pygments_prefix = nil)
|
||||
@pygments_prefix = pygments_prefix if pygments_prefix
|
||||
@pygments_prefix
|
||||
def self.highlighter_prefix(highlighter_prefix = nil)
|
||||
@highlighter_prefix = highlighter_prefix if highlighter_prefix
|
||||
@highlighter_prefix
|
||||
end
|
||||
|
||||
# Public: Get or set the pygments suffix. When an argument is specified,
|
||||
# Public: Get or set the highlighter suffix. When an argument is specified,
|
||||
# the suffix will be set. If no argument is specified, the current suffix
|
||||
# will be returned.
|
||||
#
|
||||
# pygments_suffix - The String suffix (default: nil).
|
||||
# highlighter_suffix - The String suffix (default: nil).
|
||||
#
|
||||
# Returns the String suffix.
|
||||
def self.pygments_suffix(pygments_suffix = nil)
|
||||
@pygments_suffix = pygments_suffix if pygments_suffix
|
||||
@pygments_suffix
|
||||
def self.highlighter_suffix(highlighter_suffix = nil)
|
||||
@highlighter_suffix = highlighter_suffix if highlighter_suffix
|
||||
@highlighter_suffix
|
||||
end
|
||||
|
||||
# Initialize the converter.
|
||||
@@ -31,18 +31,18 @@ module Jekyll
|
||||
@config = config
|
||||
end
|
||||
|
||||
# Get the pygments prefix.
|
||||
# Get the highlighter prefix.
|
||||
#
|
||||
# Returns the String prefix.
|
||||
def pygments_prefix
|
||||
self.class.pygments_prefix
|
||||
def highlighter_prefix
|
||||
self.class.highlighter_prefix
|
||||
end
|
||||
|
||||
# Get the pygments suffix.
|
||||
# Get the highlighter suffix.
|
||||
#
|
||||
# Returns the String suffix.
|
||||
def pygments_suffix
|
||||
self.class.pygments_suffix
|
||||
def highlighter_suffix
|
||||
self.class.highlighter_suffix
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,28 +3,49 @@ module Jekyll
|
||||
class Markdown < Converter
|
||||
safe true
|
||||
|
||||
pygments_prefix "\n"
|
||||
pygments_suffix "\n"
|
||||
highlighter_prefix "\n"
|
||||
highlighter_suffix "\n"
|
||||
|
||||
def setup
|
||||
return if @setup
|
||||
@parser = case @config['markdown']
|
||||
when 'redcarpet'
|
||||
RedcarpetParser.new @config
|
||||
when 'kramdown'
|
||||
KramdownParser.new @config
|
||||
when 'rdiscount'
|
||||
RDiscountParser.new @config
|
||||
when 'maruku'
|
||||
MarukuParser.new @config
|
||||
@parser =
|
||||
case @config['markdown'].downcase
|
||||
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
|
||||
STDERR.puts "Invalid Markdown processor: #{@config['markdown']}"
|
||||
STDERR.puts " Valid options are [ maruku | rdiscount | kramdown | redcarpet ]"
|
||||
raise FatalException.new("Invalid Markdown process: #{@config['markdown']}")
|
||||
end
|
||||
# So they can't try some tricky bullshit or go down the ancestor chain, I hope.
|
||||
if allowed_custom_class?(@config['markdown'])
|
||||
self.class.const_get(@config['markdown']).new(@config)
|
||||
else
|
||||
Jekyll.logger.error "Invalid Markdown Processor:", "#{@config['markdown']}"
|
||||
Jekyll.logger.error "", "Valid options are [ #{valid_processors.join(" | ")} ]"
|
||||
raise Errors::FatalException, "Invalid Markdown Processor: #{@config['markdown']}"
|
||||
end
|
||||
end
|
||||
@setup = true
|
||||
end
|
||||
|
||||
def valid_processors
|
||||
%w[
|
||||
maruku
|
||||
rdiscount
|
||||
kramdown
|
||||
redcarpet
|
||||
] + third_party_processors
|
||||
end
|
||||
|
||||
def third_party_processors
|
||||
self.class.constants - %w[
|
||||
KramdownParser
|
||||
MarukuParser
|
||||
RDiscountParser
|
||||
RedcarpetParser
|
||||
PRIORITIES
|
||||
].map(&:to_sym)
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
rgx = '^\.(' + @config['markdown_ext'].gsub(',','|') +')$'
|
||||
ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
|
||||
@@ -38,6 +59,19 @@ module Jekyll
|
||||
setup
|
||||
@parser.convert(content)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Private: Determine whether a class name is an allowed custom markdown
|
||||
# class name
|
||||
#
|
||||
# parser_name - the name of the parser class
|
||||
#
|
||||
# Returns true if the parser name contains only alphanumeric characters
|
||||
# and is defined within Jekyll::Converters::Markdown
|
||||
def allowed_custom_class?(parser_name)
|
||||
parser_name !~ /[^A-Za-z0-9]/ && self.class.constants.include?(parser_name.to_sym)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@ module Jekyll
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install kramdown'
|
||||
raise FatalException.new("Missing dependency: kramdown")
|
||||
raise Errors::FatalException.new("Missing dependency: kramdown")
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
@@ -16,11 +16,11 @@ module Jekyll
|
||||
if @config['kramdown']['use_coderay']
|
||||
%w[wrap line_numbers line_numbers_start tab_width bold_every css default_lang].each do |opt|
|
||||
key = "coderay_#{opt}"
|
||||
@config['kramdown'][key] = @config['kramdown']['coderay'][key] unless @config['kramdown'].has_key?(key)
|
||||
@config['kramdown'][key] = @config['kramdown']['coderay'][key] unless @config['kramdown'].key?(key)
|
||||
end
|
||||
end
|
||||
|
||||
Kramdown::Document.new(content, @config["kramdown"].symbolize_keys).to_html
|
||||
Kramdown::Document.new(content, Utils.symbolize_hash_keys(@config["kramdown"])).to_html
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -8,10 +8,14 @@ module Jekyll
|
||||
@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 FatalException.new("Missing dependency: maruku")
|
||||
raise Errors::FatalException.new("Missing dependency: maruku")
|
||||
end
|
||||
|
||||
def load_divs_library
|
||||
|
||||
@@ -3,13 +3,9 @@ module Jekyll
|
||||
class Markdown
|
||||
class RDiscountParser
|
||||
def initialize(config)
|
||||
require 'rdiscount'
|
||||
Jekyll::Deprecator.gracefully_require "rdiscount"
|
||||
@config = config
|
||||
@rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym }
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install rdiscount'
|
||||
raise FatalException.new("Missing dependency: rdiscount")
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
|
||||
@@ -5,7 +5,8 @@ module Jekyll
|
||||
|
||||
module CommonMethods
|
||||
def add_code_tags(code, lang)
|
||||
code = code.sub(/<pre>/, "<pre><code class=\"#{lang} language-#{lang}\" data-lang=\"#{lang}\">")
|
||||
code = code.to_s
|
||||
code = code.sub(/<pre>/, "<pre><code class=\"language-#{lang}\" data-lang=\"#{lang}\">")
|
||||
code = code.sub(/<\/pre>/,"</code></pre>")
|
||||
end
|
||||
end
|
||||
@@ -13,16 +14,16 @@ module Jekyll
|
||||
module WithPygments
|
||||
include CommonMethods
|
||||
def block_code(code, lang)
|
||||
require 'pygments'
|
||||
Jekyll::Deprecator.gracefully_require("pygments")
|
||||
lang = lang && lang.split.first || "text"
|
||||
output = add_code_tags(
|
||||
add_code_tags(
|
||||
Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
|
||||
lang
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
module WithoutPygments
|
||||
module WithoutHighlighting
|
||||
require 'cgi'
|
||||
|
||||
include CommonMethods
|
||||
@@ -33,29 +34,61 @@ module Jekyll
|
||||
|
||||
def block_code(code, lang)
|
||||
lang = lang && lang.split.first || "text"
|
||||
output = add_code_tags(code_wrap(code), lang)
|
||||
add_code_tags(code_wrap(code), lang)
|
||||
end
|
||||
end
|
||||
|
||||
module WithRouge
|
||||
def block_code(code, lang)
|
||||
code = "<pre>#{super}</pre>"
|
||||
|
||||
output = "<div class=\"highlight\">"
|
||||
output << add_code_tags(code, lang)
|
||||
output << "</div>"
|
||||
end
|
||||
|
||||
protected
|
||||
def rouge_formatter(opts = {})
|
||||
Rouge::Formatters::HTML.new(opts.merge(wrap: false))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def initialize(config)
|
||||
require 'redcarpet'
|
||||
Deprecator.gracefully_require("redcarpet")
|
||||
@config = config
|
||||
@redcarpet_extensions = {}
|
||||
@config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true }
|
||||
|
||||
@renderer ||= if @config['pygments']
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithPygments
|
||||
end
|
||||
else
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithoutPygments
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install redcarpet'
|
||||
raise FatalException.new("Missing dependency: redcarpet")
|
||||
@renderer ||= class_with_proper_highlighter(@config['highlighter'])
|
||||
end
|
||||
|
||||
def class_with_proper_highlighter(highlighter)
|
||||
case highlighter
|
||||
when "pygments"
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithPygments
|
||||
end
|
||||
when "rouge"
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
Jekyll::Deprecator.gracefully_require(%w[
|
||||
rouge
|
||||
rouge/plugins/redcarpet
|
||||
])
|
||||
|
||||
if Rouge.version < '1.3.0'
|
||||
abort "Please install Rouge 1.3.0 or greater and try running Jekyll again."
|
||||
end
|
||||
|
||||
include Rouge::Plugins::Redcarpet
|
||||
include CommonMethods
|
||||
include WithRouge
|
||||
end
|
||||
else
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithoutHighlighting
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
|
||||
@@ -3,8 +3,8 @@ module Jekyll
|
||||
class Textile < Converter
|
||||
safe true
|
||||
|
||||
pygments_prefix '<notextile>'
|
||||
pygments_suffix '</notextile>'
|
||||
highlighter_prefix '<notextile>'
|
||||
highlighter_suffix '</notextile>'
|
||||
|
||||
def setup
|
||||
return if @setup
|
||||
@@ -13,7 +13,7 @@ module Jekyll
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Textile. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install RedCloth'
|
||||
raise FatalException.new("Missing dependency: RedCloth")
|
||||
raise Errors::FatalException.new("Missing dependency: RedCloth")
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
@@ -32,7 +32,7 @@ module Jekyll
|
||||
return RedCloth.new(content).to_html if @config['redcloth'].nil?
|
||||
|
||||
# List of attributes defined on RedCloth
|
||||
# (from http://redcloth.rubyforge.org/classes/RedCloth/TextileDoc.html)
|
||||
# (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']
|
||||
|
||||
|
||||
@@ -13,17 +13,25 @@ require 'set'
|
||||
# self.ext=
|
||||
# self.output=
|
||||
# self.name
|
||||
# self.path
|
||||
# self.type -> :page, :post or :draft
|
||||
|
||||
module Jekyll
|
||||
module Convertible
|
||||
# Returns the contents as a String.
|
||||
def to_s
|
||||
self.content || ''
|
||||
content || ''
|
||||
end
|
||||
|
||||
# Returns merged optin hash for File.read of self.site (if exists)
|
||||
# Whether the file is published or not, as indicated in YAML front-matter
|
||||
def published?
|
||||
!(data.key?('published') && data['published'] == false)
|
||||
end
|
||||
|
||||
# Returns merged option hash for File.read of self.site (if exists)
|
||||
# and a given param
|
||||
def merged_file_read_opts(opts)
|
||||
(self.site ? self.site.file_read_opts : {}).merge(opts)
|
||||
(site ? site.file_read_opts : {}).merge(opts)
|
||||
end
|
||||
|
||||
# Read the YAML frontmatter.
|
||||
@@ -35,16 +43,16 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def read_yaml(base, name, opts = {})
|
||||
begin
|
||||
self.content = File.read_with_options(File.join(base, name),
|
||||
merged_file_read_opts(opts))
|
||||
if self.content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
||||
self.content = File.read(Jekyll.sanitized_path(base, name),
|
||||
merged_file_read_opts(opts))
|
||||
if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
|
||||
self.content = $POSTMATCH
|
||||
self.data = YAML.safe_load($1)
|
||||
self.data = SafeYAML.load($1)
|
||||
end
|
||||
rescue SyntaxError => e
|
||||
puts "YAML Exception reading #{File.join(base, name)}: #{e.message}"
|
||||
Jekyll.logger.warn "YAML Exception reading #{File.join(base, name)}: #{e.message}"
|
||||
rescue Exception => e
|
||||
puts "Error reading file #{File.join(base, name)}: #{e.message}"
|
||||
Jekyll.logger.warn "Error reading file #{File.join(base, name)}: #{e.message}"
|
||||
end
|
||||
|
||||
self.data ||= {}
|
||||
@@ -54,11 +62,14 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def transform
|
||||
self.content = converter.convert(self.content)
|
||||
rescue => e
|
||||
Jekyll.logger.error "Conversion error:", "There was an error converting" +
|
||||
" '#{self.path}'."
|
||||
raise e
|
||||
converters.reduce(content) do |output, converter|
|
||||
begin
|
||||
converter.convert output
|
||||
rescue => e
|
||||
Jekyll.logger.error "Conversion error:", "#{converter.class} encountered an error converting '#{path}'."
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Determine the extension depending on content_type.
|
||||
@@ -66,15 +77,21 @@ module Jekyll
|
||||
# Returns the String extension for the output file.
|
||||
# e.g. ".html" for an HTML output file.
|
||||
def output_ext
|
||||
converter.output_ext(self.ext)
|
||||
if converters.all? { |c| c.is_a?(Jekyll::Converters::Identity) }
|
||||
ext
|
||||
else
|
||||
converters.map { |c|
|
||||
c.output_ext(ext) unless c.is_a?(Jekyll::Converters::Identity)
|
||||
}.compact.last
|
||||
end
|
||||
end
|
||||
|
||||
# Determine which converter to use based on this convertible's
|
||||
# extension.
|
||||
#
|
||||
# Returns the Converter instance.
|
||||
def converter
|
||||
@converter ||= self.site.converters.find { |c| c.matches(self.ext) }
|
||||
def converters
|
||||
@converters ||= site.converters.select { |c| c.matches(ext) }.sort
|
||||
end
|
||||
|
||||
# Render Liquid in the content
|
||||
@@ -101,7 +118,71 @@ module Jekyll
|
||||
further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map { |attribute|
|
||||
[attribute, send(attribute)]
|
||||
}]
|
||||
data.deep_merge(further_data)
|
||||
|
||||
defaults = site.frontmatter_defaults.all(relative_path, type)
|
||||
Utils.deep_merge_hashes defaults, Utils.deep_merge_hashes(data, further_data)
|
||||
end
|
||||
|
||||
# The type of a document,
|
||||
# i.e., its classname downcase'd and to_sym'd.
|
||||
#
|
||||
# Returns the type of self.
|
||||
def type
|
||||
if is_a?(Draft)
|
||||
:drafts
|
||||
elsif is_a?(Post)
|
||||
:posts
|
||||
elsif is_a?(Page)
|
||||
:pages
|
||||
end
|
||||
end
|
||||
|
||||
# Determine whether the document is an asset file.
|
||||
# Asset files include CoffeeScript files and Sass/SCSS files.
|
||||
#
|
||||
# Returns true if the extname belongs to the set of extensions
|
||||
# that asset files use.
|
||||
def asset_file?
|
||||
sass_file? || coffeescript_file?
|
||||
end
|
||||
|
||||
# Determine whether the document is a Sass file.
|
||||
#
|
||||
# Returns true if extname == .sass or .scss, false otherwise.
|
||||
def sass_file?
|
||||
%w[.sass .scss].include?(ext)
|
||||
end
|
||||
|
||||
# Determine whether the document is a CoffeeScript file.
|
||||
#
|
||||
# Returns true if extname == .coffee, false otherwise.
|
||||
def coffeescript_file?
|
||||
'.coffee'.eql?(ext)
|
||||
end
|
||||
|
||||
# Determine whether the file should be rendered with Liquid.
|
||||
#
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
# true otherwise.
|
||||
def render_with_liquid?
|
||||
!coffeescript_file?
|
||||
end
|
||||
|
||||
# Determine whether the file should be placed into layouts.
|
||||
#
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
# true otherwise.
|
||||
def place_in_layout?
|
||||
!asset_file?
|
||||
end
|
||||
|
||||
# Checks if the layout specified in the document actually exists
|
||||
#
|
||||
# layout - the layout to check
|
||||
#
|
||||
# Returns true if the layout is invalid, false if otherwise
|
||||
def invalid_layout?(layout)
|
||||
!data["layout"].nil? && layout.nil? && !(self.is_a? Jekyll::Excerpt)
|
||||
end
|
||||
|
||||
# Recursively render layouts
|
||||
@@ -113,16 +194,19 @@ module Jekyll
|
||||
# Returns nothing
|
||||
def render_all_layouts(layouts, payload, info)
|
||||
# recursively render layouts
|
||||
layout = layouts[self.data["layout"]]
|
||||
layout = layouts[data["layout"]]
|
||||
|
||||
Jekyll.logger.warn("Build Warning:", "Layout '#{data["layout"]}' requested in #{path} does not exist.") if invalid_layout? layout
|
||||
|
||||
used = Set.new([layout])
|
||||
|
||||
while layout
|
||||
payload = payload.deep_merge({"content" => self.output, "page" => layout.data})
|
||||
payload = Utils.deep_merge_hashes(payload, {"content" => output, "page" => layout.data})
|
||||
|
||||
self.output = self.render_liquid(layout.content,
|
||||
self.output = render_liquid(layout.content,
|
||||
payload,
|
||||
info,
|
||||
File.join(self.site.config['layouts'], layout.name))
|
||||
File.join(site.config['layouts'], layout.name))
|
||||
|
||||
if layout = layouts[layout.data["layout"]]
|
||||
if used.include?(layout)
|
||||
@@ -141,21 +225,19 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def do_layout(payload, layouts)
|
||||
info = { :filters => [Jekyll::Filters], :registers => { :site => self.site, :page => payload['page'] } }
|
||||
info = { :filters => [Jekyll::Filters], :registers => { :site => site, :page => payload['page'] } }
|
||||
|
||||
# render and transform content (this becomes the final content of the object)
|
||||
payload["pygments_prefix"] = converter.pygments_prefix
|
||||
payload["pygments_suffix"] = converter.pygments_suffix
|
||||
payload["highlighter_prefix"] = converters.first.highlighter_prefix
|
||||
payload["highlighter_suffix"] = converters.first.highlighter_suffix
|
||||
|
||||
self.content = self.render_liquid(self.content,
|
||||
payload,
|
||||
info)
|
||||
self.transform
|
||||
self.content = render_liquid(content, payload, info) if render_with_liquid?
|
||||
self.content = transform
|
||||
|
||||
# output keeps track of what will finally be written
|
||||
self.output = self.content
|
||||
self.output = content
|
||||
|
||||
self.render_all_layouts(layouts, payload, info)
|
||||
render_all_layouts(layouts, payload, info) if place_in_layout?
|
||||
end
|
||||
|
||||
# Write the generated page file to the destination directory.
|
||||
@@ -167,7 +249,20 @@ module Jekyll
|
||||
path = destination(dest)
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
File.open(path, 'wb') do |f|
|
||||
f.write(self.output)
|
||||
f.write(output)
|
||||
end
|
||||
end
|
||||
|
||||
# Accessor for data properties by Liquid.
|
||||
#
|
||||
# property - The String name of the property to retrieve.
|
||||
#
|
||||
# Returns the String value or nil if the property isn't included.
|
||||
def [](property)
|
||||
if self.class::ATTRIBUTES_FOR_LIQUID.include?(property)
|
||||
send(property)
|
||||
else
|
||||
data[property]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
class Hash
|
||||
# Merges self with another hash, recursively.
|
||||
#
|
||||
# This code was lovingly stolen from some random gem:
|
||||
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
|
||||
#
|
||||
# Thanks to whoever made it.
|
||||
def deep_merge(hash)
|
||||
target = dup
|
||||
|
||||
hash.keys.each do |key|
|
||||
if hash[key].is_a? Hash and self[key].is_a? Hash
|
||||
target[key] = target[key].deep_merge(hash[key])
|
||||
next
|
||||
end
|
||||
|
||||
target[key] = hash[key]
|
||||
end
|
||||
|
||||
target
|
||||
end
|
||||
|
||||
# Read array from the supplied hash favouring the singular key
|
||||
# and then the plural key, and handling any nil entries.
|
||||
# +hash+ the hash to read from
|
||||
# +singular_key+ the singular key
|
||||
# +plural_key+ the plural key
|
||||
#
|
||||
# Returns an array
|
||||
def pluralized_array(singular_key, plural_key)
|
||||
hash = self
|
||||
if hash.has_key?(singular_key)
|
||||
array = [hash[singular_key]] if hash[singular_key]
|
||||
elsif hash.has_key?(plural_key)
|
||||
case hash[plural_key]
|
||||
when String
|
||||
array = hash[plural_key].split
|
||||
when Array
|
||||
array = hash[plural_key].compact
|
||||
end
|
||||
end
|
||||
array || []
|
||||
end
|
||||
|
||||
def symbolize_keys!
|
||||
keys.each do |key|
|
||||
self[(key.to_sym rescue key) || key] = delete(key)
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def symbolize_keys
|
||||
dup.symbolize_keys!
|
||||
end
|
||||
end
|
||||
|
||||
# Thanks, ActiveSupport!
|
||||
class Date
|
||||
# Converts datetime to an appropriate format for use in XML
|
||||
def xmlschema
|
||||
strftime("%Y-%m-%dT%H:%M:%S%Z")
|
||||
end if RUBY_VERSION < '1.9'
|
||||
end
|
||||
|
||||
module Enumerable
|
||||
# Returns true if path matches against any glob pattern.
|
||||
# Look for more detail about glob pattern in method File::fnmatch.
|
||||
def glob_include?(e)
|
||||
any? { |exp| File.fnmatch?(exp, e) }
|
||||
end
|
||||
end
|
||||
|
||||
# Ruby 1.8's File.read don't support option.
|
||||
# read_with_options ignore optional parameter for 1.8,
|
||||
# and act as alias for 1.9 or later.
|
||||
class File
|
||||
if RUBY_VERSION < '1.9'
|
||||
def self.read_with_options(path, opts = {})
|
||||
self.read(path)
|
||||
end
|
||||
else
|
||||
def self.read_with_options(path, opts = {})
|
||||
self.read(path, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,8 @@
|
||||
module Jekyll
|
||||
class Deprecator
|
||||
def self.process(args)
|
||||
module Deprecator
|
||||
extend self
|
||||
|
||||
def process(args)
|
||||
no_subcommand(args)
|
||||
arg_is_present? args, "--server", "The --server command has been replaced by the \
|
||||
'serve' subcommand."
|
||||
@@ -9,28 +11,51 @@ module Jekyll
|
||||
arg_is_present? args, "--auto", "The switch '--auto' has been replaced with '--watch'."
|
||||
arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \
|
||||
the '--watch' switch."
|
||||
arg_is_present? args, "--pygments", "The 'pygments' setting can only be set in \
|
||||
your config files."
|
||||
arg_is_present? args, "--pygments", "The 'pygments'settings has been removed in \
|
||||
favour of 'highlighter'."
|
||||
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."
|
||||
end
|
||||
|
||||
def self.no_subcommand(args)
|
||||
def no_subcommand(args)
|
||||
if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first)
|
||||
Jekyll.logger.error "Deprecation:", "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."
|
||||
end
|
||||
end
|
||||
|
||||
def self.arg_is_present?(args, deprecated_argument, message)
|
||||
def arg_is_present?(args, deprecated_argument, message)
|
||||
if args.include?(deprecated_argument)
|
||||
deprecation_message(message)
|
||||
end
|
||||
end
|
||||
|
||||
def self.deprecation_message(message)
|
||||
def deprecation_message(message)
|
||||
Jekyll.logger.error "Deprecation:", message
|
||||
end
|
||||
|
||||
def defaults_deprecate_type(old, current)
|
||||
Jekyll.logger.warn "Defaults:", "The '#{old}' type has become '#{current}'."
|
||||
Jekyll.logger.warn "Defaults:", "Please update your front-matter defaults to use 'type: #{current}'."
|
||||
end
|
||||
|
||||
def gracefully_require(gem_name)
|
||||
Array(gem_name).each do |name|
|
||||
begin
|
||||
require name
|
||||
rescue LoadError => e
|
||||
Jekyll.logger.error "Dependency Error:", <<-MSG
|
||||
Yikes! It looks like you don't have #{name} or one of its dependencies installed.
|
||||
In order to use Jekyll as currently configured, you'll need to install this gem.
|
||||
|
||||
The full error message from Ruby is: '#{e.message}'
|
||||
|
||||
If you run into trouble, you can find helpful resources at http://jekyllrb.com/help/!
|
||||
MSG
|
||||
raise Errors::MissingDependencyException.new(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
277
lib/jekyll/document.rb
Normal file
277
lib/jekyll/document.rb
Normal file
@@ -0,0 +1,277 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
class Document
|
||||
include Comparable
|
||||
|
||||
attr_reader :path, :site
|
||||
attr_accessor :content, :collection, :output
|
||||
|
||||
# Create a new Document.
|
||||
#
|
||||
# site - the Jekyll::Site instance to which this Document belongs
|
||||
# path - the path to the file
|
||||
#
|
||||
# Returns nothing.
|
||||
def initialize(path, relations)
|
||||
@site = relations[:site]
|
||||
@path = path
|
||||
@collection = relations[:collection]
|
||||
@has_yaml_header = nil
|
||||
end
|
||||
|
||||
# Fetch the Document's data.
|
||||
#
|
||||
# Returns a Hash containing the data. An empty hash is returned if
|
||||
# no data was read.
|
||||
def data
|
||||
@data ||= Hash.new
|
||||
end
|
||||
|
||||
# The path to the document, relative to the site source.
|
||||
#
|
||||
# Returns a String path which represents the relative path
|
||||
# from the site source to this document
|
||||
def relative_path
|
||||
Pathname.new(path).relative_path_from(Pathname.new(site.source)).to_s
|
||||
end
|
||||
|
||||
# The base filename of the document.
|
||||
#
|
||||
# suffix - (optional) the suffix to be removed from the end of the filename
|
||||
#
|
||||
# Returns the base filename of the document.
|
||||
def basename(suffix = "")
|
||||
File.basename(path, suffix)
|
||||
end
|
||||
|
||||
# The extension name of the document.
|
||||
#
|
||||
# Returns the extension name of the document.
|
||||
def extname
|
||||
File.extname(path)
|
||||
end
|
||||
|
||||
# Produces a "cleaned" relative path.
|
||||
# The "cleaned" relative path is the relative path without the extname
|
||||
# and with the collection's directory removed as well.
|
||||
# This method is useful when building the URL of the document.
|
||||
#
|
||||
# Examples:
|
||||
# When relative_path is "_methods/site/generate.md":
|
||||
# cleaned_relative_path
|
||||
# # => "/site/generate"
|
||||
#
|
||||
# Returns the cleaned relative path of the document.
|
||||
def cleaned_relative_path
|
||||
relative_path[0 .. -extname.length - 1].sub(collection.relative_directory, "")
|
||||
end
|
||||
|
||||
# Determine whether the document is a YAML file.
|
||||
#
|
||||
# Returns true if the extname is either .yml or .yaml, false otherwise.
|
||||
def yaml_file?
|
||||
%w[.yaml .yml].include?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the document is an asset file.
|
||||
# Asset files include CoffeeScript files and Sass/SCSS files.
|
||||
#
|
||||
# Returns true if the extname belongs to the set of extensions
|
||||
# that asset files use.
|
||||
def asset_file?
|
||||
sass_file? || coffeescript_file?
|
||||
end
|
||||
|
||||
# Determine whether the document is a Sass file.
|
||||
#
|
||||
# Returns true if extname == .sass or .scss, false otherwise.
|
||||
def sass_file?
|
||||
%w[.sass .scss].include?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the document is a CoffeeScript file.
|
||||
#
|
||||
# Returns true if extname == .coffee, false otherwise.
|
||||
def coffeescript_file?
|
||||
'.coffee'.eql?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the file should be rendered with Liquid.
|
||||
#
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
# true otherwise.
|
||||
def render_with_liquid?
|
||||
!(coffeescript_file? || yaml_file?)
|
||||
end
|
||||
|
||||
# Determine whether the file should be placed into layouts.
|
||||
#
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
# true otherwise.
|
||||
def place_in_layout?
|
||||
!(asset_file? || yaml_file?)
|
||||
end
|
||||
|
||||
# The URL template where the document would be accessible.
|
||||
#
|
||||
# Returns the URL template for the document.
|
||||
def url_template
|
||||
collection.url_template
|
||||
end
|
||||
|
||||
# Construct a Hash of key-value pairs which contain a mapping between
|
||||
# a key in the URL template and the corresponding value for this document.
|
||||
#
|
||||
# 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
|
||||
}
|
||||
end
|
||||
|
||||
# The permalink for this Document.
|
||||
# Permalink is set via the data Hash.
|
||||
#
|
||||
# Returns the permalink or nil if no permalink was set in the data.
|
||||
def permalink
|
||||
data && data.is_a?(Hash) && data['permalink']
|
||||
end
|
||||
|
||||
# The computed URL for the document. See `Jekyll::URL#to_s` for more details.
|
||||
#
|
||||
# Returns the computed URL for the document.
|
||||
def url
|
||||
@url = URL.new({
|
||||
template: url_template,
|
||||
placeholders: url_placeholders,
|
||||
permalink: permalink
|
||||
}).to_s
|
||||
end
|
||||
|
||||
# The full path to the output file.
|
||||
#
|
||||
# base_directory - the base path of the output directory
|
||||
#
|
||||
# Returns the full path to the output file of this document.
|
||||
def destination(base_directory)
|
||||
path = Jekyll.sanitized_path(base_directory, url)
|
||||
path = File.join(path, "index.html") if url =~ /\/$/
|
||||
path
|
||||
end
|
||||
|
||||
# Write the generated Document file to the destination directory.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def write(dest)
|
||||
path = destination(dest)
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
File.open(path, 'wb') do |f|
|
||||
f.write(output)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns merged option hash for File.read of self.site (if exists)
|
||||
# and a given param
|
||||
#
|
||||
# opts - override options
|
||||
#
|
||||
# Return the file read options hash.
|
||||
def merged_file_read_opts(opts)
|
||||
site ? site.file_read_opts.merge(opts) : opts
|
||||
end
|
||||
|
||||
# Whether the file is published or not, as indicated in YAML front-matter
|
||||
#
|
||||
# Returns true if the 'published' key is specified in the YAML front-matter and not `false`.
|
||||
def published?
|
||||
!(data.key?('published') && data['published'] == false)
|
||||
end
|
||||
|
||||
# Read in the file and assign the content and data based on the file contents.
|
||||
# Merge the frontmatter of the file with the frontmatter default
|
||||
# values
|
||||
#
|
||||
# Returns nothing.
|
||||
def read(opts = {})
|
||||
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
|
||||
data_file = SafeYAML.load($1)
|
||||
unless data_file.nil?
|
||||
@data = Utils.deep_merge_hashes(defaults, data_file)
|
||||
end
|
||||
end
|
||||
rescue SyntaxError => e
|
||||
puts "YAML Exception reading #{path}: #{e.message}"
|
||||
rescue Exception => e
|
||||
puts "Error reading file #{path}: #{e.message}"
|
||||
end
|
||||
end
|
||||
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, {
|
||||
"output" => output,
|
||||
"content" => content,
|
||||
"path" => path,
|
||||
"relative_path" => relative_path,
|
||||
"url" => url,
|
||||
"collection" => collection.label
|
||||
}
|
||||
else
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
# The inspect string for this document.
|
||||
# Includes the relative path and the collection label.
|
||||
#
|
||||
# Returns the inspect string for this document.
|
||||
def inspect
|
||||
"#<Jekyll::Document #{relative_path} collection=#{collection.label}>"
|
||||
end
|
||||
|
||||
# The string representation for this document.
|
||||
#
|
||||
# Returns the content of the document
|
||||
def to_s
|
||||
content || ''
|
||||
end
|
||||
|
||||
# Compare this document against another document.
|
||||
# Comparison is a comparison between the 2 paths of the documents.
|
||||
#
|
||||
# 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
|
||||
end
|
||||
|
||||
# Determine whether this document should be written.
|
||||
# Based on the Collection to which it belongs.
|
||||
#
|
||||
# True if the document has a collection and if that collection's #write?
|
||||
# method returns true, otherwise false.
|
||||
def write?
|
||||
collection && collection.write?
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -18,6 +18,11 @@ module Jekyll
|
||||
File.join(source, 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.
|
||||
|
||||
@@ -1,35 +1,72 @@
|
||||
class EntryFilter
|
||||
attr_reader :site
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
module Jekyll
|
||||
class EntryFilter
|
||||
SPECIAL_LEADING_CHARACTERS = ['.', '_', '#'].freeze
|
||||
|
||||
def filter(entries)
|
||||
entries.reject do |e|
|
||||
unless included?(e)
|
||||
special?(e) || backup?(e) || excluded?(e) || symlink?(e)
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site, base_directory = nil)
|
||||
@site = site
|
||||
@base_directory = derive_base_directory(@site, base_directory.to_s.dup)
|
||||
end
|
||||
|
||||
def base_directory
|
||||
@base_directory.to_s
|
||||
end
|
||||
|
||||
def derive_base_directory(site, base_dir)
|
||||
if base_dir.start_with?(site.source)
|
||||
base_dir[site.source] = ""
|
||||
end
|
||||
base_dir
|
||||
end
|
||||
|
||||
def relative_to_source(entry)
|
||||
File.join(base_directory, entry)
|
||||
end
|
||||
|
||||
def filter(entries)
|
||||
entries.reject do |e|
|
||||
unless included?(e)
|
||||
special?(e) || backup?(e) || excluded?(e) || symlink?(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def included?(entry)
|
||||
glob_include?(site.include, entry)
|
||||
end
|
||||
|
||||
def special?(entry)
|
||||
SPECIAL_LEADING_CHARACTERS.include?(entry[0..0]) ||
|
||||
SPECIAL_LEADING_CHARACTERS.include?(File.basename(entry)[0..0])
|
||||
end
|
||||
|
||||
def backup?(entry)
|
||||
entry[-1..-1] == '~'
|
||||
end
|
||||
|
||||
def excluded?(entry)
|
||||
excluded = glob_include?(site.exclude, relative_to_source(entry))
|
||||
Jekyll.logger.debug "excluded?(#{relative_to_source(entry)}) ==> #{excluded}"
|
||||
excluded
|
||||
end
|
||||
|
||||
def symlink?(entry)
|
||||
File.symlink?(entry) && site.safe
|
||||
end
|
||||
|
||||
def ensure_leading_slash(path)
|
||||
path[0..0] == "/" ? path : "/#{path}"
|
||||
end
|
||||
|
||||
# Returns true if path matches against any glob pattern.
|
||||
# Look for more detail about glob pattern in method File::fnmatch.
|
||||
def glob_include?(enum, e)
|
||||
entry = ensure_leading_slash(e)
|
||||
enum.any? do |exp|
|
||||
item = ensure_leading_slash(exp)
|
||||
File.fnmatch?(item, entry) || entry.start_with?(item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def included?(entry)
|
||||
site.include.glob_include?(entry)
|
||||
end
|
||||
|
||||
def special?(entry)
|
||||
['.', '_', '#'].include?(entry[0..0])
|
||||
end
|
||||
|
||||
def backup?(entry)
|
||||
entry[-1..-1] == '~'
|
||||
end
|
||||
|
||||
def excluded?(entry)
|
||||
site.exclude.glob_include?(entry)
|
||||
end
|
||||
|
||||
def symlink?(entry)
|
||||
File.symlink?(entry) && site.safe
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
module Jekyll
|
||||
class FatalException < StandardError
|
||||
module Errors
|
||||
class FatalException < RuntimeError
|
||||
end
|
||||
|
||||
class MissingDependencyException < FatalException
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
require 'forwardable'
|
||||
|
||||
module Jekyll
|
||||
class Excerpt
|
||||
include Convertible
|
||||
extend Forwardable
|
||||
|
||||
attr_accessor :post
|
||||
attr_accessor :content, :output, :ext
|
||||
|
||||
def_delegator :@post, :site, :site
|
||||
def_delegator :@post, :name, :name
|
||||
def_delegator :@post, :ext, :ext
|
||||
|
||||
# Initialize this Post instance.
|
||||
#
|
||||
# site - The Site.
|
||||
@@ -17,14 +24,8 @@ module Jekyll
|
||||
self.content = extract_excerpt(post.content)
|
||||
end
|
||||
|
||||
%w[site name ext].each do |meth|
|
||||
define_method(meth) do
|
||||
post.send(meth)
|
||||
end
|
||||
end
|
||||
|
||||
def to_liquid
|
||||
post.to_liquid(Post::EXCERPT_ATTRIBUTES_FOR_LIQUID)
|
||||
post.to_liquid(post.class::EXCERPT_ATTRIBUTES_FOR_LIQUID)
|
||||
end
|
||||
|
||||
# Fetch YAML front-matter data from related post, without layout key
|
||||
@@ -37,7 +38,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
# 'Path' of the excerpt.
|
||||
#
|
||||
#
|
||||
# Returns the path for the post this excerpt belongs to with #excerpt appended
|
||||
def path
|
||||
File.join(post.path, "#excerpt")
|
||||
@@ -45,9 +46,9 @@ module Jekyll
|
||||
|
||||
# Check if excerpt includes a string
|
||||
#
|
||||
# Returns true if the string passed in
|
||||
# Returns true if the string passed in
|
||||
def include?(something)
|
||||
(self.output && self.output.include?(something)) || self.content.include?(something)
|
||||
(output && output.include?(something)) || content.include?(something)
|
||||
end
|
||||
|
||||
# The UID for this post (useful in feeds).
|
||||
@@ -59,7 +60,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
def to_s
|
||||
self.output || self.content
|
||||
output || content
|
||||
end
|
||||
|
||||
# Returns the shorthand String identifier of this Post.
|
||||
|
||||
@@ -25,6 +25,28 @@ module Jekyll
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Convert a Sass string into CSS output.
|
||||
#
|
||||
# input - The Sass String to convert.
|
||||
#
|
||||
# Returns the CSS formatted String.
|
||||
def sassify(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.getConverterImpl(Jekyll::Converters::Sass)
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Convert a Scss string into CSS output.
|
||||
#
|
||||
# input - The Scss String to convert.
|
||||
#
|
||||
# Returns the CSS formatted String.
|
||||
def scssify(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.getConverterImpl(Jekyll::Converters::Scss)
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Format a date in short format e.g. "27 Jan 2011".
|
||||
#
|
||||
# date - the Time to format.
|
||||
@@ -83,7 +105,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the escaped String.
|
||||
def xml_escape(input)
|
||||
CGI.escapeHTML(input)
|
||||
CGI.escapeHTML(input.to_s)
|
||||
end
|
||||
|
||||
# CGI escape a string for use in a URL. Replaces any special characters
|
||||
@@ -100,7 +122,7 @@ module Jekyll
|
||||
def cgi_escape(input)
|
||||
CGI::escape(input)
|
||||
end
|
||||
|
||||
|
||||
# URI escape a string.
|
||||
#
|
||||
# input - The String to escape.
|
||||
@@ -124,7 +146,7 @@ module Jekyll
|
||||
input.split.length
|
||||
end
|
||||
|
||||
# Join an array of things into a string by separating with commes and the
|
||||
# Join an array of things into a string by separating with commas and the
|
||||
# word "and" for the last one.
|
||||
#
|
||||
# array - The Array of Strings to join.
|
||||
@@ -155,7 +177,75 @@ module Jekyll
|
||||
#
|
||||
# Returns the converted json string
|
||||
def jsonify(input)
|
||||
input.to_json
|
||||
as_liquid(input).to_json
|
||||
end
|
||||
|
||||
# Group an array of items by a property
|
||||
#
|
||||
# input - the inputted Enumerable
|
||||
# property - the property
|
||||
#
|
||||
# Returns an array of Hashes, each looking something like this:
|
||||
# {"name" => "larry"
|
||||
# "items" => [...] } # all the items where `property` == "larry"
|
||||
def group_by(input, property)
|
||||
if groupable?(input)
|
||||
input.group_by do |item|
|
||||
item_property(item, property).to_s
|
||||
end.inject([]) do |memo, i|
|
||||
memo << {"name" => i.first, "items" => i.last}
|
||||
end
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
# Filter an array of objects
|
||||
#
|
||||
# input - the object array
|
||||
# key - key within each object to filter by
|
||||
# value - desired value
|
||||
#
|
||||
# Returns the filtered array of objects
|
||||
def where(input, property, value)
|
||||
return input unless input.is_a?(Array)
|
||||
input.select { |object| item_property(object, property) == value }
|
||||
end
|
||||
|
||||
# Sort an array of objects
|
||||
#
|
||||
# input - the object array
|
||||
# property - property within each object to filter by
|
||||
# nils ('first' | 'last') - nils appear before or after non-nil values
|
||||
#
|
||||
# Returns the filtered array of objects
|
||||
def sort(input, property = nil, nils = "first")
|
||||
if property.nil?
|
||||
input.sort
|
||||
else
|
||||
case
|
||||
when nils == "first"
|
||||
order = - 1
|
||||
when nils == "last"
|
||||
order = + 1
|
||||
else
|
||||
raise ArgumentError.new("Invalid nils order: " +
|
||||
"'#{nils}' is not a valid nils order. It must be 'first' or 'last'.")
|
||||
end
|
||||
|
||||
input.sort { |apple, orange|
|
||||
apple_property = item_property(apple, property)
|
||||
orange_property = item_property(orange, property)
|
||||
|
||||
if !apple_property.nil? && orange_property.nil?
|
||||
- order
|
||||
elsif apple_property.nil? && !orange_property.nil?
|
||||
+ order
|
||||
else
|
||||
apple_property <=> orange_property
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -164,11 +254,31 @@ module Jekyll
|
||||
when Time
|
||||
input
|
||||
when String
|
||||
Time.parse(input)
|
||||
Time.parse(input) rescue Time.at(input.to_i)
|
||||
when Numeric
|
||||
Time.at(input)
|
||||
else
|
||||
Jekyll.logger.error "Invalid Date:", "'#{input}' is not a valid datetime."
|
||||
exit(1)
|
||||
end
|
||||
end
|
||||
|
||||
def groupable?(element)
|
||||
element.respond_to?(:group_by)
|
||||
end
|
||||
|
||||
def item_property(item, property)
|
||||
if item.respond_to?(:to_liquid)
|
||||
item.to_liquid[property.to_s]
|
||||
elsif item.respond_to?(:data)
|
||||
item.data[property.to_s]
|
||||
else
|
||||
item[property.to_s]
|
||||
end
|
||||
end
|
||||
|
||||
def as_liquid(item)
|
||||
item.respond_to?(:to_liquid) ? item.to_liquid : item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
180
lib/jekyll/frontmatter_defaults.rb
Normal file
180
lib/jekyll/frontmatter_defaults.rb
Normal file
@@ -0,0 +1,180 @@
|
||||
module Jekyll
|
||||
# This class handles custom defaults for YAML frontmatter settings.
|
||||
# These are set in _config.yml and apply both to internal use (e.g. layout)
|
||||
# and the data available to liquid.
|
||||
#
|
||||
# It is exposed via the frontmatter_defaults method on the site class.
|
||||
class FrontmatterDefaults
|
||||
# Initializes a new instance.
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
def update_deprecated_types(set)
|
||||
return set unless set.key?('scope') && set['scope'].key?('type')
|
||||
|
||||
set['scope']['type'] = case set['scope']['type']
|
||||
when 'page'
|
||||
Deprecator.defaults_deprecate_type('page', 'pages')
|
||||
'pages'
|
||||
when 'post'
|
||||
Deprecator.defaults_deprecate_type('post', 'posts')
|
||||
'posts'
|
||||
when 'draft'
|
||||
Deprecator.defaults_deprecate_type('draft', 'drafts')
|
||||
'drafts'
|
||||
else
|
||||
set['scope']['type']
|
||||
end
|
||||
|
||||
set
|
||||
end
|
||||
|
||||
# Finds a default value for a given setting, filtered by path and type
|
||||
#
|
||||
# path - the path (relative to the source) of the page, post or :draft the default is used in
|
||||
# type - a symbol indicating whether a :page, a :post or a :draft calls this method
|
||||
#
|
||||
# Returns the default value or nil if none was found
|
||||
def find(path, type, setting)
|
||||
value = nil
|
||||
old_scope = nil
|
||||
|
||||
matching_sets(path, type).each do |set|
|
||||
if set['values'].key?(setting) && has_precedence?(old_scope, set['scope'])
|
||||
value = set['values'][setting]
|
||||
old_scope = set['scope']
|
||||
end
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
# Collects a hash with all default values for a page or post
|
||||
#
|
||||
# path - the relative path of the page or post
|
||||
# type - a symbol indicating the type (:post, :page or :draft)
|
||||
#
|
||||
# Returns a hash with all default values (an empty hash if there are none)
|
||||
def all(path, type)
|
||||
defaults = {}
|
||||
old_scope = nil
|
||||
matching_sets(path, type).each do |set|
|
||||
if has_precedence?(old_scope, set['scope'])
|
||||
defaults = Utils.deep_merge_hashes(defaults, set['values'])
|
||||
old_scope = set['scope']
|
||||
else
|
||||
defaults = Utils.deep_merge_hashes(set['values'], defaults)
|
||||
end
|
||||
end
|
||||
defaults
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Checks if a given default setting scope matches the given path and type
|
||||
#
|
||||
# scope - the hash indicating the scope, as defined in _config.yml
|
||||
# path - the path to check for
|
||||
# type - the type (:post, :page or :draft) to check for
|
||||
#
|
||||
# Returns true if the scope applies to the given path and type
|
||||
def applies?(scope, path, type)
|
||||
applies_path?(scope, path) && applies_type?(scope, type)
|
||||
end
|
||||
|
||||
def applies_path?(scope, path)
|
||||
return true if !scope.has_key?('path') || scope['path'].empty?
|
||||
|
||||
scope_path = Pathname.new(scope['path'])
|
||||
Pathname.new(sanitize_path(path)).ascend do |path|
|
||||
if path == scope_path
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Determines whether the scope applies to type.
|
||||
# The scope applies to the type if:
|
||||
# 1. no 'type' is specified
|
||||
# 2. the 'type' in the scope is the same as the type asked about
|
||||
#
|
||||
# scope - the Hash defaults set being asked about application
|
||||
# type - the type of the document being processed / asked about
|
||||
# its defaults.
|
||||
#
|
||||
# Returns true if either of the above conditions are satisfied,
|
||||
# otherwise returns false
|
||||
def applies_type?(scope, type)
|
||||
!scope.key?('type') || scope['type'].eql?(type.to_s)
|
||||
end
|
||||
|
||||
# Checks if a given set of default values is valid
|
||||
#
|
||||
# set - the default value hash, as defined in _config.yml
|
||||
#
|
||||
# Returns true if the set is valid and can be used in this class
|
||||
def valid?(set)
|
||||
set.is_a?(Hash) && set['values'].is_a?(Hash)
|
||||
end
|
||||
|
||||
# Determines if a new scope has precedence over an old one
|
||||
#
|
||||
# old_scope - the old scope hash, or nil if there's none
|
||||
# new_scope - the new scope hash
|
||||
#
|
||||
# Returns true if the new scope has precedence over the older
|
||||
def has_precedence?(old_scope, new_scope)
|
||||
return true if old_scope.nil?
|
||||
|
||||
new_path = sanitize_path(new_scope['path'])
|
||||
old_path = sanitize_path(old_scope['path'])
|
||||
|
||||
if new_path.length != old_path.length
|
||||
new_path.length >= old_path.length
|
||||
elsif new_scope.key? 'type'
|
||||
true
|
||||
else
|
||||
!old_scope.key? 'type'
|
||||
end
|
||||
end
|
||||
|
||||
# Collects a list of sets that match the given path and type
|
||||
#
|
||||
# Returns an array of hashes
|
||||
def matching_sets(path, type)
|
||||
valid_sets.select do |set|
|
||||
!set.has_key?('scope') || applies?(set['scope'], path, type)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a list of valid sets
|
||||
#
|
||||
# This is not cached to allow plugins to modify the configuration
|
||||
# and have their changes take effect
|
||||
#
|
||||
# Returns an array of hashes
|
||||
def valid_sets
|
||||
sets = @site.config['defaults']
|
||||
return [] unless sets.is_a?(Array)
|
||||
|
||||
sets.map do |set|
|
||||
if valid?(set)
|
||||
update_deprecated_types(set)
|
||||
else
|
||||
Jekyll.logger.warn "Defaults:", "An invalid front-matter default set was found:"
|
||||
Jekyll.logger.warn "#{set}"
|
||||
nil
|
||||
end
|
||||
end.compact
|
||||
end
|
||||
|
||||
# Sanitizes the given path by removing a leading and addding a trailing slash
|
||||
def sanitize_path(path)
|
||||
if path.nil? || path.empty?
|
||||
""
|
||||
else
|
||||
path.gsub(/\A\//, '').gsub(/([^\/])\z/, '\1/')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,217 +0,0 @@
|
||||
module Jekyll
|
||||
module Generators
|
||||
class Pagination < Generator
|
||||
# This generator is safe from arbitrary code execution.
|
||||
safe true
|
||||
|
||||
# This generator should be passive with regard to its execution
|
||||
priority :lowest
|
||||
|
||||
# Generate paginated pages if necessary.
|
||||
#
|
||||
# site - The Site.
|
||||
#
|
||||
# Returns nothing.
|
||||
def generate(site)
|
||||
if Pager.pagination_enabled?(site)
|
||||
if template = template_page(site)
|
||||
paginate(site, template)
|
||||
else
|
||||
Jekyll.logger.warn "Pagination:", "Pagination is enabled, but I couldn't find " +
|
||||
"an index.html page to use as the pagination template. Skipping pagination."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Paginates the blog's posts. Renders the index.html file into paginated
|
||||
# directories, e.g.: page2/index.html, page3/index.html, etc and adds more
|
||||
# site-wide data.
|
||||
#
|
||||
# site - The Site.
|
||||
# page - The index.html Page that requires pagination.
|
||||
#
|
||||
# {"paginator" => { "page" => <Number>,
|
||||
# "per_page" => <Number>,
|
||||
# "posts" => [<Post>],
|
||||
# "total_posts" => <Number>,
|
||||
# "total_pages" => <Number>,
|
||||
# "previous_page" => <Number>,
|
||||
# "next_page" => <Number> }}
|
||||
def paginate(site, page)
|
||||
all_posts = site.site_payload['site']['posts']
|
||||
pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
|
||||
(1..pages).each do |num_page|
|
||||
pager = Pager.new(site, num_page, all_posts, pages)
|
||||
if num_page > 1
|
||||
newpage = Page.new(site, site.source, page.dir, page.name)
|
||||
newpage.pager = pager
|
||||
newpage.dir = Pager.paginate_path(site, num_page)
|
||||
site.pages << newpage
|
||||
else
|
||||
page.pager = pager
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Static: Fetch the URL of the template page. Used to determine the
|
||||
# path to the first pager in the series.
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
#
|
||||
# Returns the url of the template page
|
||||
def self.first_page_url(site)
|
||||
if page = Pagination.new.template_page(site)
|
||||
page.url
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Find the Jekyll::Page which will act as the pager template
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
#
|
||||
# Returns the Jekyll::Page which will act as the pager template
|
||||
def template_page(site)
|
||||
site.pages.dup.select do |page|
|
||||
Pager.pagination_candidate?(site.config, page)
|
||||
end.sort do |one, two|
|
||||
two.path.size <=> one.path.size
|
||||
end.first
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Pager
|
||||
attr_reader :page, :per_page, :posts, :total_posts, :total_pages,
|
||||
:previous_page, :previous_page_path, :next_page, :next_page_path
|
||||
|
||||
# Calculate the number of pages.
|
||||
#
|
||||
# all_posts - The Array of all Posts.
|
||||
# per_page - The Integer of entries per page.
|
||||
#
|
||||
# Returns the Integer number of pages.
|
||||
def self.calculate_pages(all_posts, per_page)
|
||||
(all_posts.size.to_f / per_page.to_i).ceil
|
||||
end
|
||||
|
||||
# Determine if pagination is enabled the site.
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
#
|
||||
# Returns true if pagination is enabled, false otherwise.
|
||||
def self.pagination_enabled?(site)
|
||||
!site.config['paginate'].nil? &&
|
||||
site.pages.size > 0
|
||||
end
|
||||
|
||||
# Static: Determine if a page is a possible candidate to be a template page.
|
||||
# Page's name must be `index.html` and exist in any of the directories
|
||||
# between the site source and `paginate_path`.
|
||||
#
|
||||
# config - the site configuration hash
|
||||
# page - the Jekyll::Page about which we're inquiring
|
||||
#
|
||||
# Returns true if the
|
||||
def self.pagination_candidate?(config, page)
|
||||
page_dir = File.dirname(File.expand_path(remove_leading_slash(page.path), config['source']))
|
||||
paginate_path = remove_leading_slash(config['paginate_path'])
|
||||
paginate_path = File.expand_path(paginate_path, config['source'])
|
||||
page.name == 'index.html' &&
|
||||
in_hierarchy(config['source'], page_dir, File.dirname(paginate_path))
|
||||
end
|
||||
|
||||
# Determine if the subdirectories of the two paths are the same relative to source
|
||||
#
|
||||
# source - the site source
|
||||
# page_dir - the directory of the Jekyll::Page
|
||||
# paginate_path - the absolute paginate path (from root of FS)
|
||||
#
|
||||
# Returns whether the subdirectories are the same relative to source
|
||||
def self.in_hierarchy(source, page_dir, paginate_path)
|
||||
return false if paginate_path == File.dirname(paginate_path)
|
||||
return false if paginate_path == Pathname.new(source).parent
|
||||
page_dir == paginate_path ||
|
||||
in_hierarchy(source, page_dir, File.dirname(paginate_path))
|
||||
end
|
||||
|
||||
# Static: Return the pagination path of the page
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
# num_page - the pagination page number
|
||||
#
|
||||
# Returns the pagination path as a string
|
||||
def self.paginate_path(site, num_page)
|
||||
return nil if num_page.nil?
|
||||
return Generators::Pagination.first_page_url(site) if num_page <= 1
|
||||
format = site.config['paginate_path']
|
||||
format = format.sub(':num', num_page.to_s)
|
||||
ensure_leading_slash(format)
|
||||
end
|
||||
|
||||
# Static: Return a String version of the input which has a leading slash.
|
||||
# If the input already has a forward slash in position zero, it will be
|
||||
# returned unchanged.
|
||||
#
|
||||
# path - a String path
|
||||
#
|
||||
# Returns the path with a leading slash
|
||||
def self.ensure_leading_slash(path)
|
||||
path[0..0] == "/" ? path : "/#{path}"
|
||||
end
|
||||
|
||||
# Static: Return a String version of the input without a leading slash.
|
||||
#
|
||||
# path - a String path
|
||||
#
|
||||
# Returns the input without the leading slash
|
||||
def self.remove_leading_slash(path)
|
||||
ensure_leading_slash(path)[1..-1]
|
||||
end
|
||||
|
||||
# Initialize a new Pager.
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
# page - The Integer page number.
|
||||
# all_posts - The Array of all the site's Posts.
|
||||
# num_pages - The Integer number of pages or nil if you'd like the number
|
||||
# of pages calculated.
|
||||
def initialize(site, page, all_posts, num_pages = nil)
|
||||
@page = page
|
||||
@per_page = site.config['paginate'].to_i
|
||||
@total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page)
|
||||
|
||||
if @page > @total_pages
|
||||
raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}"
|
||||
end
|
||||
|
||||
init = (@page - 1) * @per_page
|
||||
offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1)
|
||||
|
||||
@total_posts = all_posts.size
|
||||
@posts = all_posts[init..offset]
|
||||
@previous_page = @page != 1 ? @page - 1 : nil
|
||||
@previous_page_path = Pager.paginate_path(site, @previous_page)
|
||||
@next_page = @page != @total_pages ? @page + 1 : nil
|
||||
@next_page_path = Pager.paginate_path(site, @next_page)
|
||||
end
|
||||
|
||||
# Convert this Pager's data to a Hash suitable for use by Liquid.
|
||||
#
|
||||
# Returns the Hash representation of this Pager.
|
||||
def to_liquid
|
||||
{
|
||||
'page' => page,
|
||||
'per_page' => per_page,
|
||||
'posts' => posts,
|
||||
'total_posts' => total_posts,
|
||||
'total_pages' => total_pages,
|
||||
'previous_page' => previous_page,
|
||||
'previous_page_path' => previous_page_path,
|
||||
'next_page' => next_page,
|
||||
'next_page_path' => next_page_path
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -29,8 +29,8 @@ module Jekyll
|
||||
|
||||
self.data = {}
|
||||
|
||||
self.process(name)
|
||||
self.read_yaml(base, name)
|
||||
process(name)
|
||||
read_yaml(base, name)
|
||||
end
|
||||
|
||||
# Extract information from the layout filename.
|
||||
|
||||
53
lib/jekyll/layout_reader.rb
Normal file
53
lib/jekyll/layout_reader.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
module Jekyll
|
||||
class LayoutReader
|
||||
attr_reader :site
|
||||
def initialize(site)
|
||||
@site = site
|
||||
@layouts = {}
|
||||
end
|
||||
|
||||
def read
|
||||
layout_entries.each do |f|
|
||||
@layouts[layout_name(f)] = Layout.new(site, layout_directory, f)
|
||||
end
|
||||
|
||||
@layouts
|
||||
end
|
||||
|
||||
def layout_directory
|
||||
@layout_directory ||= (layout_directory_in_cwd || layout_directory_inside_source)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def layout_entries
|
||||
entries = []
|
||||
within(layout_directory) do
|
||||
entries = EntryFilter.new(site).filter(Dir['**/*.*'])
|
||||
end
|
||||
entries
|
||||
end
|
||||
|
||||
def layout_name(file)
|
||||
file.split(".")[0..-2].join(".")
|
||||
end
|
||||
|
||||
def within(directory)
|
||||
return unless File.exist?(directory)
|
||||
Dir.chdir(directory) { yield }
|
||||
end
|
||||
|
||||
def layout_directory_inside_source
|
||||
Jekyll.sanitized_path(site.source, site.config['layouts'])
|
||||
end
|
||||
|
||||
def layout_directory_in_cwd
|
||||
dir = Jekyll.sanitized_path(Dir.pwd, site.config['layouts'])
|
||||
if File.directory?(dir)
|
||||
dir
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
22
lib/jekyll/liquid_extensions.rb
Normal file
22
lib/jekyll/liquid_extensions.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
module Jekyll
|
||||
module LiquidExtensions
|
||||
|
||||
# Lookup a Liquid variable in the given context.
|
||||
#
|
||||
# context - the Liquid context in question.
|
||||
# variable - the variable name, as a string.
|
||||
#
|
||||
# Returns the value of the variable in the context
|
||||
# or the variable name if not found.
|
||||
def lookup_variable(context, variable)
|
||||
lookup = context
|
||||
|
||||
variable.split(".").each do |value|
|
||||
lookup = lookup[value]
|
||||
end
|
||||
|
||||
lookup || variable
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
102
lib/jekyll/log_adapter.rb
Normal file
102
lib/jekyll/log_adapter.rb
Normal file
@@ -0,0 +1,102 @@
|
||||
module Jekyll
|
||||
class LogAdapter
|
||||
attr_reader :writer
|
||||
|
||||
LOG_LEVELS = {
|
||||
:debug => ::Logger::DEBUG,
|
||||
:info => ::Logger::INFO,
|
||||
:warn => ::Logger::WARN,
|
||||
:error => ::Logger::ERROR
|
||||
}
|
||||
|
||||
# Public: Create a new instance of Jekyll's log writer
|
||||
#
|
||||
# writer - Logger compatible instance
|
||||
# log_level - (optional, symbol) the log level
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(writer, level = :info)
|
||||
@writer = writer
|
||||
self.log_level = level
|
||||
end
|
||||
|
||||
# Public: Set the log level on the writer
|
||||
#
|
||||
# level - (symbol) the log level
|
||||
#
|
||||
# Returns nothing
|
||||
def log_level=(level)
|
||||
writer.level = LOG_LEVELS.fetch(level)
|
||||
end
|
||||
|
||||
# Public: Print a jekyll debug message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def debug(topic, message = nil)
|
||||
writer.debug(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def info(topic, message = nil)
|
||||
writer.info(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def warn(topic, message = nil)
|
||||
writer.warn(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll error message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def error(topic, message = nil)
|
||||
writer.error(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a Jekyll 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)
|
||||
#
|
||||
# Returns nothing
|
||||
def abort_with(topic, message = nil)
|
||||
error(topic, message)
|
||||
abort
|
||||
end
|
||||
|
||||
# Internal: Build a Jekyll topic method
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns the formatted message
|
||||
def message(topic, message)
|
||||
formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ')
|
||||
end
|
||||
|
||||
# Internal: Format the topic
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
#
|
||||
# Returns the formatted topic statement
|
||||
def formatted_topic(topic)
|
||||
"#{topic} ".rjust(20)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,12 +1,13 @@
|
||||
# These are the same MIME types that GitHub Pages uses as of 17 Mar 2013.
|
||||
-# These are the same MIME types that GitHub Pages uses as of 26 January 2014
|
||||
|
||||
text/html html htm shtml
|
||||
text/css css
|
||||
text/xml xml rss xsl
|
||||
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
|
||||
@@ -17,16 +18,22 @@ 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/json json
|
||||
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
|
||||
@@ -34,18 +41,19 @@ application/pdf pdf
|
||||
application/postscript ps eps ai
|
||||
application/rdf+xml rdf
|
||||
application/rtf rtf
|
||||
text/vcard vcf vcard
|
||||
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-chrome-extension crx
|
||||
application/x-cocoa cco
|
||||
application/x-font-ttf ttf
|
||||
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
|
||||
@@ -63,8 +71,8 @@ application/zip zip
|
||||
|
||||
application/octet-stream bin exe dll
|
||||
application/octet-stream deb
|
||||
application/octet-stream deploy
|
||||
application/octet-stream dmg
|
||||
application/octet-stream eot
|
||||
application/octet-stream iso img
|
||||
application/octet-stream msi msp msm
|
||||
|
||||
@@ -74,12 +82,14 @@ 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
|
||||
video/ogg ogv
|
||||
video/webm webm
|
||||
|
||||
@@ -9,9 +9,11 @@ module Jekyll
|
||||
|
||||
# Attributes for Liquid templates
|
||||
ATTRIBUTES_FOR_LIQUID = %w[
|
||||
url
|
||||
content
|
||||
dir
|
||||
name
|
||||
path
|
||||
url
|
||||
]
|
||||
|
||||
# Initialize a new Page.
|
||||
@@ -26,8 +28,13 @@ module Jekyll
|
||||
@dir = dir
|
||||
@name = name
|
||||
|
||||
self.process(name)
|
||||
self.read_yaml(File.join(base, dir), name)
|
||||
|
||||
process(name)
|
||||
read_yaml(File.join(base, dir), name)
|
||||
|
||||
data.default_proc = proc do |hash, key|
|
||||
site.frontmatter_defaults.find(File.join(dir, name), type, key)
|
||||
end
|
||||
end
|
||||
|
||||
# The generated directory into which the page will be placed
|
||||
@@ -44,11 +51,11 @@ module Jekyll
|
||||
#
|
||||
# Returns the String permalink or nil if none has been set.
|
||||
def permalink
|
||||
return nil if self.data.nil? || self.data['permalink'].nil?
|
||||
return nil if data.nil? || data['permalink'].nil?
|
||||
if site.config['relative_permalinks']
|
||||
File.join(@dir, self.data['permalink'])
|
||||
File.join(@dir, data['permalink'])
|
||||
else
|
||||
self.data['permalink']
|
||||
data['permalink']
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,7 +63,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the template String.
|
||||
def template
|
||||
if self.site.permalink_style == :pretty
|
||||
if site.permalink_style == :pretty
|
||||
if index? && html?
|
||||
"/:path/"
|
||||
elsif html?
|
||||
@@ -85,8 +92,8 @@ module Jekyll
|
||||
def url_placeholders
|
||||
{
|
||||
:path => @dir,
|
||||
:basename => self.basename,
|
||||
:output_ext => self.output_ext
|
||||
:basename => basename,
|
||||
:output_ext => output_ext
|
||||
}
|
||||
end
|
||||
|
||||
@@ -97,7 +104,7 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
self.ext = File.extname(name)
|
||||
self.basename = name[0 .. -self.ext.length-1]
|
||||
self.basename = name[0 .. -ext.length - 1]
|
||||
end
|
||||
|
||||
# Add any necessary layouts to this post
|
||||
@@ -107,10 +114,10 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def render(layouts, site_payload)
|
||||
payload = {
|
||||
"page" => self.to_liquid,
|
||||
payload = Utils.deep_merge_hashes({
|
||||
"page" => to_liquid,
|
||||
'paginator' => pager.to_liquid
|
||||
}.deep_merge(site_payload)
|
||||
}, site_payload)
|
||||
|
||||
do_layout(payload, layouts)
|
||||
end
|
||||
@@ -119,12 +126,12 @@ module Jekyll
|
||||
#
|
||||
# Returns the path to the source file
|
||||
def path
|
||||
self.data.fetch('path', self.relative_path.sub(/\A\//, ''))
|
||||
data.fetch('path', relative_path.sub(/\A\//, ''))
|
||||
end
|
||||
|
||||
# The path to the page source file, relative to the site source
|
||||
def relative_path
|
||||
File.join(@dir, @name)
|
||||
File.join(*[@dir, @name].map(&:to_s).reject(&:empty?))
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
@@ -133,14 +140,14 @@ module Jekyll
|
||||
#
|
||||
# Returns the destination file path String.
|
||||
def destination(dest)
|
||||
path = File.join(dest, self.url)
|
||||
path = File.join(path, "index.html") if self.url =~ /\/$/
|
||||
path = Jekyll.sanitized_path(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if url =~ /\/$/
|
||||
path
|
||||
end
|
||||
|
||||
# Returns the object as a debug String.
|
||||
def inspect
|
||||
"#<Jekyll:Page @name=#{self.name.inspect}>"
|
||||
"#<Jekyll:Page @name=#{name.inspect}>"
|
||||
end
|
||||
|
||||
# Returns the Boolean of whether this Page is HTML or not.
|
||||
@@ -154,7 +161,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
def uses_relative_permalinks
|
||||
permalink && @dir != "" && site.config['relative_permalinks']
|
||||
permalink && !@dir.empty? && site.config['relative_permalinks']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,22 +6,15 @@ module Jekyll
|
||||
:high => 10,
|
||||
:highest => 100 }
|
||||
|
||||
# Install a hook so that subclasses are recorded. This method is only
|
||||
# ever called by Ruby itself.
|
||||
# Fetch all the subclasses of this class and its subclasses' subclasses.
|
||||
#
|
||||
# base - The Class subclass.
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.inherited(base)
|
||||
subclasses << base
|
||||
subclasses.sort!
|
||||
end
|
||||
|
||||
# The list of Classes that have been subclassed.
|
||||
#
|
||||
# Returns an Array of Class objects.
|
||||
def self.subclasses
|
||||
@subclasses ||= []
|
||||
# Returns an array of descendant classes.
|
||||
def self.descendants
|
||||
descendants = []
|
||||
ObjectSpace.each_object(singleton_class) do |k|
|
||||
descendants.unshift k unless k == self
|
||||
end
|
||||
descendants
|
||||
end
|
||||
|
||||
# Get or set the priority of this plugin. When called without an
|
||||
@@ -34,7 +27,7 @@ module Jekyll
|
||||
# Returns the Symbol priority.
|
||||
def self.priority(priority = nil)
|
||||
@priority ||= nil
|
||||
if priority && PRIORITIES.has_key?(priority)
|
||||
if priority && PRIORITIES.key?(priority)
|
||||
@priority = priority
|
||||
end
|
||||
@priority || :normal
|
||||
@@ -63,6 +56,15 @@ module Jekyll
|
||||
PRIORITIES[other.priority] <=> PRIORITIES[self.priority]
|
||||
end
|
||||
|
||||
# Spaceship is priority [higher -> lower]
|
||||
#
|
||||
# other - The class to be compared.
|
||||
#
|
||||
# Returns -1, 0, 1.
|
||||
def <=>(other)
|
||||
self.class <=> other.class
|
||||
end
|
||||
|
||||
# Initialize a new plugin. This should be overridden by the subclass.
|
||||
#
|
||||
# config - The Hash of configuration options.
|
||||
|
||||
76
lib/jekyll/plugin_manager.rb
Normal file
76
lib/jekyll/plugin_manager.rb
Normal file
@@ -0,0 +1,76 @@
|
||||
module Jekyll
|
||||
class PluginManager
|
||||
attr_reader :site
|
||||
|
||||
# Create an instance of this class.
|
||||
#
|
||||
# site - the instance of Jekyll::Site we're concerned with
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Require all the plugins which are allowed.
|
||||
#
|
||||
# Returns nothing
|
||||
def conscientious_require
|
||||
require_plugin_files
|
||||
require_gems
|
||||
end
|
||||
|
||||
# Require each of the gem plugins specified.
|
||||
#
|
||||
# Returns nothing.
|
||||
def require_gems
|
||||
site.gems.each do |gem|
|
||||
if plugin_allowed?(gem)
|
||||
require gem
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Check whether a gem plugin is allowed to be used during this build.
|
||||
#
|
||||
# gem_name - the name of the gem
|
||||
#
|
||||
# Returns true if the gem name is in the whitelist or if the site is not
|
||||
# in safe mode.
|
||||
def plugin_allowed?(gem_name)
|
||||
!site.safe || whitelist.include?(gem_name)
|
||||
end
|
||||
|
||||
# Build an array of allowed plugin gem names.
|
||||
#
|
||||
# Returns an array of strings, each string being the name of a gem name
|
||||
# that is allowed to be used.
|
||||
def whitelist
|
||||
@whitelist ||= Array[site.config['whitelist']].flatten
|
||||
end
|
||||
|
||||
# Require all .rb files if safe mode is off
|
||||
#
|
||||
# Returns nothing.
|
||||
def require_plugin_files
|
||||
unless site.safe
|
||||
plugins_path.each do |plugins|
|
||||
Dir[File.join(plugins, "**", "*.rb")].sort.each do |f|
|
||||
require f
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Setup the plugin search path
|
||||
#
|
||||
# Returns an Array of plugin search paths
|
||||
def plugins_path
|
||||
if (site.config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
|
||||
[Jekyll.sanitized_path(site.source, site.config['plugins'])]
|
||||
else
|
||||
Array(site.config['plugins']).map { |d| File.expand_path(d) }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -9,6 +9,7 @@ module Jekyll
|
||||
EXCERPT_ATTRIBUTES_FOR_LIQUID = %w[
|
||||
title
|
||||
url
|
||||
dir
|
||||
date
|
||||
id
|
||||
categories
|
||||
@@ -34,7 +35,7 @@ module Jekyll
|
||||
|
||||
attr_accessor :site
|
||||
attr_accessor :data, :extracted_excerpt, :content, :output, :ext
|
||||
attr_accessor :date, :slug, :published, :tags, :categories
|
||||
attr_accessor :date, :slug, :tags, :categories
|
||||
|
||||
attr_reader :name
|
||||
|
||||
@@ -48,25 +49,27 @@ module Jekyll
|
||||
def initialize(site, source, dir, name)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@base = self.containing_dir(source, dir)
|
||||
@base = containing_dir(source, dir)
|
||||
@name = name
|
||||
|
||||
self.categories = dir.downcase.split('/').reject { |x| x.empty? }
|
||||
self.process(name)
|
||||
self.read_yaml(@base, name)
|
||||
process(name)
|
||||
read_yaml(@base, name)
|
||||
|
||||
if self.data.has_key?('date')
|
||||
self.date = Time.parse(self.data["date"].to_s)
|
||||
data.default_proc = proc do |hash, key|
|
||||
site.frontmatter_defaults.find(File.join(dir, name), type, key)
|
||||
end
|
||||
|
||||
self.published = self.published?
|
||||
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
|
||||
|
||||
self.populate_categories
|
||||
self.populate_tags
|
||||
populate_categories
|
||||
populate_tags
|
||||
end
|
||||
|
||||
def published?
|
||||
if self.data.has_key?('published') && self.data['published'] == false
|
||||
if data.key?('published') && data['published'] == false
|
||||
false
|
||||
else
|
||||
true
|
||||
@@ -74,14 +77,14 @@ module Jekyll
|
||||
end
|
||||
|
||||
def populate_categories
|
||||
if self.categories.empty?
|
||||
self.categories = self.data.pluralized_array('category', 'categories').map {|c| c.to_s.downcase}
|
||||
end
|
||||
self.categories.flatten!
|
||||
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 = self.data.pluralized_array("tag", "tags").flatten
|
||||
self.tags = Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
|
||||
end
|
||||
|
||||
# Get the full path to the directory containing the post files
|
||||
@@ -97,7 +100,7 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def read_yaml(base, name)
|
||||
super(base, name)
|
||||
self.extracted_excerpt = self.extract_excerpt
|
||||
self.extracted_excerpt = extract_excerpt
|
||||
end
|
||||
|
||||
# The post excerpt. This is either a custom excerpt
|
||||
@@ -105,19 +108,19 @@ module Jekyll
|
||||
#
|
||||
# Returns excerpt string.
|
||||
def excerpt
|
||||
self.data.fetch('excerpt', self.extracted_excerpt.to_s)
|
||||
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
|
||||
self.data.fetch("title", self.titleized_slug)
|
||||
data.fetch("title", titleized_slug)
|
||||
end
|
||||
|
||||
# Turns the post slug into a suitable title
|
||||
def titleized_slug
|
||||
self.slug.split('-').select {|w| w.capitalize! || w }.join(' ')
|
||||
slug.split('-').select {|w| w.capitalize! || w }.join(' ')
|
||||
end
|
||||
|
||||
# Public: the path to the post relative to the site source,
|
||||
@@ -127,12 +130,12 @@ module Jekyll
|
||||
#
|
||||
# Returns the path to the file relative to the site source
|
||||
def path
|
||||
self.data.fetch('path', self.relative_path.sub(/\A\//, ''))
|
||||
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)
|
||||
File.join(*[@dir, "_posts", @name].map(&:to_s).reject(&:empty?))
|
||||
end
|
||||
|
||||
# Compares Post objects. First compares the Post date. If the dates are
|
||||
@@ -156,11 +159,9 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
m, cats, date, slug, ext = *name.match(MATCHER)
|
||||
self.date = Time.parse(date)
|
||||
self.date = Utils.parse_date(date, "Post '#{relative_path}' does not have a valid date in the filename.")
|
||||
self.slug = slug
|
||||
self.ext = ext
|
||||
rescue ArgumentError
|
||||
raise FatalException.new("Post #{name} does not have a valid date.")
|
||||
end
|
||||
|
||||
# The generated directory into which the post will be placed
|
||||
@@ -178,11 +179,11 @@ module Jekyll
|
||||
#
|
||||
# Returns the String permalink.
|
||||
def permalink
|
||||
self.data && self.data['permalink']
|
||||
data && data['permalink']
|
||||
end
|
||||
|
||||
def template
|
||||
case self.site.permalink_style
|
||||
case site.permalink_style
|
||||
when :pretty
|
||||
"/:categories/:year/:month/:day/:title/"
|
||||
when :none
|
||||
@@ -192,7 +193,7 @@ module Jekyll
|
||||
when :ordinal
|
||||
"/:categories/:year/:y_day/:title.html"
|
||||
else
|
||||
self.site.permalink_style.to_s
|
||||
site.permalink_style.to_s
|
||||
end
|
||||
end
|
||||
|
||||
@@ -214,13 +215,14 @@ module Jekyll
|
||||
:year => date.strftime("%Y"),
|
||||
:month => date.strftime("%m"),
|
||||
:day => date.strftime("%d"),
|
||||
:title => CGI.escape(slug),
|
||||
:i_day => date.strftime("%d").to_i.to_s,
|
||||
:i_month => date.strftime("%m").to_i.to_s,
|
||||
:categories => (categories || []).map { |c| URI.escape(c.to_s) }.join('/'),
|
||||
: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 => self.output_ext
|
||||
:output_ext => output_ext
|
||||
}
|
||||
end
|
||||
|
||||
@@ -229,7 +231,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the String UID.
|
||||
def id
|
||||
File.join(self.dir, self.slug)
|
||||
File.join(dir, slug)
|
||||
end
|
||||
|
||||
# Calculate related posts.
|
||||
@@ -247,16 +249,16 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def render(layouts, site_payload)
|
||||
# construct payload
|
||||
payload = {
|
||||
payload = Utils.deep_merge_hashes({
|
||||
"site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
|
||||
"page" => self.to_liquid(EXCERPT_ATTRIBUTES_FOR_LIQUID)
|
||||
}.deep_merge(site_payload)
|
||||
"page" => to_liquid(self.class::EXCERPT_ATTRIBUTES_FOR_LIQUID)
|
||||
}, site_payload)
|
||||
|
||||
if generate_excerpt?
|
||||
self.extracted_excerpt.do_layout(payload, {})
|
||||
extracted_excerpt.do_layout(payload, {})
|
||||
end
|
||||
|
||||
do_layout(payload.merge({"page" => self.to_liquid}), layouts)
|
||||
do_layout(payload.merge({"page" => to_liquid}), layouts)
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
@@ -266,30 +268,29 @@ module Jekyll
|
||||
# Returns destination file path String.
|
||||
def destination(dest)
|
||||
# The url needs to be unescaped in order to preserve the correct filename
|
||||
path = File.join(dest, CGI.unescape(self.url))
|
||||
path = Jekyll.sanitized_path(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: #{self.id}>"
|
||||
"<Post: #{id}>"
|
||||
end
|
||||
|
||||
def next
|
||||
pos = self.site.posts.index(self)
|
||||
|
||||
if pos && pos < self.site.posts.length-1
|
||||
self.site.posts[pos+1]
|
||||
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 = self.site.posts.index(self)
|
||||
pos = site.posts.index {|post| post.equal?(self) }
|
||||
if pos && pos > 0
|
||||
self.site.posts[pos-1]
|
||||
site.posts[pos - 1]
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
21
lib/jekyll/publisher.rb
Normal file
21
lib/jekyll/publisher.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
module Jekyll
|
||||
class Publisher
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
def publish?(thing)
|
||||
can_be_published?(thing) && !hidden_in_the_future?(thing)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_be_published?(thing)
|
||||
thing.data.fetch('published', true) || @site.unpublished
|
||||
end
|
||||
|
||||
def hidden_in_the_future?(thing)
|
||||
thing.is_a?(Post) && !@site.future && thing.date > @site.time
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,13 +10,13 @@ module Jekyll
|
||||
def initialize(post)
|
||||
@post = post
|
||||
@site = post.site
|
||||
require 'classifier' if site.lsi
|
||||
require 'classifier-reborn' if site.lsi
|
||||
end
|
||||
|
||||
def build
|
||||
return [] unless self.site.posts.size > 1
|
||||
return [] unless site.posts.size > 1
|
||||
|
||||
if self.site.lsi
|
||||
if site.lsi
|
||||
build_index
|
||||
lsi_related_posts
|
||||
else
|
||||
@@ -27,10 +27,10 @@ module Jekyll
|
||||
|
||||
def build_index
|
||||
self.class.lsi ||= begin
|
||||
lsi = Classifier::LSI.new(:auto_rebuild => false)
|
||||
lsi = ClassifierReborn::LSI.new(:auto_rebuild => false)
|
||||
display("Populating LSI...")
|
||||
|
||||
self.site.posts.each do |x|
|
||||
site.posts.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) - [self.post]
|
||||
self.class.lsi.find_related(post.content, 11) - [post]
|
||||
end
|
||||
|
||||
def most_recent_posts
|
||||
recent_posts = self.site.posts.reverse - [self.post]
|
||||
recent_posts = site.posts.reverse - [post]
|
||||
recent_posts.first(10)
|
||||
end
|
||||
|
||||
|
||||
153
lib/jekyll/renderer.rb
Normal file
153
lib/jekyll/renderer.rb
Normal file
@@ -0,0 +1,153 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
class Renderer
|
||||
|
||||
attr_reader :document, :site
|
||||
|
||||
def initialize(site, document)
|
||||
@site = site
|
||||
@document = document
|
||||
end
|
||||
|
||||
# Determine which converters to use based on this document's
|
||||
# extension.
|
||||
#
|
||||
# Returns an array of Converter instances.
|
||||
def converters
|
||||
@converters ||= site.converters.select { |c| c.matches(document.extname) }
|
||||
end
|
||||
|
||||
# Determine the extname the outputted file should have
|
||||
#
|
||||
# Returns the output extname including the leading period.
|
||||
def output_ext
|
||||
converters.first.output_ext(document.extname)
|
||||
end
|
||||
|
||||
######################
|
||||
## DAT RENDER THO
|
||||
######################
|
||||
|
||||
def run
|
||||
payload = Utils.deep_merge_hashes({
|
||||
"page" => document.to_liquid
|
||||
}, site.site_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
|
||||
|
||||
output = document.content
|
||||
|
||||
if document.render_with_liquid?
|
||||
output = render_liquid(output, payload, info)
|
||||
end
|
||||
|
||||
output = convert(output)
|
||||
document.content = output
|
||||
|
||||
if document.place_in_layout?
|
||||
place_in_layouts(
|
||||
output,
|
||||
payload,
|
||||
info
|
||||
)
|
||||
else
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
# Convert the given content using the converters which match this renderer's document.
|
||||
#
|
||||
# content - the raw, unconverted content
|
||||
#
|
||||
# Returns the converted content.
|
||||
def convert(content)
|
||||
converters.reduce(content) do |output, converter|
|
||||
begin
|
||||
converter.convert output
|
||||
rescue => e
|
||||
Jekyll.logger.error "Conversion error:", "#{converter.class} encountered an error converting '#{document.relative_path}'."
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Render the given content with the payload and info
|
||||
#
|
||||
# content -
|
||||
# payload -
|
||||
# info -
|
||||
# path - (optional) the path to the file, for use in ex
|
||||
#
|
||||
# Returns the content, rendered by Liquid.
|
||||
def render_liquid(content, payload, info, path = nil)
|
||||
Liquid::Template.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
|
||||
rescue Exception => e
|
||||
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{path || document.relative_path}"
|
||||
raise e
|
||||
end
|
||||
|
||||
# Checks if the layout specified in the document actually exists
|
||||
#
|
||||
# layout - the layout to check
|
||||
#
|
||||
# Returns true if the layout is invalid, false if otherwise
|
||||
def invalid_layout?(layout)
|
||||
!document.data["layout"].nil? && layout.nil?
|
||||
end
|
||||
|
||||
# Render layouts and place given content inside.
|
||||
#
|
||||
# content - the content to be placed in the layout
|
||||
#
|
||||
#
|
||||
# Returns the content placed in the Liquid-rendered layouts
|
||||
def place_in_layouts(content, payload, info)
|
||||
output = content.dup
|
||||
layout = site.layouts[document.data["layout"]]
|
||||
|
||||
Jekyll.logger.warn("Build Warning:", "Layout '#{document.data["layout"]}' requested in #{document.relative_path} does not exist.") if invalid_layout? layout
|
||||
|
||||
used = Set.new([layout])
|
||||
|
||||
while layout
|
||||
payload = Utils.deep_merge_hashes(
|
||||
payload,
|
||||
{
|
||||
"content" => output,
|
||||
"page" => document.to_liquid,
|
||||
"layout" => layout.data
|
||||
}
|
||||
)
|
||||
|
||||
output = render_liquid(
|
||||
layout.content,
|
||||
payload,
|
||||
info,
|
||||
File.join(site.config['layouts'], layout.name)
|
||||
)
|
||||
|
||||
if layout = site.layouts[layout.data["layout"]]
|
||||
if used.include?(layout)
|
||||
layout = nil # avoid recursive chain
|
||||
else
|
||||
used << layout
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
output
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,9 +1,12 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
class Site
|
||||
attr_accessor :config, :layouts, :posts, :pages, :static_files,
|
||||
:categories, :exclude, :include, :source, :dest, :lsi, :pygments,
|
||||
:permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts, :gems
|
||||
:exclude, :include, :source, :dest, :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
|
||||
|
||||
@@ -11,54 +14,52 @@ module Jekyll
|
||||
#
|
||||
# config - A Hash containing site configuration details.
|
||||
def initialize(config)
|
||||
self.config = config.clone
|
||||
self.config = config.clone
|
||||
|
||||
%w[safe lsi pygments baseurl exclude include future show_drafts limit_posts keep_files gems].each do |opt|
|
||||
%w[safe lsi highlighter baseurl exclude include future unpublished
|
||||
show_drafts limit_posts keep_files gems].each do |opt|
|
||||
self.send("#{opt}=", config[opt])
|
||||
end
|
||||
|
||||
self.source = File.expand_path(config['source'])
|
||||
self.dest = File.expand_path(config['destination'])
|
||||
self.plugins = plugins_path
|
||||
self.permalink_style = config['permalink'].to_sym
|
||||
|
||||
self.plugin_manager = Jekyll::PluginManager.new(self)
|
||||
self.plugins = plugin_manager.plugins_path
|
||||
|
||||
self.file_read_opts = {}
|
||||
self.file_read_opts[:encoding] = config['encoding'] if config['encoding']
|
||||
|
||||
self.reset
|
||||
self.setup
|
||||
reset
|
||||
setup
|
||||
end
|
||||
|
||||
# Public: Read, process, and write this Site to output.
|
||||
#
|
||||
# Returns nothing.
|
||||
def process
|
||||
self.reset
|
||||
self.read
|
||||
self.generate
|
||||
self.render
|
||||
self.cleanup
|
||||
self.write
|
||||
reset
|
||||
read
|
||||
generate
|
||||
render
|
||||
cleanup
|
||||
write
|
||||
end
|
||||
|
||||
# Reset Site details.
|
||||
#
|
||||
# Returns nothing
|
||||
def reset
|
||||
self.time = if self.config['time']
|
||||
Time.parse(self.config['time'].to_s)
|
||||
else
|
||||
Time.now
|
||||
end
|
||||
self.layouts = {}
|
||||
self.posts = []
|
||||
self.pages = []
|
||||
self.static_files = []
|
||||
self.categories = Hash.new { |hash, key| hash[key] = [] }
|
||||
self.tags = Hash.new { |hash, key| hash[key] = [] }
|
||||
self.data = {}
|
||||
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
|
||||
|
||||
if self.limit_posts < 0
|
||||
if limit_posts < 0
|
||||
raise ArgumentError, "limit_posts must be a non-negative number"
|
||||
end
|
||||
end
|
||||
@@ -69,18 +70,7 @@ module Jekyll
|
||||
def setup
|
||||
ensure_not_in_dest
|
||||
|
||||
# If safe mode is off, load in any Ruby files under the plugins
|
||||
# directory.
|
||||
unless self.safe
|
||||
self.plugins.each do |plugins|
|
||||
Dir[File.join(plugins, "**/*.rb")].sort.each do |f|
|
||||
require f
|
||||
end
|
||||
end
|
||||
self.gems.each do |gem|
|
||||
require gem
|
||||
end
|
||||
end
|
||||
plugin_manager.conscientious_require
|
||||
|
||||
self.converters = instantiate_subclasses(Jekyll::Converter)
|
||||
self.generators = instantiate_subclasses(Jekyll::Generator)
|
||||
@@ -89,22 +79,37 @@ module Jekyll
|
||||
# Check that the destination dir isn't the source dir or a directory
|
||||
# parent to the source dir.
|
||||
def ensure_not_in_dest
|
||||
dest = Pathname.new(self.dest)
|
||||
Pathname.new(self.source).ascend do |path|
|
||||
if path == dest
|
||||
raise FatalException.new "Destination directory cannot be or contain the Source directory."
|
||||
dest_pathname = Pathname.new(dest)
|
||||
Pathname.new(source).ascend do |path|
|
||||
if path == dest_pathname
|
||||
raise Errors::FatalException.new "Destination directory cannot be or contain the Source directory."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Internal: Setup the plugin search path
|
||||
# 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.
|
||||
#
|
||||
# Returns an Array of plugin search paths
|
||||
def plugins_path
|
||||
if (config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
|
||||
[File.join(self.source, config['plugins'])]
|
||||
# Returns a Hash containing collection name-to-instance pairs.
|
||||
def collections
|
||||
@collections ||= Hash[collection_names.map { |coll| [coll, Jekyll::Collection.new(self, coll)] } ]
|
||||
end
|
||||
|
||||
# The list of collection names.
|
||||
#
|
||||
# Returns an array of collection names from the configuration,
|
||||
# or an empty array if the `collections` key is not set.
|
||||
def collection_names
|
||||
case config['collections']
|
||||
when Hash
|
||||
config['collections'].keys
|
||||
when Array
|
||||
config['collections']
|
||||
when nil
|
||||
[]
|
||||
else
|
||||
Array(config['plugins']).map { |d| File.expand_path(d) }
|
||||
raise ArgumentError, "Your `collections` key must be a hash or an array."
|
||||
end
|
||||
end
|
||||
|
||||
@@ -112,25 +117,10 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read
|
||||
self.read_layouts
|
||||
self.read_directories
|
||||
self.read_data(config['data_source'])
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<layouts> and create a new Layout object
|
||||
# with each one.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_layouts
|
||||
base = File.join(self.source, self.config['layouts'])
|
||||
return unless File.exists?(base)
|
||||
entries = []
|
||||
Dir.chdir(base) { entries = filter_entries(Dir['**/*.*']) }
|
||||
|
||||
entries.each do |f|
|
||||
name = f.split(".")[0..-2].join(".")
|
||||
self.layouts[name] = Layout.new(self, base, f)
|
||||
end
|
||||
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
|
||||
@@ -141,25 +131,28 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_directories(dir = '')
|
||||
base = File.join(self.source, dir)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir.entries('.')) }
|
||||
base = File.join(source, dir)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
|
||||
|
||||
self.read_posts(dir)
|
||||
self.read_drafts(dir) if self.show_drafts
|
||||
self.posts.sort!
|
||||
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 = File.join(base, f)
|
||||
if File.directory?(f_abs)
|
||||
f_rel = File.join(dir, f)
|
||||
read_directories(f_rel) unless self.dest.sub(/\/$/, '') == f_abs
|
||||
elsif has_yaml_header?(f_abs)
|
||||
pages << Page.new(self, self.source, 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, self.source, dir, f)
|
||||
static_files << StaticFile.new(self, source, dir, f)
|
||||
end
|
||||
end
|
||||
|
||||
pages.sort_by!(&:name)
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_posts and create a new Post
|
||||
@@ -169,14 +162,12 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_posts(dir)
|
||||
posts = read_things(dir, '_posts', Post)
|
||||
posts = read_content(dir, '_posts', Post)
|
||||
|
||||
posts.each do |post|
|
||||
if post.published && (self.future || post.date <= self.time)
|
||||
aggregate_post_info(post)
|
||||
end
|
||||
aggregate_post_info(post) if publisher.publish?(post)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_drafts and create a new Post
|
||||
# object with each one.
|
||||
@@ -185,16 +176,20 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_drafts(dir)
|
||||
drafts = read_things(dir, '_drafts', Draft)
|
||||
drafts = read_content(dir, '_drafts', Draft)
|
||||
|
||||
drafts.each do |draft|
|
||||
aggregate_post_info(draft)
|
||||
if draft.published?
|
||||
aggregate_post_info(draft)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def read_things(dir, magic_dir, klass)
|
||||
things = get_entries(dir, magic_dir).map do |entry|
|
||||
klass.new(self, self.source, dir, entry) if klass.valid?(entry)
|
||||
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
|
||||
|
||||
@@ -202,18 +197,43 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing
|
||||
def read_data(dir)
|
||||
base = File.join(self.source, dir)
|
||||
return unless File.directory?(base) && (!self.safe || !File.symlink?(base))
|
||||
base = Jekyll.sanitized_path(source, dir)
|
||||
read_data_to(base, self.data)
|
||||
end
|
||||
|
||||
entries = Dir.chdir(base) { Dir['*.{yaml,yml}'] }
|
||||
entries.delete_if { |e| File.directory?(File.join(base, e)) }
|
||||
# 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}'] + Dir['*'].select { |fn| File.directory?(fn) }
|
||||
end
|
||||
|
||||
entries.each do |entry|
|
||||
path = File.join(self.source, dir, entry)
|
||||
next if File.symlink?(path) && self.safe
|
||||
path = Jekyll.sanitized_path(dir, entry)
|
||||
next if File.symlink?(path) && safe
|
||||
|
||||
key = sanitize_filename(File.basename(entry, '.*'))
|
||||
self.data[key] = YAML.safe_load_file(path)
|
||||
if File.directory?(path)
|
||||
read_data_to(path, data[key] = {})
|
||||
else
|
||||
data[key] = SafeYAML.load_file(path)
|
||||
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
|
||||
end
|
||||
|
||||
@@ -221,7 +241,7 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def generate
|
||||
self.generators.each do |generator|
|
||||
generators.each do |generator|
|
||||
generator.generate(self)
|
||||
end
|
||||
end
|
||||
@@ -232,13 +252,16 @@ module Jekyll
|
||||
def render
|
||||
relative_permalinks_deprecation_method
|
||||
|
||||
payload = site_payload
|
||||
[self.posts, self.pages].flatten.each do |page_or_post|
|
||||
page_or_post.render(self.layouts, payload)
|
||||
collections.each do |label, collection|
|
||||
collection.docs.each do |document|
|
||||
document.output = Jekyll::Renderer.new(self, document).run
|
||||
end
|
||||
end
|
||||
|
||||
self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a } }
|
||||
self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a } }
|
||||
payload = site_payload
|
||||
[posts, pages].flatten.each do |page_or_post|
|
||||
page_or_post.render(layouts, payload)
|
||||
end
|
||||
rescue Errno::ENOENT => e
|
||||
# ignore missing layout dir
|
||||
end
|
||||
@@ -254,7 +277,7 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def write
|
||||
each_site_file { |item| item.write(self.dest) }
|
||||
each_site_file { |item| item.write(dest) }
|
||||
end
|
||||
|
||||
# Construct a Hash of Posts indexed by the specified Post attribute.
|
||||
@@ -273,18 +296,26 @@ module Jekyll
|
||||
def post_attr_hash(post_attr)
|
||||
# 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 { |hsh, key| hsh[key] = Array.new }
|
||||
self.posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
|
||||
hash.values.map { |sortme| sortme.sort! { |a, b| b <=> a } }
|
||||
hash = Hash.new { |h, key| h[key] = [] }
|
||||
posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
|
||||
hash.values.each { |posts| posts.sort!.reverse! }
|
||||
hash
|
||||
end
|
||||
|
||||
def tags
|
||||
post_attr_hash('tags')
|
||||
end
|
||||
|
||||
def categories
|
||||
post_attr_hash('categories')
|
||||
end
|
||||
|
||||
# Prepare site data for site payload. The method maintains backward compatibility
|
||||
# if the key 'data' is already used in _config.yml.
|
||||
#
|
||||
# Returns the Hash to be hooked to site.data.
|
||||
def site_data
|
||||
self.config['data'] || self.data
|
||||
config['data'] || data
|
||||
end
|
||||
|
||||
# The Hash payload containing site-wide data.
|
||||
@@ -301,15 +332,25 @@ module Jekyll
|
||||
# "tags" - The Hash of tag values and Posts.
|
||||
# See Site#post_attr_hash for type info.
|
||||
def site_payload
|
||||
{"jekyll" => { "version" => Jekyll::VERSION },
|
||||
"site" => self.config.merge({
|
||||
"time" => self.time,
|
||||
"posts" => self.posts.sort { |a, b| b <=> a },
|
||||
"pages" => self.pages,
|
||||
"html_pages" => self.pages.reject { |page| !page.html? },
|
||||
"categories" => post_attr_hash('categories'),
|
||||
"tags" => post_attr_hash('tags'),
|
||||
"data" => site_data})}
|
||||
{
|
||||
"jekyll" => {
|
||||
"version" => Jekyll::VERSION,
|
||||
"environment" => Jekyll.env
|
||||
},
|
||||
"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 },
|
||||
"pages" => pages,
|
||||
"static_files" => static_files.sort { |a, b| a.relative_path <=> b.relative_path },
|
||||
"html_pages" => pages.select { |page| page.html? || page.url.end_with?("/") },
|
||||
"categories" => post_attr_hash('categories'),
|
||||
"tags" => post_attr_hash('tags'),
|
||||
"collections" => collections,
|
||||
"documents" => documents,
|
||||
"data" => site_data
|
||||
}))
|
||||
}
|
||||
end
|
||||
|
||||
# Filter out any files/directories that are hidden or backup files (start
|
||||
@@ -320,8 +361,8 @@ module Jekyll
|
||||
# entries - The Array of String file/directory entries to filter.
|
||||
#
|
||||
# Returns the Array of filtered entries.
|
||||
def filter_entries(entries)
|
||||
EntryFilter.new(self).filter(entries)
|
||||
def filter_entries(entries, base_directory = nil)
|
||||
EntryFilter.new(self, base_directory).filter(entries)
|
||||
end
|
||||
|
||||
# Get the implementation class for the given Converter.
|
||||
@@ -330,7 +371,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the Converter instance implementing the given Converter.
|
||||
def getConverterImpl(klass)
|
||||
matches = self.converters.select { |c| c.class == klass }
|
||||
matches = converters.select { |c| c.class == klass }
|
||||
if impl = matches.first
|
||||
impl
|
||||
else
|
||||
@@ -346,10 +387,10 @@ module Jekyll
|
||||
#
|
||||
# Returns array of instances of subclasses of parameter
|
||||
def instantiate_subclasses(klass)
|
||||
klass.subclasses.select do |c|
|
||||
!self.safe || c.safe
|
||||
klass.descendants.select do |c|
|
||||
!safe || c.safe
|
||||
end.sort.map do |c|
|
||||
c.new(self.config)
|
||||
c.new(config)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -360,9 +401,9 @@ module Jekyll
|
||||
#
|
||||
# Returns the list of entries to process
|
||||
def get_entries(dir, subfolder)
|
||||
base = File.join(self.source, dir, subfolder)
|
||||
return [] unless File.exists?(base)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir['**/*']) }
|
||||
base = File.join(source, dir, subfolder)
|
||||
return [] unless File.exist?(base)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir['**/*'], base) }
|
||||
entries.delete_if { |e| File.directory?(File.join(base, e)) }
|
||||
end
|
||||
|
||||
@@ -372,44 +413,50 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing
|
||||
def aggregate_post_info(post)
|
||||
self.posts << post
|
||||
post.categories.each { |c| self.categories[c] << post }
|
||||
post.tags.each { |c| self.tags[c] << post }
|
||||
posts << post
|
||||
end
|
||||
|
||||
def relative_permalinks_deprecation_method
|
||||
if config['relative_permalinks'] && has_relative_page?
|
||||
$stderr.puts # Places newline after "Generating..."
|
||||
Jekyll.logger.warn "Deprecation:", "Starting in 2.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."
|
||||
$stderr.print Jekyll.logger.formatted_topic("") + "..." # for "done."
|
||||
end
|
||||
end
|
||||
|
||||
def docs_to_write
|
||||
documents.select(&:write?)
|
||||
end
|
||||
|
||||
def documents
|
||||
collections.reduce(Set.new) do |docs, (_, collection)|
|
||||
docs + collection.docs + collection.files
|
||||
end.to_a
|
||||
end
|
||||
|
||||
def each_site_file
|
||||
%w(posts pages static_files).each do |type|
|
||||
self.send(type).each do |item|
|
||||
%w(posts pages static_files docs_to_write).each do |type|
|
||||
send(type).each do |item|
|
||||
yield item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def frontmatter_defaults
|
||||
@frontmatter_defaults ||= FrontmatterDefaults.new(self)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def has_relative_page?
|
||||
self.pages.any? { |page| page.uses_relative_permalinks }
|
||||
end
|
||||
|
||||
def has_yaml_header?(file)
|
||||
"---" == File.open(file) { |fd| fd.read(3) }
|
||||
pages.any? { |page| page.uses_relative_permalinks }
|
||||
end
|
||||
|
||||
def limit_posts!
|
||||
limit = self.posts.length < limit_posts ? self.posts.length : limit_posts
|
||||
self.posts = self.posts[-limit, limit]
|
||||
limit = posts.length < limit_posts ? posts.length : limit_posts
|
||||
self.posts = posts[-limit, limit]
|
||||
end
|
||||
|
||||
def site_cleaner
|
||||
@@ -417,9 +464,13 @@ module Jekyll
|
||||
end
|
||||
|
||||
def sanitize_filename(name)
|
||||
name = name.gsub(/[^\w\s_-]+/, '')
|
||||
name = name.gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
||||
name = name.gsub(/\s+/, '_')
|
||||
name.gsub!(/[^\w\s_-]+/, '')
|
||||
name.gsub!(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
||||
name.gsub(/\s+/, '_')
|
||||
end
|
||||
|
||||
def publisher
|
||||
@publisher ||= Publisher.new(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,16 +9,26 @@ module Jekyll
|
||||
# base - The String path to the <source>.
|
||||
# dir - The String path between <source> and the file.
|
||||
# name - The String filename of the file.
|
||||
def initialize(site, base, dir, name)
|
||||
def initialize(site, base, dir, name, collection = nil)
|
||||
@site = site
|
||||
@base = base
|
||||
@dir = dir
|
||||
@name = name
|
||||
@collection = collection
|
||||
end
|
||||
|
||||
# Returns source file path.
|
||||
def path
|
||||
File.join(@base, @dir, @name)
|
||||
File.join(*[@base, @dir, @name].compact)
|
||||
end
|
||||
|
||||
# Returns the source file path relative to the site source
|
||||
def relative_path
|
||||
@relative_path ||= File.join(*[@dir, @name].compact)
|
||||
end
|
||||
|
||||
def extname
|
||||
File.extname(path)
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
@@ -27,7 +37,15 @@ module Jekyll
|
||||
#
|
||||
# Returns destination file path.
|
||||
def destination(dest)
|
||||
File.join(dest, @dir, @name)
|
||||
File.join(*[dest, destination_rel_dir, @name].compact)
|
||||
end
|
||||
|
||||
def destination_rel_dir
|
||||
if @collection
|
||||
@dir.gsub(/\A_/, '')
|
||||
else
|
||||
@dir
|
||||
end
|
||||
end
|
||||
|
||||
# Returns last modification time for this file.
|
||||
@@ -42,6 +60,13 @@ module Jekyll
|
||||
@@mtimes[path] != mtime
|
||||
end
|
||||
|
||||
# Whether to write the file to the filesystem
|
||||
#
|
||||
# Returns true.
|
||||
def write?
|
||||
true
|
||||
end
|
||||
|
||||
# Write the static file to the destination directory (if modified).
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
@@ -54,6 +79,7 @@ module Jekyll
|
||||
@@mtimes[path] = mtime
|
||||
|
||||
FileUtils.mkdir_p(File.dirname(dest_path))
|
||||
FileUtils.rm(dest_path) if File.exist?(dest_path)
|
||||
FileUtils.cp(path, dest_path)
|
||||
|
||||
true
|
||||
@@ -66,5 +92,13 @@ module Jekyll
|
||||
@@mtimes = Hash.new
|
||||
nil
|
||||
end
|
||||
|
||||
def to_liquid
|
||||
{
|
||||
"path" => File.join("", relative_path),
|
||||
"modified_time" => mtime.to_s,
|
||||
"extname" => File.extname(relative_path)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,89 +1,58 @@
|
||||
module Jekyll
|
||||
class Stevenson
|
||||
attr_accessor :log_level
|
||||
|
||||
DEBUG = 0
|
||||
INFO = 1
|
||||
WARN = 2
|
||||
ERROR = 3
|
||||
|
||||
# Public: Create a new instance of Stevenson, Jekyll's logger
|
||||
#
|
||||
# level - (optional, integer) the log level
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(level = INFO)
|
||||
@log_level = level
|
||||
end
|
||||
|
||||
# Public: Print a jekyll debug message to stdout
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def debug(topic, message = nil)
|
||||
$stdout.puts(message(topic, message)) if log_level <= DEBUG
|
||||
class Stevenson < ::Logger
|
||||
def initialize
|
||||
@progname = nil
|
||||
@level = DEBUG
|
||||
@default_formatter = Formatter.new
|
||||
@logdev = $stdout
|
||||
@formatter = proc do |severity, datetime, progname, msg|
|
||||
"#{msg}"
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message to stdout
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def info(topic, message = nil)
|
||||
$stdout.puts(message(topic, message)) if log_level <= INFO
|
||||
def add(severity, message = nil, progname = nil, &block)
|
||||
severity ||= UNKNOWN
|
||||
@logdev = set_logdevice(severity)
|
||||
|
||||
if @logdev.nil? or severity < @level
|
||||
return true
|
||||
end
|
||||
progname ||= @progname
|
||||
if message.nil?
|
||||
if block_given?
|
||||
message = yield
|
||||
else
|
||||
message = progname
|
||||
progname = @progname
|
||||
end
|
||||
end
|
||||
@logdev.puts(
|
||||
format_message(format_severity(severity), Time.now, progname, message))
|
||||
true
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message to stderr
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def warn(topic, message = nil)
|
||||
$stderr.puts(message(topic, message).yellow) if log_level <= WARN
|
||||
# Log a +WARN+ message
|
||||
def warn(progname = nil, &block)
|
||||
add(WARN, nil, progname.yellow, &block)
|
||||
end
|
||||
|
||||
# Public: Print a jekyll error message to stderr
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def error(topic, message = nil)
|
||||
$stderr.puts(message(topic, message).red) if log_level <= ERROR
|
||||
# Log an +ERROR+ message
|
||||
def error(progname = nil, &block)
|
||||
add(ERROR, nil, progname.red, &block)
|
||||
end
|
||||
|
||||
# Public: Print a Jekyll error message to stderr and immediately abort the process
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail (can be omitted)
|
||||
#
|
||||
# Returns nothing
|
||||
def abort_with(topic, message = nil)
|
||||
error(topic, message)
|
||||
abort
|
||||
def close
|
||||
# No LogDevice in use
|
||||
end
|
||||
|
||||
# Public: Build a Jekyll topic method
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns the formatted message
|
||||
def message(topic, message)
|
||||
formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ')
|
||||
end
|
||||
private
|
||||
|
||||
# Public: Format the topic
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
#
|
||||
# Returns the formatted topic statement
|
||||
def formatted_topic(topic)
|
||||
"#{topic} ".rjust(20)
|
||||
def set_logdevice(severity)
|
||||
if severity > INFO
|
||||
$stderr
|
||||
else
|
||||
$stdout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
# Gist Liquid Tag
|
||||
#
|
||||
# Example:
|
||||
# {% gist 1234567 %}
|
||||
# {% gist 1234567 file.rb %}
|
||||
|
||||
module Jekyll
|
||||
class GistTag < Liquid::Tag
|
||||
|
||||
def render(context)
|
||||
if tag_contents = determine_arguments(@markup.strip)
|
||||
gist_id, filename = tag_contents[0], tag_contents[1]
|
||||
gist_script_tag(gist_id, filename)
|
||||
else
|
||||
raise ArgumentError.new <<-eos
|
||||
Syntax error in tag 'gist' while parsing the following markup:
|
||||
|
||||
#{@markup}
|
||||
|
||||
Valid syntax:
|
||||
for public gists: {% gist 1234567 %}
|
||||
for private gists: {% gist user/1234567 %}
|
||||
eos
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def determine_arguments(input)
|
||||
matched = if input.include?("/")
|
||||
input.match(/\A([a-zA-Z0-9\/\-_]+) ?(\S*)\Z/)
|
||||
else
|
||||
input.match(/\A(\d+) ?(\S*)\Z/)
|
||||
end
|
||||
[matched[1].strip, matched[2].strip] if matched && matched.length >= 3
|
||||
end
|
||||
|
||||
def gist_script_tag(gist_id, filename = nil)
|
||||
if filename.empty?
|
||||
"<script src=\"https://gist.github.com/#{gist_id}.js\"> </script>"
|
||||
else
|
||||
"<script src=\"https://gist.github.com/#{gist_id}.js?file=#{filename}\"> </script>"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('gist', Jekyll::GistTag)
|
||||
@@ -4,12 +4,11 @@ module Jekyll
|
||||
include Liquid::StandardFilters
|
||||
|
||||
# The regular expression syntax checker. Start with the language specifier.
|
||||
# Follow that by zero or more space separated options that take one of two
|
||||
# forms:
|
||||
# Follow that by zero or more space separated options that take one of three
|
||||
# forms: name, name=value, or name="<quoted list>"
|
||||
#
|
||||
# 1. name
|
||||
# 2. name=value
|
||||
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
|
||||
# <quoted list> is a space-separated list of numbers
|
||||
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=(\w+|"([0-9]+\s)*[0-9]+"))?)*)$/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
@@ -17,18 +16,18 @@ module Jekyll
|
||||
@lang = $1.downcase
|
||||
@options = {}
|
||||
if defined?($2) && $2 != ''
|
||||
$2.split.each do |opt|
|
||||
# Split along 3 possible forms -- key="<quoted list>", key=value, or key
|
||||
$2.scan(/(?:\w="[^"]*"|\w=\w|\w)+/) do |opt|
|
||||
key, value = opt.split('=')
|
||||
if value.nil?
|
||||
if key == 'linenos'
|
||||
value = 'inline'
|
||||
else
|
||||
value = true
|
||||
end
|
||||
# If a quoted list, convert to array
|
||||
if value && value.include?("\"")
|
||||
value.gsub!(/"/, "")
|
||||
value = value.split
|
||||
end
|
||||
@options[key] = value
|
||||
@options[key.to_sym] = value || true
|
||||
end
|
||||
end
|
||||
@options[:linenos] = "inline" if @options.key?(:linenos) and @options[:linenos] == true
|
||||
else
|
||||
raise SyntaxError.new <<-eos
|
||||
Syntax Error in tag 'highlight' while parsing the following markup:
|
||||
@@ -41,41 +40,81 @@ eos
|
||||
end
|
||||
|
||||
def render(context)
|
||||
if context.registers[:site].pygments
|
||||
render_pygments(context, super)
|
||||
prefix = context["highlighter_prefix"] || ""
|
||||
suffix = context["highlighter_suffix"] || ""
|
||||
code = super.to_s.strip
|
||||
|
||||
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(context, super)
|
||||
render_codehighlighter(code)
|
||||
end
|
||||
|
||||
rendered_output = add_code_tag(output)
|
||||
prefix + rendered_output + suffix
|
||||
end
|
||||
|
||||
def sanitized_opts(opts, is_safe)
|
||||
if is_safe
|
||||
Hash[[
|
||||
[:startinline, opts.fetch(:startinline, nil)],
|
||||
[:hl_linenos, opts.fetch(:hl_linenos, nil)],
|
||||
[:linenos, opts.fetch(:linenos, nil)],
|
||||
[:encoding, opts.fetch(:encoding, 'utf-8')],
|
||||
[:cssclass, opts.fetch(:cssclass, nil)]
|
||||
].reject {|f| f.last.nil? }]
|
||||
else
|
||||
opts
|
||||
end
|
||||
end
|
||||
|
||||
def render_pygments(context, code)
|
||||
def render_pygments(code, is_safe)
|
||||
require 'pygments'
|
||||
|
||||
@options[:encoding] = 'utf-8'
|
||||
|
||||
output = add_code_tags(
|
||||
Pygments.highlight(code, :lexer => @lang, :options => @options),
|
||||
@lang
|
||||
highlighted_code = Pygments.highlight(
|
||||
code,
|
||||
:lexer => @lang,
|
||||
:options => sanitized_opts(@options, is_safe)
|
||||
)
|
||||
|
||||
output = context["pygments_prefix"] + output if context["pygments_prefix"]
|
||||
output = output + context["pygments_suffix"] if context["pygments_suffix"]
|
||||
output
|
||||
if highlighted_code.nil?
|
||||
Jekyll.logger.error "There was an error highlighting your code:"
|
||||
puts
|
||||
Jekyll.logger.error code
|
||||
puts
|
||||
Jekyll.logger.error "While attempting to convert the above code, Pygments.rb" +
|
||||
" returned an unacceptable value."
|
||||
Jekyll.logger.error "This is usually a timeout problem solved by running `jekyll build` again."
|
||||
raise ArgumentError.new("Pygments.rb returned an unacceptable value when attempting to highlight some code.")
|
||||
end
|
||||
|
||||
highlighted_code
|
||||
end
|
||||
|
||||
def render_codehighlighter(context, code)
|
||||
#The div is required because RDiscount blows ass
|
||||
<<-HTML
|
||||
<div>
|
||||
<pre><code class='#{@lang}'>#{h(code).strip}</code></pre>
|
||||
</div>
|
||||
HTML
|
||||
def render_rouge(code)
|
||||
require '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>"
|
||||
end
|
||||
|
||||
def add_code_tags(code, lang)
|
||||
def render_codehighlighter(code)
|
||||
"<div class=\"highlight\"><pre>#{h(code).strip}</pre></div>"
|
||||
end
|
||||
|
||||
def add_code_tag(code)
|
||||
# Add nested <code> tags to code blocks
|
||||
code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
|
||||
code = code.sub(/<\/pre>/,"</code></pre>")
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Tags
|
||||
class IncludeTagError < StandardError
|
||||
@@ -14,12 +16,19 @@ module Jekyll
|
||||
SYNTAX_EXAMPLE = "{% include file.ext param='value' param2='value' %}"
|
||||
|
||||
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
|
||||
VARIABLE_SYNTAX = /(?<variable>[^{]*\{\{\s*(?<name>[\w\-\.]+)\s*(\|.*)?\}\}[^\s}]*)(?<params>.*)/
|
||||
|
||||
INCLUDES_DIR = '_includes'
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
@file, @params = markup.strip.split(' ', 2);
|
||||
matched = markup.strip.match(VARIABLE_SYNTAX)
|
||||
if matched
|
||||
@file = matched['variable'].strip
|
||||
@params = matched['params'].strip
|
||||
else
|
||||
@file, @params = markup.strip.split(' ', 2);
|
||||
end
|
||||
validate_params if @params
|
||||
end
|
||||
|
||||
@@ -48,11 +57,11 @@ module Jekyll
|
||||
raise ArgumentError.new <<-eos
|
||||
Invalid syntax for include tag. File contains invalid characters or sequences:
|
||||
|
||||
#{@file}
|
||||
#{file}
|
||||
|
||||
Valid syntax:
|
||||
|
||||
#{SYNTAX_EXAMPLE}
|
||||
#{SYNTAX_EXAMPLE}
|
||||
|
||||
eos
|
||||
end
|
||||
@@ -64,11 +73,11 @@ eos
|
||||
raise ArgumentError.new <<-eos
|
||||
Invalid syntax for include tag:
|
||||
|
||||
#{@params}
|
||||
#{@params}
|
||||
|
||||
Valid syntax:
|
||||
|
||||
#{SYNTAX_EXAMPLE}
|
||||
#{SYNTAX_EXAMPLE}
|
||||
|
||||
eos
|
||||
end
|
||||
@@ -79,22 +88,22 @@ eos
|
||||
context.registers[:site].file_read_opts
|
||||
end
|
||||
|
||||
def retrieve_variable(context)
|
||||
if /\{\{([\w\-\.]+)\}\}/ =~ @file
|
||||
raise ArgumentError.new("No variable #{$1} was found in include tag") if context[$1].nil?
|
||||
context[$1]
|
||||
# Render the variable if required
|
||||
def render_variable(context)
|
||||
if @file.match(VARIABLE_SYNTAX)
|
||||
partial = Liquid::Template.parse(@file)
|
||||
partial.render!(context)
|
||||
end
|
||||
end
|
||||
|
||||
def render(context)
|
||||
dir = File.join(context.registers[:site].source, INCLUDES_DIR)
|
||||
validate_dir(dir, context.registers[:site].safe)
|
||||
dir = File.join(File.realpath(context.registers[:site].source), INCLUDES_DIR)
|
||||
|
||||
file = retrieve_variable(context) || @file
|
||||
file = render_variable(context) || @file
|
||||
validate_file_name(file)
|
||||
|
||||
path = File.join(dir, file)
|
||||
validate_file(path, context.registers[:site].safe)
|
||||
validate_path(path, dir, context.registers[:site].safe)
|
||||
|
||||
begin
|
||||
partial = Liquid::Template.parse(source(path, context))
|
||||
@@ -108,27 +117,25 @@ eos
|
||||
end
|
||||
end
|
||||
|
||||
def validate_dir(dir, safe)
|
||||
if File.symlink?(dir) && safe
|
||||
raise IOError.new "Includes directory '#{dir}' cannot be a symlink"
|
||||
def validate_path(path, dir, safe)
|
||||
if safe && !realpath_prefixed_with?(path, dir)
|
||||
raise IOError.new "The included file '#{path}' should exist and should not be a symlink"
|
||||
elsif !File.exist?(path)
|
||||
raise IOError.new "Included file '#{path_relative_to_source(dir, path)}' not found"
|
||||
end
|
||||
end
|
||||
|
||||
def validate_file(file, safe)
|
||||
if !File.exists?(file)
|
||||
raise IOError.new "Included file '#{@file}' not found in '#{INCLUDES_DIR}' directory"
|
||||
elsif File.symlink?(file) && safe
|
||||
raise IOError.new "The included file '#{INCLUDES_DIR}/#{@file}' should not be a symlink"
|
||||
end
|
||||
def path_relative_to_source(dir, path)
|
||||
File.join(INCLUDES_DIR, path.sub(Regexp.new("^#{dir}"), ""))
|
||||
end
|
||||
|
||||
def blank?
|
||||
false
|
||||
def realpath_prefixed_with?(path, dir)
|
||||
File.exist?(path) && File.realpath(path).start_with?(dir)
|
||||
end
|
||||
|
||||
# This method allows to modify the file content by inheriting from the class.
|
||||
def source(file, context)
|
||||
File.read_with_options(file, file_read_opts(context))
|
||||
File.read(file, file_read_opts(context))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,8 +7,9 @@ module Jekyll
|
||||
|
||||
def initialize(name)
|
||||
all, path, date, slug = *name.sub(/^\//, "").match(MATCHER)
|
||||
raise ArgumentError.new("'#{name}' does not contain valid date and/or title.") unless all
|
||||
@slug = path ? path + slug : slug
|
||||
@date = Time.parse(date)
|
||||
@date = Utils.parse_date(date, "'#{name}' does not contain valid date.")
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
@@ -38,7 +39,15 @@ module Jekyll
|
||||
def initialize(tag_name, post, tokens)
|
||||
super
|
||||
@orig_post = post.strip
|
||||
@post = PostComparer.new(@orig_post)
|
||||
begin
|
||||
@post = PostComparer.new(@orig_post)
|
||||
rescue
|
||||
raise ArgumentError.new <<-eos
|
||||
Could not parse name of post "#{@orig_post}" in tag 'post_url'.
|
||||
|
||||
Make sure the post exists and the name is correct.
|
||||
eos
|
||||
end
|
||||
end
|
||||
|
||||
def render(context)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'uri'
|
||||
|
||||
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
||||
#
|
||||
# Examples
|
||||
@@ -22,9 +24,9 @@ module Jekyll
|
||||
# template. Instead, the given permalink will be
|
||||
# used as URL.
|
||||
def initialize(options)
|
||||
@template = options[:template]
|
||||
@template = options[:template]
|
||||
@placeholders = options[:placeholders] || {}
|
||||
@permalink = options[:permalink]
|
||||
@permalink = options[:permalink]
|
||||
|
||||
if (@template || @permalink).nil?
|
||||
raise ArgumentError, "One of :template or :permalink must be supplied."
|
||||
@@ -44,12 +46,13 @@ module Jekyll
|
||||
# Returns the _unsanitizied_ String URL
|
||||
def generate_url
|
||||
@placeholders.inject(@template) do |result, token|
|
||||
result.gsub(/:#{token.first}/, token.last)
|
||||
result.gsub(/:#{token.first}/, self.class.escape_path(token.last))
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a sanitized String URL
|
||||
def sanitize_url(in_url)
|
||||
|
||||
# Remove all double slashes
|
||||
url = in_url.gsub(/\/\//, "/")
|
||||
|
||||
@@ -61,7 +64,46 @@ module Jekyll
|
||||
|
||||
# Always add a leading slash
|
||||
url.gsub!(/\A([^\/])/, '/\1')
|
||||
|
||||
url
|
||||
end
|
||||
|
||||
# Escapes a path to be a valid URL path segment
|
||||
#
|
||||
# path - The path to be escaped.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# URL.escape_path("/a b")
|
||||
# # => "/a%20b"
|
||||
#
|
||||
# Returns the escaped path.
|
||||
def self.escape_path(path)
|
||||
# Because URI.escape doesn't escape '?', '[' and ']' by defaut,
|
||||
# specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
|
||||
#
|
||||
# URI path segment is defined in RFC 3986 as follows:
|
||||
# segment = *pchar
|
||||
# pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
# pct-encoded = "%" HEXDIG HEXDIG
|
||||
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
# / "*" / "+" / "," / ";" / "="
|
||||
URI.escape(path, /[^a-zA-Z\d\-._~!$&\'()*+,;=:@\/]/).encode('utf-8')
|
||||
end
|
||||
|
||||
# Unescapes a URL path segment
|
||||
#
|
||||
# path - The path to be unescaped.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# URL.unescape_path("/a%20b")
|
||||
# # => "/a b"
|
||||
#
|
||||
# Returns the unescaped path.
|
||||
def self.unescape_path(path)
|
||||
URI.unescape(path.encode('utf-8'))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
106
lib/jekyll/utils.rb
Normal file
106
lib/jekyll/utils.rb
Normal file
@@ -0,0 +1,106 @@
|
||||
module Jekyll
|
||||
module Utils
|
||||
extend self
|
||||
|
||||
# Merges a master hash with another hash, recursively.
|
||||
#
|
||||
# master_hash - the "parent" hash whose values will be overridden
|
||||
# other_hash - the other hash whose values will be persisted after the merge
|
||||
#
|
||||
# This code was lovingly stolen from some random gem:
|
||||
# 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.keys.each 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])
|
||||
next
|
||||
end
|
||||
|
||||
target[key] = other_hash[key]
|
||||
end
|
||||
|
||||
target
|
||||
end
|
||||
|
||||
# Read array from the supplied hash favouring the singular key
|
||||
# and then the plural key, and handling any nil entries.
|
||||
#
|
||||
# hash - the hash to read from
|
||||
# singular_key - the singular key
|
||||
# plural_key - the plural key
|
||||
#
|
||||
# Returns an array
|
||||
def pluralized_array_from_hash(hash, singular_key, plural_key)
|
||||
[].tap do |array|
|
||||
array << (value_from_singular_key(hash, singular_key) || value_from_plural_key(hash, plural_key))
|
||||
end.flatten.compact
|
||||
end
|
||||
|
||||
def value_from_singular_key(hash, key)
|
||||
hash[key] if (hash.key?(key) || (hash.default_proc && hash[key]))
|
||||
end
|
||||
|
||||
def value_from_plural_key(hash, key)
|
||||
if hash.key?(key) || (hash.default_proc && hash[key])
|
||||
val = hash[key]
|
||||
case val
|
||||
when String
|
||||
val.split
|
||||
when Array
|
||||
val.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def transform_keys(hash)
|
||||
result = {}
|
||||
hash.each_key do |key|
|
||||
result[yield(key)] = hash[key]
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Apply #to_sym to all keys in the hash
|
||||
#
|
||||
# hash - the hash to which to apply this transformation
|
||||
#
|
||||
# Returns a new hash with symbolized keys
|
||||
def symbolize_hash_keys(hash)
|
||||
transform_keys(hash) { |key| key.to_sym rescue key }
|
||||
end
|
||||
|
||||
# Apply #to_s to all keys in the Hash
|
||||
#
|
||||
# hash - the hash to which to apply this transformation
|
||||
#
|
||||
# Returns a new hash with stringified keys
|
||||
def stringify_hash_keys(hash)
|
||||
transform_keys(hash) { |key| key.to_s rescue key }
|
||||
end
|
||||
|
||||
# Parse a date/time and throw an error if invalid
|
||||
#
|
||||
# input - the date/time to parse
|
||||
# msg - (optional) the error message to show the user
|
||||
#
|
||||
# Returns the parsed date if successful, throws a FatalException
|
||||
# if not
|
||||
def parse_date(input, msg = "Input could not be parsed.")
|
||||
Time.parse(input)
|
||||
rescue ArgumentError
|
||||
raise Errors::FatalException.new("Invalid date '#{input}': " + msg)
|
||||
end
|
||||
|
||||
# Determines whether a given file has
|
||||
#
|
||||
# Returns true if the YAML front matter is present.
|
||||
def has_yaml_header?(file)
|
||||
!!(File.open(file, 'rb') { |f| f.read(5) } =~ /\A---\r?\n/)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
3
lib/jekyll/version.rb
Normal file
3
lib/jekyll/version.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
module Jekyll
|
||||
VERSION = '2.3.0'
|
||||
end
|
||||
@@ -1,3 +1,14 @@
|
||||
name: Your New Jekyll Site
|
||||
markdown: redcarpet
|
||||
pygments: true
|
||||
# Site settings
|
||||
title: Your awesome title
|
||||
email: your-email@domain.com
|
||||
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/
|
||||
url: "http://yourdomain.com" # the base hostname & protocol for your site
|
||||
twitter_username: jekyllrb
|
||||
github_username: jekyll
|
||||
|
||||
# Build settings
|
||||
markdown: kramdown
|
||||
|
||||
55
lib/site_template/_includes/footer.html
Normal file
55
lib/site_template/_includes/footer.html
Normal file
@@ -0,0 +1,55 @@
|
||||
<footer class="site-footer">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<h2 class="footer-heading">{{ site.title }}</h2>
|
||||
|
||||
<div class="footer-col-wrapper">
|
||||
<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">
|
||||
<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>
|
||||
</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>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-3">
|
||||
<p class="text">{{ site.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
11
lib/site_template/_includes/head.html
Normal file
11
lib/site_template/_includes/head.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
||||
<title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}</title>
|
||||
<meta name="description" content="{{ site.description }}">
|
||||
|
||||
<link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}">
|
||||
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
|
||||
</head>
|
||||
27
lib/site_template/_includes/header.html
Normal file
27
lib/site_template/_includes/header.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<header class="site-header">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<a class="site-title" href="{{ site.baseurl }}/">{{ site.title }}</a>
|
||||
|
||||
<nav class="site-nav">
|
||||
<a href="#" class="menu-icon">
|
||||
<svg viewBox="0 0 18 15">
|
||||
<path fill="#424242" d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.031C17.335,0,18,0.665,18,1.484L18,1.484z"/>
|
||||
<path fill="#424242" d="M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0c0-0.82,0.665-1.484,1.484-1.484 h15.031C17.335,6.031,18,6.696,18,7.516L18,7.516z"/>
|
||||
<path fill="#424242" d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z"/>
|
||||
</svg>
|
||||
</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>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
</header>
|
||||
@@ -1,44 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>{{ page.title }}</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<!-- syntax highlighting CSS -->
|
||||
<link rel="stylesheet" href="/css/syntax.css">
|
||||
{% include head.html %}
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<body>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
{% include header.html %}
|
||||
|
||||
<div class="site">
|
||||
<div class="header">
|
||||
<h1 class="title"><a href="/">{{ site.name }}</a></h1>
|
||||
<a class="extra" href="/">home</a>
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ content }}
|
||||
{% include footer.html %}
|
||||
|
||||
<div class="footer">
|
||||
<div class="contact">
|
||||
<p>
|
||||
Your Name<br />
|
||||
What You Are<br />
|
||||
you@example.com
|
||||
</p>
|
||||
</div>
|
||||
<div class="contact">
|
||||
<p>
|
||||
<a href="https://github.com/yourusername">github.com/yourusername</a><br />
|
||||
<a href="https://twitter.com/yourusername">twitter.com/yourusername</a><br />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
14
lib/site_template/_layouts/page.html
Normal file
14
lib/site_template/_layouts/page.html
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">{{ page.title }}</h1>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
{{ content }}
|
||||
</article>
|
||||
|
||||
</div>
|
||||
@@ -1,9 +1,15 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
<h2>{{ page.title }}</h2>
|
||||
<p class="meta">{{ page.date | date_to_string }}</p>
|
||||
|
||||
<div class="post">
|
||||
{{ content }}
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">{{ page.title }}</h1>
|
||||
<p class="post-meta">{{ page.date | date: "%b %-d, %Y" }}{% if page.author %} • {{ page.author }}{% endif %}{% if page.meta %} • {{ page.meta }}{% endif %}</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
{{ content }}
|
||||
</article>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -4,9 +4,9 @@ title: "Welcome to Jekyll!"
|
||||
date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S') %>
|
||||
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 --watch`, which launches a web server and auto-regenerates your site when a file is updated.
|
||||
|
||||
You'll find this post in your `_posts` directory - edit this post and re-build (or run with the `-w` switch) to see your changes!
|
||||
To add new posts, simply add a file in the `_posts` directory that follows the convention: YYYY-MM-DD-name-of-post.ext.
|
||||
To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.
|
||||
|
||||
Jekyll also offers powerful support for code snippets:
|
||||
|
||||
@@ -18,7 +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].
|
||||
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].
|
||||
|
||||
[jekyll-gh]: https://github.com/mojombo/jekyll
|
||||
[jekyll]: http://jekyllrb.com
|
||||
[jekyll]: http://jekyllrb.com
|
||||
[jekyll-gh]: https://github.com/jekyll/jekyll
|
||||
[jekyll-help]: https://github.com/jekyll/jekyll-help
|
||||
|
||||
203
lib/site_template/_sass/_base.scss
Normal file
203
lib/site_template/_sass/_base.scss
Normal file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* Reset some basic elements
|
||||
*/
|
||||
body, h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre, hr,
|
||||
dl, dd, ol, ul, figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Basic styling
|
||||
*/
|
||||
body {
|
||||
font-family: $base-font-family;
|
||||
font-size: $base-font-size;
|
||||
line-height: $base-line-height;
|
||||
font-weight: 300;
|
||||
color: $text-color;
|
||||
background-color: $background-color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set `margin-bottom` to maintain vertycal rhythm
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre,
|
||||
ul, ol, dl, figure,
|
||||
%vertical-rhythm {
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Images
|
||||
*/
|
||||
img {
|
||||
max-width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Figures
|
||||
*/
|
||||
figure > img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Lists
|
||||
*/
|
||||
ul, ol {
|
||||
margin-left: $spacing-unit;
|
||||
}
|
||||
|
||||
li {
|
||||
> ul,
|
||||
> ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Headings
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Links
|
||||
*/
|
||||
a {
|
||||
color: $brand-color;
|
||||
text-decoration: none;
|
||||
|
||||
&:visited {
|
||||
color: darken($brand-color, 15%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $text-color;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Blockquotes
|
||||
*/
|
||||
blockquote {
|
||||
color: $grey-color;
|
||||
border-left: 4px solid $grey-color-light;
|
||||
padding-left: $spacing-unit / 2;
|
||||
font-size: 18px;
|
||||
letter-spacing: -1px;
|
||||
font-style: italic;
|
||||
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Code formatting
|
||||
*/
|
||||
pre,
|
||||
code {
|
||||
font-size: 15px;
|
||||
border: 1px solid $grey-color-light;
|
||||
border-radius: 3px;
|
||||
background-color: #eef;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 8px 12px;
|
||||
overflow-x: scroll;
|
||||
|
||||
> code {
|
||||
border: 0;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper
|
||||
*/
|
||||
.wrapper {
|
||||
max-width: -webkit-calc(800px - (#{$spacing-unit} * 2));
|
||||
max-width: calc(800px - (#{$spacing-unit} * 2));
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-right: $spacing-unit;
|
||||
padding-left: $spacing-unit;
|
||||
@extend %clearfix;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
max-width: -webkit-calc(800px - (#{$spacing-unit}));
|
||||
max-width: calc(800px - (#{$spacing-unit}));
|
||||
padding-right: $spacing-unit / 2;
|
||||
padding-left: $spacing-unit / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clearfix
|
||||
*/
|
||||
%clearfix {
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Icons
|
||||
*/
|
||||
.icon {
|
||||
|
||||
> svg {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
|
||||
path {
|
||||
fill: $grey-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
236
lib/site_template/_sass/_layout.scss
Normal file
236
lib/site_template/_sass/_layout.scss
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Site header
|
||||
*/
|
||||
.site-header {
|
||||
border-top: 5px solid $grey-color-dark;
|
||||
border-bottom: 1px solid $grey-color-light;
|
||||
min-height: 56px;
|
||||
|
||||
// Positioning context for the mobile navigation icon
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 26px;
|
||||
line-height: 56px;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 0;
|
||||
float: left;
|
||||
|
||||
&,
|
||||
&:visited {
|
||||
color: $grey-color-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
float: right;
|
||||
line-height: 56px;
|
||||
|
||||
.menu-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: $text-color;
|
||||
line-height: $base-line-height;
|
||||
|
||||
// Gaps between nav items, but not on the first one
|
||||
&:not(:first-child) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-query($on-palm) {
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
right: 30px;
|
||||
background-color: $background-color;
|
||||
border: 1px solid $grey-color-light;
|
||||
border-radius: 5px;
|
||||
text-align: right;
|
||||
|
||||
.menu-icon {
|
||||
display: block;
|
||||
float: right;
|
||||
width: 36px;
|
||||
height: 26px;
|
||||
line-height: 0;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
|
||||
> svg {
|
||||
width: 18px;
|
||||
height: 15px;
|
||||
|
||||
path {
|
||||
fill: $grey-color-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.trigger {
|
||||
clear: both;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover .trigger {
|
||||
display: block;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Site footer
|
||||
*/
|
||||
.site-footer {
|
||||
border-top: 1px solid $grey-color-light;
|
||||
padding: $spacing-unit 0;
|
||||
}
|
||||
|
||||
.footer-heading {
|
||||
font-size: 18px;
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
.contact-list,
|
||||
.social-media-list {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.footer-col-wrapper {
|
||||
font-size: 15px;
|
||||
color: $grey-color;
|
||||
margin-left: -$spacing-unit / 2;
|
||||
@extend %clearfix;
|
||||
}
|
||||
|
||||
.footer-col {
|
||||
float: left;
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
padding-left: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
.footer-col-1 {
|
||||
width: -webkit-calc(35% - (#{$spacing-unit} / 2));
|
||||
width: calc(35% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-2 {
|
||||
width: -webkit-calc(20% - (#{$spacing-unit} / 2));
|
||||
width: calc(20% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-3 {
|
||||
width: -webkit-calc(45% - (#{$spacing-unit} / 2));
|
||||
width: calc(45% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
.footer-col-1,
|
||||
.footer-col-2 {
|
||||
width: -webkit-calc(50% - (#{$spacing-unit} / 2));
|
||||
width: calc(50% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-3 {
|
||||
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||
width: calc(100% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
}
|
||||
|
||||
@include media-query($on-palm) {
|
||||
.footer-col {
|
||||
float: none;
|
||||
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||
width: calc(100% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Page content
|
||||
*/
|
||||
.page-content {
|
||||
padding: $spacing-unit 0;
|
||||
}
|
||||
|
||||
.page-heading {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.post-list {
|
||||
margin-left: 0;
|
||||
list-style: none;
|
||||
|
||||
> li {
|
||||
margin-bottom: $spacing-unit;
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
font-size: $small-font-size;
|
||||
color: $grey-color;
|
||||
}
|
||||
|
||||
.post-link {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Posts
|
||||
*/
|
||||
.post-header {
|
||||
margin-bottom: $spacing-unit;
|
||||
}
|
||||
|
||||
.post-title {
|
||||
font-size: 42px;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
margin-bottom: $spacing-unit;
|
||||
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 26px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 20px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
67
lib/site_template/_sass/_syntax-highlighting.scss
Normal file
67
lib/site_template/_sass/_syntax-highlighting.scss
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Syntax highlighting styles
|
||||
*/
|
||||
.highlight {
|
||||
background: #fff;
|
||||
@extend %vertical-rhythm;
|
||||
|
||||
.c { color: #998; font-style: italic } // Comment
|
||||
.err { color: #a61717; background-color: #e3d2d2 } // Error
|
||||
.k { font-weight: bold } // Keyword
|
||||
.o { font-weight: bold } // Operator
|
||||
.cm { color: #998; font-style: italic } // Comment.Multiline
|
||||
.cp { color: #999; font-weight: bold } // Comment.Preproc
|
||||
.c1 { color: #998; font-style: italic } // Comment.Single
|
||||
.cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special
|
||||
.gd { color: #000; background-color: #fdd } // Generic.Deleted
|
||||
.gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific
|
||||
.ge { font-style: italic } // Generic.Emph
|
||||
.gr { color: #a00 } // Generic.Error
|
||||
.gh { color: #999 } // Generic.Heading
|
||||
.gi { color: #000; background-color: #dfd } // Generic.Inserted
|
||||
.gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific
|
||||
.go { color: #888 } // Generic.Output
|
||||
.gp { color: #555 } // Generic.Prompt
|
||||
.gs { font-weight: bold } // Generic.Strong
|
||||
.gu { color: #aaa } // Generic.Subheading
|
||||
.gt { color: #a00 } // Generic.Traceback
|
||||
.kc { font-weight: bold } // Keyword.Constant
|
||||
.kd { font-weight: bold } // Keyword.Declaration
|
||||
.kp { font-weight: bold } // Keyword.Pseudo
|
||||
.kr { font-weight: bold } // Keyword.Reserved
|
||||
.kt { color: #458; font-weight: bold } // Keyword.Type
|
||||
.m { color: #099 } // Literal.Number
|
||||
.s { color: #d14 } // Literal.String
|
||||
.na { color: #008080 } // Name.Attribute
|
||||
.nb { color: #0086B3 } // Name.Builtin
|
||||
.nc { color: #458; font-weight: bold } // Name.Class
|
||||
.no { color: #008080 } // Name.Constant
|
||||
.ni { color: #800080 } // Name.Entity
|
||||
.ne { color: #900; font-weight: bold } // Name.Exception
|
||||
.nf { color: #900; font-weight: bold } // Name.Function
|
||||
.nn { color: #555 } // Name.Namespace
|
||||
.nt { color: #000080 } // Name.Tag
|
||||
.nv { color: #008080 } // Name.Variable
|
||||
.ow { font-weight: bold } // Operator.Word
|
||||
.w { color: #bbb } // Text.Whitespace
|
||||
.mf { color: #099 } // Literal.Number.Float
|
||||
.mh { color: #099 } // Literal.Number.Hex
|
||||
.mi { color: #099 } // Literal.Number.Integer
|
||||
.mo { color: #099 } // Literal.Number.Oct
|
||||
.sb { color: #d14 } // Literal.String.Backtick
|
||||
.sc { color: #d14 } // Literal.String.Char
|
||||
.sd { color: #d14 } // Literal.String.Doc
|
||||
.s2 { color: #d14 } // Literal.String.Double
|
||||
.se { color: #d14 } // Literal.String.Escape
|
||||
.sh { color: #d14 } // Literal.String.Heredoc
|
||||
.si { color: #d14 } // Literal.String.Interpol
|
||||
.sx { color: #d14 } // Literal.String.Other
|
||||
.sr { color: #009926 } // Literal.String.Regex
|
||||
.s1 { color: #d14 } // Literal.String.Single
|
||||
.ss { color: #990073 } // Literal.String.Symbol
|
||||
.bp { color: #999 } // Name.Builtin.Pseudo
|
||||
.vc { color: #008080 } // Name.Variable.Class
|
||||
.vg { color: #008080 } // Name.Variable.Global
|
||||
.vi { color: #008080 } // Name.Variable.Instance
|
||||
.il { color: #099 } // Literal.Number.Integer.Long
|
||||
}
|
||||
11
lib/site_template/about.md
Normal file
11
lib/site_template/about.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
layout: page
|
||||
title: About
|
||||
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 Jekyll at [github.com/jekyll/jekyll](https://github.com/jekyll/jekyll)
|
||||
@@ -1,160 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
/* Common
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Global Reset */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html, body { height: 100%; }
|
||||
|
||||
body {
|
||||
background-color: #FFF;
|
||||
font: 13.34px Helvetica, Arial, sans-serif;
|
||||
font-size: small;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-size: 100%; }
|
||||
|
||||
h1 { margin-bottom: 1em; }
|
||||
p { margin: 1em 0; }
|
||||
|
||||
a { color: #00a; }
|
||||
a:hover { color: #000; }
|
||||
a:visited { color: #a0a; }
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
/* Home
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
.posts {
|
||||
list-style-type: none;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.posts li {
|
||||
line-height: 1.75em;
|
||||
}
|
||||
|
||||
.posts span {
|
||||
color: #aaa;
|
||||
font-family: Monaco, "Courier New", monospace;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
/* Site
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
|
||||
.site {
|
||||
font-size: 115%;
|
||||
text-align: justify;
|
||||
width: 42em;
|
||||
margin: 3em auto 2em;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.header a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: inline-block;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.title a {
|
||||
color: #a00;
|
||||
}
|
||||
|
||||
.title a:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.header a.extra {
|
||||
color: #aaa;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.header a.extra:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.meta {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-size: 80%;
|
||||
color: #666;
|
||||
border-top: 4px solid #eee;
|
||||
margin-top: 2em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.footer .contact {
|
||||
float: left;
|
||||
margin-right: 3em;
|
||||
}
|
||||
|
||||
.footer .contact a {
|
||||
color: #8085C1;
|
||||
}
|
||||
|
||||
.footer .rss {
|
||||
margin-top: 1.1em;
|
||||
margin-right: -.2em;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.footer .rss img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
/* Posts
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
|
||||
/* standard */
|
||||
.post pre {
|
||||
border: 1px solid #ddd;
|
||||
background-color: #eef;
|
||||
padding: 0 .4em;
|
||||
}
|
||||
|
||||
.post ul, .post ol {
|
||||
margin-left: 1.35em;
|
||||
}
|
||||
|
||||
.post code {
|
||||
border: 1px solid #ddd;
|
||||
background-color: #eef;
|
||||
padding: 0 .2em;
|
||||
}
|
||||
|
||||
.post pre code {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* terminal */
|
||||
.post pre.terminal {
|
||||
border: 1px solid #000;
|
||||
background-color: #333;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.post pre.terminal code {
|
||||
background-color: #333;
|
||||
}
|
||||
49
lib/site_template/css/main.scss
Executable file
49
lib/site_template/css/main.scss
Executable file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
# Only the main Sass file needs front matter (the dashes are enough)
|
||||
---
|
||||
@charset "utf-8";
|
||||
|
||||
|
||||
|
||||
// Our variables
|
||||
$base-font-family: Helvetica, Arial, sans-serif;
|
||||
$base-font-size: 16px;
|
||||
$small-font-size: $base-font-size * 0.875;
|
||||
$base-line-height: 1.5;
|
||||
|
||||
$spacing-unit: 30px;
|
||||
|
||||
$text-color: #111;
|
||||
$background-color: #fdfdfd;
|
||||
$brand-color: #2a7ae2;
|
||||
|
||||
$grey-color: #828282;
|
||||
$grey-color-light: lighten($grey-color, 40%);
|
||||
$grey-color-dark: darken($grey-color, 25%);
|
||||
|
||||
$on-palm: 600px;
|
||||
$on-laptop: 800px;
|
||||
|
||||
|
||||
|
||||
// Using media queries with like this:
|
||||
// @include media-query($palm) {
|
||||
// .wrapper {
|
||||
// padding-right: $spacing-unit / 2;
|
||||
// padding-left: $spacing-unit / 2;
|
||||
// }
|
||||
// }
|
||||
@mixin media-query($device) {
|
||||
@media screen and (max-width: $device) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Import partials from `sass_dir` (defaults to `_sass`)
|
||||
@import
|
||||
"base",
|
||||
"layout",
|
||||
"syntax-highlighting"
|
||||
;
|
||||
@@ -1,60 +0,0 @@
|
||||
.highlight { background: #ffffff; }
|
||||
.highlight .c { color: #999988; font-style: italic } /* Comment */
|
||||
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
||||
.highlight .k { font-weight: bold } /* Keyword */
|
||||
.highlight .o { font-weight: bold } /* Operator */
|
||||
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
|
||||
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #aa0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #999999 } /* Generic.Heading */
|
||||
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
||||
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
|
||||
.highlight .go { color: #888888 } /* Generic.Output */
|
||||
.highlight .gp { color: #555555 } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
|
||||
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
|
||||
.highlight .kc { font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
|
||||
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
|
||||
.highlight .m { color: #009999 } /* Literal.Number */
|
||||
.highlight .s { color: #d14 } /* Literal.String */
|
||||
.highlight .na { color: #008080 } /* Name.Attribute */
|
||||
.highlight .nb { color: #0086B3 } /* Name.Builtin */
|
||||
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #008080 } /* Name.Constant */
|
||||
.highlight .ni { color: #800080 } /* Name.Entity */
|
||||
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
|
||||
.highlight .nn { color: #555555 } /* Name.Namespace */
|
||||
.highlight .nt { color: #000080 } /* Name.Tag */
|
||||
.highlight .nv { color: #008080 } /* Name.Variable */
|
||||
.highlight .ow { font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #009999 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #d14 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #d14 } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #d14 } /* Literal.String.Double */
|
||||
.highlight .se { color: #d14 } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #d14 } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #d14 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #009926 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #d14 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #008080 } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #008080 } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
|
||||
30
lib/site_template/feed.xml
Normal file
30
lib/site_template/feed.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
layout: null
|
||||
---
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ site.title | xml_escape }}</title>
|
||||
<description>{{ site.description | xml_escape }}</description>
|
||||
<link>{{ site.url }}{{ site.baseurl }}/</link>
|
||||
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />
|
||||
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
|
||||
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
|
||||
<generator>Jekyll v{{ jekyll.version }}</generator>
|
||||
{% for post in site.posts limit:10 %}
|
||||
<item>
|
||||
<title>{{ post.title | xml_escape }}</title>
|
||||
<description>{{ post.content | xml_escape }}</description>
|
||||
<pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
|
||||
<link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>
|
||||
<guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
|
||||
{% for tag in post.tags %}
|
||||
<category>{{ tag | xml_escape }}</category>
|
||||
{% endfor %}
|
||||
{% for cat in post.categories %}
|
||||
<category>{{ cat | xml_escape }}</category>
|
||||
{% endfor %}
|
||||
</item>
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,13 +1,23 @@
|
||||
---
|
||||
layout: default
|
||||
title: Your New Jekyll Site
|
||||
---
|
||||
|
||||
<div id="home">
|
||||
<h1>Blog Posts</h1>
|
||||
<ul class="posts">
|
||||
<div class="home">
|
||||
|
||||
<h1 class="page-heading">Posts</h1>
|
||||
|
||||
<ul class="post-list">
|
||||
{% for post in site.posts %}
|
||||
<li><span>{{ post.date | date_to_string }}</span> » <a href="{{ post.url }}">{{ post.title }}</a></li>
|
||||
<li>
|
||||
<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
|
||||
|
||||
<h2>
|
||||
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
|
||||
</h2>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p class="rss-subscribe">subscribe <a href="{{ "/feed.xml" | prepend: site.baseurl }}">via RSS</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
script/branding
|
||||
bundle install
|
||||
|
||||
11
script/branding
Executable file
11
script/branding
Executable file
@@ -0,0 +1,11 @@
|
||||
#! /bin/bash
|
||||
|
||||
echo " ---------------------------------------------------------- "
|
||||
echo " _ ______ _ __ __ __ _ _ "
|
||||
echo " | | | ____| | |/ / \ \ / / | | | | "
|
||||
echo " | | | |__ | ' / \ \_/ / | | | | "
|
||||
echo " _ | | | __| | < \ / | | | | "
|
||||
echo " | |__| | | |____ | . \ | | | |____ | |____ "
|
||||
echo " \____/ |______| |_|\_\ |_| |______| |______| "
|
||||
echo " "
|
||||
echo " ---------------------------------------------------------- "
|
||||
16
script/cibuild
Executable file
16
script/cibuild
Executable file
@@ -0,0 +1,16 @@
|
||||
#! /bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
parallelize_tests() {
|
||||
ls -1 script/{test,cucumber,proof} | xargs -P 3 -L 1 /bin/bash
|
||||
}
|
||||
|
||||
serialize_tests() {
|
||||
script/proof
|
||||
script/test
|
||||
script/cucumber
|
||||
}
|
||||
|
||||
script/branding
|
||||
time parallelize_tests
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user