mirror of
https://github.com/jekyll/jekyll.git
synced 2026-04-28 03:01:03 -04:00
Compare commits
863 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb04d0db3b | ||
|
|
f9411bd362 | ||
|
|
4528772e20 | ||
|
|
5457fa16f6 | ||
|
|
a473b45e35 | ||
|
|
41c3dd4cde | ||
|
|
071e775a55 | ||
|
|
cb6e2574ce | ||
|
|
413783c4e8 | ||
|
|
daf638b600 | ||
|
|
a449512912 | ||
|
|
41e2994868 | ||
|
|
51f79a4387 | ||
|
|
6422477c5e | ||
|
|
e801d55ddf | ||
|
|
ade2847301 | ||
|
|
7040448b75 | ||
|
|
d5b26c94d2 | ||
|
|
eadba642ce | ||
|
|
387c40f667 | ||
|
|
2bd3815b42 | ||
|
|
df2a92cb39 | ||
|
|
a224491d20 | ||
|
|
7861f12727 | ||
|
|
6ee728efcb | ||
|
|
ba9a28474f | ||
|
|
6c9200252a | ||
|
|
4b471fe9fb | ||
|
|
f80321ecac | ||
|
|
06ab708edf | ||
|
|
f2aa15555b | ||
|
|
afa89d68f8 | ||
|
|
9474c370dc | ||
|
|
a04df2f440 | ||
|
|
d213981a24 | ||
|
|
7cdc8394aa | ||
|
|
f16c5d0e65 | ||
|
|
1ab0ed3664 | ||
|
|
9be387ef6f | ||
|
|
9234fa7510 | ||
|
|
7a4817e55a | ||
|
|
f0e9b378f6 | ||
|
|
da4a664290 | ||
|
|
9fc4a85806 | ||
|
|
59d1a122c6 | ||
|
|
0f2df6c7b3 | ||
|
|
c7d4386b63 | ||
|
|
54fcc97725 | ||
|
|
5f97f928de | ||
|
|
c27c669796 | ||
|
|
c6564d352b | ||
|
|
87d0f03f5c | ||
|
|
7695ba6eb4 | ||
|
|
01d48320fd | ||
|
|
22d9312eaf | ||
|
|
da35e134f1 | ||
|
|
09f9f193d8 | ||
|
|
0c172f6463 | ||
|
|
4ce50e3936 | ||
|
|
007b7d45dc | ||
|
|
9b60df8883 | ||
|
|
84b7d9b3ac | ||
|
|
b5e459430b | ||
|
|
d2c754c0fe | ||
|
|
8786163f35 | ||
|
|
e1fe161071 | ||
|
|
e873934d60 | ||
|
|
f542d817b0 | ||
|
|
4cb6b249f1 | ||
|
|
27d617a319 | ||
|
|
aeecbd741f | ||
|
|
b06af5a44f | ||
|
|
62669d9229 | ||
|
|
0a2c8bb26a | ||
|
|
bbb76a39a2 | ||
|
|
2736be44c5 | ||
|
|
848b1358a1 | ||
|
|
526ded00e9 | ||
|
|
983cd60a8d | ||
|
|
a54cedbb72 | ||
|
|
bd0cdcd4cb | ||
|
|
c795acd09f | ||
|
|
46c08e5dc1 | ||
|
|
4618a2a8b5 | ||
|
|
c28a17d71f | ||
|
|
a81bc9773f | ||
|
|
68892ab693 | ||
|
|
af47b3c1a7 | ||
|
|
0c73a6ded9 | ||
|
|
4b32bd2b13 | ||
|
|
f79f9d60a9 | ||
|
|
ac9a72482d | ||
|
|
b9859489b0 | ||
|
|
5930bbfac1 | ||
|
|
4883a24363 | ||
|
|
97efa0f0ce | ||
|
|
329878c45f | ||
|
|
bb1bd671b7 | ||
|
|
c006979160 | ||
|
|
a882c88081 | ||
|
|
3014444b0e | ||
|
|
ebe46f1ddc | ||
|
|
417b5a3b2e | ||
|
|
e33574b391 | ||
|
|
204e3074c9 | ||
|
|
15e7c30cc7 | ||
|
|
e92a46e156 | ||
|
|
2ea3bc53d3 | ||
|
|
c206df3401 | ||
|
|
d4c1d97cb3 | ||
|
|
4948b5a3b3 | ||
|
|
64d5e3dfd3 | ||
|
|
79f8210fff | ||
|
|
52eb60e171 | ||
|
|
8c9ebd2674 | ||
|
|
1768bcc489 | ||
|
|
86e4fa9a35 | ||
|
|
b086a3b423 | ||
|
|
1c59be1494 | ||
|
|
c759771dc7 | ||
|
|
238341ac8a | ||
|
|
21847980e3 | ||
|
|
b4ca9a56fe | ||
|
|
3403a76ec8 | ||
|
|
61e549d317 | ||
|
|
2240d52338 | ||
|
|
3acf4beb81 | ||
|
|
0f8a3b2971 | ||
|
|
d2fd910828 | ||
|
|
a068bfb8ee | ||
|
|
a3577d953d | ||
|
|
40a5e5c60c | ||
|
|
9e57eb1858 | ||
|
|
0f50dd1bb7 | ||
|
|
a93c3eadd1 | ||
|
|
9e0ed00a59 | ||
|
|
a1835c0a31 | ||
|
|
c49d1fc1bd | ||
|
|
3129372d12 | ||
|
|
faf06d1969 | ||
|
|
d912f3a456 | ||
|
|
9520d9bbf9 | ||
|
|
ce3ea138ce | ||
|
|
85685a8981 | ||
|
|
13912482ad | ||
|
|
3213ea70e5 | ||
|
|
24da7f8883 | ||
|
|
71d510a79c | ||
|
|
46bdaa49dc | ||
|
|
b3c6714b12 | ||
|
|
37cc45239d | ||
|
|
456007aab7 | ||
|
|
b8b5cb47ec | ||
|
|
d8bb9ae77b | ||
|
|
26782e246b | ||
|
|
664206608d | ||
|
|
90e83e0636 | ||
|
|
09b9db259c | ||
|
|
a416802a89 | ||
|
|
03f57a898b | ||
|
|
ff91463c43 | ||
|
|
e130a0841f | ||
|
|
55edf76590 | ||
|
|
7b80cb78bd | ||
|
|
6262a59be8 | ||
|
|
1bc9e0ed63 | ||
|
|
b80a0cb5ce | ||
|
|
301fe59dc6 | ||
|
|
1853f6a210 | ||
|
|
0654e2f65e | ||
|
|
059d7d2997 | ||
|
|
81c88d6833 | ||
|
|
11d2d78cd9 | ||
|
|
3954cb4dd4 | ||
|
|
25cf188caa | ||
|
|
de8f67c4a2 | ||
|
|
7e21d2a98f | ||
|
|
928faed7c7 | ||
|
|
67904e849d | ||
|
|
377d212ecc | ||
|
|
f274179d9b | ||
|
|
b0c730d278 | ||
|
|
f66f791668 | ||
|
|
14e9ec2bbb | ||
|
|
39a4dc6fb7 | ||
|
|
c16a2f4d6a | ||
|
|
390fc11239 | ||
|
|
cddea273a9 | ||
|
|
38d2445430 | ||
|
|
c0f0efc1cd | ||
|
|
f2c428bedc | ||
|
|
9b889217fa | ||
|
|
c6a85ff359 | ||
|
|
b638c94625 | ||
|
|
8e81dd69ec | ||
|
|
0114c51c6e | ||
|
|
ac704b9763 | ||
|
|
ae228705b2 | ||
|
|
aa1b565228 | ||
|
|
0618ae8a2e | ||
|
|
dafb25cbfe | ||
|
|
43873bb881 | ||
|
|
c6790bd8c9 | ||
|
|
61567f430e | ||
|
|
2a2326aea3 | ||
|
|
e3cfe13ef5 | ||
|
|
0e155adef6 | ||
|
|
1367123d5b | ||
|
|
d51c1c471a | ||
|
|
268f8f41ed | ||
|
|
b7d4f92764 | ||
|
|
d4cf0dbb0c | ||
|
|
502be39e9b | ||
|
|
43f4be7752 | ||
|
|
7665488e39 | ||
|
|
455e12a1a4 | ||
|
|
87a1a1426f | ||
|
|
9d3a5be579 | ||
|
|
b2eb00b902 | ||
|
|
cd633ea188 | ||
|
|
579733dbb5 | ||
|
|
fa1eb68941 | ||
|
|
e4a3712f30 | ||
|
|
7728d7bb86 | ||
|
|
d67cd63723 | ||
|
|
3fbca47b1a | ||
|
|
f5f8548eb8 | ||
|
|
6245ddb14d | ||
|
|
d14600152f | ||
|
|
9c1a897d60 | ||
|
|
58a74a166d | ||
|
|
cfb4a848b4 | ||
|
|
b2e6211f2f | ||
|
|
9f93b2595d | ||
|
|
14cccbfdc2 | ||
|
|
98b5ca3850 | ||
|
|
70ed98fadd | ||
|
|
279d24a8f5 | ||
|
|
7542ab51b7 | ||
|
|
64ad293b89 | ||
|
|
03a7e22b7e | ||
|
|
b6a0b9e548 | ||
|
|
9e67c0a9b7 | ||
|
|
107c95cf5f | ||
|
|
04ff228660 | ||
|
|
8537e36936 | ||
|
|
7bffb39244 | ||
|
|
0fd3c2d64c | ||
|
|
3c7c645505 | ||
|
|
d1c08d85d2 | ||
|
|
f05e3f340e | ||
|
|
e9ecb93dec | ||
|
|
fa4d327ddb | ||
|
|
18126d0ebd | ||
|
|
8d7e329a6e | ||
|
|
391960b55f | ||
|
|
5d66a12ed4 | ||
|
|
05d753f4e0 | ||
|
|
32c5ac35dd | ||
|
|
a47b913273 | ||
|
|
d929242e2b | ||
|
|
3aa80b7d04 | ||
|
|
3b93625a8f | ||
|
|
7897a1842c | ||
|
|
551f8b751f | ||
|
|
d387fd0baa | ||
|
|
f0b8db0d72 | ||
|
|
b440d478ea | ||
|
|
65e7605342 | ||
|
|
2bd0d062e1 | ||
|
|
d38d90f278 | ||
|
|
5e6aef6138 | ||
|
|
84f9bcdd42 | ||
|
|
40928364d4 | ||
|
|
22f5b19884 | ||
|
|
bc1ea4b602 | ||
|
|
c9e027fd9a | ||
|
|
4d648c8558 | ||
|
|
db9865ebb6 | ||
|
|
e4aa45b03f | ||
|
|
4cb7079601 | ||
|
|
abd8fef19b | ||
|
|
4c8c59dfcb | ||
|
|
3ba1128ac5 | ||
|
|
13bea15bbe | ||
|
|
2f790b993d | ||
|
|
5fa5c54c1e | ||
|
|
44b20ab8a1 | ||
|
|
bbdbcefbbb | ||
|
|
8d8021e0ac | ||
|
|
769331d8c2 | ||
|
|
99b9c8486c | ||
|
|
150862ee96 | ||
|
|
e191109549 | ||
|
|
c85a3aafbe | ||
|
|
fd0e99ceac | ||
|
|
29a5a3c303 | ||
|
|
b8f5b9f63e | ||
|
|
05d99a9c96 | ||
|
|
2e5e6ace3d | ||
|
|
f57899fdb8 | ||
|
|
d35d6a8cd4 | ||
|
|
adadc2eeab | ||
|
|
3b5f91adc3 | ||
|
|
b237b1f93c | ||
|
|
5aed7c5467 | ||
|
|
db241c4f91 | ||
|
|
a040af37c0 | ||
|
|
0e89a37eaf | ||
|
|
246e65914f | ||
|
|
d603b38ef0 | ||
|
|
3373eb6525 | ||
|
|
3950408e39 | ||
|
|
2d0c572d29 | ||
|
|
48c44e158d | ||
|
|
b0797c3035 | ||
|
|
38bc4f55e4 | ||
|
|
9366a90d38 | ||
|
|
8cf68c5216 | ||
|
|
fd121e2a5e | ||
|
|
ac463bb397 | ||
|
|
011152e5e0 | ||
|
|
71e04760c9 | ||
|
|
bffd34bfbf | ||
|
|
d47ae6ce95 | ||
|
|
130cc229e2 | ||
|
|
99c71d3cc6 | ||
|
|
6d27a1c660 | ||
|
|
1671c98975 | ||
|
|
53c1107eaa | ||
|
|
ac3348b9a6 | ||
|
|
6ea6f79b69 | ||
|
|
d18769aff0 | ||
|
|
aa284d90cc | ||
|
|
b4deb79392 | ||
|
|
53bb262fed | ||
|
|
49e3180607 | ||
|
|
7df8f50248 | ||
|
|
b0d6988c1d | ||
|
|
75b55ff4f2 | ||
|
|
7886fdb166 | ||
|
|
6e37d16907 | ||
|
|
5058382d5a | ||
|
|
bbefef20cd | ||
|
|
27535e2b3c | ||
|
|
65a1fc4120 | ||
|
|
7ae4973788 | ||
|
|
a452d0cb29 | ||
|
|
b1b409433c | ||
|
|
7f6d29af5d | ||
|
|
198103ce7a | ||
|
|
8234c01d58 | ||
|
|
e32daaedb4 | ||
|
|
a820f8d9c8 | ||
|
|
6e76f85b52 | ||
|
|
2814838406 | ||
|
|
def633060d | ||
|
|
1d58938f4b | ||
|
|
f89c180188 | ||
|
|
36591f5d28 | ||
|
|
99aabaaf16 | ||
|
|
4d805e29bc | ||
|
|
183ea08de6 | ||
|
|
6e93dbbbd1 | ||
|
|
932d6641bc | ||
|
|
9dc273ca50 | ||
|
|
39ac364b2c | ||
|
|
c6dde4af51 | ||
|
|
6fbd965509 | ||
|
|
bfee5c5b59 | ||
|
|
1d1ffdff9b | ||
|
|
00d753612c | ||
|
|
eb5be62cba | ||
|
|
98a64c8783 | ||
|
|
cc390d1a80 | ||
|
|
0deae96a75 | ||
|
|
0b32252506 | ||
|
|
5d126350d6 | ||
|
|
8592aed284 | ||
|
|
6c4a1bf00e | ||
|
|
5fc48ffcb9 | ||
|
|
e898b6e8bd | ||
|
|
6cd393c8ef | ||
|
|
b1868983c7 | ||
|
|
9daebe8dd2 | ||
|
|
b70ee10198 | ||
|
|
aad54c9a87 | ||
|
|
38b64faeb2 | ||
|
|
ce77fe6488 | ||
|
|
a13102f039 | ||
|
|
ea5e3d56f5 | ||
|
|
74fb4aca16 | ||
|
|
a4ba8246d7 | ||
|
|
d7ff4234f0 | ||
|
|
e940dd1be4 | ||
|
|
29da9024ca | ||
|
|
778fa4cc0e | ||
|
|
55910f19c3 | ||
|
|
368f5b67a9 | ||
|
|
c5818d1837 | ||
|
|
ab8f2d6bb1 | ||
|
|
7b5febdcd5 | ||
|
|
96b80b1a72 | ||
|
|
4b827e1797 | ||
|
|
4d138c9ab5 | ||
|
|
ccb382679a | ||
|
|
6d67e9bdd4 | ||
|
|
512c7fdb05 | ||
|
|
2b8de59717 | ||
|
|
afff4f0bec | ||
|
|
5878acaaf1 | ||
|
|
6c40c7f553 | ||
|
|
ba1cfab73c | ||
|
|
8204e479c3 | ||
|
|
67f842546e | ||
|
|
1298ba6908 | ||
|
|
c0e0159783 | ||
|
|
c42d27e428 | ||
|
|
95df351341 | ||
|
|
cbe66193c2 | ||
|
|
cf51e32d0e | ||
|
|
442074fdb1 | ||
|
|
4ecdf6ce10 | ||
|
|
31ae61b419 | ||
|
|
b3ddd985a4 | ||
|
|
4017e30cca | ||
|
|
e9be8933de | ||
|
|
a72629908a | ||
|
|
1ba23c32c6 | ||
|
|
ec0eff3315 | ||
|
|
f1ac1f2125 | ||
|
|
7b8c39722b | ||
|
|
af20abf1bc | ||
|
|
94b0c500c6 | ||
|
|
e50d4d6b6e | ||
|
|
61acafe97a | ||
|
|
37e1101690 | ||
|
|
f44a9cf401 | ||
|
|
090cf5a50b | ||
|
|
8507cda6dd | ||
|
|
805ab6b7f8 | ||
|
|
f8e8672148 | ||
|
|
d50656021f | ||
|
|
ecc5121918 | ||
|
|
56a711f1ee | ||
|
|
00285f7b9a | ||
|
|
32fba4f01a | ||
|
|
be0e951bb0 | ||
|
|
d27f1d95d5 | ||
|
|
e75d703806 | ||
|
|
2d5feab2ae | ||
|
|
c5830ce6e0 | ||
|
|
4de1873b56 | ||
|
|
a351a70b03 | ||
|
|
275d56a0fe | ||
|
|
2de5bacb41 | ||
|
|
5cf5ce979f | ||
|
|
2554281188 | ||
|
|
cc6e49a389 | ||
|
|
1d369aada3 | ||
|
|
e5d8bdee8f | ||
|
|
66dc083ad0 | ||
|
|
0a6f289ba5 | ||
|
|
ae3a71ed0d | ||
|
|
736a800f0e | ||
|
|
9a6f4e08b7 | ||
|
|
e9c5c45651 | ||
|
|
2adb70a247 | ||
|
|
dd15e3c368 | ||
|
|
7d81c00b29 | ||
|
|
d343da61eb | ||
|
|
9676b775de | ||
|
|
4482f80d34 | ||
|
|
10ae624d65 | ||
|
|
9c6f33024f | ||
|
|
b3b4abe80a | ||
|
|
281f75182e | ||
|
|
c678640553 | ||
|
|
d9aef14063 | ||
|
|
0daafd7bda | ||
|
|
06fa14c11a | ||
|
|
89db3c6384 | ||
|
|
948dcf2714 | ||
|
|
15a2dacd37 | ||
|
|
04e1768807 | ||
|
|
ea9cac5214 | ||
|
|
0587a3bb57 | ||
|
|
207fcbdef7 | ||
|
|
5d79c55b2c | ||
|
|
22931f42b8 | ||
|
|
3e81331af1 | ||
|
|
156e093b5c | ||
|
|
5681742223 | ||
|
|
f8a63157d7 | ||
|
|
9368e261cc | ||
|
|
54b6395806 | ||
|
|
4048b8e2a7 | ||
|
|
9c4695c47f | ||
|
|
5555db8c72 | ||
|
|
712c16a7f1 | ||
|
|
4595aab855 | ||
|
|
9efeade8b4 | ||
|
|
ba017ebb97 | ||
|
|
1583b26627 | ||
|
|
03582c32ed | ||
|
|
da6618c6fc | ||
|
|
a32c77fb87 | ||
|
|
4dccb00832 | ||
|
|
c5b8b3315f | ||
|
|
597021a813 | ||
|
|
3e30c72994 | ||
|
|
00b9f9dd62 | ||
|
|
2f36e09db5 | ||
|
|
d58e38c1a7 | ||
|
|
3fd887f648 | ||
|
|
6048dcdba2 | ||
|
|
e192588013 | ||
|
|
e888375081 | ||
|
|
1de7449767 | ||
|
|
9fee9d3d3b | ||
|
|
1d38500480 | ||
|
|
3c0a1386ea | ||
|
|
3c9f159fb8 | ||
|
|
70f741b86f | ||
|
|
b96b0a80ea | ||
|
|
716f912ae7 | ||
|
|
1aae802ea2 | ||
|
|
5dd611d601 | ||
|
|
55423e344e | ||
|
|
8337da8978 | ||
|
|
8669077daf | ||
|
|
86ed09ffdd | ||
|
|
dc6858504a | ||
|
|
88b970f5dc | ||
|
|
c3e6c04af5 | ||
|
|
7c7d550442 | ||
|
|
9d98aca86a | ||
|
|
36a42e5c71 | ||
|
|
070f07d971 | ||
|
|
a8fa52a816 | ||
|
|
92ba22f8fe | ||
|
|
735554007c | ||
|
|
bb4f5910c9 | ||
|
|
e558d0b983 | ||
|
|
53e4c162a2 | ||
|
|
428e4fe3b5 | ||
|
|
390503b2c7 | ||
|
|
15eaefa337 | ||
|
|
ddf640e6bd | ||
|
|
bd325acc85 | ||
|
|
6996fed26c | ||
|
|
bfc07a39c6 | ||
|
|
97a6a312ac | ||
|
|
a12ee55139 | ||
|
|
ade8a0107f | ||
|
|
754bf14e23 | ||
|
|
0c4969f017 | ||
|
|
3ca451a855 | ||
|
|
ab2cdac979 | ||
|
|
a5fbc25d8c | ||
|
|
50086b686a | ||
|
|
acb2263f51 | ||
|
|
7eefa0ffd7 | ||
|
|
a1b39840bb | ||
|
|
3061f2d204 | ||
|
|
c9d667594f | ||
|
|
b1a2115948 | ||
|
|
a48c02a889 | ||
|
|
4cde2ad41c | ||
|
|
8e68de2740 | ||
|
|
dc31264160 | ||
|
|
9579924f8a | ||
|
|
dab53a697b | ||
|
|
b6c283a4ae | ||
|
|
935e5563e1 | ||
|
|
f995d86673 | ||
|
|
657b6b328c | ||
|
|
f47612ee98 | ||
|
|
a9b80b2f06 | ||
|
|
d37de5c8df | ||
|
|
4fe9eecf05 | ||
|
|
10a1b9451a | ||
|
|
a78230ccdb | ||
|
|
cb5bc1093e | ||
|
|
1ea667474b | ||
|
|
ed815b0d2c | ||
|
|
c603be6a38 | ||
|
|
ee2db21202 | ||
|
|
e097a15657 | ||
|
|
a62e085ea0 | ||
|
|
378ec5a4b8 | ||
|
|
e10c483ec3 | ||
|
|
95a3c54ddb | ||
|
|
62d7f5ecad | ||
|
|
06c45df8c3 | ||
|
|
2756503e7b | ||
|
|
735194ccaf | ||
|
|
87978e79f4 | ||
|
|
eaade1e49a | ||
|
|
5580972282 | ||
|
|
060904d809 | ||
|
|
ab3d906e04 | ||
|
|
cce848d3d8 | ||
|
|
c273d91df1 | ||
|
|
c1c8b6dbf7 | ||
|
|
04e635b10c | ||
|
|
6711234d5f | ||
|
|
086e85ca9e | ||
|
|
be3666fcf0 | ||
|
|
ec83ef60b5 | ||
|
|
085a778b0a | ||
|
|
78e9f3389e | ||
|
|
f9926edbc4 | ||
|
|
af9ec6831d | ||
|
|
c4047c37b2 | ||
|
|
f6fd9014ba | ||
|
|
046928e395 | ||
|
|
c38e1fcbb8 | ||
|
|
2c9a349f9a | ||
|
|
f221b925b4 | ||
|
|
13c980c896 | ||
|
|
4c5d77a4b5 | ||
|
|
224a1ab9ef | ||
|
|
fd8fdd87d3 | ||
|
|
e3189e3828 | ||
|
|
11f0aab4b1 | ||
|
|
7ca4f7cd62 | ||
|
|
af5d51289f | ||
|
|
704ca6b8cc | ||
|
|
663a2d3279 | ||
|
|
a70d89a862 | ||
|
|
cda226de45 | ||
|
|
2530a8cdfc | ||
|
|
d157a04c6d | ||
|
|
ff5f7b7120 | ||
|
|
98a19cdf2b | ||
|
|
fb0457bf3d | ||
|
|
6550867051 | ||
|
|
8223ebd861 | ||
|
|
0eae36aec2 | ||
|
|
44d2995277 | ||
|
|
31dd0ebed5 | ||
|
|
ffdbeb89dd | ||
|
|
22a0be3f7b | ||
|
|
8e00301fca | ||
|
|
b7d5a26d53 | ||
|
|
a2623be3da | ||
|
|
2a280b7f62 | ||
|
|
13f520f2b4 | ||
|
|
519c0f1b38 | ||
|
|
f5fe4b89bd | ||
|
|
a1c97c66fb | ||
|
|
fdffc8aaaa | ||
|
|
bf4bfcf4f0 | ||
|
|
61bbc0666a | ||
|
|
0309c940df | ||
|
|
e98f543513 | ||
|
|
e048e428d1 | ||
|
|
43618c90c7 | ||
|
|
f2f88dbd9f | ||
|
|
5034216637 | ||
|
|
cb342c375d | ||
|
|
7c4876d2eb | ||
|
|
e302873203 | ||
|
|
1b73751abf | ||
|
|
8e887dcd8b | ||
|
|
5bf596b239 | ||
|
|
69a6323599 | ||
|
|
59a5fc64f9 | ||
|
|
1bc3f63db7 | ||
|
|
fe690a8377 | ||
|
|
a47ce7b655 | ||
|
|
d138558c1d | ||
|
|
cc5937815e | ||
|
|
f386752184 | ||
|
|
ceca1bcf14 | ||
|
|
839fd45b9d | ||
|
|
72c951fd45 | ||
|
|
3fa8af2a18 | ||
|
|
95b05cd0c5 | ||
|
|
57613b31dd | ||
|
|
75be388487 | ||
|
|
e3da5a3f9f | ||
|
|
1f298e0d9d | ||
|
|
b70ea3ca5c | ||
|
|
1afbe9967d | ||
|
|
b05b174b87 | ||
|
|
c63b51b661 | ||
|
|
debdb15171 | ||
|
|
b34e8e0bc0 | ||
|
|
ec25ddee17 | ||
|
|
3effae59d8 | ||
|
|
9ab232fd70 | ||
|
|
b2b634e767 | ||
|
|
fcce0d5482 | ||
|
|
d070a77716 | ||
|
|
bff1726a5a | ||
|
|
6a72d4a986 | ||
|
|
cd2688ab66 | ||
|
|
9bb59e9999 | ||
|
|
30ceda52ef | ||
|
|
659f0869e0 | ||
|
|
233589e150 | ||
|
|
532bb9e9cb | ||
|
|
bbbe6479e5 | ||
|
|
9288c81854 | ||
|
|
4935e85f7c | ||
|
|
03488b1cde | ||
|
|
ebe3c10604 | ||
|
|
b9721024be | ||
|
|
82c3ee365f | ||
|
|
f92d6639e6 | ||
|
|
fe5984ee15 | ||
|
|
cc63354367 | ||
|
|
37517c9a39 | ||
|
|
4c050bba65 | ||
|
|
05285798be | ||
|
|
645a2cc664 | ||
|
|
595ad56a7e | ||
|
|
be06296595 | ||
|
|
115926fd54 | ||
|
|
fb8bf7bab6 | ||
|
|
fdcd761313 | ||
|
|
2c5a5e76ec | ||
|
|
02b8e326ed | ||
|
|
366a1d8979 | ||
|
|
05924bae5e | ||
|
|
763702d4ff | ||
|
|
e61e93b486 | ||
|
|
b9d4419749 | ||
|
|
9e5b1c9f6a | ||
|
|
92adfd0e46 | ||
|
|
b94800361b | ||
|
|
dfa3f8b33a | ||
|
|
4f21458b34 | ||
|
|
29e721a804 | ||
|
|
ce0bd80527 | ||
|
|
ed41ff7774 | ||
|
|
b79c172921 | ||
|
|
fceddca1b2 | ||
|
|
6ddcc7f63a | ||
|
|
961c807c72 | ||
|
|
2b6b7b6a9f | ||
|
|
f97a48d970 | ||
|
|
e8b1a8aa44 | ||
|
|
6a4c8a0b1c | ||
|
|
be032c54fb | ||
|
|
c9ead955a4 | ||
|
|
eadbf2a711 | ||
|
|
11959ab2bc | ||
|
|
0e89e80426 | ||
|
|
f4fa2e735e | ||
|
|
7f9fd11a35 | ||
|
|
915d8adb1b | ||
|
|
643ae68912 | ||
|
|
fdf12efde4 | ||
|
|
68d58f4183 | ||
|
|
b63712e403 | ||
|
|
99042fa870 | ||
|
|
79ceb4d394 | ||
|
|
c6255d5f28 | ||
|
|
47d2a2459d | ||
|
|
dd971a3581 | ||
|
|
313582f06d | ||
|
|
8efbdc01ff | ||
|
|
a43d2907c7 | ||
|
|
2e91d094e5 | ||
|
|
d10dc01290 | ||
|
|
28c568386d | ||
|
|
0aa3c96d11 | ||
|
|
b6de905ee4 | ||
|
|
86195655d7 | ||
|
|
96bc62c666 | ||
|
|
b78d5085f1 | ||
|
|
6cbd06ea85 | ||
|
|
fe13c3b366 | ||
|
|
e331a37260 | ||
|
|
3432fd2c2d | ||
|
|
a5be27b222 | ||
|
|
a4d918d328 | ||
|
|
15fdc82821 | ||
|
|
0f23f69048 | ||
|
|
e5e5369cde | ||
|
|
c7eacbdfcd | ||
|
|
b90f8e048a | ||
|
|
928f51ad24 | ||
|
|
4890cecaf3 | ||
|
|
ac9fa413a5 | ||
|
|
47081736ef | ||
|
|
d100a68563 | ||
|
|
9ff614c2f8 | ||
|
|
c8edb15820 | ||
|
|
2a4aa0fdb1 | ||
|
|
d2ea28d122 | ||
|
|
3e8f00a069 | ||
|
|
64e87bfac9 | ||
|
|
face3985dc | ||
|
|
147a29302f | ||
|
|
918bfd5fe5 | ||
|
|
4359dba84a | ||
|
|
c159f19c7d | ||
|
|
e60e5f3532 | ||
|
|
657a8d7239 | ||
|
|
effe23a008 | ||
|
|
c227530300 | ||
|
|
43cfad250e | ||
|
|
7a284b802b | ||
|
|
79380e86fa | ||
|
|
1bde4ce84a | ||
|
|
8a09418083 | ||
|
|
d7bac8cc40 | ||
|
|
ac1b2b88d4 | ||
|
|
934273ad92 | ||
|
|
20f5434692 | ||
|
|
1c42a8225e | ||
|
|
3a4621870a | ||
|
|
35070d6806 | ||
|
|
6739072fb2 | ||
|
|
256212649a | ||
|
|
95203d99ba | ||
|
|
f7a2b52cd9 | ||
|
|
a7730914df | ||
|
|
3417a33e7a | ||
|
|
bf66d1fc23 | ||
|
|
2011addabc | ||
|
|
6814bc8e63 | ||
|
|
16aea22c8d | ||
|
|
c4fe2b0513 | ||
|
|
10b147f429 | ||
|
|
547de56c19 | ||
|
|
9ea8129d85 | ||
|
|
275aea11d1 | ||
|
|
2c04321d5a | ||
|
|
487d9ffc21 | ||
|
|
20a78dcca0 | ||
|
|
58c9a070a7 | ||
|
|
5d8be167d9 | ||
|
|
22a9fbb2a1 | ||
|
|
e9f8b4df74 | ||
|
|
0ef5ab352d | ||
|
|
a729a1f086 | ||
|
|
a95e5f16f0 | ||
|
|
90865d5fc1 | ||
|
|
970edaf238 | ||
|
|
c1761bc478 | ||
|
|
0cdf659ebf | ||
|
|
20735e12f9 | ||
|
|
a168edae45 | ||
|
|
bd2c337e5b | ||
|
|
4a91bb669c | ||
|
|
056abdf899 | ||
|
|
87a8695196 | ||
|
|
cf71c563ab | ||
|
|
36a41cd224 | ||
|
|
1eb626b1df | ||
|
|
3b60237cb1 | ||
|
|
e0b8539670 | ||
|
|
a58f23aeaf | ||
|
|
34438ed325 | ||
|
|
34ff0bbb36 | ||
|
|
6055f112fb | ||
|
|
a0da18e4f8 | ||
|
|
98405edf61 |
29
.codeclimate.yml
Normal file
29
.codeclimate.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
engines:
|
||||
rubocop: { enabled: true }
|
||||
fixme: { enabled: false }
|
||||
exclude_paths:
|
||||
- .rubocop.yml
|
||||
- .codeclimate.yml
|
||||
- .travis.yml
|
||||
- .gitignore
|
||||
- .rspec
|
||||
|
||||
- Gemfile.lock
|
||||
- CHANGELOG.{md,markdown,txt,textile}
|
||||
- CONTRIBUTING.{md,markdown,txt,textile}
|
||||
- readme.{md,markdown,txt,textile}
|
||||
- README.{md,markdown,txt,textile}
|
||||
- Readme.{md,markdown,txt,textile}
|
||||
- ReadMe.{md,markdown,txt,textile}
|
||||
- COPYING
|
||||
- LICENSE
|
||||
|
||||
- site/**/*
|
||||
- test/**/*
|
||||
- vendor/**/*
|
||||
- features/**/*
|
||||
- script/**/*
|
||||
- spec/**/*
|
||||
ratings:
|
||||
paths:
|
||||
- lib/**/*.rb
|
||||
122
.github/CONTRIBUTING.markdown
vendored
Normal file
122
.github/CONTRIBUTING.markdown
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
# Contributing to Jekyll
|
||||
|
||||
Hi there! Interested in contributing to Jekyll? We'd love your help. Jekyll is an open source project, built one contribution at a time by users like you.
|
||||
|
||||
## Where to get help or report a problem
|
||||
|
||||
* If you have a question about using Jekyll, start a discussion on [Jekyll Talk](https://talk.jekyllrb.com).
|
||||
* If you think you've found a bug within a Jekyll plugin, open an issue in that plugin's repository.
|
||||
* If you think you've found a bug within Jekyll itself, [open an issue](https://github.com/jekyll/jekyll/issues/new).
|
||||
* More resources are listed on our [Help page](https://jekyllrb.com/help/).
|
||||
|
||||
## Ways to contribute
|
||||
|
||||
Whether you're a developer, a designer, or just a Jekyll devotee, there are lots of ways to contribute. Here's a few ideas:
|
||||
|
||||
* [Install Jekyll on your computer](https://jekyllrb.com/docs/installation/) and kick the tires. Does it work? Does it do what you'd expect? If not, [open an issue](https://github.com/jekyll/jekyll/issues/new) and let us know.
|
||||
* Comment on some of the project's [open issues](https://github.com/jekyll/jekyll/issues). Have you experienced the same problem? Know a work around? Do you have a suggestion for how the feature could be better?
|
||||
* Read through [the documentation](https://jekyllrb.com/docs/home/), and click the "improve this page" button, any time you see something confusing, or have a suggestion for something that could be improved.
|
||||
* Browse through [the Jekyll discussion forum](https://talk.jekyllrb.com/), and lend a hand answering questions. There's a good chance you've already experienced what another user is experiencing.
|
||||
* Find [an open issue](https://github.com/jekyll/jekyll/issues) (especially [those labeled `help-wanted`](https://github.com/jekyll/jekyll/issues?q=is%3Aopen+is%3Aissue+label%3Ahelp-wanted)), and submit a proposed fix. If it's your first pull request, we promise we won't bite, and are glad to answer any questions.
|
||||
* Help evaluate [open pull requests](https://github.com/jekyll/jekyll/pulls), by testing the changes locally and reviewing what's proposed.
|
||||
|
||||
## Submitting a pull request
|
||||
|
||||
### Pull requests generally
|
||||
|
||||
* The smaller the proposed change, the better. If you'd like to propose two unrelated changes, submit two pull requests.
|
||||
|
||||
* The more information, the better. Make judicious use of the pull request body. Describe what changes were made, why you made them, and what impact they will have for users.
|
||||
|
||||
* Pull request are easy and fun. If this is your first pull request, it may help to [understand GitHub Flow](https://guides.github.com/introduction/flow/).
|
||||
|
||||
* If you're submitting a code contribution, be sure to read the [code contributions](#code-contributions) section below.
|
||||
|
||||
### Submitting a pull request via github.com
|
||||
|
||||
Many small changes can be made entirely through the github.com web interface.
|
||||
|
||||
1. Navigate to the file within [`jekyll/jekyll`](https://github.com/jekyll/jekyll) that you'd like to edit.
|
||||
2. Click the pencil icon in the top right corner to edit the file
|
||||
3. Make your proposed changes
|
||||
4. Click "Propose file change"
|
||||
5. Click "Create pull request"
|
||||
6. Add a descriptive title and detailed description for your proposed change. The more information the better.
|
||||
7. Click "Create pull request"
|
||||
|
||||
That's it! You'll be automatically subscribed to receive updates as others review your proposed change and provide feedback.
|
||||
|
||||
### Submitting a pull request via Git command line
|
||||
|
||||
1. Fork the project by clicking "Fork" in the top right corner of [`jekyll/jekyll`](https://github.com/jekyll/jekyll).
|
||||
2. Clone the repository lcoally `git clone https://github.com/<you-username>/jekyll`.
|
||||
3. Create a new, descriptively named branch to contain your change ( `git checkout -b my-awesome-feature` ).
|
||||
4. Hack away, add tests. Not necessarily in that order.
|
||||
5. Make sure everything still passes by running `script/cibuild` (see [the tests section](#running-tests-locally) below)
|
||||
6. Push the branch up ( `git push origin my-awesome-feature` ).
|
||||
7. Create a pull request by visiting `https://github.com/<your-username>/jekyll` and following the instructions at the top of the screen.
|
||||
|
||||
## Proposing updates to the documentation
|
||||
|
||||
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.
|
||||
|
||||
### How to submit changes
|
||||
|
||||
You can find the documentation for jekyllrb.com in the [site](https://github.com/jekyll/jekyll/tree/master/site) directory. See the section above, [submitting a pull request](#submitting-a-pull-request) for information on how to propose a change.
|
||||
|
||||
One gotcha, all pull requests should be directed at the `master` branch (the default branch).
|
||||
|
||||
### Adding plugins
|
||||
|
||||
If you want to add your plugin to the [list of plugins](https://jekyllrb.com/docs/plugins/#available-plugins), please submit a pull request modifying the [plugins page source file](site/_docs/plugins.md) by adding a link to your plugin under the proper subheading depending upon its type.
|
||||
|
||||
## Code Contributions
|
||||
|
||||
Interesting in submitting a pull request? Awesome. Read on. There's a few common gotchas that we'd love to help you avoid.
|
||||
|
||||
### Tests and documentation
|
||||
|
||||
Any time you propose a code change, you should also include updates to the documentation and tests within the same pull request.
|
||||
|
||||
#### Documentation
|
||||
|
||||
If your contribution changes any Jekyll behavior, make sure to update the documentation. Documentation lives in the `site/_docs` folder (spoiler alert: it's a Jekyll site!). If the docs are missing information, please feel free to add it in. Great docs make a great project. Include changes to the documentation within your pull request, and once merged, `jekyllrb.com` will be updated.
|
||||
|
||||
#### Tests
|
||||
|
||||
* If you're creating a small fix or patch to an existing feature, a simple test is more than enough. You can usually copy/paste from an existing example in the `tests` folder, but if you need you can find out about our tests suites [Shoulda](https://github.com/thoughtbot/shoulda/tree/master) and [RSpec-Mocks](https://github.com/rspec/rspec-mocks).
|
||||
|
||||
* If it's a brand new feature, create a new [Cucumber](https://github.com/cucumber/cucumber/) feature, reusing existing steps where appropriate.
|
||||
|
||||
### Code contributions generally
|
||||
|
||||
* Jekyll follows the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby).
|
||||
|
||||
* Don't bump the Gem version in your pull request (if you don't know what that means, you probably didn't).
|
||||
|
||||
## Running tests locally
|
||||
|
||||
### Test Dependencies
|
||||
|
||||
To run the test suite and build the gem you'll need to install Jekyll's dependencies by running the following command:
|
||||
|
||||
<pre class="highlight"><code>$ script/bootstrap</code></pre>
|
||||
|
||||
Before you make any changes, run the tests and make sure that they pass (to confirm your environment is configured properly):
|
||||
|
||||
<pre class="highlight"><code>$ script/cibuild</code></pre>
|
||||
|
||||
If you are only updating a file in `test/`, you can use the command:
|
||||
|
||||
<pre class="highlight"><code>$ script/test test/blah_test.rb</code></pre>
|
||||
|
||||
If you are only updating a `.feature` file, you can use the command:
|
||||
|
||||
<pre class="highlight"><code>$ script/cucumber features/blah.feature</code></pre>
|
||||
|
||||
Both `script/test` and `script/cucumber` can be run without arguments to
|
||||
run its entire respective suite.
|
||||
|
||||
## A thank you
|
||||
|
||||
Thanks! Hacking on Jekyll should be fun. If you find any of this hard to figure out, let us know so we can improve our process or documentation!
|
||||
20
.github/ISSUE_TEMPLATE.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
###### What version of Jekyll are you using (`jekyll -v`)?
|
||||
|
||||
|
||||
|
||||
###### What operating system are you using?
|
||||
|
||||
|
||||
|
||||
###### What did you do?
|
||||
(Please include the content causing the issue, any relevant configuration settings, and the command you ran)
|
||||
|
||||
|
||||
|
||||
###### What did you expect to see?
|
||||
|
||||
|
||||
|
||||
###### What did you see instead?
|
||||
|
||||
|
||||
30
.gitignore
vendored
30
.gitignore
vendored
@@ -1,20 +1,22 @@
|
||||
Gemfile.lock
|
||||
test/dest
|
||||
*.gem
|
||||
pkg/
|
||||
*.swp
|
||||
*~
|
||||
_site/
|
||||
.bundle/
|
||||
.DS_Store
|
||||
bbin/
|
||||
gh-pages/
|
||||
site/_site/
|
||||
coverage
|
||||
.ruby-version
|
||||
.ruby-gemset
|
||||
.sass-cache
|
||||
tmp/*
|
||||
.analysis
|
||||
.bundle/
|
||||
.byebug_history
|
||||
.jekyll-metadata
|
||||
/vendor
|
||||
.ruby-gemset
|
||||
.ruby-version
|
||||
.sass-cache
|
||||
/test/source/file_name.txt
|
||||
/vendor
|
||||
Gemfile.lock
|
||||
_site/
|
||||
bbin/
|
||||
coverage
|
||||
gh-pages/
|
||||
pkg/
|
||||
site/_site/
|
||||
test/dest
|
||||
tmp/*
|
||||
|
||||
3
.jrubyrc
3
.jrubyrc
@@ -1,6 +1,3 @@
|
||||
backtrace.mask=true
|
||||
compile.invokedynamic=true
|
||||
objectspace.enabled=true
|
||||
backtrace.color=true
|
||||
compat.version=2.2
|
||||
backtrace.style=mri
|
||||
|
||||
80
.rubocop.yml
Normal file
80
.rubocop.yml
Normal file
@@ -0,0 +1,80 @@
|
||||
Metrics/MethodLength: { Max: 24 }
|
||||
Metrics/ClassLength: { Max: 240 }
|
||||
Metrics/ModuleLength: { Max: 240 }
|
||||
Metrics/LineLength: { Max: 112 }
|
||||
Metrics/CyclomaticComplexity: { Max: 8 }
|
||||
Metrics/PerceivedComplexity: { Max: 8 }
|
||||
Metrics/ParameterLists: { Max: 4 }
|
||||
Metrics/MethodLength: { Max: 24 }
|
||||
Metrics/AbcSize: { Max: 20 }
|
||||
|
||||
Style/IndentHash: { EnforcedStyle: consistent }
|
||||
Style/HashSyntax: { EnforcedStyle: hash_rockets }
|
||||
Style/SignalException: { EnforcedStyle: only_raise }
|
||||
Style/AlignParameters: { EnforcedStyle: with_fixed_indentation }
|
||||
Style/StringLiteralsInInterpolation: { EnforcedStyle: double_quotes }
|
||||
Style/MultilineMethodCallIndentation: { EnforcedStyle: indented }
|
||||
Style/MultilineOperationIndentation: { EnforcedStyle: indented }
|
||||
Style/FirstParameterIndentation: { EnforcedStyle: consistent }
|
||||
Style/StringLiterals: { EnforcedStyle: double_quotes }
|
||||
Style/RegexpLiteral: { EnforcedStyle: slashes }
|
||||
Style/IndentArray: { EnforcedStyle: consistent }
|
||||
Style/ExtraSpacing: { AllowForAlignment: true }
|
||||
|
||||
Style/PercentLiteralDelimiters:
|
||||
PreferredDelimiters:
|
||||
'%q': '{}'
|
||||
'%Q': '{}'
|
||||
'%r': '!!'
|
||||
'%s': '()'
|
||||
'%w': '()'
|
||||
'%W': '()'
|
||||
'%x': '()'
|
||||
|
||||
Style/AlignArray: { Enabled: false }
|
||||
Style/StringLiterals: { Enabled: false }
|
||||
Style/Documentation: { Enabled: false }
|
||||
Style/DoubleNegation: { Enabled: false }
|
||||
Style/UnneededCapitalW: { Enabled: false }
|
||||
Style/EmptyLinesAroundModuleBody: { Enabled: false }
|
||||
Style/EmptyLinesAroundAccessModifier: { Enabled: false }
|
||||
Style/BracesAroundHashParameters: { Enabled: false }
|
||||
Style/SpaceInsideBrackets: { Enabled: false }
|
||||
Style/IfUnlessModifier: { Enabled: false }
|
||||
Style/ModuleFunction: { Enabled: false }
|
||||
Style/RescueModifier: { Enabled: false }
|
||||
Style/GuardClause: { Enabled: false }
|
||||
Style/FileName: { Enabled: false }
|
||||
Lint/UselessAccessModifier: { Enabled: false }
|
||||
Style/SpaceAroundOperators: { Enabled: false }
|
||||
Style/RedundantReturn: { Enabled: false }
|
||||
Style/SingleLineMethods: { Enabled: false }
|
||||
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.0
|
||||
Include:
|
||||
- lib/**/*.rb
|
||||
|
||||
Exclude:
|
||||
- .rubocop.yml
|
||||
- .codeclimate.yml
|
||||
- .travis.yml
|
||||
- .gitignore
|
||||
- .rspec
|
||||
|
||||
- Gemfile.lock
|
||||
- CHANGELOG.{md,markdown,txt,textile}
|
||||
- CONTRIBUTING.{md,markdown,txt,textile}
|
||||
- readme.{md,markdown,txt,textile}
|
||||
- README.{md,markdown,txt,textile}
|
||||
- Readme.{md,markdown,txt,textile}
|
||||
- ReadMe.{md,markdown,txt,textile}
|
||||
- COPYING
|
||||
- LICENSE
|
||||
|
||||
- site/**/*
|
||||
- test/**/*
|
||||
- vendor/**/*
|
||||
- features/**/*
|
||||
- script/**/*
|
||||
- spec/**/*
|
||||
61
.travis.yml
61
.travis.yml
@@ -1,35 +1,52 @@
|
||||
language: ruby
|
||||
before_script: bundle update
|
||||
bundler_args: --without benchmark:site:development
|
||||
script: script/cibuild
|
||||
cache: bundler
|
||||
language: ruby
|
||||
sudo: false
|
||||
|
||||
rvm:
|
||||
- 2.2
|
||||
- 2.1
|
||||
- 2.0
|
||||
- ruby-head
|
||||
- jruby-9.0.3.0
|
||||
- &ruby1 2.3.0
|
||||
- &ruby2 2.2.4
|
||||
- &ruby3 2.1.8
|
||||
- &jruby jruby-9.0.4.0
|
||||
- &rhead ruby-head
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- rvm: ruby-head
|
||||
- rvm: jruby-9.0.3.0
|
||||
exclude:
|
||||
- rvm: jruby-9.0.3.0
|
||||
env: TEST_SUITE=cucumber
|
||||
- rvm: *jruby
|
||||
- rvm: *rhead
|
||||
env:
|
||||
matrix:
|
||||
- TEST_SUITE=test
|
||||
- TEST_SUITE=cucumber
|
||||
before_script: bundle update
|
||||
script: script/cibuild
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
notifications:
|
||||
irc:
|
||||
on_success: change
|
||||
on_failure: change
|
||||
channels:
|
||||
- irc.freenode.org#jekyll
|
||||
template:
|
||||
- "%{repository}#%{build_number} (%{branch}) %{message} %{build_url}"
|
||||
template: "%{repository}#%{build_number} (%{branch}) %{message} %{build_url}"
|
||||
channels: irc.freenode.org#jekyll
|
||||
|
||||
email:
|
||||
on_success: never
|
||||
on_failure: never
|
||||
recipients:
|
||||
- jordon@envygeeks.io
|
||||
|
||||
slack:
|
||||
secure: dNdKk6nahNURIUbO3ULhA09/vTEQjK0fNbgjVjeYPEvROHgQBP1cIP3AJy8aWs8rl5Yyow4YGEilNRzKPz18AsFptVXofpwyqcBxaCfmHP809NX5PHBaadydveLm+TNVao2XeLXSWu+HUNAYO1AanCUbJSEyJTju347xCBGzESU=
|
||||
secure: "\
|
||||
dNdKk6nahNURIUbO3ULhA09/vTEQjK0fNbgjVjeYPEvROHgQBP1cIP3AJy8aWs8rl5Yyow4Y\
|
||||
GEilNRzKPz18AsFptVXofpwyqcBxaCfmHP809NX5PHBaadydveLm+TNVao2XeLXSWu+HUNAY\
|
||||
O1AanCUbJSEyJTju347xCBGzESU=\
|
||||
"
|
||||
|
||||
addons:
|
||||
code_climate:
|
||||
repo_token:
|
||||
secure: "\
|
||||
mAuvDu+nrzB8dOaLqsublDGt423mGRyZYM3vsrXh4Tf1sT+L1PxsRzU4gLmcV27HtX2Oq9\
|
||||
DA4vsRURfABU0fIhwYkQuZqEcA3d8TL36BZcGEshG6MQ2AmnYsmFiTcxqV5bmlElHEqQuT\
|
||||
5SUFXLafgZPBnL0qDwujQcHukID41sE=\
|
||||
"
|
||||
|
||||
49
CONDUCT.markdown
Normal file
49
CONDUCT.markdown
Normal file
@@ -0,0 +1,49 @@
|
||||
# Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of
|
||||
fostering an open and welcoming community, we pledge to respect all people who
|
||||
contribute through reporting issues, posting feature requests, updating
|
||||
documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free
|
||||
experience for everyone, regardless of level of experience, gender, gender
|
||||
identity and expression, sexual orientation, disability, personal appearance,
|
||||
body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic
|
||||
addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
By adopting this Code of Conduct, project maintainers commit themselves to
|
||||
fairly and consistently applying these principles to every aspect of managing
|
||||
this project. Project maintainers who do not follow or enforce the Code of
|
||||
Conduct may be permanently removed from the project team.
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by opening an issue or contacting a project maintainer. All complaints
|
||||
will be reviewed and investigated and will result in a response that is deemed
|
||||
necessary and appropriate to the circumstances. Maintainers are obligated to
|
||||
maintain confidentiality with regard to the reporter of an incident.
|
||||
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 1.3.0, available at
|
||||
[http://contributor-covenant.org/version/1/3/0/][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/3/0/
|
||||
22
CONDUCT.md
22
CONDUCT.md
@@ -1,22 +0,0 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
||||
@@ -1,106 +0,0 @@
|
||||
Contribute
|
||||
==========
|
||||
|
||||
So you've got an awesome idea to throw into Jekyll. Great! Please keep the
|
||||
following in mind:
|
||||
|
||||
* **Use https://talk.jekyllrb.com for non-technical or indirect Jekyll questions that are not bugs.**
|
||||
* **Contributions will not be accepted without tests or necessary documentation updates.**
|
||||
* If you're creating a small fix or patch to an existing feature, just a simple
|
||||
test will do. Please stay in the confines of the current test suite and use
|
||||
[Shoulda](https://github.com/thoughtbot/shoulda/tree/master) and
|
||||
[RSpec-Mocks](https://github.com/rspec/rspec-mocks).
|
||||
* If it's a brand new feature, make sure to create a new
|
||||
[Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
|
||||
where appropriate. Also, whipping up some documentation in your fork's `site`
|
||||
would be appreciated, and once merged it will be transferred over to the main
|
||||
`site`, jekyllrb.com.
|
||||
* If your contribution changes any Jekyll behavior, make sure to update the
|
||||
documentation. It lives in `site/_docs`. If the docs are missing information,
|
||||
please feel free to add it in. Great docs make a great project!
|
||||
* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
||||
when modifying Ruby code.
|
||||
* Please do your best to submit **small pull requests**. The easier the proposed
|
||||
change is to review, the more likely it will be merged.
|
||||
* When submitting a pull request, please make judicious use of the pull request
|
||||
body. A description of what changes were made, the motivations behind the
|
||||
changes and [any tasks completed or left to complete](http://git.io/gfm-tasks)
|
||||
will also speed up review time.
|
||||
|
||||
Test Dependencies
|
||||
-----------------
|
||||
|
||||
To run the test suite and build the gem you'll need to install Jekyll's
|
||||
dependencies. Simply run this command to get all setup:
|
||||
|
||||
$ script/bootstrap
|
||||
|
||||
Before you start, run the tests and make sure that they pass (to confirm your
|
||||
environment is configured properly):
|
||||
|
||||
$ script/cibuild
|
||||
|
||||
If you are only updating a file in `test/`, you can use the command:
|
||||
|
||||
$ script/test test/blah_test.rb
|
||||
|
||||
If you are only updating a `.feature` file, you can use the command:
|
||||
|
||||
$ script/cucumber features/blah.feature
|
||||
|
||||
Both `script/test` and `script/cucumber` can be run without arguments to
|
||||
run its entire respective suite.
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
Here's the most direct way to get your work merged into the project:
|
||||
|
||||
* Fork the project.
|
||||
* Clone down your fork ( `git clone git@github.com:[username]/jekyll.git` ).
|
||||
* Create a topic branch to contain your change ( `git checkout -b my_awesome_feature` ).
|
||||
* Hack away, add tests. Not necessarily in that order.
|
||||
* Make sure everything still passes by running `script/cibuild`.
|
||||
* If necessary, rebase your commits into logical chunks, without errors.
|
||||
* Push the branch up ( `git push origin my_awesome_feature` ).
|
||||
* Create a pull request against jekyll/jekyll and describe what your change
|
||||
does and the why you think it should be merged.
|
||||
|
||||
Updating Documentation
|
||||
----------------------
|
||||
|
||||
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/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.
|
||||
|
||||
The [Jekyll wiki](https://github.com/jekyll/jekyll/wiki) on GitHub
|
||||
can be freely updated without a pull request as all GitHub users have access.
|
||||
|
||||
If you want to add your plugin to the
|
||||
[list of plugins](http://jekyllrb.com/docs/plugins/#available-plugins),
|
||||
please submit a pull request modifying the
|
||||
[plugins page source file](site/_docs/plugins.md) by adding a
|
||||
link to your plugin under the proper subheading depending upon its type.
|
||||
|
||||
Gotchas
|
||||
-------
|
||||
|
||||
* Please do not bump the gem version in your pull requests.
|
||||
* Try to keep your patch(es) based from the latest commit on jekyll/jekyll.
|
||||
The easier it is to apply your work, the less work the maintainers have to do,
|
||||
which is always a good thing.
|
||||
* Please don't tag your GitHub issue with [fix], [feature], etc. The maintainers
|
||||
actively read the issues and will label it once they come across it.
|
||||
|
||||
Finally...
|
||||
----------
|
||||
|
||||
Thanks! Hacking on Jekyll should be fun. If you find any of this hard to figure
|
||||
out, let us know so we can improve our process or documentation!
|
||||
109
Gemfile
109
Gemfile
@@ -1,55 +1,88 @@
|
||||
source 'https://rubygems.org'
|
||||
gemspec name: 'jekyll'
|
||||
source "https://rubygems.org"
|
||||
gemspec :name => "jekyll"
|
||||
|
||||
gem 'rake', '~> 10.1'
|
||||
gem "rake", "~> 11.0"
|
||||
group :development do
|
||||
gem 'rdoc', '~> 4.2'
|
||||
gem 'launchy', '~> 2.3'
|
||||
gem 'toml', '~> 0.1.0'
|
||||
gem 'pry'
|
||||
gem "launchy", "~> 2.3"
|
||||
gem "rubocop", :branch => :master, :github => "bbatsov/rubocop"
|
||||
gem "pry"
|
||||
|
||||
unless RUBY_ENGINE == "jruby"
|
||||
gem "pry-byebug"
|
||||
end
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'redgreen', '~> 1.2'
|
||||
gem 'shoulda', '~> 3.5'
|
||||
gem 'cucumber', '~> 2.0', '< 2.1'
|
||||
gem 'simplecov', '~> 0.9'
|
||||
gem 'jekyll_test_plugin'
|
||||
gem 'jekyll_test_plugin_malicious'
|
||||
gem 'minitest-reporters'
|
||||
gem 'minitest-profile'
|
||||
gem 'minitest'
|
||||
gem 'rspec-mocks'
|
||||
#
|
||||
|
||||
group :test do
|
||||
gem "cucumber", "~> 2.1"
|
||||
gem "jekyll_test_plugin"
|
||||
gem "jekyll_test_plugin_malicious"
|
||||
gem "codeclimate-test-reporter"
|
||||
gem "rspec-mocks"
|
||||
gem "nokogiri"
|
||||
gem "rspec"
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
group :test_legacy do
|
||||
if RUBY_PLATFORM =~ /cygwin/ || RUBY_VERSION.start_with?("2.2")
|
||||
gem 'test-unit'
|
||||
end
|
||||
|
||||
if ENV['PROOF']
|
||||
gem 'html-proofer', '~> 2.0'
|
||||
end
|
||||
gem "redgreen"
|
||||
gem "simplecov"
|
||||
gem "minitest-reporters"
|
||||
gem "minitest-profile"
|
||||
gem "minitest"
|
||||
gem "shoulda"
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
group :benchmark do
|
||||
if ENV['BENCHMARK']
|
||||
gem 'ruby-prof'
|
||||
gem 'rbtrace'
|
||||
gem 'stackprof'
|
||||
gem 'benchmark-ips'
|
||||
if ENV["BENCHMARK"]
|
||||
gem "ruby-prof"
|
||||
gem "benchmark-ips"
|
||||
gem "stackprof"
|
||||
gem "rbtrace"
|
||||
end
|
||||
end
|
||||
|
||||
gem 'jekyll-paginate', '~> 1.0'
|
||||
gem 'jekyll-coffeescript', '~> 1.0'
|
||||
gem 'jekyll-feed'
|
||||
gem 'jekyll-gist', '~> 1.0'
|
||||
gem 'mime-types', '~> 2.6'
|
||||
gem 'kramdown', '~> 1.9'
|
||||
#
|
||||
|
||||
platform :ruby, :mswin, :mingw do
|
||||
gem 'rdiscount', '~> 2.0'
|
||||
gem 'pygments.rb', '~> 0.6.0'
|
||||
gem 'redcarpet', '~> 3.2', '>= 3.2.3'
|
||||
gem 'classifier-reborn', '~> 2.0'
|
||||
gem 'liquid-c', '~> 3.0'
|
||||
group :jekyll_optional_dependencies do
|
||||
gem "toml", "~> 0.1.0"
|
||||
gem "coderay", "~> 1.1.0"
|
||||
gem "jekyll-docs", :path => '../docs' if Dir.exist?('../docs') && ENV['JEKYLL_VERSION']
|
||||
gem "jekyll-gist", "~> 1.0"
|
||||
gem "jekyll-feed", "~> 0.1.3"
|
||||
gem "jekyll-coffeescript", "~> 1.0"
|
||||
gem "jekyll-redirect-from", "~> 0.9.1"
|
||||
gem "jekyll-paginate", "~> 1.0"
|
||||
gem "mime-types", "~> 3.0"
|
||||
gem "kramdown", "~> 1.9"
|
||||
gem "rdoc", "~> 4.2"
|
||||
|
||||
platform :ruby, :mswin, :mingw do
|
||||
gem "rdiscount", "~> 2.0"
|
||||
gem "pygments.rb", "~> 0.6.0"
|
||||
gem "redcarpet", "~> 3.2", ">= 3.2.3"
|
||||
gem "classifier-reborn", "~> 2.0"
|
||||
gem "liquid-c", "~> 3.0"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
group :site do
|
||||
if ENV["PROOF"]
|
||||
gem "html-proofer", "~> 2.0"
|
||||
end
|
||||
|
||||
gem "jemoji", "0.5.1"
|
||||
gem "jekyll-sitemap"
|
||||
gem "jekyll-seo-tag", "~> 1.1"
|
||||
gem "jekyll-avatar"
|
||||
end
|
||||
|
||||
602
History.markdown
602
History.markdown
File diff suppressed because it is too large
Load Diff
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2008-2015 Tom Preston-Werner
|
||||
Copyright (c) 2008-2016 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
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
# [Jekyll](http://jekyllrb.com/)
|
||||
# [Jekyll](https://jekyllrb.com/)
|
||||
|
||||
[](https://rubygems.org/gems/jekyll)
|
||||
[](https://travis-ci.org/jekyll/jekyll)
|
||||
[](https://codeclimate.com/github/jekyll/jekyll)
|
||||
[](https://gemnasium.com/jekyll/jekyll)
|
||||
[](https://hakiri.io/github/jekyll/jekyll/master)
|
||||
[][ruby-gems]
|
||||
[][travis]
|
||||
[][coverage]
|
||||
[][codeclimate]
|
||||
[][gemnasium]
|
||||
[][hakiri]
|
||||
|
||||
By Tom Preston-Werner, Nick Quaranto, Parker Moore, and many [awesome contributors](https://github.com/jekyll/jekyll/graphs/contributors)!
|
||||
[ruby-gems]: https://rubygems.org/gems/jekyll
|
||||
[gemnasium]: https://gemnasium.com/jekyll/jekyll
|
||||
[codeclimate]: https://codeclimate.com/github/jekyll/jekyll
|
||||
[coverage]: https://codeclimate.com/github/jekyll/jekyll/coverage
|
||||
[hakiri]: https://hakiri.io/github/jekyll/jekyll/master
|
||||
[travis]: https://travis-ci.org/jekyll/jekyll
|
||||
|
||||
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 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](https://pages.github.com), which you can use to host sites right from your GitHub repositories.
|
||||
|
||||
## Philosophy
|
||||
|
||||
@@ -16,37 +22,37 @@ Jekyll does what you tell it to do — no more, no less. It doesn't try to outs
|
||||
|
||||
## Having trouble with OS X El Capitan?
|
||||
|
||||
See: http://jekyllrb.com/docs/troubleshooting/#jekyll-amp-mac-os-x-1011
|
||||
See: https://jekyllrb.com/docs/troubleshooting/#jekyll-amp-mac-os-x-1011
|
||||
|
||||
## Getting Started
|
||||
|
||||
* [Install](http://jekyllrb.com/docs/installation/) the gem
|
||||
* Read up about its [Usage](http://jekyllrb.com/docs/usage/) and [Configuration](http://jekyllrb.com/docs/configuration/)
|
||||
* [Install](https://jekyllrb.com/docs/installation/) the gem
|
||||
* Read up about its [Usage](https://jekyllrb.com/docs/usage/) and [Configuration](https://jekyllrb.com/docs/configuration/)
|
||||
* Take a gander at some existing [Sites](https://wiki.github.com/jekyll/jekyll/sites)
|
||||
* Fork and [Contribute](http://jekyllrb.com/docs/contributing/) your own modifications
|
||||
* [Fork](https://github.com/jekyll/jekyll/fork) and [Contribute](https://jekyllrb.com/docs/contributing/) your own modifications
|
||||
* Have questions? Check out our official forum community [Jekyll Talk](https://talk.jekyllrb.com/) or [`#jekyll` on irc.freenode.net](https://botbot.me/freenode/jekyll/)
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
In order to have a more open and welcoming community, Jekyll adheres to a
|
||||
[code of conduct](CONDUCT.md) adapted from the Ruby on Rails code of
|
||||
[code of conduct](CONDUCT.markdown) adapted from the Ruby on Rails code of
|
||||
conduct.
|
||||
|
||||
Please adhere to this code of conduct in any interactions you have in the
|
||||
Jekyll community. It is strictly enforced on all official Jekyll
|
||||
repositories, websites, and resources. If you encounter someone violating
|
||||
these terms, please let a maintainer (@parkr, @envygeeks, or @mattr-) know
|
||||
these terms, please let a maintainer ([@parkr](https://github.com/parkr), [@envygeeks](https://github.com/envygeeks), or [@mattr-](https://github.com/mattr-)) know
|
||||
and we will address it as soon as possible.
|
||||
|
||||
## Diving In
|
||||
|
||||
* [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
|
||||
* Learn how the [YAML Front Matter](https://jekyllrb.com/docs/frontmatter/) works
|
||||
* Put information on your site with [Variables](https://jekyllrb.com/docs/variables/)
|
||||
* Customize the [Permalinks](https://jekyllrb.com/docs/permalinks/) your posts are generated with
|
||||
* Use the built-in [Liquid Extensions](https://jekyllrb.com/docs/templates/) to make your life easier
|
||||
* Use custom [Plugins](https://jekyllrb.com/docs/plugins/) to generate content specific to your site
|
||||
|
||||
## License
|
||||
|
||||
See [LICENSE](https://github.com/jekyll/jekyll/blob/master/LICENSE).
|
||||
See the [LICENSE](https://github.com/jekyll/jekyll/blob/master/LICENSE) file.
|
||||
|
||||
231
Rakefile
231
Rakefile
@@ -7,6 +7,8 @@ require 'yaml'
|
||||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
||||
require 'jekyll/version'
|
||||
|
||||
Dir.glob('rake/**.rake').each { |f| import f }
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# Helper functions
|
||||
@@ -85,6 +87,34 @@ def converted_history(markdown)
|
||||
normalize_bullets(markdown)))))
|
||||
end
|
||||
|
||||
def siteify_file(file, overrides_front_matter = {})
|
||||
abort "You seem to have misplaced your #{file} file. I can haz?" unless File.exists?(file)
|
||||
title = begin
|
||||
File.read(file).match(/\A# (.*)$/)[1]
|
||||
rescue
|
||||
File.basename(file, ".*").downcase.capitalize
|
||||
end
|
||||
slug = File.basename(file, ".markdown").downcase
|
||||
front_matter = {
|
||||
"title" => title,
|
||||
"layout" => "docs",
|
||||
"permalink" => "/docs/#{slug}/",
|
||||
"note" => "This file is autogenerated. Edit /#{file} instead."
|
||||
}.merge(overrides_front_matter)
|
||||
contents = "#{front_matter.to_yaml}---\n\n#{content_for(file)}"
|
||||
File.write("site/_docs/#{slug}.md", contents)
|
||||
end
|
||||
|
||||
def content_for(file)
|
||||
contents = File.read(file)
|
||||
case file
|
||||
when "History.markdown"
|
||||
converted_history(contents)
|
||||
else
|
||||
contents.gsub(/\A# .*\n\n?/, "")
|
||||
end
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# Standard tasks
|
||||
@@ -128,204 +158,3 @@ desc "Open an irb session preloaded with this library"
|
||||
task :console do
|
||||
sh "irb -rubygems -r ./lib/#{name}.rb"
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# Site tasks - http://jekyllrb.com
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
namespace :site do
|
||||
desc "Generate and view the site locally"
|
||||
task :preview => [:history, :version_file] do
|
||||
require "launchy"
|
||||
require "jekyll"
|
||||
|
||||
# Yep, it's a hack! Wait a few seconds for the Jekyll site to generate and
|
||||
# then open it in a browser. Someday we can do better than this, I hope.
|
||||
Thread.new do
|
||||
sleep 4
|
||||
puts "Opening in browser..."
|
||||
Launchy.open("http://localhost:4000")
|
||||
end
|
||||
|
||||
# Generate the site in server mode.
|
||||
puts "Running Jekyll..."
|
||||
options = {
|
||||
"source" => File.expand_path("site"),
|
||||
"destination" => File.expand_path("site/_site"),
|
||||
"watch" => true,
|
||||
"serving" => true
|
||||
}
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
end
|
||||
|
||||
desc "Generate the site"
|
||||
task :generate => [:history, :version_file] do
|
||||
require "jekyll"
|
||||
Jekyll::Commands::Build.process({
|
||||
"source" => File.expand_path("site"),
|
||||
"destination" => File.expand_path("site/_site")
|
||||
})
|
||||
end
|
||||
|
||||
desc "Update normalize.css library to the latest version and minify"
|
||||
task :update_normalize_css do
|
||||
Dir.chdir("site/_sass") do
|
||||
sh 'curl "http://necolas.github.io/normalize.css/latest/normalize.css" -o "normalize.scss"'
|
||||
sh 'sass "normalize.scss":"_normalize.scss" --style compressed'
|
||||
rm ['normalize.scss', Dir.glob('*.map')].flatten
|
||||
end
|
||||
end
|
||||
|
||||
desc "Commit the local site to the gh-pages branch and publish to GitHub Pages"
|
||||
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 "Creating gh-pages dir..."
|
||||
sh "git clone git@github.com:jekyll/jekyll gh-pages"
|
||||
end
|
||||
|
||||
# Ensure latest gh-pages branch history.
|
||||
Dir.chdir('gh-pages') do
|
||||
sh "git checkout gh-pages"
|
||||
sh "git pull origin gh-pages"
|
||||
end
|
||||
|
||||
# Proceed to purge all files in case we removed a file in this release.
|
||||
puts "Cleaning gh-pages directory..."
|
||||
purge_exclude = %w[
|
||||
gh-pages/.
|
||||
gh-pages/..
|
||||
gh-pages/.git
|
||||
gh-pages/.gitignore
|
||||
]
|
||||
FileList["gh-pages/{*,.*}"].exclude(*purge_exclude).each do |path|
|
||||
sh "rm -rf #{path}"
|
||||
end
|
||||
|
||||
# Copy site to gh-pages dir.
|
||||
puts "Building site into gh-pages branch..."
|
||||
ENV['JEKYLL_ENV'] = 'production'
|
||||
require "jekyll"
|
||||
Jekyll::Commands::Build.process({
|
||||
"source" => File.expand_path("site"),
|
||||
"destination" => File.expand_path("gh-pages"),
|
||||
"sass" => { "style" => "compressed" }
|
||||
})
|
||||
|
||||
File.open('gh-pages/.nojekyll', 'wb') { |f| f.puts(":dog: food.") }
|
||||
|
||||
# Commit and push.
|
||||
puts "Committing and pushing to GitHub Pages..."
|
||||
sha = `git rev-parse HEAD`.strip
|
||||
Dir.chdir('gh-pages') do
|
||||
sh "git add ."
|
||||
sh "git commit --allow-empty -m 'Updating to #{sha}.'"
|
||||
sh "git push origin gh-pages"
|
||||
end
|
||||
puts 'Done.'
|
||||
end
|
||||
|
||||
desc "Create a nicely formatted history page for the jekyll site based on the repo history."
|
||||
task :history do
|
||||
if File.exist?("History.markdown")
|
||||
history_file = File.read("History.markdown")
|
||||
front_matter = {
|
||||
"layout" => "docs",
|
||||
"title" => "History",
|
||||
"permalink" => "/docs/history/"
|
||||
}
|
||||
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))
|
||||
end
|
||||
end
|
||||
else
|
||||
abort "You seem to have misplaced your History.markdown file. I can haz?"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Write the site latest_version.txt file"
|
||||
task :version_file do
|
||||
File.open('site/latest_version.txt', 'wb') { |f| f.puts(version) } unless version =~ /(beta|rc|alpha)/i
|
||||
end
|
||||
|
||||
namespace :releases do
|
||||
desc "Create new release post"
|
||||
task :new, :version do |t, args|
|
||||
raise "Specify a version: rake site:releases:new['1.2.3']" unless args.version
|
||||
today = Time.new.strftime('%Y-%m-%d')
|
||||
release = args.version.to_s
|
||||
filename = "site/_posts/#{today}-jekyll-#{release.split('.').join('-')}-released.markdown"
|
||||
|
||||
File.open(filename, "wb") do |post|
|
||||
post.puts("---")
|
||||
post.puts("layout: news_item")
|
||||
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: #{release}")
|
||||
post.puts("categories: [release]")
|
||||
post.puts("---")
|
||||
post.puts
|
||||
post.puts
|
||||
end
|
||||
|
||||
puts "Created #{filename}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# Packaging tasks
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
desc "Release #{name} v#{version}"
|
||||
task :release => :build do
|
||||
unless `git branch` =~ /^\* 3\.0-stable$/
|
||||
puts "You must be on the 3.0-stable branch to release!"
|
||||
exit!
|
||||
end
|
||||
sh "git commit --allow-empty -m 'Release :gem: #{version}'"
|
||||
sh "git tag v#{version}"
|
||||
sh "git push origin master"
|
||||
sh "git push origin v#{version}"
|
||||
sh "gem push pkg/#{name}-#{version}.gem"
|
||||
end
|
||||
|
||||
desc "Build #{name} v#{version} into pkg/"
|
||||
task :build do
|
||||
mkdir_p "pkg"
|
||||
sh "gem build #{gemspec_file}"
|
||||
sh "mv #{gem_file} pkg"
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# Packaging tasks for jekyll-docs
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
namespace :docs do
|
||||
desc "Release #{docs_name} v#{version}"
|
||||
task :release => :build do
|
||||
unless `git branch` =~ /^\* master$/
|
||||
puts "You must be on the master branch to release!"
|
||||
exit!
|
||||
end
|
||||
sh "gem push pkg/#{docs_name}-#{version}.gem"
|
||||
end
|
||||
|
||||
desc "Build #{docs_name} v#{version} into pkg/"
|
||||
task :build do
|
||||
mkdir_p "pkg"
|
||||
sh "gem build #{docs_name}.gemspec"
|
||||
sh "mv #{docs_name}-#{version}.gem pkg"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,10 +4,12 @@ Benchmark.ips do |x|
|
||||
path_without_ending_slash = '/some/very/very/long/path/to/a/file/i/like'
|
||||
x.report('no slash regexp') { path_without_ending_slash =~ /\/$/ }
|
||||
x.report('no slash end_with?') { path_without_ending_slash.end_with?("/") }
|
||||
x.report('no slash [-1, 1]') { path_without_ending_slash[-1, 1] == "/" }
|
||||
end
|
||||
|
||||
Benchmark.ips do |x|
|
||||
path_with_ending_slash = '/some/very/very/long/path/to/a/file/i/like/'
|
||||
x.report('slash regexp') { path_with_ending_slash =~ /\/$/ }
|
||||
x.report('slash end_with?') { path_with_ending_slash.end_with?("/") }
|
||||
x.report('slash [-1, 1]') { path_with_ending_slash[-1, 1] == "/" }
|
||||
end
|
||||
|
||||
54
benchmark/file-dir-ensure-trailing-slash
Normal file
54
benchmark/file-dir-ensure-trailing-slash
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env ruby
|
||||
require 'benchmark/ips'
|
||||
|
||||
# For this pull request, which changes Page#dir
|
||||
# https://github.com/jekyll/jekyll/pull/4403
|
||||
|
||||
FORWARD_SLASH = '/'.freeze
|
||||
|
||||
def pre_pr(url)
|
||||
url[-1, 1] == FORWARD_SLASH ? url : File.dirname(url)
|
||||
end
|
||||
|
||||
def pr(url)
|
||||
if url.end_with?(FORWARD_SLASH)
|
||||
url
|
||||
else
|
||||
url_dir = File.dirname(url)
|
||||
url_dir.end_with?(FORWARD_SLASH) ? url_dir : "#{url_dir}/"
|
||||
end
|
||||
end
|
||||
|
||||
def envygeeks(url)
|
||||
return url if url.end_with?(FORWARD_SLASH) || url == FORWARD_SLASH
|
||||
|
||||
url = File.dirname(url)
|
||||
url == FORWARD_SLASH ? url : "#{url}/"
|
||||
end
|
||||
|
||||
# Just a slash
|
||||
Benchmark.ips do |x|
|
||||
path = '/'
|
||||
x.report("pre_pr:#{path}") { pre_pr(path) }
|
||||
x.report("pr:#{path}") { pr(path) }
|
||||
x.report("envygeeks:#{path}") { pr(path) }
|
||||
x.compare!
|
||||
end
|
||||
|
||||
# No trailing slash
|
||||
Benchmark.ips do |x|
|
||||
path = '/some/very/very/long/path/to/a/file/i/like'
|
||||
x.report("pre_pr:#{path}") { pre_pr(path) }
|
||||
x.report("pr:#{path}") { pr(path) }
|
||||
x.report("envygeeks:#{path}") { pr(path) }
|
||||
x.compare!
|
||||
end
|
||||
|
||||
# No trailing slash
|
||||
Benchmark.ips do |x|
|
||||
path = '/some/very/very/long/path/to/a/file/i/like/'
|
||||
x.report("pre_pr:#{path}") { pre_pr(path) }
|
||||
x.report("pr:#{path}") { pr(path) }
|
||||
x.report("envygeeks:#{path}") { pr(path) }
|
||||
x.compare!
|
||||
end
|
||||
51
benchmark/regexp-vs-include.rb
Normal file
51
benchmark/regexp-vs-include.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env ruby
|
||||
require 'benchmark/ips'
|
||||
|
||||
# For this pull request, which changes Page#dir
|
||||
# https://github.com/jekyll/jekyll/pull/4403
|
||||
|
||||
CONTENT_CONTAINING = <<-HTML.freeze
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<title>Jemoji</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/css/screen.css">
|
||||
</head>
|
||||
<body class="wrap">
|
||||
<p><img class="emoji" title=":+1:" alt=":+1:" src="https://assets.github.com/images/icons/emoji/unicode/1f44d.png" height="20" width="20" align="absmiddle"></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
CONTENT_NOT_CONTAINING = <<-HTML.freeze
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<title>Jemoji</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/css/screen.css">
|
||||
</head>
|
||||
<body class="wrap">
|
||||
<p><img class="emoji" title=":+1:" alt=":+1:" src="https://assets.github.com/images/icons/emoji/unicode/1f44d.png" height="20" width="20" align="absmiddle"></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report("no body include?") { CONTENT_NOT_CONTAINING.include?('<body') }
|
||||
x.report("no body regexp") { CONTENT_NOT_CONTAINING =~ /<\s*body/ }
|
||||
x.compare!
|
||||
end
|
||||
|
||||
# No trailing slash
|
||||
Benchmark.ips do |x|
|
||||
x.report("with body include?") { CONTENT_CONTAINING.include?('<body') }
|
||||
x.report("with body regexp") { CONTENT_CONTAINING =~ /<\s*body/ }
|
||||
x.compare!
|
||||
end
|
||||
25
bin/jekyll
25
bin/jekyll
@@ -1,15 +1,11 @@
|
||||
#!/usr/bin/env ruby
|
||||
STDOUT.sync = true
|
||||
|
||||
$:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
|
||||
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w( .. lib ))
|
||||
|
||||
require 'jekyll'
|
||||
require 'mercenary'
|
||||
|
||||
Jekyll::External.require_if_present(
|
||||
Jekyll::External.blessed_gems
|
||||
)
|
||||
|
||||
Jekyll::PluginManager.require_from_bundler
|
||||
|
||||
Jekyll::Deprecator.process(ARGV)
|
||||
@@ -26,16 +22,29 @@ Mercenary.program(:jekyll) do |p|
|
||||
p.option 'layouts_dir', '--layouts DIR', String, 'Layouts directory (defaults to ./_layouts)'
|
||||
p.option 'profile', '--profile', 'Generate a Liquid rendering profile'
|
||||
|
||||
Jekyll::External.require_if_present(Jekyll::External.blessed_gems) do |g|
|
||||
cmd = g.split('-').last
|
||||
p.command(cmd.to_sym) do |c|
|
||||
c.syntax cmd
|
||||
c.action do
|
||||
Jekyll.logger.abort_with "You must install the '#{g}' gem to use the 'jekyll #{cmd}' command."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Jekyll::Command.subclasses.each { |c| c.init_with_program(p) }
|
||||
|
||||
p.action do |args, options|
|
||||
p.action do |args, _|
|
||||
if args.empty?
|
||||
Jekyll.logger.error "A subcommand is required."
|
||||
puts p
|
||||
abort
|
||||
else
|
||||
unless p.has_command?(args.first)
|
||||
Jekyll.logger.abort_with "Invalid command. Use --help for more information"
|
||||
subcommand = args.first
|
||||
unless p.has_command? subcommand
|
||||
Jekyll.logger.abort_with "fatal: 'jekyll #{args.first}' could not" \
|
||||
" be found. You may need to install the jekyll-#{args.first} gem" \
|
||||
" or a related gem to be able to use this subcommand."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,12 +8,12 @@ Feature: Collections
|
||||
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 class=\"highlighter-rouge\">Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>\n<p>Signs are nice</p>\n<p><code class=\"highlighter-rouge\">Jekyll.sanitized_path</code> is used to make sure your path is in your source.</p>\n<p>Run your generators! default</p>\n<p>Page without title.</p>\n<p>Run your generators! default</p>" in "_site/index.html"
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
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 }}"
|
||||
Given I have an "index.html" page that contains "Collections: output => {{ site.collections[0].output }} label => {{ site.collections[0].label }}"
|
||||
And I have an "collection_metadata.html" page that contains "Methods metadata: {{ site.collections[0].foo }} {{ site.collections[0] }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
@@ -24,9 +24,10 @@ Feature: Collections
|
||||
foo: bar
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: {\"output\"=>true" in "_site/index.html"
|
||||
And I should see "\"label\"=>\"methods\"," in "_site/index.html"
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Collections: output => true" in "_site/index.html"
|
||||
And I should see "label => methods" in "_site/index.html"
|
||||
And I should see "Methods metadata: bar" in "_site/collection_metadata.html"
|
||||
And I should see "<p>Whatever: foo.bar</p>" in "_site/methods/configuration.html"
|
||||
|
||||
@@ -41,11 +42,12 @@ Feature: Collections
|
||||
permalink: /:collection/:path/
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 }}"
|
||||
Given I have an "index.html" page that contains "Collections: output => {{ site.collections[0].output }} label => {{ site.collections[0].label }} foo => {{ site.collections[0].foo }}"
|
||||
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:
|
||||
@@ -56,9 +58,11 @@ Feature: Collections
|
||||
foo: bar
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: {\"output\"=>true" in "_site/index.html"
|
||||
And I should see "\"label\"=>\"methods\"," in "_site/index.html"
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Collections: output => true" in "_site/index.html"
|
||||
And I should see "label => methods" in "_site/index.html"
|
||||
And I should see "foo => bar" 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"
|
||||
|
||||
@@ -71,8 +75,9 @@ Feature: Collections
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
|
||||
And I should see "Collections: _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].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 %}"
|
||||
@@ -83,8 +88,9 @@ Feature: Collections
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
|
||||
And I should see "Collections: _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].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 %}"
|
||||
@@ -95,11 +101,12 @@ Feature: Collections
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
Then the _site directory should exist
|
||||
And I should see "All documents: _methods/configuration.md _methods/escape-\+ #%20\[\].md _methods/sanitized_path.md _methods/site/generate.md _methods/site/initialize.md _methods/um_hi.md" in "_site/index.html"
|
||||
And I should see "All documents: _methods/collection/entries _methods/configuration.md _methods/escape-\+ #%20\[\].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 }}"
|
||||
Given I have an "index.html" page that contains "Second document's output: {{ site.documents[1].output }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
@@ -107,8 +114,9 @@ Feature: Collections
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
Then the _site directory should exist
|
||||
And I should see "First document's output: <p>Use <code class=\"highlighter-rouge\">Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>" in "_site/index.html"
|
||||
And I should see "Second document's output: <p>Use <code class=\"highlighter-rouge\">Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>" in "_site/index.html"
|
||||
|
||||
Scenario: Filter documents by where
|
||||
Given I have an "index.html" page that contains "{% assign items = site.methods | where: 'whatever','foo.bar' %}Item count: {{ items.size }}"
|
||||
@@ -119,11 +127,12 @@ Feature: Collections
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Item count: 2" in "_site/index.html"
|
||||
|
||||
Scenario: Sort by title
|
||||
Given I have an "index.html" page that contains "{% assign items = site.methods | sort: 'title' %}1. of {{ items.size }}: {{ items.first.output }}"
|
||||
Given I have an "index.html" page that contains "{% assign items = site.methods | sort: 'title' %}2. of {{ items.size }}: {{ items[1].output }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
@@ -131,11 +140,12 @@ Feature: Collections
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "1. of 7: <p>Page without title.</p>" in "_site/index.html"
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "2. of 8: <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 %}"
|
||||
Given I have an "index.html" page that contains "Collections: {% assign methods = site.methods | sort: 'relative_path' %}{{ methods | map:"title" | join: ", " }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
@@ -143,5 +153,22 @@ Feature: Collections
|
||||
- methods
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
Then the _site directory should exist
|
||||
And I should see "Collections: Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, , Site#generate," in "_site/index.html"
|
||||
And I should see "Collections: Collection#entries, Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, Initialize, Site#generate," in "_site/index.html"
|
||||
|
||||
Scenario: Rendered collection with date/dateless filename
|
||||
Given I have an "index.html" page that contains "Collections: {% for method in site.thanksgiving %}{{ method.title }} {% endfor %}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
collections:
|
||||
thanksgiving:
|
||||
output: true
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Thanksgiving Black Friday" in "_site/index.html"
|
||||
And I should see "Happy Thanksgiving" in "_site/thanksgiving/2015-11-26-thanksgiving.html"
|
||||
And I should see "Black Friday" in "_site/thanksgiving/black-friday.html"
|
||||
|
||||
@@ -13,7 +13,8 @@ Feature: Create sites
|
||||
Scenario: Basic site
|
||||
Given I have an "index.html" file that contains "Basic Site"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Basic Site" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with a post
|
||||
@@ -22,7 +23,8 @@ Feature: Create sites
|
||||
| title | date | content |
|
||||
| Hackers | 2009-03-27 | My First Exploit |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "My First Exploit" in "_site/2009/03/27/hackers.html"
|
||||
|
||||
Scenario: Basic site with layout and a page
|
||||
@@ -30,7 +32,8 @@ Feature: Create sites
|
||||
And I have an "index.html" page with layout "default" that contains "Basic Site with Layout"
|
||||
And I have a default layout that contains "Page Layout: {{ content }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Page Layout: Basic Site with Layout" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with layout and a post
|
||||
@@ -41,7 +44,8 @@ Feature: Create sites
|
||||
| Wargames | 2009-03-27 | default | The only winning move is not to play. |
|
||||
And I have a default layout that contains "Post Layout: {{ content }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
||||
|
||||
Scenario: Basic site with layout inside a subfolder and a post
|
||||
@@ -52,7 +56,8 @@ Feature: Create sites
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
||||
|
||||
Scenario: Basic site with layouts, pages, posts and files
|
||||
@@ -75,7 +80,8 @@ Feature: Create sites
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
And I should see "" in "_site/another_file"
|
||||
@@ -90,7 +96,8 @@ Feature: Create sites
|
||||
And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}"
|
||||
And I have an "_includes/about.textile" file that contains "Generated by Jekyll"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with subdir include tag
|
||||
@@ -99,7 +106,8 @@ Feature: Create sites
|
||||
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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Basic Site with subdir include tag: Generated by Jekyll" in "_site/info/index.html"
|
||||
|
||||
Scenario: Basic site with nested include tag
|
||||
@@ -108,7 +116,8 @@ Feature: Create sites
|
||||
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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with internal post linking
|
||||
@@ -120,19 +129,22 @@ Feature: Create sites
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
| entry2 | 2008-01-01 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "URL: /2008/01/01/entry2/" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with whitelisted dotfile
|
||||
Given I have an ".htaccess" file that contains "SomeDirective"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
@@ -146,13 +158,15 @@ Feature: Create sites
|
||||
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
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -164,9 +178,28 @@ Feature: Create sites
|
||||
| entry1 | 2020-12-31 | post | content for entry1. |
|
||||
| entry2 | 2007-12-31 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "content for entry2" in "_site/2007/12/31/entry2.html"
|
||||
And the "_site/2020/12/31/entry1.html" file should not exist
|
||||
When I run jekyll build --future
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And the "_site/2020/12/31/entry1.html" file should exist
|
||||
|
||||
Scenario: Basic site with layouts, posts and related posts
|
||||
Given I have a _layouts directory
|
||||
And I have a page layout that contains "Page {{ page.title }}: {{ content }}"
|
||||
And I have a post layout that contains "Post {{ page.title }}: {{ content }}Related posts: {{ site.related_posts | size }}"
|
||||
And I have an "index.html" page with layout "page" that contains "Site contains {{ site.pages.size }} pages and {{ site.posts.size }} posts; Related posts: {{ site.related_posts | size }}"
|
||||
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. |
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Page : Site contains 1 pages and 2 posts; Related posts: 0" in "_site/index.html"
|
||||
And I should see "Post entry1: <p>content for entry1.</p>\nRelated posts: 1" in "_site/2009/03/27/entry1.html"
|
||||
And I should see "Post entry2: <p>content for entry2.</p>\nRelated posts: 1" in "_site/2009/04/27/entry2.html"
|
||||
|
||||
@@ -10,7 +10,8 @@ Feature: Draft Posts
|
||||
| title | date | layout | content |
|
||||
| Recipe | 2009-03-27 | default | Not baked yet. |
|
||||
When I run jekyll build --drafts
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Not baked yet." in "_site/recipe.html"
|
||||
|
||||
Scenario: Don't preview a draft
|
||||
@@ -21,7 +22,8 @@ Feature: Draft Posts
|
||||
| title | date | layout | content |
|
||||
| Recipe | 2009-03-27 | default | Not baked yet. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And the "_site/recipe.html" file should not exist
|
||||
|
||||
Scenario: Don't preview a draft that is not published
|
||||
@@ -32,7 +34,8 @@ Feature: Draft Posts
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And the "_site/recipe.html" file should not exist
|
||||
|
||||
Scenario: Use page.path variable
|
||||
@@ -42,5 +45,6 @@ Feature: Draft Posts
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post path: _drafts/recipe.markdown" in "_site/recipe.html"
|
||||
|
||||
@@ -11,7 +11,8 @@ Feature: Embed filters
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see today's date in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Escape text for XML
|
||||
@@ -22,7 +23,8 @@ Feature: Embed filters
|
||||
| Star & Wars | 2009-03-27 | default | These aren't the droids you're looking for. |
|
||||
And I have a default layout that contains "{{ page.title | xml_escape }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Star & Wars" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Calculate number of words
|
||||
@@ -33,7 +35,8 @@ Feature: Embed filters
|
||||
| Star Wars | 2009-03-27 | default | These aren't the droids you're looking for. |
|
||||
And I have a default layout that contains "{{ content | number_of_words }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "7" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Convert an array into a sentence
|
||||
@@ -44,7 +47,8 @@ Feature: Embed filters
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "scifi, movies, and force" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Markdownify a given string
|
||||
@@ -55,7 +59,8 @@ Feature: Embed filters
|
||||
| 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_' | markdownify }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -68,38 +73,37 @@ Feature: Embed filters
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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 pages:
|
||||
| title | layout | content |
|
||||
| Dog | default | Run |
|
||||
| Bird | default | Fly |
|
||||
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 |
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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 pages:
|
||||
| title | layout | content |
|
||||
| Dog | default | Run |
|
||||
| Bird | default | Fly |
|
||||
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 |
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see exactly "The rule of 3: Fly, Run, Jump," in "_site/bird.html"
|
||||
|
||||
@@ -12,7 +12,8 @@ Feature: frontmatter defaults
|
||||
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
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -24,7 +25,8 @@ Feature: frontmatter defaults
|
||||
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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "<p>some special data</p>\n<div>Ben</div>" in "_site/2013/09/11/default-data.html"
|
||||
And I should see "just some special data by Ben" in "_site/index.html"
|
||||
|
||||
@@ -48,7 +50,8 @@ Feature: frontmatter defaults
|
||||
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
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
@@ -71,7 +74,8 @@ Feature: frontmatter defaults
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: "special"}, values: {layout: "main"}}, {scope: {path: "special/_posts"}, values: {layout: "main"}}, {scope: {path: "_posts"}, values: {layout: "main"}}]"
|
||||
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "main: <p>content of site/2013/10/14/about.html</p>" in "_site/2013/10/14/about.html"
|
||||
And I should see "main: <p>content of site/special/2013/10/14/about1.html</p>" in "_site/special/2013/10/14/about1.html"
|
||||
And I should see "main: <p>content of site/special/2013/10/14/about2.html</p>" in "_site/special/2013/10/14/about2.html"
|
||||
@@ -132,7 +136,8 @@ Feature: frontmatter defaults
|
||||
myval: "Test"
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Value: Test" in "_site/slides/slide1.html"
|
||||
|
||||
Scenario: Override frontmatter defaults inside a collection
|
||||
@@ -159,7 +164,8 @@ Feature: frontmatter defaults
|
||||
myval: "Test"
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Value: Override" in "_site/slides/slide2.html"
|
||||
|
||||
Scenario: Deep merge frontmatter defaults
|
||||
|
||||
@@ -24,7 +24,8 @@ Feature: Hooks
|
||||
end
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "mytinypage" in "_site/foo.html"
|
||||
|
||||
Scenario: Modify the payload before rendering the site
|
||||
@@ -37,7 +38,8 @@ Feature: Hooks
|
||||
end
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "myparam!" in "_site/index.html"
|
||||
|
||||
Scenario: Modify the site contents after reading
|
||||
@@ -51,7 +53,8 @@ Feature: Hooks
|
||||
end
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And the "_site/page1.html" file should not exist
|
||||
And I should see "page2" in "_site/page2.html"
|
||||
|
||||
@@ -67,7 +70,8 @@ Feature: Hooks
|
||||
"""
|
||||
And I have a "page1.html" page that contains "page1"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "page1" in "_site/firstpage.html"
|
||||
|
||||
Scenario: Alter a page right after it is initialized
|
||||
@@ -81,7 +85,8 @@ Feature: Hooks
|
||||
"""
|
||||
And I have a "page1.html" page that contains "page1"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "page1" in "_site/renamed.html"
|
||||
|
||||
Scenario: Alter the payload for one page but not another
|
||||
@@ -89,11 +94,11 @@ Feature: Hooks
|
||||
And I have a "_plugins/ext.rb" file with content:
|
||||
"""
|
||||
Jekyll::Hooks.register :pages, :pre_render do |page, payload|
|
||||
payload['myparam'] = 'special' if page.name == 'page1.html'
|
||||
payload['page']['myparam'] = 'special' if page.name == 'page1.html'
|
||||
end
|
||||
"""
|
||||
And I have a "page1.html" page that contains "{{ myparam }}"
|
||||
And I have a "page2.html" page that contains "{{ myparam }}"
|
||||
And I have a "page1.html" page that contains "{{ page.myparam }}"
|
||||
And I have a "page2.html" page that contains "{{ page.myparam }}"
|
||||
When I run jekyll build
|
||||
Then I should see "special" in "_site/page1.html"
|
||||
And I should not see "special" in "_site/page2.html"
|
||||
@@ -138,7 +143,8 @@ Feature: Hooks
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2015-03-14 | nil | {{ page.harold }} |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "pbagrag sbe ragel1." in "_site/2015/03/14/entry1.html"
|
||||
|
||||
Scenario: Alter the payload for certain posts
|
||||
@@ -268,7 +274,8 @@ Feature: Hooks
|
||||
{{ site.memes.first.text }}
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "all your base are belong to us" in "_site/index.html"
|
||||
|
||||
Scenario: Update a document after rendering it, but before writing it to disk
|
||||
@@ -294,7 +301,8 @@ Feature: Hooks
|
||||
{{ page.text }}
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "<p class=\"meme\">all your base are belong to us" in "_site/memes/doc1.html"
|
||||
|
||||
Scenario: Perform an action after every document is written
|
||||
@@ -322,5 +330,6 @@ Feature: Hooks
|
||||
{{ page.text }}
|
||||
"""
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Wrote document 0" in "_site/document-build.log"
|
||||
|
||||
@@ -15,11 +15,12 @@ Feature: Include tags
|
||||
| Ignore params if unused | 2013-03-21 | html | {% include ignore.html date="today" %} |
|
||||
| List multiple parameters | 2013-03-21 | html | {% include params.html date="today" start="tomorrow" %} |
|
||||
| Dont keep parameters | 2013-03-21 | html | {% include ignore.html param="test" %}\n{% include header.html %} |
|
||||
| Allow params with spaces and quotes | 2013-04-07 | html | {% include params.html cool="param with spaces" super="\"quoted\"" single='has "quotes"' escaped='\'single\' quotes' %} |
|
||||
| Allow params with spaces and quotes | 2013-04-07 | html | {% include params.html cool="param with spaces" super="\\"quoted\\"" single='has "quotes"' escaped='\\'single\\' quotes' %} |
|
||||
| Parameter syntax | 2013-04-12 | html | {% include params.html param1_or_2="value" %} |
|
||||
| Pass a variable | 2013-06-22 | html | {% assign var = 'some text' %}{% include params.html local=var title=page.title %} |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
And I should see "<li>date = today</li>" in "_site/2013/03/21/list-multiple-parameters.html"
|
||||
@@ -44,7 +45,8 @@ Feature: Include tags
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "a snippet that works with parameters" in "_site/index.html"
|
||||
|
||||
Scenario: Include a variable file in a loop
|
||||
@@ -53,7 +55,8 @@ Feature: Include tags
|
||||
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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "one two" in "_site/index.html"
|
||||
|
||||
Scenario: Include a file with variables and filters
|
||||
@@ -64,7 +67,8 @@ Feature: Include tags
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "one included" in "_site/index.html"
|
||||
|
||||
Scenario: Include a file with partial variables
|
||||
@@ -75,5 +79,28 @@ Feature: Include tags
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "one included" in "_site/index.html"
|
||||
|
||||
Scenario: Include a file and rebuild when include content is changed
|
||||
Given I have an _includes directory
|
||||
And I have an "_includes/one.html" file that contains "include"
|
||||
And I have an "index.html" page that contains "{% include one.html %}"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "include" in "_site/index.html"
|
||||
When I wait 1 second
|
||||
Then I have an "_includes/one.html" file that contains "include content changed"
|
||||
When I run jekyll build
|
||||
Then I should see "include content changed" in "_site/index.html"
|
||||
|
||||
Scenario: Include a file with multiple variables
|
||||
Given I have an _includes directory
|
||||
And I have an "_includes/header-en.html" file that contains "include"
|
||||
And I have an "index.html" page that contains "{% assign name = 'header' %}{% assign locale = 'en' %}{% include {{name}}-{{locale}}.html %}"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "include" in "_site/index.html"
|
||||
|
||||
@@ -11,10 +11,12 @@ Feature: Incremental rebuild
|
||||
| Wargames | 2009-03-27 | default | The only winning move is not to play. |
|
||||
And I have a default layout that contains "Post Layout: {{ content }}"
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
||||
|
||||
Scenario: Generate a metadata file
|
||||
@@ -25,12 +27,14 @@ Feature: Incremental rebuild
|
||||
Scenario: Rebuild when content is changed
|
||||
Given I have an "index.html" file that contains "Basic Site"
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Basic Site" in "_site/index.html"
|
||||
When I wait 1 second
|
||||
Then I have an "index.html" file that contains "Bacon Site"
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Bacon Site" in "_site/index.html"
|
||||
|
||||
Scenario: Rebuild when layout is changed
|
||||
@@ -38,12 +42,14 @@ Feature: Incremental rebuild
|
||||
And I have an "index.html" page with layout "default" that contains "Basic Site with Layout"
|
||||
And I have a default layout that contains "Page Layout: {{ content }}"
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Page Layout: Basic Site with Layout" in "_site/index.html"
|
||||
When I wait 1 second
|
||||
Then I have a default layout that contains "Page Layout Changed: {{ content }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Page Layout Changed: Basic Site with Layout" in "_site/index.html"
|
||||
|
||||
Scenario: Rebuild when an include is changed
|
||||
@@ -51,10 +57,12 @@ Feature: Incremental rebuild
|
||||
And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}"
|
||||
And I have an "_includes/about.textile" file that contains "Generated by Jekyll"
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
|
||||
When I wait 1 second
|
||||
Then I have an "_includes/about.textile" file that contains "Regenerated by Jekyll"
|
||||
When I run jekyll build -I
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Regenerated by Jekyll" in "_site/index.html"
|
||||
|
||||
37
features/layout_data.feature
Normal file
37
features/layout_data.feature
Normal file
@@ -0,0 +1,37 @@
|
||||
Feature: Layout data
|
||||
As a hacker who likes to avoid repetition
|
||||
I want to be able to embed data into my layouts
|
||||
In order to make the layouts slightly dynamic
|
||||
|
||||
Scenario: Use custom layout data
|
||||
Given I have a _layouts directory
|
||||
And I have a "_layouts/custom.html" file with content:
|
||||
"""
|
||||
---
|
||||
foo: my custom data
|
||||
---
|
||||
{{ content }} foo: {{ layout.foo }}
|
||||
"""
|
||||
And I have an "index.html" page with layout "custom" that contains "page content"
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "page content\n foo: my custom data" in "_site/index.html"
|
||||
|
||||
Scenario: Inherit custom layout data
|
||||
Given I have a _layouts directory
|
||||
And I have a "_layouts/custom.html" file with content:
|
||||
"""
|
||||
---
|
||||
layout: base
|
||||
foo: my custom data
|
||||
---
|
||||
{{ content }}
|
||||
"""
|
||||
And I have a "_layouts/base.html" file with content:
|
||||
"""
|
||||
{{ content }} foo: {{ layout.foo }}
|
||||
"""
|
||||
And I have an "index.html" page with layout "custom" that contains "page content"
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "page content\n foo: my custom data" in "_site/index.html"
|
||||
@@ -11,7 +11,8 @@ Feature: Markdown
|
||||
| title | date | content | type |
|
||||
| Hackers | 2009-03-27 | # My Title | markdown |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
@@ -27,6 +28,7 @@ Feature: Markdown
|
||||
| title | date | content | type |
|
||||
| Hackers | 2009-03-27 | # My Title | markdown |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -10,7 +10,8 @@ Feature: Fancy permalinks
|
||||
| None Permalink Schema | 2009-03-27 | Totally nothing. |
|
||||
And I have a configuration file with "permalink" set to "none"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Totally nothing." in "_site/none-permalink-schema.html"
|
||||
|
||||
Scenario: Use pretty permalink schema
|
||||
@@ -20,7 +21,8 @@ Feature: Fancy permalinks
|
||||
| Pretty Permalink Schema | 2009-03-27 | Totally wordpress. |
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Totally wordpress." in "_site/2009/03/27/pretty-permalink-schema/index.html"
|
||||
|
||||
Scenario: Use pretty permalink schema for pages
|
||||
@@ -29,7 +31,8 @@ Feature: Fancy permalinks
|
||||
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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
And I should see "Totally uhm, sitemap" in "_site/sitemap.xml"
|
||||
@@ -41,7 +44,8 @@ Feature: Fancy permalinks
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -51,7 +55,8 @@ Feature: Fancy permalinks
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -61,7 +66,8 @@ Feature: Fancy permalinks
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-schema.html"
|
||||
|
||||
Scenario: Use custom permalink schema with date and time
|
||||
@@ -74,7 +80,8 @@ Feature: Fancy permalinks
|
||||
| permalink | "/:year:month:day:hour:minute:second.html" |
|
||||
| timezone | UTC |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Totally custom." in "_site/20090327223107.html"
|
||||
|
||||
Scenario: Use per-post permalink
|
||||
@@ -83,7 +90,8 @@ Feature: Fancy permalinks
|
||||
| title | date | permalink | content |
|
||||
| Some post | 2013-04-14 | /custom/posts/1/ | bla bla |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -93,7 +101,8 @@ Feature: Fancy permalinks
|
||||
| title | date | permalink | content |
|
||||
| Some post | 2013-04-14 | /custom/posts/some.html | bla bla |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -102,7 +111,8 @@ Feature: Fancy permalinks
|
||||
And I have an "_posts/2009-03-27-Pretty-Permalink-Schema.md" page that contains "Totally wordpress"
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Totally wordpress." in "_site/2009/03/27/Pretty-Permalink-Schema/index.html"
|
||||
|
||||
Scenario: Use custom permalink schema with cased file name
|
||||
@@ -110,7 +120,8 @@ Feature: Fancy permalinks
|
||||
And I have an "_posts/2009-03-27-Custom-Schema.md" page with title "Custom Schema" that contains "Totally awesome"
|
||||
And I have a configuration file with "permalink" set to "/:year/:month/:day/:slug/"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Totally awesome" in "_site/2009/03/27/custom-schema/index.html"
|
||||
|
||||
Scenario: Use pretty permalink schema with title containing underscore
|
||||
@@ -118,5 +129,16 @@ Feature: Fancy permalinks
|
||||
And I have an "_posts/2009-03-27-Custom_Schema.md" page with title "Custom Schema" that contains "Totally awesome"
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Totally awesome" in "_site/2009/03/27/Custom_Schema/index.html"
|
||||
|
||||
Scenario: Use a non-HTML file extension in the permalink
|
||||
Given I have a _posts directory
|
||||
And I have an "_posts/2016-01-18-i-am-php.md" page with permalink "/2016/i-am-php.php" that contains "I am PHP"
|
||||
And I have a "i-am-also-php.md" page with permalink "/i-am-also-php.php" that contains "I am also PHP"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "I am PHP" in "_site/2016/i-am-php.php"
|
||||
And I should see "I am also PHP" in "_site/i-am-also-php.php"
|
||||
|
||||
@@ -6,7 +6,8 @@ Feature: Configuring and using plugins
|
||||
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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -17,7 +18,8 @@ Feature: Configuring and using plugins
|
||||
| gems | [jekyll_test_plugin] |
|
||||
| whitelist | [] |
|
||||
When I run jekyll build --safe
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And the "_site/test.txt" file should not exist
|
||||
|
||||
@@ -28,7 +30,8 @@ Feature: Configuring and using plugins
|
||||
| gems | [jekyll_test_plugin, jekyll_test_plugin_malicious] |
|
||||
| whitelist | [jekyll_test_plugin] |
|
||||
When I run jekyll build --safe
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -11,7 +11,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post title: Star Wars" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.url variable
|
||||
@@ -22,7 +23,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
Scenario: Use post.date variable
|
||||
@@ -33,7 +35,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post date: 27 Mar 2009" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.date variable with invalid
|
||||
@@ -58,7 +61,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post id: /2009/03/27/star-wars" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.content variable
|
||||
@@ -69,7 +73,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
Scenario: Use post.categories variable when category is in a folder
|
||||
@@ -81,7 +86,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -93,7 +99,8 @@ Feature: Post data
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -105,7 +112,8 @@ Feature: Post data
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -117,7 +125,8 @@ Feature: Post data
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.tags variable
|
||||
@@ -128,7 +137,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post tags: twist" in "_site/2009/05/18/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in folders
|
||||
@@ -141,7 +151,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 folders with mixed case
|
||||
@@ -154,7 +165,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 category is in YAML
|
||||
@@ -165,7 +177,8 @@ Feature: Post data
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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 and is mixed-case
|
||||
@@ -176,7 +189,8 @@ Feature: Post data
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post category: Movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in YAML
|
||||
@@ -187,7 +201,8 @@ Feature: Post data
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -198,7 +213,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Superdirectories of _posts applied to post.categories
|
||||
@@ -207,7 +223,8 @@ Feature: Post data
|
||||
And I have a _layouts directory
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Subdirectories of _posts not applied to post.categories
|
||||
@@ -216,7 +233,8 @@ Feature: Post data
|
||||
And I have a _layouts directory
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in YAML with mixed case
|
||||
@@ -228,7 +246,8 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -238,7 +257,8 @@ Feature: Post data
|
||||
| title | type | date | content |
|
||||
| my-post | html | 2013-04-12 | Source path: {{ page.path }} |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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:
|
||||
@@ -247,14 +267,15 @@ Feature: Post data
|
||||
| dir | dir/ |
|
||||
| dir/nested | dir/nested/ |
|
||||
|
||||
Scenario: Override page.path variable
|
||||
Scenario: Cannot override page.path variable
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | path | content |
|
||||
| override | 2013-04-12 | override-path.html | Custom path: {{ page.path }} |
|
||||
| override | 2013-04-12 | override-path.html | Non-custom path: {{ page.path }} |
|
||||
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"
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Non-custom path: _posts/2013-04-12-override.markdown" in "_site/2013/04/12/override.html"
|
||||
|
||||
Scenario: Disable a post from being published
|
||||
Given I have a _posts directory
|
||||
@@ -263,7 +284,8 @@ Feature: Post data
|
||||
| title | date | layout | published | content |
|
||||
| Star Wars | 2009-03-27 | simple | false | Luke, I am your father. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -275,9 +297,22 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Post author: Darth Vader" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use a variable which is a reserved keyword in Ruby
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | class | content |
|
||||
| My post | 2016-01-21 | simple | kewl-post | Luke, I am your father. |
|
||||
And I have a simple layout that contains "{{page.title}} has class {{page.class}}"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "My post has class kewl-post" in "_site/2016/01/21/my-post.html"
|
||||
|
||||
Scenario: Previous and next posts title
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
@@ -288,6 +323,7 @@ Feature: Post data
|
||||
| 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -12,7 +12,8 @@ Feature: Post excerpts
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see exactly "<p>content for entry1.</p>" in "_site/index.html"
|
||||
|
||||
Scenario: An excerpt from a post with a layout
|
||||
@@ -24,7 +25,8 @@ Feature: Post excerpts
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And the _site/2007 directory should exist
|
||||
And the _site/2007/12 directory should exist
|
||||
And the _site/2007/12/31 directory should exist
|
||||
@@ -41,7 +43,8 @@ Feature: Post excerpts
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2007-12-31 | post | content for entry1. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And the _site/2007 directory should exist
|
||||
And the _site/2007/12 directory should exist
|
||||
And the _site/2007/12/31 directory should exist
|
||||
|
||||
@@ -16,7 +16,8 @@ Feature: Rendering
|
||||
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
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
@@ -25,7 +26,8 @@ Feature: Rendering
|
||||
And I have a configuration file with "gems" set to "[jekyll-coffeescript]"
|
||||
And I have a simple layout that contains "{{ content }}Ahoy, indeed!"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -33,18 +35,21 @@ Feature: Rendering
|
||||
Given I have an "index.scss" page that contains ".foo-bar { color:{{site.color}}; }"
|
||||
And I have a configuration file with "color" set to "red"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see ".foo-bar {\n color: red; }" in "_site/index.css"
|
||||
|
||||
Scenario: Not render liquid in CoffeeScript without explicitly including jekyll-coffeescript
|
||||
Given I have an "index.coffee" page with animal "cicada" that contains "hey='for {{page.animal}}'"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And the "_site/index.js" file should not exist
|
||||
|
||||
Scenario: Render liquid in CoffeeScript with jekyll-coffeescript enabled
|
||||
Given I have an "index.coffee" page with animal "cicada" that contains "hey='for {{page.animal}}'"
|
||||
And I have a configuration file with "gems" set to "[jekyll-coffeescript]"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "hey = 'for cicada';" in "_site/index.js"
|
||||
|
||||
@@ -8,7 +8,8 @@ Feature: Site configuration
|
||||
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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Changing source directory" in "_site/index.html"
|
||||
|
||||
Scenario: Change destination directory
|
||||
@@ -66,27 +67,31 @@ Feature: Site configuration
|
||||
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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "<a href=\"http://google.com\">Google</a>" in "_site/index.html"
|
||||
|
||||
Scenario: Highlight code with pygments
|
||||
Given I have an "index.html" page that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -94,7 +99,8 @@ Feature: Site configuration
|
||||
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
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
|
||||
@@ -122,7 +128,8 @@ Feature: Site configuration
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
And the "_site/2020/01/31/entry2.html" file should not exist
|
||||
@@ -142,7 +149,8 @@ Feature: Site configuration
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
And I should see "Post Layout: <p>content for entry2.</p>" in "_site/2020/01/31/entry2.html"
|
||||
@@ -161,7 +169,8 @@ Feature: Site configuration
|
||||
| entry1 | 2013-04-09 23:22 -0400 | post | content for entry1. |
|
||||
| entry2 | 2013-04-10 03:14 -0400 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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>\n built at 2013-04-09T23:22:00-04:00" in "_site/2013/04/09/entry1.html"
|
||||
And I should see "Post Layout: <p>content for entry2.</p>\n built at 2013-04-10T03:14:00-04:00" in "_site/2013/04/10/entry2.html"
|
||||
@@ -180,7 +189,8 @@ Feature: Site configuration
|
||||
| entry1 | 2013-04-09 23:22 +0400 | post | content for entry1. |
|
||||
| entry2 | 2013-04-10 03:14 +0400 | post | content for entry2. |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Page Layout: 2" in "_site/index.html"
|
||||
And the "_site/2013/04/09/entry1.html" file should exist
|
||||
And the "_site/2013/04/09/entry2.html" file should exist
|
||||
@@ -198,7 +208,8 @@ Feature: Site configuration
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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
|
||||
And the "_site/2009/03/27/apples.html" file should not exist
|
||||
@@ -211,7 +222,8 @@ Feature: Site configuration
|
||||
| .gitignore |
|
||||
| .foo |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see ".DS_Store" in "_site/.gitignore"
|
||||
And the "_site/.htaccess" file should not exist
|
||||
|
||||
@@ -231,7 +243,8 @@ Feature: Site configuration
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And 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"
|
||||
And I should see "Post Layout: <p>content for entry2.</p>" in "_site/2020/01/31/entry2.html"
|
||||
@@ -240,6 +253,7 @@ Feature: Site configuration
|
||||
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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "FOO" in "_site/index.html"
|
||||
And I should not see " " in "_site/index.html"
|
||||
|
||||
@@ -6,14 +6,16 @@ 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Source path: <path>" in "_site/<path>"
|
||||
|
||||
Examples:
|
||||
@@ -25,13 +27,15 @@ Feature: Site data
|
||||
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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see today's time in "_site/index.html"
|
||||
|
||||
Scenario: Use site.posts variable for latest post
|
||||
@@ -43,7 +47,8 @@ Feature: Site data
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Third Post: /2009/03/27/third-post.html" in "_site/index.html"
|
||||
|
||||
Scenario: Use site.posts variable in a loop
|
||||
@@ -55,7 +60,8 @@ Feature: Site data
|
||||
| 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
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Third Post Second Post First Post" in "_site/index.html"
|
||||
|
||||
Scenario: Use site.categories.code variable
|
||||
@@ -66,7 +72,8 @@ Feature: Site data
|
||||
| Awesome Hack | 2009-03-26 | code | puts 'Hello World' |
|
||||
| Delicious Beer | 2009-03-26 | food | 1) Yuengling |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Awesome Hack" in "_site/index.html"
|
||||
|
||||
Scenario: Use site.tags variable
|
||||
@@ -76,7 +83,8 @@ Feature: Site data
|
||||
| title | date | tag | content |
|
||||
| Delicious Beer | 2009-03-26 | beer | 1) Yuengling |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Yuengling" in "_site/index.html"
|
||||
|
||||
Scenario: Order Posts by name when on the same date
|
||||
@@ -90,18 +98,21 @@ Feature: Site data
|
||||
| C | 2009-03-26 | C |
|
||||
| last | 2009-04-26 | last |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And 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 build
|
||||
Then the _site directory should exist
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "\d+\.\d+\.\d+" in "_site/index.html"
|
||||
|
||||
245
features/step_definitions.rb
Normal file
245
features/step_definitions.rb
Normal file
@@ -0,0 +1,245 @@
|
||||
Before do
|
||||
FileUtils.mkdir_p(Paths.test_dir) unless Paths.test_dir.directory?
|
||||
Dir.chdir(Paths.test_dir)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
After do
|
||||
Paths.test_dir.rmtree if Paths.test_dir.exist?
|
||||
Paths.output_file.delete if Paths.output_file.exist?
|
||||
Paths.status_file.delete if Paths.status_file.exist?
|
||||
Dir.chdir(Paths.test_dir.parent)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have a blank site in "(.*)"$} do |path|
|
||||
if !File.exist?(path)
|
||||
then FileUtils.mkdir_p(path)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I do not have a "(.*)" directory$} do |path|
|
||||
Paths.test_dir.join(path).directory?
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$} do |file, key, value, text|
|
||||
File.write(file, Jekyll::Utils.strip_heredoc(<<-DATA))
|
||||
---
|
||||
#{key || 'layout'}: #{value || 'nil'}
|
||||
---
|
||||
|
||||
#{text}
|
||||
DATA
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have an? "(.*)" file that contains "(.*)"$} do |file, text|
|
||||
File.write(file, text)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have an? (.*) (layout|theme) that contains "(.*)"$} do |name, type, text|
|
||||
folder = type == "layout" ? "_layouts" : "_theme"
|
||||
|
||||
destination_file = Pathname.new(File.join(folder, "#{name}.html"))
|
||||
FileUtils.mkdir_p(destination_file.parent) unless destination_file.parent.directory?
|
||||
File.write(destination_file, text)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have an? "(.*)" file with content:$} do |file, text|
|
||||
File.write(file, text)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have an? (.*) directory$} do |dir|
|
||||
if !File.directory?(dir)
|
||||
then FileUtils.mkdir_p(dir)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^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"] || "markdown"
|
||||
filename = filename = "#{title}.#{ext}" if %w(draft page).include?(status)
|
||||
before, after = location(folder, direction)
|
||||
dest_folder = "_drafts" if status == "draft"
|
||||
dest_folder = "_posts" if status == "post"
|
||||
dest_folder = "" if status == "page"
|
||||
|
||||
if status == "post"
|
||||
parsed_date = Time.xmlschema(input_hash['date']) rescue Time.parse(input_hash['date'])
|
||||
filename = "#{parsed_date.strftime('%Y-%m-%d')}-#{title}.#{ext}"
|
||||
end
|
||||
|
||||
path = File.join(before, dest_folder, after, filename)
|
||||
File.write(path, file_content_from_hash(input_hash))
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have a configuration file with "(.*)" set to "(.*)"$} do |key, value|
|
||||
config = if source_dir.join("_config.yml").exist?
|
||||
SafeYAML.load_file(source_dir.join("_config.yml"))
|
||||
else
|
||||
{}
|
||||
end
|
||||
config[key] = YAML.load(value)
|
||||
File.write("_config.yml", YAML.dump(config))
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have a configuration file with:$} do |table|
|
||||
table.hashes.each do |row|
|
||||
step %(I have a configuration file with "#{row["key"]}" set to "#{row["value"]}")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have a configuration file with "([^\"]*)" set to:$} do |key, table|
|
||||
File.open("_config.yml", "w") do |f|
|
||||
f.write("#{key}:\n")
|
||||
table.hashes.each do |row|
|
||||
f.write("- #{row["value"]}\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I have fixture collections$} do
|
||||
FileUtils.cp_r Paths.source_dir.join("test", "source", "_methods"), source_dir
|
||||
FileUtils.cp_r Paths.source_dir.join("test", "source", "_thanksgiving"), source_dir
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given %r{^I wait (\d+) second(s?)$} do |time, plural|
|
||||
sleep(time.to_f)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
When %r{^I run jekyll(.*)$} do |args|
|
||||
run_jekyll(args)
|
||||
if args.include?("--verbose") || ENV["DEBUG"]
|
||||
$stderr.puts "\n#{jekyll_run_output}\n"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
When %r{^I run bundle(.*)$} do |args|
|
||||
run_bundle(args)
|
||||
if args.include?("--verbose") || ENV['DEBUG']
|
||||
$stderr.puts "\n#{jekyll_run_output}\n"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
When %r{^I change "(.*)" to contain "(.*)"$} do |file, text|
|
||||
File.open(file, "a") do |f|
|
||||
f.write(text)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
When %r{^I delete the file "(.*)"$} do |file|
|
||||
File.delete(file)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^the (.*) directory should +(not )?exist$} do |dir, negative|
|
||||
if negative.nil?
|
||||
expect(Pathname.new(dir)).to exist
|
||||
else
|
||||
expect(Pathname.new(dir)).to_not exist
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
Then %r{^I should (not )?see "(.*)" in "(.*)"$} do |negative, text, file|
|
||||
step %(the "#{file}" file should exist)
|
||||
regexp = Regexp.new(text, Regexp::MULTILINE)
|
||||
if negative.nil? || negative.empty?
|
||||
expect(file_contents(file)).to match regexp
|
||||
else
|
||||
expect(file_contents(file)).not_to match regexp
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^I should see exactly "(.*)" in "(.*)"$} do |text, file|
|
||||
step %(the "#{file}" file should exist)
|
||||
expect(file_contents(file).strip).to eq text
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^I should see escaped "(.*)" in "(.*)"$} do |text, file|
|
||||
step %(I should see "#{Regexp.escape(text)}" in "#{file}")
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^the "(.*)" file should +(not )?exist$} do |file, negative|
|
||||
if negative.nil?
|
||||
expect(Pathname.new(file)).to exist
|
||||
else
|
||||
expect(Pathname.new(file)).to_not exist
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^I should see today's time in "(.*)"$} do |file|
|
||||
step %(I should see "#{seconds_agnostic_time(Time.now)}" in "#{file}")
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^I should see today's date in "(.*)"$} do |file|
|
||||
step %(I should see "#{Date.today.to_s}" in "#{file}")
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^I should (not )?see "(.*)" in the build output$} do |negative, text|
|
||||
if negative.nil? || negative.empty?
|
||||
expect(jekyll_run_output).to match Regexp.new(text)
|
||||
else
|
||||
expect(jekyll_run_output).not_to match Regexp.new(text)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^I should get a zero exit(?:\-| )status$} do
|
||||
step %(I should see "EXIT STATUS: 0" in the build output)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Then %r{^I should get a non-zero exit(?:\-| )status$} do
|
||||
step %(I should not see "EXIT STATUS: 0" in the build output)
|
||||
end
|
||||
@@ -1,234 +0,0 @@
|
||||
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.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)
|
||||
FileUtils.rm(JEKYLL_COMMAND_STATUS_FILE) if File.exist?(JEKYLL_COMMAND_STATUS_FILE)
|
||||
Dir.chdir(File.dirname(TEST_DIR))
|
||||
end
|
||||
|
||||
World do
|
||||
MinitestWorld.new
|
||||
end
|
||||
|
||||
Given /^I have a blank site in "(.*)"$/ do |path|
|
||||
FileUtils.mkdir_p(path) unless File.exist?(path)
|
||||
end
|
||||
|
||||
Given /^I do not have a "(.*)" directory$/ do |path|
|
||||
File.directory?("#{TEST_DIR}/#{path}")
|
||||
end
|
||||
|
||||
# Like "I have a foo file" but gives a yaml front matter so jekyll actually processes it
|
||||
Given /^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$/ do |file, key, value, text|
|
||||
File.open(file, 'w') do |f|
|
||||
f.write <<-EOF
|
||||
---
|
||||
#{key || 'layout'}: #{value || 'nil'}
|
||||
---
|
||||
#{text}
|
||||
EOF
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have an? "(.*)" file that contains "(.*)"$/ do |file, text|
|
||||
File.open(file, 'w') do |f|
|
||||
f.write(text)
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have an? (.*) (layout|theme) that contains "(.*)"$/ do |name, type, text|
|
||||
folder = if type == 'layout'
|
||||
'_layouts'
|
||||
else
|
||||
'_theme'
|
||||
end
|
||||
destination_file = File.join(folder, name + '.html')
|
||||
destination_path = File.dirname(destination_file)
|
||||
unless File.exist?(destination_path)
|
||||
FileUtils.mkdir_p(destination_path)
|
||||
end
|
||||
File.open(destination_file, 'w') do |f|
|
||||
f.write(text)
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have an? "(.*)" file with content:$/ do |file, text|
|
||||
File.open(file, 'w') do |f|
|
||||
f.write(text)
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have an? (.*) directory$/ do |dir|
|
||||
FileUtils.mkdir_p(dir)
|
||||
end
|
||||
|
||||
Given /^I have the following (draft|page|post)s?(?: (in|under) "([^"]+)")?:$/ do |status, direction, folder, table|
|
||||
table.hashes.each do |input_hash|
|
||||
title = slug(input_hash['title'])
|
||||
ext = input_hash['type'] || 'markdown'
|
||||
before, after = location(folder, direction)
|
||||
|
||||
case status
|
||||
when "draft"
|
||||
dest_folder = '_drafts'
|
||||
filename = "#{title}.#{ext}"
|
||||
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, dest_folder, after, filename)
|
||||
File.open(path, 'w') do |f|
|
||||
f.write file_content_from_hash(input_hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have a configuration file with "(.*)" set to "(.*)"$/ do |key, value|
|
||||
File.open('_config.yml', 'w') do |f|
|
||||
f.write("#{key}: #{value}\n")
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have a configuration file with:$/ do |table|
|
||||
File.open('_config.yml', 'w') do |f|
|
||||
table.hashes.each do |row|
|
||||
f.write("#{row["key"]}: #{row["value"]}\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have a configuration file with "([^\"]*)" set to:$/ do |key, table|
|
||||
File.open('_config.yml', 'w') do |f|
|
||||
f.write("#{key}:\n")
|
||||
table.hashes.each do |row|
|
||||
f.write("- #{row["value"]}\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have fixture collections$/ do
|
||||
FileUtils.cp_r File.join(JEKYLL_SOURCE_DIR, "test", "source", "_methods"), source_dir
|
||||
end
|
||||
|
||||
Given /^I wait (\d+) second(s?)$/ do |time, plural|
|
||||
sleep(time.to_f)
|
||||
end
|
||||
|
||||
##################
|
||||
#
|
||||
# Changing stuff
|
||||
#
|
||||
##################
|
||||
|
||||
When /^I run jekyll(.*)$/ do |args|
|
||||
status = run_jekyll(args)
|
||||
if args.include?("--verbose") || ENV['DEBUG']
|
||||
puts jekyll_run_output
|
||||
end
|
||||
end
|
||||
|
||||
When /^I run bundle(.*)$/ do |args|
|
||||
status = run_bundle(args)
|
||||
if args.include?("--verbose") || ENV['DEBUG']
|
||||
puts jekyll_run_output
|
||||
end
|
||||
end
|
||||
|
||||
When /^I change "(.*)" to contain "(.*)"$/ do |file, text|
|
||||
File.open(file, 'a') do |f|
|
||||
f.write(text)
|
||||
end
|
||||
end
|
||||
|
||||
When /^I delete the file "(.*)"$/ do |file|
|
||||
File.delete(file)
|
||||
end
|
||||
|
||||
##################
|
||||
#
|
||||
# Checking stuff
|
||||
#
|
||||
##################
|
||||
|
||||
Then /^the (.*) directory should +exist$/ do |dir|
|
||||
assert File.directory?(dir), "The directory \"#{dir}\" does not exist"
|
||||
end
|
||||
|
||||
Then /^the (.*) directory should not exist$/ do |dir|
|
||||
assert !File.directory?(dir), "The directory \"#{dir}\" exists"
|
||||
end
|
||||
|
||||
Then /^I should see "(.*)" in "(.*)"$/ do |text, file|
|
||||
assert_match Regexp.new(text, Regexp::MULTILINE), file_contents(file)
|
||||
end
|
||||
|
||||
Then /^I should see exactly "(.*)" in "(.*)"$/ do |text, file|
|
||||
assert_equal text, file_contents(file).strip
|
||||
end
|
||||
|
||||
Then /^I should not see "(.*)" in "(.*)"$/ do |text, file|
|
||||
refute_match Regexp.new(text, Regexp::MULTILINE), file_contents(file)
|
||||
end
|
||||
|
||||
Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file|
|
||||
assert_match Regexp.new(Regexp.escape(text)), file_contents(file)
|
||||
end
|
||||
|
||||
Then /^the "(.*)" file should +exist$/ do |file|
|
||||
file_does_exist = File.file?(file)
|
||||
unless file_does_exist
|
||||
all_steps_to_path(file).each do |dir|
|
||||
STDERR.puts ""
|
||||
STDERR.puts "Dir #{dir}:"
|
||||
STDERR.puts Dir["#{dir}/**/*"]
|
||||
end
|
||||
end
|
||||
assert file_does_exist, "The file \"#{file}\" does not exist.\n"
|
||||
end
|
||||
|
||||
Then /^the "(.*)" file should not exist$/ do |file|
|
||||
assert !File.exist?(file), "The file \"#{file}\" exists"
|
||||
end
|
||||
|
||||
Then /^I should see today's time in "(.*)"$/ do |file|
|
||||
assert_match Regexp.new(seconds_agnostic_time(Time.now)), file_contents(file)
|
||||
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
|
||||
|
||||
Then /^I should get a non-zero exit(?:\-| )status$/ do
|
||||
assert jekyll_run_status > 0
|
||||
end
|
||||
@@ -1,116 +0,0 @@
|
||||
require 'fileutils'
|
||||
require 'posix-spawn'
|
||||
require 'minitest/spec'
|
||||
require 'time'
|
||||
|
||||
class MinitestWorld
|
||||
extend Minitest::Assertions
|
||||
attr_accessor :assertions
|
||||
|
||||
def initialize
|
||||
self.assertions = 0
|
||||
end
|
||||
end
|
||||
|
||||
JEKYLL_SOURCE_DIR = File.dirname(File.dirname(File.dirname(__FILE__)))
|
||||
TEST_DIR = File.expand_path(File.join('..', '..', 'tmp', 'jekyll'), File.dirname(__FILE__))
|
||||
JEKYLL_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll'))
|
||||
JEKYLL_COMMAND_OUTPUT_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_output.txt')
|
||||
JEKYLL_COMMAND_STATUS_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_status.txt')
|
||||
|
||||
def source_dir(*files)
|
||||
File.join(TEST_DIR, *files)
|
||||
end
|
||||
|
||||
def all_steps_to_path(path)
|
||||
source = Pathname.new(source_dir('_site')).expand_path
|
||||
dest = Pathname.new(path).expand_path
|
||||
paths = []
|
||||
dest.ascend do |f|
|
||||
break if f.eql? source
|
||||
paths.unshift f.to_s
|
||||
end
|
||||
paths
|
||||
end
|
||||
|
||||
def jekyll_output_file
|
||||
JEKYLL_COMMAND_OUTPUT_FILE
|
||||
end
|
||||
|
||||
def jekyll_status_file
|
||||
JEKYLL_COMMAND_STATUS_FILE
|
||||
end
|
||||
|
||||
def jekyll_run_output
|
||||
File.read(jekyll_output_file) if File.file?(jekyll_output_file)
|
||||
end
|
||||
|
||||
def jekyll_run_status
|
||||
(File.read(jekyll_status_file) rescue 0).to_i
|
||||
end
|
||||
|
||||
def run_bundle(args)
|
||||
run_in_shell('bundle', *args.strip.split(' '))
|
||||
end
|
||||
|
||||
def run_jekyll(args)
|
||||
child = run_in_shell(JEKYLL_PATH, *args.strip.split(' '), "--trace")
|
||||
child.status.exitstatus == 0
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# XXX: POSIX::Spawn::Child does not write output when the exit status is > 0
|
||||
# for example when doing [:out, :err] => [file, "w"] it will skip
|
||||
# writing the file entirely, we sould switch to Open.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def run_in_shell(*args)
|
||||
spawned = POSIX::Spawn::Child.new(*args)
|
||||
status = spawned.status.exitstatus
|
||||
File.write(JEKYLL_COMMAND_STATUS_FILE, status)
|
||||
File.open(JEKYLL_COMMAND_OUTPUT_FILE, "w+") do |file|
|
||||
status == 0 ? file.write(spawned.out) : file.write(spawned.err)
|
||||
end
|
||||
|
||||
spawned
|
||||
end
|
||||
|
||||
def slug(title)
|
||||
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)
|
||||
if folder
|
||||
before = folder if direction == "in"
|
||||
after = folder if direction == "under"
|
||||
end
|
||||
[before || '.', after || '.']
|
||||
end
|
||||
|
||||
def file_contents(path)
|
||||
File.open(path) do |file|
|
||||
file.readlines.join # avoid differences with \n and \r\n line endings
|
||||
end
|
||||
end
|
||||
|
||||
def seconds_agnostic_datetime(datetime = Time.now)
|
||||
date, time, zone = datetime.to_s.split(" ")
|
||||
time = seconds_agnostic_time(time)
|
||||
[
|
||||
Regexp.escape(date),
|
||||
"#{time}:\\d{2}",
|
||||
Regexp.escape(zone)
|
||||
].join("\\ ")
|
||||
end
|
||||
|
||||
def seconds_agnostic_time(time)
|
||||
if time.is_a? Time
|
||||
time = time.strftime("%H:%M:%S")
|
||||
end
|
||||
hour, minutes, _ = time.split(":")
|
||||
"#{hour}:#{minutes}"
|
||||
end
|
||||
@@ -2,140 +2,177 @@ 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
|
||||
module Jekyll
|
||||
module Cucumber
|
||||
class Formatter
|
||||
attr_accessor :indent, :runtime
|
||||
include ::Cucumber::Formatter::Console
|
||||
include ::Cucumber::Formatter::Io
|
||||
include FileUtils
|
||||
include Cucumber::Formatter::Console
|
||||
include Cucumber::Formatter::Io
|
||||
include Gherkin::Formatter::Escaping
|
||||
attr_writer :indent
|
||||
attr_reader :runtime
|
||||
|
||||
CHARS = {
|
||||
:failed => "\u2718".red,
|
||||
:pending => "\u203D".yellow,
|
||||
:undefined => "\u2718".red,
|
||||
:passed => "\u2714".green,
|
||||
:skipped => "\u203D".blue
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
def initialize(runtime, path_or_io, options)
|
||||
@runtime, @io, @options = runtime, ensure_io(path_or_io, "pretty"), options
|
||||
@exceptions = []
|
||||
@indent = 0
|
||||
@runtime = runtime
|
||||
@snippets_input = []
|
||||
@io = ensure_io(path_or_io)
|
||||
@prefixes = options[:prefixes] || {}
|
||||
@delayed_messages = []
|
||||
@options = options
|
||||
@exceptions = []
|
||||
@indent = 0
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def before_features(features)
|
||||
print_profile_information
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def after_features(features)
|
||||
@io.puts
|
||||
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 comment_line(comment_line); end
|
||||
def after_feature_element(feature_element); 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
|
||||
@indent = 2
|
||||
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)
|
||||
#
|
||||
|
||||
def background_name(keyword, name, source_line, indend)
|
||||
print_feature_element_name(
|
||||
keyword, name, source_line, indend
|
||||
)
|
||||
end
|
||||
|
||||
def scenario_name(keyword, name, file_colon_line, source_indent)
|
||||
print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
||||
#
|
||||
|
||||
def scenario_name(keyword, name, source_line, indent)
|
||||
print_feature_element_name(
|
||||
keyword, name, source_line, 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)
|
||||
#
|
||||
|
||||
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]
|
||||
@io.print " "
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def exception(exception, status)
|
||||
return if @hide_this_step
|
||||
|
||||
@io.puts
|
||||
print_exception(exception, status, @indent)
|
||||
@io.flush
|
||||
end
|
||||
|
||||
private
|
||||
#
|
||||
|
||||
def print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
||||
def after_test_step(test_step, result)
|
||||
collect_snippet_data(
|
||||
test_step, result
|
||||
)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
private
|
||||
def print_feature_element_name(keyword, name, source_line, 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
|
||||
|
||||
names = name.empty? ? [name] : name.each_line.to_a
|
||||
line = " #{keyword}: #{names[0]}"
|
||||
|
||||
@io.print(source_line) if @options[:source]
|
||||
@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)
|
||||
161
features/support/helpers.rb
Normal file
161
features/support/helpers.rb
Normal file
@@ -0,0 +1,161 @@
|
||||
require "fileutils"
|
||||
require "jekyll/utils"
|
||||
require "open3"
|
||||
require "time"
|
||||
require "safe_yaml/load"
|
||||
|
||||
class Paths
|
||||
SOURCE_DIR = Pathname.new(File.expand_path("../..", __dir__))
|
||||
def self.test_dir; source_dir.join("tmp", "jekyll"); end
|
||||
def self.output_file; test_dir.join("jekyll_output.txt"); end
|
||||
def self.status_file; test_dir.join("jekyll_status.txt"); end
|
||||
def self.jekyll_bin; source_dir.join("bin", "jekyll"); end
|
||||
def self.source_dir; SOURCE_DIR; end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def file_content_from_hash(input_hash)
|
||||
matter_hash = input_hash.reject { |k, v| k == "content" }
|
||||
matter = matter_hash.map do |k, v| "#{k}: #{v}\n"
|
||||
end
|
||||
|
||||
matter = matter.join.chomp
|
||||
content = \
|
||||
if !input_hash['input'] || !input_hash['filter']
|
||||
then input_hash['content']
|
||||
else "{{ #{input_hash['input']} | " \
|
||||
"#{input_hash['filter']} }}"
|
||||
end
|
||||
|
||||
Jekyll::Utils.strip_heredoc(<<-EOF)
|
||||
---
|
||||
#{matter.gsub(
|
||||
/\n/, "\n "
|
||||
)}
|
||||
---
|
||||
#{content}
|
||||
EOF
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def source_dir(*files)
|
||||
return Paths.test_dir(*files)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def all_steps_to_path(path)
|
||||
source = source_dir
|
||||
dest = Pathname.new(path).expand_path
|
||||
paths = []
|
||||
|
||||
dest.ascend do |f|
|
||||
break if f == source
|
||||
paths.unshift f.to_s
|
||||
end
|
||||
|
||||
paths
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def jekyll_run_output
|
||||
if Paths.output_file.file?
|
||||
then return Paths.output_file.read
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def jekyll_run_status
|
||||
if Paths.status_file.file?
|
||||
then return Paths.status_file.read
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def run_bundle(args)
|
||||
run_in_shell("bundle", *args.strip.split(' '))
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def run_jekyll(args)
|
||||
args = args.strip.split(" ") # Shellwords?
|
||||
process = run_in_shell(Paths.jekyll_bin.to_s, *args, "--trace")
|
||||
process.exitstatus == 0
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def run_in_shell(*args)
|
||||
i, o, e, p = Open3.popen3(*args)
|
||||
out = o.read.strip
|
||||
err = e.read.strip
|
||||
|
||||
[i, o, e].each do |m|
|
||||
m.close
|
||||
end
|
||||
|
||||
File.write(Paths.status_file, p.value.exitstatus)
|
||||
File.open(Paths.output_file, "wb") do |f|
|
||||
f.puts "$ " << args.join(" ")
|
||||
f.puts out
|
||||
f.puts err
|
||||
f.puts "EXIT STATUS: #{p.value.exitstatus}"
|
||||
end
|
||||
|
||||
p.value
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def slug(title = nil)
|
||||
if !title
|
||||
then Time.now.strftime("%s%9N") # nanoseconds since the Epoch
|
||||
else title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def location(folder, direction)
|
||||
if folder
|
||||
before = folder if direction == "in"
|
||||
after = folder if direction == "under"
|
||||
end
|
||||
|
||||
[before || '.',
|
||||
after || '.']
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def file_contents(path)
|
||||
return Pathname.new(path).read
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def seconds_agnostic_datetime(datetime = Time.now)
|
||||
date, time, zone = datetime.to_s.split(" ")
|
||||
time = seconds_agnostic_time(time)
|
||||
|
||||
[
|
||||
Regexp.escape(date),
|
||||
"#{time}:\\d{2}",
|
||||
Regexp.escape(zone)
|
||||
] \
|
||||
.join("\\ ")
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def seconds_agnostic_time(time)
|
||||
time = time.strftime("%H:%M:%S") if time.is_a?(Time)
|
||||
hour, minutes, _ = time.split(":")
|
||||
"#{hour}:#{minutes}"
|
||||
end
|
||||
@@ -1,22 +0,0 @@
|
||||
# coding: utf-8
|
||||
lib = File.expand_path('../lib', __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'jekyll/version'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = 'jekyll-docs'
|
||||
spec.version = Jekyll::VERSION
|
||||
spec.authors = ['Parker Moore']
|
||||
spec.email = ['parkrmoore@gmail.com']
|
||||
spec.summary = %q{Offline usage documentation for Jekyll.}
|
||||
spec.homepage = 'http://jekyllrb.com'
|
||||
spec.license = 'MIT'
|
||||
|
||||
spec.files = `git ls-files -z`.split("\x0").grep(%r{^site/})
|
||||
spec.require_paths = ['lib']
|
||||
|
||||
spec.add_dependency 'jekyll', Jekyll::VERSION
|
||||
|
||||
spec.add_development_dependency 'bundler', '~> 1.7'
|
||||
spec.add_development_dependency 'rake', '~> 10.0'
|
||||
end
|
||||
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
||||
s.homepage = 'https://github.com/jekyll/jekyll'
|
||||
|
||||
all_files = `git ls-files -z`.split("\x0")
|
||||
s.files = all_files.grep(%r{^(bin|lib)/})
|
||||
s.files = all_files.grep(%r{^(bin|lib)/|^.rubocop.yml$})
|
||||
s.executables = all_files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||
s.require_paths = ['lib']
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
||||
$LOAD_PATH.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
||||
|
||||
# Require all of the Ruby files in the given directory.
|
||||
#
|
||||
@@ -16,6 +16,7 @@ end
|
||||
require 'rubygems'
|
||||
|
||||
# stdlib
|
||||
require 'forwardable'
|
||||
require 'fileutils'
|
||||
require 'time'
|
||||
require 'English'
|
||||
@@ -32,7 +33,6 @@ require 'colorator'
|
||||
SafeYAML::OPTIONS[:suppress_warnings] = true
|
||||
|
||||
module Jekyll
|
||||
|
||||
# internal requires
|
||||
autoload :Cleaner, 'jekyll/cleaner'
|
||||
autoload :Collection, 'jekyll/collection'
|
||||
@@ -95,7 +95,7 @@ module Jekyll
|
||||
# list of option names and their defaults.
|
||||
#
|
||||
# Returns the final configuration Hash.
|
||||
def configuration(override = Hash.new)
|
||||
def configuration(override = {})
|
||||
config = Configuration[Configuration::DEFAULTS]
|
||||
override = Configuration[override].stringify_keys
|
||||
unless override.delete('skip_config_files')
|
||||
@@ -153,25 +153,27 @@ module Jekyll
|
||||
def sanitized_path(base_directory, questionable_path)
|
||||
return base_directory if base_directory.eql?(questionable_path)
|
||||
|
||||
questionable_path.insert(0, '/') if questionable_path.start_with?('~')
|
||||
clean_path = File.expand_path(questionable_path, "/")
|
||||
clean_path = clean_path.sub(/\A\w\:\//, '/')
|
||||
clean_path.sub!(/\A\w\:\//, '/')
|
||||
|
||||
unless clean_path.start_with?(base_directory.sub(/\A\w\:\//, '/'))
|
||||
File.join(base_directory, clean_path)
|
||||
else
|
||||
if clean_path.start_with?(base_directory.sub(/\A\w\:\//, '/'))
|
||||
clean_path
|
||||
else
|
||||
File.join(base_directory, clean_path)
|
||||
end
|
||||
end
|
||||
|
||||
# Conditional optimizations
|
||||
Jekyll::External.require_if_present('liquid-c')
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
require "jekyll/drops/drop"
|
||||
require_all 'jekyll/commands'
|
||||
require_all 'jekyll/converters'
|
||||
require_all 'jekyll/converters/markdown'
|
||||
require_all 'jekyll/drops'
|
||||
require_all 'jekyll/generators'
|
||||
require_all 'jekyll/tags'
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ module Jekyll
|
||||
# Cleans up the site's destination directory
|
||||
def cleanup!
|
||||
FileUtils.rm_rf(obsolete_files)
|
||||
FileUtils.rm_rf(metadata_file) if !@site.incremental?
|
||||
FileUtils.rm_rf(metadata_file) unless @site.incremental?
|
||||
end
|
||||
|
||||
private
|
||||
@@ -40,7 +40,7 @@ module Jekyll
|
||||
regex = keep_file_regex
|
||||
dirs = keep_dirs
|
||||
|
||||
Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file|
|
||||
Utils.safe_glob(site.in_dest_dir, ["**", "*"], File::FNM_DOTMATCH).each do |file|
|
||||
next if file =~ HIDDEN_FILE_REGEX || file =~ regex || dirs.include?(file)
|
||||
files << file
|
||||
end
|
||||
@@ -95,11 +95,12 @@ module Jekyll
|
||||
# Private: Creates a regular expression from the config's keep_files array
|
||||
#
|
||||
# Examples
|
||||
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
||||
# ['.git','.svn'] with site.dest "/myblog/_site" creates
|
||||
# the following regex: /\A\/myblog\/_site\/(\.git|\/.svn)/
|
||||
#
|
||||
# Returns the regular expression
|
||||
def keep_file_regex
|
||||
Regexp.union(site.keep_files)
|
||||
/\A#{Regexp.quote(site.dest)}\/(#{Regexp.union(site.keep_files).source})/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,7 +32,7 @@ module Jekyll
|
||||
# Override of method_missing to check in @data for the key.
|
||||
def method_missing(method, *args, &blck)
|
||||
if docs.respond_to?(method.to_sym)
|
||||
Jekyll.logger.warn "Deprecation:", "Collection##{method} should be called on the #docs array directly."
|
||||
Jekyll.logger.warn "Deprecation:", "#{label}.#{method} should be changed to #{label}.docs.#{method}."
|
||||
Jekyll.logger.warn "", "Called by #{caller.first}."
|
||||
docs.public_send(method.to_sym, *args, &blck)
|
||||
else
|
||||
@@ -56,9 +56,13 @@ module Jekyll
|
||||
full_path = collection_dir(file_path)
|
||||
next if File.directory?(full_path)
|
||||
if Utils.has_yaml_header? full_path
|
||||
doc = Jekyll::Document.new(full_path, { site: site, collection: self })
|
||||
doc = Jekyll::Document.new(full_path, { :site => site, :collection => self })
|
||||
doc.read
|
||||
docs << doc if site.publisher.publish?(doc) || !write?
|
||||
if site.publisher.publish?(doc) || !write?
|
||||
docs << doc
|
||||
else
|
||||
Jekyll.logger.debug "Skipped From Publishing:", doc.relative_path
|
||||
end
|
||||
else
|
||||
relative_dir = Jekyll.sanitized_path(relative_directory, File.dirname(file_path)).chomp("/.")
|
||||
files << StaticFile.new(site, site.source, relative_dir, File.basename(full_path), self)
|
||||
@@ -72,10 +76,11 @@ module Jekyll
|
||||
# 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?
|
||||
return [] unless exists?
|
||||
@entries ||=
|
||||
Dir.glob(collection_dir("**", "*.*")).map do |entry|
|
||||
entry["#{collection_dir}/"] = ''; entry
|
||||
Utils.safe_glob(collection_dir, ["**", "*"]).map do |entry|
|
||||
entry["#{collection_dir}/"] = ''
|
||||
entry
|
||||
end
|
||||
end
|
||||
|
||||
@@ -84,7 +89,7 @@ module Jekyll
|
||||
#
|
||||
# Returns a list of filtered entry paths.
|
||||
def filtered_entries
|
||||
return Array.new unless exists?
|
||||
return [] unless exists?
|
||||
@filtered_entries ||=
|
||||
Dir.chdir(directory) do
|
||||
entry_filter.filter(entries).reject do |f|
|
||||
@@ -166,14 +171,7 @@ module Jekyll
|
||||
#
|
||||
# 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
|
||||
})
|
||||
Drops::CollectionDrop.new self
|
||||
end
|
||||
|
||||
# Whether the collection's documents ought to be written as individual
|
||||
@@ -188,8 +186,8 @@ module Jekyll
|
||||
#
|
||||
# Returns the URL template to render collection's documents at.
|
||||
def url_template
|
||||
metadata.fetch('permalink') do
|
||||
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
||||
@url_template ||= metadata.fetch('permalink') do
|
||||
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -198,7 +196,7 @@ module Jekyll
|
||||
# Returns the metadata for this collection
|
||||
def extract_metadata
|
||||
if site.config['collections'].is_a?(Hash)
|
||||
site.config['collections'][label] || Hash.new
|
||||
site.config['collections'][label] || {}
|
||||
else
|
||||
{}
|
||||
end
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module Jekyll
|
||||
class Command
|
||||
|
||||
class << self
|
||||
|
||||
# A list of subclasses of Jekyll::Command
|
||||
def subclasses
|
||||
@subclasses ||= []
|
||||
@@ -62,8 +60,6 @@ module Jekyll
|
||||
c.option 'verbose', '-V', '--verbose', 'Print verbose output.'
|
||||
c.option 'incremental', '-I', '--incremental', 'Enable incremental rebuild.'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Build < Command
|
||||
|
||||
class << self
|
||||
|
||||
# Create the Mercenary command for the Jekyll CLI for this Command
|
||||
def init_with_program(prog)
|
||||
prog.command(:build) do |c|
|
||||
@@ -13,7 +11,7 @@ module Jekyll
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
c.action do |args, options|
|
||||
c.action do |_, options|
|
||||
options["serving"] = false
|
||||
Jekyll::Commands::Build.process(options)
|
||||
end
|
||||
@@ -35,7 +33,9 @@ module Jekyll
|
||||
build(site, options)
|
||||
end
|
||||
|
||||
if options.fetch('watch', false)
|
||||
if options.fetch('detach', false)
|
||||
Jekyll.logger.info "Auto-regeneration:", "disabled when running server detached."
|
||||
elsif options.fetch('watch', false)
|
||||
watch(site, options)
|
||||
else
|
||||
Jekyll.logger.info "Auto-regeneration:", "disabled. Use --watch to enable."
|
||||
@@ -67,13 +67,11 @@ module Jekyll
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def watch(site, options)
|
||||
def watch(_site, options)
|
||||
External.require_with_graceful_fail 'jekyll-watch'
|
||||
Jekyll::Watcher.watch(options)
|
||||
end
|
||||
|
||||
end # end of class << self
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,6 @@ module Jekyll
|
||||
module Commands
|
||||
class Clean < Command
|
||||
class << self
|
||||
|
||||
def init_with_program(prog)
|
||||
prog.command(:clean) do |c|
|
||||
c.syntax 'clean [subcommand]'
|
||||
@@ -10,8 +9,8 @@ module Jekyll
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
c.action do |args, _|
|
||||
Jekyll::Commands::Clean.process({})
|
||||
c.action do |_, options|
|
||||
Jekyll::Commands::Clean.process(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -20,24 +19,21 @@ module Jekyll
|
||||
options = configuration_from_options(options)
|
||||
destination = options['destination']
|
||||
metadata_file = File.join(options['source'], '.jekyll-metadata')
|
||||
sass_cache = File.join(options['source'], '.sass-cache')
|
||||
|
||||
if File.directory? destination
|
||||
Jekyll.logger.info "Cleaning #{destination}..."
|
||||
FileUtils.rm_rf(destination)
|
||||
Jekyll.logger.info "", "done."
|
||||
else
|
||||
Jekyll.logger.info "Nothing to do for #{destination}."
|
||||
end
|
||||
|
||||
if File.file? metadata_file
|
||||
Jekyll.logger.info "Removing #{metadata_file}..."
|
||||
FileUtils.rm_rf(metadata_file)
|
||||
Jekyll.logger.info "", "done."
|
||||
else
|
||||
Jekyll.logger.info "Nothing to do for #{metadata_file}."
|
||||
end
|
||||
remove(destination, checker_func: :directory?)
|
||||
remove(metadata_file, checker_func: :file?)
|
||||
remove(sass_cache, checker_func: :directory?)
|
||||
end
|
||||
|
||||
def remove(filename, checker_func: :file?)
|
||||
if File.public_send(checker_func, filename)
|
||||
Jekyll.logger.info "Cleaner:", "Removing #{filename}..."
|
||||
FileUtils.rm_rf(filename)
|
||||
else
|
||||
Jekyll.logger.info "Cleaner:", "Nothing to do for #{filename}."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,16 +2,15 @@ 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.option 'config', '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
|
||||
c.action do |args, options|
|
||||
c.action do |_, options|
|
||||
Jekyll::Commands::Doctor.process(options)
|
||||
end
|
||||
end
|
||||
@@ -32,14 +31,15 @@ module Jekyll
|
||||
[
|
||||
fsnotify_buggy?(site),
|
||||
!deprecated_relative_permalinks(site),
|
||||
!conflicting_urls(site)
|
||||
!conflicting_urls(site),
|
||||
!urls_only_differ_by_case(site)
|
||||
].all?
|
||||
end
|
||||
|
||||
def deprecated_relative_permalinks(site)
|
||||
if site.config['relative_permalinks']
|
||||
Jekyll::Deprecator.deprecation_message "Your site still uses relative" +
|
||||
" permalinks, which was removed in" +
|
||||
Jekyll::Deprecator.deprecation_message "Your site still uses relative" \
|
||||
" permalinks, which was removed in" \
|
||||
" Jekyll v3.0.0."
|
||||
return true
|
||||
end
|
||||
@@ -51,17 +51,16 @@ module Jekyll
|
||||
urls = collect_urls(urls, site.pages, site.dest)
|
||||
urls = collect_urls(urls, site.posts.docs, site.dest)
|
||||
urls.each do |url, paths|
|
||||
if paths.size > 1
|
||||
conflicting_urls = true
|
||||
Jekyll.logger.warn "Conflict:", "The URL '#{url}' is the destination" +
|
||||
" for the following pages: #{paths.join(", ")}"
|
||||
end
|
||||
next unless paths.size > 1
|
||||
conflicting_urls = true
|
||||
Jekyll.logger.warn "Conflict:", "The URL '#{url}' is the destination" \
|
||||
" for the following pages: #{paths.join(", ")}"
|
||||
end
|
||||
conflicting_urls
|
||||
end
|
||||
|
||||
def fsnotify_buggy?(site)
|
||||
return true if !Utils::Platforms.osx?
|
||||
def fsnotify_buggy?(_site)
|
||||
return true unless Utils::Platforms.osx?
|
||||
if Dir.pwd != `pwd`.strip
|
||||
Jekyll.logger.error " " + <<-STR.strip.gsub(/\n\s+/, "\n ")
|
||||
We have detected that there might be trouble using fsevent on your
|
||||
@@ -76,6 +75,19 @@ module Jekyll
|
||||
true
|
||||
end
|
||||
|
||||
def urls_only_differ_by_case(site)
|
||||
urls_only_differ_by_case = false
|
||||
urls = case_insensitive_urls(site.pages + site.docs_to_write, site.dest)
|
||||
urls.each do |case_insensitive_url, real_urls|
|
||||
next unless real_urls.uniq.size > 1
|
||||
urls_only_differ_by_case = true
|
||||
Jekyll.logger.warn "Warning:", "The following URLs only differ" \
|
||||
" by case. On a case-insensitive file system one of the URLs" \
|
||||
" will be overwritten by the other: #{real_urls.join(", ")}"
|
||||
end
|
||||
urls_only_differ_by_case
|
||||
end
|
||||
|
||||
private
|
||||
def collect_urls(urls, things, destination)
|
||||
things.each do |thing|
|
||||
@@ -89,8 +101,14 @@ module Jekyll
|
||||
urls
|
||||
end
|
||||
|
||||
def case_insensitive_urls(things, destination)
|
||||
things.inject({}) do |memo, thing|
|
||||
dest = thing.destination(destination)
|
||||
(memo[dest.downcase] ||= []) << dest
|
||||
memo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,6 @@ module Jekyll
|
||||
module Commands
|
||||
class Help < Command
|
||||
class << self
|
||||
|
||||
def init_with_program(prog)
|
||||
prog.command(:help) do |c|
|
||||
c.syntax 'help [subcommand]'
|
||||
@@ -26,7 +25,6 @@ module Jekyll
|
||||
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
|
||||
|
||||
@@ -35,6 +35,10 @@ module Jekyll
|
||||
File.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
|
||||
f.write(scaffold_post_content)
|
||||
end
|
||||
|
||||
File.open(File.expand_path("Gemfile", new_blog_path), "w") do |f|
|
||||
f.write(gemfile_contents)
|
||||
end
|
||||
end
|
||||
|
||||
Jekyll.logger.info "New jekyll site installed in #{new_blog_path}."
|
||||
@@ -59,6 +63,31 @@ module Jekyll
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def gemfile_contents
|
||||
<<-RUBY
|
||||
source "https://rubygems.org"
|
||||
|
||||
# Hello! This is where you manage which Jekyll version is used to run.
|
||||
# When you want to use a different version, change it below, save the
|
||||
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||
#
|
||||
# bundle exec jekyll serve
|
||||
#
|
||||
# This will help ensure the proper Jekyll version is running.
|
||||
# Happy Jekylling!
|
||||
gem "jekyll", "#{Jekyll::VERSION}"
|
||||
|
||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||
# gem "github-pages", group: :jekyll_plugins
|
||||
|
||||
# If you have any plugins, put them here!
|
||||
# group :jekyll_plugins do
|
||||
# gem "jekyll-github-metadata", "~> 1.0"
|
||||
# end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def preserve_source_location?(path, options)
|
||||
!options["force"] && !Dir["#{path}/**/*"].empty?
|
||||
|
||||
@@ -1,151 +1,205 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve < Command
|
||||
|
||||
class << self
|
||||
COMMAND_OPTIONS = {
|
||||
"ssl_cert" => ["--ssl-cert [CERT]", "X.509 (SSL) certificate."],
|
||||
"host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
|
||||
"open_url" => ["-o", "--open-url", "Launch your browser with your site."],
|
||||
"detach" => ["-B", "--detach", "Run the server in the background (detach)"],
|
||||
"ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
|
||||
"port" => ["-P", "--port [PORT]", "Port to listen on"],
|
||||
"baseurl" => ["-b", "--baseurl [URL]", "Base URL"],
|
||||
"show_dir_listing" => ["--show-dir-listing",
|
||||
"Show a directory listing instead of loading your index file."],
|
||||
"skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
|
||||
"Skips the initial site build which occurs before the server is started."]
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
def init_with_program(prog)
|
||||
prog.command(:serve) do |c|
|
||||
c.syntax 'serve [options]'
|
||||
c.description 'Serve your site locally'
|
||||
c.alias :server
|
||||
c.alias :s
|
||||
prog.command(:serve) do |cmd|
|
||||
cmd.description "Serve your site locally"
|
||||
cmd.syntax "serve [options]"
|
||||
cmd.alias :server
|
||||
cmd.alias :s
|
||||
|
||||
add_build_options(c)
|
||||
add_build_options(cmd)
|
||||
COMMAND_OPTIONS.each do |key, val|
|
||||
cmd.option key, *val
|
||||
end
|
||||
|
||||
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
|
||||
options["watch"] = true unless options.key?("watch")
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
cmd.action do |_, opts|
|
||||
opts["serving"] = true
|
||||
opts["watch" ] = true unless opts.key?("watch")
|
||||
Build.process(opts)
|
||||
Serve.process(opts)
|
||||
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']
|
||||
#
|
||||
|
||||
def process(opts)
|
||||
opts = configuration_from_options(opts)
|
||||
destination = opts["destination"]
|
||||
setup(destination)
|
||||
|
||||
s = WEBrick::HTTPServer.new(webrick_options(options))
|
||||
s.unmount("")
|
||||
server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
|
||||
server.mount(opts["baseurl"], Servlet, destination, file_handler_opts)
|
||||
Jekyll.logger.info "Server address:", server_address(server, opts)
|
||||
launch_browser server, opts if opts["open_url"]
|
||||
boot_or_detach server, opts
|
||||
end
|
||||
|
||||
s.mount(
|
||||
options['baseurl'],
|
||||
custom_file_handler,
|
||||
destination,
|
||||
file_handler_options
|
||||
)
|
||||
# Do a base pre-setup of WEBRick so that everything is in place
|
||||
# when we get ready to party, checking for an setting up an error page
|
||||
# and making sure our destination exists.
|
||||
|
||||
Jekyll.logger.info "Server address:", server_address(s, options)
|
||||
private
|
||||
def setup(destination)
|
||||
require_relative "serve/servlet"
|
||||
|
||||
FileUtils.mkdir_p(destination)
|
||||
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
|
||||
|
||||
#
|
||||
|
||||
private
|
||||
def webrick_opts(opts)
|
||||
opts = {
|
||||
:JekyllOptions => opts,
|
||||
:DoNotReverseLookup => true,
|
||||
:MimeTypes => mime_types,
|
||||
:DocumentRoot => opts["destination"],
|
||||
:StartCallback => start_callback(opts["detach"]),
|
||||
:BindAddress => opts["host"],
|
||||
:Port => opts["port"],
|
||||
:DirectoryIndex => %W(
|
||||
index.htm
|
||||
index.html
|
||||
index.rhtml
|
||||
index.cgi
|
||||
index.xml
|
||||
)
|
||||
}
|
||||
|
||||
opts[:DirectoryIndex] = [] if opts[:JekyllOptions]['show_dir_listing']
|
||||
|
||||
enable_ssl(opts)
|
||||
enable_logging(opts)
|
||||
opts
|
||||
end
|
||||
|
||||
# Recreate NondisclosureName under utf-8 circumstance
|
||||
|
||||
private
|
||||
def file_handler_opts
|
||||
WEBrick::Config::FileHandler.merge({
|
||||
:FancyIndexing => true,
|
||||
:NondisclosureName => [
|
||||
'.ht*', '~*'
|
||||
]
|
||||
})
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
private
|
||||
def server_address(server, opts)
|
||||
address = server.config[:BindAddress]
|
||||
baseurl = "#{opts["baseurl"]}/" if opts["baseurl"]
|
||||
port = server.config[:Port]
|
||||
|
||||
"http://#{address}:#{port}#{baseurl}"
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
private
|
||||
def launch_browser(server, opts)
|
||||
address = server_address(server, opts)
|
||||
return system "start", address if Utils::Platforms.windows?
|
||||
return system "xdg-open", address if Utils::Platforms.linux?
|
||||
return system "open", address if Utils::Platforms.osx?
|
||||
Jekyll.logger.error "Refusing to launch browser; " \
|
||||
"Platform launcher unknown."
|
||||
end
|
||||
|
||||
# Keep in our area with a thread or detach the server as requested
|
||||
# by the user. This method determines what we do based on what you
|
||||
# ask us to do.
|
||||
|
||||
private
|
||||
def boot_or_detach(server, opts)
|
||||
if opts["detach"]
|
||||
pid = Process.fork do
|
||||
server.start
|
||||
end
|
||||
|
||||
if options['detach'] # detach the server
|
||||
pid = Process.fork { s.start }
|
||||
Process.detach(pid)
|
||||
Jekyll.logger.info "Server detached with pid '#{pid}'.", "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
|
||||
else # create a new server thread, then join it with current terminal
|
||||
t = Thread.new { s.start }
|
||||
trap("INT") { s.shutdown }
|
||||
Jekyll.logger.info "Server detached with pid '#{pid}'.", \
|
||||
"Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
|
||||
else
|
||||
t = Thread.new { server.start }
|
||||
trap("INT") { server.shutdown }
|
||||
t.join
|
||||
end
|
||||
end
|
||||
|
||||
def setup(destination)
|
||||
require 'webrick'
|
||||
# Make the stack verbose if the user requests it.
|
||||
|
||||
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
|
||||
private
|
||||
def enable_logging(opts)
|
||||
opts[:AccessLog] = []
|
||||
level = WEBrick::Log.const_get(opts[:JekyllOptions]["verbose"] ? :DEBUG : :WARN)
|
||||
opts[:Logger] = WEBrick::Log.new($stdout, level)
|
||||
end
|
||||
|
||||
def webrick_options(config)
|
||||
opts = {
|
||||
:BindAddress => config['host'],
|
||||
:DirectoryIndex => %w(index.html index.htm index.cgi index.rhtml index.xml),
|
||||
:DocumentRoot => config['destination'],
|
||||
:DoNotReverseLookup => true,
|
||||
:MimeTypes => mime_types,
|
||||
:Port => config['port'],
|
||||
:StartCallback => start_callback(config['detach'])
|
||||
}
|
||||
# Add SSL to the stack if the user triggers --enable-ssl and they
|
||||
# provide both types of certificates commonly needed. Raise if they
|
||||
# forget to add one of the certificates.
|
||||
|
||||
if config['verbose']
|
||||
opts.merge!({
|
||||
:Logger => WEBrick::Log.new($stdout, WEBrick::Log::DEBUG)
|
||||
})
|
||||
else
|
||||
opts.merge!({
|
||||
:AccessLog => [],
|
||||
:Logger => WEBrick::Log.new([], WEBrick::Log::WARN)
|
||||
})
|
||||
private
|
||||
def enable_ssl(opts)
|
||||
return if !opts[:JekyllOptions]["ssl_cert"] && !opts[:JekyllOptions]["ssl_key"]
|
||||
if !opts[:JekyllOptions]["ssl_cert"] || !opts[:JekyllOptions]["ssl_key"]
|
||||
raise RuntimeError, "--ssl-cert or --ssl-key missing."
|
||||
end
|
||||
|
||||
opts
|
||||
end
|
||||
|
||||
# Custom WEBrick FileHandler servlet for serving "/file.html" at "/file"
|
||||
# when no exact match is found. This mirrors the behavior of GitHub
|
||||
# Pages and many static web server configs.
|
||||
def custom_file_handler
|
||||
Class.new WEBrick::HTTPServlet::FileHandler do
|
||||
def search_file(req, res, basename)
|
||||
if file = super
|
||||
file
|
||||
else
|
||||
super(req, res, "#{basename}.html")
|
||||
end
|
||||
end
|
||||
end
|
||||
require "openssl"
|
||||
require "webrick/https"
|
||||
source_key = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_key" ])
|
||||
source_certificate = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_cert"])
|
||||
opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read(source_certificate))
|
||||
opts[:SSLPrivateKey ] = OpenSSL::PKey::RSA.new(File.read(source_key))
|
||||
opts[:EnableSSL] = true
|
||||
end
|
||||
|
||||
private
|
||||
def start_callback(detached)
|
||||
unless detached
|
||||
Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
|
||||
proc do
|
||||
Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def mime_types
|
||||
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
||||
WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
||||
file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
||||
WEBrick::HTTPUtils.load_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
|
||||
def file_handler_options
|
||||
WEBrick::Config::FileHandler.merge({
|
||||
:FancyIndexing => true,
|
||||
:NondisclosureName => ['.ht*','~*']
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
61
lib/jekyll/commands/serve/servlet.rb
Normal file
61
lib/jekyll/commands/serve/servlet.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
require "webrick"
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve
|
||||
class Servlet < WEBrick::HTTPServlet::FileHandler
|
||||
DEFAULTS = {
|
||||
"Cache-Control" => "private, max-age=0, proxy-revalidate, " \
|
||||
"no-store, no-cache, must-revalidate"
|
||||
}
|
||||
|
||||
def initialize(server, root, callbacks)
|
||||
# So we can access them easily.
|
||||
@jekyll_opts = server.config[:JekyllOptions]
|
||||
set_defaults
|
||||
super
|
||||
end
|
||||
|
||||
# Add the ability to tap file.html the same way that Nginx does on our
|
||||
# Docker images (or on GitHub Pages.) The difference is that we might end
|
||||
# up with a different preference on which comes first.
|
||||
|
||||
def search_file(req, res, basename)
|
||||
# /file.* > /file/index.html > /file.html
|
||||
super || super(req, res, "#{basename}.html")
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def do_GET(req, res)
|
||||
rtn = super
|
||||
validate_and_ensure_charset(req, res)
|
||||
res.header.merge!(@headers)
|
||||
rtn
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
private
|
||||
def validate_and_ensure_charset(_req, res)
|
||||
key = res.header.keys.grep(/content-type/i).first
|
||||
typ = res.header[key]
|
||||
|
||||
unless typ =~ /;\s*charset=/
|
||||
res.header[key] = "#{typ}; charset=#{@jekyll_opts["encoding"]}"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
private
|
||||
def set_defaults
|
||||
hash_ = @jekyll_opts.fetch("webrick", {}).fetch("headers", {})
|
||||
DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|
|
||||
hash[key] = val unless hash.key?(key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
module Jekyll
|
||||
class Configuration < Hash
|
||||
|
||||
# Default options. Overridden by values in _config.yml.
|
||||
# Strings rather than symbols are used for compatibility with YAML.
|
||||
DEFAULTS = Configuration[{
|
||||
@@ -19,7 +18,7 @@ module Jekyll
|
||||
'safe' => false,
|
||||
'include' => ['.htaccess'],
|
||||
'exclude' => [],
|
||||
'keep_files' => ['.git','.svn'],
|
||||
'keep_files' => ['.git', '.svn'],
|
||||
'encoding' => 'utf-8',
|
||||
'markdown_ext' => 'markdown,mkdown,mkdn,mkd,md',
|
||||
|
||||
@@ -45,6 +44,7 @@ module Jekyll
|
||||
'port' => '4000',
|
||||
'host' => '127.0.0.1',
|
||||
'baseurl' => '',
|
||||
'show_dir_listing' => false,
|
||||
|
||||
# Output Configuration
|
||||
'permalink' => 'date',
|
||||
@@ -65,20 +65,12 @@ module Jekyll
|
||||
|
||||
'kramdown' => {
|
||||
'auto_ids' => true,
|
||||
'footnote_nr' => 1,
|
||||
'entity_output' => 'as_char',
|
||||
'toc_levels' => '1..6',
|
||||
'entity_output' => 'as_char',
|
||||
'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
|
||||
'enable_coderay' => false,
|
||||
|
||||
'coderay' => {
|
||||
'coderay_wrap' => 'div',
|
||||
'coderay_line_numbers' => 'inline',
|
||||
'coderay_line_number_start' => 1,
|
||||
'coderay_tab_width' => 4,
|
||||
'coderay_bold_every' => 10,
|
||||
'coderay_css' => 'style'
|
||||
}
|
||||
'input' => "GFM",
|
||||
'hard_wrap' => false,
|
||||
'footnote_nr' => 1
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -86,7 +78,7 @@ module Jekyll
|
||||
#
|
||||
# Return a copy of the hash where all its keys are strings
|
||||
def stringify_keys
|
||||
reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
|
||||
reduce({}) { |hsh, (k, v)| hsh.merge(k.to_s => v) }
|
||||
end
|
||||
|
||||
def get_config_value_with_override(config_key, override)
|
||||
@@ -118,7 +110,7 @@ module Jekyll
|
||||
Jekyll::External.require_with_graceful_fail('toml') unless defined?(TOML)
|
||||
TOML.load_file(filename)
|
||||
when /\.ya?ml/i
|
||||
SafeYAML.load_file(filename)
|
||||
SafeYAML.load_file(filename) || {}
|
||||
else
|
||||
raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
|
||||
end
|
||||
@@ -136,7 +128,7 @@ module Jekyll
|
||||
# Get configuration from <source>/_config.yml or <source>/<config_file>
|
||||
config_files = override.delete('config')
|
||||
if config_files.to_s.empty?
|
||||
default = %w[yml yaml].find(Proc.new { 'yml' }) do |ext|
|
||||
default = %w(yml yaml).find(-> { 'yml' }) do |ext|
|
||||
File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}"))
|
||||
end
|
||||
config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
|
||||
@@ -153,11 +145,11 @@ module Jekyll
|
||||
# Returns this configuration, overridden by the values in the file
|
||||
def read_config_file(file)
|
||||
next_config = safe_load_file(file)
|
||||
raise ArgumentError.new("Configuration file: (INVALID) #{file}".yellow) unless next_config.is_a?(Hash)
|
||||
check_config_is_hash!(next_config, file)
|
||||
Jekyll.logger.info "Configuration file:", file
|
||||
next_config
|
||||
rescue SystemCallError
|
||||
if @default_config_file
|
||||
if @default_config_file ||= nil
|
||||
Jekyll.logger.warn "Configuration file:", "none"
|
||||
{}
|
||||
else
|
||||
@@ -181,7 +173,7 @@ module Jekyll
|
||||
configuration = Utils.deep_merge_hashes(configuration, new_config)
|
||||
end
|
||||
rescue ArgumentError => err
|
||||
Jekyll.logger.warn "WARNING:", "Error reading configuration. " +
|
||||
Jekyll.logger.warn "WARNING:", "Error reading configuration. " \
|
||||
"Using defaults (and options)."
|
||||
$stderr.puts "#{err}"
|
||||
end
|
||||
@@ -206,16 +198,16 @@ module Jekyll
|
||||
config = clone
|
||||
# Provide backwards-compatibility
|
||||
if config.key?('auto') || config.key?('watch')
|
||||
Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" +
|
||||
" be set from your configuration file(s). Use the"+
|
||||
Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" \
|
||||
" be set from your configuration file(s). Use the"\
|
||||
" --[no-]watch/-w command-line option instead."
|
||||
config.delete('auto')
|
||||
config.delete('watch')
|
||||
end
|
||||
|
||||
if config.key? 'server'
|
||||
Jekyll::Deprecator.deprecation_message "The 'server' configuration option" +
|
||||
" is no longer accepted. Use the 'jekyll serve'" +
|
||||
Jekyll::Deprecator.deprecation_message "The 'server' configuration option" \
|
||||
" is no longer accepted. Use the 'jekyll serve'" \
|
||||
" subcommand to serve your site with WEBrick."
|
||||
config.delete('server')
|
||||
end
|
||||
@@ -226,20 +218,21 @@ module Jekyll
|
||||
renamed_key 'data_source', 'data_dir', config
|
||||
|
||||
if config.key? 'pygments'
|
||||
Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" +
|
||||
" has been renamed to 'highlighter'. Please update your" +
|
||||
" config file accordingly. The allowed values are 'rouge', " +
|
||||
Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" \
|
||||
" has been renamed to 'highlighter'. Please update your" \
|
||||
" config file accordingly. The allowed values are 'rouge', " \
|
||||
"'pygments' or null."
|
||||
|
||||
config['highlighter'] = 'pygments' if config['pygments']
|
||||
config.delete('pygments')
|
||||
end
|
||||
|
||||
%w[include exclude].each do |option|
|
||||
if config.fetch(option, []).is_a?(String)
|
||||
Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" +
|
||||
" must now be specified as an array, but you specified" +
|
||||
" a string. For now, we've treated the string you provided" +
|
||||
%w(include exclude).each do |option|
|
||||
config[option] ||= []
|
||||
if config[option].is_a?(String)
|
||||
Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" \
|
||||
" must now be specified as an array, but you specified" \
|
||||
" a string. For now, we've treated the string you provided" \
|
||||
" as a list of comma-separated values."
|
||||
config[option] = csv_to_array(config[option])
|
||||
end
|
||||
@@ -247,16 +240,16 @@ module Jekyll
|
||||
end
|
||||
|
||||
if (config['kramdown'] || {}).key?('use_coderay')
|
||||
Jekyll::Deprecator.deprecation_message "Please change 'use_coderay'" +
|
||||
Jekyll::Deprecator.deprecation_message "Please change 'use_coderay'" \
|
||||
" to 'enable_coderay' in your configuration file."
|
||||
config['kramdown']['use_coderay'] = config['kramdown'].delete('enable_coderay')
|
||||
end
|
||||
|
||||
if config.fetch('markdown', 'kramdown').to_s.downcase.eql?("maruku")
|
||||
Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " +
|
||||
"Markdown processor, which has been removed as of 3.0.0. " +
|
||||
"We recommend you switch to Kramdown. To do this, replace " +
|
||||
"`markdown: maruku` with `markdown: kramdown` in your " +
|
||||
Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " \
|
||||
"Markdown processor, which has been removed as of 3.0.0. " \
|
||||
"We recommend you switch to Kramdown. To do this, replace " \
|
||||
"`markdown: maruku` with `markdown: kramdown` in your " \
|
||||
"`_config.yml` file."
|
||||
end
|
||||
|
||||
@@ -267,7 +260,7 @@ module Jekyll
|
||||
config = clone
|
||||
|
||||
if config.key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
|
||||
Jekyll.logger.warn "Config Warning:", "The `paginate` key must be a" +
|
||||
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
|
||||
end
|
||||
@@ -281,7 +274,7 @@ module Jekyll
|
||||
return config if config['collections'].nil?
|
||||
|
||||
if config['collections'].is_a?(Array)
|
||||
config['collections'] = Hash[config['collections'].map{|c| [c, {}]}]
|
||||
config['collections'] = Hash[config['collections'].map { |c| [c, {}] }]
|
||||
end
|
||||
config['collections']['posts'] ||= {}
|
||||
config['collections']['posts']['output'] = true
|
||||
@@ -290,29 +283,42 @@ module Jekyll
|
||||
config
|
||||
end
|
||||
|
||||
def renamed_key(old, new, config, allowed_values = nil)
|
||||
def renamed_key(old, new, config, _ = nil)
|
||||
if config.key?(old)
|
||||
Jekyll::Deprecator.deprecation_message "The '#{old}' configuration" +
|
||||
"option has been renamed to '#{new}'. Please update your config " +
|
||||
Jekyll::Deprecator.deprecation_message "The '#{old}' configuration" \
|
||||
"option has been renamed to '#{new}'. Please update your config " \
|
||||
"file accordingly."
|
||||
config[new] = config.delete(old)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def style_to_permalink(permalink_style)
|
||||
case permalink_style.to_sym
|
||||
when :pretty
|
||||
"/:categories/:year/:month/:day/:title/"
|
||||
when :none
|
||||
"/:categories/:title.html"
|
||||
"/:categories/:title:output_ext"
|
||||
when :date
|
||||
"/:categories/:year/:month/:day/:title.html"
|
||||
"/:categories/:year/:month/:day/:title:output_ext"
|
||||
when :ordinal
|
||||
"/:categories/:year/:y_day/:title.html"
|
||||
"/:categories/:year/:y_day/:title:output_ext"
|
||||
else
|
||||
permalink_style.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Private: Checks if a given config is a hash
|
||||
#
|
||||
# extracted_config - the value to check
|
||||
# file - the file from which the config was extracted
|
||||
#
|
||||
# Raises an ArgumentError if given config is not a hash
|
||||
def check_config_is_hash!(extracted_config, file)
|
||||
unless extracted_config.is_a?(Hash)
|
||||
raise ArgumentError.new("Configuration file: (INVALID) #{file}".yellow)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,9 @@ module Jekyll
|
||||
#
|
||||
# Returns the String prefix.
|
||||
def self.highlighter_prefix(highlighter_prefix = nil)
|
||||
@highlighter_prefix = highlighter_prefix if highlighter_prefix
|
||||
if !defined?(@highlighter_prefix) || !highlighter_prefix.nil?
|
||||
@highlighter_prefix = highlighter_prefix
|
||||
end
|
||||
@highlighter_prefix
|
||||
end
|
||||
|
||||
@@ -20,7 +22,9 @@ module Jekyll
|
||||
#
|
||||
# Returns the String suffix.
|
||||
def self.highlighter_suffix(highlighter_suffix = nil)
|
||||
@highlighter_suffix = highlighter_suffix if highlighter_suffix
|
||||
if !defined?(@highlighter_suffix) || !highlighter_suffix.nil?
|
||||
@highlighter_suffix = highlighter_suffix
|
||||
end
|
||||
@highlighter_suffix
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ module Jekyll
|
||||
|
||||
priority :lowest
|
||||
|
||||
def matches(ext)
|
||||
def matches(_ext)
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
@@ -1,57 +1,62 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown < Converter
|
||||
safe true
|
||||
|
||||
highlighter_prefix "\n"
|
||||
highlighter_suffix "\n"
|
||||
safe true
|
||||
|
||||
def setup
|
||||
return if @setup
|
||||
@parser =
|
||||
case @config['markdown'].downcase
|
||||
when 'redcarpet' then RedcarpetParser.new(@config)
|
||||
when 'kramdown' then KramdownParser.new(@config)
|
||||
when 'rdiscount' then RDiscountParser.new(@config)
|
||||
else
|
||||
# So they can't try some tricky bullshit or go down the ancestor chain, I hope.
|
||||
if allowed_custom_class?(@config['markdown'])
|
||||
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
|
||||
return if @setup ||= false
|
||||
unless (@parser = get_processor)
|
||||
Jekyll.logger.error "Invalid Markdown processor given:", @config["markdown"]
|
||||
Jekyll.logger.info "", "Custom processors are not loaded in safe mode" if @config["safe"]
|
||||
Jekyll.logger.error "", "Available processors are: #{valid_processors.join(", ")}"
|
||||
raise Errors::FatalException, "Bailing out; invalid Markdown processor."
|
||||
end
|
||||
|
||||
@setup = true
|
||||
end
|
||||
|
||||
def valid_processors
|
||||
%w[
|
||||
rdiscount
|
||||
kramdown
|
||||
redcarpet
|
||||
] + third_party_processors
|
||||
def get_processor
|
||||
case @config["markdown"].downcase
|
||||
when "redcarpet" then return RedcarpetParser.new(@config)
|
||||
when "kramdown" then return KramdownParser.new(@config)
|
||||
when "rdiscount" then return RDiscountParser.new(@config)
|
||||
else
|
||||
get_custom_processor
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Provides you with a list of processors, the ones we
|
||||
# support internally and the ones that you have provided to us (if you
|
||||
# are not in safe mode.)
|
||||
|
||||
def valid_processors
|
||||
%W(rdiscount kramdown redcarpet) + third_party_processors
|
||||
end
|
||||
|
||||
# Public: A list of processors that you provide via plugins.
|
||||
# This is really only available if you are not in safe mode, if you are
|
||||
# in safe mode (re: GitHub) then there will be none.
|
||||
|
||||
def third_party_processors
|
||||
self.class.constants - %w[
|
||||
KramdownParser
|
||||
RDiscountParser
|
||||
RedcarpetParser
|
||||
PRIORITIES
|
||||
].map(&:to_sym)
|
||||
self.class.constants - \
|
||||
%w(KramdownParser RDiscountParser RedcarpetParser PRIORITIES).map(
|
||||
&:to_sym
|
||||
)
|
||||
end
|
||||
|
||||
def extname_list
|
||||
@extname_list ||= @config['markdown_ext'].split(',').map { |e| ".#{e.downcase}" }
|
||||
@extname_list ||= @config['markdown_ext'].split(',').map do |e|
|
||||
".#{e.downcase}"
|
||||
end
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
extname_list.include? ext.downcase
|
||||
extname_list.include?(ext.downcase)
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
def output_ext(_ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
@@ -61,16 +66,26 @@ module Jekyll
|
||||
end
|
||||
|
||||
private
|
||||
def get_custom_processor
|
||||
converter_name = @config["markdown"]
|
||||
if custom_class_allowed?(converter_name)
|
||||
self.class.const_get(converter_name).new(@config)
|
||||
end
|
||||
end
|
||||
|
||||
# Private: Determine whether a class name is an allowed custom markdown
|
||||
# class name
|
||||
# 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)
|
||||
# Returns true if the parser name contains only alphanumeric
|
||||
# characters and is defined within Jekyll::Converters::Markdown
|
||||
|
||||
private
|
||||
def custom_class_allowed?(parser_name)
|
||||
parser_name !~ /[^A-Za-z0-9_]/ && self.class.constants.include?(
|
||||
parser_name.to_sym
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,33 +1,117 @@
|
||||
# Frozen-string-literal: true
|
||||
# Encoding: utf-8
|
||||
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown
|
||||
class KramdownParser
|
||||
CODERAY_DEFAULTS = {
|
||||
"css" => "style",
|
||||
"bold_every" => 10,
|
||||
"line_numbers" => "inline",
|
||||
"line_number_start" => 1,
|
||||
"tab_width" => 4,
|
||||
"wrap" => "div"
|
||||
}.freeze
|
||||
|
||||
def initialize(config)
|
||||
require 'kramdown'
|
||||
@config = config
|
||||
# If kramdown supported highlighter enabled, use that
|
||||
highlighter = @config['highlighter']
|
||||
if highlighter == 'rouge' || highlighter == 'coderay'
|
||||
@config['kramdown']['syntax_highlighter'] ||= highlighter
|
||||
end
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install kramdown'
|
||||
raise Errors::FatalException.new("Missing dependency: kramdown")
|
||||
Jekyll::External.require_with_graceful_fail "kramdown"
|
||||
@main_fallback_highlighter = config["highlighter"] || "rouge"
|
||||
@config = config["kramdown"] || {}
|
||||
@highlighter = nil
|
||||
setup
|
||||
end
|
||||
|
||||
# Setup and normalize the configuration:
|
||||
# * Create Kramdown if it doesn't exist.
|
||||
# * Set syntax_highlighter, detecting enable_coderay and merging highlighter if none.
|
||||
# * Merge kramdown[coderay] into syntax_highlighter_opts stripping coderay_.
|
||||
# * Make sure `syntax_highlighter_opts` exists.
|
||||
|
||||
def setup
|
||||
@config["syntax_highlighter"] ||= highlighter
|
||||
@config["syntax_highlighter_opts"] ||= {}
|
||||
@config["coderay"] ||= {} # XXX: Legacy.
|
||||
modernize_coderay_config
|
||||
make_accessible
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
# Check for use of coderay
|
||||
if @config['kramdown']['enable_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'].key?(key)
|
||||
end
|
||||
end
|
||||
|
||||
Kramdown::Document.new(content, Utils.symbolize_hash_keys(@config['kramdown'])).to_html
|
||||
Kramdown::Document.new(content, @config).to_html
|
||||
end
|
||||
|
||||
private
|
||||
def make_accessible(hash = @config)
|
||||
proc_ = proc { |hash_, key| hash_[key.to_s] if key.is_a?(Symbol) }
|
||||
hash.default_proc = proc_
|
||||
|
||||
hash.each do |_, val|
|
||||
make_accessible val if val.is_a?(
|
||||
Hash
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# config[kramdown][syntax_higlighter] > config[kramdown][enable_coderay] > config[highlighter]
|
||||
# Where `enable_coderay` is now deprecated because Kramdown
|
||||
# supports Rouge now too.
|
||||
|
||||
private
|
||||
def highlighter
|
||||
return @highlighter if @highlighter
|
||||
|
||||
if @config["syntax_highlighter"]
|
||||
return @highlighter = @config[
|
||||
"syntax_highlighter"
|
||||
]
|
||||
end
|
||||
|
||||
@highlighter = begin
|
||||
if @config.key?("enable_coderay") && @config["enable_coderay"]
|
||||
Jekyll::Deprecator.deprecation_message "You are using 'enable_coderay', " \
|
||||
"use syntax_highlighter: coderay in your configuration file."
|
||||
|
||||
"coderay"
|
||||
else
|
||||
@main_fallback_highlighter
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def strip_coderay_prefix(hash)
|
||||
hash.each_with_object({}) do |(key, val), hsh|
|
||||
cleaned_key = key.gsub(/\Acoderay_/, "")
|
||||
|
||||
if key != cleaned_key
|
||||
Jekyll::Deprecator.deprecation_message(
|
||||
"You are using '#{key}'. Normalizing to #{cleaned_key}."
|
||||
)
|
||||
end
|
||||
|
||||
hsh[cleaned_key] = val
|
||||
end
|
||||
end
|
||||
|
||||
# If our highlighter is CodeRay we go in to merge the CodeRay defaults
|
||||
# with your "coderay" key if it's there, deprecating it in the
|
||||
# process of you using it.
|
||||
|
||||
private
|
||||
def modernize_coderay_config
|
||||
if highlighter == "coderay"
|
||||
Jekyll::Deprecator.deprecation_message "You are using 'kramdown.coderay' in your configuration, " \
|
||||
"please use 'syntax_highlighter_opts' instead."
|
||||
|
||||
@config["syntax_highlighter_opts"] = begin
|
||||
strip_coderay_prefix(
|
||||
@config["syntax_highlighter_opts"] \
|
||||
.merge(CODERAY_DEFAULTS) \
|
||||
.merge(@config["coderay"])
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ module Jekyll
|
||||
def initialize(config)
|
||||
Jekyll::External.require_with_graceful_fail "rdiscount"
|
||||
@config = config
|
||||
@rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym }
|
||||
@rdiscount_extensions = @config['rdiscount']['extensions'].map(&:to_sym)
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
|
||||
@@ -2,12 +2,12 @@ module Jekyll
|
||||
module Converters
|
||||
class Markdown
|
||||
class RedcarpetParser
|
||||
|
||||
module CommonMethods
|
||||
def add_code_tags(code, lang)
|
||||
code = code.to_s
|
||||
code = code.sub(/<pre>/, "<pre><code class=\"language-#{lang}\" data-lang=\"#{lang}\">")
|
||||
code = code.sub(/<\/pre>/,"</code></pre>")
|
||||
code = code.sub(/<\/pre>/, "</code></pre>")
|
||||
code
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,12 +48,11 @@ module Jekyll
|
||||
end
|
||||
|
||||
protected
|
||||
def rouge_formatter(lexer)
|
||||
def rouge_formatter(_lexer)
|
||||
Rouge::Formatters::HTML.new(:wrap => false)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def initialize(config)
|
||||
External.require_with_graceful_fail("redcarpet")
|
||||
@config = config
|
||||
@@ -71,10 +70,10 @@ module Jekyll
|
||||
end
|
||||
when "rouge"
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
Jekyll::External.require_with_graceful_fail(%w[
|
||||
Jekyll::External.require_with_graceful_fail(%w(
|
||||
rouge
|
||||
rouge/plugins/redcarpet
|
||||
])
|
||||
))
|
||||
|
||||
unless Gem::Version.new(Rouge.version) > Gem::Version.new("1.3.0")
|
||||
abort "Please install Rouge 1.3.0 or greater and try running Jekyll again."
|
||||
|
||||
34
lib/jekyll/converters/smartypants.rb
Normal file
34
lib/jekyll/converters/smartypants.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
class Kramdown::Parser::SmartyPants < Kramdown::Parser::Kramdown
|
||||
def initialize(source, options)
|
||||
super
|
||||
@block_parsers = [:block_html]
|
||||
@span_parsers = [:smart_quotes, :html_entity, :typographic_syms, :span_html]
|
||||
end
|
||||
end
|
||||
|
||||
module Jekyll
|
||||
module Converters
|
||||
class SmartyPants < Converter
|
||||
safe true
|
||||
priority :low
|
||||
|
||||
def initialize(config)
|
||||
Jekyll::External.require_with_graceful_fail "kramdown"
|
||||
@config = config["kramdown"].dup || {}
|
||||
@config[:input] = :SmartyPants
|
||||
end
|
||||
|
||||
def matches(_)
|
||||
false
|
||||
end
|
||||
|
||||
def output_ext(_)
|
||||
nil
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
Kramdown::Document.new(content, @config).to_html.chomp
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -28,12 +28,6 @@ module Jekyll
|
||||
!(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)
|
||||
(site ? site.file_read_opts : {}).merge(opts)
|
||||
end
|
||||
|
||||
# Read the YAML frontmatter.
|
||||
#
|
||||
# base - The String path to the dir containing the file.
|
||||
@@ -42,28 +36,41 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_yaml(base, name, opts = {})
|
||||
filename = File.join(base, name)
|
||||
|
||||
begin
|
||||
self.content = File.read(site.in_source_dir(base, name),
|
||||
merged_file_read_opts(opts))
|
||||
Utils.merged_file_read_opts(site, opts))
|
||||
if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
|
||||
self.content = $POSTMATCH
|
||||
self.data = SafeYAML.load($1)
|
||||
self.data = SafeYAML.load(Regexp.last_match(1))
|
||||
end
|
||||
rescue SyntaxError => e
|
||||
Jekyll.logger.warn "YAML Exception reading #{File.join(base, name)}: #{e.message}"
|
||||
Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
|
||||
rescue Exception => e
|
||||
Jekyll.logger.warn "Error reading file #{File.join(base, name)}: #{e.message}"
|
||||
Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
|
||||
end
|
||||
|
||||
self.data ||= {}
|
||||
|
||||
unless self.data.is_a?(Hash)
|
||||
Jekyll.logger.abort_with "Fatal:", "Invalid YAML front matter in #{File.join(base, name)}"
|
||||
end
|
||||
validate_data! filename
|
||||
validate_permalink! filename
|
||||
|
||||
self.data
|
||||
end
|
||||
|
||||
def validate_data!(filename)
|
||||
unless self.data.is_a?(Hash)
|
||||
raise Errors::InvalidYAMLFrontMatterError, "Invalid YAML front matter in #{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
def validate_permalink!(filename)
|
||||
if self.data['permalink'] && self.data['permalink'].size == 0
|
||||
raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
# Transform the contents based on the content type.
|
||||
#
|
||||
# Returns the transformed contents.
|
||||
@@ -84,13 +91,7 @@ module Jekyll
|
||||
# Returns the String extension for the output file.
|
||||
# e.g. ".html" for an HTML output file.
|
||||
def output_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
|
||||
Jekyll::Renderer.new(site, self).output_ext
|
||||
end
|
||||
|
||||
# Determine which converter to use based on this convertible's
|
||||
@@ -122,9 +123,9 @@ module Jekyll
|
||||
#
|
||||
# Returns the Hash representation of this Convertible.
|
||||
def to_liquid(attrs = nil)
|
||||
further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map { |attribute|
|
||||
further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map do |attribute|
|
||||
[attribute, send(attribute)]
|
||||
}]
|
||||
end]
|
||||
|
||||
defaults = site.frontmatter_defaults.all(relative_path, type)
|
||||
Utils.deep_merge_hashes defaults, Utils.deep_merge_hashes(data, further_data)
|
||||
@@ -160,7 +161,7 @@ module Jekyll
|
||||
#
|
||||
# Returns true if extname == .sass or .scss, false otherwise.
|
||||
def sass_file?
|
||||
%w[.sass .scss].include?(ext)
|
||||
%w(.sass .scss).include?(ext)
|
||||
end
|
||||
|
||||
# Determine whether the document is a CoffeeScript file.
|
||||
@@ -210,7 +211,8 @@ module Jekyll
|
||||
|
||||
while layout
|
||||
Jekyll.logger.debug "Rendering Layout:", path
|
||||
payload = Utils.deep_merge_hashes(payload, {"content" => output, "page" => layout.data})
|
||||
payload["content"] = output
|
||||
payload["layout"] = Utils.deep_merge_hashes(payload["layout"] || {}, layout.data)
|
||||
|
||||
self.output = render_liquid(layout.content,
|
||||
payload,
|
||||
@@ -235,7 +237,7 @@ module Jekyll
|
||||
|
||||
# Add any necessary layouts to this convertible document.
|
||||
#
|
||||
# payload - The site payload Hash.
|
||||
# payload - The site payload Drop or Hash.
|
||||
# layouts - A Hash of {"name" => "layout"}.
|
||||
#
|
||||
# Returns nothing.
|
||||
@@ -244,7 +246,7 @@ module Jekyll
|
||||
|
||||
Jekyll.logger.debug "Pre-Render Hooks:", self.relative_path
|
||||
Jekyll::Hooks.trigger hook_owner, :pre_render, self, payload
|
||||
info = { :filters => [Jekyll::Filters], :registers => { :site => site, :page => payload['page'] } }
|
||||
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
|
||||
|
||||
@@ -21,8 +21,8 @@ module Jekyll
|
||||
end
|
||||
|
||||
def no_subcommand(args)
|
||||
if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first)
|
||||
deprecation_message "Jekyll now uses subcommands instead of just switches. Run `jekyll --help` to find out more."
|
||||
if args.size > 0 && args.first =~ /^--/ && !%w(--help --version).include?(args.first)
|
||||
deprecation_message "Jekyll now uses subcommands instead of just switches. Run `jekyll help` to find out more."
|
||||
abort
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,23 +4,25 @@ module Jekyll
|
||||
class Document
|
||||
include Comparable
|
||||
|
||||
attr_reader :path, :site, :extname, :output_ext, :content, :output, :collection
|
||||
attr_reader :path, :site, :extname, :collection
|
||||
attr_accessor :content, :output
|
||||
|
||||
YAML_FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
|
||||
DATELESS_FILENAME_MATCHER = /^(.*)(\.[^.]+)$/
|
||||
DATELESS_FILENAME_MATCHER = /^(.+\/)*(.*)(\.[^.]+)$/
|
||||
DATE_FILENAME_MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
||||
|
||||
# Create a new Document.
|
||||
#
|
||||
# site - the Jekyll::Site instance to which this Document belongs
|
||||
# path - the path to the file
|
||||
# relations - a hash with keys :site and :collection, the values of which
|
||||
# are the Jekyll::Site and Jekyll::Collection to which this
|
||||
# Document belong.
|
||||
#
|
||||
# Returns nothing.
|
||||
def initialize(path, relations)
|
||||
def initialize(path, relations = {})
|
||||
@site = relations[:site]
|
||||
@path = path
|
||||
@extname = File.extname(path)
|
||||
@output_ext = Jekyll::Renderer.new(site, self).output_ext
|
||||
@collection = relations[:collection]
|
||||
@has_yaml_header = nil
|
||||
|
||||
@@ -30,29 +32,19 @@ module Jekyll
|
||||
categories_from_path(collection.relative_directory)
|
||||
end
|
||||
|
||||
data.default_proc = proc do |hash, key|
|
||||
data.default_proc = proc do |_, key|
|
||||
site.frontmatter_defaults.find(relative_path, collection.label, key)
|
||||
end
|
||||
|
||||
trigger_hooks(:post_init)
|
||||
end
|
||||
|
||||
def output=(output)
|
||||
@to_liquid = nil
|
||||
@output = output
|
||||
end
|
||||
|
||||
def content=(content)
|
||||
@to_liquid = nil
|
||||
@content = content
|
||||
end
|
||||
|
||||
# Fetch the Document's data.
|
||||
#
|
||||
# Returns a Hash containing the data. An empty hash is returned if
|
||||
# no data was read.
|
||||
def data
|
||||
@data ||= Hash.new
|
||||
@data ||= {}
|
||||
end
|
||||
|
||||
# Merge some data in with this document's data.
|
||||
@@ -67,13 +59,20 @@ module Jekyll
|
||||
end
|
||||
Utils.deep_merge_hashes!(data, other)
|
||||
if data.key?('date') && !data['date'].is_a?(Time)
|
||||
data['date'] = Utils.parse_date(data['date'].to_s, "Document '#{relative_path}' does not have a valid date in the #{source}.")
|
||||
data['date'] = Utils.parse_date(
|
||||
data['date'].to_s,
|
||||
"Document '#{relative_path}' does not have a valid date in the #{source}."
|
||||
)
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
def date
|
||||
data['date'] ||= site.time
|
||||
data['date'] ||= (draft? ? source_file_mtime : site.time)
|
||||
end
|
||||
|
||||
def source_file_mtime
|
||||
@source_file_mtime ||= File.mtime(path)
|
||||
end
|
||||
|
||||
# Returns whether the document is a draft. This is only the case if
|
||||
@@ -93,6 +92,13 @@ module Jekyll
|
||||
@relative_path ||= Pathname.new(path).relative_path_from(Pathname.new(site.source)).to_s
|
||||
end
|
||||
|
||||
# The output extension of the document.
|
||||
#
|
||||
# Returns the output extension
|
||||
def output_ext
|
||||
Jekyll::Renderer.new(site, self).output_ext
|
||||
end
|
||||
|
||||
# The base filename of the document, without the file extname.
|
||||
#
|
||||
# Returns the basename without the file extname.
|
||||
@@ -120,14 +126,14 @@ module Jekyll
|
||||
# Returns the cleaned relative path of the document.
|
||||
def cleaned_relative_path
|
||||
@cleaned_relative_path ||=
|
||||
relative_path[0 .. -extname.length - 1].sub(collection.relative_directory, "")
|
||||
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)
|
||||
%w(.yaml .yml).include?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the document is an asset file.
|
||||
@@ -143,7 +149,7 @@ module Jekyll
|
||||
#
|
||||
# Returns true if extname == .sass or .scss, false otherwise.
|
||||
def sass_file?
|
||||
%w[.sass .scss].include?(extname)
|
||||
%w(.sass .scss).include?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the document is a CoffeeScript file.
|
||||
@@ -181,27 +187,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the Hash of key-value pairs for replacement in the URL.
|
||||
def url_placeholders
|
||||
{
|
||||
collection: collection.label,
|
||||
path: cleaned_relative_path,
|
||||
output_ext: output_ext,
|
||||
name: Utils.slugify(basename_without_ext),
|
||||
title: Utils.slugify(data['slug'], mode: "pretty", cased: true) || Utils
|
||||
.slugify(basename_without_ext, mode: "pretty", cased: true),
|
||||
slug: Utils.slugify(data['slug']) || Utils.slugify(basename_without_ext),
|
||||
year: date.strftime("%Y"),
|
||||
month: date.strftime("%m"),
|
||||
day: date.strftime("%d"),
|
||||
hour: date.strftime("%H"),
|
||||
minute: date.strftime("%M"),
|
||||
second: date.strftime("%S"),
|
||||
i_day: date.strftime("%-d"),
|
||||
i_month: date.strftime("%-m"),
|
||||
categories: (data['categories'] || []).map { |c| c.to_s.downcase }.uniq.join('/'),
|
||||
short_month: date.strftime("%b"),
|
||||
short_year: date.strftime("%y"),
|
||||
y_day: date.strftime("%j"),
|
||||
}
|
||||
@url_placeholders ||= Drops::UrlDrop.new(self)
|
||||
end
|
||||
|
||||
# The permalink for this Document.
|
||||
@@ -217,9 +203,9 @@ module Jekyll
|
||||
# Returns the computed URL for the document.
|
||||
def url
|
||||
@url = URL.new({
|
||||
template: url_template,
|
||||
placeholders: url_placeholders,
|
||||
permalink: permalink
|
||||
:template => url_template,
|
||||
:placeholders => url_placeholders,
|
||||
:permalink => permalink
|
||||
}).to_s
|
||||
end
|
||||
|
||||
@@ -235,8 +221,11 @@ module Jekyll
|
||||
def destination(base_directory)
|
||||
dest = site.in_dest_dir(base_directory)
|
||||
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if url.end_with?("/")
|
||||
path << output_ext unless path.end_with?(output_ext)
|
||||
if url.end_with? "/"
|
||||
path = File.join(path, "index.html")
|
||||
else
|
||||
path << output_ext unless path.end_with? output_ext
|
||||
end
|
||||
path
|
||||
end
|
||||
|
||||
@@ -255,16 +244,6 @@ module Jekyll
|
||||
trigger_hooks(:post_write)
|
||||
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`.
|
||||
@@ -278,8 +257,6 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read(opts = {})
|
||||
@to_liquid = nil
|
||||
|
||||
Jekyll.logger.debug "Reading:", relative_path
|
||||
|
||||
if yaml_file?
|
||||
@@ -289,10 +266,10 @@ module Jekyll
|
||||
defaults = @site.frontmatter_defaults.all(url, collection.label.to_sym)
|
||||
merge_data!(defaults, source: "front matter defaults") unless defaults.empty?
|
||||
|
||||
self.content = File.read(path, merged_file_read_opts(opts))
|
||||
self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
|
||||
if content =~ YAML_FRONT_MATTER_REGEXP
|
||||
self.content = $POSTMATCH
|
||||
data_file = SafeYAML.load($1)
|
||||
data_file = SafeYAML.load(Regexp.last_match(1))
|
||||
merge_data!(data_file, source: "YAML front matter") if data_file
|
||||
end
|
||||
|
||||
@@ -309,23 +286,24 @@ module Jekyll
|
||||
end
|
||||
|
||||
def post_read
|
||||
if DATE_FILENAME_MATCHER =~ relative_path
|
||||
m, cats, date, slug, ext = *relative_path.match(DATE_FILENAME_MATCHER)
|
||||
merge_data!({
|
||||
"slug" => slug,
|
||||
"ext" => ext
|
||||
}, source: "filename")
|
||||
if data['date'].nil? || data['date'].to_i == site.time.to_i
|
||||
if relative_path =~ DATE_FILENAME_MATCHER
|
||||
date, slug, ext = $2, $3, $4
|
||||
if !data['date'] || data['date'].to_i == site.time.to_i
|
||||
merge_data!({"date" => date}, source: "filename")
|
||||
end
|
||||
data['title'] ||= slug.split('-').select {|w| w.capitalize! || w }.join(' ')
|
||||
elsif relative_path =~ DATELESS_FILENAME_MATCHER
|
||||
slug, ext = $2, $3
|
||||
end
|
||||
|
||||
# Try to ensure the user gets a title.
|
||||
data["title"] ||= Utils.titleize_slug(slug)
|
||||
# Only overwrite slug & ext if they aren't specified.
|
||||
data['slug'] ||= slug
|
||||
data['ext'] ||= ext
|
||||
|
||||
populate_categories
|
||||
populate_tags
|
||||
|
||||
if generate_excerpt?
|
||||
data['excerpt'] ||= Jekyll::Excerpt.new(self)
|
||||
end
|
||||
generate_excerpt
|
||||
end
|
||||
|
||||
# Add superdirectories of the special_dir to categories.
|
||||
@@ -344,7 +322,7 @@ module Jekyll
|
||||
merge_data!({
|
||||
'categories' => (
|
||||
Array(data['categories']) + Utils.pluralized_array_from_hash(data, 'category', 'categories')
|
||||
).map { |c| c.to_s }.flatten.uniq
|
||||
).map(&:to_s).flatten.uniq
|
||||
})
|
||||
end
|
||||
|
||||
@@ -358,21 +336,7 @@ module Jekyll
|
||||
#
|
||||
# Returns a Hash representing this Document's data.
|
||||
def to_liquid
|
||||
@to_liquid ||= if data.is_a?(Hash)
|
||||
Utils.deep_merge_hashes Utils.deep_merge_hashes({
|
||||
"output" => output,
|
||||
"content" => content,
|
||||
"relative_path" => relative_path,
|
||||
"path" => relative_path,
|
||||
"url" => url,
|
||||
"collection" => collection.label,
|
||||
"next" => next_doc,
|
||||
"previous" => previous_doc,
|
||||
"id" => id,
|
||||
}, data), { 'excerpt' => data['excerpt'].to_s }
|
||||
else
|
||||
data
|
||||
end
|
||||
@to_liquid ||= Drops::DocumentDrop.new(self)
|
||||
end
|
||||
|
||||
# The inspect string for this document.
|
||||
@@ -396,9 +360,9 @@ module Jekyll
|
||||
# Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
|
||||
# equal or greater than the other doc's path. See String#<=> for more details.
|
||||
def <=>(other)
|
||||
return nil if !other.respond_to?(:data)
|
||||
return nil unless other.respond_to?(:data)
|
||||
cmp = data['date'] <=> other.data['date']
|
||||
cmp = path <=> other.path if cmp == 0
|
||||
cmp = path <=> other.path if cmp.nil? || cmp == 0
|
||||
cmp
|
||||
end
|
||||
|
||||
@@ -427,7 +391,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
def next_doc
|
||||
pos = collection.docs.index {|post| post.equal?(self) }
|
||||
pos = collection.docs.index { |post| post.equal?(self) }
|
||||
if pos && pos < collection.docs.length - 1
|
||||
collection.docs[pos + 1]
|
||||
else
|
||||
@@ -436,7 +400,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
def previous_doc
|
||||
pos = collection.docs.index {|post| post.equal?(self) }
|
||||
pos = collection.docs.index { |post| post.equal?(self) }
|
||||
if pos && pos > 0
|
||||
collection.docs[pos - 1]
|
||||
else
|
||||
@@ -476,5 +440,12 @@ module Jekyll
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private # :nodoc:
|
||||
def generate_excerpt
|
||||
if generate_excerpt?
|
||||
data["excerpt"] ||= Jekyll::Excerpt.new(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
22
lib/jekyll/drops/collection_drop.rb
Normal file
22
lib/jekyll/drops/collection_drop.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class CollectionDrop < Drop
|
||||
extend Forwardable
|
||||
|
||||
mutable false
|
||||
|
||||
def_delegator :@obj, :write?, :output
|
||||
def_delegators :@obj, :label, :docs, :files, :directory,
|
||||
:relative_directory
|
||||
|
||||
def to_s
|
||||
docs.to_s
|
||||
end
|
||||
|
||||
private
|
||||
def_delegator :@obj, :metadata, :fallback_data
|
||||
end
|
||||
end
|
||||
end
|
||||
34
lib/jekyll/drops/document_drop.rb
Normal file
34
lib/jekyll/drops/document_drop.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class DocumentDrop < Drop
|
||||
extend Forwardable
|
||||
|
||||
mutable false
|
||||
|
||||
def_delegator :@obj, :next_doc, :next
|
||||
def_delegator :@obj, :previous_doc, :previous
|
||||
def_delegator :@obj, :relative_path, :path
|
||||
def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url
|
||||
|
||||
def collection
|
||||
@obj.collection.label
|
||||
end
|
||||
|
||||
def excerpt
|
||||
fallback_data['excerpt'].to_s
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
return nil unless other.is_a? DocumentDrop
|
||||
cmp = self['date'] <=> other['date']
|
||||
cmp = self['path'] <=> other['path'] if cmp.nil? || cmp == 0
|
||||
cmp
|
||||
end
|
||||
|
||||
private
|
||||
def_delegator :@obj, :data, :fallback_data
|
||||
end
|
||||
end
|
||||
end
|
||||
176
lib/jekyll/drops/drop.rb
Normal file
176
lib/jekyll/drops/drop.rb
Normal file
@@ -0,0 +1,176 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class Drop < Liquid::Drop
|
||||
NON_CONTENT_METHODS = [:[], :[]=, :inspect, :to_h, :fallback_data].freeze
|
||||
|
||||
# Get or set whether the drop class is mutable.
|
||||
# Mutability determines whether or not pre-defined fields may be
|
||||
# overwritten.
|
||||
#
|
||||
# is_mutable - Boolean set mutability of the class (default: nil)
|
||||
#
|
||||
# Returns the mutability of the class
|
||||
def self.mutable(is_mutable = nil)
|
||||
if is_mutable
|
||||
@is_mutable = is_mutable
|
||||
else
|
||||
@is_mutable = false
|
||||
end
|
||||
end
|
||||
|
||||
def self.mutable?
|
||||
@is_mutable
|
||||
end
|
||||
|
||||
# Create a new Drop
|
||||
#
|
||||
# obj - the Jekyll Site, Collection, or Document required by the
|
||||
# drop.
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(obj)
|
||||
@obj = obj
|
||||
@mutations = {} # only if mutable: true
|
||||
end
|
||||
|
||||
# Access a method in the Drop or a field in the underlying hash data.
|
||||
# If mutable, checks the mutations first. Then checks the methods,
|
||||
# and finally check the underlying hash (e.g. document front matter)
|
||||
# if all the previous places didn't match.
|
||||
#
|
||||
# key - the string key whose value to fetch
|
||||
#
|
||||
# Returns the value for the given key, or nil if none exists
|
||||
def [](key)
|
||||
if self.class.mutable? && @mutations.key?(key)
|
||||
@mutations[key]
|
||||
elsif self.class.invokable? key
|
||||
public_send key
|
||||
else
|
||||
fallback_data[key]
|
||||
end
|
||||
end
|
||||
|
||||
# Set a field in the Drop. If mutable, sets in the mutations and
|
||||
# returns. If not mutable, checks first if it's trying to override a
|
||||
# Drop method and raises a DropMutationException if so. If not
|
||||
# mutable and the key is not a method on the Drop, then it sets the
|
||||
# key to the value in the underlying hash (e.g. document front
|
||||
# matter)
|
||||
#
|
||||
# key - the String key whose value to set
|
||||
# val - the Object to set the key's value to
|
||||
#
|
||||
# Returns the value the key was set to unless the Drop is not mutable
|
||||
# and the key matches a method in which case it raises a
|
||||
# DropMutationException.
|
||||
def []=(key, val)
|
||||
if respond_to?("#{key}=")
|
||||
public_send("#{key}=", val)
|
||||
elsif respond_to? key
|
||||
if self.class.mutable?
|
||||
@mutations[key] = val
|
||||
else
|
||||
raise Errors::DropMutationException, "Key #{key} cannot be set in the drop."
|
||||
end
|
||||
else
|
||||
fallback_data[key] = val
|
||||
end
|
||||
end
|
||||
|
||||
# Generates a list of strings which correspond to content getter
|
||||
# methods.
|
||||
#
|
||||
# Returns an Array of strings which represent method-specific keys.
|
||||
def content_methods
|
||||
@content_methods ||= (
|
||||
self.class.instance_methods(false) - NON_CONTENT_METHODS
|
||||
).map(&:to_s).reject do |method|
|
||||
method.end_with?("=")
|
||||
end
|
||||
end
|
||||
|
||||
# Check if key exists in Drop
|
||||
#
|
||||
# key - the string key whose value to fetch
|
||||
#
|
||||
# Returns true if the given key is present
|
||||
def key?(key)
|
||||
if self.class.mutable && @mutations.key?(key)
|
||||
true
|
||||
else
|
||||
respond_to?(key) || fallback_data.key?(key)
|
||||
end
|
||||
end
|
||||
|
||||
# Generates a list of keys with user content as their values.
|
||||
# This gathers up the Drop methods and keys of the mutations and
|
||||
# underlying data hashes and performs a set union to ensure a list
|
||||
# of unique keys for the Drop.
|
||||
#
|
||||
# Returns an Array of unique keys for content for the Drop.
|
||||
def keys
|
||||
(content_methods |
|
||||
@mutations.keys |
|
||||
fallback_data.keys).flatten
|
||||
end
|
||||
|
||||
# Generate a Hash representation of the Drop by resolving each key's
|
||||
# value. It includes Drop methods, mutations, and the underlying object's
|
||||
# data. See the documentation for Drop#keys for more.
|
||||
#
|
||||
# Returns a Hash with all the keys and values resolved.
|
||||
def to_h
|
||||
keys.each_with_object({}) do |(key, _), result|
|
||||
result[key] = self[key]
|
||||
end
|
||||
end
|
||||
alias_method :to_hash, :to_h
|
||||
|
||||
# Inspect the drop's keys and values through a JSON representation
|
||||
# of its keys and values.
|
||||
#
|
||||
# Returns a pretty generation of the hash representation of the Drop.
|
||||
def inspect
|
||||
require 'json'
|
||||
JSON.pretty_generate to_h
|
||||
end
|
||||
|
||||
# Collects all the keys and passes each to the block in turn.
|
||||
#
|
||||
# block - a block which accepts one argument, the key
|
||||
#
|
||||
# Returns nothing.
|
||||
def each_key(&block)
|
||||
keys.each(&block)
|
||||
end
|
||||
|
||||
def merge(other, &block)
|
||||
self.dup.tap do |me|
|
||||
if block.nil?
|
||||
me.merge!(other)
|
||||
else
|
||||
me.merge!(other, block)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def merge!(other)
|
||||
other.each_key do |key|
|
||||
if block_given?
|
||||
self[key] = yield key, self[key], other[key]
|
||||
else
|
||||
if Utils.mergable?(self[key]) && Utils.mergable?(other[key])
|
||||
self[key] = Utils.deep_merge_hashes(self[key], other[key])
|
||||
next
|
||||
end
|
||||
|
||||
self[key] = other[key] unless other[key].nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
21
lib/jekyll/drops/jekyll_drop.rb
Normal file
21
lib/jekyll/drops/jekyll_drop.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class JekyllDrop < Liquid::Drop
|
||||
class << self
|
||||
def global
|
||||
@global ||= JekyllDrop.new
|
||||
end
|
||||
end
|
||||
|
||||
def version
|
||||
Jekyll::VERSION
|
||||
end
|
||||
|
||||
def environment
|
||||
Jekyll.env
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
38
lib/jekyll/drops/site_drop.rb
Normal file
38
lib/jekyll/drops/site_drop.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class SiteDrop < Drop
|
||||
extend Forwardable
|
||||
|
||||
mutable false
|
||||
|
||||
def_delegator :@obj, :site_data, :data
|
||||
def_delegators :@obj, :time, :pages, :static_files, :documents,
|
||||
:tags, :categories
|
||||
|
||||
def [](key)
|
||||
if @obj.collections.key?(key) && key != "posts"
|
||||
@obj.collections[key].docs
|
||||
else
|
||||
super(key)
|
||||
end
|
||||
end
|
||||
|
||||
def posts
|
||||
@site_posts ||= @obj.posts.docs.sort { |a, b| b <=> a }
|
||||
end
|
||||
|
||||
def html_pages
|
||||
@site_html_pages ||= @obj.pages.select { |page| page.html? || page.url.end_with?("/") }
|
||||
end
|
||||
|
||||
def collections
|
||||
@site_collections ||= @obj.collections.values.map(&:to_liquid)
|
||||
end
|
||||
|
||||
private
|
||||
def_delegator :@obj, :config, :fallback_data
|
||||
end
|
||||
end
|
||||
end
|
||||
25
lib/jekyll/drops/unified_payload_drop.rb
Normal file
25
lib/jekyll/drops/unified_payload_drop.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class UnifiedPayloadDrop < Drop
|
||||
mutable true
|
||||
|
||||
attr_accessor :page, :layout, :content, :paginator
|
||||
attr_accessor :highlighter_prefix, :highlighter_suffix
|
||||
|
||||
def jekyll
|
||||
JekyllDrop.global
|
||||
end
|
||||
|
||||
def site
|
||||
@site_drop ||= SiteDrop.new(@obj)
|
||||
end
|
||||
|
||||
private
|
||||
def fallback_data
|
||||
@fallback_data ||= {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
83
lib/jekyll/drops/url_drop.rb
Normal file
83
lib/jekyll/drops/url_drop.rb
Normal file
@@ -0,0 +1,83 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class UrlDrop < Drop
|
||||
extend Forwardable
|
||||
|
||||
mutable false
|
||||
|
||||
def_delegator :@obj, :cleaned_relative_path, :path
|
||||
def_delegator :@obj, :output_ext, :output_ext
|
||||
|
||||
def collection
|
||||
@obj.collection.label
|
||||
end
|
||||
|
||||
def name
|
||||
Utils.slugify(@obj.basename_without_ext)
|
||||
end
|
||||
|
||||
def title
|
||||
Utils.slugify(@obj.data['slug'], :mode => "pretty", :cased => true) ||
|
||||
Utils.slugify(@obj.basename_without_ext, :mode => "pretty", :cased => true)
|
||||
end
|
||||
|
||||
def slug
|
||||
Utils.slugify(@obj.data['slug']) || Utils.slugify(@obj.basename_without_ext)
|
||||
end
|
||||
|
||||
def categories
|
||||
category_set = Set.new
|
||||
Array(@obj.data['categories']).each do |category|
|
||||
category_set << category.to_s.downcase
|
||||
end
|
||||
category_set.to_a.join('/')
|
||||
end
|
||||
|
||||
def year
|
||||
@obj.date.strftime("%Y")
|
||||
end
|
||||
|
||||
def month
|
||||
@obj.date.strftime("%m")
|
||||
end
|
||||
|
||||
def day
|
||||
@obj.date.strftime("%d")
|
||||
end
|
||||
|
||||
def hour
|
||||
@obj.date.strftime("%H")
|
||||
end
|
||||
|
||||
def minute
|
||||
@obj.date.strftime("%M")
|
||||
end
|
||||
|
||||
def second
|
||||
@obj.date.strftime("%S")
|
||||
end
|
||||
|
||||
def i_day
|
||||
@obj.date.strftime("%-d")
|
||||
end
|
||||
|
||||
def i_month
|
||||
@obj.date.strftime("%-m")
|
||||
end
|
||||
|
||||
def short_month
|
||||
@obj.date.strftime("%b")
|
||||
end
|
||||
|
||||
def short_year
|
||||
@obj.date.strftime("%y")
|
||||
end
|
||||
|
||||
def y_day
|
||||
@obj.date.strftime("%j")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
module Jekyll
|
||||
class EntryFilter
|
||||
SPECIAL_LEADING_CHARACTERS = ['.', '_', '#'].freeze
|
||||
SPECIAL_LEADING_CHARACTERS = ['.', '_', '#', '~'].freeze
|
||||
|
||||
attr_reader :site
|
||||
|
||||
@@ -47,7 +47,7 @@ module Jekyll
|
||||
|
||||
def excluded?(entry)
|
||||
excluded = glob_include?(site.exclude, relative_to_source(entry))
|
||||
Jekyll.logger.debug "EntryFilter:", "excluded?(#{relative_to_source(entry)}) ==> #{excluded}"
|
||||
Jekyll.logger.debug "EntryFilter:", "excluded #{relative_to_source(entry)}" if excluded
|
||||
excluded
|
||||
end
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
module Jekyll
|
||||
module Errors
|
||||
class FatalException < RuntimeError
|
||||
end
|
||||
FatalException = Class.new(::RuntimeError)
|
||||
|
||||
class MissingDependencyException < FatalException
|
||||
end
|
||||
DropMutationException = Class.new(FatalException)
|
||||
InvalidPermalinkError = Class.new(FatalException)
|
||||
InvalidYAMLFrontMatterError = Class.new(FatalException)
|
||||
MissingDependencyException = Class.new(FatalException)
|
||||
|
||||
InvalidDateError = Class.new(FatalException)
|
||||
InvalidPostNameError = Class.new(FatalException)
|
||||
PostURLError = Class.new(FatalException)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
require 'forwardable'
|
||||
|
||||
module Jekyll
|
||||
class Excerpt
|
||||
extend Forwardable
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
module Jekyll
|
||||
module External
|
||||
class << self
|
||||
|
||||
#
|
||||
# Gems that, if installed, should be loaded.
|
||||
# Usually contain subcommands.
|
||||
#
|
||||
def blessed_gems
|
||||
%w{
|
||||
%w(
|
||||
jekyll-docs
|
||||
jekyll-import
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
#
|
||||
@@ -18,12 +17,13 @@ module Jekyll
|
||||
#
|
||||
# names - a string gem name or array of gem names
|
||||
#
|
||||
def require_if_present(names)
|
||||
def require_if_present(names, &block)
|
||||
Array(names).each do |name|
|
||||
begin
|
||||
require name
|
||||
rescue LoadError
|
||||
Jekyll.logger.debug "Couldn't load #{name}. Skipping."
|
||||
block.call(name) if block
|
||||
false
|
||||
end
|
||||
end
|
||||
@@ -39,6 +39,7 @@ module Jekyll
|
||||
def require_with_graceful_fail(names)
|
||||
Array(names).each do |name|
|
||||
begin
|
||||
Jekyll.logger.debug "Requiring:", "#{name}"
|
||||
require name
|
||||
rescue LoadError => e
|
||||
Jekyll.logger.error "Dependency Error:", <<-MSG
|
||||
@@ -53,7 +54,6 @@ If you run into trouble, you can find helpful resources at http://jekyllrb.com/h
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,6 +15,17 @@ module Jekyll
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Convert quotes into smart quotes.
|
||||
#
|
||||
# input - The String to convert.
|
||||
#
|
||||
# Returns the smart-quotified String.
|
||||
def smartify(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.find_converter_instance(Jekyll::Converters::SmartyPants)
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Convert a Sass string into CSS output.
|
||||
#
|
||||
# input - The Sass String to convert.
|
||||
@@ -45,7 +56,7 @@ module Jekyll
|
||||
# Returns the given filename or title as a lowercase URL String.
|
||||
# See Utils.slugify for more detail.
|
||||
def slugify(input, mode=nil)
|
||||
Utils.slugify(input, mode: mode)
|
||||
Utils.slugify(input, :mode => mode)
|
||||
end
|
||||
|
||||
# Format a date in short format e.g. "27 Jan 2011".
|
||||
@@ -106,7 +117,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the escaped String.
|
||||
def xml_escape(input)
|
||||
CGI.escapeHTML(input.to_s)
|
||||
input.to_s.encode(:xml => :attr).gsub(/\A"|"\Z/, "")
|
||||
end
|
||||
|
||||
# CGI escape a string for use in a URL. Replaces any special characters
|
||||
@@ -194,7 +205,7 @@ module Jekyll
|
||||
input.group_by do |item|
|
||||
item_property(item, property).to_s
|
||||
end.inject([]) do |memo, i|
|
||||
memo << {"name" => i.first, "items" => i.last}
|
||||
memo << { "name" => i.first, "items" => i.last, "size" => i.last.size }
|
||||
end
|
||||
else
|
||||
input
|
||||
@@ -211,7 +222,7 @@ module Jekyll
|
||||
def where(input, property, value)
|
||||
return input unless input.is_a?(Enumerable)
|
||||
input = input.values if input.is_a?(Hash)
|
||||
input.select { |object| item_property(object, property).to_s == value.to_s }
|
||||
input.select { |object| Array(item_property(object, property)).map(&:to_s).include?(value.to_s) }
|
||||
end
|
||||
|
||||
# Sort an array of objects
|
||||
@@ -223,7 +234,7 @@ module Jekyll
|
||||
# Returns the filtered array of objects
|
||||
def sort(input, property = nil, nils = "first")
|
||||
if input.nil?
|
||||
raise ArgumentError.new("Cannot sort a null object.")
|
||||
raise ArgumentError.new("Cannot sort a null object.")
|
||||
end
|
||||
if property.nil?
|
||||
input.sort
|
||||
@@ -234,11 +245,11 @@ module Jekyll
|
||||
when nils == "last"
|
||||
order = + 1
|
||||
else
|
||||
raise ArgumentError.new("Invalid nils order: " +
|
||||
raise ArgumentError.new("Invalid nils order: " \
|
||||
"'#{nils}' is not a valid nils order. It must be 'first' or 'last'.")
|
||||
end
|
||||
|
||||
input.sort { |apple, orange|
|
||||
input.sort do |apple, orange|
|
||||
apple_property = item_property(apple, property)
|
||||
orange_property = item_property(orange, property)
|
||||
|
||||
@@ -249,7 +260,7 @@ module Jekyll
|
||||
else
|
||||
apple_property <=> orange_property
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -281,20 +292,30 @@ module Jekyll
|
||||
new_ary
|
||||
end
|
||||
|
||||
def sample(input, num = 1)
|
||||
return input unless input.respond_to?(:sample)
|
||||
n = num.to_i rescue 1
|
||||
if n == 1
|
||||
input.sample
|
||||
else
|
||||
input.sample(n)
|
||||
end
|
||||
end
|
||||
|
||||
# Convert an object into its String representation for debugging
|
||||
#
|
||||
# input - The Object to be converted
|
||||
#
|
||||
# Returns a String representation of the object.
|
||||
def inspect(input)
|
||||
CGI.escapeHTML(input.inspect)
|
||||
xml_escape(input.inspect)
|
||||
end
|
||||
|
||||
private
|
||||
def time(input)
|
||||
case input
|
||||
when Time
|
||||
input
|
||||
input.clone
|
||||
when Date
|
||||
input.to_time
|
||||
when String
|
||||
@@ -327,7 +348,7 @@ module Jekyll
|
||||
pairs = item.map { |k, v| as_liquid([k, v]) }
|
||||
Hash[pairs]
|
||||
when Array
|
||||
item.map{ |i| as_liquid(i) }
|
||||
item.map { |i| as_liquid(i) }
|
||||
else
|
||||
if item.respond_to?(:to_liquid)
|
||||
liquidated = item.to_liquid
|
||||
|
||||
@@ -13,23 +13,31 @@ module Jekyll
|
||||
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['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
|
||||
|
||||
def ensure_time!(set)
|
||||
return set unless set.key?('values') && set['values'].key?('date')
|
||||
return set if set['values']['date'].is_a?(Time)
|
||||
set['values']['date'] = Utils.parse_date(set['values']['date'], "An invalid date format was found in a front-matter default set: #{set}")
|
||||
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
|
||||
@@ -83,11 +91,11 @@ module Jekyll
|
||||
end
|
||||
|
||||
def applies_path?(scope, path)
|
||||
return true if !scope.has_key?('path') || scope['path'].empty?
|
||||
return true if !scope.key?('path') || scope['path'].empty?
|
||||
|
||||
scope_path = Pathname.new(scope['path'])
|
||||
Pathname.new(sanitize_path(path)).ascend do |path|
|
||||
if path.to_s == scope_path.to_s
|
||||
Pathname.new(sanitize_path(path)).ascend do |ascended_path|
|
||||
if ascended_path.to_s == scope_path.to_s
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -143,7 +151,7 @@ module Jekyll
|
||||
# Returns an array of hashes
|
||||
def matching_sets(path, type)
|
||||
valid_sets.select do |set|
|
||||
!set.has_key?('scope') || applies?(set['scope'], path, type)
|
||||
!set.key?('scope') || applies?(set['scope'], path, type)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -159,7 +167,7 @@ module Jekyll
|
||||
|
||||
sets.map do |set|
|
||||
if valid?(set)
|
||||
update_deprecated_types(set)
|
||||
ensure_time!(update_deprecated_types(set))
|
||||
else
|
||||
Jekyll.logger.warn "Defaults:", "An invalid front-matter default set was found:"
|
||||
Jekyll.logger.warn "#{set}"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
module Jekyll
|
||||
class Generator < Plugin
|
||||
end
|
||||
Generator = Class.new(Plugin)
|
||||
end
|
||||
|
||||
@@ -4,38 +4,39 @@ module Jekyll
|
||||
|
||||
# compatibility layer for octopress-hooks users
|
||||
PRIORITY_MAP = {
|
||||
low: 10,
|
||||
normal: 20,
|
||||
high: 30,
|
||||
:low => 10,
|
||||
:normal => 20,
|
||||
:high => 30
|
||||
}.freeze
|
||||
|
||||
# initial empty hooks
|
||||
@registry = {
|
||||
:site => {
|
||||
after_reset: [],
|
||||
post_read: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
:after_init => [],
|
||||
:after_reset => [],
|
||||
:post_read => [],
|
||||
:pre_render => [],
|
||||
:post_render => [],
|
||||
:post_write => []
|
||||
},
|
||||
:pages => {
|
||||
post_init: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
:post_init => [],
|
||||
:pre_render => [],
|
||||
:post_render => [],
|
||||
:post_write => []
|
||||
},
|
||||
:posts => {
|
||||
post_init: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
:post_init => [],
|
||||
:pre_render => [],
|
||||
:post_render => [],
|
||||
:post_write => []
|
||||
},
|
||||
:documents => {
|
||||
post_init: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
},
|
||||
:post_init => [],
|
||||
:pre_render => [],
|
||||
:post_render => [],
|
||||
:post_write => []
|
||||
}
|
||||
}
|
||||
|
||||
# map of all hooks and their priorities
|
||||
@@ -60,14 +61,14 @@ module Jekyll
|
||||
# register a single hook to be called later, internal API
|
||||
def self.register_one(owner, event, priority, &block)
|
||||
@registry[owner] ||={
|
||||
post_init: [],
|
||||
pre_render: [],
|
||||
post_render: [],
|
||||
post_write: [],
|
||||
:post_init => [],
|
||||
:pre_render => [],
|
||||
:post_render => [],
|
||||
:post_write => []
|
||||
}
|
||||
|
||||
unless @registry[owner][event]
|
||||
raise NotAvailable, "Invalid hook. #{owner} supports only the " <<
|
||||
raise NotAvailable, "Invalid hook. #{owner} supports only the " \
|
||||
"following hooks #{@registry[owner].keys.inspect}"
|
||||
end
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ module Jekyll
|
||||
def file(filename)
|
||||
filename = @site.in_source_dir(filename).sub(/\A#{Regexp.escape(@site.source)}\//, '')
|
||||
|
||||
LiquidRenderer::File.new(self, filename).tap do |file|
|
||||
LiquidRenderer::File.new(self, filename).tap do
|
||||
@stats[filename] ||= {}
|
||||
@stats[filename][:count] ||= 0
|
||||
@stats[filename][:count] += 1
|
||||
|
||||
@@ -8,7 +8,7 @@ module Jekyll
|
||||
|
||||
def parse(content)
|
||||
measure_time do
|
||||
@template = Liquid::Template.parse(content)
|
||||
@template = Liquid::Template.parse(content, line_numbers: true)
|
||||
end
|
||||
|
||||
self
|
||||
|
||||
@@ -69,10 +69,10 @@ module Jekyll
|
||||
end
|
||||
|
||||
def data_for_table(n)
|
||||
sorted = @stats.sort_by{ |filename, file_stats| -file_stats[:time] }
|
||||
sorted = @stats.sort_by { |_, file_stats| -file_stats[:time] }
|
||||
sorted = sorted.slice(0, n)
|
||||
|
||||
table = [[ 'Filename', 'Count', 'Bytes', 'Time' ]]
|
||||
table = [%w(Filename Count Bytes Time)]
|
||||
|
||||
sorted.each do |filename, file_stats|
|
||||
row = []
|
||||
|
||||
@@ -7,14 +7,27 @@ module Jekyll
|
||||
attr_accessor :name, :ext, :basename
|
||||
attr_accessor :data, :content, :output
|
||||
|
||||
alias_method :extname, :ext
|
||||
|
||||
FORWARD_SLASH = '/'.freeze
|
||||
|
||||
# Attributes for Liquid templates
|
||||
ATTRIBUTES_FOR_LIQUID = %w[
|
||||
ATTRIBUTES_FOR_LIQUID = %w(
|
||||
content
|
||||
dir
|
||||
name
|
||||
path
|
||||
url
|
||||
]
|
||||
)
|
||||
|
||||
# A set of extensions that are considered HTML or HTML-like so we
|
||||
# should not alter them, this includes .xhtml through XHTM5.
|
||||
|
||||
HTML_EXTENSIONS = %W(
|
||||
.html
|
||||
.xhtml
|
||||
.htm
|
||||
)
|
||||
|
||||
# Initialize a new Page.
|
||||
#
|
||||
@@ -28,11 +41,10 @@ module Jekyll
|
||||
@dir = dir
|
||||
@name = name
|
||||
|
||||
|
||||
process(name)
|
||||
read_yaml(File.join(base, dir), name)
|
||||
|
||||
data.default_proc = proc do |hash, key|
|
||||
data.default_proc = proc do |_, key|
|
||||
site.frontmatter_defaults.find(File.join(dir, name), type, key)
|
||||
end
|
||||
|
||||
@@ -45,7 +57,12 @@ module Jekyll
|
||||
#
|
||||
# Returns the String destination directory.
|
||||
def dir
|
||||
url[-1, 1] == '/' ? url : File.dirname(url)
|
||||
if url.end_with?(FORWARD_SLASH)
|
||||
url
|
||||
else
|
||||
url_dir = File.dirname(url)
|
||||
url_dir.end_with?(FORWARD_SLASH) ? url_dir : "#{url_dir}/"
|
||||
end
|
||||
end
|
||||
|
||||
# The full path and filename of the post. Defined in the YAML of the post
|
||||
@@ -53,8 +70,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the String permalink or nil if none has been set.
|
||||
def permalink
|
||||
return nil if data.nil? || data['permalink'].nil?
|
||||
data['permalink']
|
||||
data.nil? ? nil : data['permalink']
|
||||
end
|
||||
|
||||
# The template of the permalink.
|
||||
@@ -98,7 +114,7 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
self.ext = File.extname(name)
|
||||
self.basename = name[0 .. -ext.length - 1]
|
||||
self.basename = name[0..-ext.length - 1]
|
||||
end
|
||||
|
||||
# Add any necessary layouts to this post
|
||||
@@ -108,12 +124,10 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def render(layouts, site_payload)
|
||||
payload = Utils.deep_merge_hashes({
|
||||
"page" => to_liquid,
|
||||
'paginator' => pager.to_liquid
|
||||
}, site_payload)
|
||||
site_payload["page"] = to_liquid
|
||||
site_payload["paginator"] = pager.to_liquid
|
||||
|
||||
do_layout(payload, layouts)
|
||||
do_layout(site_payload, layouts)
|
||||
end
|
||||
|
||||
# The path to the source file
|
||||
@@ -135,8 +149,8 @@ module Jekyll
|
||||
# Returns the destination file path String.
|
||||
def destination(dest)
|
||||
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if url.end_with?("/")
|
||||
path << output_ext unless path.end_with?(output_ext)
|
||||
path = File.join(path, "index") if url.end_with?("/")
|
||||
path << output_ext unless path.end_with? output_ext
|
||||
path
|
||||
end
|
||||
|
||||
@@ -147,12 +161,20 @@ module Jekyll
|
||||
|
||||
# Returns the Boolean of whether this Page is HTML or not.
|
||||
def html?
|
||||
output_ext == '.html'
|
||||
HTML_EXTENSIONS.include?(output_ext)
|
||||
end
|
||||
|
||||
# Returns the Boolean of whether this Page is an index file or not.
|
||||
def index?
|
||||
basename == 'index'
|
||||
end
|
||||
|
||||
def trigger_hooks(hook_name, *args)
|
||||
Jekyll::Hooks.trigger :pages, hook_name, self, *args
|
||||
end
|
||||
|
||||
def write?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,20 +1,39 @@
|
||||
module Jekyll
|
||||
class Plugin
|
||||
PRIORITIES = { :lowest => -100,
|
||||
:low => -10,
|
||||
:normal => 0,
|
||||
:high => 10,
|
||||
:highest => 100 }
|
||||
PRIORITIES = {
|
||||
:low => -10,
|
||||
:highest => 100,
|
||||
:lowest => -100,
|
||||
:normal => 0,
|
||||
:high => 10
|
||||
}
|
||||
|
||||
# Fetch all the subclasses of this class and its 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
|
||||
|
||||
def self.inherited(const)
|
||||
return catch_inheritance(const) do |const_|
|
||||
catch_inheritance(const_)
|
||||
end
|
||||
descendants
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def self.catch_inheritance(const)
|
||||
const.define_singleton_method :inherited do |const_|
|
||||
(@children ||= Set.new).add const_
|
||||
if block_given?
|
||||
yield const_
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def self.descendants
|
||||
@children ||= Set.new
|
||||
out = @children.map(&:descendants)
|
||||
out << self unless superclass == Plugin
|
||||
Set.new(out).flatten
|
||||
end
|
||||
|
||||
# Get or set the priority of this plugin. When called without an
|
||||
@@ -41,7 +60,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the safety Boolean.
|
||||
def self.safe(safe = nil)
|
||||
if safe
|
||||
if !defined?(@safe) || !safe.nil?
|
||||
@safe = safe
|
||||
end
|
||||
@safe || false
|
||||
|
||||
@@ -24,12 +24,7 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def require_gems
|
||||
site.gems.each do |gem|
|
||||
if plugin_allowed?(gem)
|
||||
Jekyll.logger.debug("PluginManager:", "Requiring #{gem}")
|
||||
require gem
|
||||
end
|
||||
end
|
||||
Jekyll::External.require_with_graceful_fail(site.gems.select { |gem| plugin_allowed?(gem) })
|
||||
end
|
||||
|
||||
def self.require_from_bundler
|
||||
@@ -70,10 +65,9 @@ module Jekyll
|
||||
# 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
|
||||
plugins_path.each do |plugin_search_path|
|
||||
plugin_files = Utils.safe_glob(plugin_search_path, File.join("**", "*.rb"))
|
||||
Jekyll::External.require_with_graceful_fail(plugin_files)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -82,7 +76,7 @@ module Jekyll
|
||||
#
|
||||
# Returns an Array of plugin search paths
|
||||
def plugins_path
|
||||
if (site.config['plugins_dir'] == Jekyll::Configuration::DEFAULTS['plugins_dir'])
|
||||
if site.config['plugins_dir'] == Jekyll::Configuration::DEFAULTS['plugins_dir']
|
||||
[site.in_source_dir(site.config['plugins_dir'])]
|
||||
else
|
||||
Array(site.config['plugins_dir']).map { |d| File.expand_path(d) }
|
||||
@@ -92,11 +86,10 @@ module Jekyll
|
||||
def deprecation_checks
|
||||
pagination_included = (site.config['gems'] || []).include?('jekyll-paginate') || defined?(Jekyll::Paginate)
|
||||
if site.config['paginate'] && !pagination_included
|
||||
Jekyll::Deprecator.deprecation_message "You appear to have pagination " +
|
||||
"turned on, but you haven't included the `jekyll-paginate` gem. " +
|
||||
Jekyll::Deprecator.deprecation_message "You appear to have pagination " \
|
||||
"turned on, but you haven't included the `jekyll-paginate` gem. " \
|
||||
"Ensure you have `gems: [jekyll-paginate]` in your configuration file."
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,14 +8,14 @@ module Jekyll
|
||||
can_be_published?(thing) && !hidden_in_the_future?(thing)
|
||||
end
|
||||
|
||||
def hidden_in_the_future?(thing)
|
||||
thing.respond_to?(:date) && !@site.future && thing.date.to_i > @site.time.to_i
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_be_published?(thing)
|
||||
thing.data.fetch('published', true) || @site.unpublished
|
||||
end
|
||||
|
||||
def hidden_in_the_future?(thing)
|
||||
thing.respond_to?(:date) && !@site.future && thing.date.to_i > @site.time.to_i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ module Jekyll
|
||||
|
||||
# Sorts posts, pages, and static files.
|
||||
def sort_files!
|
||||
site.collections.values.each{|c| c.docs.sort!}
|
||||
site.collections.values.each { |c| c.docs.sort! }
|
||||
site.pages.sort_by!(&:name)
|
||||
site.static_files.sort_by!(&:relative_path)
|
||||
end
|
||||
@@ -38,9 +38,9 @@ module Jekyll
|
||||
base = site.in_source_dir(dir)
|
||||
|
||||
dot = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
|
||||
dot_dirs = dot.select{ |file| File.directory?(@site.in_source_dir(base,file)) }
|
||||
dot_dirs = dot.select { |file| File.directory?(@site.in_source_dir(base, file)) }
|
||||
dot_files = (dot - dot_dirs)
|
||||
dot_pages = dot_files.select{ |file| Utils.has_yaml_header?(@site.in_source_dir(base,file)) }
|
||||
dot_pages = dot_files.select { |file| Utils.has_yaml_header?(@site.in_source_dir(base, file)) }
|
||||
dot_static_files = dot_files - dot_pages
|
||||
|
||||
retrieve_posts(dir)
|
||||
@@ -67,12 +67,12 @@ module Jekyll
|
||||
# dot_dirs - The Array of subdirectories in the dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_dirs(base, dir, dot_dirs)
|
||||
dot_dirs.map { |file|
|
||||
dir_path = site.in_source_dir(dir,file)
|
||||
def retrieve_dirs(_base, dir, dot_dirs)
|
||||
dot_dirs.map do |file|
|
||||
dir_path = site.in_source_dir(dir, file)
|
||||
rel_path = File.join(dir, file)
|
||||
@site.reader.read_directories(rel_path) unless @site.dest.sub(/\/$/, '') == dir_path
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Retrieve all the pages from the current directory,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module Jekyll
|
||||
class CollectionReader
|
||||
SPECIAL_COLLECTIONS = %w{posts data}.freeze
|
||||
SPECIAL_COLLECTIONS = %w(posts data).freeze
|
||||
|
||||
attr_reader :site, :content
|
||||
def initialize(site)
|
||||
@@ -16,6 +16,5 @@ module Jekyll
|
||||
collection.read unless SPECIAL_COLLECTIONS.include?(collection.label)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,13 +50,13 @@ module Jekyll
|
||||
# Returns the contents of the data file.
|
||||
def read_data_file(path)
|
||||
case File.extname(path).downcase
|
||||
when '.csv'
|
||||
CSV.read(path, {
|
||||
:headers => true,
|
||||
:encoding => site.config['encoding']
|
||||
}).map(&:to_hash)
|
||||
else
|
||||
SafeYAML.load_file(path)
|
||||
when '.csv'
|
||||
CSV.read(path, {
|
||||
:headers => true,
|
||||
:encoding => site.config['encoding']
|
||||
}).map(&:to_hash)
|
||||
else
|
||||
SafeYAML.load_file(path)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ module Jekyll
|
||||
def initialize(site, dir)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@unfiltered_content = Array.new
|
||||
@unfiltered_content = []
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/ for Yaml header and create a new Page
|
||||
@@ -14,8 +14,8 @@ module Jekyll
|
||||
#
|
||||
# Returns an array of static pages.
|
||||
def read(files)
|
||||
files.map{ |page| @unfiltered_content << Page.new(@site, @site.source, @dir, page) }
|
||||
@unfiltered_content.select{ |page| site.publisher.publish?(page) }
|
||||
files.map { |page| @unfiltered_content << Page.new(@site, @site.source, @dir, page) }
|
||||
@unfiltered_content.select { |page| site.publisher.publish?(page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,7 +35,11 @@ module Jekyll
|
||||
read_content(dir, magic_dir, matcher).tap do |docs|
|
||||
docs.each(&:read)
|
||||
end.select do |doc|
|
||||
site.publisher.publish?(doc)
|
||||
site.publisher.publish?(doc).tap do |will_publish|
|
||||
if !will_publish && site.publisher.hidden_in_the_future?(doc)
|
||||
Jekyll.logger.debug "Skipping:", "#{doc.relative_path} has a future date"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,8 +57,8 @@ module Jekyll
|
||||
next unless entry =~ matcher
|
||||
path = @site.in_source_dir(File.join(dir, magic_dir, entry))
|
||||
Document.new(path, {
|
||||
site: @site,
|
||||
collection: @site.posts
|
||||
:site => @site,
|
||||
:collection => @site.posts
|
||||
})
|
||||
end.reject(&:nil?)
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ module Jekyll
|
||||
def initialize(site, dir)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@unfiltered_content = Array.new
|
||||
@unfiltered_content = []
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/ for Yaml header and create a new Page
|
||||
@@ -14,7 +14,7 @@ module Jekyll
|
||||
#
|
||||
# Returns an array of static files.
|
||||
def read(files)
|
||||
files.map{ |file| @unfiltered_content << StaticFile.new(@site, @site.source, @dir, file)}
|
||||
files.map { |file| @unfiltered_content << StaticFile.new(@site, @site.source, @dir, file) }
|
||||
@unfiltered_content
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
module Jekyll
|
||||
class Regenerator
|
||||
attr_reader :site, :metadata, :cache
|
||||
attr_accessor :disabled
|
||||
private :disabled, :disabled=
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
@@ -62,7 +64,6 @@ module Jekyll
|
||||
clear_cache
|
||||
end
|
||||
|
||||
|
||||
# Clear just the cache
|
||||
#
|
||||
# Returns nothing
|
||||
@@ -70,13 +71,12 @@ module Jekyll
|
||||
@cache = {}
|
||||
end
|
||||
|
||||
|
||||
# Checks if the source has been modified or the
|
||||
# destination is missing
|
||||
#
|
||||
# returns a boolean
|
||||
def source_modified_or_dest_missing?(source_path, dest_path)
|
||||
modified?(source_path) || (dest_path and !File.exist?(dest_path))
|
||||
modified?(source_path) || (dest_path && !File.exist?(dest_path))
|
||||
end
|
||||
|
||||
# Checks if a path's (or one of its dependencies)
|
||||
@@ -90,7 +90,7 @@ module Jekyll
|
||||
return true if path.nil?
|
||||
|
||||
# Check for path in cache
|
||||
if cache.has_key? path
|
||||
if cache.key? path
|
||||
return cache[path]
|
||||
end
|
||||
|
||||
@@ -117,9 +117,9 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def add_dependency(path, dependency)
|
||||
return if (metadata[path].nil? || @disabled)
|
||||
return if metadata[path].nil? || disabled
|
||||
|
||||
if !metadata[path]["deps"].include? dependency
|
||||
unless metadata[path]["deps"].include? dependency
|
||||
metadata[path]["deps"] << dependency
|
||||
add(dependency) unless metadata.include?(dependency)
|
||||
end
|
||||
@@ -146,8 +146,8 @@ module Jekyll
|
||||
#
|
||||
# Returns a Boolean (true for disabled, false for enabled).
|
||||
def disabled?
|
||||
@disabled = !site.incremental? if @disabled.nil?
|
||||
@disabled
|
||||
self.disabled = !site.incremental? if disabled.nil?
|
||||
disabled
|
||||
end
|
||||
|
||||
private
|
||||
@@ -157,20 +157,21 @@ module Jekyll
|
||||
#
|
||||
# Returns the read metadata.
|
||||
def read_metadata
|
||||
@metadata = if !disabled? && File.file?(metadata_file)
|
||||
content = File.binread(metadata_file)
|
||||
@metadata =
|
||||
if !disabled? && File.file?(metadata_file)
|
||||
content = File.binread(metadata_file)
|
||||
|
||||
begin
|
||||
Marshal.load(content)
|
||||
rescue TypeError
|
||||
SafeYAML.load(content)
|
||||
rescue ArgumentError => e
|
||||
Jekyll.logger.warn("Failed to load #{metadata_file}: #{e}")
|
||||
begin
|
||||
Marshal.load(content)
|
||||
rescue TypeError
|
||||
SafeYAML.load(content)
|
||||
rescue ArgumentError => e
|
||||
Jekyll.logger.warn("Failed to load #{metadata_file}: #{e}")
|
||||
{}
|
||||
end
|
||||
else
|
||||
{}
|
||||
end
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module Jekyll
|
||||
class RelatedPosts
|
||||
|
||||
class << self
|
||||
attr_accessor :lsi
|
||||
end
|
||||
@@ -24,7 +23,6 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def build_index
|
||||
self.class.lsi ||= begin
|
||||
lsi = ClassifierReborn::LSI.new(:auto_rebuild => false)
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
|
||||
module Jekyll
|
||||
class Renderer
|
||||
|
||||
attr_reader :document, :site, :site_payload
|
||||
attr_reader :document, :site, :payload
|
||||
|
||||
def initialize(site, document, site_payload = nil)
|
||||
@site = site
|
||||
@document = document
|
||||
@site_payload = site_payload
|
||||
@site = site
|
||||
@document = document
|
||||
@payload = site_payload || site.site_payload
|
||||
end
|
||||
|
||||
# Determine which converters to use based on this document's
|
||||
@@ -23,7 +22,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the output extname including the leading period.
|
||||
def output_ext
|
||||
@output_ext ||= converters.first.output_ext(document.extname)
|
||||
@output_ext ||= (permalink_ext || converter_output_ext)
|
||||
end
|
||||
|
||||
######################
|
||||
@@ -33,26 +32,30 @@ module Jekyll
|
||||
def run
|
||||
Jekyll.logger.debug "Rendering:", document.relative_path
|
||||
|
||||
payload = Utils.deep_merge_hashes({
|
||||
"page" => document.to_liquid
|
||||
}, site_payload || site.site_payload)
|
||||
payload["page"] = document.to_liquid
|
||||
|
||||
if document.collection.label == 'posts' && document.is_a?(Document)
|
||||
payload['site']['related_posts'] = document.related_posts
|
||||
if document.respond_to? :pager
|
||||
payload["paginator"] = document.pager.to_liquid
|
||||
end
|
||||
|
||||
if document.is_a?(Document) && document.collection.label == 'posts'
|
||||
payload['site']['related_posts'] = document.related_posts
|
||||
else
|
||||
payload['site']['related_posts'] = nil
|
||||
end
|
||||
|
||||
# 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
|
||||
|
||||
Jekyll.logger.debug "Pre-Render Hooks:", document.relative_path
|
||||
document.trigger_hooks(:pre_render, payload)
|
||||
|
||||
info = {
|
||||
filters: [Jekyll::Filters],
|
||||
registers: { :site => site, :page => payload['page'] }
|
||||
: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?
|
||||
@@ -135,14 +138,9 @@ module Jekyll
|
||||
used = Set.new([layout])
|
||||
|
||||
while layout
|
||||
payload = Utils.deep_merge_hashes(
|
||||
payload,
|
||||
{
|
||||
"content" => output,
|
||||
"page" => document.to_liquid,
|
||||
"layout" => layout.data
|
||||
}
|
||||
)
|
||||
payload['content'] = output
|
||||
payload['page'] = document.to_liquid
|
||||
payload['layout'] = Utils.deep_merge_hashes(payload['layout'] || {}, layout.data)
|
||||
|
||||
output = render_liquid(
|
||||
layout.content,
|
||||
@@ -169,5 +167,27 @@ module Jekyll
|
||||
output
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def permalink_ext
|
||||
if document.permalink && !document.permalink.end_with?("/")
|
||||
permalink_ext = File.extname(document.permalink)
|
||||
permalink_ext unless permalink_ext.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def converter_output_ext
|
||||
if output_exts.size == 1
|
||||
output_exts.last
|
||||
else
|
||||
output_exts[-2]
|
||||
end
|
||||
end
|
||||
|
||||
def output_exts
|
||||
@output_exts ||= converters.map do |c|
|
||||
c.output_ext(document.extname)
|
||||
end.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,24 +17,38 @@ module Jekyll
|
||||
#
|
||||
# config - A Hash containing site configuration details.
|
||||
def initialize(config)
|
||||
# Source and destination may not be changed after the site has been created.
|
||||
@source = File.expand_path(config['source']).freeze
|
||||
@dest = File.expand_path(config['destination']).freeze
|
||||
|
||||
self.config = config
|
||||
|
||||
@reader = Reader.new(self)
|
||||
@regenerator = Regenerator.new(self)
|
||||
@liquid_renderer = LiquidRenderer.new(self)
|
||||
|
||||
Jekyll.sites << self
|
||||
|
||||
Jekyll::Hooks.trigger :site, :after_init, self
|
||||
|
||||
reset
|
||||
setup
|
||||
end
|
||||
|
||||
# Public: Set the site's configuration. This handles side-effects caused by
|
||||
# changing values in the configuration.
|
||||
#
|
||||
# config - a Jekyll::Configuration, containing the new configuration.
|
||||
#
|
||||
# Returns the new configuration.
|
||||
def config=(config)
|
||||
@config = config.clone
|
||||
|
||||
%w[safe lsi highlighter baseurl exclude include future unpublished
|
||||
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
|
||||
|
||||
# Source and destination may not be changed after the site has been created.
|
||||
@source = File.expand_path(config['source']).freeze
|
||||
@dest = File.expand_path(config['destination']).freeze
|
||||
|
||||
@reader = Jekyll::Reader.new(self)
|
||||
|
||||
# Initialize incremental regenerator
|
||||
@regenerator = Regenerator.new(self)
|
||||
|
||||
@liquid_renderer = LiquidRenderer.new(self)
|
||||
|
||||
self.plugin_manager = Jekyll::PluginManager.new(self)
|
||||
self.plugins = plugin_manager.plugins_path
|
||||
|
||||
@@ -43,10 +57,7 @@ module Jekyll
|
||||
|
||||
self.permalink_style = config['permalink'].to_sym
|
||||
|
||||
Jekyll.sites << self
|
||||
|
||||
reset
|
||||
setup
|
||||
@config
|
||||
end
|
||||
|
||||
# Public: Read, process, and write this Site to output.
|
||||
@@ -165,7 +176,7 @@ module Jekyll
|
||||
|
||||
Jekyll::Hooks.trigger :site, :pre_render, self, payload
|
||||
|
||||
collections.each do |label, collection|
|
||||
collections.each do |_, collection|
|
||||
collection.docs.each do |document|
|
||||
if regenerator.regenerate?(document)
|
||||
document.output = Jekyll::Renderer.new(self, document, payload).run
|
||||
@@ -176,7 +187,8 @@ module Jekyll
|
||||
|
||||
pages.flatten.each do |page|
|
||||
if regenerator.regenerate?(page)
|
||||
page.render(layouts, payload)
|
||||
page.output = Jekyll::Renderer.new(self, page, payload).run
|
||||
page.trigger_hooks(:post_render)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -196,9 +208,9 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def write
|
||||
each_site_file { |item|
|
||||
each_site_file do |item|
|
||||
item.write(dest) if regenerator.regenerate?(item)
|
||||
}
|
||||
end
|
||||
regenerator.write_metadata
|
||||
Jekyll::Hooks.trigger :site, :post_write, self
|
||||
end
|
||||
@@ -259,47 +271,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,
|
||||
"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.docs.sort { |a, b| b <=> a },
|
||||
"pages" => pages,
|
||||
"static_files" => static_files,
|
||||
"html_pages" => pages.select { |page| page.html? || page.url.end_with?("/") },
|
||||
"categories" => post_attr_hash('categories'),
|
||||
"tags" => post_attr_hash('tags'),
|
||||
"collections" => collections.values.map(&:to_liquid),
|
||||
"documents" => documents,
|
||||
"data" => site_data
|
||||
}))
|
||||
}
|
||||
Drops::UnifiedPayloadDrop.new self
|
||||
end
|
||||
|
||||
# Get the implementation class for the given Converter.
|
||||
#
|
||||
# klass - The Class of the Converter to fetch.
|
||||
#
|
||||
# Returns the Converter instance implementing the given Converter.
|
||||
# klass - The Class of the Converter to fetch.
|
||||
|
||||
def find_converter_instance(klass)
|
||||
converters.find { |c| c.class == klass } || proc { raise "No converter for #{klass}" }.call
|
||||
converters.find { |klass_| klass_.instance_of?(klass) } || \
|
||||
raise("No Converters found for #{klass}")
|
||||
end
|
||||
|
||||
# klass - class or module containing the subclasses.
|
||||
# Returns array of instances of subclasses of parameter.
|
||||
# Create array of instances of the subclasses of the class or module
|
||||
# passed in as argument.
|
||||
#
|
||||
# klass - class or module containing the subclasses which should be
|
||||
# instantiated
|
||||
#
|
||||
# Returns array of instances of subclasses of parameter
|
||||
# passed in as argument.
|
||||
|
||||
def instantiate_subclasses(klass)
|
||||
klass.descendants.select do |c|
|
||||
!safe || c.safe
|
||||
end.sort.map do |c|
|
||||
klass.descendants.select { |c| !safe || c.safe }.sort.map do |c|
|
||||
c.new(config)
|
||||
end
|
||||
end
|
||||
@@ -310,10 +300,10 @@ module Jekyll
|
||||
# Returns
|
||||
def relative_permalinks_are_deprecated
|
||||
if config['relative_permalinks']
|
||||
Jekyll.logger.abort_with "Since v3.0, permalinks for pages" +
|
||||
" in subfolders must be relative to the" +
|
||||
" site source directory, not the parent" +
|
||||
" directory. Check http://jekyllrb.com/docs/upgrading/"+
|
||||
Jekyll.logger.abort_with "Since v3.0, permalinks for pages" \
|
||||
" in subfolders must be relative to the" \
|
||||
" site source directory, not the parent" \
|
||||
" directory. Check http://jekyllrb.com/docs/upgrading/"\
|
||||
" for more info."
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module Jekyll
|
||||
class StaticFile
|
||||
# The cache of last modification times [path] -> mtime.
|
||||
@@mtimes = Hash.new
|
||||
@@mtimes = {}
|
||||
|
||||
attr_reader :relative_path, :extname
|
||||
|
||||
@@ -75,12 +75,16 @@ module Jekyll
|
||||
def write(dest)
|
||||
dest_path = destination(dest)
|
||||
|
||||
return false if File.exist?(dest_path) and !modified?
|
||||
return false if File.exist?(dest_path) && !modified?
|
||||
@@mtimes[path] = mtime
|
||||
|
||||
FileUtils.mkdir_p(File.dirname(dest_path))
|
||||
FileUtils.rm(dest_path) if File.exist?(dest_path)
|
||||
FileUtils.cp(path, dest_path)
|
||||
if @site.safe || Jekyll.env == "production"
|
||||
FileUtils.cp(path, dest_path)
|
||||
else
|
||||
FileUtils.copy_entry(path, dest_path)
|
||||
end
|
||||
File.utime(@@mtimes[path], @@mtimes[path], dest_path)
|
||||
|
||||
true
|
||||
@@ -90,7 +94,7 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.reset_cache
|
||||
@@mtimes = Hash.new
|
||||
@@mtimes = {}
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -104,12 +108,12 @@ module Jekyll
|
||||
|
||||
def placeholders
|
||||
{
|
||||
collection: @collection.label,
|
||||
path: relative_path[
|
||||
:collection => @collection.label,
|
||||
:path => relative_path[
|
||||
@collection.relative_directory.size..relative_path.size],
|
||||
output_ext: '',
|
||||
name: '',
|
||||
title: '',
|
||||
:output_ext => '',
|
||||
:name => '',
|
||||
:title => ''
|
||||
}
|
||||
end
|
||||
|
||||
@@ -118,13 +122,13 @@ module Jekyll
|
||||
# be overriden in the collection's configuration in _config.yml.
|
||||
def url
|
||||
@url ||= if @collection.nil?
|
||||
relative_path
|
||||
else
|
||||
::Jekyll::URL.new({
|
||||
template: @collection.url_template,
|
||||
placeholders: placeholders,
|
||||
})
|
||||
end.to_s.gsub /\/$/, ''
|
||||
relative_path
|
||||
else
|
||||
::Jekyll::URL.new({
|
||||
:template => @collection.url_template,
|
||||
:placeholders => placeholders
|
||||
})
|
||||
end.to_s.gsub(/\/$/, '')
|
||||
end
|
||||
|
||||
# Returns the type of the collection if present, nil otherwise.
|
||||
|
||||
@@ -5,7 +5,7 @@ module Jekyll
|
||||
@level = DEBUG
|
||||
@default_formatter = Formatter.new
|
||||
@logdev = $stdout
|
||||
@formatter = proc do |severity, datetime, progname, msg|
|
||||
@formatter = proc do |_, _, _, msg|
|
||||
"#{msg}"
|
||||
end
|
||||
end
|
||||
@@ -14,7 +14,7 @@ module Jekyll
|
||||
severity ||= UNKNOWN
|
||||
@logdev = set_logdevice(severity)
|
||||
|
||||
if @logdev.nil? or severity < @level
|
||||
if @logdev.nil? || severity < @level
|
||||
return true
|
||||
end
|
||||
progname ||= @progname
|
||||
|
||||
@@ -13,21 +13,21 @@ module Jekyll
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
if markup.strip =~ SYNTAX
|
||||
@lang = $1.downcase
|
||||
@options = {}
|
||||
if defined?($2) && $2 != ''
|
||||
@lang = Regexp.last_match(1).downcase
|
||||
@highlight_options = {}
|
||||
if defined?(Regexp.last_match(2)) && Regexp.last_match(2) != ''
|
||||
# Split along 3 possible forms -- key="<quoted list>", key=value, or key
|
||||
$2.scan(/(?:\w="[^"]*"|\w=\w|\w)+/) do |opt|
|
||||
Regexp.last_match(2).scan(/(?:\w="[^"]*"|\w=\w|\w)+/) do |opt|
|
||||
key, value = opt.split('=')
|
||||
# If a quoted list, convert to array
|
||||
if value && value.include?("\"")
|
||||
value.gsub!(/"/, "")
|
||||
value.delete!('"')
|
||||
value = value.split
|
||||
end
|
||||
@options[key.to_sym] = value || true
|
||||
@highlight_options[key.to_sym] = value || true
|
||||
end
|
||||
end
|
||||
@options[:linenos] = "inline" if @options.key?(:linenos) and @options[:linenos] == true
|
||||
@highlight_options[:linenos] = "inline" if @highlight_options.key?(:linenos) && @highlight_options[:linenos] == true
|
||||
else
|
||||
raise SyntaxError.new <<-eos
|
||||
Syntax Error in tag 'highlight' while parsing the following markup:
|
||||
@@ -68,7 +68,7 @@ eos
|
||||
[:linenos, opts.fetch(:linenos, nil)],
|
||||
[:encoding, opts.fetch(:encoding, 'utf-8')],
|
||||
[:cssclass, opts.fetch(:cssclass, nil)]
|
||||
].reject {|f| f.last.nil? }]
|
||||
].reject { |f| f.last.nil? }]
|
||||
else
|
||||
opts
|
||||
end
|
||||
@@ -80,7 +80,7 @@ eos
|
||||
highlighted_code = Pygments.highlight(
|
||||
code,
|
||||
:lexer => @lang,
|
||||
:options => sanitized_opts(@options, is_safe)
|
||||
:options => sanitized_opts(@highlight_options, is_safe)
|
||||
)
|
||||
|
||||
if highlighted_code.nil?
|
||||
@@ -88,7 +88,7 @@ eos
|
||||
puts
|
||||
Jekyll.logger.error code
|
||||
puts
|
||||
Jekyll.logger.error "While attempting to convert the above code, Pygments.rb" +
|
||||
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.")
|
||||
@@ -99,7 +99,7 @@ eos
|
||||
|
||||
def render_rouge(code)
|
||||
Jekyll::External.require_with_graceful_fail('rouge')
|
||||
formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false)
|
||||
formatter = Rouge::Formatters::HTML.new(:line_numbers => @highlight_options[:linenos], :wrap => false)
|
||||
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
||||
formatter.format(lexer.lex(code))
|
||||
end
|
||||
@@ -110,12 +110,11 @@ eos
|
||||
|
||||
def add_code_tag(code)
|
||||
code_attributes = [
|
||||
"class=\"language-#{@lang.to_s.gsub('+', '-')}\"",
|
||||
"data-lang=\"#{@lang.to_s}\""
|
||||
"class=\"language-#{@lang.to_s.tr('+', '-')}\"",
|
||||
"data-lang=\"#{@lang}\""
|
||||
].join(" ")
|
||||
"<figure class=\"highlight\"><pre><code #{code_attributes}>#{code.chomp}</code></pre></figure>"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user