mirror of https://github.com/mpastell/Weave.jl
Compare commits
871 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
77793c775c | |
![]() |
ad0885ce00 | |
![]() |
e10aaefd94 | |
![]() |
8ad4e876d3 | |
![]() |
af2a6e14c9 | |
![]() |
20aaefec0a | |
![]() |
2a78676d41 | |
![]() |
59332c1768 | |
![]() |
db28a69d94 | |
![]() |
0b96591f39 | |
![]() |
a38cec95db | |
![]() |
562f8e4ab3 | |
![]() |
9f666b3bb5 | |
![]() |
a63577f69c | |
![]() |
7e0f5641c2 | |
![]() |
b022a54458 | |
![]() |
b669a14038 | |
![]() |
b7941c2811 | |
![]() |
d40e95a4bb | |
![]() |
df47ea191f | |
![]() |
381de22c7d | |
![]() |
06b259a7b0 | |
![]() |
749c0c262c | |
![]() |
696db1d82b | |
![]() |
d4c65729e4 | |
![]() |
1dfb8d76d6 | |
![]() |
48c99c791f | |
![]() |
ec3f464c37 | |
![]() |
4c60bd8d64 | |
![]() |
e1d31c2ef6 | |
![]() |
99916dd70c | |
![]() |
6b6f82bed4 | |
![]() |
b1de7efede | |
![]() |
849cc20e88 | |
![]() |
10de1057a3 | |
![]() |
e753f70f7a | |
![]() |
8dc0441b90 | |
![]() |
c9fc740d72 | |
![]() |
cc5913e812 | |
![]() |
e02d5ce2fd | |
![]() |
b583ac2e40 | |
![]() |
955675d89a | |
![]() |
196d4ca7ce | |
![]() |
d3a7f2aea7 | |
![]() |
7d361bb40d | |
![]() |
e927495a62 | |
![]() |
78befc61b5 | |
![]() |
c24a262135 | |
![]() |
3e8200c2f8 | |
![]() |
8f23084471 | |
![]() |
a1830e0502 | |
![]() |
0e662ecdec | |
![]() |
fa71830479 | |
![]() |
21d7fbdbea | |
![]() |
fe3711074b | |
![]() |
766847ec65 | |
![]() |
46a0f8bff4 | |
![]() |
51f905ca83 | |
![]() |
b5ba227e75 | |
![]() |
74768a7e0f | |
![]() |
90d8c8430f | |
![]() |
a61ade7778 | |
![]() |
8ac94989f1 | |
![]() |
191282c1e5 | |
![]() |
d8eca00fd8 | |
![]() |
957d12e751 | |
![]() |
82c7c2a8c6 | |
![]() |
ba5bc9ca08 | |
![]() |
5f0d9d4627 | |
![]() |
676ecc64f9 | |
![]() |
2a509d8f96 | |
![]() |
9b2a1228cd | |
![]() |
785768c728 | |
![]() |
7e9c4fb99d | |
![]() |
29546b7716 | |
![]() |
db5308b286 | |
![]() |
174585e504 | |
![]() |
8206ca2d14 | |
![]() |
092adb6805 | |
![]() |
872f7c7153 | |
![]() |
5ae1fd5cf1 | |
![]() |
bd447ec8e3 | |
![]() |
3dfe817584 | |
![]() |
12e148af18 | |
![]() |
03079a5dac | |
![]() |
e179bd098e | |
![]() |
4a96f2c19a | |
![]() |
7955308a0a | |
![]() |
21835644a0 | |
![]() |
5a585f845a | |
![]() |
f077609798 | |
![]() |
46a0da597d | |
![]() |
2070610a58 | |
![]() |
7d6fddc749 | |
![]() |
dadce5110c | |
![]() |
5d3dd15733 | |
![]() |
608bb3df4a | |
![]() |
b569740915 | |
![]() |
972869da47 | |
![]() |
e0a9d044cd | |
![]() |
912387c331 | |
![]() |
1135c5ddfa | |
![]() |
c1bc2fd5c5 | |
![]() |
d586c24792 | |
![]() |
d468912332 | |
![]() |
753afe24d7 | |
![]() |
c0e7e66ec3 | |
![]() |
fd07d2db3f | |
![]() |
8d95e159e2 | |
![]() |
9fac56f681 | |
![]() |
b709ce8aef | |
![]() |
4a89b04759 | |
![]() |
ec986b387b | |
![]() |
5c853150c8 | |
![]() |
f8b1c5104b | |
![]() |
d88675d521 | |
![]() |
e52c30f72e | |
![]() |
66c33e6679 | |
![]() |
cdd653e028 | |
![]() |
8515c0dcde | |
![]() |
3a7cb360af | |
![]() |
c7b566aaaa | |
![]() |
630ac466e7 | |
![]() |
3e6cda8950 | |
![]() |
f1d8838bc5 | |
![]() |
3faa8e2d95 | |
![]() |
3ddb1375eb | |
![]() |
73bf7fe77f | |
![]() |
533667b9ad | |
![]() |
aa7fd311d8 | |
![]() |
0760591021 | |
![]() |
04b24ea83b | |
![]() |
4b12f3da99 | |
![]() |
c6b23d4541 | |
![]() |
ae48729cff | |
![]() |
19b4a7974f | |
![]() |
0bdab33630 | |
![]() |
55d2c975cd | |
![]() |
ae0dc70ffa | |
![]() |
543f99a915 | |
![]() |
b5477d27ff | |
![]() |
9875bc10f7 | |
![]() |
45adb8992f | |
![]() |
3eba5de7f4 | |
![]() |
62d56846f4 | |
![]() |
770496b3af | |
![]() |
6e99822905 | |
![]() |
119b3332aa | |
![]() |
9ccf3a2c5e | |
![]() |
db89118b4c | |
![]() |
e7637de643 | |
![]() |
e0e9ae8753 | |
![]() |
5b959a972c | |
![]() |
788f926067 | |
![]() |
c87782f451 | |
![]() |
96de887308 | |
![]() |
aa63b20e7c | |
![]() |
cc936f5377 | |
![]() |
f4ed10b625 | |
![]() |
2fdd09b585 | |
![]() |
e20042848d | |
![]() |
1e9ba19db4 | |
![]() |
14b56f1667 | |
![]() |
227ab2cbf8 | |
![]() |
84e91104d5 | |
![]() |
44ed8788d5 | |
![]() |
022bb216eb | |
![]() |
e43a2843af | |
![]() |
bb4ebb105e | |
![]() |
b0db8b991c | |
![]() |
dd0c51b6e5 | |
![]() |
3d4f04902c | |
![]() |
e9c9274896 | |
![]() |
542f3e3225 | |
![]() |
976d822f58 | |
![]() |
819079c0f6 | |
![]() |
b62a744dfe | |
![]() |
eca4ed2559 | |
![]() |
9b55d7e924 | |
![]() |
0fc915b748 | |
![]() |
39d3d8d91c | |
![]() |
125d73982e | |
![]() |
0bc0d3b510 | |
![]() |
b8b9b095b7 | |
![]() |
48adeff932 | |
![]() |
a7de8f5f58 | |
![]() |
60fc450c88 | |
![]() |
1fb40645ed | |
![]() |
9ca328f468 | |
![]() |
d84504267b | |
![]() |
29ff436a00 | |
![]() |
c24920870d | |
![]() |
f4caba1561 | |
![]() |
3c76b804dc | |
![]() |
f71a491847 | |
![]() |
af45cc01ab | |
![]() |
31f670b74c | |
![]() |
0cdcc72bfb | |
![]() |
3ee7dec864 | |
![]() |
0f94c7b49c | |
![]() |
54ccd9b1ed | |
![]() |
3f4ba672b3 | |
![]() |
745abe176c | |
![]() |
301f9b2f27 | |
![]() |
ef295e9a24 | |
![]() |
a03a1d4c34 | |
![]() |
daec0e618f | |
![]() |
129a654b1d | |
![]() |
500d77c9ca | |
![]() |
8aa8f0c4df | |
![]() |
ec0c0a327f | |
![]() |
b4c2bbea45 | |
![]() |
5e5cb875cf | |
![]() |
576ca2b6c9 | |
![]() |
4113402908 | |
![]() |
249c94a5c1 | |
![]() |
101b170ea6 | |
![]() |
6d1732247a | |
![]() |
b7233b468e | |
![]() |
405deb3681 | |
![]() |
87ba87d2d1 | |
![]() |
cec388e94f | |
![]() |
0831144393 | |
![]() |
e60f066d31 | |
![]() |
f86f5a7bd0 | |
![]() |
f9daa3a289 | |
![]() |
91403b4ec0 | |
![]() |
5fb3fae741 | |
![]() |
7b53eb8e9e | |
![]() |
58bc741b7f | |
![]() |
a740ba3556 | |
![]() |
bca3ee7dd1 | |
![]() |
ba8e9f4724 | |
![]() |
6121d21bfb | |
![]() |
99a50ad86f | |
![]() |
2a6ee38850 | |
![]() |
11c720ad7f | |
![]() |
c1cf566c53 | |
![]() |
0d3d3a8c19 | |
![]() |
6d91ab6512 | |
![]() |
98abd5e92e | |
![]() |
6100083c9e | |
![]() |
6955ca6be2 | |
![]() |
17c2151d86 | |
![]() |
492d1f330b | |
![]() |
95c3dac962 | |
![]() |
42115e7d52 | |
![]() |
094ebea6cf | |
![]() |
7c2eb23bcd | |
![]() |
589e1ce3d1 | |
![]() |
1ddff9a1b7 | |
![]() |
636e3540c7 | |
![]() |
bc0f687352 | |
![]() |
2c7f3da7cc | |
![]() |
423146f981 | |
![]() |
2e19930565 | |
![]() |
de2a6657ea | |
![]() |
867ad7c954 | |
![]() |
54e50a54cb | |
![]() |
d809ddf703 | |
![]() |
e459bfb87d | |
![]() |
98e44db659 | |
![]() |
ede31bcf74 | |
![]() |
e89d5da250 | |
![]() |
4b6fc2d913 | |
![]() |
c825076e36 | |
![]() |
68f72bdfb3 | |
![]() |
ca42e09f8d | |
![]() |
a526cb8f15 | |
![]() |
f1df02c2b7 | |
![]() |
4dae2a0816 | |
![]() |
8303311d59 | |
![]() |
36bdd4f82b | |
![]() |
5f7cf529b9 | |
![]() |
66d32fabe8 | |
![]() |
750b7624e0 | |
![]() |
8b910c0d70 | |
![]() |
3b8201df04 | |
![]() |
79579053f1 | |
![]() |
d4413a1d78 | |
![]() |
5dbe54316b | |
![]() |
e41202d3ff | |
![]() |
14e7635458 | |
![]() |
ac486c5e1d | |
![]() |
9a1b81a026 | |
![]() |
4e7fda212d | |
![]() |
b25300b269 | |
![]() |
0c59e92fd7 | |
![]() |
2376a9dae9 | |
![]() |
020b4353a4 | |
![]() |
36bce9cf1f | |
![]() |
db13be44e3 | |
![]() |
95e32c4908 | |
![]() |
8bbe31324f | |
![]() |
f126e1c7a9 | |
![]() |
7e88052db3 | |
![]() |
67126a515a | |
![]() |
3a3385471b | |
![]() |
20fd22ec75 | |
![]() |
f1e87123f4 | |
![]() |
d40e21ea35 | |
![]() |
a759dc10bd | |
![]() |
b6b4082977 | |
![]() |
840f1b3b8f | |
![]() |
efccb5c7f1 | |
![]() |
dfb9e63d0e | |
![]() |
9e9fe45231 | |
![]() |
7a7d8f3dde | |
![]() |
f8c32c865b | |
![]() |
529edaf94e | |
![]() |
e1365ba9b5 | |
![]() |
16bc2d7be9 | |
![]() |
545baecdaa | |
![]() |
6339303569 | |
![]() |
62ae84d32d | |
![]() |
1f8514a737 | |
![]() |
5fd0bcb9ee | |
![]() |
47323b37f7 | |
![]() |
d8595e266f | |
![]() |
230a8c5454 | |
![]() |
db0aa06f38 | |
![]() |
32bddc543f | |
![]() |
0f5e3df9aa | |
![]() |
deeb54dc7c | |
![]() |
372974e1ad | |
![]() |
7c58a284ee | |
![]() |
04ed58102d | |
![]() |
a250a48499 | |
![]() |
ae8812de51 | |
![]() |
9ae54c80d6 | |
![]() |
048603ffe6 | |
![]() |
ab5db9aa24 | |
![]() |
c020fea642 | |
![]() |
2aa7cb7ca5 | |
![]() |
4dfa7da71f | |
![]() |
4cfcc61fb6 | |
![]() |
d9b37f8244 | |
![]() |
79a3d73882 | |
![]() |
d4ce8cdb6b | |
![]() |
d108e4a1dc | |
![]() |
fd216ca1f5 | |
![]() |
e18c5f35e3 | |
![]() |
d0ecc30f52 | |
![]() |
6ca6c51ea6 | |
![]() |
652b19cd0f | |
![]() |
72e7ccfe8a | |
![]() |
a64fccbf2c | |
![]() |
585c4111b6 | |
![]() |
05c93b8607 | |
![]() |
3d673d0338 | |
![]() |
c9e26d5638 | |
![]() |
0018f0e24c | |
![]() |
da66a8f272 | |
![]() |
d31d16581b | |
![]() |
31d3c2da56 | |
![]() |
b01b18ea2f | |
![]() |
bd5ff7031c | |
![]() |
9fa28726ed | |
![]() |
4fcee4d0e2 | |
![]() |
3be6245820 | |
![]() |
fa4a1a629d | |
![]() |
1b450b9e3d | |
![]() |
eeb723981d | |
![]() |
474cb6e4b2 | |
![]() |
51903c3df3 | |
![]() |
4d7a444246 | |
![]() |
e7e5bd7c7f | |
![]() |
18cce8472b | |
![]() |
36464be927 | |
![]() |
02134d29d5 | |
![]() |
59edca786d | |
![]() |
ed41be610a | |
![]() |
1c0506342e | |
![]() |
9f664ba5a6 | |
![]() |
9e462a480b | |
![]() |
df7f0d1f3c | |
![]() |
5d3e05511e | |
![]() |
6621920bec | |
![]() |
975a67ad44 | |
![]() |
ea1de0fb9e | |
![]() |
bd69ef1f59 | |
![]() |
c9a814759d | |
![]() |
95e860816c | |
![]() |
99db6a9406 | |
![]() |
8194c8a1b8 | |
![]() |
83e2e0ae20 | |
![]() |
35addd2b50 | |
![]() |
c33309abf6 | |
![]() |
4338fc4b07 | |
![]() |
6f83f1abf5 | |
![]() |
3488af5534 | |
![]() |
4ab1c09b8c | |
![]() |
e7a10eacdc | |
![]() |
37aa0237a8 | |
![]() |
371cec474f | |
![]() |
1de36fd1f5 | |
![]() |
4e70d32901 | |
![]() |
700e00b329 | |
![]() |
6082786f92 | |
![]() |
52f3a23d28 | |
![]() |
d62172ad88 | |
![]() |
6510ea0556 | |
![]() |
efec59cdbf | |
![]() |
ecb66471a3 | |
![]() |
e9ea54bc1b | |
![]() |
a14b7a8f80 | |
![]() |
0332137000 | |
![]() |
edd558de0e | |
![]() |
badaaa7dea | |
![]() |
710b67ca45 | |
![]() |
f2773376d9 | |
![]() |
6a30aa20f2 | |
![]() |
73584edd34 | |
![]() |
8d1bb63b0a | |
![]() |
e52083c42a | |
![]() |
73536707dc | |
![]() |
056db5141a | |
![]() |
bad5650027 | |
![]() |
12f829a0ca | |
![]() |
26cf943d25 | |
![]() |
6e0daf9335 | |
![]() |
7587b4f9cf | |
![]() |
cb791e8b69 | |
![]() |
73f0e1e998 | |
![]() |
adf7338f34 | |
![]() |
1e630ed825 | |
![]() |
f1a85d3726 | |
![]() |
972937e4a0 | |
![]() |
4a7d63bc7e | |
![]() |
caf64b2407 | |
![]() |
4bf8e0e209 | |
![]() |
0a21a2ec90 | |
![]() |
36339a07ff | |
![]() |
d0c71ba556 | |
![]() |
921b9ec2ba | |
![]() |
ab09bddcd8 | |
![]() |
bf57bf8a07 | |
![]() |
6d0779ca4d | |
![]() |
246f7eef62 | |
![]() |
73e9e71c3a | |
![]() |
aa4ba7ed52 | |
![]() |
b41b4b4d41 | |
![]() |
af7a6779a5 | |
![]() |
ecc02dcd55 | |
![]() |
d0a2291aa8 | |
![]() |
9aa01e4b89 | |
![]() |
2508268500 | |
![]() |
6217f4fb72 | |
![]() |
c72b7e7668 | |
![]() |
2dbb5cc696 | |
![]() |
341edd3784 | |
![]() |
4cd0b92792 | |
![]() |
3fc3e3c6e0 | |
![]() |
3c81cd5bf2 | |
![]() |
28428e0832 | |
![]() |
a5ba74dcd1 | |
![]() |
347ddbc45c | |
![]() |
89e990b1dd | |
![]() |
5c803db6ae | |
![]() |
bb350ab334 | |
![]() |
bd5e1d9a3b | |
![]() |
160017b6e8 | |
![]() |
44455a1fda | |
![]() |
973274bf22 | |
![]() |
93bb9ced2d | |
![]() |
f90547cee6 | |
![]() |
b136fa615d | |
![]() |
b5e02cad36 | |
![]() |
e5d2045350 | |
![]() |
373f5e9d37 | |
![]() |
d72734a828 | |
![]() |
ac26ffe271 | |
![]() |
7c091ed034 | |
![]() |
4523b3a58e | |
![]() |
57724aff67 | |
![]() |
e6cea19d5e | |
![]() |
0956ce6dff | |
![]() |
83c506252d | |
![]() |
7a2150430d | |
![]() |
01f8810bc3 | |
![]() |
f8978eb560 | |
![]() |
fb854a1d63 | |
![]() |
f04b67f69b | |
![]() |
53d76a61bb | |
![]() |
6ff3bee3e8 | |
![]() |
5e1d8c1976 | |
![]() |
53c2a337f3 | |
![]() |
b4ebf0cd16 | |
![]() |
ce43dea594 | |
![]() |
8ab0d66dda | |
![]() |
1341aed3d0 | |
![]() |
b2b143c22e | |
![]() |
88d8665e03 | |
![]() |
d19d6b6d81 | |
![]() |
eead8f24a8 | |
![]() |
51ea08ca88 | |
![]() |
048b484d83 | |
![]() |
57c17e05a3 | |
![]() |
48327bd570 | |
![]() |
742f00bf6a | |
![]() |
965eb6dfe9 | |
![]() |
be0ac321b3 | |
![]() |
5b6d50cf72 | |
![]() |
484b1fdf23 | |
![]() |
6dc482d997 | |
![]() |
15d4cdf512 | |
![]() |
dc566fc69a | |
![]() |
6c149b383c | |
![]() |
51641124b5 | |
![]() |
83b5c8f276 | |
![]() |
2596670aa3 | |
![]() |
6ef6a0b739 | |
![]() |
65af831152 | |
![]() |
e0cd57e6a9 | |
![]() |
0f0e190dd6 | |
![]() |
753402529e | |
![]() |
9e5ad966eb | |
![]() |
361f404f95 | |
![]() |
c1795e7310 | |
![]() |
eb87de143b | |
![]() |
8c5bc5633a | |
![]() |
f8ffe9218d | |
![]() |
c54032d99a | |
![]() |
165f6e71bb | |
![]() |
1536ad455a | |
![]() |
5bb5e8994c | |
![]() |
c0ad60d138 | |
![]() |
6a81c53af3 | |
![]() |
c2f581a31d | |
![]() |
45a3f46918 | |
![]() |
ebd4f6dbed | |
![]() |
2693389a3a | |
![]() |
8c22b41920 | |
![]() |
95008e5704 | |
![]() |
3f42023b42 | |
![]() |
a35d57e1cb | |
![]() |
6b7e88d465 | |
![]() |
c4c5eb11e3 | |
![]() |
b043542007 | |
![]() |
96bc072619 | |
![]() |
aaabc2cd4f | |
![]() |
0213c2f774 | |
![]() |
dffb554c8a | |
![]() |
4bc5435e6d | |
![]() |
2e65f08e0e | |
![]() |
5c83309aa3 | |
![]() |
da17ac2cc1 | |
![]() |
7edd8f8bc3 | |
![]() |
0682ca8c59 | |
![]() |
562968f9be | |
![]() |
93c2762653 | |
![]() |
1ab37ae48c | |
![]() |
bdedf37e5b | |
![]() |
5b7ac28e3c | |
![]() |
3297d07102 | |
![]() |
3176ae88bf | |
![]() |
32f5728ad6 | |
![]() |
ebcee727aa | |
![]() |
0131bae775 | |
![]() |
97f309af19 | |
![]() |
1915501026 | |
![]() |
9d4817007e | |
![]() |
b4f5221e3a | |
![]() |
c179d3082c | |
![]() |
5513656f35 | |
![]() |
1a54d6a557 | |
![]() |
38d3b04363 | |
![]() |
bbad66d0b8 | |
![]() |
1b5c0f819c | |
![]() |
d729d4f878 | |
![]() |
b2ffefdb27 | |
![]() |
09ecdb6f2c | |
![]() |
d3e0f31f9e | |
![]() |
f39069e40a | |
![]() |
0ffa04b3fd | |
![]() |
2e6e83e467 | |
![]() |
70c850e79e | |
![]() |
888b732f86 | |
![]() |
b0d2ccdba2 | |
![]() |
868efa8208 | |
![]() |
c788f5f15e | |
![]() |
b66ae83e37 | |
![]() |
bc1e8738a7 | |
![]() |
1ec393dc05 | |
![]() |
6c2f0a7bb5 | |
![]() |
f1b42156e1 | |
![]() |
c5659c03bf | |
![]() |
a984b46b5b | |
![]() |
090ad87ed9 | |
![]() |
9a1d655681 | |
![]() |
2715baa347 | |
![]() |
b61a2a01b0 | |
![]() |
de1e08e1ef | |
![]() |
3837142f9b | |
![]() |
c7918241f2 | |
![]() |
9dc99ba602 | |
![]() |
a7cd923e27 | |
![]() |
e10f27b26f | |
![]() |
a4cfebcc17 | |
![]() |
f63fe62445 | |
![]() |
3da8865a15 | |
![]() |
7c5fcd24c6 | |
![]() |
458ef30e90 | |
![]() |
7c69ce9b0c | |
![]() |
4d499da343 | |
![]() |
68b9bfda08 | |
![]() |
d75ae6d86b | |
![]() |
ff79618182 | |
![]() |
c0f3bac70a | |
![]() |
89859c0898 | |
![]() |
b14cd13063 | |
![]() |
a2b63b8f07 | |
![]() |
57629c1547 | |
![]() |
0f66b0cbae | |
![]() |
f8fff02777 | |
![]() |
3542374d92 | |
![]() |
d8ba7316fe | |
![]() |
360713458c | |
![]() |
832b87d92a | |
![]() |
0234b3d059 | |
![]() |
2191794f38 | |
![]() |
33fb6db33c | |
![]() |
3cbc63b7c3 | |
![]() |
a4891b01a8 | |
![]() |
96f4fd03b8 | |
![]() |
ad08d4c4ae | |
![]() |
7222bfa9ab | |
![]() |
c62fb709d1 | |
![]() |
e2c40262dd | |
![]() |
82cc021f3c | |
![]() |
e3051a7525 | |
![]() |
13e40cefa8 | |
![]() |
8a6aac0129 | |
![]() |
db2de48133 | |
![]() |
a6b74156f6 | |
![]() |
05b0c04b6d | |
![]() |
b2932f1b86 | |
![]() |
c11b390533 | |
![]() |
262589cfdc | |
![]() |
606bf9147f | |
![]() |
84dbf05b3e | |
![]() |
5fb5a7ab3f | |
![]() |
277c6f3e0f | |
![]() |
d5bbf4f678 | |
![]() |
9664acbe85 | |
![]() |
50127eaa90 | |
![]() |
6de5ba342c | |
![]() |
2afd25fd09 | |
![]() |
1753da1016 | |
![]() |
434d5d4286 | |
![]() |
d27ba7879c | |
![]() |
37787be647 | |
![]() |
e0199b2e6e | |
![]() |
daafd8e911 | |
![]() |
ded6ce2c2a | |
![]() |
9b170349d1 | |
![]() |
d683625444 | |
![]() |
f0bcaf546a | |
![]() |
718cfc7338 | |
![]() |
975bd14635 | |
![]() |
7d556beb11 | |
![]() |
985b3b1972 | |
![]() |
76bec5c438 | |
![]() |
6a68be5161 | |
![]() |
15157a213a | |
![]() |
85b661f2cd | |
![]() |
c61adf1230 | |
![]() |
99fbfeca90 | |
![]() |
9308081714 | |
![]() |
6b87fbeb90 | |
![]() |
7fad94eeb6 | |
![]() |
56e92c648c | |
![]() |
afb9fabef3 | |
![]() |
43e850f113 | |
![]() |
544ae925e2 | |
![]() |
82e56aa9f3 | |
![]() |
901050a32f | |
![]() |
93f9e9ac02 | |
![]() |
3d30e4fcfc | |
![]() |
4bc881378b | |
![]() |
827934dfa6 | |
![]() |
7bccdd2ab1 | |
![]() |
10e089379b | |
![]() |
3bf251bc0d | |
![]() |
60ba918a7a | |
![]() |
8922124d21 | |
![]() |
cbdf0e2886 | |
![]() |
bfd163e50f | |
![]() |
0ce73efeaa | |
![]() |
68a8fbdcf4 | |
![]() |
d50770abe1 | |
![]() |
b7908bc2ea | |
![]() |
d2fe2a82e2 | |
![]() |
00b5829fe9 | |
![]() |
fd1f13eb33 | |
![]() |
8324d32f01 | |
![]() |
7bd1dfa044 | |
![]() |
e1dc9926e0 | |
![]() |
3ad6d7ae56 | |
![]() |
f48b61c776 | |
![]() |
a11c9eead0 | |
![]() |
d5749ecd7d | |
![]() |
ef59d52698 | |
![]() |
bec1cd08d3 | |
![]() |
0698165193 | |
![]() |
181869a663 | |
![]() |
fd3e7e4c87 | |
![]() |
bd300ed881 | |
![]() |
6ab484848d | |
![]() |
e097c2c01e | |
![]() |
95cfdaf04d | |
![]() |
da5ffa7794 | |
![]() |
5e929b7ef6 | |
![]() |
0dd0d3d8af | |
![]() |
1834b93cb3 | |
![]() |
eecef35305 | |
![]() |
1d72309959 | |
![]() |
4a2062644b | |
![]() |
cffbb7ff5c | |
![]() |
60a234a95d | |
![]() |
7a0958cf13 | |
![]() |
a760def865 | |
![]() |
9caf014c07 | |
![]() |
bc1d88c8d3 | |
![]() |
699f5b46e7 | |
![]() |
30a83667ee | |
![]() |
d5f1fd4d19 | |
![]() |
3d8bccdb52 | |
![]() |
244cb9ab17 | |
![]() |
81bca0543f | |
![]() |
9f5a141701 | |
![]() |
b6031cd111 | |
![]() |
daa645ac58 | |
![]() |
2681f19c19 | |
![]() |
e2da54fa54 | |
![]() |
9d4e68ca5c | |
![]() |
dca852ed89 | |
![]() |
64fd4daa1d | |
![]() |
506f48f4dd | |
![]() |
31392a067f | |
![]() |
da5001bd31 | |
![]() |
45f8871740 | |
![]() |
37f0c7f796 | |
![]() |
f24b2157a6 | |
![]() |
87e7965627 | |
![]() |
4483f6f052 | |
![]() |
1ab5351461 | |
![]() |
dcfc315c17 | |
![]() |
9cd17ca212 | |
![]() |
8ffef8ff7d | |
![]() |
6b1722b354 | |
![]() |
09bde0577d | |
![]() |
476619eb44 | |
![]() |
121ace9ec3 | |
![]() |
985d027939 | |
![]() |
13670b1620 | |
![]() |
b5ac812ff4 | |
![]() |
01a235fd88 | |
![]() |
6ef016cc5f | |
![]() |
0132cdd33b | |
![]() |
47317b512b | |
![]() |
d5aaae43fc | |
![]() |
cc2e66e0b9 | |
![]() |
ec00702fe0 | |
![]() |
a9d0120c3d | |
![]() |
8292c17674 | |
![]() |
42faaae5de | |
![]() |
15f6f3b920 | |
![]() |
d2a298a1d6 | |
![]() |
2b5e8ee968 | |
![]() |
680c089c1c | |
![]() |
aa66a8d1d0 | |
![]() |
0c847f2378 | |
![]() |
50ead387bb | |
![]() |
54ada93bdd | |
![]() |
6f4fa68427 | |
![]() |
3df46a118a | |
![]() |
bbe797fcc8 | |
![]() |
92a5a372c4 | |
![]() |
54a9a79e98 | |
![]() |
f62a315dc0 | |
![]() |
589e0aaf61 | |
![]() |
1d2c108fa9 | |
![]() |
65a10335a3 | |
![]() |
9a7aebc98d | |
![]() |
34ea7f495e | |
![]() |
bb613d1017 | |
![]() |
d974134ee4 | |
![]() |
6bec8f19ea | |
![]() |
dca8fa5bf4 | |
![]() |
9ad7493e1d | |
![]() |
ffcccbb71c | |
![]() |
363fd98d24 | |
![]() |
57fdbe72f9 | |
![]() |
a1de2c64e2 | |
![]() |
f7e18f45a3 | |
![]() |
54663179cb | |
![]() |
1ede33365b | |
![]() |
526646bb79 | |
![]() |
f50c94d0ed | |
![]() |
3c1e0e87a9 | |
![]() |
0399b57c0e | |
![]() |
a0fbf826c0 | |
![]() |
8a35d741f6 | |
![]() |
6ab22417bf | |
![]() |
4fb521e219 | |
![]() |
0254a78e27 | |
![]() |
dfd4f6dadd | |
![]() |
1250b4b0de | |
![]() |
5dc7be69a9 | |
![]() |
0e44f9683c | |
![]() |
178c295605 | |
![]() |
97fe1a43bd | |
![]() |
7ed8638658 | |
![]() |
abb21a6d80 | |
![]() |
bf3e88ace0 | |
![]() |
3a9388d063 | |
![]() |
e3fd3833eb | |
![]() |
bf69fb7d28 | |
![]() |
e8b69bfa72 | |
![]() |
c2f76c7190 | |
![]() |
00660a6332 | |
![]() |
c5d91dd6c7 | |
![]() |
78f04cafbd | |
![]() |
4af0801afb | |
![]() |
d19b374fe9 | |
![]() |
053829ca78 | |
![]() |
6635eb5c74 | |
![]() |
ee262e81a4 | |
![]() |
91914d675a | |
![]() |
19304a4613 | |
![]() |
c4dd999294 | |
![]() |
5d1f5ab4d7 | |
![]() |
e76e823a3d | |
![]() |
3c4cc04e14 | |
![]() |
3407564589 | |
![]() |
c4b1f58a28 | |
![]() |
5871978520 | |
![]() |
15252000d0 | |
![]() |
c8185984c3 | |
![]() |
0b56046bb8 | |
![]() |
25fb2096d3 | |
![]() |
f66e0e41aa | |
![]() |
fb30b28c12 | |
![]() |
42108cb69d | |
![]() |
fc8f5814f1 | |
![]() |
0e5468b7bf | |
![]() |
06c5933cd1 | |
![]() |
0d170ead3a | |
![]() |
bf6b64bf3f | |
![]() |
b2e2c890db | |
![]() |
5ec60597b0 | |
![]() |
eff8f1f522 | |
![]() |
7444c3b612 | |
![]() |
9becda6e83 | |
![]() |
ba08d1b890 | |
![]() |
fe2ed88a23 | |
![]() |
ca6da03bcb | |
![]() |
8ae1cbd920 | |
![]() |
fa1691b511 | |
![]() |
cf7187666a | |
![]() |
5ae4314ac7 | |
![]() |
21c20933f3 | |
![]() |
6910d6e707 | |
![]() |
f333b53a73 | |
![]() |
9b620e4a67 | |
![]() |
cb60eee6f8 | |
![]() |
7cbdd2e431 | |
![]() |
8c8f18ec9a | |
![]() |
ef28c52f77 | |
![]() |
f5250bab6a |
|
@ -0,0 +1 @@
|
|||
* text eol=lf
|
|
@ -0,0 +1 @@
|
|||
custom: https://numfocus.salsalabs.org/donate-to-julia/index.html
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
name: bug report
|
||||
about: create a bug report
|
||||
title: "[BUG]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid duplicates. -->
|
||||
|
||||
## description
|
||||
|
||||
|
||||
## versions
|
||||
|
||||
> `using InteractiveUtils; versioninfo()`:
|
||||
<!-- please paste the the output of `using InteractiveUtils; versioninfo()` in the backticks below -->
|
||||
```julia
|
||||
|
||||
```
|
||||
|
||||
> `using Pkg; Pkg.status()`:
|
||||
<!-- please paste the the output of `using Pkg; Pkg.status()` in the backticks below -->
|
||||
```julia
|
||||
|
||||
```
|
||||
|
||||
|
||||
## minimum reproducible steps
|
||||
|
||||
<!-- if possible, paste here a minimum reproducible example document and steps -->
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
name: enhancement
|
||||
about: suggest an enhancement idea
|
||||
title: "[FR]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid duplicates. -->
|
||||
|
||||
## description
|
|
@ -0,0 +1,19 @@
|
|||
name: CompatHelper
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 00 * * *'
|
||||
|
||||
jobs:
|
||||
CompatHelper:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: julia-actions/setup-julia@latest
|
||||
with:
|
||||
version: 1.3
|
||||
- name: Pkg.add("CompatHelper")
|
||||
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
|
||||
- name: CompatHelper.main()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: julia -e 'using CompatHelper; CompatHelper.main()'
|
|
@ -0,0 +1,11 @@
|
|||
name: TagBot
|
||||
on:
|
||||
schedule:
|
||||
- cron: 0 * * * *
|
||||
jobs:
|
||||
TagBot:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: JuliaRegistries/TagBot@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -0,0 +1,67 @@
|
|||
# TODO: build docs via github-actions
|
||||
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
jobs:
|
||||
test:
|
||||
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.allow-failure }}
|
||||
strategy:
|
||||
fail-fast: false # don't stop CI even when one of them fails
|
||||
matrix:
|
||||
version:
|
||||
- '1.5'
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macOS-latest
|
||||
# - windows-latest # TODO: test on Windows
|
||||
arch:
|
||||
- x64
|
||||
- x86
|
||||
allow-failure: [false]
|
||||
include:
|
||||
# this is so verbose... any other way to simplify this ?
|
||||
- version: 'nightly'
|
||||
os: ubuntu-latest
|
||||
arch: x64
|
||||
allow-failure: true
|
||||
- version: 'nightly'
|
||||
os: ubuntu-latest
|
||||
arch: x86
|
||||
allow-failure: true
|
||||
- version: 'nightly'
|
||||
os: macOS-latest
|
||||
arch: x64
|
||||
allow-failure: true
|
||||
# - version: 'nightly'
|
||||
# os: windows-latest
|
||||
# arch: x64
|
||||
# allow-failure: true
|
||||
# - version: 'nightly'
|
||||
# os: windows-latest
|
||||
# arch: x86
|
||||
# allow-failure: true
|
||||
exclude:
|
||||
- os: macOS-latest
|
||||
arch: x86
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: julia-actions/setup-julia@v1
|
||||
with:
|
||||
version: ${{ matrix.version }}
|
||||
arch: ${{ matrix.arch }}
|
||||
- uses: julia-actions/julia-buildpkg@latest
|
||||
- uses: julia-actions/julia-runtest@latest
|
||||
- uses: julia-actions/julia-processcoverage@v1
|
||||
- uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: ./lcov.info
|
||||
flags: unittests
|
||||
name: codecov-umbrella
|
||||
fail_ci_if_error: false
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
|
@ -1,24 +1,29 @@
|
|||
|
||||
src/*.cov
|
||||
test.jl
|
||||
examples/figures/
|
||||
examples/*.md
|
||||
examples/*.pdf
|
||||
examples/*.html
|
||||
examples/*.rst
|
||||
examples/*.tex
|
||||
test/documents/figures
|
||||
test/documents/*.tex
|
||||
test/documents/*.md
|
||||
test/documents/*.rst
|
||||
test/documents/*.html
|
||||
test/documents/*.pdf
|
||||
!test/documents/*ref.*
|
||||
|
||||
|
||||
tmp/
|
||||
.idea
|
||||
*.*~
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
Manifest.toml
|
||||
|
||||
examples/figures/
|
||||
examples/*.md
|
||||
examples/*.pdf
|
||||
examples/*.html
|
||||
examples/*.rst
|
||||
examples/*.tex
|
||||
test/**/cache
|
||||
test/**/figures
|
||||
test/documents/output/gadfly_formats_test.txt
|
||||
test/**/*.tex
|
||||
test/**/*.md
|
||||
test/**/*.rst
|
||||
test/**/*.html
|
||||
test/**/*.pdf
|
||||
test/**/*.png
|
||||
test/**/chunk_options.jl
|
||||
test/**/*.ipynb
|
||||
!test/**/*ref.*
|
||||
|
||||
doc/build
|
||||
doc/site
|
||||
|
||||
.idea
|
||||
*.*~
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
|
|
35
.travis.yml
35
.travis.yml
|
@ -1,25 +1,14 @@
|
|||
language: cpp
|
||||
compiler:
|
||||
- clang
|
||||
language: julia
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: "Documentation"
|
||||
julia: 1.5
|
||||
os: linux
|
||||
script:
|
||||
- julia --project=doc/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
|
||||
- julia --project=doc/ doc/make.jl
|
||||
after_success: skip
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
env:
|
||||
matrix:
|
||||
- JULIAVERSION="juliareleases"
|
||||
- JULIAVERSION="julianightlies"
|
||||
before_install:
|
||||
#- wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh
|
||||
#- chmod +x miniconda.sh
|
||||
#- ./miniconda.sh -b
|
||||
#- export PATH=/home/travis/miniconda/bin:$PATH
|
||||
#- conda update --yes conda
|
||||
#- conda install --yes matplotlib
|
||||
- sudo add-apt-repository ppa:staticfloat/julia-deps -y
|
||||
- sudo add-apt-repository ppa:staticfloat/${JULIAVERSION} -y
|
||||
- sudo apt-get update -qq -y
|
||||
- sudo apt-get install libpcre3-dev julia python-matplotlib -y
|
||||
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
|
||||
script:
|
||||
- xvfb-run julia -e 'Pkg.init(); Pkg.add("PyPlot"); Pkg.add("Winston"); Pkg.add("Cairo"); Pkg.add("Gadfly"); Pkg.clone(pwd()); Pkg.test("Weave", coverage=true)'
|
||||
after_success:
|
||||
- julia -e 'cd(Pkg.dir("Weave")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
|
||||
|
|
40
LICENSE.md
40
LICENSE.md
|
@ -1,22 +1,20 @@
|
|||
The Weave.jl package is licensed under the MIT "Expat" License:
|
||||
Copyright (c) 2020: Contributors
|
||||
|
||||
> Copyright (c) 2014: Matti Pastell.
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining
|
||||
> a copy of this software and associated documentation files (the
|
||||
> "Software"), to deal in the Software without restriction, including
|
||||
> without limitation the rights to use, copy, modify, merge, publish,
|
||||
> distribute, sublicense, and/or sell copies of the Software, and to
|
||||
> permit persons to whom the Software is furnished to do so, subject to
|
||||
> the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be
|
||||
> included in all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
## Release notes for Weave.jl
|
||||
|
||||
### v0.10.6 – 2020/10/03
|
||||
|
||||
improvements:
|
||||
- cleaned up chunk rendering (removed unnecessary extra newlines): #401
|
||||
- `WEAVE_ARGS` now can take arbitrary objects: https://github.com/JunoLab/Weave.jl/commit/c24a2621359b5d0af1bb6825f488e58cc11b8a9e
|
||||
- improved docs: #397 by @baggepinnen
|
||||
|
||||
bug fixes
|
||||
- fixed #398: #399
|
||||
- removed unnecessary quote for markdown output: https://github.com/JunoLab/Weave.jl/commit/a1830e05029f33195627ec5dedbacb30af23947e
|
||||
- fixed #386: #396 by @torfjelde
|
||||
|
||||
|
||||
### v0.10 – 2020/05/18
|
||||
|
||||
improvements:
|
||||
- `weave` is now integrated with Juno's progress bar; just call `weave` function inside Juno or use `julia-client: weave-to-html(pdf)` command (#331)
|
||||
- document metadata in YAML header can be given dynamically (#329)
|
||||
- headers are now striped more gracefully; only Weave.jl related header is stripped when weaving to `github` or `hugo` document (#329, #305)
|
||||
- `WeavePlots`/`GadflyPlots` won't be loaded into `Main` module (#322)
|
||||
- un`const` bindings in a sandbox module are correctly cleared, helping GC free as much memory usage as possible (#317)
|
||||
- keep latex figures even if weaving failed (#302)
|
||||
- bunch of documentation improvements (#297, #295)
|
||||
- code size in HTML header is now not hardcoded, leading to more readable font size (#281)
|
||||
|
||||
bug fixes:
|
||||
- display of "big" object is fixed and limited (#311)
|
||||
- fix dependencies issues
|
||||
|
||||
internal:
|
||||
- bunch of internal refactors, code clean up (#330, #327, #325, #321, #320, #319, #318, #313)
|
||||
- internal error now doesn't mess up display system (#316)
|
||||
- format code base (#312)
|
||||
|
||||
breaking change:
|
||||
- `options` YAML key is deprecated, use `weave_options` key instead (#334)
|
||||
- `set_chunk_defaults` is now renamed to `set_chunk_defaults!` (#323)
|
||||
- `restore_chunk_defaults` is now renamed to `restore_chunk_defaults!` (#323)
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
### v0.4.1
|
||||
|
||||
* Disable precompilation due to warnings from dependencies
|
||||
* Fix deprecation warnings for Julia 0.6
|
||||
* Fix PyPlot for Julia 0.6
|
||||
* Support citations in `pandoc2html` and `pandoc2pdf` output
|
||||
* Fix extra whitespace when `term=true`
|
||||
* Fix mime type priority for `md2html`
|
||||
|
||||
|
||||
### V0.4.0
|
||||
|
||||
* Support passing arguments to document using `args` option
|
||||
* Add `include_weave` for including code from Weave documents
|
||||
* Add support for inline code chunks
|
||||
* Remove generated figure files when publishing to html and pdf
|
||||
|
||||
|
||||
### v0.3.0
|
||||
|
||||
* Add support for YAML title block
|
||||
* Use Julia markdown for publishing to pdf and html
|
||||
* Add `template`, `highlight_theme`, `latex_cmd` and `css` option to `weave` for customizing html and pdf output
|
||||
* Bug fixes
|
||||
* Fix plotting on Windows
|
||||
* Fix extra whitespace from code chunk output
|
||||
* Improved GR and GLVisualize support with Plots
|
||||
|
||||
|
||||
### v0.2.2
|
||||
|
||||
* Add IJulia notebook as input format
|
||||
* Add `convert_doc` method to convert between input formats
|
||||
|
||||
|
||||
### v0.2.1
|
||||
|
||||
* Fix critical hanging on Windows using proper handling of redirect_stdout
|
||||
* Add support for Plots.jl plotly and plotlyjs backends for including javascipt
|
||||
output in published HTML documents.
|
||||
* Fix semicolons for `term=true`
|
||||
|
||||
|
||||
### v0.2
|
||||
|
||||
* Move to Julia 0.5 only
|
||||
* New `display` and `prompt` chunk options by @gragusa
|
||||
* Implemented fig_width and fig_height chunk option for Plots.jl
|
||||
* Added pre and post chunk hooks, only used internally for now
|
||||
* Automatic detection of plotting library, `:auto` is the new default options
|
||||
* Support for displaying general multimedia objects e.g. Plots.jl and Images.jl
|
||||
now work with weave.
|
||||
* Support for including html, latex and markdown output from objects
|
||||
* New logic for displaying output in script chunks, output is shown by default for:
|
||||
- Writing to stdout
|
||||
- Calling display
|
||||
- Gadfly plots
|
||||
- Variables on their own
|
||||
- If the last line of a chunk is a function call that returns output e.g. plot(1:10)
|
||||
* Bug fixes
|
||||
- Fix parsing of lone variables from chunks
|
||||
- Fix error with md2html formatter and dates #38
|
||||
|
||||
|
||||
### v0.1.2
|
||||
|
||||
27th April 2016
|
||||
|
||||
* Fix a bug with `out_path` for md2html and md2pdf
|
||||
* Fix md2html and md2pdf on Windows
|
||||
* Improve doctype autodetection
|
||||
* Improved regex for parsing markdown input format
|
||||
|
||||
|
||||
### v0.1.1
|
||||
|
||||
* Change pandoc output to use inline images if there is no caption.
|
||||
* Use Documenter.jl for documentation.
|
||||
* Add chunk option `hold`, replaces results = "hold". This way you can use e.g. `hold = true, results=raw`.
|
||||
* Methods for setting and restoring default chunk options for documents.
|
||||
* New output options `md2pdf` and `md2html`, both use pandoc to output pdf
|
||||
and html files directly with own templates.
|
||||
* Restored and improved Winston support.
|
||||
* New input format: scripts with markup in comments
|
||||
* New output format: MultiMarkdown
|
||||
* Added support for figure width in Pandoc
|
||||
* Autodetect input and output formats based on filename
|
||||
* Allow `out_path` be a file or directory.
|
||||
|
||||
|
||||
### v0.1.0
|
||||
|
||||
19th April 2016
|
||||
|
||||
* Updated for Julia 0.4x, drop 0.3x support
|
||||
* Each document is executed in separate sandbox module instead of redefining the same one. Fixes warnings and occasional segfaults.
|
||||
* Change the output of chunks:
|
||||
- Output will be added to the output directly where they are created (default).
|
||||
- Use results = "hold" to push all output after the chunk.
|
||||
* New chunk option: `line_width`.
|
||||
* Winston support is not implemented yet for this version.
|
||||
* Bug fix in wrapping output lines.
|
||||
* Internal changes
|
||||
- Chunks are now represented with their own type. Allows multiple dispatch
|
||||
and easier implementation of new chunks.
|
||||
|
||||
|
||||
### 0.0.4
|
||||
|
||||
4th January 2015
|
||||
|
||||
* Added AsciiDoc formatter
|
||||
* Default plotting library changed to Gadfly
|
||||
* New option: `out_path` for controlling where weaved documents and figures are saved
|
||||
* Command line script `bin/weave.jl` for calling weave from command line
|
||||
|
||||
|
||||
### 0.0.3
|
||||
|
||||
9th December 2014
|
||||
|
||||
* Sandbox module for running code is cleared between documents
|
||||
* Fixed Latex figure handling (with contributions from @wildart)
|
||||
* Changed "tex" format: separate environment for term chunks
|
||||
* Improved test coverage
|
||||
* Fixed a bug with eval=false chunk option.
|
||||
|
||||
|
||||
### 0.0.2
|
||||
|
||||
7th December 2014
|
||||
|
||||
First release:
|
||||
- Noweb and markdown input formats
|
||||
- Support for Gadfly, Winston and PyPlot figures
|
||||
- Term and script chunks
|
||||
- Support for markdown, tex and rst output
|
|
@ -0,0 +1,37 @@
|
|||
name = "Weave"
|
||||
uuid = "44d3d7a6-8a23-5bf8-98c5-b353f8df5ec9"
|
||||
version = "0.10.12"
|
||||
|
||||
[deps]
|
||||
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||
Highlights = "eafb193a-b7ab-5a9e-9068-77385905fa72"
|
||||
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
||||
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
||||
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
|
||||
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
||||
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||||
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||||
RelocatableFolders = "05181044-ff0b-4ac5-8273-598c1e38db00"
|
||||
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
|
||||
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
||||
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
||||
|
||||
[compat]
|
||||
Highlights = "0.3.1, 0.4, 0.5"
|
||||
JSON = "0.21"
|
||||
Mustache = "0.4.1, 0.5, 1"
|
||||
Plots = "0.28, 0.29, 1.0"
|
||||
RelocatableFolders = "0.1,0.2,0.3,1"
|
||||
Requires = "1.0"
|
||||
YAML = "0.3, 0.4"
|
||||
julia = "1.2"
|
||||
|
||||
[extras]
|
||||
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
||||
Gadfly = "c91e804a-d5a3-530f-b6f0-dfbca275c004"
|
||||
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||
|
||||
[targets]
|
||||
test = ["DataFrames", "Test"]
|
182
README.md
182
README.md
|
@ -1,78 +1,104 @@
|
|||
# Weave
|
||||
|
||||
[![Build Status](https://travis-ci.org/mpastell/Weave.jl.svg?branch=master)](https://travis-ci.org/mpastell/Weave.jl)[![Coverage Status](https://img.shields.io/coveralls/mpastell/Weave.jl.svg)](https://coveralls.io/r/mpastell/Weave.jl?branch=master)
|
||||
|
||||
Weave is a scientific report generator/literate programming tool
|
||||
for Julia. It resembles [Pweave](http://mpastell.com/pweave) and, Knitr
|
||||
and Sweave.
|
||||
|
||||
|
||||
**Current features**
|
||||
|
||||
* Noweb or markdown syntax for input documents.
|
||||
* Execute code as terminal or "script" chunks.
|
||||
* Capture PyPlot, Gadfly or Winston figures.
|
||||
* Supports LaTex, Pandoc and Github markdown and reStructuredText output
|
||||
|
||||
|
||||
## Chunk options
|
||||
|
||||
I've tried to follow [Knitr](http://yihui.name/knitr/options)'s naming for chunk options, but not all options are implemented.
|
||||
You can see [`src/config.jl`](https://github.com/mpastell/Weave.jl/blob/master/src/config.jl) for the current situation.
|
||||
|
||||
Options are separated using ";" and need to be valid Julia expressions. e.g.
|
||||
|
||||
<<term=true; fig_width=6; fig_height=4>>=
|
||||
|
||||
## File formats
|
||||
|
||||
You can get a list of supported output formats:
|
||||
|
||||
````julia
|
||||
julia> list_out_formats()
|
||||
pandoc: Pandoc markdown
|
||||
rst: reStructuredText and Sphinx
|
||||
texminted: Latex using minted for highlighting
|
||||
github: Github markdown
|
||||
tex: Latex with custom code environments
|
||||
````
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Run from julia:
|
||||
|
||||
````julia
|
||||
using Weave
|
||||
weave(Pkg.dir("Weave","examples","julia_sample.mdw")
|
||||
````
|
||||
|
||||
Using Winston for plots (Julia 0.3 only):
|
||||
|
||||
````julia
|
||||
weave(Pkg.dir("Weave","examples","winston_sample.mdw"),
|
||||
plotlib="Winston", doctype="pandoc")
|
||||
````
|
||||
|
||||
Using Gadfly (Julia 0.3 only):
|
||||
|
||||
````julia
|
||||
weave(Pkg.dir("Weave","examples","gadfly_sample.mdw"), plotlib="Gadfly")
|
||||
````
|
||||
|
||||
The signature of weave functions is:
|
||||
|
||||
````julia
|
||||
function weave(source ; doctype = "pandoc",
|
||||
plotlib="PyPlot", informat="noweb", fig_path = "figures", fig_ext = nothing)
|
||||
````
|
||||
|
||||
**Note:** Run Weave from terminal and not using IJulia, Juno or ESS, they tend to mess with capturing output.
|
||||
|
||||
## Contributing
|
||||
|
||||
I will probably add new features to Weave when I need them myself or if they are requested and not too difficult to implement. You can contribute by opening issues on Github or implementing things yourself and making a pull request. I'd also appreciate example documents written using Weave to add to examples.
|
||||
|
||||
## Contributors
|
||||
|
||||
Douglas Bates has contributed a number of important fixes and comments.
|
||||
# Weave
|
||||
|
||||
![CI](https://github.com/JunoLab/Weave.jl/workflows/CI/badge.svg)
|
||||
[![codecov](https://codecov.io/gh/JunoLab/Weave.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JunoLab/Weave.jl)
|
||||
[![](https://img.shields.io/badge/docs-stable-blue.svg)](http://weavejl.mpastell.com/stable/)
|
||||
[![](https://img.shields.io/badge/docs-dev-blue.svg)](http://weavejl.mpastell.com/dev/)
|
||||
[![](http://joss.theoj.org/papers/10.21105/joss.00204/status.svg)](http://dx.doi.org/10.21105/joss.00204)
|
||||
|
||||
Weave is a scientific report generator/literate programming tool for the [Julia programming language](https://julialang.org/).
|
||||
It resembles
|
||||
[Pweave](http://mpastell.com/pweave),
|
||||
[knitr](https://yihui.org/knitr/),
|
||||
[R Markdown](https://rmarkdown.rstudio.com/),
|
||||
and [Sweave](https://stat.ethz.ch/R-manual/R-patched/library/utils/doc/Sweave.pdf).
|
||||
|
||||
You can write your documentation and code in input document using Markdown, Noweb or ordinal Julia script syntax,
|
||||
and then use `weave` function to execute code and generate an output document while capturing results and figures.
|
||||
|
||||
**Current features**
|
||||
|
||||
- Publish markdown directly to HTML and PDF using Julia or [Pandoc](https://pandoc.org/MANUAL.html)
|
||||
- Execute code as in terminal or in a unit of code chunk
|
||||
- Capture [Plots.jl](https://github.com/JuliaPlots/Plots.jl) or [Gadfly.jl](https://github.com/GiovineItalia/Gadfly.jl) figures
|
||||
- Supports various input format: Markdown, [Noweb](https://www.cs.tufts.edu/~nr/noweb/), [Jupyter Notebook](https://jupyter.org/), and ordinal Julia script
|
||||
- Conversions between those input formats
|
||||
- Supports various output document formats: HTML, PDF, GitHub markdown, Jupyter Notebook, MultiMarkdown, Asciidoc and reStructuredText
|
||||
- Simple caching of results
|
||||
|
||||
**Citing Weave:** *Pastell, Matti. 2017. Weave.jl: Scientific Reports Using Julia. The Journal of Open Source Software. http://dx.doi.org/10.21105/joss.00204*
|
||||
|
||||
![Weave in Juno demo](https://user-images.githubusercontent.com/40514306/76081328-32f41900-5fec-11ea-958a-375f77f642a2.png)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
You can install the latest release using Julia package manager:
|
||||
|
||||
```julia
|
||||
using Pkg
|
||||
Pkg.add("Weave")
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```julia
|
||||
using Weave
|
||||
|
||||
# add depencies for the example
|
||||
using Pkg; Pkg.add(["Plots", "DSP"])
|
||||
|
||||
filename = normpath(Weave.EXAMPLE_FOLDER, "FIR_design.jmd")
|
||||
weave(filename, out_path = :pwd)
|
||||
```
|
||||
|
||||
If you have LaTeX installed you can also weave directly to pdf.
|
||||
|
||||
```julia
|
||||
filename = normpath(Weave.EXAMPLE_FOLDER, "FIR_design.jmd")
|
||||
weave(filename, out_path = :pwd, doctype = "md2pdf")
|
||||
```
|
||||
|
||||
NOTE: `Weave.EXAMPLE_FOLDER` just points to [`examples` directory](./examples).
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
Documenter.jl with MKDocs generated documentation:
|
||||
|
||||
[![](https://img.shields.io/badge/docs-stable-blue.svg)](http://weavejl.mpastell.com/stable/)
|
||||
[![](https://img.shields.io/badge/docs-dev-blue.svg)](http://weavejl.mpastell.com/dev/)
|
||||
|
||||
|
||||
## Editor support
|
||||
|
||||
Install [language-weave](https://atom.io/packages/language-weave) to add Weave support to Juno.
|
||||
It allows running code from Weave documents with usual keybindings and allows preview of
|
||||
html and pdf output.
|
||||
|
||||
The [Julia extension for Visual Studio Code](https://www.julia-vscode.org/)
|
||||
adds Weave support to [Visual Studio Code](https://code.visualstudio.com/).
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
You can contribute to this package by opening issues on GitHub or implementing things yourself and making a pull request.
|
||||
We'd also appreciate more example documents written using Weave.
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
You can see the list of contributors on GitHub: https://github.com/JunoLab/Weave.jl/graphs/contributors .
|
||||
Thanks for the important additions, fixes and comments.
|
||||
|
||||
|
||||
## Example projects using Weave
|
||||
|
||||
- [DiffEqTutorials.jl](https://github.com/JuliaDiffEq/DiffEqTutorials.jl) uses Weave to output tutorials (`.jmd` documents) to html, pdf and Jupyter notebooks.
|
||||
- [TuringTutorials](https://github.com/TuringLang/TuringTutorials) uses Weave to convert notebooks to html.
|
||||
|
||||
## Related packages
|
||||
|
||||
- [Literate.jl](https://github.com/fredrikekre/Literate.jl) can be used to generate Markdown and Jupyter notebooks directly from Julia source files with markdown in comments.
|
||||
- [Quarto](https://quarto.org) can generate Jupyter notebooks, HTML, or PDF directly from a Markdown format containing Julia code blocks, and also works with R and Python.
|
||||
|
|
24
RELEASE.md
24
RELEASE.md
|
@ -1,24 +0,0 @@
|
|||
|
||||
# Release notes for Weave.jl
|
||||
|
||||
|
||||
### 0.0.3
|
||||
|
||||
9th December 2014
|
||||
|
||||
* Sandbox module for running code is cleared between documents
|
||||
* Fixed Latex figure handling (with contributions from @wildart)
|
||||
* Changed "tex" format: separate environment for term chunks
|
||||
* Improved test coverage
|
||||
* Fixed a bug with eval=false chunk option.
|
||||
|
||||
|
||||
### 0.0.2
|
||||
|
||||
7th December 2014
|
||||
|
||||
* First release
|
||||
* Noweb and markdown input formats
|
||||
* Support for Gadfly, Winston and PyPlot figures
|
||||
* Term and script chunks
|
||||
* Support for markdown, tex and rst output
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env julia
|
||||
|
||||
|
||||
using Weave
|
||||
using ArgParse
|
||||
|
||||
ap = ArgParseSettings("Weave Julia documents using Weave.jl",
|
||||
version = string(Pkg.installed("Weave")),
|
||||
add_version = true)
|
||||
|
||||
@add_arg_table ap begin
|
||||
"source"
|
||||
nargs = '+'
|
||||
help = "source document(s)"
|
||||
required = true
|
||||
"--doctype"
|
||||
default = nothing
|
||||
help = "output format"
|
||||
"--plotlib"
|
||||
arg_type = String
|
||||
default = "Gadfly"
|
||||
help = "output format"
|
||||
"--informat"
|
||||
default = nothing
|
||||
help = "output format"
|
||||
"--out_path"
|
||||
arg_type = String
|
||||
default = ":doc"
|
||||
help = "output directory"
|
||||
"--fig_path"
|
||||
arg_type = String
|
||||
default = "figures"
|
||||
help = "figure output directory"
|
||||
"--fig_ext"
|
||||
default = nothing
|
||||
help = "figure file format"
|
||||
end
|
||||
|
||||
args = ArgParse.parse_args(ap)
|
||||
source = args["source"]
|
||||
delete!(args, "source")
|
||||
args_col = []
|
||||
|
||||
#Check for special values of out_path
|
||||
|
||||
if args["out_path"] == ":doc"
|
||||
args["out_path"] = :doc
|
||||
elseif args["out_path"] == ":pwd"
|
||||
args["out_path"] = :pwd
|
||||
end
|
||||
|
||||
for (key, val) in args
|
||||
push!(args_col, (Meta.parse(key), val))
|
||||
end
|
||||
|
||||
for s=source
|
||||
weave(s; args_col...)
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
[deps]
|
||||
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
|
||||
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
|
||||
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,29 @@
|
|||
using Documenter, Weave
|
||||
|
||||
CI_FLG = get(ENV, "CI", nothing) == "true"
|
||||
|
||||
makedocs(
|
||||
modules = [Weave],
|
||||
format = Documenter.HTML(
|
||||
prettyurls = CI_FLG,
|
||||
canonical = "http://weavejl.mpastell.com/stable/",
|
||||
),
|
||||
sitename = "Weave.jl",
|
||||
pages = [
|
||||
"index.md",
|
||||
"getting_started.md",
|
||||
"usage.md",
|
||||
"publish.md",
|
||||
"chunk_options.md",
|
||||
"header.md",
|
||||
"notebooks.md",
|
||||
"function_index.md",
|
||||
],
|
||||
)
|
||||
|
||||
CI_FLG && include("make_examples.jl")
|
||||
|
||||
deploydocs(
|
||||
repo = "github.com/JunoLab/Weave.jl.git",
|
||||
push_preview = true,
|
||||
)
|
|
@ -0,0 +1,30 @@
|
|||
using Weave
|
||||
|
||||
let start_dir = pwd()
|
||||
cd(@__DIR__)
|
||||
|
||||
weave("../examples/FIR_design.jmd", doctype = "pandoc", out_path = "build/examples")
|
||||
weave("../examples/FIR_design.jmd", doctype = "md2html", out_path = "build/examples")
|
||||
weave("../examples/FIR_design_plots.jl", doctype = "md2html", out_path = "build/examples")
|
||||
|
||||
# PDF outputs
|
||||
if haskey(ENV, "TRAVIS")
|
||||
# in Travis, just cp already generated PDFs
|
||||
cp("assets/FIR_design.pdf", "build/examples/FIR_design.pdf", force = true)
|
||||
cp("assets/FIR_design_plots.pdf", "build/examples/FIR_design_plots.pdf", force = true)
|
||||
else
|
||||
# otherwise try to generate them
|
||||
try
|
||||
weave("../examples/FIR_design.jmd", doctype = "md2pdf", out_path = "assets")
|
||||
weave("../examples/FIR_design_plots.jl", doctype = "md2pdf", out_path = "assets")
|
||||
catch err
|
||||
@error err
|
||||
end
|
||||
end
|
||||
|
||||
cp("../examples/FIR_design.jmd", "build/examples/FIR_design.jmd", force = true)
|
||||
cp("build/examples/FIR_design.md", "build/examples/FIR_design.txt", force = true)
|
||||
cp("../examples/FIR_design_plots.jl", "build/examples/FIR_design_plots.jl", force = true)
|
||||
|
||||
cd(start_dir)
|
||||
end
|
|
@ -0,0 +1,81 @@
|
|||
# [Chunk Options](@id chunk-options)
|
||||
|
||||
You can use chunk options to configure how each chunk is evaluated, rendered, etc.
|
||||
Most of the ideas came from [chunk options in RMarkdown](http://yihui.name/knitr/options).
|
||||
|
||||
|
||||
## Syntax
|
||||
|
||||
Chunk options come after [code chunk](@ref code-chunks) header.
|
||||
There are two (slightly) different syntax to write them:
|
||||
- (Julia's toplevel expression) options are separated by semicolon (`;`)
|
||||
- (RMarkdown style) options are separated by comma (`,`)
|
||||
|
||||
Let's take a look at examples. All the following code chunk header are valid,
|
||||
and so configured to hide the source code from generated output (`echo = false`)
|
||||
and displays figures with 12cm width (`out_width = "12cm"`):
|
||||
```md
|
||||
```julia; echo = false; out_width = "12cm"
|
||||
|
||||
```{julia; echo = false; out_width = "12cm"}
|
||||
|
||||
```julia, echo = false, out_width = "12cm"
|
||||
|
||||
```{julia, echo = false, out_width = "12cm"}
|
||||
```
|
||||
|
||||
|
||||
## Weave Chunk Options
|
||||
|
||||
Weave currently supports the following chunk options:
|
||||
we've mostly followed [RMarkdown's namings](http://yihui.name/knitr/options), but not all options are implemented.
|
||||
|
||||
### Evaluation
|
||||
|
||||
- `eval = true`: Evaluate the code chunk. If `false` the chunk won’t be executed.
|
||||
- `error = true`: If `true` [`weave`](@ref) won't stop on errors and rather they will be included in output document. If `false`, [`weave`](@ref) will halt on any of un-caught errors.
|
||||
- `cache = false`: Cache results, depending on `cache` parameter on [`weave`](@ref) function.
|
||||
- `tangle = true`: Set tangle to `false` to exclude chunk from tangled code.
|
||||
|
||||
### Rendering
|
||||
|
||||
- `echo = true`: Echo the code in the output document. If `false` the source code will be hidden.
|
||||
- `results = "markup"`: The output format of the printed results. `"markup"` for literal block, `"hidden"` for hidden results, or anything else for raw output (I tend to use `"tex"` for Latex and `"rst"` for rest). Raw output is useful if you want to e.g. create tables from code chunks.
|
||||
- `term = false`: If `true` the output emulates a REPL session. Otherwise only stdout and figures will be included in output.
|
||||
- `wrap = true`: Wrap long lines from output.
|
||||
- `line_width = 75`: Line width for wrapped lines.
|
||||
- `hold = false`: Hold all results until the end of the chunk.
|
||||
|
||||
### Figures
|
||||
|
||||
- `label = nothing`: Chunk label, will be used for figure labels in Latex as `fig:label`.
|
||||
- `fig_width = 6`: Figure width passed to plotting library.
|
||||
- `fig_height = 4`: Figure height passed to plotting library.
|
||||
- `out_width`: Width of saved figure in output markup e.g. `"50%"`, `"12cm"`, `0.5\linewidth`
|
||||
- `out_height`: Height of saved figure in output markup
|
||||
- `dpi = 96`: Resolution of saved figures.
|
||||
- `fig_cap`: Figure caption.
|
||||
- `fig_ext`: File extension (format) of saved figures.
|
||||
- `fig_pos = "!h"`: Figure position in Latex, e.g.: `"ht"`.
|
||||
- `fig_env = "figure"`: Figure environment in Latex.
|
||||
|
||||
|
||||
## Default Chunk Options
|
||||
|
||||
You can set the default chunk options (and `weave` arguments) for a document using `weave_options` key in YAML [Header Configuration](@ref).
|
||||
E.g. to set the default `out_width` of all figures you can use:
|
||||
|
||||
```yaml
|
||||
---
|
||||
weave_options:
|
||||
out_width : 50%
|
||||
---
|
||||
```
|
||||
|
||||
You can also set or change the default chunk options for a document either before weave using the `set_chunk_defaults` function.
|
||||
|
||||
```@docs
|
||||
set_chunk_defaults!
|
||||
get_chunk_defaults
|
||||
restore_chunk_defaults!
|
||||
```
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
# Function index
|
||||
|
||||
```@index
|
||||
```
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
# Getting started
|
||||
|
||||
The best way to get started using Weave.jl is to look at the example input and output documents.
|
||||
Examples for different formats are included in the package's [`examples`](https://github.com/JunoLab/Weave.jl/tree/master/examples) directory.
|
||||
|
||||
First have a look at source document using markdown code chunks and [Plots.jl](https://github.com/JuliaPlots/Plots.jl) for figures:
|
||||
|
||||
All the different format documents below are generated from a single Weave document [`FIR_design.jmd`](../examples/FIR_design.jmd):
|
||||
- HTML: [`FIR_design.html`](../examples/FIR_design.html)
|
||||
- PDF: [`FIR_design.pdf`](../examples/FIR_design.pdf)
|
||||
- Pandoc markdown: [`FIR_design.txt`](../examples/FIR_design.txt)
|
||||
|
||||
!!! note
|
||||
Producing PDF output requires that you have XeLateX installed.
|
||||
|
||||
Add dependencies for the example if needed:
|
||||
|
||||
```julia
|
||||
using Pkg; Pkg.add.(["Plots", "DSP"])
|
||||
```
|
||||
|
||||
Weave the files to your working directory:
|
||||
|
||||
```julia
|
||||
using Weave
|
||||
|
||||
filename = normpath(Weave.EXAMPLE_FOLDER, "FIR_design.jmd")
|
||||
|
||||
# Julia markdown to HTML
|
||||
weave(filename; doctype = "md2html", out_path = :pwd)
|
||||
|
||||
# Julia markdown to PDF
|
||||
weave(filename; doctype = "md2pdf", out_path = :pwd)
|
||||
|
||||
# Julia markdown to Pandoc markdown
|
||||
weave(filename; doctype = "pandoc", out_path = :pwd)
|
||||
```
|
||||
|
||||
!!! tips
|
||||
`Weave.EXAMPLE_FOLDER` points to [the `examples` directory](https://github.com/JunoLab/Weave.jl/tree/master/examples).
|
|
@ -0,0 +1,101 @@
|
|||
# Header Configuration
|
||||
|
||||
When `weave`ing a markdown document, you use YAML header to provide additional metadata and configuration options.
|
||||
A YAML header should be in the beginning of the input document delimited with `---`.
|
||||
|
||||
|
||||
!!! warning
|
||||
YAML header configuration is only supported when `weave`ing [markdown or Noweb syntax documents](@ref document-syntax).
|
||||
|
||||
|
||||
## Document Metadata
|
||||
|
||||
You can set additional document metadata in YAML header.
|
||||
When `weave`ing to Julia markdown documents to HTML or PDF, Weave respects the following metadata specification:
|
||||
- `title`
|
||||
- `author`
|
||||
- `date`
|
||||
|
||||
An example:
|
||||
```yaml
|
||||
---
|
||||
title : Header Example
|
||||
author : Shuhei Kadowaki
|
||||
date: 16th May 2020
|
||||
---
|
||||
```
|
||||
|
||||
!!! note
|
||||
You can also have other metadata, but they won't appear in the resulting HTML and PDF.
|
||||
If you weave to Julia markdown to GitHub/Hugo markdown, all the metadata will be preserved.
|
||||
|
||||
### Dynamic Metadata
|
||||
|
||||
The metadata can be given "dynamically"; if you have [inline code](@ref) within YAML header, they will be evaluated _after_ evaluating all the chunks and replaced with the results.
|
||||
|
||||
The example document below will set `date` metadata dynamically.
|
||||
Note that `Date` is available since the chunk is evaluated first.
|
||||
```md
|
||||
---
|
||||
title : Header Example
|
||||
author : Shuhei Kadowaki
|
||||
date: `j import Dates; Dates.Date(Dates.now())`
|
||||
---
|
||||
|
||||
```julia; echo = false
|
||||
using Dates
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
## Configuration Options
|
||||
|
||||
Each of keyword arguments of [`weave`](@ref) can be set in the YAML header under `options` field.
|
||||
You can also set [Chunks Options](@ref) there that will be applied globally.
|
||||
|
||||
The example below sets `out_path` and `doctype` options and overwrites `term` and `wrap` chunk options:
|
||||
```yaml
|
||||
---
|
||||
title : Header Example
|
||||
author : Shuhei Kadowaki
|
||||
date: 16th May 2020
|
||||
weave_options:
|
||||
out_path: relative/path/to/this/document
|
||||
doctype: github
|
||||
term: true
|
||||
wrap: false
|
||||
---
|
||||
```
|
||||
|
||||
!!! note
|
||||
- configurations specified within the YAML header have higher precedence than those specified via `weave` keyword arguments
|
||||
- chunk options specified within each chunk have higher precedence than the global global chunk options specified within the YAML header
|
||||
|
||||
!!! warning
|
||||
As opposed to metadata, _most_ of those configuration options can't be given dynamically (i.e. can't be via inline code),
|
||||
since they are needed for evaluation of chunks themselves.
|
||||
But some configuration options that are needed "formatting" document can still be given dynamically:
|
||||
- `template`
|
||||
- `css`
|
||||
- `highlight_theme`
|
||||
- `pandoc_options`
|
||||
- `latex_cmd`
|
||||
- `keep_unicode`
|
||||
|
||||
See also: [`weave`](@ref)
|
||||
|
||||
|
||||
## Format Specific Options
|
||||
|
||||
The header configurations can be format specific.
|
||||
Here is how to set different `out_path` for `md2html` and `md2pdf` and set `fig_ext` globally:
|
||||
```yaml
|
||||
---
|
||||
weave_options:
|
||||
md2html:
|
||||
out_path : html
|
||||
md2pdf:
|
||||
out_path : pdf
|
||||
fig_ext : .png
|
||||
---
|
||||
```
|
|
@ -0,0 +1,38 @@
|
|||
# Weave.jl - Scientific Reports Using Julia
|
||||
|
||||
This is the documentation of [Weave.jl](http://github.com/mpastell/weave.jl).
|
||||
Weave is a scientific report generator/literate programming tool for Julia.
|
||||
It resembles
|
||||
[Pweave](http://mpastell.com/pweave),
|
||||
[knitr](https://yihui.org/knitr/),
|
||||
[R Markdown](https://rmarkdown.rstudio.com/),
|
||||
and [Sweave](https://stat.ethz.ch/R-manual/R-patched/library/utils/doc/Sweave.pdf).
|
||||
|
||||
|
||||
**Current features**
|
||||
|
||||
- Publish markdown directly to HTML and PDF using Julia or [Pandoc](https://pandoc.org/MANUAL.html)
|
||||
- Execute code as in terminal or in a unit of code chunk
|
||||
- Capture [Plots.jl](https://github.com/JuliaPlots/Plots.jl) or [Gadfly.jl](https://github.com/GiovineItalia/Gadfly.jl) figures
|
||||
- Supports various input format: Markdown, [Noweb](https://www.cs.tufts.edu/~nr/noweb/), [Jupyter Notebook](https://jupyter.org/), and ordinal Julia script
|
||||
- Conversions between those input formats
|
||||
- Supports various output document formats: HTML, PDF, GitHub markdown, Jupyter Notebook, MultiMarkdown, Asciidoc and reStructuredText
|
||||
- Simple caching of results
|
||||
|
||||
![Weave in Juno demo](https://user-images.githubusercontent.com/40514306/76081328-32f41900-5fec-11ea-958a-375f77f642a2.png)
|
||||
|
||||
|
||||
## Index
|
||||
|
||||
```@contents
|
||||
Pages = [
|
||||
"index.md",
|
||||
"getting_started.md",
|
||||
"usage.md",
|
||||
"publish.md",
|
||||
"chunk_options.md",
|
||||
"header.md",
|
||||
"notebooks.md",
|
||||
"function_index.md",
|
||||
]
|
||||
```
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
# Working with Jupyter notebooks
|
||||
|
||||
## Weaving from Jupyter notebooks
|
||||
|
||||
Weave supports using [Jupyter Notebook](https://jupyter.org/)s as input format.
|
||||
This means you can [`weave`](@ref) notebooks to any supported formats;
|
||||
by default, it will be weaved to HTML.
|
||||
|
||||
```julia
|
||||
weave("notebook.ipynb") # will be weaved to HTML
|
||||
```
|
||||
|
||||
!!! warning
|
||||
You can't use chunk options with notebooks.
|
||||
|
||||
## Output to Jupyter notebooks
|
||||
|
||||
As of Weave 0.5.1. there is new [`notebook`](@ref) method to convert Weave documents to Jupyter notebooks using
|
||||
[nbconvert](http://nbconvert.readthedocs.io/en/latest/execute_api.html).
|
||||
|
||||
```@docs
|
||||
notebook
|
||||
```
|
||||
|
||||
You can specify `jupyter` used to execute the notebook with the `jupyter_path` keyword argument
|
||||
(this defaults to the `"jupyter"`, i.e. whatever you have linked to that location).
|
||||
|
||||
Instead, you might want to use the [`convert_doc`](@ref) method below and run the code in Jupyter.
|
||||
|
||||
## Converting between formats
|
||||
|
||||
You can convert between all supported input formats using the [`convert_doc`](@ref) function.
|
||||
|
||||
To convert from script to notebook:
|
||||
|
||||
```julia
|
||||
convert_doc("examples/FIR_design.jl", "FIR_design.ipynb")
|
||||
```
|
||||
|
||||
and from notebook to Markdown use:
|
||||
|
||||
```julia
|
||||
convert_doc("FIR_design.ipynb", "FIR_design.jmd")
|
||||
```
|
||||
|
||||
```@docs
|
||||
convert_doc
|
||||
```
|
|
@ -0,0 +1,67 @@
|
|||
# Publishing to HTML and PDF
|
||||
|
||||
You can also publish any supported input format to HTML and PDF documents.
|
||||
|
||||
!!! note
|
||||
Producing PDF output requires that you have XeLaTex installed and in your path.
|
||||
|
||||
You can use a YAML header in the beginning of the input document delimited with `---`
|
||||
to set the document title, author and date, e.g.:
|
||||
```
|
||||
---
|
||||
title : Weave example
|
||||
author : Matti Pastell
|
||||
date: 15th December 2016
|
||||
---
|
||||
```
|
||||
|
||||
Here are sample input and outputs:
|
||||
- input (Julia markdown format): [`FIR_design_plots.jl`](../examples/FIR_design_plots.jl) (its path is bound to `Weave.SAMPLE_JL_DOC`)
|
||||
- HTML output: [`FIR_design_plots.html`](../examples/FIR_design_plots.html)
|
||||
- PDF output: [`FIR_design_plots.pdf`](../examples/FIR_design_plots.pdf)
|
||||
|
||||
They are generated as follows:
|
||||
```julia
|
||||
weave(Weave.SAMPLE_JL_DOC)) # default to md2html output format
|
||||
weave(Weave.SAMPLE_JL_DOC; doctype = "md2pdf")
|
||||
```
|
||||
|
||||
!!! tips
|
||||
`Weave.SAMPLE_JL_DOC` is the path of [FIR_design.jl](../examples/FIR_design.jl).
|
||||
|
||||
!!! note
|
||||
`"md2html"` and `"md2pdf"` assume Julia markdown format as an input,
|
||||
while `pandoc2pdf` and `pandoc2html` assume Noweb input format (i.e. Pandoc markdown).
|
||||
|
||||
|
||||
## Templates
|
||||
|
||||
You can use a custom template with `md2html` and `md2pdf` formats with `template` keyword option,
|
||||
e.g.: `weave("FIR_design_plots.jl", template = "custom.tpl"`.
|
||||
|
||||
As starting point, you can use the existing templates:
|
||||
|
||||
- HTML (`md2html`): [`md2html.tpl`](https://github.com/JunoLab/Weave.jl/blob/master/templates/md2html.tpl)
|
||||
- LaTex (`md2pdf`): [`md2pdf.tpl`](https://github.com/JunoLab/Weave.jl/blob/master/templates/md2pdf.tpl)
|
||||
|
||||
Templates are rendered using [Mustache.jl](https://github.com/jverzani/Mustache.jl).
|
||||
|
||||
|
||||
## Supported Markdown syntax
|
||||
|
||||
The markdown variant used by Weave is [Julia markdown](https://docs.julialang.org/en/v1/stdlib/Markdown/#).
|
||||
In addition Weave supports few additional Markdown features:
|
||||
|
||||
### Comments
|
||||
|
||||
You can add comments using html syntax: `<!-- -->`
|
||||
|
||||
### Multiline equations
|
||||
|
||||
You can add multiline equations using:
|
||||
|
||||
```
|
||||
$$
|
||||
x^2 = x*x
|
||||
$$
|
||||
```
|
|
@ -0,0 +1,182 @@
|
|||
# Using Weave
|
||||
|
||||
You can write your documentation and code in input document using Markdown, Noweb or script
|
||||
syntax and use [`weave`](@ref) function to execute to document to capture results and figures.
|
||||
|
||||
## `weave`
|
||||
|
||||
Weave document with markup and julia code using `Plots.jl` for plots,
|
||||
`out_path = :pwd` makes the results appear in the current working directory.
|
||||
|
||||
> A prepared example: [`Weave.SAMPLE_JL_DOC`](../examples/FIR_design.jmd)
|
||||
|
||||
```julia
|
||||
# First add depencies for the example
|
||||
using Pkg; Pkg.add.(["Plots", "DSP"])
|
||||
using Weave
|
||||
weave(Weave.SAMPLE_JL_DOC; out_path=:pwd)
|
||||
```
|
||||
|
||||
```@docs
|
||||
weave
|
||||
```
|
||||
|
||||
## `tangle`
|
||||
|
||||
Tangling extracts the code from document:
|
||||
|
||||
```@docs
|
||||
tangle
|
||||
```
|
||||
|
||||
## Supported Output Formats
|
||||
|
||||
Weave automatically detects the output format based on the file extension.
|
||||
The auto output format detection is handled by `detect_doctype(path::AbstractString)`:
|
||||
|
||||
```julia
|
||||
function detect_doctype(path::AbstractString)
|
||||
_, ext = lowercase.(splitext(path))
|
||||
|
||||
match(r"^\.(jl|.?md|ipynb)", ext) !== nothing && return "md2html"
|
||||
ext == ".rst" && return "rst"
|
||||
ext == ".tex" && return "texminted"
|
||||
ext == ".txt" && return "asciidoc"
|
||||
|
||||
return "pandoc"
|
||||
end
|
||||
```
|
||||
|
||||
You can also manually specify it using the `doctype` keyword option.
|
||||
You can get a list of supported output formats:
|
||||
|
||||
```@docs
|
||||
list_out_formats
|
||||
```
|
||||
|
||||
```@example
|
||||
using Weave # hide
|
||||
list_out_formats()
|
||||
```
|
||||
|
||||
## [Document Syntax](@id document-syntax)
|
||||
|
||||
Weave uses markdown, Noweb or script syntax for defining the code chunks and
|
||||
documentation chunks. You can also weave Jupyter notebooks. The format is detected based on the file extension, but you can also set it manually using the `informat` parameter.
|
||||
|
||||
The rules for autodetection are:
|
||||
|
||||
```julia
|
||||
ext == ".jl" && return "script"
|
||||
ext == ".jmd" && return "markdown"
|
||||
ext == ".ipynb" && return "notebook"
|
||||
return "noweb"
|
||||
```
|
||||
|
||||
|
||||
### Documentation Chunks
|
||||
|
||||
In markdown and Noweb input formats documentation chunks are the parts that aren't inside code delimiters. Documentation chunks can be written with several different markup languages.
|
||||
|
||||
|
||||
### [Code Chunks](@id code-chunks)
|
||||
|
||||
Code chunks are written in different ways in different formats.
|
||||
|
||||
#### Markdown Format
|
||||
|
||||
Weave code chunks are defined using fenced code blocks, same as with [common markdown](https://spec.commonmark.org/0.29/#fenced-code-blocks):
|
||||
```markdown
|
||||
```julia
|
||||
code
|
||||
...
|
||||
```
|
||||
```
|
||||
|
||||
Weave code chunks can optionally be followed by [chunk options](@ref) on the same line.
|
||||
E.g. the chunk below will hide code itself from generated output:
|
||||
```markdown
|
||||
```julia, echo = false
|
||||
code
|
||||
...
|
||||
```
|
||||
```
|
||||
|
||||
#### Noweb Format
|
||||
|
||||
Code chunks start with a line marked with `<<>>=` or `<<options>>=` and end with line marked with `@`.
|
||||
The code between the start and end markers is executed and the output is captured to the output document.
|
||||
|
||||
### [Inline Code](@id inline-code)
|
||||
|
||||
You can also add inline code to your documents using
|
||||
```
|
||||
`j juliacode`
|
||||
```
|
||||
or
|
||||
```
|
||||
! juliacode
|
||||
```
|
||||
syntax.
|
||||
|
||||
The former syntax allows you to insert code _anywhere_ in a line
|
||||
while the `!` syntax treats the whole line as code,
|
||||
and the code will be replaced with captured output in the weaved document.
|
||||
|
||||
If the code produces figures, the filename or base64 encoded string will be added to output,
|
||||
e.g. to include a Plots figure in markdown you can use:
|
||||
```
|
||||
![A plot](`j plot(1:10)`)
|
||||
```
|
||||
or to produce any HTML output:
|
||||
```
|
||||
! display("text/html", HTML("Header from julia"));
|
||||
```
|
||||
|
||||
### Script Format
|
||||
|
||||
Weave also supports script input format with a markup in comments.
|
||||
These scripts can be executed normally using Julia or published with Weave.
|
||||
|
||||
Lines starting with `#'`, `#%%` or `# %%` are treated as document.
|
||||
|
||||
All non-document lines are treated as code.
|
||||
You can set chunk options using lines starting with `#+` just before code e.g:
|
||||
```julia
|
||||
#+ term=true
|
||||
hoge # some code comes here
|
||||
```
|
||||
|
||||
The format is identical to [Pweave](http://mpastell.com/pweave/pypublish.html) and the concept is similar to publishing documents with MATLAB or using Knitr's [spin](http://yihui.name/knitr/demo/stitch/).
|
||||
Weave will remove the first empty space from each line of documentation.
|
||||
|
||||
!!! tip
|
||||
- Here are sample documents:
|
||||
+ [markdown format](https://github.com/JunoLab/Weave.jl/blob/master/examples/FIR_design.jmd)
|
||||
+ [script format](https://github.com/JunoLab/Weave.jl/blob/master/examples/FIR_design.jl)
|
||||
- [Details about chunk options](@ref chunk-options)
|
||||
|
||||
|
||||
## Configuration via YAML Header
|
||||
|
||||
When `weave`ing markdown files, you can use YAML header to provide additional metadata and configuration options.
|
||||
See [Header Configuration](@ref) section for more details.
|
||||
|
||||
|
||||
## Passing Runtime Arguments to Documents
|
||||
|
||||
You can pass arbitrary object to the weaved document using [`weave`](@ref)'s optional argument `args`.
|
||||
It will be available as `WEAVE_ARGS` variable in the `weave`d document.
|
||||
|
||||
This makes it possible to create the same report easily for e.g. different date ranges of input data from a database or from files with similar format giving the filename as input.
|
||||
|
||||
E.g. if you call `weave("weavefile.jmd", args = (datalocation = "somedata.h5",))`, and then you can retrieve the `datalocation` in `weavefile.jmd` as follows: `WEAVE_ARGS.datalocation`
|
||||
|
||||
|
||||
## `include_weave`
|
||||
|
||||
You can call `include_weave` on a Weave document and run all code chunks within in the current session.
|
||||
|
||||
```@docs
|
||||
include_weave
|
||||
```
|
|
@ -0,0 +1,83 @@
|
|||
#' ---
|
||||
#' title : FIR filter design with Julia
|
||||
#' author : Matti Pastell
|
||||
#' date : 21th April 2016
|
||||
#' ---
|
||||
|
||||
#' # Introduction
|
||||
|
||||
#' This an example of a julia script that can be published using
|
||||
#' [Weave](http://weavejl.mpastell.com/dev/usage/).
|
||||
#' The script can be executed normally using Julia
|
||||
#' or published to HTML or pdf with Weave.
|
||||
#' Text is written in markdown in lines starting with "`#'` " and code
|
||||
#' is executed and results are included in the published document.
|
||||
|
||||
#' Notice that you don't need to define chunk options, but you can using
|
||||
#' `#+`. just before code e.g. `#+ term=True, caption='Fancy plots.'`.
|
||||
#' If you're viewing the published version have a look at the
|
||||
#' [source](FIR_design.jl) to see the markup.
|
||||
|
||||
|
||||
#' # FIR Filter Design
|
||||
|
||||
#' We'll implement lowpass, highpass and ' bandpass FIR filters. If
|
||||
#' you want to read more about DSP I highly recommend [The Scientist
|
||||
#' and Engineer's Guide to Digital Signal
|
||||
#' Processing](http://www.dspguide.com/) which is freely available
|
||||
#' online.
|
||||
|
||||
#' ## Calculating frequency response
|
||||
|
||||
#' DSP.jl package doesn't (yet) have a method to calculate the
|
||||
#' the frequency response of a FIR filter so we define it:
|
||||
|
||||
using Gadfly, DSP
|
||||
|
||||
function FIRfreqz(b::Array, w = range(0, stop=π, length=1024))
|
||||
n = length(w)
|
||||
h = Array{ComplexF32}(n)
|
||||
sw = 0
|
||||
for i = 1:n
|
||||
for j = 1:length(b)
|
||||
sw += b[j]*exp(-im*w[i])^-j
|
||||
end
|
||||
h[i] = sw
|
||||
sw = 0
|
||||
end
|
||||
return h
|
||||
end
|
||||
|
||||
|
||||
#' ## Design Lowpass FIR filter
|
||||
|
||||
#' Designing a lowpass FIR filter is very simple to do with DSP.jl, all you
|
||||
#' need to do is to define the window length, cut off frequency and the
|
||||
#' window. We will define a lowpass filter with cut off frequency at 5Hz for a signal
|
||||
#' sampled at 20 Hz.
|
||||
#' We will use the Hamming window, which is defined as:
|
||||
#' $w(n) = \alpha - \beta\cos\frac{2\pi n}{N-1}$, where $\alpha=0.54$ and $\beta=0.46$
|
||||
|
||||
fs = 20
|
||||
f = digitalfilter(Lowpass(5, fs = fs), FIRWindow(hamming(61)))
|
||||
w = range(0, stop=pi, length=1024)
|
||||
h = FIRfreqz(f, w)
|
||||
|
||||
#' ## Plot the frequency and impulse response
|
||||
|
||||
#' The next code chunk is executed in term mode, see the [script](FIR_design.jl) for syntax.
|
||||
#+ term=true
|
||||
|
||||
h_db = log10(abs.(h));
|
||||
ws = w/pi*(fs/2)
|
||||
|
||||
#+
|
||||
|
||||
plot(y = h_db, x = ws, Geom.line,
|
||||
Guide.xlabel("Frequency (Hz)"), Guide.ylabel("Magnitude (db)"))
|
||||
|
||||
#' And again with default options
|
||||
|
||||
h_phase = unwrap(-atan(imag(h),real(h)))
|
||||
plot(y = h_phase, x = ws, Geom.line,
|
||||
Guide.xlabel("Frequency (Hz)"), Guide.ylabel("Phase (radians)"))
|
|
@ -0,0 +1,106 @@
|
|||
---
|
||||
title: FIR filter design with Julia
|
||||
author: Matti Pastell
|
||||
date: 21th April 2016
|
||||
---
|
||||
|
||||
|
||||
# Introduction
|
||||
|
||||
|
||||
This an example of a julia script that can be published using
|
||||
[Weave](http://weavejl.mpastell.com/dev/usage/).
|
||||
The script can be executed normally using Julia
|
||||
or published to HTML or pdf with Weave.
|
||||
Text is written in markdown in lines starting with "`#'` " and code
|
||||
is executed and results are included in the published document.
|
||||
|
||||
|
||||
Notice that you don't need to define chunk options, but you can using
|
||||
`#+`. just before code e.g. `#+ term=True, caption='Fancy plots.'`.
|
||||
If you're viewing the published version have a look at the
|
||||
[source](FIR_design_plots.jl) to see the markup.
|
||||
|
||||
|
||||
<!-- this setup dependencies, but doesn't appear in the generated document -->
|
||||
```julia; echo = false; results = "hidden"
|
||||
using Pkg
|
||||
"Plots" ∉ keys(Pkg.project().dependencies) && Pkg.add("Plots")
|
||||
"DSP" ∉ keys(Pkg.project().dependencies) && Pkg.add("DSP")
|
||||
```
|
||||
|
||||
|
||||
# FIR Filter Design
|
||||
|
||||
|
||||
We'll implement lowpass, highpass and ' bandpass FIR filters. If
|
||||
you want to read more about DSP I highly recommend [The Scientist
|
||||
and Engineer's Guide to Digital Signal
|
||||
Processing](http://www.dspguide.com/) which is freely available
|
||||
online.
|
||||
|
||||
|
||||
## Calculating frequency response
|
||||
|
||||
|
||||
DSP.jl package doesn't (yet) have a method to calculate the
|
||||
the frequency response of a FIR filter so we define it:
|
||||
|
||||
```julia
|
||||
using Plots, DSP
|
||||
gr()
|
||||
|
||||
function FIRfreqz(b::Array, w = range(0, stop=π, length=1024))
|
||||
n = length(w)
|
||||
h = Array{ComplexF32}(undef, n)
|
||||
sw = 0
|
||||
for i = 1:n
|
||||
for j = 1:length(b)
|
||||
sw += b[j]*exp(-im*w[i])^-j
|
||||
end
|
||||
h[i] = sw
|
||||
sw = 0
|
||||
end
|
||||
return h
|
||||
end
|
||||
```
|
||||
|
||||
## Design Lowpass FIR filter
|
||||
|
||||
|
||||
Designing a lowpass FIR filter is very simple to do with DSP.jl, all you
|
||||
need to do is to define the window length, cut off frequency and the
|
||||
window. We will define a lowpass filter with cut off frequency at 5Hz for a signal
|
||||
sampled at 20 Hz.
|
||||
We will use the Hamming window, which is defined as:
|
||||
$w(n) = \alpha - \beta\cos\frac{2\pi n}{N-1}$, where $\alpha=0.54$ and $\beta=0.46$
|
||||
|
||||
```julia
|
||||
fs = 20
|
||||
f = digitalfilter(Lowpass(5, fs = fs), FIRWindow(hamming(61)))
|
||||
w = range(0, stop=pi, length=1024)
|
||||
h = FIRfreqz(f, w)
|
||||
```
|
||||
|
||||
## Plot the frequency and impulse response
|
||||
|
||||
|
||||
The next code chunk is executed in term mode, see the [script](FIR_design.jl) for syntax.
|
||||
|
||||
```julia; term=true
|
||||
h_db = log10.(abs.(h));
|
||||
ws = w/pi*(fs/2)
|
||||
```
|
||||
|
||||
```julia
|
||||
plot(ws, h_db,
|
||||
xlabel = "Frequency (Hz)", ylabel = "Magnitude (db)")
|
||||
```
|
||||
|
||||
And again with default options
|
||||
|
||||
```julia
|
||||
h_phase = unwrap(-atan.(imag.(h),real.(h)))
|
||||
plot(ws, h_phase,
|
||||
xlabel = "Frequency (Hz)", ylabel = "Phase (radians)")
|
||||
```
|
|
@ -0,0 +1,85 @@
|
|||
#' ---
|
||||
#' title: FIR filter design with Julia
|
||||
#' author: Matti Pastell
|
||||
#' date: 21th April 2016
|
||||
#' ---
|
||||
|
||||
#' # Introduction
|
||||
|
||||
#' This an example of a julia script that can be published using
|
||||
#' [Weave](http://weavejl.mpastell.com/dev/usage/).
|
||||
#' The script can be executed normally using Julia
|
||||
#' or published to HTML or pdf with Weave.
|
||||
#' Text is written in markdown in lines starting with "`#'` " and code
|
||||
#' is executed and results are included in the published document.
|
||||
|
||||
#' Notice that you don't need to define chunk options, but you can using
|
||||
#' `#+`. just before code e.g. `#+ term=True, caption='Fancy plots.'`.
|
||||
#' If you're viewing the published version have a look at the
|
||||
#' [source](FIR_design_plots.jl) to see the markup.
|
||||
|
||||
|
||||
#' # FIR Filter Design
|
||||
|
||||
#' We'll implement lowpass, highpass and ' bandpass FIR filters. If
|
||||
#' you want to read more about DSP I highly recommend [The Scientist
|
||||
#' and Engineer's Guide to Digital Signal
|
||||
#' Processing](http://www.dspguide.com/) which is freely available
|
||||
#' online.
|
||||
|
||||
#' ## Calculating frequency response
|
||||
|
||||
#' DSP.jl package doesn't (yet) have a method to calculate the
|
||||
#' the frequency response of a FIR filter so we define it:
|
||||
|
||||
using Plots, DSP
|
||||
gr()
|
||||
|
||||
function FIRfreqz(b::Array, w = range(0, stop=π, length=1024))
|
||||
n = length(w)
|
||||
h = Array{ComplexF32}(undef, n)
|
||||
sw = 0
|
||||
for i = 1:n
|
||||
for j = 1:length(b)
|
||||
sw += b[j]*exp(-im*w[i])^-j
|
||||
end
|
||||
h[i] = sw
|
||||
sw = 0
|
||||
end
|
||||
return h
|
||||
end
|
||||
|
||||
|
||||
#' ## Design Lowpass FIR filter
|
||||
|
||||
#' Designing a lowpass FIR filter is very simple to do with DSP.jl, all you
|
||||
#' need to do is to define the window length, cut off frequency and the
|
||||
#' window. We will define a lowpass filter with cut off frequency at 5Hz for a signal
|
||||
#' sampled at 20 Hz.
|
||||
#' We will use the Hamming window, which is defined as:
|
||||
#' $w(n) = \alpha - \beta\cos\frac{2\pi n}{N-1}$, where $\alpha=0.54$ and $\beta=0.46$
|
||||
|
||||
|
||||
fs = 20
|
||||
f = digitalfilter(Lowpass(5, fs = fs), FIRWindow(hamming(61)))
|
||||
w = range(0, stop=pi, length=1024)
|
||||
h = FIRfreqz(f, w)
|
||||
|
||||
#' ## Plot the frequency and impulse response
|
||||
|
||||
#' The next code chunk is executed in term mode, see the [script](FIR_design.jl) for syntax.
|
||||
#+ term=true
|
||||
|
||||
h_db = log10.(abs.(h));
|
||||
ws = w/pi*(fs/2)
|
||||
|
||||
#+
|
||||
|
||||
plot(ws, h_db,
|
||||
xlabel = "Frequency (Hz)", ylabel = "Magnitude (db)")
|
||||
|
||||
#' And again with default options
|
||||
|
||||
h_phase = unwrap(-atan.(imag.(h),real.(h)))
|
||||
plot(ws, h_phase,
|
||||
xlabel = "Frequency (Hz)", ylabel = "Phase (radians)")
|
|
@ -0,0 +1,46 @@
|
|||
\documentclass{beamer}
|
||||
|
||||
\usepackage{lmodern}
|
||||
\usepackage{amssymb,amsmath}
|
||||
\usepackage{bm}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{microtype}
|
||||
\usepackage{hyperref}
|
||||
\setlength{\parindent}{0pt}
|
||||
\setlength{\parskip}{1.2ex}
|
||||
|
||||
\hypersetup
|
||||
{ pdfauthor = { {{{:author}}} },
|
||||
pdftitle={ {{{:title}}} },
|
||||
colorlinks=TRUE,
|
||||
linkcolor=black,
|
||||
citecolor=blue,
|
||||
urlcolor=blue
|
||||
}
|
||||
|
||||
|
||||
{{#:title}}
|
||||
\title{ {{{ :title }}} }
|
||||
{{/:title}}
|
||||
|
||||
{{#:author}}
|
||||
\author{ {{{ :author }}} }
|
||||
{{/:author}}
|
||||
|
||||
{{#:date}}
|
||||
\date{ {{{ :date }}} }
|
||||
{{/:date}}
|
||||
|
||||
{{ :highlight }}
|
||||
|
||||
\begin{document}
|
||||
|
||||
{{{#:title}}}
|
||||
\begin{frame}
|
||||
\titlepage
|
||||
\end{frame}
|
||||
{{{/:title}}}
|
||||
|
||||
{{{ :body }}}
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
|
||||
<<term=true>>=
|
||||
using Gadfly
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
y = 20
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
@
|
||||
|
||||
<<>>=
|
||||
x = linspace(0, 200)
|
||||
println(x)
|
||||
@
|
||||
|
||||
<<fig_cap="Cosine function">>=
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
@
|
|
@ -0,0 +1,76 @@
|
|||
---
|
||||
title : Intro to Weave.jl with Gadfly
|
||||
author : Matti Pastell
|
||||
date : 13th December 2016
|
||||
---
|
||||
|
||||
# Intro
|
||||
|
||||
This a sample [Julia](http://julialang.org/) markdown document that can
|
||||
be executed using [Weave.jl](https://github.com/JunoLab/Weave.jl).
|
||||
|
||||
The code is delimited from docs using markdown fenced code blocks
|
||||
markup which can be seen looking at the source document
|
||||
[gadfly_md_sample.jmd](gadfly_md_sample.jmd)
|
||||
in the examples directory of the package. The source document can be executed
|
||||
and the results with Gadfly plots are captured in the resulting file.
|
||||
|
||||
You can create markdown output or pdf (with xelatex) and HTML directly using
|
||||
the weave command as follows:
|
||||
|
||||
```{julia; eval=false}
|
||||
using Weave
|
||||
#Markdown
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), informat="markdown",
|
||||
out_path = :pwd, doctype = "pandoc")
|
||||
#HTML
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), informat="markdown",
|
||||
out_path = :pwd, doctype = "md2html")
|
||||
#pdf
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), informat="markdown",
|
||||
out_path = :pwd, doctype = "md2pdf")
|
||||
```
|
||||
|
||||
*The markdown variant used for html and pdf output is Julia markdown.*
|
||||
|
||||
|
||||
The documents will be written to the Julia working directory when you
|
||||
use the `out_path = :pwd`.
|
||||
|
||||
# Capturing code
|
||||
|
||||
The basic code chunk will be run with default options and the code and
|
||||
output will be captured.
|
||||
|
||||
```julia
|
||||
using Gadfly
|
||||
x = linspace(0, 2*pi)
|
||||
println(x)
|
||||
plot(x = x, y = sin.(x))
|
||||
```
|
||||
|
||||
You can also control the way the results are captured, plot size etc.
|
||||
using chunk options. Here is an example of a chunk that behaves like a repl.
|
||||
|
||||
```{julia;term=true}
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
```
|
||||
|
||||
You can also for instance hide the code and show only the figure, add a
|
||||
caption to the figure and make it wider as follows (you can only see the
|
||||
syntax from the source document):
|
||||
|
||||
```{julia;echo=false; fig_cap="A random walk."; label="random"; fig_width=7; fig_height=4}
|
||||
plot(y = cumsum(randn(1000, 1)), Geom.line)
|
||||
```
|
||||
|
||||
# Whats next
|
||||
|
||||
Read the documentation:
|
||||
|
||||
- stable: [http://mpastell.github.io/Weave.jl/stable/](http://mpastell.github.io/Weave.jl/stable/)
|
||||
- latest: [http://weavejl.mpastell.com/dev/](http://weavejl.mpastell.com/dev/)
|
||||
|
||||
See other examples in the [GitHub repo](https://github.com/JunoLab/Weave.jl/tree/master/examples)
|
|
@ -0,0 +1,83 @@
|
|||
\documentclass{article}
|
||||
|
||||
%Minted for syntax hightlighting
|
||||
\usepackage{minted}
|
||||
|
||||
%These are for plots
|
||||
\usepackage{pgfplots}
|
||||
\usepackage{fontspec}
|
||||
\setmainfont{TeX Gyre Pagella}
|
||||
\usepackage{amsmath}
|
||||
\usepackage[active,tightpage]{preview}
|
||||
|
||||
%Hyperlinks
|
||||
\usepackage{hyperref}
|
||||
\hypersetup{colorlinks=true, urlcolor=blue}
|
||||
%Some style changes
|
||||
\setlength{\parindent}{0in}
|
||||
\setlength{\parskip}{12pt}
|
||||
|
||||
|
||||
\author{Matti Pastell}
|
||||
\title{Using PGF plots with Weave and Gadfly}
|
||||
|
||||
\begin{document}
|
||||
|
||||
|
||||
\maketitle
|
||||
|
||||
\section{Intro}
|
||||
|
||||
This is a minimal example on using PGF format with Gadfly plots in
|
||||
\href{https://github.com/JunoLab/Weave.jl}{Weave.jl} document.
|
||||
The source is in github:
|
||||
|
||||
\url{https://github.com/JunoLab/Weave.jl/blob/master/examples/gadfly_pgf.texw}.
|
||||
|
||||
You can run this example with first weaving it from Julia using:
|
||||
|
||||
<<eval=false>>=
|
||||
using Weave
|
||||
weave(Pkg.dir("Weave", "examples", "gadfly_pgf.texw"),
|
||||
doctype="texminted", out_path=:pwd, fig_ext=".tex")
|
||||
@
|
||||
|
||||
which will save the generated output in your working directory and use minted
|
||||
package for syntax hightlighting. You'll need to use either xetex or luatex with
|
||||
\texttt{-shell-escape} flag to get pdf e.g.
|
||||
|
||||
\begin{minted}{bash}
|
||||
lualatex -shell-escape gadfly_pgf.tex
|
||||
\end{minted}
|
||||
|
||||
\section{Sample code}
|
||||
|
||||
You can set the default font in Gadfly to match the font in the document.
|
||||
Use the \texttt{fontspec} latex package (see preamble) and define the
|
||||
defaults to Gadfly as follows.
|
||||
|
||||
If you want you can hide the chunk using the \texttt{echo=false} chunk option.
|
||||
|
||||
<<>>=
|
||||
using Gadfly
|
||||
Gadfly.default_theme.major_label_font = "Tex Gyre Pagella"
|
||||
Gadfly.default_theme.minor_label_font = "Tex Gyre Pagella"
|
||||
Gadfly.default_theme.major_label_color = colorant"black"
|
||||
Gadfly.default_theme.minor_label_color = colorant"black"
|
||||
@
|
||||
|
||||
Let's create a simple plot:
|
||||
|
||||
<<>>=
|
||||
x = 1:10
|
||||
plot(x=x, y=x)
|
||||
@
|
||||
|
||||
And a figure with a caption
|
||||
|
||||
<<fig_cap="Nice Gadfly figure">>=
|
||||
plot([sin, cos], 0, 25)
|
||||
@
|
||||
|
||||
|
||||
\end{document}
|
|
@ -1,30 +0,0 @@
|
|||
|
||||
# Gadfly
|
||||
|
||||
```{julia;term=true;fig_width=5}
|
||||
using Gadfly
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
y = 20
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
```
|
||||
|
||||
|
||||
```julia
|
||||
x = linspace(0, 200)
|
||||
println(x)
|
||||
```
|
||||
|
||||
|
||||
~~~{julia;term=true;fig_width=5}
|
||||
using Gadfly
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
y = 20
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
~~~
|
||||
|
||||
~~~julia
|
||||
x = linspace(0, 200)
|
||||
println(x)
|
||||
~~~
|
|
@ -1,14 +1,70 @@
|
|||
# Gadfly
|
||||
% Intro to Weave.jl with Gadfly
|
||||
% Matti Pastell
|
||||
% 20th April 2016
|
||||
|
||||
<<term=true>>=
|
||||
using Gadfly
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
y = 20
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
@
|
||||
# Introduction
|
||||
|
||||
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||
be executed using [Weave.jl](https://github.com/JunoLab/Weave.jl).
|
||||
|
||||
The code is delimited from docs using `<<>>=` and `@` markup which can be seen
|
||||
looking at the source document `gadfly_sample.mdw` in the examples directory
|
||||
of the package. The source document can be executed and the results with Gadfly
|
||||
plots are captured in the resulting file.
|
||||
|
||||
You can create markdown output or pdf and HTML directly (with Pandoc) using
|
||||
the weave command as follows:
|
||||
|
||||
```julia
|
||||
using Weave
|
||||
#Markdown
|
||||
weave(Pkg.dir("Weave","examples","gadfly_sample.mdw"),
|
||||
out_path = :pwd, doctype = "pandoc")
|
||||
#HTML
|
||||
weave(Pkg.dir("Weave","examples","gadfly_sample.mdw"),
|
||||
out_path = :pwd, doctype = "md2html")
|
||||
#pdf
|
||||
weave(Pkg.dir("Weave","examples","gadfly_sample.mdw"),
|
||||
out_path = :pwd, doctype = "md2pdf")
|
||||
```
|
||||
|
||||
*The documents will be written to the Julia working directory when you
|
||||
use the `out_path = :pwd`.*
|
||||
|
||||
# Capturing code
|
||||
|
||||
The basic code chunk will be run with default options and the code and
|
||||
output will be captured.
|
||||
|
||||
<<>>=
|
||||
x = linspace(0, 200)
|
||||
using Gadfly
|
||||
x = linspace(0, 2*pi)
|
||||
println(x)
|
||||
plot(x = x, y = sin(x))
|
||||
@
|
||||
|
||||
You can also control the way the results are captured, plot size etc.
|
||||
using chunk options. Here is an example of a chunk that behaves like a repl.
|
||||
|
||||
<<term=true>>=
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
@
|
||||
|
||||
You can also for instance hide the code and show only the figure, add a
|
||||
caption to the figure and make it wider as follows (you can only see the
|
||||
syntax from the source document):
|
||||
|
||||
<<echo=false; fig_cap="A random walk."; label="random"; fig_width=8; fig_height=4>>=
|
||||
plot(y = cumsum(randn(1000, 1)), Geom.line)
|
||||
@
|
||||
|
||||
# Whats next
|
||||
|
||||
Read the documentation:
|
||||
|
||||
- stable: <http://mpastell.github.io/Weave.jl/stable/>
|
||||
- latest: <http://weavejl.mpastell.com/dev/>
|
||||
|
||||
See other examples in: <https://github.com/JunoLab/Weave.jl/tree/master/examples>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||
be executed using Weave. Output from code chunks and PyPlot
|
||||
plots will be included in the weaved document. You also need to install Pweave from Github in order to use Weave.
|
||||
plots will be included in the weaved document. You also need to install Pweave from GitHub in order to use Weave.
|
||||
|
||||
This documented can be turned into Pandoc markdown with captured
|
||||
result from Julia prompt.
|
||||
|
@ -17,7 +17,7 @@ weave("examples/julia_sample.mdw")
|
|||
|
||||
<<term=true>>=
|
||||
x = 1:10
|
||||
d = {"Weave" => "testing"}
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
@
|
||||
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
title: A minimal beamer example using Weave markdown
|
||||
author: Matti Pastell
|
||||
weave_options:
|
||||
doctype : md2pdf
|
||||
out_path : pdf
|
||||
template : beamer.tpl
|
||||
---
|
||||
|
||||
```julia; echo=false
|
||||
struct Begin
|
||||
text
|
||||
title
|
||||
end
|
||||
|
||||
struct End
|
||||
text
|
||||
end
|
||||
Base.show(io::IO, m::MIME"text/latex", b::Begin) = write(io, "\\begin{$(b.text)}[fragile]\n\\frametitle{$(b.title)}\n")
|
||||
Base.show(io::IO, m::MIME"text/latex", e::End) = write(io, "\\end{$(e.text)}")
|
||||
```
|
||||
|
||||
! Begin("frame", "Random plot")
|
||||
|
||||
```julia; out_width="0.5\\textwidth"
|
||||
using Plots
|
||||
scatter(randn(1000), randn(1000))
|
||||
```
|
||||
! End("frame")
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
<<>>=
|
||||
using Plots
|
||||
pyplot()
|
||||
x = linspace(0, 2π, 2056)
|
||||
@
|
||||
|
||||
<<>>=
|
||||
plot(sinc(x))
|
||||
@
|
||||
|
||||
<<>>=
|
||||
plot(-sinc(x))
|
||||
@
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
<<>>=
|
||||
using Plots
|
||||
plotly()
|
||||
x = linspace(0, 2π, 2056)
|
||||
@
|
||||
|
||||
<<>>=
|
||||
plot(sinc(x))
|
||||
@
|
||||
|
||||
<<>>=
|
||||
plot(-sinc(x))
|
||||
@
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
# Introducion to Weave
|
||||
|
||||
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||
be executed using Weave. Output from code chunks and Winston
|
||||
plots will be included in the weaved document. You also need to install Pweave from Github in order to use Weave.
|
||||
|
||||
This documented can be turned into Pandoc markdown with captured
|
||||
result from Julia prompt.
|
||||
|
||||
~~~~{.julia}
|
||||
using Weave
|
||||
weave(Pkg.dir("Weave","examples","winston_sample.mdw"), plotlib="Winston")
|
||||
~~~~
|
||||
|
||||
## Terminal chunk
|
||||
|
||||
<<term=true>>=
|
||||
x = 1:10
|
||||
d = {"Weave" => "testing"}
|
||||
y = [2, 4 ,8]
|
||||
@
|
||||
|
||||
## Capturing figures
|
||||
|
||||
The figures and code can be included in the output.
|
||||
|
||||
<<term=true>>=
|
||||
using Winston
|
||||
t = linspace(0, 2*pi, 100)
|
||||
p = plot(t, sinc(t))
|
||||
@
|
||||
|
||||
You can also include a plot with caption and hide the code:
|
||||
|
||||
<<echo=false; fig_cap="Random walk."; label="random"; fig_width=8; fig_height=4>>=
|
||||
p = plot(cumsum(randn(1000, 1)))
|
||||
xlabel("x")
|
||||
ylabel("sinc(x)")
|
||||
display(p)
|
||||
@
|
||||
|
||||
<<>>=
|
||||
x = linspace(0, 3pi, 100)
|
||||
c = cos(x)
|
||||
s = sin(x)
|
||||
|
||||
p = FramedPlot(
|
||||
title="title!",
|
||||
xlabel="\\Sigma x^2_i",
|
||||
ylabel="\\Theta_i")
|
||||
|
||||
add(p, FillBetween(x, c, x, s))
|
||||
add(p, Curve(x, c, color="red"))
|
||||
add(p, Curve(x, s, color="blue"))
|
||||
display(p)
|
||||
@
|
|
@ -0,0 +1,21 @@
|
|||
@article{julia,
|
||||
author = {Jeff Bezanson and Alan Edelman and Stefan Karpinski and Viral B. Shah},
|
||||
title = {Julia: A Fresh Approach to Numerical Computing},
|
||||
journal = {SIAM Review},
|
||||
volume = {59},
|
||||
number = {1},
|
||||
pages = {65-98},
|
||||
year = {2017},
|
||||
doi = {10.1137/141000671},
|
||||
}
|
||||
|
||||
@Book{knitr,
|
||||
title = {Dynamic Documents with {R} and knitr},
|
||||
author = {Yihui Xie},
|
||||
publisher = {Chapman and Hall/CRC},
|
||||
address = {Boca Raton, Florida},
|
||||
year = {2015},
|
||||
edition = {2nd},
|
||||
note = {ISBN 978-1498716963},
|
||||
url = {http://yihui.name/knitr/},
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
title: 'Weave.jl: Scientific Reports Using Julia'
|
||||
tags:
|
||||
- Scientific reports
|
||||
- Julia
|
||||
authors:
|
||||
- name: Matti Pastell
|
||||
orcid: 0000-0002-5810-4801
|
||||
affiliation: 1
|
||||
affiliations:
|
||||
- name: Natural Resources Institute Finland (Luke)
|
||||
index: 1
|
||||
date: 6 March 2017
|
||||
bibliography: paper.bib
|
||||
---
|
||||
|
||||
# Summary
|
||||
|
||||
Weave is a tool for writing scientific reports using Julia
|
||||
[@julia]. It allows writing of text, mathematics and code in a single
|
||||
document which can be run capturing results into a rich report.
|
||||
Output can include text using several markup languages, plots
|
||||
generated using one of the several Julia plotting libraries and other
|
||||
objects displayed using Julia's multimedia output. The workflow is
|
||||
very similar to using Knitr [@knitr] R-package.
|
||||
|
||||
Weave supports noweb, markdown, script syntax for delimiting code from
|
||||
text in the source document and several output formats including
|
||||
Markdown and Latex. The output from code can be controlled using chunk
|
||||
options making it possible e.g. to hide code and only show output when
|
||||
needed as well as set a figure caption and figure size. The library
|
||||
also has methods for converting documents from all input formats to
|
||||
Jupyter notebooks and vice versa.
|
||||
|
||||
The package aims to support writing scientific papers and enable easy
|
||||
sharing of analysis in order to promote reproducible research. It also
|
||||
aims to enable simple writing of educational material, tutorials and
|
||||
blog posts.
|
||||
|
||||
# References
|
597
src/Weave.jl
597
src/Weave.jl
|
@ -1,275 +1,344 @@
|
|||
module Weave
|
||||
using Compat
|
||||
|
||||
#Contains report global properties
|
||||
type Report <: Display
|
||||
source::String
|
||||
documentationmode::Bool
|
||||
cwd::String
|
||||
basename::String
|
||||
formatdict
|
||||
pending_code::String
|
||||
cur_result::String
|
||||
fignum::Int
|
||||
figures::Array
|
||||
term_state::Symbol
|
||||
cur_chunk::Dict{Symbol, Any}
|
||||
using Highlights, Mustache, Requires, Pkg, REPL, RelocatableFolders, Base64
|
||||
|
||||
# directories
|
||||
const PKG_DIR = normpath(@__DIR__, "..")
|
||||
const TEMPLATE_DIR = @path joinpath(PKG_DIR, "templates")
|
||||
const STYLESHEET_DIR = @path joinpath(PKG_DIR, "stylesheets")
|
||||
# keeps paths of sample documents for easy try
|
||||
const EXAMPLE_FOLDER = @path joinpath(PKG_DIR, "examples")
|
||||
|
||||
function Report()
|
||||
new("", false, "", "", Any[], "", "", 1, Any[], :text, @compat Dict{Symbol, Any}() )
|
||||
end
|
||||
# constant names
|
||||
const WEAVE_OPTION_NAME = "weave_options"
|
||||
const WEAVE_OPTION_NAME_DEPRECATED = "options" # remove this when tagging v0.11
|
||||
const WEAVE_OPTION_DEPRECATE_ID = "weave_option_duplicate_id"
|
||||
const DEFAULT_FIG_PATH = "figures"
|
||||
|
||||
const WEAVE_VERSION = try
|
||||
'v' * Pkg.TOML.parsefile(normpath(PKG_DIR, "Project.toml"))["version"]
|
||||
catch
|
||||
""
|
||||
end
|
||||
weave_info() = WEAVE_VERSION, string(Date(now()))
|
||||
|
||||
function __init__()
|
||||
@require Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" include("plots.jl")
|
||||
@require Gadfly = "c91e804a-d5a3-530f-b6f0-dfbca275c004" include("gadfly.jl")
|
||||
end
|
||||
|
||||
const report = Report()
|
||||
|
||||
const supported_mime_types =
|
||||
[MIME"image/png",
|
||||
MIME"text/plain"]
|
||||
|
||||
function Base.display(doc::Report, data)
|
||||
for m in supported_mime_types
|
||||
if mimewritable(m(), data)
|
||||
display(doc, m(), data)
|
||||
brea
|
||||
end
|
||||
end
|
||||
end
|
||||
# utilitity functions
|
||||
take2string!(io) = String(take!(io))
|
||||
joinlines(lines) = join(lines, '\n')
|
||||
|
||||
|
||||
function list_out_formats()
|
||||
for format = keys(formats)
|
||||
println(string(format,": ", formats[format].description))
|
||||
end
|
||||
end
|
||||
|
||||
#module ReportSandBox
|
||||
#end
|
||||
|
||||
|
||||
function weave(source ; doctype = "pandoc", plotlib="PyPlot", informat="noweb", fig_path = "figures", fig_ext = nothing)
|
||||
|
||||
cwd, fname = splitdir(abspath(source))
|
||||
basename = splitext(fname)[1]
|
||||
formatdict = formats[doctype].formatdict
|
||||
if fig_ext == nothing
|
||||
rcParams[:chunk_defaults][:fig_ext] = formatdict[:fig_ext]
|
||||
else
|
||||
rcParams[:chunk_defaults][:fig_ext] = fig_ext
|
||||
end
|
||||
|
||||
|
||||
|
||||
report.source = source
|
||||
report.cwd = cwd
|
||||
report.basename = basename
|
||||
rcParams[:chunk_defaults][:fig_path] = fig_path
|
||||
report.formatdict = formatdict
|
||||
|
||||
|
||||
if plotlib == nothing
|
||||
rcParams[:chunk_defaults][:fig] = false
|
||||
else
|
||||
l_plotlib = lowercase(plotlib)
|
||||
rcParams[:chunk_defaults][:fig] = true
|
||||
if l_plotlib == "winston"
|
||||
eval(parse("""include(Pkg.dir("Weave","src","winston.jl"))"""))
|
||||
rcParams[:plotlib] = "Winston"
|
||||
elseif l_plotlib == "pyplot"
|
||||
eval(Expr(:using, :PyPlot))
|
||||
rcParams[:plotlib] = "PyPlot"
|
||||
elseif l_plotlib == "gadfly"
|
||||
eval(parse("""include(Pkg.dir("Weave","src","gadfly.jl"))"""))
|
||||
rcParams[:plotlib] = "Gadfly"
|
||||
end
|
||||
end
|
||||
|
||||
pushdisplay(report)
|
||||
parsed = read_document(source, informat)
|
||||
executed = run(parsed)
|
||||
popdisplay(report)
|
||||
formatted = format(executed, doctype)
|
||||
outname = "$(report.cwd)/$(report.basename).$(formatdict[:extension])"
|
||||
open(outname, "w") do io
|
||||
write(io, join(formatted, "\n"))
|
||||
end
|
||||
|
||||
info("Report weaved to $(report.basename).$(formatdict[:extension])")
|
||||
|
||||
end
|
||||
|
||||
|
||||
function run_block(code_str)
|
||||
oldSTDOUT = STDOUT
|
||||
result = ""
|
||||
|
||||
rw, wr = redirect_stdout()
|
||||
#If there is nothing to read code will hang
|
||||
println()
|
||||
|
||||
try
|
||||
n = length(code_str)
|
||||
pos = 1 #The first character is extra line end
|
||||
while pos < n
|
||||
oldpos = pos
|
||||
code, pos = parse(code_str, pos)
|
||||
s = eval(ReportSandBox, code)
|
||||
if rcParams[:plotlib] == "Gadfly"
|
||||
s != nothing && display(s)
|
||||
end
|
||||
end
|
||||
finally
|
||||
|
||||
redirect_stdout(oldSTDOUT)
|
||||
close(wr)
|
||||
result = readall(rw)
|
||||
close(rw)
|
||||
end
|
||||
|
||||
return string("\n", result)
|
||||
end
|
||||
|
||||
function run_term(code_str)
|
||||
prompt = "\njulia> "
|
||||
codestart = "\n\n"*report.formatdict[:codestart]
|
||||
|
||||
if haskey(report.formatdict, :indent)
|
||||
prompt = indent(prompt, report.formatdict[:indent])
|
||||
end
|
||||
|
||||
#Emulate terminal
|
||||
n = length(code_str)
|
||||
pos = 2 #The first character is extra line end
|
||||
while pos < n
|
||||
oldpos = pos
|
||||
code, pos = parse(code_str, pos)
|
||||
|
||||
report.term_state == :fig && (report.cur_result*= codestart)
|
||||
prompts = string(prompt, rstrip(code_str[oldpos:(pos-1)]), "\n")
|
||||
report.cur_result *= prompts
|
||||
report.term_state = :text
|
||||
s = eval(ReportSandBox, code)
|
||||
s != nothing && display(s)
|
||||
end
|
||||
|
||||
return string(report.cur_result)
|
||||
end
|
||||
|
||||
|
||||
function run(parsed)
|
||||
#Clear sandbox for each document
|
||||
#Raises a warning, couldn't find a "cleaner"
|
||||
#way to do it.
|
||||
eval(parse("module ReportSandBox\nend"))
|
||||
|
||||
i = 1
|
||||
for chunk in copy(parsed)
|
||||
if chunk[:type] == "code"
|
||||
#print(chunk["content"])
|
||||
info("Weaving chunk $(chunk[:number]) from line $(chunk[:start_line])")
|
||||
defaults = copy(rcParams[:chunk_defaults])
|
||||
options = copy(chunk[:options])
|
||||
try
|
||||
options = merge(rcParams[:chunk_defaults], options)
|
||||
catch
|
||||
options = rcParams[:chunk_defaults]
|
||||
warn("Invalid format for chunk options line: $(chunk[:start_line])")
|
||||
end
|
||||
|
||||
merge!(chunk, options)
|
||||
delete!(chunk, :options)
|
||||
|
||||
if !chunk[:eval]
|
||||
chunk[:result] = ""
|
||||
parsed[i] = copy(chunk)
|
||||
i += 1
|
||||
continue #Do nothing if eval is false
|
||||
end
|
||||
|
||||
report.fignum = 1
|
||||
report.cur_result = ""
|
||||
report.figures = String[]
|
||||
report.cur_chunk = chunk
|
||||
report.term_state = :text
|
||||
if haskey(report.formatdict, :out_width) && chunk[:out_width] == nothing
|
||||
chunk[:out_width] = report.formatdict[:out_width]
|
||||
end
|
||||
|
||||
if chunk[:term]
|
||||
chunk[:result] = run_term(chunk[:content])
|
||||
chunk[:term_state] = report.term_state
|
||||
else
|
||||
chunk[:result] = run_block(chunk[:content])
|
||||
end
|
||||
|
||||
if rcParams[:plotlib] == "PyPlot"
|
||||
chunk[:fig] && (chunk[:figure] = savefigs(chunk))
|
||||
else
|
||||
chunk[:fig] && (chunk[:figure] = copy(report.figures))
|
||||
end
|
||||
end
|
||||
parsed[i] = copy(chunk)
|
||||
i += 1
|
||||
end
|
||||
parsed
|
||||
end
|
||||
|
||||
function savefigs(chunk)
|
||||
l_plotlib = lowercase(rcParams[:plotlib])
|
||||
if l_plotlib == "pyplot"
|
||||
return savefigs_pyplot(chunk)
|
||||
end
|
||||
end
|
||||
|
||||
function savefigs_pyplot(chunk)
|
||||
fignames = String[]
|
||||
ext = report.formatdict[:fig_ext]
|
||||
figpath = joinpath(report.cwd, chunk[:fig_path])
|
||||
isdir(figpath) || mkdir(figpath)
|
||||
chunkid = (chunk[:name] == nothing) ? chunk[:number] : chunk[:name]
|
||||
#Iterate over all open figures, save them and store names
|
||||
for fig = plt.get_fignums()
|
||||
full_name, rel_name = get_figname(report, chunk, fignum=fig)
|
||||
savefig(full_name, dpi=chunk[:dpi])
|
||||
push!(fignames, rel_name)
|
||||
plt.draw()
|
||||
plt.close()
|
||||
end
|
||||
return fignames
|
||||
end
|
||||
|
||||
|
||||
function Base.display(report::Report, m::MIME"text/plain", data)
|
||||
if report.term_state == :fig #Catch Winston plot command output
|
||||
report.cur_result *= "\n" * report.formatdict[:codestart] * "\n"
|
||||
end
|
||||
|
||||
s = reprmime(m, data)
|
||||
haskey(report.formatdict, :indent) && (s = indent(s, report.formatdict[:indent]))
|
||||
|
||||
report.cur_result *= s * "\n"
|
||||
|
||||
if report.term_state == :fig #Catch Winston plot command output
|
||||
report.cur_result *= "\n" * report.formatdict[:codeend] * "\n"
|
||||
end
|
||||
end
|
||||
|
||||
function get_figname(report::Report, chunk; fignum = nothing)
|
||||
figpath = joinpath(report.cwd, chunk[:fig_path])
|
||||
isdir(figpath) || mkdir(figpath)
|
||||
ext = chunk[:fig_ext]
|
||||
fignum == nothing && (fignum = report.fignum)
|
||||
|
||||
chunkid = (chunk[:name] == nothing) ? chunk[:number] : chunk[:name]
|
||||
full_name = joinpath(report.cwd, chunk[:fig_path], "$(report.basename)_$(chunkid)_$(fignum)$ext")
|
||||
rel_name = "$(chunk[:fig_path])/$(report.basename)_$(chunkid)_$(fignum)$ext" #Relative path is used in output
|
||||
return full_name, rel_name
|
||||
end
|
||||
|
||||
export weave, list_out_formats
|
||||
|
||||
include("types.jl")
|
||||
include("config.jl")
|
||||
include("readers.jl")
|
||||
include("formatters.jl")
|
||||
include("WeaveMarkdown/markdown.jl")
|
||||
include("display_methods.jl")
|
||||
include("reader/reader.jl")
|
||||
include("run.jl")
|
||||
include("cache.jl")
|
||||
include("rendering/rendering.jl")
|
||||
include("writer/writer.jl")
|
||||
include("converter.jl")
|
||||
|
||||
|
||||
get_format(doctype::AbstractString) = FORMATS[doctype]
|
||||
|
||||
"""
|
||||
list_out_formats()
|
||||
|
||||
List supported output formats with its description.
|
||||
"""
|
||||
list_out_formats() = [k => v.description for (k,v) in FORMATS]
|
||||
|
||||
"""
|
||||
tangle(source::AbstractString; kwargs...)
|
||||
|
||||
Tangle source code from input document to .jl file.
|
||||
|
||||
## Keyword options
|
||||
|
||||
- `informat::Union{Nothing,AbstractString} = nothing`: Input document format. By default (i.e. given `nothing`), Weave will set it automatically based on file extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
|
||||
- `out_path::Union{Symbol,AbstractString} = :doc`: Path where the output is generated can be either of:
|
||||
* `:doc`: Path of the source document (default)
|
||||
* `:pwd`: Julia working directory
|
||||
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
||||
"""
|
||||
function tangle(
|
||||
source::AbstractString;
|
||||
out_path::Union{Symbol,AbstractString} = :doc,
|
||||
informat::Union{Nothing,AbstractString} = nothing,
|
||||
)
|
||||
doc = WeaveDoc(source, informat)
|
||||
doc.cwd = get_cwd(doc, out_path)
|
||||
|
||||
out_path = get_out_path(doc, out_path, "jl")
|
||||
|
||||
open(out_path, "w") do io
|
||||
for chunk in doc.chunks
|
||||
if typeof(chunk) == CodeChunk
|
||||
options = merge(doc.chunk_defaults, chunk.options)
|
||||
options[:tangle] && write(io, chunk.content * "\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@info "Tangled to $(out_path)"
|
||||
end
|
||||
|
||||
"""
|
||||
weave(source::AbstractString; kwargs...)
|
||||
|
||||
Weave an input document to output file.
|
||||
|
||||
## Keyword options
|
||||
|
||||
- `doctype::Union{Nothing,AbstractString} = nothing`: Output document format. By default (i.e. given `nothing`), Weave will set it automatically based on file extension. You can also manually specify it; see [`list_out_formats()`](@ref) for the supported formats
|
||||
- `informat::Union{Nothing,AbstractString} = nothing`: Input document format. By default (i.e. given `nothing`), Weave will set it automatically based on file extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
|
||||
- `out_path::Union{Symbol,AbstractString} = :doc`: Path where the output is generated can be either of:
|
||||
* `:doc`: Path of the source document (default)
|
||||
* `:pwd`: Julia working directory
|
||||
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
||||
- `args::Any = Dict()`: A runtime object that is available as `WEAVE_ARGS` while `weave`ing
|
||||
- `mod::Union{Module,Nothing} = nothing`: Module where Weave `eval`s code. You can pass a `Module` object, otherwise create an new sandbox module.
|
||||
- `fig_path::Union{Nothing,AbstractString} = nothing`: Where figures will be generated, relative to `out_path`. By default (i.e. given `nothing`), Weave will automatically create `$(DEFAULT_FIG_PATH)` directory.
|
||||
- `fig_ext::Union{Nothing,AbstractString} = nothing`: Extension for saved figures e.g. `".pdf"`, `".png"`. Default setting depends on `doctype`
|
||||
- `cache_path::AbstractString = "cache"`: Where of cached output will be saved
|
||||
- `cache::Symbol = :off`: Controls caching of code:
|
||||
* `:off` means no caching (default)
|
||||
* `:all` caches everything
|
||||
* `:user` caches based on chunk options
|
||||
* `:refresh` runs all code chunks and save new cache
|
||||
- `template::Union{Nothing,AbstractString,Mustache.MustacheTokens} = nothing`: Template (file path) or `Mustache.MustacheTokens`s for `md2html` or `md2tex` formats
|
||||
- `css::Union{Nothing,AbstractString} = nothing`: Path of a CSS file used for md2html format
|
||||
- `highlight_theme::Union{Nothing,Type{<:Highlights.AbstractTheme}} = nothing`: Theme used for syntax highlighting (defaults to `Highlights.Themes.DefaultTheme`)
|
||||
- `pandoc_options::Vector{<:AbstractString} = $(DEFAULT_PANDOC_OPTIONS)`: `String`s of options to pass to pandoc for `pandoc2html` and `pandoc2pdf` formats, e.g. `["--toc", "-N"]`
|
||||
- `latex_cmd::Vector{<:AbstractString} = $(DEFAULT_LATEX_CMD)`: The command used to make PDF file from .tex
|
||||
- `keep_unicode::Bool = false`: If `true`, do not convert unicode characters to their respective latex representation. This is especially useful if a font and tex-engine with support for unicode characters are used
|
||||
|
||||
!!! note
|
||||
Run Weave from terminal and try to avoid weaving from IJulia or ESS; they tend to mess with capturing output.
|
||||
"""
|
||||
function weave(
|
||||
source::AbstractString;
|
||||
doctype::Union{Nothing,AbstractString} = nothing,
|
||||
informat::Union{Nothing,AbstractString} = nothing,
|
||||
out_path::Union{Symbol,AbstractString} = :doc,
|
||||
args::Any = Dict(),
|
||||
mod::Union{Module,Nothing} = nothing,
|
||||
fig_path::Union{Nothing,AbstractString} = nothing,
|
||||
fig_ext::Union{Nothing,AbstractString} = nothing,
|
||||
cache_path::AbstractString = "cache",
|
||||
cache::Symbol = :off,
|
||||
template::Union{Nothing,AbstractString,Mustache.MustacheTokens} = nothing,
|
||||
css::Union{Nothing,AbstractString} = nothing, # TODO: rename to `stylesheet`
|
||||
highlight_theme::Union{Nothing,Type{<:Highlights.AbstractTheme}} = nothing,
|
||||
pandoc_options::Vector{<:AbstractString} = DEFAULT_PANDOC_OPTIONS,
|
||||
latex_cmd::Vector{<:AbstractString} = DEFAULT_LATEX_CMD,
|
||||
keep_unicode::Bool = false,
|
||||
)
|
||||
doc = WeaveDoc(source, informat)
|
||||
|
||||
# run document
|
||||
# ------------
|
||||
|
||||
# overwrites options with those specified in header, that are needed for running document
|
||||
# NOTE: these YAML options can NOT be given dynamically
|
||||
weave_options = get(doc.header, WEAVE_OPTION_NAME, nothing)
|
||||
if haskey(doc.header, WEAVE_OPTION_NAME_DEPRECATED)
|
||||
@warn "Weave: `options` key is deprecated. Use `weave_options` key instead." _id = WEAVE_OPTION_DEPRECATE_ID maxlog = 1
|
||||
weave_options = get(doc.header, WEAVE_OPTION_NAME_DEPRECATED, nothing)
|
||||
end
|
||||
|
||||
if !isnothing(weave_options)
|
||||
doctype = get(weave_options, "doctype", doctype)
|
||||
specific_options!(weave_options, doctype)
|
||||
if haskey(weave_options, "out_path")
|
||||
out_path = let
|
||||
out_path = weave_options["out_path"]
|
||||
if out_path == ":doc" || out_path == ":pwd"
|
||||
Symbol(out_path)
|
||||
else
|
||||
normpath(dirname(source), out_path) # resolve relative to this document
|
||||
end
|
||||
end
|
||||
end
|
||||
mod = get(weave_options, "mod", mod)
|
||||
mod isa AbstractString && (mod = Main.eval(Meta.parse(mod)))
|
||||
fig_path = get(weave_options, "fig_path", fig_path)
|
||||
fig_ext = get(weave_options, "fig_ext", fig_ext)
|
||||
cache_path = get(weave_options, "cache_path", cache_path)
|
||||
cache = Symbol(get(weave_options, "cache", cache))
|
||||
end
|
||||
|
||||
doc = run_doc(
|
||||
doc;
|
||||
doctype = doctype,
|
||||
mod = mod,
|
||||
out_path = out_path,
|
||||
args = args,
|
||||
fig_path = fig_path,
|
||||
fig_ext = fig_ext,
|
||||
cache_path = cache_path,
|
||||
cache = cache,
|
||||
)
|
||||
|
||||
# overwrites options with those specified in header, that are needed for rendering/writing document
|
||||
# NOTE: these YAML options can be given dynamically
|
||||
if !isnothing(weave_options)
|
||||
if haskey(weave_options, "template")
|
||||
template = weave_options["template"]
|
||||
# resolve relative to this document
|
||||
template isa AbstractString && (template = normpath(dirname(source), template))
|
||||
end
|
||||
if haskey(weave_options, "css")
|
||||
css = weave_options["css"]
|
||||
# resolve relative to this document
|
||||
css isa AbstractString && (css = normpath(dirname(source), css))
|
||||
end
|
||||
highlight_theme = get(weave_options, "highlight_theme", highlight_theme)
|
||||
keep_unicode = get(weave_options, "keep_unicode", keep_unicode)
|
||||
latex_cmd = get(weave_options, "latex_cmd", latex_cmd)
|
||||
pandoc_options = get(weave_options, "pandoc_options", pandoc_options)
|
||||
end
|
||||
|
||||
set_format_options!(
|
||||
doc;
|
||||
# general
|
||||
template = template,
|
||||
highlight_theme = highlight_theme,
|
||||
css = css,
|
||||
# pandoc
|
||||
pandoc_options = pandoc_options,
|
||||
# latex
|
||||
keep_unicode = keep_unicode,
|
||||
latex_cmd = latex_cmd,
|
||||
)
|
||||
|
||||
# render document
|
||||
# ---------------
|
||||
rendered = render_doc(doc)
|
||||
|
||||
# write documents
|
||||
# ---------------
|
||||
out_path = write_doc(doc, rendered, get_out_path(doc, out_path))
|
||||
|
||||
@info "Weaved to $(out_path)"
|
||||
return out_path
|
||||
end
|
||||
|
||||
weave(doc::AbstractString, doctype::Union{Symbol,AbstractString}; kwargs...) =
|
||||
weave(doc; doctype = doctype, kwargs...)
|
||||
|
||||
function specific_options!(weave_options, doctype)
|
||||
fmts = keys(FORMATS)
|
||||
for (k,v) in weave_options
|
||||
if k in fmts
|
||||
k == doctype && merge!(weave_options, v)
|
||||
delete!(weave_options, k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
get_out_path(doc, out_path, ext::Nothing = nothing) = get_out_path(doc, out_path, doc.format.extension)
|
||||
function get_out_path(doc, out_path, ext)
|
||||
if (out_path === :doc) || (out_path === :pwd)
|
||||
abspath(get_cwd(doc, out_path), string(doc.basename, '.', ext))
|
||||
elseif isempty(splitext(out_path)[2]) # directory given
|
||||
abspath(get_cwd(doc, out_path), string(doc.basename, '.', ext))
|
||||
else
|
||||
# out_path is given, but if extension is explitly provided override this will override the extension
|
||||
abspath(string(splitext(out_path)[1], '.', ext))
|
||||
end
|
||||
end
|
||||
"""
|
||||
notebook(source::AbstractString; kwargs...)
|
||||
|
||||
Convert Weave document `source` to Jupyter Notebook and execute the code
|
||||
using [`nbconvert`](https://nbconvert.readthedocs.io/en/latest/).
|
||||
**Ignores** all chunk options.
|
||||
|
||||
## Keyword options
|
||||
|
||||
- `out_path::Union{Symbol,AbstractString} = :pwd`: Path where the output is generated can be either of:
|
||||
* `:doc`: Path of the source document
|
||||
* `:pwd`: Julia working directory (default)
|
||||
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
||||
- `timeout = -1`: nbconvert cell timeout in seconds. Defaults to `-1` (no timeout)
|
||||
- `nbconvert_options::AbstractString = ""`: `String` of additional options to pass to nbconvert, such as `"--allow-errors"`
|
||||
- `jupyter_path::AbstractString = "jupyter"`: Path/command for the Jupyter you want to use. Defaults to `"jupyter"`, which runs whatever is linked/alias to that
|
||||
|
||||
!!! warning
|
||||
The code is _**not**_ executed by Weave, but by [`nbconvert`](https://nbconvert.readthedocs.io/en/latest/).
|
||||
This means that the output doesn't necessarily always work properly; see [#116](https://github.com/JunoLab/Weave.jl/issues/116).
|
||||
|
||||
!!! note
|
||||
In order to _just_ convert Weave document to Jupyter Notebook,
|
||||
use [`convert_doc`](@ref) instead.
|
||||
"""
|
||||
function notebook(
|
||||
source::AbstractString;
|
||||
out_path::Union{Symbol,AbstractString} = :pwd,
|
||||
timeout = -1,
|
||||
nbconvert_options::AbstractString = "",
|
||||
jupyter_path::AbstractString = "jupyter",
|
||||
)
|
||||
doc = WeaveDoc(source)
|
||||
converted = convert_to_notebook(doc)
|
||||
doc.cwd = get_cwd(doc, out_path)
|
||||
out_path = get_out_path(doc, out_path, "ipynb")
|
||||
|
||||
write(out_path, converted)
|
||||
|
||||
@info "Running nbconvert ..."
|
||||
return read(
|
||||
`$jupyter_path nbconvert --ExecutePreprocessor.timeout=$timeout --to notebook --execute $(out_path) $nbconvert_options --output $(out_path)`,
|
||||
String,
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
include_weave(source::AbstractString, informat::Union{Nothing,AbstractString} = nothing)
|
||||
include_weave(m::Module, source::AbstractString, informat::Union{Nothing,AbstractString} = nothing)
|
||||
|
||||
Include code from Weave document calling `include_string` on all code from doc.
|
||||
Code is run in the path of the include document.
|
||||
"""
|
||||
function include_weave(
|
||||
m::Module,
|
||||
source::AbstractString,
|
||||
informat::Union{Nothing,AbstractString} = nothing,
|
||||
)
|
||||
old_path = pwd()
|
||||
doc = WeaveDoc(source, informat)
|
||||
cd(dirname(doc.path))
|
||||
try
|
||||
code = join(
|
||||
[x.content for x in filter(x -> isa(x, Weave.CodeChunk), doc.chunks)],
|
||||
"\n",
|
||||
)
|
||||
include_string(m, code)
|
||||
catch err
|
||||
throw(err)
|
||||
finally
|
||||
cd(old_path)
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
include_weave(source, informat = nothing) = include_weave(Main, source, informat)
|
||||
|
||||
|
||||
export weave,
|
||||
list_out_formats,
|
||||
tangle,
|
||||
convert_doc,
|
||||
notebook,
|
||||
set_chunk_defaults!,
|
||||
get_chunk_defaults,
|
||||
restore_chunk_defaults!,
|
||||
include_weave
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
# Markdown to HTML writer, Modified from Julia Base.Markdown html writer
|
||||
|
||||
using Markdown:
|
||||
MD,
|
||||
Header,
|
||||
Code,
|
||||
Paragraph,
|
||||
BlockQuote,
|
||||
Footnote,
|
||||
Table,
|
||||
Admonition,
|
||||
List,
|
||||
HorizontalRule,
|
||||
Bold,
|
||||
Italic,
|
||||
Image,
|
||||
Link,
|
||||
LineBreak,
|
||||
LaTeX,
|
||||
isordered
|
||||
|
||||
|
||||
tohtml(io::IO, m::MIME"text/html", x) = show(io, m, x)
|
||||
|
||||
tohtml(io::IO, m::MIME"text/plain", x) = htmlesc(io, sprint(show, m, x))
|
||||
|
||||
function tohtml(io::IO, m::MIME"image/png", img)
|
||||
print(io, """<img src="data:image/png;base64,""")
|
||||
print(io, stringmime(m, img))
|
||||
print(io, "\" />")
|
||||
end
|
||||
|
||||
tohtml(m::MIME"image/svg+xml", img) = show(io, m, img)
|
||||
|
||||
# AbstractDisplay infrastructure
|
||||
|
||||
function bestmime(val)
|
||||
for mime in ("text/html", "image/svg+xml", "image/png", "text/plain")
|
||||
showable(mime, val) && return MIME(Symbol(mime))
|
||||
end
|
||||
error("Cannot render $val to Markdown.")
|
||||
end
|
||||
|
||||
tohtml(io::IO, x) = tohtml(io, bestmime(x), x)
|
||||
|
||||
# Utils
|
||||
|
||||
function withtag(f, io::IO, tag, attrs...)
|
||||
print(io, "<$tag")
|
||||
for (attr, value) in attrs
|
||||
print(io, " ")
|
||||
htmlesc(io, attr)
|
||||
print(io, "=\"")
|
||||
htmlesc(io, value)
|
||||
print(io, "\"")
|
||||
end
|
||||
f === nothing && return print(io, " />")
|
||||
|
||||
print(io, ">")
|
||||
f()
|
||||
print(io, "</$tag>")
|
||||
end
|
||||
|
||||
tag(io::IO, tag, attrs...) = withtag(nothing, io, tag, attrs...)
|
||||
|
||||
const _htmlescape_chars = Dict(
|
||||
'<' => "<",
|
||||
'>' => ">",
|
||||
'"' => """,
|
||||
'&' => "&",
|
||||
# ' '=>" ",
|
||||
)
|
||||
for ch in "'`!\$%()=+{}[]"
|
||||
_htmlescape_chars[ch] = "&#$(Int(ch));"
|
||||
end
|
||||
|
||||
function htmlesc(io::IO, s::AbstractString)
|
||||
# s1 = replace(s, r"&(?!(\w+|\#\d+);)" => "&")
|
||||
for ch in s
|
||||
print(io, get(_htmlescape_chars, ch, ch))
|
||||
end
|
||||
end
|
||||
function htmlesc(io::IO, s::Symbol)
|
||||
htmlesc(io, string(s))
|
||||
end
|
||||
function htmlesc(io::IO, xs::Union{AbstractString,Symbol}...)
|
||||
for s in xs
|
||||
htmlesc(io, s)
|
||||
end
|
||||
end
|
||||
function htmlesc(s::Union{AbstractString,Symbol})
|
||||
sprint(htmlesc, s)
|
||||
end
|
||||
|
||||
# Block elements
|
||||
|
||||
function html(io::IO, content::Vector)
|
||||
for md in content
|
||||
html(io, md)
|
||||
println(io)
|
||||
end
|
||||
end
|
||||
|
||||
html(io::IO, md::MD) = html(io, md.content)
|
||||
|
||||
function html(io::IO, header::Header{l}) where {l}
|
||||
withtag(io, "h$l") do
|
||||
htmlinline(io, header.text)
|
||||
end
|
||||
end
|
||||
|
||||
function html(io::IO, code::Code)
|
||||
withtag(io, :pre) do
|
||||
maybe_lang = !isempty(code.language) ? Any[:class=>"language-$(code.language)"] : []
|
||||
withtag(io, :code, maybe_lang...) do
|
||||
htmlesc(io, code.code)
|
||||
# TODO should print newline if this is longer than one line ?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function html(io::IO, md::Paragraph)
|
||||
withtag(io, :p) do
|
||||
htmlinline(io, md.content)
|
||||
end
|
||||
end
|
||||
|
||||
function html(io::IO, md::BlockQuote)
|
||||
withtag(io, :blockquote) do
|
||||
println(io)
|
||||
html(io, md.content)
|
||||
end
|
||||
end
|
||||
|
||||
function html(io::IO, f::Footnote)
|
||||
withtag(io, :div, :class => "footnote", :id => "footnote-$(f.id)") do
|
||||
withtag(io, :p, :class => "footnote-title") do
|
||||
print(io, f.id)
|
||||
end
|
||||
html(io, f.text)
|
||||
end
|
||||
end
|
||||
|
||||
function html(io::IO, md::Admonition)
|
||||
withtag(io, :div, :class => "admonition $(md.category)") do
|
||||
withtag(io, :p, :class => "admonition-title") do
|
||||
print(io, md.title)
|
||||
end
|
||||
html(io, md.content)
|
||||
end
|
||||
end
|
||||
|
||||
function html(io::IO, md::List)
|
||||
maybe_attr = md.ordered > 1 ? Any[:start=>string(md.ordered)] : []
|
||||
withtag(io, isordered(md) ? :ol : :ul, maybe_attr...) do
|
||||
for item in md.items
|
||||
println(io)
|
||||
withtag(io, :li) do
|
||||
html(io, item)
|
||||
end
|
||||
end
|
||||
println(io)
|
||||
end
|
||||
end
|
||||
|
||||
html(io::IO, md::HorizontalRule) = tag(io, :hr)
|
||||
|
||||
function html(io::IO, tex::LaTeX)
|
||||
withtag(io, :p, :class => "math") do
|
||||
write(io, string("\\[\n", tex.formula, "\n\\]"))
|
||||
end
|
||||
end
|
||||
|
||||
html(io::IO, comment::Comment) = write(io, "\n<!-- $(comment.text) -->\n")
|
||||
|
||||
function html(io::IO, md::Table)
|
||||
withtag(io, :table) do
|
||||
for (i, row) in enumerate(md.rows)
|
||||
withtag(io, :tr) do
|
||||
for c in md.rows[i]
|
||||
withtag(io, i == 1 ? :th : :td) do
|
||||
htmlinline(io, c)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
html(io::IO, x) = tohtml(io, x)
|
||||
|
||||
# Inline elements
|
||||
|
||||
function htmlinline(io::IO, content::Vector)
|
||||
for x in content
|
||||
htmlinline(io, x)
|
||||
end
|
||||
end
|
||||
|
||||
function htmlinline(io::IO, code::Code)
|
||||
withtag(io, :code) do
|
||||
htmlesc(io, code.code)
|
||||
end
|
||||
end
|
||||
|
||||
function htmlinline(io::IO, tex::LaTeX)
|
||||
withtag(io, :span, :class => "math") do
|
||||
write(io, string("\$", tex.formula, "\$"))
|
||||
end
|
||||
end
|
||||
|
||||
htmlinline(io::IO, md::Union{Symbol,AbstractString}) = htmlesc(io, md)
|
||||
|
||||
function htmlinline(io::IO, md::Bold)
|
||||
withtag(io, :strong) do
|
||||
htmlinline(io, md.text)
|
||||
end
|
||||
end
|
||||
|
||||
function htmlinline(io::IO, md::Italic)
|
||||
withtag(io, :em) do
|
||||
htmlinline(io, md.text)
|
||||
end
|
||||
end
|
||||
|
||||
htmlinline(io::IO, md::Image) = tag(io, :img, :src => md.url, :alt => md.alt)
|
||||
|
||||
function htmlinline(io::IO, f::Footnote)
|
||||
withtag(io, :a, :href => "#footnote-$(f.id)", :class => "footnote") do
|
||||
print(io, "[", f.id, "]")
|
||||
end
|
||||
end
|
||||
|
||||
function htmlinline(io::IO, link::Link)
|
||||
withtag(io, :a, :href => link.url) do
|
||||
htmlinline(io, link.text)
|
||||
end
|
||||
end
|
||||
|
||||
htmlinline(io::IO, br::LineBreak) = tag(io, :br)
|
||||
|
||||
htmlinline(io::IO, comment::Comment) = write(io, "<!-- $(comment.text) -->")
|
||||
|
||||
htmlinline(io::IO, x) = tohtml(io, x)
|
||||
|
||||
# API
|
||||
|
||||
html(md) = sprint(html, md)
|
|
@ -0,0 +1,9 @@
|
|||
import Markdown: latex, latexinline
|
||||
|
||||
function latex(io::IO, comment::Comment)
|
||||
for line in split(comment.text, r"\r\n|\n")
|
||||
write(io, "% $line\n")
|
||||
end
|
||||
end
|
||||
|
||||
latexinline(io, comment::Comment) = write(io, "")
|
|
@ -0,0 +1,92 @@
|
|||
# This module extends the julia markdown parser to improve compatibility with Jupyter, Pandoc etc.
|
||||
module WeaveMarkdown
|
||||
|
||||
using ..Weave: isnothing, take2string!
|
||||
using Markdown
|
||||
import Markdown: @trigger, @breaking, Code, MD, withstream, startswith, LaTeX
|
||||
|
||||
# HACK: that this definition is type-piracy. It is required since `Markdown`
|
||||
# does not have a built in system for contextual rendering by users. `io` here
|
||||
# should always be either `IOBuffer` or `IOContext` since it is reached via
|
||||
# `sprint` in all user-facing code paths in `Markdown`.
|
||||
function Markdown.latex(io::Union{IOBuffer,IOContext}, tex::Markdown.LaTeX)
|
||||
math_envs = ["align", "equation", "eqnarray"]
|
||||
use_dollars =
|
||||
!any([occursin("\\begin{$me", tex.formula) for me in math_envs])
|
||||
use_dollars && write(io, "\\[")
|
||||
write(io, string("\n", tex.formula, "\n"))
|
||||
use_dollars && write(io, "\\]\n")
|
||||
end
|
||||
|
||||
mutable struct Comment
|
||||
text::String
|
||||
end
|
||||
|
||||
@breaking true -> function dollarmath(stream::IO, block::MD)
|
||||
withstream(stream) do
|
||||
str = Markdown.startswith(stream, r"^\$\$$"m)
|
||||
isempty(str) && return false
|
||||
trailing = strip(readline(stream))
|
||||
buffer = IOBuffer()
|
||||
while !eof(stream)
|
||||
line_start = position(stream)
|
||||
estr = Markdown.startswith(stream, r"^\$\$$"m)
|
||||
if !isempty(estr)
|
||||
estr = Markdown.startswith(stream, r"^\$\$$"m)
|
||||
if isempty(estr)
|
||||
push!(block, LaTeX(take2string!(buffer) |> chomp))
|
||||
end
|
||||
return true
|
||||
else
|
||||
seek(stream, line_start)
|
||||
end
|
||||
write(buffer, readline(stream, keep = true))
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
@breaking true -> function topcomment(stream::IO, block::MD)
|
||||
buffer = IOBuffer()
|
||||
withstream(stream) do
|
||||
str = Markdown.startswith(stream, r"^<!--")
|
||||
isempty(str) && return false
|
||||
while !eof(stream)
|
||||
line = readline(stream, keep = true)
|
||||
write(buffer, line)
|
||||
if occursin(r"-->$", line)
|
||||
s = replace(take2string!(buffer) |> chomp, r"-->$" => "")
|
||||
push!(block, Comment(s))
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
@trigger '<' -> function comment(stream::IO, md::MD)
|
||||
withstream(stream) do
|
||||
Markdown.startswith(stream, "<!--") || return
|
||||
text = Markdown.readuntil(stream, "-->")
|
||||
isnothing(text) && return
|
||||
return Comment(text)
|
||||
end
|
||||
end
|
||||
|
||||
# Create own flavor and copy all the features from julia flavor
|
||||
Markdown.@flavor weavemd [dollarmath, comment, topcomment]
|
||||
weavemd.breaking = [weavemd.breaking; Markdown.julia.breaking]
|
||||
weavemd.regular = [weavemd.regular; Markdown.julia.regular]
|
||||
for key in keys(Markdown.julia.inner)
|
||||
if haskey(weavemd.inner, key)
|
||||
weavemd.inner[key] = [weavemd.inner[key]; Markdown.julia.inner[key]]
|
||||
else
|
||||
weavemd.inner[key] = Markdown.julia.inner[key]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
include("html.jl")
|
||||
include("latex.jl")
|
||||
|
||||
end # module
|
|
@ -0,0 +1,64 @@
|
|||
# Serialization is imported only if cache is used
|
||||
|
||||
function write_cache(doc::WeaveDoc, cache_path)
|
||||
cache_dir = joinpath(doc.cwd, cache_path)
|
||||
isdir(cache_dir) || mkpath(cache_dir)
|
||||
open(joinpath(cache_dir, doc.basename * ".cache"), "w") do io
|
||||
Serialization.serialize(io, doc)
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function read_cache(doc::WeaveDoc, cache_path)
|
||||
name = joinpath(doc.cwd, cache_path, doc.basename * ".cache")
|
||||
isfile(name) || return nothing
|
||||
open(name, "r") do io
|
||||
doc = Serialization.deserialize(io)
|
||||
end
|
||||
return doc
|
||||
end
|
||||
|
||||
function restore_chunk(chunk::CodeChunk, cached)
|
||||
chunks = filter(
|
||||
x -> x.number == chunk.number && string(typeof(x)) == "Weave.CodeChunk",
|
||||
cached.chunks,
|
||||
)
|
||||
|
||||
# Chunk types, don't match after loading. Fix by constructing chunks
|
||||
# from loaded content
|
||||
new_chunks = []
|
||||
for c in chunks
|
||||
newc = CodeChunk(c.content, c.number, c.start_line, c.optionstring, c.options)
|
||||
newc.figures = c.figures
|
||||
newc.result = c.result
|
||||
newc.output = c.output
|
||||
newc.rich_output = c.rich_output
|
||||
push!(new_chunks, newc)
|
||||
end
|
||||
return new_chunks
|
||||
end
|
||||
|
||||
# Restore inline code
|
||||
function restore_chunk(chunk::DocChunk, cached::WeaveDoc)
|
||||
# Get chunk from cached doc
|
||||
c_chunk = filter(x -> x.number == chunk.number && isa(x, DocChunk), cached.chunks)
|
||||
isempty(c_chunk) && return chunk
|
||||
c_chunk = c_chunk[1]
|
||||
|
||||
# Collect cached code
|
||||
c_inline = filter(x -> isa(x, InlineCode), c_chunk.content)
|
||||
isempty(c_inline) && return chunk
|
||||
|
||||
# Restore cached results for Inline code
|
||||
n = length(chunk.content)
|
||||
for i = 1:n
|
||||
if isa(chunk.content[i], InlineCode)
|
||||
ci = filter(x -> x.number == chunk.content[i].number, c_inline)
|
||||
isempty(ci) && continue
|
||||
chunk.content[i].output = ci[1].output
|
||||
chunk.content[i].rich_output = ci[1].rich_output
|
||||
chunk.content[i].figures = ci[1].figures
|
||||
end
|
||||
end
|
||||
return chunk
|
||||
end
|
135
src/config.jl
135
src/config.jl
|
@ -1,77 +1,58 @@
|
|||
const rcParams =
|
||||
@compat Dict{Symbol,Any}(:plotlib => "PyPlot",
|
||||
:storeresults => false,
|
||||
:chunk_defaults =>
|
||||
Dict{Symbol,Any}(
|
||||
:echo=> true,
|
||||
:results=> "markup",
|
||||
:fig=> true,
|
||||
:include=> true,
|
||||
:eval => true,
|
||||
:fig_cap=> nothing,
|
||||
#Size in inches
|
||||
:fig_width => 6,
|
||||
:fig_height => 4,
|
||||
:fig_path=> "figures",
|
||||
:dpi => 96,
|
||||
:term=> false,
|
||||
:name=> nothing,
|
||||
:wrap=> true,
|
||||
:engine=> "julia",
|
||||
:option_string=> "",
|
||||
#Defined in formats
|
||||
:fig_ext => nothing,
|
||||
:fig_pos=> nothing,
|
||||
:fig_env=> nothing,
|
||||
:out_width=> nothing,
|
||||
:out_height=> nothing,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Working towards Knitr compatible options, implemented options are
|
||||
# added to defaultoptions dictionary above and work in progress stays here,
|
||||
# options from https://github.com/yihui/knitr/blob/master/R/defaults.R
|
||||
# If you need a particular options, consider implementing it and making a
|
||||
# pull request.
|
||||
|
||||
#tidy = FALSE,
|
||||
#tidy.opts = NULL,
|
||||
#collapse = FALSE
|
||||
#prompt = FALSE
|
||||
#highlight = TRUE
|
||||
#strip.white = TRUE
|
||||
#size = 'normalsize'
|
||||
#background = '#F7F7F7',
|
||||
#cache = FALSE
|
||||
#cache.path = 'cache/'
|
||||
#cache.vars = NULL
|
||||
#cache.lazy = TRUE,
|
||||
#dependson = NULL
|
||||
#autodep = FALSE,
|
||||
#fig.keep = 'high'
|
||||
#fig.show = 'asis'
|
||||
#fig.align = 'default'
|
||||
#dev = NULL
|
||||
#dev.args = NULL
|
||||
#fig.ext = NULL
|
||||
#fig.scap = NULL
|
||||
#fig.lp = 'fig:'
|
||||
#fig.subcap = NULL,
|
||||
#out.extra = NULL
|
||||
#fig.retina = 1,
|
||||
#external = TRUE
|
||||
#sanitize = FALSE
|
||||
#interval = 1
|
||||
#aniopts = 'controls,loop',
|
||||
#warning = TRUE
|
||||
#error = TRUE
|
||||
#message = TRUE,
|
||||
#render = NULL,
|
||||
#ref.label = NULL
|
||||
#child = NULL
|
||||
#split = FALSE
|
||||
#purl = TRUE
|
||||
# TODO: follow RMarkdown convention more
|
||||
const _DEFAULT_PARAMS = Dict{Symbol,Any}(
|
||||
:echo => true,
|
||||
:results => "markup",
|
||||
:hold => false,
|
||||
:fig => true,
|
||||
:eval => true,
|
||||
:error => true,
|
||||
:tangle => true,
|
||||
:cache => false,
|
||||
:fig_cap => nothing,
|
||||
# NOTE: size in inches
|
||||
:fig_width => 6,
|
||||
:fig_height => 4,
|
||||
:fig_path => DEFAULT_FIG_PATH,
|
||||
:dpi => 96,
|
||||
:term => false,
|
||||
:prompt => "julia>",
|
||||
:label => nothing,
|
||||
:wrap => true,
|
||||
:line_width => 75,
|
||||
:fig_ext => nothing,
|
||||
:fig_pos => nothing,
|
||||
:fig_env => nothing,
|
||||
:out_width => nothing,
|
||||
:out_height => nothing,
|
||||
)
|
||||
const DEFAULT_PARAMS = deepcopy(_DEFAULT_PARAMS) # might be changed at runtime
|
||||
|
||||
"""
|
||||
set_chunk_defaults!(k, v)
|
||||
set_chunk_defaults!(kv::Pair...)
|
||||
set_chunk_defaults!(opts::AbstractDict)
|
||||
|
||||
Set default options for code chunks, use [`get_chunk_defaults`](@ref) to see the current values.
|
||||
|
||||
E.g.: all the three examples below will set default `dpi` to `200` and `fig_width` to `8`:
|
||||
- `set_chunk_defaults!(:dpi, 200); set_chunk_defaults!(:fig_width, 8)`
|
||||
- `set_chunk_defaults!(:dpi => 200, :fig_width => 8)`
|
||||
- `set_chunk_defaults!(Dict(:dpi => 200, :fig_width => 8))`
|
||||
"""
|
||||
set_chunk_defaults!(k, v) = DEFAULT_PARAMS[k]= v
|
||||
set_chunk_defaults!(kv::Pair...) = for (k,v) in kv; set_chunk_defaults!(k, v); end
|
||||
set_chunk_defaults!(opts::AbstractDict) = merge!(DEFAULT_PARAMS, opts)
|
||||
|
||||
"""
|
||||
get_chunk_defaults()
|
||||
|
||||
Get default options used for code chunks.
|
||||
"""
|
||||
get_chunk_defaults() = DEFAULT_PARAMS
|
||||
|
||||
"""
|
||||
restore_chunk_defaults!()
|
||||
|
||||
Restore Weave.jl default chunk options.
|
||||
"""
|
||||
restore_chunk_defaults!() = for (k,v) in _DEFAULT_PARAMS; DEFAULT_PARAMS[k] = v; end
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
using JSON, Mustache
|
||||
|
||||
"""
|
||||
convert_doc(infile::AbstractString, outfile::AbstractString; outformat::Union{Nothing,AbstractString} = nothing)
|
||||
|
||||
Convert Weave documents between different formats
|
||||
|
||||
- `infile`: Path of the input document
|
||||
- `outfile`: Path of the output document
|
||||
- `outformat = nothing`: Output document format (optional). By default (i.e. given `nothing`) Weave will try to automatically detect it from the `outfile`'s extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
|
||||
"""
|
||||
function convert_doc(
|
||||
infile::AbstractString,
|
||||
outfile::AbstractString;
|
||||
outformat::Union{Nothing,AbstractString} = nothing,
|
||||
)
|
||||
doc = WeaveDoc(infile)
|
||||
|
||||
if isnothing(outformat)
|
||||
ext = lowercase(splitext(outfile)[2])
|
||||
outformat =
|
||||
ext == ".jl" ? "script" :
|
||||
ext == ".jmd" ? "markdown" :
|
||||
ext == ".ipynb" ? "notebook" :
|
||||
"noweb" # fallback
|
||||
end
|
||||
|
||||
converted = _convert_doc(doc, outformat)
|
||||
|
||||
open(outfile, "w") do f
|
||||
write(f, converted)
|
||||
end
|
||||
return outfile
|
||||
end
|
||||
|
||||
function _convert_doc(doc, outformat)
|
||||
outformat == "script" ? convert_to_script(doc) :
|
||||
outformat == "markdown" ? convert_to_markdown(doc) :
|
||||
outformat == "notebook" ? convert_to_notebook(doc) :
|
||||
convert_to_noweb(doc)
|
||||
end
|
||||
|
||||
function convert_to_script(doc)
|
||||
output = ""
|
||||
for chunk in doc.chunks
|
||||
if typeof(chunk) == Weave.DocChunk
|
||||
content = join([repr(c) for c in chunk.content], "")
|
||||
output *= join(["#' " * s for s in split(content, "\n")], "\n")
|
||||
else
|
||||
output *= "\n#+ "
|
||||
isempty(chunk.optionstring) || (output *= strip(chunk.optionstring))
|
||||
output *= "\n\n" * lstrip(chunk.content)
|
||||
output *= "\n"
|
||||
end
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
function convert_to_markdown(doc)
|
||||
output = ""
|
||||
for chunk in doc.chunks
|
||||
if isa(chunk, DocChunk)
|
||||
output *= join([repr(c) for c in chunk.content], "")
|
||||
else
|
||||
output *= "\n" * "```julia"
|
||||
isempty(chunk.optionstring) || (output *= ";" * chunk.optionstring)
|
||||
output *= "\n" * lstrip(chunk.content)
|
||||
output *= "```\n"
|
||||
end
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
function convert_to_notebook(doc)
|
||||
nb = Dict()
|
||||
nb["nbformat"] = 4
|
||||
nb["nbformat_minor"] = 2
|
||||
metadata = Dict()
|
||||
kernelspec = Dict()
|
||||
kernelspec["language"] = "julia"
|
||||
kernelspec["name"] = "julia-$(VERSION.major).$(VERSION.minor)"
|
||||
kernelspec["display_name"] = "Julia $(VERSION.major).$(VERSION.minor).$(VERSION.patch)"
|
||||
metadata["kernelspec"] = kernelspec
|
||||
language_info = Dict()
|
||||
language_info["file_extension"] = ".jl"
|
||||
language_info["mimetype"] = "application/julia"
|
||||
language_info["name"] = "julia"
|
||||
language_info["version"] = "$(VERSION.major).$(VERSION.minor).$(VERSION.patch)"
|
||||
metadata["language_info"] = language_info
|
||||
cells = []
|
||||
ex_count = 1
|
||||
|
||||
for chunk in doc.chunks
|
||||
if isa(chunk, DocChunk)
|
||||
push!(
|
||||
cells,
|
||||
Dict(
|
||||
"cell_type" => "markdown",
|
||||
"metadata" => Dict(),
|
||||
"source" => [strip(join([repr(c) for c in chunk.content], ""))],
|
||||
),
|
||||
)
|
||||
else
|
||||
push!(
|
||||
cells,
|
||||
Dict(
|
||||
"cell_type" => "code",
|
||||
"metadata" => Dict(),
|
||||
"source" => [strip(chunk.content)],
|
||||
"execution_count" => nothing,
|
||||
"outputs" => [],
|
||||
),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
nb["cells"] = cells
|
||||
nb["metadata"] = metadata
|
||||
|
||||
json_nb = JSON.json(nb, 2)
|
||||
return json_nb
|
||||
end
|
||||
|
||||
function convert_to_noweb(doc)
|
||||
output = ""
|
||||
for chunk in doc.chunks
|
||||
if isa(chunk, DocChunk)
|
||||
output *= join([repr(c) for c in chunk.content], "")
|
||||
else
|
||||
output *= "\n" * "<<"
|
||||
isempty(chunk.optionstring) || (output *= strip(chunk.optionstring))
|
||||
output *= ">>="
|
||||
output *= "\n" * lstrip(chunk.content)
|
||||
output *= "@\n"
|
||||
end
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
Base.repr(c::InlineText) = c.content
|
||||
Base.repr(c::InlineCode) = "`j $(c.content)`"
|
|
@ -0,0 +1,133 @@
|
|||
using Markdown, .WeaveMarkdown
|
||||
|
||||
# Contains report global properties
|
||||
mutable struct Report <: AbstractDisplay
|
||||
cwd::String
|
||||
basename::String
|
||||
format::WeaveFormat
|
||||
rich_output::String
|
||||
fignum::Int
|
||||
figures::Vector{String}
|
||||
cur_chunk::Union{Nothing,CodeChunk}
|
||||
mimetypes::Vector{String}
|
||||
first_plot::Bool
|
||||
header_script::String
|
||||
end
|
||||
|
||||
Report(cwd, basename, format, mimetypes) =
|
||||
Report(cwd, basename, format, "", 1, String[], nothing, mimetypes, true, "")
|
||||
|
||||
# Default mimetypes in order, can be overridden for some inside `run method` formats
|
||||
const default_mime_types = ["image/svg+xml", "image/png", "text/html", "text/plain"]
|
||||
# const default_mime_types = ["image/png", "image/svg+xml", "text/html", "text/plain"]
|
||||
# From IJulia as a reminder
|
||||
# const supported_mime_types = [ "text/html", "text/latex", "image/svg+xml", "image/png", "image/jpeg", "text/plain", "text/markdown" ]
|
||||
|
||||
const mimetype_ext = Dict(
|
||||
".png" => "image/png",
|
||||
".jpg" => "image/jpeg",
|
||||
".jpeg" => "image/jpeg",
|
||||
".svg" => "image/svg+xml",
|
||||
".js.svg" => "image/svg+xml",
|
||||
".pdf" => "application/pdf",
|
||||
".ps" => "application/postscript",
|
||||
".tex" => "text/latex",
|
||||
)
|
||||
|
||||
function Base.display(report::Report, data)
|
||||
# Set preferred mimetypes for report based on format
|
||||
fig_ext = report.cur_chunk.options[:fig_ext]
|
||||
for m in unique([mimetype_ext[fig_ext]; report.mimetypes])
|
||||
if Base.invokelatest(showable, m, data)
|
||||
try
|
||||
if !istextmime(m)
|
||||
Base.invokelatest(display, report, m, data)
|
||||
elseif report.cur_chunk.options[:term]
|
||||
Base.invokelatest(display, report, "text/plain", data)
|
||||
else
|
||||
Base.invokelatest(display, report, m, data)
|
||||
end
|
||||
catch e
|
||||
throw(e)
|
||||
@warn("Failed to display data in \"$m\" format")
|
||||
continue
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Base.display(report::Report, m::MIME"image/png", data) = add_figure(report, data, m, ".png")
|
||||
|
||||
Base.display(report::Report, m::MIME"image/svg+xml", data) = add_figure(report, data, m, ".svg")
|
||||
|
||||
Base.display(report::Report, m::MIME"application/pdf", data) = add_figure(report, data, m, ".pdf")
|
||||
|
||||
# Text is written to stdout, called from "term" mode chunks
|
||||
function Base.display(report::Report, m::MIME"text/plain", data)
|
||||
io = PipeBuffer()
|
||||
show(IOContext(io, :limit => true), m, data)
|
||||
flush(io)
|
||||
s = read(io, String)
|
||||
close(io)
|
||||
println(s)
|
||||
end
|
||||
|
||||
function Base.display(report::Report, m::MIME"text/plain", data::Exception)
|
||||
println("Error: " * sprint(showerror, data))
|
||||
end
|
||||
|
||||
function Base.display(report::Report, m::MIME"text/html", data::Exception)
|
||||
report.rich_output = sprint(show, m, data)
|
||||
end
|
||||
|
||||
function Base.show(io, m::MIME"text/html", data::Exception)
|
||||
println(io, "<pre class=\"julia-error\">")
|
||||
println(io, Markdown.htmlesc("ERROR: " * sprint(showerror, data)))
|
||||
println(io, "</pre>")
|
||||
end
|
||||
|
||||
# Catch "rich_output"
|
||||
function Base.display(report::Report, m::MIME"text/html", data)
|
||||
io = IOBuffer()
|
||||
show(IOContext(io, :limit => true), m, data)
|
||||
report.rich_output *= string('\n', take2string!(io))
|
||||
end
|
||||
|
||||
# Catch "rich_output"
|
||||
function Base.display(report::Report, m::MIME"text/markdown", data)
|
||||
s = repr(m, data)
|
||||
# Convert to "richer" type of possible
|
||||
for m in report.mimetypes
|
||||
if m == "text/html" || m == "text/latex"
|
||||
display(Markdown.parse(s, flavor = WeaveMarkdown.weavemd))
|
||||
break
|
||||
elseif m == "text/markdown"
|
||||
report.rich_output *= "\n" * s
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Base.display(report::Report, m::MIME"text/latex", data)
|
||||
s = repr(m, data)
|
||||
report.rich_output *= string('\n', s)
|
||||
end
|
||||
|
||||
"""Add saved figure name to results and return the name"""
|
||||
function add_figure(report::Report, data, m, ext)
|
||||
chunk = report.cur_chunk
|
||||
full_name, rel_name = get_figname(report, chunk, ext = ext)
|
||||
|
||||
open(full_name, "w") do io
|
||||
if ext == ".pdf"
|
||||
write(io, repr(m, data))
|
||||
else
|
||||
show(io, m, data)
|
||||
end
|
||||
end
|
||||
|
||||
push!(report.figures, rel_name)
|
||||
report.fignum += 1
|
||||
return full_name
|
||||
end
|
|
@ -1,293 +0,0 @@
|
|||
using TextWrap
|
||||
|
||||
#Format the executed document
|
||||
function format(executed, doctype)
|
||||
formatted = String[]
|
||||
docformat = formats[doctype]
|
||||
#@show docformat
|
||||
|
||||
#Complete format dictionaries with defaults
|
||||
formatdict = docformat.formatdict
|
||||
get!(formatdict, :termstart, formatdict[:codestart])
|
||||
get!(formatdict, :termend, formatdict[:codeend])
|
||||
get!(formatdict, :out_width, nothing)
|
||||
get!(formatdict, :out_height, nothing)
|
||||
get!(formatdict, :fig_pos, nothing)
|
||||
get!(formatdict, :fig_env, nothing)
|
||||
|
||||
|
||||
for chunk in copy(executed)
|
||||
|
||||
if chunk[:type] == "doc"
|
||||
push!(formatted, chunk[:content])
|
||||
else
|
||||
#Fill undefined options with format specific defaults
|
||||
chunk[:out_width] == nothing && (chunk[:out_width] = docformat.formatdict[:out_width])
|
||||
chunk[:fig_pos] == nothing && (chunk[:fig_pos] = docformat.formatdict[:fig_pos])
|
||||
|
||||
#Only use floats if chunk has caption or sets fig_env
|
||||
if chunk[:fig_cap] != nothing && chunk[:fig_env] == nothing
|
||||
(chunk[:fig_env] = docformat.formatdict[:fig_env])
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
#Format code
|
||||
result = format_codechunk(chunk, formatdict)
|
||||
#Handle figures
|
||||
if chunk[:fig] && length(chunk[:figure]) > 0
|
||||
if chunk[:include]
|
||||
result *= formatfigures(chunk, docformat)
|
||||
end
|
||||
end
|
||||
push!(formatted, result)
|
||||
end
|
||||
end
|
||||
|
||||
return formatted
|
||||
end
|
||||
|
||||
|
||||
function format_codechunk(chunk, formatdict)
|
||||
if haskey(formatdict, :indent)
|
||||
chunk[:content] = indent(chunk[:content], formatdict[:indent])
|
||||
end
|
||||
|
||||
if !chunk[:eval]
|
||||
if chunk[:echo]
|
||||
result = "$(formatdict[:codestart])$(chunk[:content])\n$(formatdict[:codeend])"
|
||||
return result
|
||||
else
|
||||
r = ""
|
||||
return r
|
||||
end
|
||||
end
|
||||
|
||||
if chunk[:term]
|
||||
result = format_termchunk(chunk, formatdict)
|
||||
else
|
||||
if chunk[:wrap]
|
||||
chunk[:result] = "\n" * wrap(chunk[:result], replace_whitespace=false)
|
||||
end
|
||||
|
||||
if chunk[:echo]
|
||||
result = "$(formatdict[:codestart])$(chunk[:content])\n$(formatdict[:codeend])\n"
|
||||
else
|
||||
result = ""
|
||||
end
|
||||
|
||||
if (strip(chunk[:result])!= "") && (chunk[:results] != "hidden")
|
||||
#@show chunk
|
||||
if chunk[:results] != "markup"
|
||||
result *= "$(chunk[:result])"
|
||||
elseif chunk[:results] == "markup"
|
||||
if haskey(formatdict, :indent)
|
||||
chunk[:result] = indent(chunk[:result], formatdict[:indent])
|
||||
end
|
||||
result *= "$(formatdict[:outputstart])$(chunk[:result])\n$(formatdict[:outputend])\n"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return result
|
||||
|
||||
end
|
||||
|
||||
function format_termchunk(chunk, formatdict)
|
||||
if chunk[:echo] && chunk[:results] != "hidden"
|
||||
result = "$(formatdict[:termstart])$(chunk[:result])\n"
|
||||
#@show chunk[:term_state]
|
||||
chunk[:term_state] == :text && (result*= "$(formatdict[:termend])\n")
|
||||
else
|
||||
result = ""
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function indent(text, nindent)
|
||||
return join(map(x->
|
||||
string(repeat(" ", nindent), x), split(text, "\n")), "\n")
|
||||
end
|
||||
|
||||
|
||||
type Tex
|
||||
description::String
|
||||
formatdict::Dict{Symbol,Any}
|
||||
end
|
||||
|
||||
const tex = Tex("Latex with custom code environments",
|
||||
@compat Dict{Symbol,Any}(:codestart => "\\begin{juliacode}",
|
||||
:codeend => "\\end{juliacode}",
|
||||
:outputstart => "\\begin{juliaout}",
|
||||
:outputend => "\\end{juliaout}",
|
||||
:termstart => "\\begin{juliaterm}",
|
||||
:termend => "\\end{juliaterm}",
|
||||
:fig_ext => ".pdf",
|
||||
:extension =>"tex",
|
||||
:out_width=> "\\linewidth",
|
||||
:fig_env=> "figure",
|
||||
:fig_pos => "htpb",
|
||||
:doctype => "tex"
|
||||
))
|
||||
|
||||
const texminted = Tex("Latex using minted for highlighting",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => "\\begin{minted}[mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}",
|
||||
:codeend => "\\end{minted}",
|
||||
:outputstart => "\\begin{minted}[fontsize=\\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}",
|
||||
:outputend => "\\end{minted}",
|
||||
:termstart=> "\\begin{minted}[fontsize=\\footnotesize, xleftmargin=0.5em, mathescape]{julia}",
|
||||
:termend => "\\end{minted}",
|
||||
:fig_ext => ".pdf",
|
||||
:extension =>"tex",
|
||||
:out_width => "\\linewidth",
|
||||
:fig_env=> "figure",
|
||||
:fig_pos => "htpb",
|
||||
:doctype => "texminted"
|
||||
))
|
||||
|
||||
type Markdown
|
||||
description::String
|
||||
formatdict::Dict{Symbol,Any}
|
||||
end
|
||||
|
||||
const pandoc = Markdown("Pandoc markdown",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => "~~~~{.julia}",
|
||||
:codeend=>"~~~~~~~~~~~~~\n\n",
|
||||
:outputstart=>"~~~~{.julia}",
|
||||
:outputend=>"~~~~~~~~~~~~~\n\n",
|
||||
:fig_ext=>".png",
|
||||
:extension=>"md",
|
||||
:doctype=>"pandoc"
|
||||
))
|
||||
|
||||
|
||||
const github = Markdown("Github markdown",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => "````julia",
|
||||
:codeend=> "````\n\n",
|
||||
:outputstart=> "````julia",
|
||||
:outputend=> "````\n\n",
|
||||
:fig_ext=> ".png",
|
||||
:extension=> "md",
|
||||
:doctype=> "github"
|
||||
))
|
||||
|
||||
|
||||
type Rest
|
||||
description::String
|
||||
formatdict::Dict{Symbol,Any}
|
||||
end
|
||||
|
||||
const rst = Rest("reStructuredText and Sphinx",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => ".. code-block:: julia\n",
|
||||
:codeend => "\n\n",
|
||||
:outputstart => "::\n",
|
||||
:outputend => "\n\n",
|
||||
:indent=> 4,
|
||||
:fig_ext => ".png",
|
||||
:extension => "rst",
|
||||
:out_width => "15 cm",
|
||||
:doctype => "rst"
|
||||
))
|
||||
|
||||
|
||||
|
||||
function formatfigures(chunk, docformat::Tex)
|
||||
fignames = chunk[:figure]
|
||||
caption = chunk[:fig_cap]
|
||||
width = chunk[:out_width]
|
||||
f_pos = chunk[:fig_pos]
|
||||
f_env = chunk[:fig_env]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
|
||||
|
||||
if f_env != nothing
|
||||
result *= """\\begin{$f_env}[$f_pos]\n"""
|
||||
end
|
||||
|
||||
|
||||
for fig = fignames
|
||||
figstring *= "\\includegraphics[width=$width]{$fig}\n"
|
||||
end
|
||||
|
||||
# Figure environment
|
||||
if caption != nothing
|
||||
result *= string("\\center\n",
|
||||
"$figstring",
|
||||
"\\caption{$caption}\n")
|
||||
else
|
||||
result *= figstring
|
||||
end
|
||||
|
||||
if chunk[:name] != nothing && f_env !=nothing
|
||||
label = chunk[:name]
|
||||
result *= "\\label{fig:$label}\n"
|
||||
end
|
||||
|
||||
|
||||
if f_env != nothing
|
||||
result *= "\\end{$f_env}\n"
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function formatfigures(chunk, docformat::Markdown)
|
||||
fignames = chunk[:figure]
|
||||
caption = chunk[:fig_cap]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
length(fignames) > 0 || (return "")
|
||||
|
||||
if caption != nothing
|
||||
result *= "![$caption]($(fignames[1]))\n"
|
||||
for fig = fignames[2:end]
|
||||
result *= "![]($fig)\n"
|
||||
println("Warning, only the first figure gets a caption\n")
|
||||
end
|
||||
else
|
||||
for fig in fignames
|
||||
result *= "![]($fig)\n"
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
function formatfigures(chunk, docformat::Rest)
|
||||
fignames = chunk[:figure]
|
||||
caption = chunk[:fig_cap]
|
||||
width = chunk[:out_width]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
for fig=fignames
|
||||
figstring *= @sprintf(".. image:: %s\n :width: %s\n\n", fig, width)
|
||||
end
|
||||
|
||||
if caption != nothing
|
||||
result *= string(".. figure:: $(fignames[1])\n",
|
||||
" :width: $width\n\n",
|
||||
" $caption\n\n")
|
||||
else
|
||||
result *= figstring
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#Add new supported formats here
|
||||
const formats = @compat Dict{String, Any}("tex" => tex,
|
||||
"texminted" => texminted,
|
||||
"pandoc" => pandoc,
|
||||
"github" => github,
|
||||
"rst" => rst
|
||||
)
|
|
@ -1,56 +1,51 @@
|
|||
using Gadfly
|
||||
module GadflyPlots
|
||||
|
||||
Gadfly.set_default_plot_format(:png)
|
||||
using ..Weave, ..Gadfly
|
||||
|
||||
#Captures figures
|
||||
function Base.display(report::Report, m::MIME"image/png", p::Plot)
|
||||
|
||||
Gadfly.set_default_plot_format(:svg)
|
||||
|
||||
Base.showable(m::MIME"application/pdf", p::Gadfly.Plot) = true
|
||||
Base.showable(m::MIME"application/png", p::Gadfly.Plot) = true
|
||||
|
||||
function Base.display(report::Weave.Report, m::MIME"application/pdf", p::Gadfly.Plot)
|
||||
display(report, MIME("image/svg+xml"), p)
|
||||
end
|
||||
|
||||
function Base.display(report::Weave.Report, m::MIME"image/png", p::Gadfly.Plot)
|
||||
display(report, MIME("image/svg+xml"), p)
|
||||
end
|
||||
|
||||
# Gadfly doesn't call the default display methods, this catches
|
||||
# all Gadfly plots
|
||||
function Base.display(report::Weave.Report, m::MIME"image/svg+xml", p::Gadfly.Plot)
|
||||
chunk = report.cur_chunk
|
||||
|
||||
#if chunk[:fig_ext] != ".png"
|
||||
# chunk[:fig_ext]
|
||||
# warn("Saving figures as .png with Gadfly")
|
||||
#end
|
||||
w = chunk.options[:fig_width] * Gadfly.inch
|
||||
h = chunk.options[:fig_height] * Gadfly.inch
|
||||
format = chunk.options[:fig_ext]
|
||||
dpi = chunk.options[:dpi]
|
||||
|
||||
full_name, rel_name = get_figname(report, chunk)
|
||||
|
||||
docformat = formats[report.formatdict[:doctype]]
|
||||
|
||||
#Add to results for term chunks and store otherwise
|
||||
if chunk[:term]
|
||||
chunk[:figure] = [rel_name]
|
||||
|
||||
if report.term_state == :text
|
||||
report.cur_result *= "\n" * report.formatdict[:codeend] * "\n"
|
||||
end
|
||||
|
||||
|
||||
report.cur_result *= formatfigures(chunk, docformat)
|
||||
report.term_state = :fig
|
||||
chunk[:figure] = String[]
|
||||
else
|
||||
push!(report.figures, rel_name)
|
||||
end
|
||||
full_name, rel_name = Weave.get_figname(report, chunk, ext = format)
|
||||
|
||||
push!(report.figures, rel_name)
|
||||
report.fignum += 1
|
||||
|
||||
#TODO other formats
|
||||
#Can't specify dpi in Gadfly? Opened Gadfly issue #504
|
||||
w = chunk[:fig_width]inch
|
||||
h = chunk[:fig_height]inch
|
||||
format = chunk[:fig_ext]
|
||||
|
||||
#This is probably not the correct way to handle different formats, but it works.
|
||||
if format == ".png"
|
||||
draw(PNG(full_name, w, h), p)
|
||||
elseif format == ".pdf"
|
||||
draw(PDF(full_name, w, h), p)
|
||||
elseif format == ".ps"
|
||||
draw(PS(full_name, w, h), p)
|
||||
elseif format == ".svg"
|
||||
draw(SVG(full_name, w, h), p)
|
||||
if format == ".svg"
|
||||
Gadfly.draw(Gadfly.SVG(full_name, w, h), p)
|
||||
elseif format == ".js.svg"
|
||||
draw(SVGJS(full_name, w, h), p)
|
||||
else:
|
||||
warn("Can't save figure. Unsupported format")
|
||||
Gadfly.draw(Gadfly.SVGJS(full_name, w, h), p)
|
||||
elseif format == ".png"
|
||||
Gadfly.draw(Gadfly.PNG(full_name, w, h, dpi = dpi), p)
|
||||
elseif format == ".pdf"
|
||||
Gadfly.draw(Gadfly.PDF(full_name, w, h), p)
|
||||
elseif format == ".ps"
|
||||
Gadfly.draw(Gadfly.PS(full_name, w, h), p)
|
||||
elseif format == ".tex"
|
||||
Gadfly.draw(Gadfly.PGF(full_name, w, h, true), p)
|
||||
else
|
||||
@warn("Can't save figure. Unsupported format, $format")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
module WeavePlots
|
||||
|
||||
using ..Base64, ..Plots, ..Weave
|
||||
|
||||
|
||||
# Pre-execute hooks to set the plot size for the chunk
|
||||
function plots_set_size!(chunk)
|
||||
w = chunk.options[:fig_width] * chunk.options[:dpi]
|
||||
h = chunk.options[:fig_height] * chunk.options[:dpi]
|
||||
Plots.default(size = (w, h))
|
||||
end
|
||||
|
||||
Weave.push_preexecution_hook!(plots_set_size!)
|
||||
|
||||
# PNG or SVG is not working, output html
|
||||
function Base.display(
|
||||
report::Weave.Report,
|
||||
m::MIME"image/svg+xml",
|
||||
data::Plots.Plot{Plots.PlotlyBackend},
|
||||
)
|
||||
# Remove extra spaces from start of line for pandoc
|
||||
s = repr(MIME("text/html"), data)
|
||||
splitted = split(s, "\n")
|
||||
start = split(splitted[1], r"(?=<div)")
|
||||
# script = lstrip(start[1]) # local
|
||||
|
||||
div = lstrip(start[2])
|
||||
plot = join(map(lstrip, splitted[2:end]), "\n")
|
||||
|
||||
if report.first_plot
|
||||
report.header_script *= "<script src=\"https://cdn.plot.ly/plotly-latest.min.js\"></script>"
|
||||
report.first_plot = false
|
||||
end
|
||||
|
||||
report.rich_output *= "\n" * div * "\n" * plot
|
||||
end
|
||||
|
||||
function Base.display(
|
||||
report::Weave.Report,
|
||||
m::MIME"image/png",
|
||||
data::Plots.Plot{Plots.PlotlyBackend},
|
||||
)
|
||||
display(report, MIME("image/svg+xml"), data)
|
||||
end
|
||||
|
||||
# PNG or SVG is not working, output html
|
||||
function Base.display(
|
||||
report::Weave.Report,
|
||||
m::MIME"image/svg+xml",
|
||||
plot::Plots.Plot{Plots.PlotlyJSBackend},
|
||||
)
|
||||
body = Plots.PlotlyJS.html_body(plot.o.plot)
|
||||
|
||||
if report.first_plot
|
||||
report.header_script *= "<script src=\"https://cdn.plot.ly/plotly-latest.min.js\"></script>"
|
||||
report.first_plot = false
|
||||
end
|
||||
|
||||
report.rich_output *= "\n" * body
|
||||
end
|
||||
|
||||
function Base.display(
|
||||
report::Weave.Report,
|
||||
m::MIME"image/png",
|
||||
plot::Plots.Plot{Plots.PlotlyJSBackend},
|
||||
)
|
||||
display(report, MIME("image/svg+xml"), data)
|
||||
end
|
||||
|
||||
"""Add saved figure name to results and return the name"""
|
||||
function add_plots_figure(report::Weave.Report, plot::Plots.Plot, ext)
|
||||
chunk = report.cur_chunk
|
||||
full_name, rel_name = Weave.get_figname(report, chunk, ext = ext)
|
||||
|
||||
Plots.savefig(plot, full_name)
|
||||
push!(report.figures, rel_name)
|
||||
report.fignum += 1
|
||||
return full_name
|
||||
end
|
||||
|
||||
function Base.display(report::Weave.Report, m::MIME"application/pdf", plot::Plots.Plot)
|
||||
add_plots_figure(report, plot, ".pdf")
|
||||
end
|
||||
|
||||
function Base.display(report::Weave.Report, m::MIME"image/png", plot::Plots.Plot)
|
||||
add_plots_figure(report, plot, ".png")
|
||||
end
|
||||
|
||||
function Base.display(report::Weave.Report, m::MIME"image/svg+xml", plot::Plots.Plot)
|
||||
add_plots_figure(report, plot, ".svg")
|
||||
end
|
||||
|
||||
# write out html to view Animated gif
|
||||
function Base.display(report::Weave.Report, ::MIME"text/html", agif::Plots.AnimatedGif)
|
||||
ext = agif.filename[end-2:end]
|
||||
res = ""
|
||||
if ext == "gif"
|
||||
img = stringmime(MIME("image/gif"), read(agif.filename))
|
||||
res = "<img src=\"data:image/gif;base64,$img\" />"
|
||||
elseif ext in ("mov", "mp4")
|
||||
# Uncomment to embed mp4, make global or chunk option?
|
||||
# img = stringmime(MIME("video/$ext"), read(agif.filename))
|
||||
# res = "<video controls><source src=\"data:video/$(ext);base64,$img\" type=\"video/$ext\"></video>"
|
||||
res = "<video controls><source src=\"$(relpath(agif.filename))\" type=\"video/$ext\"></video>"
|
||||
else
|
||||
error("Cannot show animation with extension $ext: $agif")
|
||||
end
|
||||
|
||||
report.rich_output *= "\n" * res * "\n"
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,95 @@
|
|||
function parse_markdown(document_body; is_pandoc = false)
|
||||
header_text, document_body, offset = separate_header_text(document_body)
|
||||
header = parse_header(header_text)
|
||||
code_start, code_end = if is_pandoc
|
||||
r"^<<(?<options>.*?)>>=\s*$",
|
||||
r"^@\s*$"
|
||||
else
|
||||
r"^[`~]{3}(\{?)julia\s*([;,\{]?)\s*(?<options>.*?)(\}|\s*)$",
|
||||
r"^[`~]{3}\s*$"
|
||||
end
|
||||
return header, parse_markdown_body(document_body, code_start, code_end, offset)
|
||||
end
|
||||
|
||||
# headers
|
||||
# -------
|
||||
|
||||
const HEADER_REGEX = r"^---$(?<header>((?!---).)+)^---$"ms
|
||||
|
||||
# TODO: non-Weave headers should keep live in a doc
|
||||
# separates header section from `text`
|
||||
function separate_header_text(text)
|
||||
m = match(HEADER_REGEX, text)
|
||||
isnothing(m) && return "", text, 0
|
||||
header_text = m[:header]
|
||||
offset = @static if VERSION ≥ v"1.4"
|
||||
count("\n", header_text)
|
||||
else
|
||||
count(c->c==='\n', header_text)
|
||||
end
|
||||
return header_text, replace(text, HEADER_REGEX => ""; count = 1), offset
|
||||
end
|
||||
|
||||
# HACK:
|
||||
# YAML.jl can't parse text including ``` characters, so first replace all the inline code
|
||||
# with these temporary code start/end string
|
||||
const HEADER_INLINE_START = "<weave_header_inline_start>"
|
||||
const HEADER_INLINE_END = "<weave_header_inline_end>"
|
||||
|
||||
function parse_header(header_text)
|
||||
isempty(header_text) && return Dict()
|
||||
pat = INLINE_REGEX => SubstitutionString("$(HEADER_INLINE_START)\\1$(HEADER_INLINE_END)")
|
||||
header_text = replace(header_text, pat)
|
||||
return YAML.load(header_text)
|
||||
end
|
||||
|
||||
# body
|
||||
# ----
|
||||
|
||||
function parse_markdown_body(document_body, code_start, code_end, offset)
|
||||
lines = split(document_body, '\n')
|
||||
|
||||
state = :doc
|
||||
doc_no = 0
|
||||
code_no = 0
|
||||
content = ""
|
||||
start_line = offset
|
||||
|
||||
options = OptionDict()
|
||||
option_string = ""
|
||||
|
||||
chunks = WeaveChunk[]
|
||||
for (line_no, line) in enumerate(lines)
|
||||
m = match(code_start, line)
|
||||
if !isnothing(m) && state === :doc
|
||||
state = :code
|
||||
|
||||
option_string = isnothing(m[:options]) ? "" : strip(m[:options])
|
||||
options = parse_options(option_string)
|
||||
haskey(options, :label) && (options[:name] = options[:label])
|
||||
haskey(options, :name) || (options[:name] = nothing)
|
||||
|
||||
isempty(strip(content)) || push!(chunks, DocChunk(content, doc_no += 1, start_line))
|
||||
|
||||
start_line = line_no + offset
|
||||
content = ""
|
||||
continue
|
||||
end
|
||||
|
||||
if occursin(code_end, line) && state === :code
|
||||
push!(chunks, CodeChunk(content, code_no += 1, start_line, option_string, options))
|
||||
|
||||
start_line = line_no + offset
|
||||
content = ""
|
||||
state = :doc
|
||||
continue
|
||||
end
|
||||
|
||||
content *= isone(line_no) ? line : string('\n', line)
|
||||
end
|
||||
|
||||
# Remember the last chunk
|
||||
isempty(strip(content)) || push!(chunks, DocChunk(content, doc_no += 1, start_line))
|
||||
|
||||
return chunks
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
using JSON
|
||||
|
||||
|
||||
function parse_notebook(document_body)
|
||||
nb = JSON.parse(document_body)
|
||||
code_no = 0
|
||||
doc_no = 0
|
||||
|
||||
# TODO: handle some of options ?
|
||||
options = Dict{Symbol,Any}()
|
||||
opt_string = ""
|
||||
|
||||
chunks = map(nb["cells"]) do cell
|
||||
text = string('\n', join(cell["source"]), '\n')
|
||||
return if cell["cell_type"] == "code"
|
||||
CodeChunk(text, code_no += 1, 0, opt_string, options)
|
||||
else
|
||||
DocChunk(text, doc_no += 1, 0; notebook = true)
|
||||
end
|
||||
end
|
||||
|
||||
return Dict(), chunks
|
||||
end
|
|
@ -0,0 +1,128 @@
|
|||
using YAML
|
||||
|
||||
|
||||
function WeaveDoc(source, informat = nothing)
|
||||
path = abspath(source)
|
||||
_, fname = splitdir(path)
|
||||
basename = splitext(fname)[1]
|
||||
|
||||
isnothing(informat) && (informat = detect_informat(source))
|
||||
header, chunks = parse_doc(read(source, String), informat)
|
||||
|
||||
# update default chunk options from header
|
||||
chunk_defaults = deepcopy(get_chunk_defaults())
|
||||
if (weave_options = get(header, WEAVE_OPTION_NAME, nothing)) !== nothing
|
||||
for key in keys(chunk_defaults)
|
||||
if (val = get(weave_options, string(key), nothing)) !== nothing
|
||||
chunk_defaults[key] = val
|
||||
end
|
||||
end
|
||||
end
|
||||
if haskey(header, WEAVE_OPTION_NAME_DEPRECATED)
|
||||
@warn "Weave: `options` key is deprecated. Use `weave_options` key instead." _id = WEAVE_OPTION_DEPRECATE_ID maxlog = 1
|
||||
for key in keys(chunk_defaults)
|
||||
if (val = get(header[WEAVE_OPTION_NAME_DEPRECATED], string(key), nothing)) !== nothing
|
||||
chunk_defaults[key] = val
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return WeaveDoc(
|
||||
source,
|
||||
basename,
|
||||
path,
|
||||
chunks,
|
||||
"",
|
||||
nothing,
|
||||
"",
|
||||
"",
|
||||
header,
|
||||
chunk_defaults,
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
detect_informat(path)
|
||||
|
||||
Detect Weave input format based on file extension of `path`.
|
||||
"""
|
||||
function detect_informat(path)
|
||||
ext = lowercase(last(splitext(path)))
|
||||
|
||||
ext == ".jl" && return "script"
|
||||
ext == ".jmd" && return "markdown"
|
||||
ext == ".ipynb" && return "notebook"
|
||||
return "noweb"
|
||||
end
|
||||
|
||||
function parse_doc(document, informat)
|
||||
document = replace(document, "\r\n" => "\n") # normalize line ending
|
||||
|
||||
return informat == "markdown" ? parse_markdown(document) :
|
||||
informat == "noweb" ? parse_markdown(document; is_pandoc = true) :
|
||||
informat == "script" ? parse_script(document) :
|
||||
informat == "notebook" ? parse_notebook(document) :
|
||||
error("unsupported input format given: $informat")
|
||||
end
|
||||
|
||||
# inline
|
||||
# ------
|
||||
|
||||
function DocChunk(text::AbstractString, number, start_line; notebook = false)
|
||||
# don't parse inline code in notebook
|
||||
content = notebook ? parse_inline(text) : parse_inlines(text)
|
||||
return DocChunk(content, number, start_line)
|
||||
end
|
||||
|
||||
const INLINE_REGEX = r"`j\s+(.*?)`"
|
||||
const INLINE_REGEXES = r"`j\s+(.*?)`|^!\s(.*)$"m
|
||||
|
||||
# handle code units correctly !
|
||||
function parse_inlines(str)
|
||||
ret = Inline[]
|
||||
s = 1
|
||||
code_no = text_no = 0
|
||||
for m in eachmatch(INLINE_REGEXES, str)
|
||||
e = m.offset
|
||||
push!(ret, InlineText((str[s:prevind(str,e)]), text_no += 1))
|
||||
i = findfirst(!isnothing, m.captures)
|
||||
push!(ret, InlineCode(m.captures[i], code_no += 1, isone(i) ? :inline : :line))
|
||||
s = e + ncodeunits(m.match)
|
||||
end
|
||||
push!(ret, InlineText(str[s:end], text_no += 1))
|
||||
return ret
|
||||
end
|
||||
|
||||
parse_inline(str) = Inline[InlineText(str, 1)]
|
||||
|
||||
# options
|
||||
# -------
|
||||
|
||||
const OptionDict = Dict{Symbol,Any}
|
||||
|
||||
function parse_options(str)::OptionDict
|
||||
str = string('(', str, ')')
|
||||
ex = Meta.parse(str)
|
||||
nt = if Meta.isexpr(ex, (
|
||||
:block, # "(k1 = v1; k2 = v2, ...)"
|
||||
:tuple, # "(k1 = v1, k2 = v2, ...)"
|
||||
))
|
||||
eval(Expr(:tuple, filter(is_valid_kv, ex.args)...))
|
||||
elseif is_valid_kv(ex) # "(k = v)"
|
||||
eval(Expr(:tuple, ex))
|
||||
else
|
||||
NamedTuple{}()
|
||||
end
|
||||
return dict(nt)
|
||||
end
|
||||
|
||||
is_valid_kv(x) = Meta.isexpr(x, :(=))
|
||||
dict(nt) = Dict((k => v for (k,v) in zip(keys(nt), values(nt)))...)
|
||||
nt(dict) = NamedTuple{(Symbol.(keys(dict))...,)}((collect(values(dict))...,))
|
||||
|
||||
# each input format
|
||||
# -----------------
|
||||
|
||||
include("markdown.jl")
|
||||
include("script.jl")
|
||||
include("notebook.jl")
|
|
@ -0,0 +1,67 @@
|
|||
function parse_script(document_body)
|
||||
lines = split(document_body, '\n')
|
||||
|
||||
doc_line = r"(^#'.*)|(^#%%.*)|(^# %%.*)"
|
||||
doc_start = r"(^#')|(^#%%)|(^# %%)"
|
||||
opt_line = r"(^#\+.*$)|(^#%%\+.*$)|(^# %%\+.*$)"
|
||||
opt_start = r"(^#\+)|(^#%%\+)|(^# %%\+)"
|
||||
|
||||
content = ""
|
||||
state = :code
|
||||
doc_no = 0
|
||||
code_no = 0
|
||||
start_line = 1
|
||||
|
||||
options = OptionDict()
|
||||
option_string = ""
|
||||
|
||||
chunks = WeaveChunk[]
|
||||
for (line_no, line) in enumerate(lines)
|
||||
if (m = match(doc_line, line)) !== nothing && (m = match(opt_line, line)) === nothing
|
||||
line = replace(line, doc_start => "", count = 1)
|
||||
startswith(line, ' ') && (line = replace(line, ' ' => "", count = 1))
|
||||
if state === :code && !isempty(strip(content))
|
||||
push!(chunks, CodeChunk(string('\n', strip(content)), code_no += 1, start_line, option_string, options))
|
||||
content = ""
|
||||
start_line = line_no
|
||||
end
|
||||
state = :doc
|
||||
elseif (m = match(opt_line, line)) !== nothing
|
||||
start_line = line_no
|
||||
if state === :code && !isempty(strip(content))
|
||||
push!(chunks, CodeChunk(string('\n', strip(content)), code_no += 1, start_line, option_string, options))
|
||||
content = ""
|
||||
end
|
||||
if state === :doc && !isempty(strip(content))
|
||||
iszero(doc_no) || (content = string('\n', content)) # Add whitespace to doc chunk. Needed for markdown output
|
||||
push!(chunks, DocChunk(content, doc_no += 1, start_line))
|
||||
content = ""
|
||||
end
|
||||
|
||||
option_string = replace(line, opt_start => "", count = 1)
|
||||
options = parse_options(option_string)
|
||||
haskey(options, :label) && (options[:name] = options[:label])
|
||||
haskey(options, :name) || (options[:name] = nothing)
|
||||
|
||||
state = :code
|
||||
continue
|
||||
elseif state === :doc # && strip(line) != "" && strip(content) != ""
|
||||
state = :code
|
||||
iszero(doc_no) || (content = string('\n', content)) # Add whitespace to doc chunk. Needed for markdown output
|
||||
push!(chunks, DocChunk(content, doc_no += 1, start_line))
|
||||
content = ""
|
||||
|
||||
options = Dict{Symbol,Any}()
|
||||
start_line = line_no
|
||||
end
|
||||
content *= string(line, '\n')
|
||||
end
|
||||
|
||||
# Handle the last chunk
|
||||
chunk = state === :code ?
|
||||
CodeChunk(string('\n', strip(content)), code_no, start_line, option_string, options) :
|
||||
DocChunk(content, doc_no, start_line)
|
||||
push!(chunks, chunk)
|
||||
|
||||
return Dict(), chunks
|
||||
end
|
|
@ -1,84 +0,0 @@
|
|||
pushopt(options::Dict,expr::Expr) = Base.Meta.isexpr(expr,:(=)) && (options[expr.args[1]] = expr.args[2])
|
||||
|
||||
|
||||
const input_formats = @compat Dict{String, Any}(
|
||||
"noweb" => Dict{Symbol, Any}(
|
||||
:codestart => r"^<<(.*?)>>=\s*$",
|
||||
:codeend => r"^@\s*$"
|
||||
),
|
||||
"markdown" => Dict{Symbol, Any}(
|
||||
:codestart => r"(?:^(?:`|~){3,}\s*(?:\{|\{\.|)julia(?:;|\s)(.*)\}\s*$)|(?:^(?:`|~){3,}\s*julia\s*$)",
|
||||
:codeend => r"^`|~{3,}\s*$"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
function read_document(document, format)
|
||||
#doctext = readall(open(document))
|
||||
lines = split(bytestring(open(document) do io
|
||||
mmap_array(Uint8,(filesize(document),),io)
|
||||
end), "\n")
|
||||
|
||||
codestart = input_formats[format][:codestart]
|
||||
codeend = input_formats[format][:codeend]
|
||||
state = "doc"
|
||||
|
||||
docno = 1
|
||||
codeno = 1
|
||||
content = ""
|
||||
start_line = 0
|
||||
|
||||
options = Dict()
|
||||
optionstring = ""
|
||||
parsed = Dict[]
|
||||
for lineno in 1:length(lines)
|
||||
line = lines[lineno]
|
||||
if (m = match(codestart, line)) != nothing && state=="doc"
|
||||
state = "code"
|
||||
if m.captures[1] == nothing
|
||||
optionstring = ""
|
||||
else
|
||||
optionstring=strip(m.captures[1])
|
||||
end
|
||||
#@show optionstring
|
||||
options = Dict{Symbol,Any}()
|
||||
if length(optionstring) > 0
|
||||
expr = parse(optionstring)
|
||||
Base.Meta.isexpr(expr,:(=)) && (options[expr.args[1]] = expr.args[2])
|
||||
Base.Meta.isexpr(expr,:toplevel) && map(pushopt,fill(options,length(expr.args)),expr.args)
|
||||
end
|
||||
haskey(options, :label) && (options[:name] = options[:label])
|
||||
haskey(options, :name) || (options[:name] = nothing)
|
||||
#@show options
|
||||
chunk = @compat Dict{Symbol,Any}(:type => "doc", :content => content,
|
||||
:number => docno,:start_line => start_line)
|
||||
docno += 1
|
||||
start_line = lineno
|
||||
push!(parsed, chunk)
|
||||
content = ""
|
||||
continue
|
||||
end
|
||||
if ismatch(codeend, line) && state=="code"
|
||||
chunk = @compat Dict{Symbol,Any}(:type => "code", :content => content,
|
||||
:number => codeno, :options => options,
|
||||
:optionstring => optionstring,
|
||||
:start_line => start_line)
|
||||
codeno+=1
|
||||
start_line = lineno
|
||||
content = ""
|
||||
state = "doc"
|
||||
push!(parsed, chunk)
|
||||
continue
|
||||
end
|
||||
|
||||
content *= "\n" * line
|
||||
end
|
||||
|
||||
#Remember the last chunk
|
||||
if content != ""
|
||||
chunk = @compat Dict{Symbol,Any}(:type => "doc", :content => content,
|
||||
:number => docno, :start_line => start_line)
|
||||
push!(parsed, chunk)
|
||||
end
|
||||
return parsed
|
||||
end
|
|
@ -0,0 +1,162 @@
|
|||
# fallback methods
|
||||
# ----------------
|
||||
|
||||
set_format_options!(docformat::WeaveFormat; _kwargs...) = return
|
||||
|
||||
function restore_header!(doc)
|
||||
(hasproperty(doc.format, :preserve_header) && doc.format.preserve_header) || return
|
||||
|
||||
# only strips Weave headers
|
||||
delete!(doc.header, WEAVE_OPTION_NAME)
|
||||
if haskey(doc.header, WEAVE_OPTION_NAME_DEPRECATED)
|
||||
@warn "Weave: `options` key is deprecated. Use `weave_options` key instead." _id = WEAVE_OPTION_DEPRECATE_ID maxlog = 1
|
||||
delete!(doc.header, WEAVE_OPTION_NAME_DEPRECATED)
|
||||
end
|
||||
isempty(doc.header) && return
|
||||
|
||||
# restore remained headers as `DocChunk`
|
||||
header_text = "---\n$(YAML.write(doc.header))---"
|
||||
pushfirst!(doc.chunks, DocChunk(header_text, 0, 0))
|
||||
end
|
||||
|
||||
render_chunk(docformat::WeaveFormat, chunk::DocChunk) = join((render_inline(c) for c in chunk.content))
|
||||
|
||||
render_inline(inline::InlineText) = inline.content
|
||||
|
||||
function render_inline(inline::InlineCode)
|
||||
isempty(inline.rich_output) || return inline.rich_output
|
||||
isempty(inline.figures) || return inline.figures[end]
|
||||
return inline.output
|
||||
end
|
||||
|
||||
function render_chunk(docformat::WeaveFormat, chunk::CodeChunk)
|
||||
|
||||
# Fill undefined options with format specific defaults
|
||||
isnothing(chunk.options[:out_width]) && (chunk.options[:out_width] = docformat.out_width)
|
||||
isnothing(chunk.options[:fig_pos]) && (chunk.options[:fig_pos] = docformat.fig_pos)
|
||||
|
||||
# Only use floats if chunk has caption or sets fig_env
|
||||
if !isnothing(chunk.options[:fig_cap]) && isnothing(chunk.options[:fig_env])
|
||||
(chunk.options[:fig_env] = docformat.fig_env)
|
||||
end
|
||||
|
||||
hasproperty(docformat, :indent) && (chunk.content = indent(chunk.content, docformat.indent))
|
||||
|
||||
chunk.content = render_code(docformat, chunk.content)
|
||||
|
||||
echo = chunk.options[:echo]
|
||||
|
||||
chunk.options[:eval] || return echo ? string(docformat.codestart, chunk.content, docformat.codeend) : ""
|
||||
|
||||
if chunk.options[:term]
|
||||
result = render_termchunk(docformat, chunk)
|
||||
else
|
||||
result = if echo
|
||||
# Convert to output format and highlight (html, tex...) if needed
|
||||
string(docformat.codestart, chunk.content, docformat.codeend, '\n')
|
||||
else
|
||||
""
|
||||
end
|
||||
|
||||
if (strip(chunk.output) ≠ "" || strip(chunk.rich_output) ≠ "") &&
|
||||
(chunk.options[:results] ≠ "hidden")
|
||||
if chunk.options[:results] ≠ "markup" && chunk.options[:results] ≠ "hold"
|
||||
strip(chunk.output) ≠ "" && (result *= "$(chunk.output)\n")
|
||||
strip(chunk.rich_output) ≠ "" && (result *= "$(chunk.rich_output)\n")
|
||||
else
|
||||
if chunk.options[:wrap]
|
||||
chunk.output =
|
||||
'\n' * wraplines(chunk.output, chunk.options[:line_width])
|
||||
chunk.output = render_output(docformat, chunk.output)
|
||||
else
|
||||
chunk.output = '\n' * rstrip(chunk.output)
|
||||
chunk.output = render_output(docformat, chunk.output)
|
||||
end
|
||||
|
||||
hasproperty(docformat, :indent) && (chunk.output = indent(chunk.output, docformat.indent))
|
||||
|
||||
strip(chunk.output) ≠ "" && (
|
||||
result *= "$(docformat.outputstart)$(chunk.output)\n$(docformat.outputend)\n"
|
||||
)
|
||||
strip(chunk.rich_output) ≠ "" && (result *= chunk.rich_output * '\n')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Handle figures
|
||||
if chunk.options[:fig] && length(chunk.figures) > 0
|
||||
result *= render_figures(docformat, chunk)
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
render_code(docformat::WeaveFormat, code) = code
|
||||
|
||||
indent(text, nindent) = join(map(x -> string(repeat(' ', nindent), x), split(text, '\n')), '\n')
|
||||
|
||||
function wraplines(text, line_width = 75)
|
||||
result = AbstractString[]
|
||||
lines = split(text, '\n')
|
||||
for line in lines
|
||||
if length(line) > line_width
|
||||
push!(result, wrapline(line, line_width))
|
||||
else
|
||||
push!(result, line)
|
||||
end
|
||||
end
|
||||
|
||||
return strip(join(result, '\n'))
|
||||
end
|
||||
|
||||
function wrapline(text, line_width = 75)
|
||||
result = ""
|
||||
while length(text) > line_width
|
||||
result *= first(text, line_width) * '\n'
|
||||
text = chop(text, head = line_width, tail = 0)
|
||||
end
|
||||
result *= text
|
||||
end
|
||||
|
||||
render_output(docformat::WeaveFormat, output) = output
|
||||
|
||||
function render_termchunk(docformat::WeaveFormat, chunk)
|
||||
return if should_render(chunk)
|
||||
string(docformat.termstart, chunk.output, docformat.termend)
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
should_render(chunk) = chunk.options[:echo] && chunk.options[:results] ≠ "hidden"
|
||||
|
||||
render_doc(docformat, body, doc) = body
|
||||
|
||||
# utilities
|
||||
# ---------
|
||||
|
||||
function clear_buffer_and_format!(io::IOBuffer, out::IOBuffer, render_function)
|
||||
text = take2string!(io)
|
||||
m = Markdown.parse(text, flavor = WeaveMarkdown.weavemd)
|
||||
write(out, string(render_function(m)))
|
||||
end
|
||||
|
||||
addlines(op, inline) = inline.ctype === :line ? string('\n', op, '\n') : op
|
||||
|
||||
get_mustache_template(path::AbstractString) = Mustache.template_from_file(path)
|
||||
get_mustache_template(tpl::Mustache.MustacheTokens) = tpl
|
||||
|
||||
get_highlight_stylesheet(mime, highlight_theme) =
|
||||
get_highlight_stylesheet(mime, get_highlight_theme(highlight_theme))
|
||||
get_highlight_stylesheet(mime, highlight_theme::Type{<:Highlights.AbstractTheme}) =
|
||||
sprint((io, x) -> Highlights.stylesheet(io, mime, x), highlight_theme)
|
||||
|
||||
get_highlight_theme(::Nothing) = Highlights.Themes.DefaultTheme
|
||||
get_highlight_theme(highlight_theme::Type{<:Highlights.AbstractTheme}) = highlight_theme
|
||||
|
||||
highlight_code(mime, code, highlight_theme) =
|
||||
highlight(mime, strip(code), Highlights.Lexers.JuliaLexer, highlight_theme)
|
||||
highlight_term(mime, output, highlight_theme) =
|
||||
highlight(mime, strip(output), Highlights.Lexers.JuliaConsoleLexer, highlight_theme)
|
||||
highlight(mime, output, lexer, theme = Highlights.Themes.DefaultTheme) =
|
||||
sprint((io, x) -> Highlights.highlight(io, mime, x, lexer, theme), output)
|
|
@ -0,0 +1,24 @@
|
|||
abstract type ExportFormat <: WeaveFormat end
|
||||
|
||||
function Base.getproperty(sf::T, s::Symbol) where {T<:ExportFormat}
|
||||
hasfield(T, s) && return getfield(sf, s)
|
||||
return getproperty(sf.primaryformat, s)
|
||||
end
|
||||
function Base.setproperty!(sf::T, s::Symbol, v) where {T<:ExportFormat}
|
||||
if hasfield(T, s)
|
||||
setfield!(sf, s, v)
|
||||
else
|
||||
setproperty!(sf.primaryformat, s, v)
|
||||
end
|
||||
end
|
||||
function Base.hasproperty(sf::T, s::Symbol) where {T<:ExportFormat}
|
||||
hasfield(T, s) || hasproperty(sf.primaryformat, s)
|
||||
end
|
||||
|
||||
render_doc(df::ExportFormat, body, doc) = render_doc(df.primaryformat, body, doc)
|
||||
|
||||
render_chunk(df::ExportFormat, chunk) = render_chunk(df.primaryformat, chunk)
|
||||
# Need to define these to avoid ambiguities
|
||||
render_chunk(df::ExportFormat, chunk::DocChunk) = render_chunk(df.primaryformat, chunk)
|
||||
render_chunk(df::ExportFormat, chunk::CodeChunk) = render_chunk(df.primaryformat, chunk)
|
||||
render_output(df::ExportFormat, output) = render_output(df.primaryformat, output)
|
|
@ -0,0 +1,146 @@
|
|||
# HTML
|
||||
# ----
|
||||
|
||||
abstract type HTMLFormat <: WeaveFormat end
|
||||
|
||||
render_code(docformat::HTMLFormat, code) =
|
||||
highlight_code(MIME("text/html"), code, docformat.highlight_theme)
|
||||
|
||||
render_termchunk(docformat::HTMLFormat, chunk) =
|
||||
should_render(chunk) ? highlight_term(MIME("text/html"), chunk.output, docformat.highlight_theme) : ""
|
||||
|
||||
# Julia markdown
|
||||
# --------------
|
||||
|
||||
Base.@kwdef mutable struct WeaveHTML <: HTMLFormat
|
||||
description = "Weave-style HTML"
|
||||
extension = "html"
|
||||
codestart = '\n'
|
||||
codeend = '\n'
|
||||
termstart = codestart
|
||||
termend = codeend
|
||||
outputstart = "<pre class=\"output\">"
|
||||
outputend = "</pre>\n"
|
||||
mimetypes = ["image/png", "image/jpg", "image/svg+xml",
|
||||
"text/html", "text/markdown", "text/plain"]
|
||||
fig_ext = ".png"
|
||||
out_width = nothing
|
||||
out_height = nothing
|
||||
fig_pos = nothing
|
||||
fig_env = nothing
|
||||
# specials
|
||||
template = nothing
|
||||
stylesheet = nothing
|
||||
highlight_theme = nothing
|
||||
end
|
||||
register_format!("md2html", WeaveHTML())
|
||||
|
||||
function set_format_options!(docformat::WeaveHTML; template = nothing, css = nothing, highlight_theme = nothing, _kwargs...)
|
||||
template_path = isnothing(template) ? normpath(TEMPLATE_DIR, "md2html.tpl") : template
|
||||
docformat.template = get_mustache_template(template_path)
|
||||
stylesheet_path = isnothing(css) ? normpath(STYLESHEET_DIR, "skeleton.css") : css
|
||||
docformat.stylesheet = read(stylesheet_path, String)
|
||||
docformat.highlight_theme = get_highlight_theme(highlight_theme)
|
||||
end
|
||||
|
||||
# very similar to tex version of function
|
||||
function render_chunk(docformat::WeaveHTML, chunk::DocChunk)
|
||||
out = IOBuffer()
|
||||
io = IOBuffer()
|
||||
for inline in chunk.content
|
||||
if isa(inline, InlineText)
|
||||
write(io, inline.content)
|
||||
elseif !isempty(inline.rich_output)
|
||||
clear_buffer_and_format!(io, out, WeaveMarkdown.html)
|
||||
write(out, addlines(inline.rich_output, inline))
|
||||
elseif !isempty(inline.figures)
|
||||
write(io, inline.figures[end])
|
||||
elseif !isempty(inline.output)
|
||||
write(io, addlines(inline.output, inline))
|
||||
end
|
||||
end
|
||||
clear_buffer_and_format!(io, out, WeaveMarkdown.html)
|
||||
return take2string!(out)
|
||||
end
|
||||
|
||||
render_output(docformat::WeaveHTML, output) = Markdown.htmlesc(output)
|
||||
|
||||
function render_figures(docformat::WeaveHTML, chunk)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
width = chunk.options[:out_width]
|
||||
height = chunk.options[:out_height]
|
||||
f_pos = chunk.options[:fig_pos]
|
||||
f_env = chunk.options[:fig_env]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
# Set size
|
||||
attribs = ""
|
||||
isnothing(width) || (attribs = "width=\"$width\"")
|
||||
(!isempty(attribs) && !isnothing(height)) && (attribs *= ",")
|
||||
isnothing(height) || (attribs *= " height=\"$height\" ")
|
||||
|
||||
if !isnothing(caption)
|
||||
result *= """<figure>\n"""
|
||||
end
|
||||
|
||||
for fig in fignames
|
||||
figstring *= """<img src="$fig" $attribs />\n"""
|
||||
end
|
||||
|
||||
result *= figstring
|
||||
|
||||
if !isnothing(caption)
|
||||
result *= """
|
||||
<figcaption>$caption</figcaption>
|
||||
"""
|
||||
end
|
||||
|
||||
if !isnothing(caption)
|
||||
result *= "</figure>\n"
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function render_doc(docformat::WeaveHTML, body, doc; css = nothing)
|
||||
_, weave_source = splitdir(abspath(doc.source))
|
||||
weave_version, weave_date = weave_info()
|
||||
|
||||
return Mustache.render(
|
||||
docformat.template;
|
||||
body = body,
|
||||
stylesheet = docformat.stylesheet,
|
||||
highlight_stylesheet = get_highlight_stylesheet(MIME("text/html"), docformat.highlight_theme),
|
||||
header_script = doc.header_script,
|
||||
weave_source = weave_source,
|
||||
weave_version = weave_version,
|
||||
weave_date = weave_date,
|
||||
[Pair(Symbol(k), v) for (k, v) in doc.header]...,
|
||||
)
|
||||
end
|
||||
|
||||
# Pandoc
|
||||
# ------
|
||||
|
||||
Base.@kwdef mutable struct Pandoc2HTML <: ExportFormat
|
||||
description = "HTML via intermediate Pandoc Markdown (requires Pandoc 2)"
|
||||
primaryformat = Pandoc()
|
||||
template_path = nothing
|
||||
stylesheet_path = nothing
|
||||
highlight_theme = nothing
|
||||
pandoc_options = String[]
|
||||
end
|
||||
register_format!("pandoc2html", Pandoc2HTML())
|
||||
|
||||
function set_format_options!(docformat::Pandoc2HTML; template = nothing, css = nothing, highlight_theme = nothing, pandoc_options = String[], _kwargs...)
|
||||
docformat.template_path =
|
||||
isnothing(template) ? normpath(TEMPLATE_DIR, "pandoc2html.html") : template
|
||||
docformat.stylesheet_path =
|
||||
isnothing(css) ? normpath(STYLESHEET_DIR, "pandoc2html_skeleton.css") : css
|
||||
docformat.highlight_theme = get_highlight_theme(highlight_theme)
|
||||
docformat.pandoc_options = pandoc_options
|
||||
end
|
||||
|
||||
render_figures(docformat::Pandoc2HTML, chunk) = render_figures(Pandoc(), chunk)
|
|
@ -0,0 +1,224 @@
|
|||
# GitHub markdown
|
||||
# ---------------
|
||||
|
||||
Base.@kwdef mutable struct GitHubMarkdown <: WeaveFormat
|
||||
description = "GitHub Markdown"
|
||||
extension = "md"
|
||||
codestart = "```julia"
|
||||
codeend = "```\n"
|
||||
termstart = codestart
|
||||
termend = codeend
|
||||
outputstart = "```"
|
||||
outputend = "```\n\n"
|
||||
fig_ext = ".png"
|
||||
mimetypes = ["image/png", "image/svg+xml", "image/jpg",
|
||||
"text/markdown", "text/plain"]
|
||||
out_width = nothing
|
||||
out_height = nothing
|
||||
fig_pos = nothing
|
||||
fig_env = nothing
|
||||
# specials
|
||||
preserve_header = true
|
||||
end
|
||||
register_format!("github", GitHubMarkdown())
|
||||
|
||||
function render_figures(docformat::GitHubMarkdown, chunk)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
length(fignames) > 0 || (return "")
|
||||
|
||||
if !isnothing(caption)
|
||||
result *= "![$caption]($(fignames[1]))\n"
|
||||
for fig in fignames[2:end]
|
||||
result *= "![]($fig)\n"
|
||||
println("Warning, only the first figure gets a caption\n")
|
||||
end
|
||||
else
|
||||
for fig in fignames
|
||||
result *= "![]($fig)\n"
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
# Hugo markdown
|
||||
# -------------
|
||||
|
||||
Base.@kwdef mutable struct Hugo <: WeaveFormat
|
||||
description = "Hugo Markdown (using shortcodes)"
|
||||
extension = "md"
|
||||
codestart = "```julia"
|
||||
codeend = "```\n"
|
||||
termstart = codestart
|
||||
termend = codeend
|
||||
outputstart = "```"
|
||||
outputend = "```\n\n"
|
||||
mimetypes = default_mime_types
|
||||
fig_ext = ".png"
|
||||
out_width = nothing
|
||||
out_height = nothing
|
||||
fig_pos = nothing
|
||||
fig_env = nothing
|
||||
# specials
|
||||
preserve_header = true
|
||||
uglyURLs = false # if `false`, prepend figure path by `..`
|
||||
end
|
||||
register_format!("hugo", Hugo())
|
||||
|
||||
function render_figures(docformat::Hugo, chunk)
|
||||
relpath = docformat.uglyURLs ? "" : ".."
|
||||
mapreduce(*, enumerate(chunk.figures), init = "") do (index, fig)
|
||||
if index > 1
|
||||
@warn("Only the first figure gets a caption.")
|
||||
title_spec = ""
|
||||
else
|
||||
caption = chunk.options[:fig_cap]
|
||||
title_spec = isnothing(caption) ? "" : "title=\"$(caption)\" "
|
||||
end
|
||||
"{{< figure src=\"$(joinpath(relpath, fig))\" $(title_spec) >}}"
|
||||
end
|
||||
end
|
||||
|
||||
# multi language markdown
|
||||
# -----------------------
|
||||
|
||||
Base.@kwdef mutable struct MultiMarkdown <: WeaveFormat
|
||||
description = "MultiMarkdown"
|
||||
extension = "md"
|
||||
codestart = "```julia"
|
||||
codeend = "```\n"
|
||||
termstart = codestart
|
||||
termend = codeend
|
||||
outputstart = "```"
|
||||
outputend = "```\n\n"
|
||||
mimetypes = default_mime_types
|
||||
fig_ext = ".png"
|
||||
out_width = nothing
|
||||
out_height = nothing
|
||||
fig_pos = nothing
|
||||
fig_env = nothing
|
||||
# specials
|
||||
preserve_header = true
|
||||
end
|
||||
register_format!("multimarkdown", MultiMarkdown())
|
||||
|
||||
function render_figures(docformat::MultiMarkdown, chunk)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
if chunk.options[:out_width] == nothing
|
||||
width = ""
|
||||
else
|
||||
width = "width=$(chunk.options[:out_width])"
|
||||
end
|
||||
|
||||
length(fignames) > 0 || (return "")
|
||||
|
||||
if !isnothing(caption)
|
||||
result *= "![$caption][$(fignames[1])]\n\n"
|
||||
result *= "[$(fignames[1])]: $(fignames[1]) $width\n"
|
||||
for fig in fignames[2:end]
|
||||
result *= "![][$fig]\n\n"
|
||||
result *= "[$fig]: $fig $width\n"
|
||||
println("Warning, only the first figure gets a caption\n")
|
||||
end
|
||||
else
|
||||
for fig in fignames
|
||||
result *= "![][$fig]\n\n"
|
||||
result *= "[$fig]: $fig $width\n"
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
# Rest
|
||||
# ----
|
||||
|
||||
Base.@kwdef mutable struct Rest <: WeaveFormat
|
||||
description = "reStructuredText and Sphinx"
|
||||
extension = "rst"
|
||||
codestart = ".. code-block:: julia\n"
|
||||
codeend = "\n"
|
||||
termstart = codestart
|
||||
termend = codeend
|
||||
outputstart = "::\n"
|
||||
outputend = "\n\n"
|
||||
mimetypes = default_mime_types
|
||||
fig_ext = ".png"
|
||||
out_width = "15 cm"
|
||||
out_height = nothing
|
||||
fig_pos = nothing
|
||||
fig_env = nothing
|
||||
# specials
|
||||
indent = 4
|
||||
end
|
||||
register_format!("rst", Rest())
|
||||
|
||||
function render_figures(docformat::Rest, chunk)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
width = chunk.options[:out_width]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
for fig in fignames
|
||||
figstring *= @sprintf(".. image:: %s\n :width: %s\n\n", fig, width)
|
||||
end
|
||||
|
||||
if !isnothing(caption)
|
||||
result *= string(
|
||||
".. figure:: $(fignames[1])\n",
|
||||
" :width: $width\n\n",
|
||||
" $caption\n\n",
|
||||
)
|
||||
else
|
||||
result *= figstring
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# Ansii
|
||||
# -----
|
||||
|
||||
# asciidoc -b html5 -a source-highlighter=pygments ...
|
||||
Base.@kwdef mutable struct AsciiDoc <: WeaveFormat
|
||||
description = "AsciiDoc"
|
||||
extension = "txt"
|
||||
codestart = "[source,julia]\n--------------------------------------"
|
||||
codeend = "--------------------------------------\n"
|
||||
termstart = codestart
|
||||
termend = codeend
|
||||
outputstart = "--------------------------------------"
|
||||
outputend = "--------------------------------------\n\n"
|
||||
mimetypes = default_mime_types
|
||||
fig_ext = ".png"
|
||||
out_width = "600"
|
||||
out_height = nothing
|
||||
fig_pos = nothing
|
||||
fig_env = nothing
|
||||
end
|
||||
register_format!("asciidoc", AsciiDoc())
|
||||
|
||||
function render_figures(docformat::AsciiDoc, chunk)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
width = chunk.options[:out_width]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
for fig in fignames
|
||||
figstring *= @sprintf("image::%s[width=%s]\n", fig, width)
|
||||
end
|
||||
|
||||
if !isnothing(caption)
|
||||
result *= string("image::$(fignames[1])", "[width=$width,", "title=\"$caption\"]")
|
||||
else
|
||||
result *= figstring
|
||||
return result
|
||||
end
|
||||
end
|
|
@ -0,0 +1,70 @@
|
|||
abstract type PandocFormat <: WeaveFormat end
|
||||
|
||||
function render_figures(docformat::PandocFormat, chunk)
|
||||
fignames = chunk.figures
|
||||
length(fignames) > 0 || (return "")
|
||||
|
||||
caption = chunk.options[:fig_cap]
|
||||
label = get(chunk.options, :label, nothing)
|
||||
result = ""
|
||||
figstring = ""
|
||||
attribs = ""
|
||||
width = chunk.options[:out_width]
|
||||
height = chunk.options[:out_height]
|
||||
|
||||
# Build figure attibutes
|
||||
attribs = String[]
|
||||
isnothing(width) || push!(attribs, "width=$width")
|
||||
isnothing(height) || push!(attribs, "height=$height")
|
||||
isnothing(label) || push!(attribs, "#fig:$label")
|
||||
attribs = isempty(attribs) ? "" : "{" * join(attribs, " ") * "}"
|
||||
|
||||
if !isnothing(caption)
|
||||
result *= "![$caption]($(fignames[1]))$attribs\n"
|
||||
for fig in fignames[2:end]
|
||||
result *= "![]($fig)$attribs\n"
|
||||
println("Warning, only the first figure gets a caption\n")
|
||||
end
|
||||
else
|
||||
for fig in fignames
|
||||
result *= "![]($fig)$attribs\\ \n\n"
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
Base.@kwdef mutable struct Pandoc <: PandocFormat
|
||||
description = "Pandoc Markdown"
|
||||
extension = "md"
|
||||
codestart = "~~~~{.julia}"
|
||||
codeend = "~~~~~~~~~~~~~\n"
|
||||
termstart = codestart
|
||||
termend = codeend
|
||||
outputstart = "~~~~"
|
||||
outputend = "~~~~\n\n"
|
||||
# Prefer png figures for markdown conversion, svg doesn't work with latex
|
||||
mimetypes = ["image/png", "image/jpg", "image/svg+xml", "text/markdown", "text/plain"]
|
||||
fig_ext = ".png"
|
||||
out_width = nothing
|
||||
out_height = nothing
|
||||
fig_pos = nothing
|
||||
fig_env = nothing
|
||||
# specials
|
||||
preserve_header = true
|
||||
end
|
||||
register_format!("pandoc", Pandoc())
|
||||
|
||||
|
||||
const DEFAULT_PANDOC_OPTIONS = String[]
|
||||
|
||||
Base.@kwdef mutable struct Pandoc2PDF <: ExportFormat
|
||||
description = "PDF via intermediate Pandoc Markdown"
|
||||
primaryformat = Pandoc()
|
||||
pandoc_options = DEFAULT_PANDOC_OPTIONS
|
||||
header_template = normpath(TEMPLATE_DIR, "pandoc2pdf_header.txt")
|
||||
end
|
||||
register_format!("pandoc2pdf", Pandoc2PDF())
|
||||
|
||||
function set_format_options!(docformat::Pandoc2PDF; pandoc_options = DEFAULT_PANDOC_OPTIONS, _kwargs...)
|
||||
docformat.pandoc_options = pandoc_options
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
# TODO:
|
||||
# - 1. Improve argument handling
|
||||
# - 2. Update code to use UnPack.jl to make it more readable
|
||||
# - 3. Export new interface
|
||||
# - 4. Document Interface
|
||||
|
||||
using Mustache, Highlights, .WeaveMarkdown, Markdown, Dates, Printf
|
||||
|
||||
|
||||
const FORMATS = Dict{String,WeaveFormat}()
|
||||
|
||||
# TODO: do some assertion for necessary fields of `format`
|
||||
register_format!(format_name::AbstractString, format::WeaveFormat) = push!(FORMATS, format_name => format)
|
||||
register_format!(_, format) = error("Format needs to be a subtype of WeaveFormat.")
|
||||
|
||||
set_format_options!(doc; kwargs...) = set_format_options!(doc.format; kwargs...)
|
||||
|
||||
function render_doc(doc::WeaveDoc)
|
||||
restore_header!(doc)
|
||||
|
||||
docformat = doc.format
|
||||
body = joinlines(render_chunk.(Ref(docformat), copy(doc.chunks)))
|
||||
return render_doc(docformat, body, doc)
|
||||
end
|
||||
|
||||
include("exportformat.jl")
|
||||
include("common.jl")
|
||||
include("pandocformats.jl")
|
||||
include("htmlformats.jl")
|
||||
include("texformats.jl")
|
||||
include("miscformats.jl")
|
|
@ -0,0 +1,264 @@
|
|||
# Tex
|
||||
# ---
|
||||
|
||||
abstract type LaTeXFormat <: WeaveFormat end
|
||||
|
||||
function set_format_options!(docformat::LaTeXFormat; keep_unicode = false, template = nothing, _kwargs...)
|
||||
docformat.keep_unicode |= keep_unicode
|
||||
docformat.template =
|
||||
get_mustache_template(isnothing(template) ? normpath(TEMPLATE_DIR, "md2pdf.tpl") : template)
|
||||
end
|
||||
|
||||
# very similar to export to html
|
||||
function render_chunk(docformat::LaTeXFormat, chunk::DocChunk)
|
||||
out = IOBuffer()
|
||||
io = IOBuffer()
|
||||
for inline in chunk.content
|
||||
if isa(inline, InlineText)
|
||||
write(io, inline.content)
|
||||
elseif !isempty(inline.rich_output)
|
||||
clear_buffer_and_format!(io, out, WeaveMarkdown.latex)
|
||||
write(out, addlines(inline.rich_output, inline))
|
||||
elseif !isempty(inline.figures)
|
||||
write(io, inline.figures[end], inline)
|
||||
elseif !isempty(inline.output)
|
||||
write(io, addlines(inline.output, inline))
|
||||
end
|
||||
end
|
||||
clear_buffer_and_format!(io, out, WeaveMarkdown.latex)
|
||||
out = take2string!(out)
|
||||
return unicode2latex(docformat, out)
|
||||
end
|
||||
|
||||
render_output(docformat::LaTeXFormat, output) = unicode2latex(docformat, output, true)
|
||||
|
||||
render_code(docformat::LaTeXFormat, code) = unicode2latex(docformat, code, true)
|
||||
|
||||
render_termchunk(docformat::LaTeXFormat, chunk) =
|
||||
string(docformat.termstart,
|
||||
unicode2latex(docformat, chunk.output, true),
|
||||
docformat.termend, "\n")
|
||||
|
||||
# from julia symbols (e.g. "\bfhoge") to valid latex
|
||||
const UNICODE2LATEX = let
|
||||
function texify(s)
|
||||
return if occursin(r"^\\bf[A-Z]$", s)
|
||||
replace(s, "\\bf" => "\\bm{\\mathrm{") * "}}"
|
||||
elseif startswith(s, "\\bfrak")
|
||||
replace(s, "\\bfrak" => "\\bm{\\mathfrak{") * "}}"
|
||||
elseif startswith(s, "\\bf")
|
||||
replace(s, "\\bf" => "\\bm{\\") * "}"
|
||||
elseif startswith(s, "\\frak")
|
||||
replace(s, "\\frak" => "\\mathfrak{") * "}"
|
||||
else
|
||||
s
|
||||
end
|
||||
end
|
||||
Dict(unicode => texify(sym) for (sym, unicode) in REPL.REPLCompletions.latex_symbols)
|
||||
end
|
||||
|
||||
function unicode2latex(docformat::LaTeXFormat, s, escape = false)
|
||||
# Check whether to convert at all and return input if not
|
||||
docformat.keep_unicode && return s
|
||||
for (unicode, latex) in UNICODE2LATEX
|
||||
body = "\\ensuremath{$(latex)}"
|
||||
target = escape ? string(docformat.escape_starter, body, docformat.escape_closer) : body
|
||||
s = replace(s, unicode => target)
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
function render_figures(docformat::LaTeXFormat, chunk)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
width = chunk.options[:out_width]
|
||||
height = chunk.options[:out_height]
|
||||
f_pos = chunk.options[:fig_pos]
|
||||
f_env = chunk.options[:fig_env]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
if isnothing(f_env) && !isnothing(caption)
|
||||
f_env = "figure"
|
||||
end
|
||||
|
||||
(isnothing(f_pos)) && (f_pos = "!h")
|
||||
# Set size
|
||||
attribs = ""
|
||||
isnothing(width) || (attribs = "width=$(md_length_to_latex(width,"\\linewidth"))")
|
||||
(!isempty(attribs) && !isnothing(height)) && (attribs *= ",")
|
||||
isnothing(height) || (attribs *= "height=$(md_length_to_latex(height,"\\paperheight"))")
|
||||
|
||||
if !isnothing(f_env)
|
||||
result *= "\\begin{$f_env}"
|
||||
(!isempty(f_pos)) && (result *= "[$f_pos]")
|
||||
result *= "\n"
|
||||
end
|
||||
|
||||
for fig in fignames
|
||||
if splitext(fig)[2] == ".tex" # Tikz figures
|
||||
figstring *= "\\resizebox{$width}{!}{\\input{$fig}}\n"
|
||||
else
|
||||
if isempty(attribs)
|
||||
figstring *= "\\includegraphics{$fig}\n"
|
||||
else
|
||||
figstring *= "\\includegraphics[$attribs]{$fig}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Figure environment
|
||||
if !isnothing(caption)
|
||||
result *= string("\\center\n", "$figstring", "\\caption{$caption}\n")
|
||||
else
|
||||
result *= figstring
|
||||
end
|
||||
|
||||
if !isnothing(chunk.options[:label]) && !isnothing(f_env)
|
||||
label = chunk.options[:label]
|
||||
result *= "\\label{fig:$label}\n"
|
||||
end
|
||||
|
||||
if !isnothing(f_env)
|
||||
result *= "\\end{$f_env}\n"
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function md_length_to_latex(def, reference)
|
||||
if occursin("%", def)
|
||||
_def = tryparse(Float64, replace(def, "%" => ""))
|
||||
isnothing(_def) && return def
|
||||
perc = round(_def / 100, digits = 2)
|
||||
return "$perc$reference"
|
||||
end
|
||||
return def
|
||||
end
|
||||
|
||||
function render_doc(docformat::LaTeXFormat, body, doc)
|
||||
return Mustache.render(
|
||||
docformat.template;
|
||||
body = body,
|
||||
highlight = "",
|
||||
tex_deps = docformat.tex_deps,
|
||||
[Pair(Symbol(k), v) for (k, v) in doc.header]...,
|
||||
)
|
||||
end
|
||||
|
||||
# minted Tex
|
||||
# ----------
|
||||
|
||||
Base.@kwdef mutable struct LaTeXMinted <: LaTeXFormat
|
||||
description = "LaTeX using minted package for code highlighting"
|
||||
extension = "tex"
|
||||
codestart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}"
|
||||
codeend = "\\end{minted}"
|
||||
termstart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\footnotesize, xleftmargin=0.5em]{jlcon}"
|
||||
termend = "\\end{minted}"
|
||||
outputstart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\small, xleftmargin=0.5em, frame = leftline]{text}"
|
||||
outputend = "\\end{minted}"
|
||||
mimetypes = ["application/pdf", "image/png", "text/latex", "text/plain"]
|
||||
fig_ext = ".pdf"
|
||||
out_width = "\\linewidth"
|
||||
out_height = nothing
|
||||
fig_pos = "htpb"
|
||||
fig_env = "figure"
|
||||
# specials
|
||||
keep_unicode = false
|
||||
template = nothing
|
||||
tex_deps = "\\usepackage{minted}"
|
||||
# how to escape latex in verbatim/code environment
|
||||
escape_starter = "|\$"
|
||||
escape_closer = reverse(escape_starter)
|
||||
end
|
||||
register_format!("texminted", LaTeXMinted())
|
||||
|
||||
# Tex (directly to PDF)
|
||||
# ---------------------
|
||||
|
||||
abstract type WeaveLaTeXFormat <: LaTeXFormat end
|
||||
|
||||
function set_format_options!(docformat::WeaveLaTeXFormat; template = nothing, highlight_theme = nothing, keep_unicode = false, _kwargs...)
|
||||
docformat.template =
|
||||
get_mustache_template(isnothing(template) ? normpath(TEMPLATE_DIR, "md2pdf.tpl") : template)
|
||||
docformat.highlight_theme = get_highlight_theme(highlight_theme)
|
||||
docformat.keep_unicode |= keep_unicode
|
||||
end
|
||||
|
||||
function render_output(docformat::WeaveLaTeXFormat, output)
|
||||
# Highligts has some extra escaping defined, eg of $, ", ...
|
||||
output_escaped = sprint(
|
||||
(io, x) ->
|
||||
Highlights.Format.escape(io, MIME("text/latex"), x, charescape = true),
|
||||
output,
|
||||
)
|
||||
return unicode2latex(docformat, output_escaped, true)
|
||||
end
|
||||
|
||||
function render_code(docformat::WeaveLaTeXFormat, code)
|
||||
ret = highlight_code(MIME("text/latex"), code, docformat.highlight_theme)
|
||||
unicode2latex(docformat, ret, false)
|
||||
end
|
||||
|
||||
function render_termchunk(docformat::WeaveLaTeXFormat, chunk)
|
||||
if should_render(chunk)
|
||||
ret = highlight_term(MIME("text/latex"), chunk.output, docformat.highlight_theme)
|
||||
unicode2latex(docformat, ret, true)
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
function render_doc(docformat::WeaveLaTeXFormat, body, doc)
|
||||
return Mustache.render(
|
||||
docformat.template;
|
||||
body = body,
|
||||
highlight = get_highlight_stylesheet(MIME("text/latex"), docformat.highlight_theme),
|
||||
tex_deps = docformat.tex_deps,
|
||||
[Pair(Symbol(k), v) for (k, v) in doc.header]...,
|
||||
)
|
||||
end
|
||||
|
||||
Base.@kwdef mutable struct WeaveLaTeX <: WeaveLaTeXFormat
|
||||
description = "Weave-styled LaTeX"
|
||||
extension = "tex"
|
||||
codestart = ""
|
||||
codeend = ""
|
||||
termstart = codestart
|
||||
termend = codeend
|
||||
outputstart = "\\begin{lstlisting}"
|
||||
outputend = "\\end{lstlisting}\n"
|
||||
mimetypes = ["application/pdf", "image/png", "image/jpg", "text/latex", "text/markdown", "text/plain"]
|
||||
fig_ext = ".pdf"
|
||||
out_width = "\\linewidth"
|
||||
out_height = nothing
|
||||
fig_pos = nothing
|
||||
fig_env = nothing
|
||||
# specials
|
||||
highlight_theme = nothing
|
||||
template = nothing
|
||||
keep_unicode = false
|
||||
tex_deps = ""
|
||||
# how to escape latex in verbatim/code environment
|
||||
escape_starter = "(*@"
|
||||
escape_closer = "@*)"
|
||||
end
|
||||
register_format!("md2tex", WeaveLaTeX())
|
||||
|
||||
# will be used by `write_doc`
|
||||
const DEFAULT_LATEX_CMD = ["xelatex", "-shell-escape", "-halt-on-error"]
|
||||
|
||||
|
||||
Base.@kwdef mutable struct LaTeX2PDF <: ExportFormat
|
||||
primaryformat = WeaveLaTeX()
|
||||
description = "PDF via LaTeX"
|
||||
latex_cmd = DEFAULT_LATEX_CMD
|
||||
end
|
||||
register_format!("md2pdf", LaTeX2PDF())
|
||||
register_format!("minted2pdf", LaTeX2PDF(primaryformat=LaTeXMinted()))
|
||||
|
||||
function set_format_options!(docformat::LaTeX2PDF; latex_cmd = DEFAULT_LATEX_CMD, _kwargs...)
|
||||
docformat.latex_cmd = latex_cmd
|
||||
set_format_options!(docformat.primaryformat; _kwargs...)
|
||||
end
|
|
@ -0,0 +1,451 @@
|
|||
using Base64
|
||||
|
||||
|
||||
const PROGRESS_ID = "weave_progress"
|
||||
|
||||
function run_doc(
|
||||
doc::WeaveDoc;
|
||||
doctype::Union{Nothing,AbstractString} = nothing,
|
||||
out_path::Union{Symbol,AbstractString} = :doc,
|
||||
args::Any = Dict(),
|
||||
mod::Union{Module,Nothing} = nothing,
|
||||
fig_path::Union{Nothing,AbstractString} = nothing,
|
||||
fig_ext::Union{Nothing,AbstractString} = nothing,
|
||||
cache_path::AbstractString = "cache",
|
||||
cache::Symbol = :off,
|
||||
)
|
||||
# cache :all, :user, :off, :refresh
|
||||
|
||||
doc.doctype = isnothing(doctype) ? (doctype = detect_doctype(doc.source)) : doctype
|
||||
doc.format = deepcopy(get_format(doctype))
|
||||
|
||||
cwd = doc.cwd = get_cwd(doc, out_path)
|
||||
mkpath(cwd)
|
||||
|
||||
# TODO: provide a way not to create `fig_path` ?
|
||||
if isnothing(fig_path)
|
||||
fig_path = if (endswith(doctype, "2pdf") && cache === :off) || endswith(doctype, "2html")
|
||||
basename(mktempdir(abspath(cwd)))
|
||||
else
|
||||
DEFAULT_FIG_PATH
|
||||
end
|
||||
end
|
||||
mkpath(normpath(cwd, fig_path))
|
||||
# This is needed for latex and should work on all output formats
|
||||
@static Sys.iswindows() && (fig_path = replace(fig_path, "\\" => "/"))
|
||||
set_rc_params(doc, fig_path, fig_ext)
|
||||
|
||||
cache === :off || @eval import Serialization # XXX: evaluate in a more sensible module
|
||||
|
||||
# New sandbox for each document with args exposed
|
||||
isnothing(mod) && (mod = sandbox = Core.eval(Main, :(module $(gensym(:WeaveSandBox)) end))::Module)
|
||||
Core.eval(mod, :(WEAVE_ARGS = $(args)))
|
||||
|
||||
mimetypes = doc.format.mimetypes
|
||||
|
||||
report = Report(cwd, doc.basename, doc.format, mimetypes)
|
||||
cd_back = let d = pwd(); () -> cd(d); end
|
||||
cd(cwd)
|
||||
pushdisplay(report)
|
||||
try
|
||||
if cache !== :off && cache !== :refresh
|
||||
cached = read_cache(doc, cache_path)
|
||||
isnothing(cached) && @info "No cached results found, running code"
|
||||
else
|
||||
cached = nothing
|
||||
end
|
||||
|
||||
executed = []
|
||||
n = length(filter(chunk->isa(chunk,CodeChunk), doc.chunks))
|
||||
i = 0
|
||||
for chunk in doc.chunks
|
||||
if chunk isa CodeChunk
|
||||
options = merge(doc.chunk_defaults, chunk.options)
|
||||
merge!(chunk.options, options)
|
||||
|
||||
@info "Weaving chunk $(chunk.number) from line $(chunk.start_line)" progress=(i)/n _id=PROGRESS_ID
|
||||
i+=1
|
||||
end
|
||||
|
||||
restore = (cache === :user && chunk isa CodeChunk && chunk.options[:cache])
|
||||
result_chunks = if cached ≠ nothing && (cache === :all || restore)
|
||||
restore_chunk(chunk, cached)
|
||||
else
|
||||
run_chunk(chunk, doc, report, mod)
|
||||
end
|
||||
executed = [executed; result_chunks]
|
||||
end
|
||||
|
||||
replace_header_inline!(doc, report, mod) # evaluate and replace inline code in header
|
||||
|
||||
doc.header_script = report.header_script
|
||||
doc.chunks = executed
|
||||
|
||||
cache !== :off && write_cache(doc, cache_path)
|
||||
|
||||
@isdefined(sandbox) && clear_module!(sandbox)
|
||||
catch err
|
||||
rethrow(err)
|
||||
finally
|
||||
@info "Weaved all chunks" progress=1 _id=PROGRESS_ID
|
||||
cd_back()
|
||||
popdisplay(report) # ensure display pops out even if internal error occurs
|
||||
# Temporary fig_path is not automatically removed because it contains files so...
|
||||
!isnothing(fig_path) && startswith(fig_path, "jl_") && rm(normpath(cwd, fig_path), force=true, recursive=true)
|
||||
end
|
||||
|
||||
return doc
|
||||
end
|
||||
|
||||
run_doc(doc::WeaveDoc, doctype::Union{Nothing,AbstractString}; kwargs...) =
|
||||
run_doc(doc; doctype = doctype, kwargs...)
|
||||
|
||||
"""
|
||||
detect_doctype(path)
|
||||
|
||||
Detect the output format based on file extension.
|
||||
"""
|
||||
function detect_doctype(path)
|
||||
_, ext = lowercase.(splitext(path))
|
||||
|
||||
match(r"^\.(jl|.?md|ipynb)", ext) !== nothing && return "md2html"
|
||||
ext == ".rst" && return "rst"
|
||||
ext == ".tex" && return "texminted"
|
||||
ext == ".txt" && return "asciidoc"
|
||||
|
||||
return "pandoc"
|
||||
end
|
||||
|
||||
function get_cwd(doc, out_path)
|
||||
return if out_path === :doc
|
||||
dirname(doc.path)
|
||||
elseif out_path === :pwd
|
||||
pwd()
|
||||
else
|
||||
path, ext = splitext(out_path)
|
||||
if isempty(ext) # directory given
|
||||
path
|
||||
else # file given
|
||||
dirname(path)
|
||||
end
|
||||
end |> abspath
|
||||
end
|
||||
|
||||
function run_chunk(chunk::CodeChunk, doc, report, mod)
|
||||
result = eval_chunk(doc, chunk, report, mod)
|
||||
occursin("2html", doc.doctype) && (embed_figures!(result, report.cwd))
|
||||
return result
|
||||
end
|
||||
|
||||
function embed_figures!(chunk::CodeChunk, cwd)
|
||||
for (i, fig) in enumerate(chunk.figures)
|
||||
chunk.figures[i] = img2base64(fig, cwd)
|
||||
end
|
||||
end
|
||||
embed_figures!(chunks, cwd) = embed_figures!.(chunks, Ref(cwd))
|
||||
|
||||
function img2base64(fig, cwd)
|
||||
ext = splitext(fig)[2]
|
||||
f = open(joinpath(cwd, fig), "r")
|
||||
raw = read(f)
|
||||
close(f)
|
||||
return ext == ".png" ? "data:image/png;base64," * stringmime(MIME("image/png"), raw) :
|
||||
ext == ".svg" ? "data:image/svg+xml;base64," * stringmime(MIME("image/svg"), raw) :
|
||||
ext == ".gif" ? "data:image/gif;base64," * stringmime(MIME("image/gif"), raw) :
|
||||
fig
|
||||
end
|
||||
|
||||
function run_chunk(chunk::DocChunk, doc, report, mod)
|
||||
chunk.content = [run_inline(c, doc, report, mod) for c in chunk.content]
|
||||
return chunk
|
||||
end
|
||||
|
||||
run_inline(inline::InlineText, ::WeaveDoc, ::Report, ::Module) = inline
|
||||
|
||||
const INLINE_OPTIONS = Dict(
|
||||
:term => false,
|
||||
:hold => true,
|
||||
:wrap => false
|
||||
)
|
||||
|
||||
function run_inline(inline::InlineCode, doc::WeaveDoc, report::Report, mod::Module)
|
||||
# Make a temporary CodeChunk for running code. Collect results and don't wrap
|
||||
chunk = CodeChunk(inline.content, 0, 0, "", INLINE_OPTIONS)
|
||||
options = merge(doc.chunk_defaults, chunk.options)
|
||||
merge!(chunk.options, options)
|
||||
|
||||
chunks = eval_chunk(doc, chunk, report, mod)
|
||||
occursin("2html", doc.doctype) && (embed_figures!(chunks, report.cwd))
|
||||
|
||||
output = chunks[1].output
|
||||
endswith(output, "\n") && (output = output[1:end-1])
|
||||
inline.output = output
|
||||
inline.rich_output = chunks[1].rich_output
|
||||
inline.figures = chunks[1].figures
|
||||
return inline
|
||||
end
|
||||
|
||||
function run_code(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module)
|
||||
code = chunk.content
|
||||
path = doc.path
|
||||
error = chunk.options[:error]
|
||||
codes = chunk.options[:term] ? split_code(code) : [code]
|
||||
capture = code -> capture_output(code, mod, path, error, report)
|
||||
return capture.(codes)
|
||||
end
|
||||
|
||||
function split_code(code)
|
||||
res = String[]
|
||||
e = 1
|
||||
ex = :init
|
||||
while true
|
||||
s = e
|
||||
ex, e = Meta.parse(code, s)
|
||||
isnothing(ex) && break
|
||||
push!(res, strip(code[s:e-1]))
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function capture_output(code, mod, path, error, report)
|
||||
reset_report!(report)
|
||||
|
||||
old = stdout
|
||||
rw, wr = redirect_stdout()
|
||||
reader = @async read(rw, String)
|
||||
|
||||
local out = nothing
|
||||
task_local_storage(:SOURCE_PATH, path) do
|
||||
try
|
||||
obj = include_string(mod, code, path) # TODO: fix line number
|
||||
!isnothing(obj) && !REPL.ends_with_semicolon(code) && display(obj)
|
||||
catch _err
|
||||
err = unwrap_load_err(_err)
|
||||
error || throw(err)
|
||||
display(err)
|
||||
@warn "ERROR: $(typeof(err)) occurred, including output in Weaved document"
|
||||
finally
|
||||
redirect_stdout(old)
|
||||
close(wr)
|
||||
out = fetch(reader)
|
||||
close(rw)
|
||||
end
|
||||
end
|
||||
|
||||
return ChunkOutput(code, remove_ansi_control_chars(out), report.rich_output, report.figures)
|
||||
end
|
||||
|
||||
function reset_report!(report)
|
||||
report.rich_output = ""
|
||||
report.figures = String[]
|
||||
end
|
||||
|
||||
unwrap_load_err(err) = return err
|
||||
unwrap_load_err(err::LoadError) = return err.error
|
||||
|
||||
# https://stackoverflow.com/a/33925425/12113178
|
||||
remove_ansi_control_chars(s) = replace(s, r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]" => "")
|
||||
|
||||
function eval_chunk(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module)
|
||||
if !chunk.options[:eval]
|
||||
chunk.output = ""
|
||||
chunk.options[:fig] = false
|
||||
return chunk
|
||||
end
|
||||
|
||||
execute_prehooks!(chunk)
|
||||
|
||||
report.fignum = 1
|
||||
report.cur_chunk = chunk
|
||||
|
||||
if hasproperty(report.format, :out_width) && isnothing(chunk.options[:out_width])
|
||||
chunk.options[:out_width] = report.format.out_width
|
||||
end
|
||||
|
||||
chunk.result = run_code(doc, chunk, report, mod)
|
||||
|
||||
execute_posthooks!(chunk)
|
||||
|
||||
return chunk.options[:term] ? collect_term_results(chunk) :
|
||||
chunk.options[:hold] ? collect_hold_results(chunk) :
|
||||
collect_results(chunk)
|
||||
end
|
||||
|
||||
# Hooks to run before and after chunks, this is form IJulia,
|
||||
const preexecution_hooks = Function[]
|
||||
push_preexecution_hook!(f::Function) = push!(preexecution_hooks, f)
|
||||
function pop_preexecution_hook!(f::Function)
|
||||
i = findfirst(x -> x == f, preexecution_hooks)
|
||||
isnothing(i) && error("this function has not been registered in the pre-execution hook yet")
|
||||
return splice!(preexecution_hooks, i)
|
||||
end
|
||||
function execute_prehooks!(chunk::CodeChunk)
|
||||
for prehook in preexecution_hooks
|
||||
Base.invokelatest(prehook, chunk)
|
||||
end
|
||||
end
|
||||
|
||||
const postexecution_hooks = Function[]
|
||||
push_postexecution_hook!(f::Function) = push!(postexecution_hooks, f)
|
||||
function pop_postexecution_hook!(f::Function)
|
||||
i = findfirst(x -> x == f, postexecution_hooks)
|
||||
isnothing(i) && error("this function has not been registered in the post-execution hook yet")
|
||||
return splice!(postexecution_hooks, i)
|
||||
end
|
||||
function execute_posthooks!(chunk::CodeChunk)
|
||||
for posthook in postexecution_hooks
|
||||
Base.invokelatest(posthook, chunk)
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
clear_module!(mod::Module)
|
||||
|
||||
Recursively sets variables in `mod` to `nothing` so that they're GCed.
|
||||
|
||||
!!! warning
|
||||
`const` variables can't be reassigned, as such they can't be cleared.
|
||||
"""
|
||||
function clear_module!(mod::Module)
|
||||
for name in names(mod; all = true)
|
||||
name === :eval && continue
|
||||
try
|
||||
v = getfield(mod, name)
|
||||
if v isa Module && v != mod
|
||||
clear_module!(v)
|
||||
continue
|
||||
end
|
||||
isconst(mod, name) && continue # can't clear constant
|
||||
Core.eval(mod, :($name = nothing))
|
||||
catch err
|
||||
@debug err
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function get_figname(report::Report, chunk; fignum = nothing, ext = nothing)
|
||||
isnothing(ext) && (ext = chunk.options[:fig_ext])
|
||||
isnothing(fignum) && (fignum = report.fignum)
|
||||
|
||||
chunkid = isnothing(chunk.options[:label]) ? chunk.number : chunk.options[:label]
|
||||
basename = string(report.basename, '_', chunkid, '_', fignum, ext)
|
||||
full_name = normpath(report.cwd, chunk.options[:fig_path], basename)
|
||||
rel_name = string(chunk.options[:fig_path], '/', basename) # Relative path is used in output
|
||||
return full_name, rel_name
|
||||
end
|
||||
|
||||
function set_rc_params(doc::WeaveDoc, fig_path, fig_ext)
|
||||
doc.chunk_defaults[:fig_ext] = isnothing(fig_ext) ? doc.format.fig_ext : fig_ext
|
||||
doc.chunk_defaults[:fig_path] = fig_path
|
||||
end
|
||||
|
||||
function collect_results(chunk::CodeChunk)
|
||||
content = ""
|
||||
result_chunks = CodeChunk[]
|
||||
for r in chunk.result
|
||||
content *= r.code
|
||||
# Check if there is any output from chunk
|
||||
if any(!isempty ∘ strip, (r.stdout, r.rich_output)) || !isempty(r.figures)
|
||||
rchunk = CodeChunk(
|
||||
content,
|
||||
chunk.number,
|
||||
chunk.start_line,
|
||||
chunk.optionstring,
|
||||
copy(chunk.options),
|
||||
)
|
||||
rchunk.output = r.stdout
|
||||
rchunk.rich_output = r.rich_output
|
||||
rchunk.figures = r.figures
|
||||
push!(result_chunks, rchunk)
|
||||
content = ""
|
||||
end
|
||||
end
|
||||
if !isempty(content)
|
||||
rchunk = CodeChunk(
|
||||
content,
|
||||
chunk.number,
|
||||
chunk.start_line,
|
||||
chunk.optionstring,
|
||||
copy(chunk.options),
|
||||
)
|
||||
push!(result_chunks, rchunk)
|
||||
end
|
||||
|
||||
return result_chunks
|
||||
end
|
||||
|
||||
function collect_term_results(chunk::CodeChunk)
|
||||
output = ""
|
||||
prompt = chunk.options[:prompt]
|
||||
result_chunks = CodeChunk[]
|
||||
for r in chunk.result
|
||||
output *= string('\n', indent_term_code(prompt, r.code), '\n', r.stdout)
|
||||
if !isempty(r.figures)
|
||||
rchunk = CodeChunk(
|
||||
"",
|
||||
chunk.number,
|
||||
chunk.start_line,
|
||||
chunk.optionstring,
|
||||
copy(chunk.options),
|
||||
)
|
||||
rchunk.output = output
|
||||
output = ""
|
||||
rchunk.figures = r.figures
|
||||
push!(result_chunks, rchunk)
|
||||
end
|
||||
end
|
||||
if !isempty(output)
|
||||
rchunk = CodeChunk(
|
||||
"",
|
||||
chunk.number,
|
||||
chunk.start_line,
|
||||
chunk.optionstring,
|
||||
copy(chunk.options),
|
||||
)
|
||||
rchunk.output = output
|
||||
push!(result_chunks, rchunk)
|
||||
end
|
||||
|
||||
return result_chunks
|
||||
end
|
||||
|
||||
function indent_term_code(prompt, code)
|
||||
prompt_with_space = string(prompt, ' ')
|
||||
n = length(prompt_with_space)
|
||||
pads = ' ' ^ n
|
||||
return map(enumerate(split(code, '\n'))) do (i,line)
|
||||
isone(i) ? string(prompt_with_space, line) : string(pads, line)
|
||||
end |> joinlines
|
||||
end
|
||||
|
||||
function collect_hold_results(chunk::CodeChunk)
|
||||
for r in chunk.result
|
||||
chunk.output *= r.stdout
|
||||
chunk.rich_output *= r.rich_output
|
||||
chunk.figures = [chunk.figures; r.figures]
|
||||
end
|
||||
return [chunk]
|
||||
end
|
||||
|
||||
const HEADER_INLINE = Regex("$(HEADER_INLINE_START)(?<code>.+)$(HEADER_INLINE_END)")
|
||||
|
||||
replace_header_inline!(doc, report, mod) = _replace_header_inline!(doc, doc.header, report, mod)
|
||||
|
||||
function _replace_header_inline!(doc, header, report, mod)
|
||||
replace!(header) do (k,v)
|
||||
return k =>
|
||||
v isa Dict ? _replace_header_inline!(doc, v, report, mod) :
|
||||
!isa(v, AbstractString) ? v :
|
||||
replace(v, HEADER_INLINE => s -> begin
|
||||
code = replace(s, HEADER_INLINE => s"\g<code>")
|
||||
run_inline_code(code, doc, report, mod)
|
||||
end)
|
||||
end
|
||||
return header
|
||||
end
|
||||
|
||||
function run_inline_code(code, doc, report, mod)
|
||||
inline = InlineCode(code, 1, :inline)
|
||||
inline = run_inline(inline, doc, report, mod)
|
||||
return strip(inline.output, '"')
|
||||
end
|
|
@ -0,0 +1,72 @@
|
|||
# TODO: concreate typing
|
||||
|
||||
abstract type WeaveChunk end
|
||||
abstract type Inline end
|
||||
abstract type WeaveFormat end
|
||||
|
||||
mutable struct WeaveDoc
|
||||
source::AbstractString
|
||||
basename::AbstractString
|
||||
path::AbstractString
|
||||
chunks::Vector{WeaveChunk}
|
||||
cwd::AbstractString
|
||||
format::Any
|
||||
doctype::String
|
||||
header_script::String
|
||||
header::Dict
|
||||
chunk_defaults::Dict{Symbol,Any}
|
||||
end
|
||||
|
||||
struct ChunkOutput
|
||||
code::String
|
||||
stdout::String
|
||||
rich_output::String
|
||||
figures::Vector{String}
|
||||
end
|
||||
|
||||
mutable struct CodeChunk <: WeaveChunk
|
||||
content::String
|
||||
number::Int
|
||||
start_line::Int
|
||||
optionstring::String
|
||||
options::Dict{Symbol,Any}
|
||||
output::AbstractString
|
||||
rich_output::AbstractString
|
||||
figures::Vector{String}
|
||||
result::Vector{ChunkOutput}
|
||||
end
|
||||
|
||||
function CodeChunk(content, number, start_line, optionstring, options)
|
||||
return CodeChunk(
|
||||
string(rstrip(content), '\n'), # normalize end of chunk)
|
||||
number,
|
||||
start_line,
|
||||
optionstring,
|
||||
options,
|
||||
"",
|
||||
"",
|
||||
AbstractString[],
|
||||
ChunkOutput[]
|
||||
)
|
||||
end
|
||||
|
||||
mutable struct DocChunk <: WeaveChunk
|
||||
content::Vector{Inline}
|
||||
number::Int
|
||||
start_line::Int
|
||||
end
|
||||
|
||||
struct InlineText <: Inline
|
||||
content::String
|
||||
number::Int
|
||||
end
|
||||
|
||||
mutable struct InlineCode <: Inline
|
||||
content::String
|
||||
number::Int
|
||||
ctype::Symbol
|
||||
output::String
|
||||
rich_output::String
|
||||
figures::Vector{String}
|
||||
end
|
||||
InlineCode(content, number, ctype) = InlineCode(content, number, ctype, "", "", String[])
|
|
@ -1,35 +0,0 @@
|
|||
import Winston
|
||||
|
||||
function Base.display(report::Report, m::MIME"image/png", data)
|
||||
|
||||
chunk = report.cur_chunk
|
||||
full_name, rel_name = get_figname(report, chunk)
|
||||
|
||||
docformat = formats[report.formatdict[:doctype]]
|
||||
|
||||
#Add to results for term chunks and store otherwise
|
||||
if chunk[:term]
|
||||
chunk[:figure] = [rel_name]
|
||||
|
||||
if report.term_state == :text
|
||||
report.cur_result *= "\n" * report.formatdict[:codeend] * "\n"
|
||||
end
|
||||
|
||||
report.cur_result *= formatfigures(chunk, docformat)
|
||||
report.term_state = :fig
|
||||
chunk[:figure] = String[]
|
||||
else
|
||||
push!(report.figures, rel_name)
|
||||
end
|
||||
|
||||
vector_fmts = [".pdf", ".svg"]
|
||||
|
||||
#Don't use dpi for vector formats
|
||||
if chunk[:fig_ext] in vector_fmts
|
||||
Winston.savefig(data, full_name, width=chunk[:fig_width]*100, height=chunk[:fig_height]*100)
|
||||
else
|
||||
Winston.savefig(data, full_name, width=chunk[:fig_width]*chunk[:dpi], height=chunk[:fig_height]*chunk[:dpi])
|
||||
end
|
||||
|
||||
report.fignum += 1
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
function write_doc(docformat::LaTeX2PDF, doc, rendered, out_path)
|
||||
cd_back = let d = pwd(); () -> cd(d); end
|
||||
cd(doc.cwd)
|
||||
try
|
||||
tex_path = basename(out_path)
|
||||
write(tex_path, rendered)
|
||||
cmds = copy(docformat.latex_cmd)
|
||||
push!(cmds, tex_path)
|
||||
cmd = Cmd(cmds)
|
||||
run(cmd); run(cmd) # XXX: is twice enough for every case ?
|
||||
catch
|
||||
@warn "Error converting document to pdf. Try running latex manually"
|
||||
rethrow()
|
||||
finally
|
||||
cd_back()
|
||||
end
|
||||
|
||||
return get_out_path(doc, out_path, "pdf")
|
||||
end
|
|
@ -0,0 +1,76 @@
|
|||
function write_doc(docformat::Pandoc2HTML, doc, rendered, out_path)
|
||||
_, weave_source = splitdir(abspath(doc.source))
|
||||
weave_version, weave_date = weave_info()
|
||||
|
||||
# Header is inserted from displayed plots
|
||||
header_script = doc.header_script
|
||||
self_contained = (header_script ≠ "") ? [] : "--self-contained"
|
||||
|
||||
if haskey(doc.header, "bibliography")
|
||||
filt = "--filter"
|
||||
citeproc = "pandoc-citeproc"
|
||||
else
|
||||
filt = []
|
||||
citeproc = []
|
||||
end
|
||||
|
||||
out_path = get_out_path(doc, out_path, "html")
|
||||
cd_back = let d = pwd(); () -> cd(d); end
|
||||
cd(dirname(out_path))
|
||||
try
|
||||
out = basename(out_path)
|
||||
highlight_stylesheet = get_highlight_stylesheet(MIME("text/html"), docformat.highlight_theme)
|
||||
cmd = `pandoc -f markdown+raw_html -s --mathjax=""
|
||||
$filt $citeproc $(docformat.pandoc_options)
|
||||
--template $(docformat.template_path)
|
||||
-H $(docformat.stylesheet_path)
|
||||
$(self_contained)
|
||||
-V highlight_stylesheet=$(highlight_stylesheet)
|
||||
-V weave_version=$(weave_version)
|
||||
-V weave_date=$(weave_date)
|
||||
-V weave_source=$(weave_source)
|
||||
-V headerscript=$(header_script)
|
||||
-o $(out)`
|
||||
proc = open(cmd, "r+")
|
||||
println(proc.in, rendered)
|
||||
close(proc.in)
|
||||
proc_output = read(proc.out, String)
|
||||
catch
|
||||
rethrow() # TODO: just show error content instead of rethrow the err
|
||||
finally
|
||||
cd_back()
|
||||
end
|
||||
|
||||
return out_path
|
||||
end
|
||||
|
||||
function write_doc(docformat::Pandoc2PDF, doc, rendered, out_path)
|
||||
if haskey(doc.header, "bibliography")
|
||||
filt = "--filter"
|
||||
citeproc = "pandoc-citeproc"
|
||||
else
|
||||
filt = []
|
||||
citeproc = []
|
||||
end
|
||||
|
||||
out_path = get_out_path(doc, out_path, "pdf")
|
||||
cd_back = let d = pwd(); () -> cd(d); end
|
||||
cd(dirname(out_path))
|
||||
try
|
||||
out = basename(out_path)
|
||||
cmd = `pandoc -f markdown+raw_tex -s --pdf-engine=xelatex --highlight-style=tango
|
||||
$filt $citeproc $(docformat.pandoc_options)
|
||||
--include-in-header=$(docformat.header_template)
|
||||
-o $(out)`
|
||||
proc = open(cmd, "r+")
|
||||
println(proc.in, rendered)
|
||||
close(proc.in)
|
||||
proc_output = read(proc.out, String)
|
||||
catch
|
||||
rethrow()
|
||||
finally
|
||||
cd_back()
|
||||
end
|
||||
|
||||
return out_path
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
function write_doc(doc, rendered, out_path)
|
||||
return write_doc(doc.format, doc, rendered, out_path)
|
||||
end
|
||||
|
||||
function write_doc(::WeaveFormat, doc, rendered, out_path)
|
||||
write(out_path, rendered)
|
||||
return out_path
|
||||
end
|
||||
|
||||
include("pandoc.jl")
|
||||
include("latex.jl")
|
|
@ -0,0 +1,550 @@
|
|||
<style type="text/css">
|
||||
@font-face {
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
}
|
||||
@font-face {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
}
|
||||
@font-face {
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
}
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
main,
|
||||
menu,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
display: inline-block; /* 1 */
|
||||
vertical-align: baseline; /* 2 */
|
||||
}
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
[hidden],
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
hr {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
}
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
color: inherit; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
button {
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
button[disabled],
|
||||
html input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
input[type="number"]::-webkit-inner-spin-button,
|
||||
input[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
table {
|
||||
font-family: monospace, monospace;
|
||||
font-size : 0.8em;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
td,
|
||||
th {
|
||||
padding: 0;
|
||||
}
|
||||
thead th {
|
||||
border-bottom: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
tr:nth-child(odd){
|
||||
background-color: rgb(248,248,248);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skeleton V2.0.4
|
||||
* Copyright 2014, Dave Gamache
|
||||
* www.getskeleton.com
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* 12/29/2014
|
||||
*/
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
box-sizing: border-box; }
|
||||
.column,
|
||||
.columns {
|
||||
width: 100%;
|
||||
float: left;
|
||||
box-sizing: border-box; }
|
||||
@media (min-width: 400px) {
|
||||
.container {
|
||||
width: 85%;
|
||||
padding: 0; }
|
||||
}
|
||||
@media (min-width: 550px) {
|
||||
.container {
|
||||
width: 80%; }
|
||||
.column,
|
||||
.columns {
|
||||
margin-left: 4%; }
|
||||
.column:first-child,
|
||||
.columns:first-child {
|
||||
margin-left: 0; }
|
||||
|
||||
.one.column,
|
||||
.one.columns { width: 4.66666666667%; }
|
||||
.two.columns { width: 13.3333333333%; }
|
||||
.three.columns { width: 22%; }
|
||||
.four.columns { width: 30.6666666667%; }
|
||||
.five.columns { width: 39.3333333333%; }
|
||||
.six.columns { width: 48%; }
|
||||
.seven.columns { width: 56.6666666667%; }
|
||||
.eight.columns { width: 65.3333333333%; }
|
||||
.nine.columns { width: 74.0%; }
|
||||
.ten.columns { width: 82.6666666667%; }
|
||||
.eleven.columns { width: 91.3333333333%; }
|
||||
.twelve.columns { width: 100%; margin-left: 0; }
|
||||
|
||||
.one-third.column { width: 30.6666666667%; }
|
||||
.two-thirds.column { width: 65.3333333333%; }
|
||||
|
||||
.one-half.column { width: 48%; }
|
||||
|
||||
/* Offsets */
|
||||
.offset-by-one.column,
|
||||
.offset-by-one.columns { margin-left: 8.66666666667%; }
|
||||
.offset-by-two.column,
|
||||
.offset-by-two.columns { margin-left: 17.3333333333%; }
|
||||
.offset-by-three.column,
|
||||
.offset-by-three.columns { margin-left: 26%; }
|
||||
.offset-by-four.column,
|
||||
.offset-by-four.columns { margin-left: 34.6666666667%; }
|
||||
.offset-by-five.column,
|
||||
.offset-by-five.columns { margin-left: 43.3333333333%; }
|
||||
.offset-by-six.column,
|
||||
.offset-by-six.columns { margin-left: 52%; }
|
||||
.offset-by-seven.column,
|
||||
.offset-by-seven.columns { margin-left: 60.6666666667%; }
|
||||
.offset-by-eight.column,
|
||||
.offset-by-eight.columns { margin-left: 69.3333333333%; }
|
||||
.offset-by-nine.column,
|
||||
.offset-by-nine.columns { margin-left: 78.0%; }
|
||||
.offset-by-ten.column,
|
||||
.offset-by-ten.columns { margin-left: 86.6666666667%; }
|
||||
.offset-by-eleven.column,
|
||||
.offset-by-eleven.columns { margin-left: 95.3333333333%; }
|
||||
|
||||
.offset-by-one-third.column,
|
||||
.offset-by-one-third.columns { margin-left: 34.6666666667%; }
|
||||
.offset-by-two-thirds.column,
|
||||
.offset-by-two-thirds.columns { margin-left: 69.3333333333%; }
|
||||
|
||||
.offset-by-one-half.column,
|
||||
.offset-by-one-half.columns { margin-left: 52%; }
|
||||
|
||||
}
|
||||
html {
|
||||
font-size: 62.5%; }
|
||||
body {
|
||||
font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #222; }
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 2rem;
|
||||
font-weight: 300; }
|
||||
h1 { font-size: 3.6rem; line-height: 1.2; letter-spacing: -.1rem;}
|
||||
h2 { font-size: 3.4rem; line-height: 1.25; letter-spacing: -.1rem; }
|
||||
h3 { font-size: 3.2rem; line-height: 1.3; letter-spacing: -.1rem; }
|
||||
h4 { font-size: 2.8rem; line-height: 1.35; letter-spacing: -.08rem; }
|
||||
h5 { font-size: 2.4rem; line-height: 1.5; letter-spacing: -.05rem; }
|
||||
h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; }
|
||||
|
||||
p {
|
||||
margin-top: 0; }
|
||||
a {
|
||||
color: #1EAEDB; }
|
||||
a:hover {
|
||||
color: #0FA0CE; }
|
||||
.button,
|
||||
button,
|
||||
input[type="submit"],
|
||||
input[type="reset"],
|
||||
input[type="button"] {
|
||||
display: inline-block;
|
||||
height: 38px;
|
||||
padding: 0 30px;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 38px;
|
||||
letter-spacing: .1rem;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
background-color: transparent;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #bbb;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box; }
|
||||
.button:hover,
|
||||
button:hover,
|
||||
input[type="submit"]:hover,
|
||||
input[type="reset"]:hover,
|
||||
input[type="button"]:hover,
|
||||
.button:focus,
|
||||
button:focus,
|
||||
input[type="submit"]:focus,
|
||||
input[type="reset"]:focus,
|
||||
input[type="button"]:focus {
|
||||
color: #333;
|
||||
border-color: #888;
|
||||
outline: 0; }
|
||||
.button.button-primary,
|
||||
button.button-primary,
|
||||
input[type="submit"].button-primary,
|
||||
input[type="reset"].button-primary,
|
||||
input[type="button"].button-primary {
|
||||
color: #FFF;
|
||||
background-color: #33C3F0;
|
||||
border-color: #33C3F0; }
|
||||
.button.button-primary:hover,
|
||||
button.button-primary:hover,
|
||||
input[type="submit"].button-primary:hover,
|
||||
input[type="reset"].button-primary:hover,
|
||||
input[type="button"].button-primary:hover,
|
||||
.button.button-primary:focus,
|
||||
button.button-primary:focus,
|
||||
input[type="submit"].button-primary:focus,
|
||||
input[type="reset"].button-primary:focus,
|
||||
input[type="button"].button-primary:focus {
|
||||
color: #FFF;
|
||||
background-color: #1EAEDB;
|
||||
border-color: #1EAEDB; }
|
||||
input[type="email"],
|
||||
input[type="number"],
|
||||
input[type="search"],
|
||||
input[type="text"],
|
||||
input[type="tel"],
|
||||
input[type="url"],
|
||||
input[type="password"],
|
||||
textarea,
|
||||
select {
|
||||
height: 38px;
|
||||
padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
|
||||
background-color: #fff;
|
||||
border: 1px solid #D1D1D1;
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
box-sizing: border-box; }
|
||||
/* Removes awkward default styles on some inputs for iOS */
|
||||
input[type="email"],
|
||||
input[type="number"],
|
||||
input[type="search"],
|
||||
input[type="text"],
|
||||
input[type="tel"],
|
||||
input[type="url"],
|
||||
input[type="password"],
|
||||
textarea {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none; }
|
||||
textarea {
|
||||
min-height: 65px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px; }
|
||||
input[type="email"]:focus,
|
||||
input[type="number"]:focus,
|
||||
input[type="search"]:focus,
|
||||
input[type="text"]:focus,
|
||||
input[type="tel"]:focus,
|
||||
input[type="url"]:focus,
|
||||
input[type="password"]:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
border: 1px solid #33C3F0;
|
||||
outline: 0; }
|
||||
label,
|
||||
legend {
|
||||
display: block;
|
||||
margin-bottom: .5rem;
|
||||
font-weight: 600; }
|
||||
fieldset {
|
||||
padding: 0;
|
||||
border-width: 0; }
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
display: inline; }
|
||||
label > .label-body {
|
||||
display: inline-block;
|
||||
margin-left: .5rem;
|
||||
font-weight: normal; }
|
||||
ul {
|
||||
list-style: circle inside; }
|
||||
ol {
|
||||
list-style: decimal inside; }
|
||||
ol, ul {
|
||||
padding-left: 0;
|
||||
margin-top: 0; }
|
||||
ul ul,
|
||||
ul ol,
|
||||
ol ol,
|
||||
ol ul {
|
||||
margin: 1.5rem 0 1.5rem 3rem;
|
||||
font-size: 90%; }
|
||||
li {
|
||||
margin-bottom: 1rem; }
|
||||
th,
|
||||
td {
|
||||
padding: 12px 15px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #E1E1E1; }
|
||||
th:first-child,
|
||||
td:first-child {
|
||||
padding-left: 0; }
|
||||
th:last-child,
|
||||
td:last-child {
|
||||
padding-right: 0; }
|
||||
button,
|
||||
.button {
|
||||
margin-bottom: 1rem; }
|
||||
input,
|
||||
textarea,
|
||||
select,
|
||||
fieldset {
|
||||
margin-bottom: 1.5rem; }
|
||||
pre,
|
||||
blockquote,
|
||||
dl,
|
||||
figure,
|
||||
table,
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
form {
|
||||
margin-bottom: 2.5rem; }
|
||||
.u-full-width {
|
||||
width: 100%;
|
||||
box-sizing: border-box; }
|
||||
.u-max-full-width {
|
||||
max-width: 100%;
|
||||
box-sizing: border-box; }
|
||||
.u-pull-right {
|
||||
float: right; }
|
||||
.u-pull-left {
|
||||
float: left; }
|
||||
hr {
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 3.5rem;
|
||||
border-width: 0;
|
||||
border-top: 1px solid #E1E1E1; }
|
||||
.container:after,
|
||||
.row:after,
|
||||
.u-cf {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
padding: 9.5px;
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre.sourceCode.julia {
|
||||
display: block;
|
||||
padding: 9.5px;
|
||||
margin: 0 0 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre.julia-error {
|
||||
color : red
|
||||
}
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
}
|
||||
code {
|
||||
background-color: #ffffff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
code.sourceCode.julia {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 400px) {}
|
||||
@media (min-width: 550px) {}
|
||||
@media (min-width: 750px) {}
|
||||
@media (min-width: 1000px) {}
|
||||
@media (min-width: 1200px) {}
|
||||
|
||||
h1.title {margin-top : 20px}
|
||||
img {max-width : 100%}
|
||||
</style>
|
|
@ -0,0 +1,538 @@
|
|||
@font-face {
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
}
|
||||
@font-face {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
}
|
||||
@font-face {
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
}
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
main,
|
||||
menu,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
display: inline-block; /* 1 */
|
||||
vertical-align: baseline; /* 2 */
|
||||
}
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
[hidden],
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
hr {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
}
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
color: inherit; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
button {
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
button[disabled],
|
||||
html input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
input[type="number"]::-webkit-inner-spin-button,
|
||||
input[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
table {
|
||||
font-family: monospace, monospace;
|
||||
font-size : 0.8em;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
td,
|
||||
th {
|
||||
padding: 0;
|
||||
}
|
||||
thead th {
|
||||
border-bottom: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
tr:nth-child(odd){
|
||||
background-color: rgb(248,248,248);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Skeleton V2.0.4
|
||||
* Copyright 2014, Dave Gamache
|
||||
* www.getskeleton.com
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* 12/29/2014
|
||||
*/
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
box-sizing: border-box; }
|
||||
.column,
|
||||
.columns {
|
||||
width: 100%;
|
||||
float: left;
|
||||
box-sizing: border-box; }
|
||||
@media (min-width: 400px) {
|
||||
.container {
|
||||
width: 85%;
|
||||
padding: 0; }
|
||||
}
|
||||
@media (min-width: 550px) {
|
||||
.container {
|
||||
width: 80%; }
|
||||
.column,
|
||||
.columns {
|
||||
margin-left: 4%; }
|
||||
.column:first-child,
|
||||
.columns:first-child {
|
||||
margin-left: 0; }
|
||||
|
||||
.one.column,
|
||||
.one.columns { width: 4.66666666667%; }
|
||||
.two.columns { width: 13.3333333333%; }
|
||||
.three.columns { width: 22%; }
|
||||
.four.columns { width: 30.6666666667%; }
|
||||
.five.columns { width: 39.3333333333%; }
|
||||
.six.columns { width: 48%; }
|
||||
.seven.columns { width: 56.6666666667%; }
|
||||
.eight.columns { width: 65.3333333333%; }
|
||||
.nine.columns { width: 74.0%; }
|
||||
.ten.columns { width: 82.6666666667%; }
|
||||
.eleven.columns { width: 91.3333333333%; }
|
||||
.twelve.columns { width: 100%; margin-left: 0; }
|
||||
|
||||
.one-third.column { width: 30.6666666667%; }
|
||||
.two-thirds.column { width: 65.3333333333%; }
|
||||
|
||||
.one-half.column { width: 48%; }
|
||||
|
||||
/* Offsets */
|
||||
.offset-by-one.column,
|
||||
.offset-by-one.columns { margin-left: 8.66666666667%; }
|
||||
.offset-by-two.column,
|
||||
.offset-by-two.columns { margin-left: 17.3333333333%; }
|
||||
.offset-by-three.column,
|
||||
.offset-by-three.columns { margin-left: 26%; }
|
||||
.offset-by-four.column,
|
||||
.offset-by-four.columns { margin-left: 34.6666666667%; }
|
||||
.offset-by-five.column,
|
||||
.offset-by-five.columns { margin-left: 43.3333333333%; }
|
||||
.offset-by-six.column,
|
||||
.offset-by-six.columns { margin-left: 52%; }
|
||||
.offset-by-seven.column,
|
||||
.offset-by-seven.columns { margin-left: 60.6666666667%; }
|
||||
.offset-by-eight.column,
|
||||
.offset-by-eight.columns { margin-left: 69.3333333333%; }
|
||||
.offset-by-nine.column,
|
||||
.offset-by-nine.columns { margin-left: 78.0%; }
|
||||
.offset-by-ten.column,
|
||||
.offset-by-ten.columns { margin-left: 86.6666666667%; }
|
||||
.offset-by-eleven.column,
|
||||
.offset-by-eleven.columns { margin-left: 95.3333333333%; }
|
||||
|
||||
.offset-by-one-third.column,
|
||||
.offset-by-one-third.columns { margin-left: 34.6666666667%; }
|
||||
.offset-by-two-thirds.column,
|
||||
.offset-by-two-thirds.columns { margin-left: 69.3333333333%; }
|
||||
|
||||
.offset-by-one-half.column,
|
||||
.offset-by-one-half.columns { margin-left: 52%; }
|
||||
|
||||
}
|
||||
html {
|
||||
font-size: 62.5%; }
|
||||
body {
|
||||
font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #222; }
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 2rem;
|
||||
font-weight: 300; }
|
||||
h1 { font-size: 3.6rem; line-height: 1.2; letter-spacing: -.1rem;}
|
||||
h2 { font-size: 3.4rem; line-height: 1.25; letter-spacing: -.1rem; }
|
||||
h3 { font-size: 3.2rem; line-height: 1.3; letter-spacing: -.1rem; }
|
||||
h4 { font-size: 2.8rem; line-height: 1.35; letter-spacing: -.08rem; }
|
||||
h5 { font-size: 2.4rem; line-height: 1.5; letter-spacing: -.05rem; }
|
||||
h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; }
|
||||
|
||||
p {
|
||||
margin-top: 0; }
|
||||
a {
|
||||
color: #1EAEDB; }
|
||||
a:hover {
|
||||
color: #0FA0CE; }
|
||||
.button,
|
||||
button,
|
||||
input[type="submit"],
|
||||
input[type="reset"],
|
||||
input[type="button"] {
|
||||
display: inline-block;
|
||||
height: 38px;
|
||||
padding: 0 30px;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 38px;
|
||||
letter-spacing: .1rem;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
background-color: transparent;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #bbb;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box; }
|
||||
.button:hover,
|
||||
button:hover,
|
||||
input[type="submit"]:hover,
|
||||
input[type="reset"]:hover,
|
||||
input[type="button"]:hover,
|
||||
.button:focus,
|
||||
button:focus,
|
||||
input[type="submit"]:focus,
|
||||
input[type="reset"]:focus,
|
||||
input[type="button"]:focus {
|
||||
color: #333;
|
||||
border-color: #888;
|
||||
outline: 0; }
|
||||
.button.button-primary,
|
||||
button.button-primary,
|
||||
input[type="submit"].button-primary,
|
||||
input[type="reset"].button-primary,
|
||||
input[type="button"].button-primary {
|
||||
color: #FFF;
|
||||
background-color: #33C3F0;
|
||||
border-color: #33C3F0; }
|
||||
.button.button-primary:hover,
|
||||
button.button-primary:hover,
|
||||
input[type="submit"].button-primary:hover,
|
||||
input[type="reset"].button-primary:hover,
|
||||
input[type="button"].button-primary:hover,
|
||||
.button.button-primary:focus,
|
||||
button.button-primary:focus,
|
||||
input[type="submit"].button-primary:focus,
|
||||
input[type="reset"].button-primary:focus,
|
||||
input[type="button"].button-primary:focus {
|
||||
color: #FFF;
|
||||
background-color: #1EAEDB;
|
||||
border-color: #1EAEDB; }
|
||||
input[type="email"],
|
||||
input[type="number"],
|
||||
input[type="search"],
|
||||
input[type="text"],
|
||||
input[type="tel"],
|
||||
input[type="url"],
|
||||
input[type="password"],
|
||||
textarea,
|
||||
select {
|
||||
height: 38px;
|
||||
padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
|
||||
background-color: #fff;
|
||||
border: 1px solid #D1D1D1;
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
box-sizing: border-box; }
|
||||
/* Removes awkward default styles on some inputs for iOS */
|
||||
input[type="email"],
|
||||
input[type="number"],
|
||||
input[type="search"],
|
||||
input[type="text"],
|
||||
input[type="tel"],
|
||||
input[type="url"],
|
||||
input[type="password"],
|
||||
textarea {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none; }
|
||||
textarea {
|
||||
min-height: 65px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px; }
|
||||
input[type="email"]:focus,
|
||||
input[type="number"]:focus,
|
||||
input[type="search"]:focus,
|
||||
input[type="text"]:focus,
|
||||
input[type="tel"]:focus,
|
||||
input[type="url"]:focus,
|
||||
input[type="password"]:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
border: 1px solid #33C3F0;
|
||||
outline: 0; }
|
||||
label,
|
||||
legend {
|
||||
display: block;
|
||||
margin-bottom: .5rem;
|
||||
font-weight: 600; }
|
||||
fieldset {
|
||||
padding: 0;
|
||||
border-width: 0; }
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
display: inline; }
|
||||
label > .label-body {
|
||||
display: inline-block;
|
||||
margin-left: .5rem;
|
||||
font-weight: normal; }
|
||||
ul {
|
||||
list-style: circle; }
|
||||
ol {
|
||||
list-style: decimal; }
|
||||
ul ul,
|
||||
ul ol,
|
||||
ol ol,
|
||||
ol ul {
|
||||
margin: 1.5rem 0 1.5rem 3rem;
|
||||
font-size: 90%; }
|
||||
li > p {margin : 0;}
|
||||
th,
|
||||
td {
|
||||
padding: 12px 15px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #E1E1E1; }
|
||||
th:first-child,
|
||||
td:first-child {
|
||||
padding-left: 0; }
|
||||
th:last-child,
|
||||
td:last-child {
|
||||
padding-right: 0; }
|
||||
button,
|
||||
.button {
|
||||
margin-bottom: 1rem; }
|
||||
input,
|
||||
textarea,
|
||||
select,
|
||||
fieldset {
|
||||
margin-bottom: 1.5rem; }
|
||||
pre,
|
||||
blockquote,
|
||||
dl,
|
||||
figure,
|
||||
table,
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
form {
|
||||
margin-bottom: 1.0rem; }
|
||||
.u-full-width {
|
||||
width: 100%;
|
||||
box-sizing: border-box; }
|
||||
.u-max-full-width {
|
||||
max-width: 100%;
|
||||
box-sizing: border-box; }
|
||||
.u-pull-right {
|
||||
float: right; }
|
||||
.u-pull-left {
|
||||
float: left; }
|
||||
hr {
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 3.5rem;
|
||||
border-width: 0;
|
||||
border-top: 1px solid #E1E1E1; }
|
||||
.container:after,
|
||||
.row:after,
|
||||
.u-cf {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
padding: 9.5px;
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
line-height: 1.42857143;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre.hljl {
|
||||
margin: 0 0 10px;
|
||||
display: block;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
padding : 5px;
|
||||
}
|
||||
|
||||
pre.output {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
pre.code {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
pre.julia-error {
|
||||
color : red
|
||||
}
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 400px) {}
|
||||
@media (min-width: 550px) {}
|
||||
@media (min-width: 750px) {}
|
||||
@media (min-width: 1000px) {}
|
||||
@media (min-width: 1200px) {}
|
||||
|
||||
h1.title {margin-top : 20px}
|
||||
img {max-width : 100%}
|
||||
div.title {text-align: center;}
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<HTML lang = "en">
|
||||
<HEAD>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
{{#:title}}<title>{{:title}}</title>{{/:title}}
|
||||
{{{ :header_script }}}
|
||||
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]},
|
||||
TeX: { equationNumbers: { autoNumber: "AMS" } }
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
||||
</script>
|
||||
|
||||
{{{ :highlight_stylesheet }}}
|
||||
|
||||
<style type="text/css">
|
||||
{{{ :stylesheet }}}
|
||||
</style>
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
<div class ="container">
|
||||
<div class = "row">
|
||||
<div class = "col-md-12 twelve columns">
|
||||
<div class="title">
|
||||
{{#:title}}<h1 class="title">{{:title}}</h1>{{/:title}}
|
||||
{{#:author}}<h5>{{{:author}}}</h5>{{/:author}}
|
||||
{{#:date}}<h5>{{{:date}}}</h5>{{/:date}}
|
||||
</div>
|
||||
|
||||
{{{ :body }}}
|
||||
|
||||
<HR/>
|
||||
<div class="footer">
|
||||
<p>
|
||||
Published from <a href="{{{:weave_source}}}">{{{:weave_source}}}</a>
|
||||
using <a href="http://github.com/JunoLab/Weave.jl">Weave.jl</a> {{:weave_version}} on {{:weave_date}}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BODY>
|
||||
|
||||
</HTML>
|
|
@ -0,0 +1,45 @@
|
|||
\documentclass[12pt,a4paper]{article}
|
||||
|
||||
\usepackage[a4paper,text={16.5cm,25.2cm},centering]{geometry}
|
||||
\usepackage{lmodern}
|
||||
\usepackage{amssymb,amsmath}
|
||||
\usepackage{bm}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{microtype}
|
||||
\usepackage{hyperref}
|
||||
{{#:tex_deps}}
|
||||
{{{ :tex_deps }}}
|
||||
{{/:tex_deps}}
|
||||
\setlength{\parindent}{0pt}
|
||||
\setlength{\parskip}{1.2ex}
|
||||
|
||||
\hypersetup
|
||||
{ pdfauthor = { {{{:author}}} },
|
||||
pdftitle={ {{{:title}}} },
|
||||
colorlinks=TRUE,
|
||||
linkcolor=black,
|
||||
citecolor=blue,
|
||||
urlcolor=blue
|
||||
}
|
||||
|
||||
{{#:title}}
|
||||
\title{ {{{ :title }}} }
|
||||
{{/:title}}
|
||||
|
||||
{{#:author}}
|
||||
\author{ {{{ :author }}} }
|
||||
{{/:author}}
|
||||
|
||||
{{#:date}}
|
||||
\date{ {{{ :date }}} }
|
||||
{{/:date}}
|
||||
|
||||
{{ :highlight }}
|
||||
|
||||
\begin{document}
|
||||
|
||||
{{#:title}}\maketitle{{/:title}}
|
||||
|
||||
{{{ :body }}}
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,96 @@
|
|||
<!DOCTYPE html>
|
||||
<html$if(lang)$ lang="$lang$"$endif$$if(dir)$ dir="$dir$"$endif$>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="pandoc">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
$for(author-meta)$
|
||||
<meta name="author" content="$author-meta$">
|
||||
$endfor$
|
||||
$if(date-meta)$
|
||||
<meta name="dcterms.date" content="$date-meta$">
|
||||
$endif$
|
||||
$if(keywords)$
|
||||
<meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$">
|
||||
$endif$
|
||||
<title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
|
||||
|
||||
<!-- TODO check if math works with plotly -->
|
||||
<!-- Need to load plotly before Mathjax or pandoc equations don't work -->
|
||||
$headerscript$
|
||||
|
||||
$if(math)$
|
||||
<script type="text/javascript">
|
||||
var fileref=document.createElement('script')
|
||||
fileref.setAttribute("type","text/javascript")
|
||||
fileref.setAttribute("src", "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML")
|
||||
document.getElementsByTagName("head")[0].appendChild(fileref)
|
||||
</script>
|
||||
$endif$
|
||||
|
||||
$for(header-includes)$
|
||||
$header-includes$
|
||||
$endfor$
|
||||
|
||||
$highlight_stylesheet$
|
||||
|
||||
$if(highlighting-css)$
|
||||
<style type="text/css">
|
||||
$highlighting-css$
|
||||
</style>
|
||||
$endif$
|
||||
|
||||
$for(css)$
|
||||
<link rel="stylesheet" href="$css$">
|
||||
$endfor$
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class ="container">
|
||||
<div class = "row">
|
||||
<div class = "col-md-12 twelve columns">
|
||||
|
||||
$for(include-before)$
|
||||
$include-before$
|
||||
$endfor$
|
||||
|
||||
$if(title)$
|
||||
|
||||
<h1 class="title">$title$</h1>
|
||||
$if(subtitle)$
|
||||
<h1 class="subtitle">$subtitle$</h1>
|
||||
$endif$
|
||||
|
||||
<p><strong>Author:</strong>
|
||||
$for(author)$
|
||||
$author$
|
||||
$endfor$
|
||||
<br/>
|
||||
|
||||
$if(date)$
|
||||
<strong>Date: </strong>$date$
|
||||
$endif$
|
||||
</p>
|
||||
$endif$
|
||||
|
||||
$if(toc)$
|
||||
<nav id="$idprefix$TOC">
|
||||
$toc$
|
||||
</nav>
|
||||
$endif$
|
||||
$body$
|
||||
$for(include-after)$
|
||||
$include-after$
|
||||
$endfor$
|
||||
|
||||
<HR/>
|
||||
<div class="footer"><p>
|
||||
Published from <a href="$source$">$source$</a> using
|
||||
<a href="http://github.com/mpastell/Weave.jl">Weave.jl</a> $weave_version$ on $weave_date$.
|
||||
<p></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
\usepackage[a4paper,text={16.5cm,25.2cm},centering]{geometry}
|
|
@ -0,0 +1,28 @@
|
|||
# Test if running document with and without cache works
|
||||
isdir("documents/cache") && rm("documents/cache", recursive = true)
|
||||
weave("documents/chunk_options.noweb", cache=:all)
|
||||
result = read("documents/chunk_options.md", String)
|
||||
rm("documents/chunk_options.md")
|
||||
weave("documents/chunk_options.noweb", cache=:all)
|
||||
cached_result = read("documents/chunk_options.md", String)
|
||||
@test result == cached_result
|
||||
|
||||
# cache = :user
|
||||
isdir("documents/cache") && rm("documents/cache", recursive = true)
|
||||
out = "documents/chunk_cache.md"
|
||||
Weave.weave("documents/chunk_cache.noweb", cache=:user);
|
||||
result = read(out, String)
|
||||
rm(out)
|
||||
Weave.weave("documents/chunk_cache.noweb", cache=:user);
|
||||
cached_result = read(out, String)
|
||||
@test result == cached_result
|
||||
|
||||
# cache = :all
|
||||
isdir("documents/cache") && rm("documents/cache", recursive = true)
|
||||
out = "documents/chunk_cache.md"
|
||||
Weave.weave("documents/chunk_cache.noweb", cache=:all);
|
||||
result = read(out, String)
|
||||
rm(out)
|
||||
Weave.weave("documents/chunk_cache.noweb", cache=:all);
|
||||
cached_result = read(out, String)
|
||||
@test result == cached_result
|
|
@ -1,23 +0,0 @@
|
|||
using Weave
|
||||
using Base.Test
|
||||
|
||||
#Test chunk options and output formats
|
||||
weave("documents/chunk_options.noweb", plotlib=nothing)
|
||||
result = readall(open("documents/chunk_options.md"))
|
||||
ref = readall(open("documents/chunk_options_ref.md"))
|
||||
@test result == ref
|
||||
|
||||
weave("documents/chunk_options.noweb", doctype="tex", plotlib=nothing)
|
||||
result = readall(open("documents/chunk_options.tex"))
|
||||
ref = readall(open("documents/chunk_options_ref.tex"))
|
||||
@test result == ref
|
||||
|
||||
weave("documents/chunk_options.noweb", doctype="texminted", plotlib=nothing)
|
||||
result = readall(open("documents/chunk_options.tex"))
|
||||
ref = readall(open("documents/chunk_options_ref.texminted"))
|
||||
@test result == ref
|
||||
|
||||
weave("documents/chunk_options.noweb", doctype="rst", plotlib=nothing)
|
||||
result = readall(open("documents/chunk_options.rst"))
|
||||
ref = readall(open("documents/chunk_options_ref.rst"))
|
||||
@test result == ref
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
<<term=true>>=
|
||||
y= [2, 5, 12]
|
||||
@
|
||||
|
||||
Some text `j print(10)` and continues with another inline code `j y`.
|
||||
|
||||
<<term=true; cache=true>>=
|
||||
y= [2, 5, 12]
|
||||
@
|
||||
|
||||
|
||||
<<>>=
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
@
|
||||
|
||||
<<cache=true>>=
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
@
|
||||
|
||||
<<>>=
|
||||
y = 1:5
|
||||
println(y)
|
||||
@
|
||||
|
||||
`j y`
|
||||
|
||||
<<cache=true>>=
|
||||
y = 1:5
|
||||
println(y)
|
||||
@
|
||||
|
||||
Some text in the end
|
|
@ -0,0 +1,179 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y= [2, 5, 12]"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"x = [12, 10]\nprintln(y)\nprintln(x)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(\"Results without code\")\nprintln(x)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y = randn(5)\nprintln(\"Don't eval, but show code\")"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y = 1:5\nprintln(y)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"a = \"Don't print me\"\nprintln(a)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(\"No markup for results.\")"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Test wrapping:"
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
}
|
||||
],
|
||||
"nbformat_minor": 2,
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "0.5.0"
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "julia-0.5",
|
||||
"display_name": "Julia 0.5.0",
|
||||
"language": "julia"
|
||||
}
|
||||
},
|
||||
"nbformat": 4
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
#+ term=true
|
||||
|
||||
y= [2, 5, 12]
|
||||
|
||||
|
||||
#+ term=true
|
||||
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
|
||||
|
||||
#+
|
||||
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
|
||||
|
||||
#+ echo=false
|
||||
|
||||
println("Results without code")
|
||||
println(x)
|
||||
|
||||
|
||||
#+ eval=false; tangle=false
|
||||
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
|
||||
|
||||
#+
|
||||
|
||||
y = 1:5
|
||||
println(y)
|
||||
|
||||
|
||||
#+ results="hidden"
|
||||
|
||||
a = "Don't print me"
|
||||
println(a)
|
||||
|
||||
|
||||
#+ results="as_is"
|
||||
|
||||
println("No markup for results.")
|
||||
|
||||
#'
|
||||
#'
|
||||
#' Test wrapping:
|
||||
#'
|
||||
#+
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
#+ wrap=false
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
#+ line_width=60
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
|
@ -3,6 +3,12 @@
|
|||
y= [2, 5, 12]
|
||||
@
|
||||
|
||||
<<term=true>>=
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
@
|
||||
|
||||
<<>>=
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
|
@ -16,7 +22,7 @@ println(x)
|
|||
@
|
||||
|
||||
|
||||
<<eval=false>>=
|
||||
<<eval=false; tangle=false>>=
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
@
|
||||
|
@ -35,3 +41,17 @@ println(a)
|
|||
<<results="as_is">>=
|
||||
println("No markup for results.")
|
||||
@
|
||||
|
||||
Test wrapping:
|
||||
|
||||
<<>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
||||
|
||||
<<wrap=false>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
||||
|
||||
<<line_width=60>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
y= [2, 5, 12]
|
||||
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
|
||||
println("Results without code")
|
||||
println(x)
|
||||
|
||||
y = 1:5
|
||||
println(y)
|
||||
|
||||
a = "Don't print me"
|
||||
println(a)
|
||||
|
||||
println("No markup for results.")
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
println(collect(0:10:1000))
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
~~~~{.julia}
|
||||
julia> y= [2, 5, 12]
|
||||
3-element Array{Int64,1}:
|
||||
|
@ -11,55 +9,75 @@ julia> y= [2, 5, 12]
|
|||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
julia> x = 1:10
|
||||
1:10
|
||||
|
||||
julia> d = Dict("Weave" => "testing")
|
||||
Dict{String,String} with 1 entry:
|
||||
"Weave" => "testing"
|
||||
|
||||
julia> y = [2, 4 ,8]
|
||||
3-element Array{Int64,1}:
|
||||
2
|
||||
4
|
||||
8
|
||||
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~
|
||||
[2, 4, 8]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
println(x)
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
[2,5,12]
|
||||
[12,10]
|
||||
~~~~~~~~~~~~~
|
||||
~~~~
|
||||
[12, 10]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
~~~~
|
||||
Results without code
|
||||
[12,10]
|
||||
~~~~~~~~~~~~~
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
~~~~
|
||||
[12, 10]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
y = 1:5
|
||||
println(y)
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
~~~~
|
||||
1:5
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
@ -70,13 +88,61 @@ println(a)
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
println("No markup for results.")
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
No markup for results.
|
||||
|
||||
|
||||
|
||||
|
||||
Test wrapping:
|
||||
|
||||
~~~~{.julia}
|
||||
println(collect(0:10:1000))
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~
|
||||
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
|
||||
170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310,
|
||||
320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460,
|
||||
470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610,
|
||||
620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760,
|
||||
770, 780, 790, 800, 810, 820, 830, 840, 850, 860, 870, 880, 890, 900, 910,
|
||||
920, 930, 940, 950, 960, 970, 980, 990, 1000]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
println(collect(0:10:1000))
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~
|
||||
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760, 770, 780, 790, 800, 810, 820, 830, 840, 850, 860, 870, 880, 890, 900, 910, 920, 930, 940, 950, 960, 970, 980, 990, 1000]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
println(collect(0:10:1000))
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~
|
||||
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130,
|
||||
140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250,
|
||||
260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370,
|
||||
380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490,
|
||||
500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610,
|
||||
620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730,
|
||||
740, 750, 760, 770, 780, 790, 800, 810, 820, 830, 840, 850,
|
||||
860, 870, 880, 890, 900, 910, 920, 930, 940, 950, 960, 970,
|
||||
980, 990, 1000]
|
||||
~~~~
|
||||
|
||||
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
|
||||
|
||||
.. code-block:: julia
|
||||
|
||||
julia> y= [2, 5, 12]
|
||||
3-element Array{Int64,1}:
|
||||
2
|
||||
5
|
||||
12
|
||||
|
||||
julia> y= [2, 5, 12]
|
||||
3-element Array{Int64,1}:
|
||||
2
|
||||
5
|
||||
12
|
||||
|
||||
|
||||
|
||||
|
@ -18,13 +16,25 @@
|
|||
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
[2,5,12]
|
||||
|
||||
|
||||
|
||||
|
||||
.. code-block:: julia
|
||||
|
||||
println(x)
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
[12,10]
|
||||
|
||||
|
||||
|
@ -36,6 +46,12 @@
|
|||
::
|
||||
|
||||
Results without code
|
||||
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
[12,10]
|
||||
|
||||
|
||||
|
@ -86,6 +102,63 @@
|
|||
|
||||
|
||||
|
||||
|
||||
No markup for results.
|
||||
|
||||
|
||||
|
||||
|
||||
Test wrapping:
|
||||
|
||||
.. code-block:: julia
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,2
|
||||
10,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,
|
||||
400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580
|
||||
,590,600,610,620,630,640,650,660,670,680,690,700,710,720,730,740,750,760,77
|
||||
0,780,790,800,810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,9
|
||||
60,970,980,990,1000]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. code-block:: julia
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
|
||||
::
|
||||
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580,590,600,610,620,630,640,650,660,670,680,690,700,710,720,730,740,750,760,770,780,790,800,810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,960,970,980,990,1000]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. code-block:: julia
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,17
|
||||
0,180,190,200,210,220,230,240,250,260,270,280,290,300,310,32
|
||||
0,330,340,350,360,370,380,390,400,410,420,430,440,450,460,47
|
||||
0,480,490,500,510,520,530,540,550,560,570,580,590,600,610,62
|
||||
0,630,640,650,660,670,680,690,700,710,720,730,740,750,760,77
|
||||
0,780,790,800,810,820,830,840,850,860,870,880,890,900,910,92
|
||||
0,930,940,950,960,970,980,990,1000]
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
|
||||
|
||||
\begin{juliaterm}
|
||||
julia> y= [2, 5, 12]
|
||||
3-element Array{Int64,1}:
|
||||
2
|
||||
5
|
||||
12
|
||||
|
||||
\end{juliaterm}
|
||||
|
||||
|
||||
|
@ -14,10 +12,16 @@ julia> y= [2, 5, 12]
|
|||
\begin{juliacode}
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
|
||||
\end{juliacode}
|
||||
\begin{juliaout}
|
||||
[2,5,12]
|
||||
\end{juliaout}
|
||||
|
||||
\begin{juliacode}
|
||||
println(x)
|
||||
\end{juliacode}
|
||||
\begin{juliaout}
|
||||
[12,10]
|
||||
\end{juliaout}
|
||||
|
||||
|
@ -26,6 +30,9 @@ println(x)
|
|||
|
||||
\begin{juliaout}
|
||||
Results without code
|
||||
\end{juliaout}
|
||||
|
||||
\begin{juliaout}
|
||||
[12,10]
|
||||
\end{juliaout}
|
||||
|
||||
|
@ -59,6 +66,45 @@ println(a)
|
|||
\begin{juliacode}
|
||||
println("No markup for results.")
|
||||
\end{juliacode}
|
||||
|
||||
No markup for results.
|
||||
|
||||
|
||||
|
||||
|
||||
Test wrapping:
|
||||
|
||||
\begin{juliacode}
|
||||
println(collect(0:10:1000))
|
||||
\end{juliacode}
|
||||
\begin{juliaout}
|
||||
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,2
|
||||
10,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,
|
||||
400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580
|
||||
,590,600,610,620,630,640,650,660,670,680,690,700,710,720,730,740,750,760,77
|
||||
0,780,790,800,810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,9
|
||||
60,970,980,990,1000]
|
||||
\end{juliaout}
|
||||
|
||||
|
||||
|
||||
\begin{juliacode}
|
||||
println(collect(0:10:1000))
|
||||
\end{juliacode}
|
||||
\begin{juliaout}[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580,590,600,610,620,630,640,650,660,670,680,690,700,710,720,730,740,750,760,770,780,790,800,810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,960,970,980,990,1000]
|
||||
|
||||
\end{juliaout}
|
||||
|
||||
|
||||
|
||||
\begin{juliacode}
|
||||
println(collect(0:10:1000))
|
||||
\end{juliacode}
|
||||
\begin{juliaout}
|
||||
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,17
|
||||
0,180,190,200,210,220,230,240,250,260,270,280,290,300,310,32
|
||||
0,330,340,350,360,370,380,390,400,410,420,430,440,450,460,47
|
||||
0,480,490,500,510,520,530,540,550,560,570,580,590,600,610,62
|
||||
0,630,640,650,660,670,680,690,700,710,720,730,740,750,760,77
|
||||
0,780,790,800,810,820,830,840,850,860,870,880,890,900,910,92
|
||||
0,930,940,950,960,970,980,990,1000]
|
||||
\end{juliaout}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
|
||||
|
||||
\begin{minted}[fontsize=\footnotesize, xleftmargin=0.5em, mathescape]{julia}
|
||||
julia> y= [2, 5, 12]
|
||||
3-element Array{Int64,1}:
|
||||
2
|
||||
5
|
||||
12
|
||||
|
||||
\end{minted}
|
||||
|
||||
|
||||
|
@ -14,10 +12,16 @@ julia> y= [2, 5, 12]
|
|||
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
|
||||
\end{minted}
|
||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||
[2,5,12]
|
||||
\end{minted}
|
||||
|
||||
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
||||
println(x)
|
||||
\end{minted}
|
||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||
[12,10]
|
||||
\end{minted}
|
||||
|
||||
|
@ -26,6 +30,9 @@ println(x)
|
|||
|
||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||
Results without code
|
||||
\end{minted}
|
||||
|
||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||
[12,10]
|
||||
\end{minted}
|
||||
|
||||
|
@ -59,6 +66,45 @@ println(a)
|
|||
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
||||
println("No markup for results.")
|
||||
\end{minted}
|
||||
|
||||
No markup for results.
|
||||
|
||||
|
||||
|
||||
|
||||
Test wrapping:
|
||||
|
||||
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
||||
println(collect(0:10:1000))
|
||||
\end{minted}
|
||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,2
|
||||
10,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,
|
||||
400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580
|
||||
,590,600,610,620,630,640,650,660,670,680,690,700,710,720,730,740,750,760,77
|
||||
0,780,790,800,810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,9
|
||||
60,970,980,990,1000]
|
||||
\end{minted}
|
||||
|
||||
|
||||
|
||||
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
||||
println(collect(0:10:1000))
|
||||
\end{minted}
|
||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580,590,600,610,620,630,640,650,660,670,680,690,700,710,720,730,740,750,760,770,780,790,800,810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,960,970,980,990,1000]
|
||||
|
||||
\end{minted}
|
||||
|
||||
|
||||
|
||||
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
||||
println(collect(0:10:1000))
|
||||
\end{minted}
|
||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,17
|
||||
0,180,190,200,210,220,230,240,250,260,270,280,290,300,310,32
|
||||
0,330,340,350,360,370,380,390,400,410,420,430,440,450,460,47
|
||||
0,480,490,500,510,520,530,540,550,560,570,580,590,600,610,62
|
||||
0,630,640,650,660,670,680,690,700,710,720,730,740,750,760,77
|
||||
0,780,790,800,810,820,830,840,850,860,870,880,890,900,910,92
|
||||
0,930,940,950,960,970,980,990,1000]
|
||||
\end{minted}
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y= [2, 5, 12]"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"x = 1:10\nd = Dict(\"Weave\" => \"testing\")\ny = [2, 4 ,8]"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"x = [12, 10]\nprintln(y)\nprintln(x)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(\"Results without code\")\nprintln(x)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y = randn(5)\nprintln(\"Don't eval, but show code\")"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y = 1:5\nprintln(y)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"a = \"Don't print me\"\nprintln(a)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(\"No markup for results.\")"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Test wrapping:"
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
}
|
||||
],
|
||||
"nbformat_minor": 2,
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "0.5.0"
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "julia-0.5",
|
||||
"display_name": "Julia 0.5.0",
|
||||
"language": "julia"
|
||||
}
|
||||
},
|
||||
"nbformat": 4
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
#+ term=true
|
||||
|
||||
y= [2, 5, 12]
|
||||
|
||||
|
||||
#+ term=true
|
||||
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
|
||||
|
||||
#+
|
||||
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
|
||||
|
||||
#+ echo=false
|
||||
|
||||
println("Results without code")
|
||||
println(x)
|
||||
|
||||
|
||||
#+ eval=false; tangle=false
|
||||
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
|
||||
|
||||
#+
|
||||
|
||||
y = 1:5
|
||||
println(y)
|
||||
|
||||
|
||||
#+ results="hidden"
|
||||
|
||||
a = "Don't print me"
|
||||
println(a)
|
||||
|
||||
|
||||
#+ results="as_is"
|
||||
|
||||
println("No markup for results.")
|
||||
|
||||
#'
|
||||
#'
|
||||
#' Test wrapping:
|
||||
#'
|
||||
#+
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
#+ wrap=false
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
#+ line_width=60
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
```julia;term=true
|
||||
y= [2, 5, 12]
|
||||
```
|
||||
|
||||
```julia;term=true
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
```
|
||||
|
||||
```julia
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
```
|
||||
|
||||
```julia;echo=false
|
||||
println("Results without code")
|
||||
println(x)
|
||||
```
|
||||
|
||||
```julia;eval=false; tangle=false
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
```
|
||||
|
||||
```julia
|
||||
y = 1:5
|
||||
println(y)
|
||||
```
|
||||
|
||||
```julia;results="hidden"
|
||||
a = "Don't print me"
|
||||
println(a)
|
||||
```
|
||||
|
||||
```julia;results="as_is"
|
||||
println("No markup for results.")
|
||||
```
|
||||
|
||||
|
||||
Test wrapping:
|
||||
|
||||
```julia
|
||||
println(collect(0:10:1000))
|
||||
```
|
||||
|
||||
```julia;wrap=false
|
||||
println(collect(0:10:1000))
|
||||
```
|
||||
|
||||
```julia;line_width=60
|
||||
println(collect(0:10:1000))
|
||||
```
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
<<term=true>>=
|
||||
y= [2, 5, 12]
|
||||
@
|
||||
|
||||
<<term=true>>=
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
@
|
||||
|
||||
<<>>=
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
@
|
||||
|
||||
<<echo=false>>=
|
||||
println("Results without code")
|
||||
println(x)
|
||||
@
|
||||
|
||||
<<eval=false; tangle=false>>=
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
@
|
||||
|
||||
<<>>=
|
||||
y = 1:5
|
||||
println(y)
|
||||
@
|
||||
|
||||
<<results="hidden">>=
|
||||
a = "Don't print me"
|
||||
println(a)
|
||||
@
|
||||
|
||||
<<results="as_is">>=
|
||||
println("No markup for results.")
|
||||
@
|
||||
|
||||
|
||||
Test wrapping:
|
||||
|
||||
<<>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
||||
|
||||
<<wrap=false>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
||||
|
||||
<<line_width=60>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
|
||||
|
||||
<<>>=
|
||||
y= [2, 5, 12]
|
||||
@
|
||||
|
||||
|
||||
|
||||
<<>>=
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
@
|
||||
|
||||
|
||||
|
||||
<<>>=
|
||||
println("Results without code")
|
||||
println(x)
|
||||
@
|
||||
|
||||
|
||||
|
||||
<<>>=
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
@
|
||||
|
||||
|
||||
|
||||
<<>>=
|
||||
y = 1:5
|
||||
println(y)
|
||||
@
|
||||
|
||||
|
||||
|
||||
<<>>=
|
||||
a = "Don't print me"
|
||||
println(a)
|
||||
@
|
||||
|
||||
|
||||
|
||||
<<>>=
|
||||
println("No markup for results.")
|
||||
@
|
||||
|
||||
Test wrapping:
|
||||
|
||||
<<>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
||||
|
||||
|
||||
|
||||
<<>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
||||
|
||||
|
||||
|
||||
<<>>=
|
||||
println(collect(0:10:1000))
|
||||
@
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
|
||||
<<fig_cap="sin(x) function."; label="sin_fun"; fig_pos="ht">>=
|
||||
using Gadfly
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
@
|
||||
|
||||
<<echo=false; fig_cap="cos(x) function.">>=
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
@
|
||||
|
||||
<<echo=false; label="cos2_fun">>=
|
||||
plot(x=x, y = cos(2x), Geom.line)
|
||||
@
|
||||
|
||||
<<term=true;fig_width=5>>=
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
y = 20
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
@
|
||||
|
||||
<<out_width="15cm">>=
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
y = 20
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
@
|
|
@ -1,80 +0,0 @@
|
|||
|
||||
|
||||
|
||||
````julia
|
||||
using Gadfly
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
````
|
||||
|
||||
|
||||
![sin(x) function.](figures/gadfly_formats_test_sin_fun_1.js.svg)
|
||||
|
||||
|
||||
|
||||
![cos(x) function.](figures/gadfly_formats_test_2_1.js.svg)
|
||||
|
||||
|
||||
|
||||
![](figures/gadfly_formats_test_cos2_fun_1.js.svg)
|
||||
|
||||
|
||||
|
||||
````julia
|
||||
julia> x = linspace(0, 2π, 200)
|
||||
200-element Array{Float64,1}:
|
||||
0.0
|
||||
0.0315738
|
||||
0.0631476
|
||||
0.0947214
|
||||
0.126295
|
||||
0.157869
|
||||
0.189443
|
||||
0.221017
|
||||
0.25259
|
||||
0.284164
|
||||
⋮
|
||||
6.03059
|
||||
6.06217
|
||||
6.09374
|
||||
6.12532
|
||||
6.15689
|
||||
6.18846
|
||||
6.22004
|
||||
6.25161
|
||||
6.28319
|
||||
|
||||
julia> plot(x=x, y = sin(x), Geom.line)
|
||||
|
||||
````
|
||||
|
||||
|
||||
![](figures/gadfly_formats_test_4_1.js.svg)
|
||||
|
||||
|
||||
````julia
|
||||
julia> y = 20
|
||||
20
|
||||
|
||||
julia> plot(x=x, y = cos(x), Geom.line)
|
||||
|
||||
````
|
||||
|
||||
|
||||
![](figures/gadfly_formats_test_4_2.js.svg)
|
||||
|
||||
|
||||
|
||||
|
||||
````julia
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
y = 20
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
````
|
||||
|
||||
|
||||
![](figures/gadfly_formats_test_5_1.js.svg)
|
||||
![](figures/gadfly_formats_test_5_2.js.svg)
|
||||
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
using Gadfly
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
![sin(x) function.](figures/gadfly_formats_test_sin_fun_1.png)
|
||||
|
||||
|
||||
|
||||
![cos(x) function.](figures/gadfly_formats_test_2_1.png)
|
||||
|
||||
|
||||
|
||||
![](figures/gadfly_formats_test_cos2_fun_1.png)
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
julia> x = linspace(0, 2π, 200)
|
||||
200-element Array{Float64,1}:
|
||||
0.0
|
||||
0.0315738
|
||||
0.0631476
|
||||
0.0947214
|
||||
0.126295
|
||||
0.157869
|
||||
0.189443
|
||||
0.221017
|
||||
0.25259
|
||||
0.284164
|
||||
⋮
|
||||
6.03059
|
||||
6.06217
|
||||
6.09374
|
||||
6.12532
|
||||
6.15689
|
||||
6.18846
|
||||
6.22004
|
||||
6.25161
|
||||
6.28319
|
||||
|
||||
julia> plot(x=x, y = sin(x), Geom.line)
|
||||
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
![](figures/gadfly_formats_test_4_1.png)
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
julia> y = 20
|
||||
20
|
||||
|
||||
julia> plot(x=x, y = cos(x), Geom.line)
|
||||
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
![](figures/gadfly_formats_test_4_2.png)
|
||||
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
y = 20
|
||||
plot(x=x, y = cos(x), Geom.line)
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
![](figures/gadfly_formats_test_5_1.png)
|
||||
![](figures/gadfly_formats_test_5_2.png)
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue