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,22 +1,27 @@
|
||||||
|
Manifest.toml
|
||||||
|
|
||||||
src/*.cov
|
|
||||||
test.jl
|
|
||||||
examples/figures/
|
examples/figures/
|
||||||
examples/*.md
|
examples/*.md
|
||||||
examples/*.pdf
|
examples/*.pdf
|
||||||
examples/*.html
|
examples/*.html
|
||||||
examples/*.rst
|
examples/*.rst
|
||||||
examples/*.tex
|
examples/*.tex
|
||||||
test/documents/figures
|
test/**/cache
|
||||||
test/documents/*.tex
|
test/**/figures
|
||||||
test/documents/*.md
|
test/documents/output/gadfly_formats_test.txt
|
||||||
test/documents/*.rst
|
test/**/*.tex
|
||||||
test/documents/*.html
|
test/**/*.md
|
||||||
test/documents/*.pdf
|
test/**/*.rst
|
||||||
!test/documents/*ref.*
|
test/**/*.html
|
||||||
|
test/**/*.pdf
|
||||||
|
test/**/*.png
|
||||||
|
test/**/chunk_options.jl
|
||||||
|
test/**/*.ipynb
|
||||||
|
!test/**/*ref.*
|
||||||
|
|
||||||
|
doc/build
|
||||||
|
doc/site
|
||||||
|
|
||||||
tmp/
|
|
||||||
.idea
|
.idea
|
||||||
*.*~
|
*.*~
|
||||||
*.aux
|
*.aux
|
||||||
|
|
35
.travis.yml
35
.travis.yml
|
@ -1,25 +1,14 @@
|
||||||
language: cpp
|
language: julia
|
||||||
compiler:
|
|
||||||
- clang
|
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:
|
notifications:
|
||||||
email: false
|
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
|
||||||
> Permission is hereby granted, free of charge, to any person obtaining
|
"Software"), to deal in the Software without restriction, including
|
||||||
> a copy of this software and associated documentation files (the
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
> "Software"), to deal in the Software without restriction, including
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
> without limitation the rights to use, copy, modify, merge, publish,
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
> distribute, sublicense, and/or sell copies of the Software, and to
|
the following conditions:
|
||||||
> 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 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
|
||||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
> 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"]
|
124
README.md
124
README.md
|
@ -1,78 +1,104 @@
|
||||||
# Weave
|
# 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)
|
![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
|
Weave is a scientific report generator/literate programming tool for the [Julia programming language](https://julialang.org/).
|
||||||
for Julia. It resembles [Pweave](http://mpastell.com/pweave) and, Knitr
|
It resembles
|
||||||
and Sweave.
|
[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**
|
**Current features**
|
||||||
|
|
||||||
* Noweb or markdown syntax for input documents.
|
- Publish markdown directly to HTML and PDF using Julia or [Pandoc](https://pandoc.org/MANUAL.html)
|
||||||
* Execute code as terminal or "script" chunks.
|
- Execute code as in terminal or in a unit of code chunk
|
||||||
* Capture PyPlot, Gadfly or Winston figures.
|
- Capture [Plots.jl](https://github.com/JuliaPlots/Plots.jl) or [Gadfly.jl](https://github.com/GiovineItalia/Gadfly.jl) figures
|
||||||
* Supports LaTex, Pandoc and Github markdown and reStructuredText output
|
- 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)
|
||||||
|
|
||||||
|
|
||||||
## Chunk options
|
## Installation
|
||||||
|
|
||||||
I've tried to follow [Knitr](http://yihui.name/knitr/options)'s naming for chunk options, but not all options are implemented.
|
You can install the latest release using Julia package manager:
|
||||||
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.
|
```julia
|
||||||
|
using Pkg
|
||||||
<<term=true; fig_width=6; fig_height=4>>=
|
Pkg.add("Weave")
|
||||||
|
```
|
||||||
## 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
|
## Usage
|
||||||
|
|
||||||
Run from julia:
|
```julia
|
||||||
|
|
||||||
````julia
|
|
||||||
using Weave
|
using Weave
|
||||||
weave(Pkg.dir("Weave","examples","julia_sample.mdw")
|
|
||||||
````
|
|
||||||
|
|
||||||
Using Winston for plots (Julia 0.3 only):
|
# add depencies for the example
|
||||||
|
using Pkg; Pkg.add(["Plots", "DSP"])
|
||||||
|
|
||||||
````julia
|
filename = normpath(Weave.EXAMPLE_FOLDER, "FIR_design.jmd")
|
||||||
weave(Pkg.dir("Weave","examples","winston_sample.mdw"),
|
weave(filename, out_path = :pwd)
|
||||||
plotlib="Winston", doctype="pandoc")
|
```
|
||||||
````
|
|
||||||
|
|
||||||
Using Gadfly (Julia 0.3 only):
|
If you have LaTeX installed you can also weave directly to pdf.
|
||||||
|
|
||||||
````julia
|
```julia
|
||||||
weave(Pkg.dir("Weave","examples","gadfly_sample.mdw"), plotlib="Gadfly")
|
filename = normpath(Weave.EXAMPLE_FOLDER, "FIR_design.jmd")
|
||||||
````
|
weave(filename, out_path = :pwd, doctype = "md2pdf")
|
||||||
|
```
|
||||||
|
|
||||||
The signature of weave functions is:
|
NOTE: `Weave.EXAMPLE_FOLDER` just points to [`examples` directory](./examples).
|
||||||
|
|
||||||
````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.
|
## 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
|
## 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.
|
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
|
## Contributors
|
||||||
|
|
||||||
Douglas Bates has contributed a number of important fixes and comments.
|
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>>=
|
# Introduction
|
||||||
using Gadfly
|
|
||||||
x = linspace(0, 2π, 200)
|
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||||
plot(x=x, y = sin(x), Geom.line)
|
be executed using [Weave.jl](https://github.com/JunoLab/Weave.jl).
|
||||||
y = 20
|
|
||||||
plot(x=x, y = cos(x), Geom.line)
|
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)
|
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
|
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||||
be executed using Weave. Output from code chunks and PyPlot
|
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
|
This documented can be turned into Pandoc markdown with captured
|
||||||
result from Julia prompt.
|
result from Julia prompt.
|
||||||
|
@ -17,7 +17,7 @@ weave("examples/julia_sample.mdw")
|
||||||
|
|
||||||
<<term=true>>=
|
<<term=true>>=
|
||||||
x = 1:10
|
x = 1:10
|
||||||
d = {"Weave" => "testing"}
|
d = Dict("Weave" => "testing")
|
||||||
y = [2, 4 ,8]
|
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
|
595
src/Weave.jl
595
src/Weave.jl
|
@ -1,275 +1,344 @@
|
||||||
module Weave
|
module Weave
|
||||||
using Compat
|
|
||||||
|
|
||||||
#Contains report global properties
|
using Highlights, Mustache, Requires, Pkg, REPL, RelocatableFolders, Base64
|
||||||
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}
|
|
||||||
|
|
||||||
|
# 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()
|
# constant names
|
||||||
new("", false, "", "", Any[], "", "", 1, Any[], :text, @compat Dict{Symbol, Any}() )
|
const WEAVE_OPTION_NAME = "weave_options"
|
||||||
end
|
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"
|
||||||
|
|
||||||
end
|
const WEAVE_VERSION = try
|
||||||
|
'v' * Pkg.TOML.parsefile(normpath(PKG_DIR, "Project.toml"))["version"]
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
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
|
catch
|
||||||
options = rcParams[:chunk_defaults]
|
""
|
||||||
warn("Invalid format for chunk options line: $(chunk[:start_line])")
|
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
|
end
|
||||||
|
|
||||||
merge!(chunk, options)
|
# utilitity functions
|
||||||
delete!(chunk, :options)
|
take2string!(io) = String(take!(io))
|
||||||
|
joinlines(lines) = join(lines, '\n')
|
||||||
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)
|
include("types.jl")
|
||||||
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("config.jl")
|
include("config.jl")
|
||||||
include("readers.jl")
|
include("WeaveMarkdown/markdown.jl")
|
||||||
include("formatters.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
|
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
|
|
@ -1,77 +1,58 @@
|
||||||
const rcParams =
|
# TODO: follow RMarkdown convention more
|
||||||
@compat Dict{Symbol,Any}(:plotlib => "PyPlot",
|
const _DEFAULT_PARAMS = Dict{Symbol,Any}(
|
||||||
:storeresults => false,
|
|
||||||
:chunk_defaults =>
|
|
||||||
Dict{Symbol,Any}(
|
|
||||||
:echo => true,
|
:echo => true,
|
||||||
:results => "markup",
|
:results => "markup",
|
||||||
|
:hold => false,
|
||||||
:fig => true,
|
:fig => true,
|
||||||
:include=> true,
|
|
||||||
:eval => true,
|
:eval => true,
|
||||||
|
:error => true,
|
||||||
|
:tangle => true,
|
||||||
|
:cache => false,
|
||||||
:fig_cap => nothing,
|
:fig_cap => nothing,
|
||||||
#Size in inches
|
# NOTE: size in inches
|
||||||
:fig_width => 6,
|
:fig_width => 6,
|
||||||
:fig_height => 4,
|
:fig_height => 4,
|
||||||
:fig_path=> "figures",
|
:fig_path => DEFAULT_FIG_PATH,
|
||||||
:dpi => 96,
|
:dpi => 96,
|
||||||
:term => false,
|
:term => false,
|
||||||
:name=> nothing,
|
:prompt => "julia>",
|
||||||
|
:label => nothing,
|
||||||
:wrap => true,
|
:wrap => true,
|
||||||
:engine=> "julia",
|
:line_width => 75,
|
||||||
:option_string=> "",
|
|
||||||
#Defined in formats
|
|
||||||
:fig_ext => nothing,
|
:fig_ext => nothing,
|
||||||
:fig_pos => nothing,
|
:fig_pos => nothing,
|
||||||
:fig_env => nothing,
|
:fig_env => nothing,
|
||||||
:out_width => nothing,
|
:out_width => nothing,
|
||||||
:out_height => 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()
|
||||||
|
|
||||||
# Working towards Knitr compatible options, implemented options are
|
Get default options used for code chunks.
|
||||||
# added to defaultoptions dictionary above and work in progress stays here,
|
"""
|
||||||
# options from https://github.com/yihui/knitr/blob/master/R/defaults.R
|
get_chunk_defaults() = DEFAULT_PARAMS
|
||||||
# If you need a particular options, consider implementing it and making a
|
|
||||||
# pull request.
|
|
||||||
|
|
||||||
#tidy = FALSE,
|
"""
|
||||||
#tidy.opts = NULL,
|
restore_chunk_defaults!()
|
||||||
#collapse = FALSE
|
|
||||||
#prompt = FALSE
|
Restore Weave.jl default chunk options.
|
||||||
#highlight = TRUE
|
"""
|
||||||
#strip.white = TRUE
|
restore_chunk_defaults!() = for (k,v) in _DEFAULT_PARAMS; DEFAULT_PARAMS[k] = v; end
|
||||||
#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
|
|
||||||
|
|
|
@ -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
|
chunk = report.cur_chunk
|
||||||
|
|
||||||
#if chunk[:fig_ext] != ".png"
|
w = chunk.options[:fig_width] * Gadfly.inch
|
||||||
# chunk[:fig_ext]
|
h = chunk.options[:fig_height] * Gadfly.inch
|
||||||
# warn("Saving figures as .png with Gadfly")
|
format = chunk.options[:fig_ext]
|
||||||
#end
|
dpi = chunk.options[:dpi]
|
||||||
|
|
||||||
full_name, rel_name = get_figname(report, chunk)
|
full_name, rel_name = Weave.get_figname(report, chunk, ext = format)
|
||||||
|
|
||||||
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)
|
push!(report.figures, rel_name)
|
||||||
end
|
|
||||||
|
|
||||||
report.fignum += 1
|
report.fignum += 1
|
||||||
|
|
||||||
#TODO other formats
|
if format == ".svg"
|
||||||
#Can't specify dpi in Gadfly? Opened Gadfly issue #504
|
Gadfly.draw(Gadfly.SVG(full_name, w, h), p)
|
||||||
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)
|
|
||||||
elseif format == ".js.svg"
|
elseif format == ".js.svg"
|
||||||
draw(SVGJS(full_name, w, h), p)
|
Gadfly.draw(Gadfly.SVGJS(full_name, w, h), p)
|
||||||
else:
|
elseif format == ".png"
|
||||||
warn("Can't save figure. Unsupported format")
|
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
|
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]
|
y= [2, 5, 12]
|
||||||
@
|
@
|
||||||
|
|
||||||
|
<<term=true>>=
|
||||||
|
x = 1:10
|
||||||
|
d = Dict("Weave" => "testing")
|
||||||
|
y = [2, 4 ,8]
|
||||||
|
@
|
||||||
|
|
||||||
<<>>=
|
<<>>=
|
||||||
x = [12, 10]
|
x = [12, 10]
|
||||||
println(y)
|
println(y)
|
||||||
|
@ -16,7 +22,7 @@ println(x)
|
||||||
@
|
@
|
||||||
|
|
||||||
|
|
||||||
<<eval=false>>=
|
<<eval=false; tangle=false>>=
|
||||||
y = randn(5)
|
y = randn(5)
|
||||||
println("Don't eval, but show code")
|
println("Don't eval, but show code")
|
||||||
@
|
@
|
||||||
|
@ -35,3 +41,17 @@ println(a)
|
||||||
<<results="as_is">>=
|
<<results="as_is">>=
|
||||||
println("No markup for results.")
|
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}
|
||||||
julia> y= [2, 5, 12]
|
julia> y= [2, 5, 12]
|
||||||
3-element Array{Int64,1}:
|
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}
|
~~~~{.julia}
|
||||||
x = [12, 10]
|
x = [12, 10]
|
||||||
println(y)
|
println(y)
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
~~~~
|
||||||
|
[2, 4, 8]
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
~~~~{.julia}
|
||||||
println(x)
|
println(x)
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
~~~~{.julia}
|
~~~~
|
||||||
[2,5,12]
|
|
||||||
[12, 10]
|
[12, 10]
|
||||||
~~~~~~~~~~~~~
|
~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
|
||||||
~~~~{.julia}
|
|
||||||
Results without code
|
Results without code
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
~~~~
|
||||||
[12, 10]
|
[12, 10]
|
||||||
~~~~~~~~~~~~~
|
~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
~~~~{.julia}
|
~~~~{.julia}
|
||||||
|
|
||||||
y = randn(5)
|
y = randn(5)
|
||||||
println("Don't eval, but show code")
|
println("Don't eval, but show code")
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
~~~~{.julia}
|
~~~~{.julia}
|
||||||
y = 1:5
|
y = 1:5
|
||||||
println(y)
|
println(y)
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
~~~~{.julia}
|
~~~~
|
||||||
1:5
|
1:5
|
||||||
~~~~~~~~~~~~~
|
~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,13 +88,61 @@ println(a)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
~~~~{.julia}
|
~~~~{.julia}
|
||||||
println("No markup for results.")
|
println("No markup for results.")
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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,5 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: julia
|
.. code-block:: julia
|
||||||
|
|
||||||
julia> y= [2, 5, 12]
|
julia> y= [2, 5, 12]
|
||||||
|
@ -13,18 +12,29 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: julia
|
.. code-block:: julia
|
||||||
|
|
||||||
x = [12, 10]
|
x = [12, 10]
|
||||||
println(y)
|
println(y)
|
||||||
println(x)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
[2,5,12]
|
[2,5,12]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: julia
|
||||||
|
|
||||||
|
println(x)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
[12,10]
|
[12,10]
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +46,12 @@
|
||||||
::
|
::
|
||||||
|
|
||||||
Results without code
|
Results without code
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
[12,10]
|
[12,10]
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,6 +102,63 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
No markup for results.
|
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}
|
\begin{juliaterm}
|
||||||
julia> y= [2, 5, 12]
|
julia> y= [2, 5, 12]
|
||||||
3-element Array{Int64,1}:
|
3-element Array{Int64,1}:
|
||||||
2
|
2
|
||||||
5
|
5
|
||||||
12
|
12
|
||||||
|
|
||||||
\end{juliaterm}
|
\end{juliaterm}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,10 +12,16 @@ julia> y= [2, 5, 12]
|
||||||
\begin{juliacode}
|
\begin{juliacode}
|
||||||
x = [12, 10]
|
x = [12, 10]
|
||||||
println(y)
|
println(y)
|
||||||
println(x)
|
|
||||||
\end{juliacode}
|
\end{juliacode}
|
||||||
\begin{juliaout}
|
\begin{juliaout}
|
||||||
[2,5,12]
|
[2,5,12]
|
||||||
|
\end{juliaout}
|
||||||
|
|
||||||
|
\begin{juliacode}
|
||||||
|
println(x)
|
||||||
|
\end{juliacode}
|
||||||
|
\begin{juliaout}
|
||||||
[12,10]
|
[12,10]
|
||||||
\end{juliaout}
|
\end{juliaout}
|
||||||
|
|
||||||
|
@ -26,6 +30,9 @@ println(x)
|
||||||
|
|
||||||
\begin{juliaout}
|
\begin{juliaout}
|
||||||
Results without code
|
Results without code
|
||||||
|
\end{juliaout}
|
||||||
|
|
||||||
|
\begin{juliaout}
|
||||||
[12,10]
|
[12,10]
|
||||||
\end{juliaout}
|
\end{juliaout}
|
||||||
|
|
||||||
|
@ -59,6 +66,45 @@ println(a)
|
||||||
\begin{juliacode}
|
\begin{juliacode}
|
||||||
println("No markup for results.")
|
println("No markup for results.")
|
||||||
\end{juliacode}
|
\end{juliacode}
|
||||||
|
|
||||||
No markup for results.
|
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}
|
\begin{minted}[fontsize=\footnotesize, xleftmargin=0.5em, mathescape]{julia}
|
||||||
julia> y= [2, 5, 12]
|
julia> y= [2, 5, 12]
|
||||||
3-element Array{Int64,1}:
|
3-element Array{Int64,1}:
|
||||||
2
|
2
|
||||||
5
|
5
|
||||||
12
|
12
|
||||||
|
|
||||||
\end{minted}
|
\end{minted}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,10 +12,16 @@ julia> y= [2, 5, 12]
|
||||||
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
||||||
x = [12, 10]
|
x = [12, 10]
|
||||||
println(y)
|
println(y)
|
||||||
println(x)
|
|
||||||
\end{minted}
|
\end{minted}
|
||||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||||
[2,5,12]
|
[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]
|
[12,10]
|
||||||
\end{minted}
|
\end{minted}
|
||||||
|
|
||||||
|
@ -26,6 +30,9 @@ println(x)
|
||||||
|
|
||||||
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||||
Results without code
|
Results without code
|
||||||
|
\end{minted}
|
||||||
|
|
||||||
|
\begin{minted}[fontsize=\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}
|
||||||
[12,10]
|
[12,10]
|
||||||
\end{minted}
|
\end{minted}
|
||||||
|
|
||||||
|
@ -59,6 +66,45 @@ println(a)
|
||||||
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
\begin{minted}[mathescape, fontsize=\small, xleftmargin=0.5em]{julia}
|
||||||
println("No markup for results.")
|
println("No markup for results.")
|
||||||
\end{minted}
|
\end{minted}
|
||||||
|
|
||||||
No markup for results.
|
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