mirror of https://github.com/mpastell/Weave.jl
Compare commits
744 Commits
Author | SHA1 | Date |
---|---|---|
Sebastian Pfitzner | 77793c775c | |
Sheehan Olver | ad0885ce00 | |
Sebastian Pfitzner | e10aaefd94 | |
Sebastian Pfitzner | 8ad4e876d3 | |
Sebastian Pfitzner | af2a6e14c9 | |
Sebastian Pfitzner | 20aaefec0a | |
Gerhard Aigner | 2a78676d41 | |
Gerhard Aigner | 59332c1768 | |
Sebastian Pfitzner | db28a69d94 | |
Sheehan Olver | 0b96591f39 | |
Sebastian Pfitzner | a38cec95db | |
Sebastian Pfitzner | 562f8e4ab3 | |
Sebastian Pfitzner | 9f666b3bb5 | |
KristofferC | a63577f69c | |
Xing Shi Cai | 7e0f5641c2 | |
Nicholas W. M. Ritchie | b022a54458 | |
Nicholas W. M. Ritchie | b669a14038 | |
Sebastian Pfitzner | b7941c2811 | |
ExpandingMan | d40e95a4bb | |
xgdgsc | df47ea191f | |
Sebastian Pfitzner | 381de22c7d | |
github-actions[bot] | 06b259a7b0 | |
Sebastian Pfitzner | 749c0c262c | |
Sebastian Pfitzner | 696db1d82b | |
Mike | d4c65729e4 | |
Mike | 1dfb8d76d6 | |
Sebastian Pfitzner | 48c99c791f | |
Sebastian Pfitzner | ec3f464c37 | |
Mike | 4c60bd8d64 | |
Sebastian Pfitzner | e1d31c2ef6 | |
Shuhei Kadowaki | 99916dd70c | |
Sebastian Pfitzner | 6b6f82bed4 | |
Shuhei Kadowaki | b1de7efede | |
Nathan Hattersley | 849cc20e88 | |
Shuhei Kadowaki | 10de1057a3 | |
Shuhei Kadowaki | e753f70f7a | |
PGunnink | 8dc0441b90 | |
Shuhei Kadowaki | c9fc740d72 | |
Shuhei Kadowaki | cc5913e812 | |
JonasIsensee | e02d5ce2fd | |
Shuhei Kadowaki | b583ac2e40 | |
Shuhei Kadowaki | 955675d89a | |
Shuhei Kadowaki | 196d4ca7ce | |
Shuhei Kadowaki | d3a7f2aea7 | |
Shuhei Kadowaki | 7d361bb40d | |
Shuhei Kadowaki | e927495a62 | |
Shuhei Kadowaki | 78befc61b5 | |
Shuhei Kadowaki | c24a262135 | |
Shuhei Kadowaki | 3e8200c2f8 | |
Shuhei Kadowaki | 8f23084471 | |
Shuhei Kadowaki | a1830e0502 | |
Shuhei Kadowaki | 0e662ecdec | |
Fredrik Bagge Carlson | fa71830479 | |
Shuhei Kadowaki | 21d7fbdbea | |
Shuhei Kadowaki | fe3711074b | |
Tor Erlend Fjelde | 766847ec65 | |
Shuhei Kadowaki | 46a0f8bff4 | |
Oscar Dowson | 51f905ca83 | |
Sebastian Pfitzner | b5ba227e75 | |
Sebastian Pfitzner | 74768a7e0f | |
Jonas Isensee | 90d8c8430f | |
Jonas Isensee | a61ade7778 | |
Jonas Isensee | 8ac94989f1 | |
Jonas Isensee | 191282c1e5 | |
Shuhei Kadowaki | d8eca00fd8 | |
Shuhei Kadowaki | 957d12e751 | |
Shuhei Kadowaki | 82c7c2a8c6 | |
Shuhei Kadowaki | ba5bc9ca08 | |
Shuhei Kadowaki | 5f0d9d4627 | |
Shuhei Kadowaki | 676ecc64f9 | |
Shuhei Kadowaki | 2a509d8f96 | |
Shuhei Kadowaki | 9b2a1228cd | |
Shuhei Kadowaki | 785768c728 | |
Shuhei Kadowaki | 7e9c4fb99d | |
Shuhei Kadowaki | 29546b7716 | |
Shuhei Kadowaki | db5308b286 | |
Shuhei Kadowaki | 174585e504 | |
Shuhei Kadowaki | 8206ca2d14 | |
Shuhei Kadowaki | 092adb6805 | |
Shuhei Kadowaki | 872f7c7153 | |
Shuhei Kadowaki | 5ae1fd5cf1 | |
Shuhei Kadowaki | bd447ec8e3 | |
Jonas Isensee | 3dfe817584 | |
Jonas Isensee | 12e148af18 | |
Shuhei Kadowaki | 03079a5dac | |
Shuhei Kadowaki | e179bd098e | |
Shuhei Kadowaki | 4a96f2c19a | |
Shuhei Kadowaki | 7955308a0a | |
Shuhei Kadowaki | 21835644a0 | |
Shuhei Kadowaki | 5a585f845a | |
Shuhei Kadowaki | f077609798 | |
Shuhei Kadowaki | 46a0da597d | |
Shuhei Kadowaki | 2070610a58 | |
Shuhei Kadowaki | 7d6fddc749 | |
Shuhei Kadowaki | dadce5110c | |
Shuhei Kadowaki | 5d3dd15733 | |
Shuhei Kadowaki | 608bb3df4a | |
Shuhei Kadowaki | b569740915 | |
Shuhei Kadowaki | 972869da47 | |
Shuhei Kadowaki | e0a9d044cd | |
Shuhei Kadowaki | 912387c331 | |
Jonas Isensee | 1135c5ddfa | |
Shuhei Kadowaki | c1bc2fd5c5 | |
Shuhei Kadowaki | d586c24792 | |
Shuhei Kadowaki | d468912332 | |
Shuhei Kadowaki | 753afe24d7 | |
Shuhei Kadowaki | c0e7e66ec3 | |
Shuhei Kadowaki | fd07d2db3f | |
Shuhei Kadowaki | 8d95e159e2 | |
Shuhei Kadowaki | 9fac56f681 | |
Shuhei Kadowaki | b709ce8aef | |
Shuhei Kadowaki | 4a89b04759 | |
Shuhei Kadowaki | ec986b387b | |
Jonas Isensee | 5c853150c8 | |
Shuhei Kadowaki | f8b1c5104b | |
Shuhei Kadowaki | d88675d521 | |
Shuhei Kadowaki | e52c30f72e | |
Shuhei Kadowaki | 66c33e6679 | |
Shuhei Kadowaki | cdd653e028 | |
Shuhei Kadowaki | 8515c0dcde | |
Shuhei Kadowaki | 3a7cb360af | |
Shuhei Kadowaki | c7b566aaaa | |
Jonas Isensee | 630ac466e7 | |
Shuhei Kadowaki | 3e6cda8950 | |
Shuhei Kadowaki | f1d8838bc5 | |
Shuhei Kadowaki | 3faa8e2d95 | |
Shuhei Kadowaki | 3ddb1375eb | |
Shuhei Kadowaki | 73bf7fe77f | |
Shuhei Kadowaki | 533667b9ad | |
Shuhei Kadowaki | aa7fd311d8 | |
Shuhei Kadowaki | 0760591021 | |
Shuhei Kadowaki | 04b24ea83b | |
Shuhei Kadowaki | 4b12f3da99 | |
Shuhei Kadowaki | c6b23d4541 | |
Shuhei Kadowaki | ae48729cff | |
Shuhei Kadowaki | 19b4a7974f | |
Shuhei Kadowaki | 0bdab33630 | |
Shuhei Kadowaki | 55d2c975cd | |
Shuhei Kadowaki | ae0dc70ffa | |
Jonas Isensee | 543f99a915 | |
Jonas Isensee | b5477d27ff | |
Jonas Isensee | 9875bc10f7 | |
Jonas Isensee | 45adb8992f | |
Jonas Isensee | 3eba5de7f4 | |
Jonas Isensee | 62d56846f4 | |
Jonas Isensee | 770496b3af | |
Jonas Isensee | 6e99822905 | |
Jonas Isensee | 119b3332aa | |
Shuhei Kadowaki | 9ccf3a2c5e | |
Shuhei Kadowaki | db89118b4c | |
Shuhei Kadowaki | e7637de643 | |
Shuhei Kadowaki | e0e9ae8753 | |
Shuhei Kadowaki | 5b959a972c | |
Shuhei Kadowaki | 788f926067 | |
Fredrik Bagge Carlson | c87782f451 | |
Shuhei Kadowaki | 96de887308 | |
Shuhei Kadowaki | aa63b20e7c | |
Shuhei Kadowaki | cc936f5377 | |
Shuhei Kadowaki | f4ed10b625 | |
Shuhei Kadowaki | 2fdd09b585 | |
Jonas Isensee | e20042848d | |
Shuhei Kadowaki | 1e9ba19db4 | |
Shuhei Kadowaki | 14b56f1667 | |
Shuhei Kadowaki | 227ab2cbf8 | |
Shuhei Kadowaki | 84e91104d5 | |
Shuhei Kadowaki | 44ed8788d5 | |
Shuhei Kadowaki | 022bb216eb | |
Shuhei Kadowaki | e43a2843af | |
Shuhei Kadowaki | bb4ebb105e | |
Shuhei Kadowaki | b0db8b991c | |
Shuhei Kadowaki | dd0c51b6e5 | |
Shuhei Kadowaki | 3d4f04902c | |
Shuhei Kadowaki | e9c9274896 | |
Shuhei Kadowaki | 542f3e3225 | |
Shuhei Kadowaki | 976d822f58 | |
Shuhei Kadowaki | 819079c0f6 | |
Shuhei Kadowaki | b62a744dfe | |
Shuhei Kadowaki | eca4ed2559 | |
Shuhei Kadowaki | 9b55d7e924 | |
Shuhei Kadowaki | 0fc915b748 | |
Shuhei Kadowaki | 39d3d8d91c | |
Shuhei Kadowaki | 125d73982e | |
Shuhei Kadowaki | 0bc0d3b510 | |
Shuhei Kadowaki | b8b9b095b7 | |
Shuhei Kadowaki | 48adeff932 | |
Shuhei Kadowaki | a7de8f5f58 | |
Shuhei Kadowaki | 60fc450c88 | |
Shuhei Kadowaki | 1fb40645ed | |
Shuhei Kadowaki | 9ca328f468 | |
Shuhei Kadowaki | d84504267b | |
Shuhei Kadowaki | 29ff436a00 | |
Shuhei Kadowaki | c24920870d | |
Shuhei Kadowaki | f4caba1561 | |
Shuhei Kadowaki | 3c76b804dc | |
Shuhei Kadowaki | f71a491847 | |
Shuhei Kadowaki | af45cc01ab | |
Shuhei Kadowaki | 31f670b74c | |
Shuhei Kadowaki | 0cdcc72bfb | |
Shuhei Kadowaki | 3ee7dec864 | |
Shuhei Kadowaki | 0f94c7b49c | |
Shuhei Kadowaki | 54ccd9b1ed | |
Shuhei Kadowaki | 3f4ba672b3 | |
Shuhei Kadowaki | 745abe176c | |
Shuhei Kadowaki | 301f9b2f27 | |
Shuhei Kadowaki | ef295e9a24 | |
Shuhei Kadowaki | a03a1d4c34 | |
Shuhei Kadowaki | daec0e618f | |
Shuhei Kadowaki | 129a654b1d | |
Shuhei Kadowaki | 500d77c9ca | |
Shuhei Kadowaki | 8aa8f0c4df | |
Shuhei Kadowaki | ec0c0a327f | |
Shuhei Kadowaki | b4c2bbea45 | |
Shuhei Kadowaki | 5e5cb875cf | |
Shuhei Kadowaki | 576ca2b6c9 | |
Shuhei Kadowaki | 4113402908 | |
Shuhei Kadowaki | 249c94a5c1 | |
Shuhei Kadowaki | 101b170ea6 | |
Shuhei Kadowaki | 6d1732247a | |
Shuhei Kadowaki | b7233b468e | |
Shuhei Kadowaki | 405deb3681 | |
Shuhei Kadowaki | 87ba87d2d1 | |
Shuhei Kadowaki | cec388e94f | |
Shuhei Kadowaki | 0831144393 | |
Shuhei Kadowaki | e60f066d31 | |
Shuhei Kadowaki | f86f5a7bd0 | |
Shuhei Kadowaki | f9daa3a289 | |
Shuhei Kadowaki | 91403b4ec0 | |
Shuhei Kadowaki | 5fb3fae741 | |
Shuhei Kadowaki | 7b53eb8e9e | |
Shuhei Kadowaki | 58bc741b7f | |
Shuhei Kadowaki | a740ba3556 | |
Shuhei Kadowaki | bca3ee7dd1 | |
Shuhei Kadowaki | ba8e9f4724 | |
Shuhei Kadowaki | 6121d21bfb | |
Shuhei Kadowaki | 99a50ad86f | |
Shuhei Kadowaki | 2a6ee38850 | |
Shuhei Kadowaki | 11c720ad7f | |
Shuhei Kadowaki | c1cf566c53 | |
Shuhei Kadowaki | 0d3d3a8c19 | |
Shuhei Kadowaki | 6d91ab6512 | |
Shuhei Kadowaki | 98abd5e92e | |
Shuhei Kadowaki | 6100083c9e | |
Shuhei Kadowaki | 6955ca6be2 | |
Shuhei Kadowaki | 17c2151d86 | |
Shuhei Kadowaki | 492d1f330b | |
Shuhei Kadowaki | 95c3dac962 | |
Shuhei Kadowaki | 42115e7d52 | |
Shuhei Kadowaki | 094ebea6cf | |
Shuhei Kadowaki | 7c2eb23bcd | |
Shuhei Kadowaki | 589e1ce3d1 | |
Shuhei Kadowaki | 1ddff9a1b7 | |
Shuhei Kadowaki | 636e3540c7 | |
Shuhei Kadowaki | bc0f687352 | |
Shuhei Kadowaki | 2c7f3da7cc | |
Shuhei Kadowaki | 423146f981 | |
Shuhei Kadowaki | 2e19930565 | |
Shuhei Kadowaki | de2a6657ea | |
Shuhei Kadowaki | 867ad7c954 | |
Shuhei Kadowaki | 54e50a54cb | |
Shuhei Kadowaki | d809ddf703 | |
Shuhei Kadowaki | e459bfb87d | |
Shuhei Kadowaki | 98e44db659 | |
Shuhei Kadowaki | ede31bcf74 | |
Shuhei Kadowaki | e89d5da250 | |
Shuhei Kadowaki | 4b6fc2d913 | |
Shuhei Kadowaki | c825076e36 | |
Shuhei Kadowaki | 68f72bdfb3 | |
Shuhei Kadowaki | ca42e09f8d | |
Shuhei Kadowaki | a526cb8f15 | |
Shuhei Kadowaki | f1df02c2b7 | |
Shuhei Kadowaki | 4dae2a0816 | |
Shuhei Kadowaki | 8303311d59 | |
Shuhei Kadowaki | 36bdd4f82b | |
Shuhei Kadowaki | 5f7cf529b9 | |
Shuhei Kadowaki | 66d32fabe8 | |
Shuhei Kadowaki | 750b7624e0 | |
Shuhei Kadowaki | 8b910c0d70 | |
Shuhei Kadowaki | 3b8201df04 | |
Shuhei Kadowaki | 79579053f1 | |
Shuhei Kadowaki | d4413a1d78 | |
Shuhei Kadowaki | 5dbe54316b | |
Shuhei Kadowaki | e41202d3ff | |
Shuhei Kadowaki | 14e7635458 | |
Shuhei Kadowaki | ac486c5e1d | |
Shuhei Kadowaki | 9a1b81a026 | |
Shuhei Kadowaki | 4e7fda212d | |
Shuhei Kadowaki | b25300b269 | |
Shuhei Kadowaki | 0c59e92fd7 | |
Shuhei Kadowaki | 2376a9dae9 | |
Shuhei Kadowaki | 020b4353a4 | |
Shuhei Kadowaki | 36bce9cf1f | |
Shuhei Kadowaki | db13be44e3 | |
Shuhei Kadowaki | 95e32c4908 | |
Shuhei Kadowaki | 8bbe31324f | |
Fredrik Bagge Carlson | f126e1c7a9 | |
Fredrik Bagge Carlson | 7e88052db3 | |
Shuhei Kadowaki | 67126a515a | |
Shuhei Kadowaki | 3a3385471b | |
Shuhei Kadowaki | 20fd22ec75 | |
Shuhei Kadowaki | f1e87123f4 | |
Shuhei Kadowaki | d40e21ea35 | |
Shuhei Kadowaki | a759dc10bd | |
Shuhei Kadowaki | b6b4082977 | |
Shuhei Kadowaki | 840f1b3b8f | |
Shuhei Kadowaki | efccb5c7f1 | |
Shuhei Kadowaki | dfb9e63d0e | |
Shuhei Kadowaki | 9e9fe45231 | |
Shuhei Kadowaki | 7a7d8f3dde | |
Shuhei Kadowaki | f8c32c865b | |
Shuhei Kadowaki | 529edaf94e | |
Shuhei Kadowaki | e1365ba9b5 | |
Shuhei Kadowaki | 16bc2d7be9 | |
Shuhei Kadowaki | 545baecdaa | |
Shuhei Kadowaki | 6339303569 | |
Shuhei Kadowaki | 62ae84d32d | |
Shuhei Kadowaki | 1f8514a737 | |
Shuhei Kadowaki | 5fd0bcb9ee | |
Shuhei Kadowaki | 47323b37f7 | |
Shuhei Kadowaki | d8595e266f | |
Shuhei Kadowaki | 230a8c5454 | |
Shuhei Kadowaki | db0aa06f38 | |
Shuhei Kadowaki | 32bddc543f | |
Shuhei Kadowaki | 0f5e3df9aa | |
Shuhei Kadowaki | deeb54dc7c | |
Shuhei Kadowaki | 372974e1ad | |
Sebastian Pfitzner | 7c58a284ee | |
Sebastian Pfitzner | 04ed58102d | |
github-actions[bot] | a250a48499 | |
github-actions[bot] | ae8812de51 | |
Dave Kleinschmidt | 9ae54c80d6 | |
Dave Kleinschmidt | 048603ffe6 | |
Sebastian Pfitzner | ab5db9aa24 | |
Shuhei Kadowaki | c020fea642 | |
Shuhei Kadowaki | 2aa7cb7ca5 | |
Shuhei Kadowaki | 4dfa7da71f | |
Shuhei Kadowaki | 4cfcc61fb6 | |
Shuhei Kadowaki | d9b37f8244 | |
Sebastian Pfitzner | 79a3d73882 | |
Shuhei Kadowaki | d4ce8cdb6b | |
Sebastian Pfitzner | d108e4a1dc | |
Julia TagBot | fd216ca1f5 | |
aviatesk | e18c5f35e3 | |
aviatesk | d0ecc30f52 | |
aviatesk | 6ca6c51ea6 | |
aviatesk | 652b19cd0f | |
Sebastian Pfitzner | 72e7ccfe8a | |
Amin Yahyaabadi | a64fccbf2c | |
Sebastian Pfitzner | 585c4111b6 | |
Sebastian Pech | 05c93b8607 | |
Sebastian Pfitzner | 3d673d0338 | |
Sebastian Pech | c9e26d5638 | |
Sebastian Pech | 0018f0e24c | |
Sebastian Pech | da66a8f272 | |
Sebastian Pfitzner | d31d16581b | |
evalparse | 31d3c2da56 | |
Sebastian Pfitzner | b01b18ea2f | |
Sebastian Pech | bd5ff7031c | |
Sebastian Pfitzner | 9fa28726ed | |
MatFi | 4fcee4d0e2 | |
Sebastian Pfitzner | 3be6245820 | |
Sebastian Pech | fa4a1a629d | |
Sebastian Pech | 1b450b9e3d | |
Sebastian Pech | eeb723981d | |
Sebastian Pech | 474cb6e4b2 | |
Tamas Nagy | 51903c3df3 | |
Sebastian Pech | 4d7a444246 | |
Tamas Nagy | e7e5bd7c7f | |
David Widmann | 18cce8472b | |
Kevin Bonham | 36464be927 | |
ilia-kats | 02134d29d5 | |
Viral B. Shah | 59edca786d | |
Sebastian Pfitzner | ed41be610a | |
Tommy Hofmann | 1c0506342e | |
Sebastian Pfitzner | 9f664ba5a6 | |
Tamas Nagy | 9e462a480b | |
Tamas Nagy | df7f0d1f3c | |
Arnav Sood | 5d3e05511e | |
Tamas Nagy | 6621920bec | |
David Anthoff | 975a67ad44 | |
Konstantinos Samaras-Tsakiris | ea1de0fb9e | |
tshort | bd69ef1f59 | |
Matti Pastell | c9a814759d | |
Matti Pastell | 95e860816c | |
Matti Pastell | 99db6a9406 | |
Matti Pastell | 8194c8a1b8 | |
Matti Pastell | 83e2e0ae20 | |
Matti Pastell | 35addd2b50 | |
Matti Pastell | c33309abf6 | |
Matti Pastell | 4338fc4b07 | |
Matti Pastell | 6f83f1abf5 | |
Matti Pastell | 3488af5534 | |
Matti Pastell | 4ab1c09b8c | |
Matti Pastell | e7a10eacdc | |
Matti Pastell | 37aa0237a8 | |
Matti Pastell | 371cec474f | |
Matti Pastell | 1de36fd1f5 | |
Matti Pastell | 4e70d32901 | |
Matti Pastell | 700e00b329 | |
Matti Pastell | 6082786f92 | |
Matti Pastell | 52f3a23d28 | |
Matti Pastell | d62172ad88 | |
Matti Pastell | 6510ea0556 | |
Matti Pastell | efec59cdbf | |
Matti Pastell | ecb66471a3 | |
Matti Pastell | e9ea54bc1b | |
Matti Pastell | a14b7a8f80 | |
Matti Pastell | 0332137000 | |
Matti Pastell | edd558de0e | |
Matti Pastell | badaaa7dea | |
Matti Pastell | 710b67ca45 | |
Matti Pastell | f2773376d9 | |
Matti Pastell | 6a30aa20f2 | |
Matti Pastell | 73584edd34 | |
Matti Pastell | 8d1bb63b0a | |
Matti Pastell | e52083c42a | |
Matti Pastell | 73536707dc | |
Matti Pastell | 056db5141a | |
Matti Pastell | bad5650027 | |
Matti Pastell | 12f829a0ca | |
Toby Driscoll | 26cf943d25 | |
Matti Pastell | 6e0daf9335 | |
Matti Pastell | 7587b4f9cf | |
Matti Pastell | cb791e8b69 | |
Christopher Rackauckas | 73f0e1e998 | |
schrimpf | adf7338f34 | |
Matti Pastell | 1e630ed825 | |
Matti Pastell | f1a85d3726 | |
Matti Pastell | 972937e4a0 | |
Matti Pastell | 4a7d63bc7e | |
Tamas Nagy | caf64b2407 | |
Dave Kleinschmidt | 4bf8e0e209 | |
Matti Pastell | 0a21a2ec90 | |
Matti Pastell | 36339a07ff | |
Dave Kleinschmidt | d0c71ba556 | |
Matti Pastell | 921b9ec2ba | |
schrimpf | ab09bddcd8 | |
Matti Pastell | bf57bf8a07 | |
Matti Pastell | 6d0779ca4d | |
Matti Pastell | 246f7eef62 | |
Matti Pastell | 73e9e71c3a | |
Matti Pastell | aa4ba7ed52 | |
Matti Pastell | b41b4b4d41 | |
Matti Pastell | af7a6779a5 | |
Matti Pastell | ecc02dcd55 | |
Matti Pastell | d0a2291aa8 | |
Matti Pastell | 9aa01e4b89 | |
Matti Pastell | 2508268500 | |
Matti Pastell | 6217f4fb72 | |
Matti Pastell | c72b7e7668 | |
Matti Pastell | 2dbb5cc696 | |
Matti Pastell | 341edd3784 | |
Matti Pastell | 4cd0b92792 | |
Matti Pastell | 3fc3e3c6e0 | |
Matti Pastell | 3c81cd5bf2 | |
Matti Pastell | 28428e0832 | |
Matti Pastell | a5ba74dcd1 | |
Matti Pastell | 347ddbc45c | |
Matti Pastell | 89e990b1dd | |
Matti Pastell | 5c803db6ae | |
Matti Pastell | bb350ab334 | |
Matti Pastell | bd5e1d9a3b | |
Matti Pastell | 160017b6e8 | |
Matti Pastell | 44455a1fda | |
Matti Pastell | 973274bf22 | |
Matti Pastell | 93bb9ced2d | |
Matti Pastell | f90547cee6 | |
Matti Pastell | b136fa615d | |
Matti Pastell | b5e02cad36 | |
Matti Pastell | e5d2045350 | |
Matti Pastell | 373f5e9d37 | |
Matti Pastell | d72734a828 | |
Matti Pastell | ac26ffe271 | |
Matti Pastell | 7c091ed034 | |
Matti Pastell | 4523b3a58e | |
Matti Pastell | 57724aff67 | |
Matti Pastell | e6cea19d5e | |
Matti Pastell | 0956ce6dff | |
Matti Pastell | 83c506252d | |
Matti Pastell | 7a2150430d | |
Matti Pastell | 01f8810bc3 | |
Matti Pastell | f8978eb560 | |
Matti Pastell | fb854a1d63 | |
femtocleaner[bot] | f04b67f69b | |
Matti Pastell | 53d76a61bb | |
Dave Kleinschmidt | 6ff3bee3e8 | |
Tom Short | 5e1d8c1976 | |
Matti Pastell | 53c2a337f3 | |
Dave Kleinschmidt | b4ebf0cd16 | |
Matti Pastell | ce43dea594 | |
Matti Pastell | 8ab0d66dda | |
Matti Pastell | 1341aed3d0 | |
Matti Pastell | b2b143c22e | |
Matti Pastell | 88d8665e03 | |
Matti Pastell | d19d6b6d81 | |
Matti Pastell | eead8f24a8 | |
Matti Pastell | 51ea08ca88 | |
Matti Pastell | 048b484d83 | |
Matti Pastell | 57c17e05a3 | |
Matti Pastell | 48327bd570 | |
Matti Pastell | 742f00bf6a | |
Matti Pastell | 965eb6dfe9 | |
Matti Pastell | be0ac321b3 | |
Matti Pastell | 5b6d50cf72 | |
Matti Pastell | 484b1fdf23 | |
Matti Pastell | 6dc482d997 | |
Matti Pastell | 15d4cdf512 | |
Matti Pastell | dc566fc69a | |
Matti Pastell | 6c149b383c | |
Matti Pastell | 51641124b5 | |
Matti Pastell | 83b5c8f276 | |
Matti Pastell | 2596670aa3 | |
Matti Pastell | 6ef6a0b739 | |
Matti Pastell | 65af831152 | |
Matti Pastell | e0cd57e6a9 | |
Matti Pastell | 0f0e190dd6 | |
Matti Pastell | 753402529e | |
Matti Pastell | 9e5ad966eb | |
Matti Pastell | 361f404f95 | |
Matti Pastell | c1795e7310 | |
Matti Pastell | eb87de143b | |
Matti Pastell | 8c5bc5633a | |
Matti Pastell | f8ffe9218d | |
Matti Pastell | c54032d99a | |
Matti Pastell | 165f6e71bb | |
Matti Pastell | 1536ad455a | |
Matti Pastell | 5bb5e8994c | |
Matti Pastell | c0ad60d138 | |
Matti Pastell | 6a81c53af3 | |
Matti Pastell | c2f581a31d | |
Matti Pastell | 45a3f46918 | |
Matti Pastell | ebd4f6dbed | |
femtocleaner[bot] | 2693389a3a | |
Matti Pastell | 8c22b41920 | |
Matti Pastell | 95008e5704 | |
Fredrik Bagge Carlson | 3f42023b42 | |
Matti Pastell | a35d57e1cb | |
Timothée Poisot | 6b7e88d465 | |
Matti Pastell | c4c5eb11e3 | |
Elliot Saba | b043542007 | |
Matti Pastell | 96bc072619 | |
Matti Pastell | aaabc2cd4f | |
Matti Pastell | 0213c2f774 | |
Matti Pastell | dffb554c8a | |
Matti Pastell | 4bc5435e6d | |
Matti Pastell | 2e65f08e0e | |
Matti Pastell | 5c83309aa3 | |
Chris Foster | da17ac2cc1 | |
Matti Pastell | 7edd8f8bc3 | |
Tamas K. Papp | 0682ca8c59 | |
Matti Pastell | 562968f9be | |
Matti Pastell | 93c2762653 | |
Maxim Grechkin | 1ab37ae48c | |
Matti Pastell | bdedf37e5b | |
Matti Pastell | 5b7ac28e3c | |
Tamas K. Papp | 3297d07102 | |
Tamas K. Papp | 3176ae88bf | |
Matti Pastell | 32f5728ad6 | |
Matti Pastell | ebcee727aa | |
Matti Pastell | 0131bae775 | |
Matti Pastell | 97f309af19 | |
Matti Pastell | 1915501026 | |
Matti Pastell | 9d4817007e | |
Matti Pastell | b4f5221e3a | |
Matti Pastell | c179d3082c | |
Matti Pastell | 5513656f35 | |
Matti Pastell | 1a54d6a557 | |
Matti Pastell | 38d3b04363 | |
Matti Pastell | bbad66d0b8 | |
Matti Pastell | 1b5c0f819c | |
Matti Pastell | d729d4f878 | |
Matti Pastell | b2ffefdb27 | |
Matti Pastell | 09ecdb6f2c | |
Matti Pastell | d3e0f31f9e | |
Matti Pastell | f39069e40a | |
Matti Pastell | 0ffa04b3fd | |
Matti Pastell | 2e6e83e467 | |
Matti Pastell | 70c850e79e | |
Matti Pastell | 888b732f86 | |
Matti Pastell | b0d2ccdba2 | |
Matti Pastell | 868efa8208 | |
Matti Pastell | c788f5f15e | |
Matti Pastell | b66ae83e37 | |
Matti Pastell | bc1e8738a7 | |
Matti Pastell | 1ec393dc05 | |
Matti Pastell | 6c2f0a7bb5 | |
Matti Pastell | f1b42156e1 | |
Matti Pastell | c5659c03bf | |
Matti Pastell | a984b46b5b | |
Matti Pastell | 090ad87ed9 | |
Matti Pastell | 9a1d655681 | |
Matti Pastell | 2715baa347 | |
Matti Pastell | b61a2a01b0 | |
Matti Pastell | de1e08e1ef | |
Matti Pastell | 3837142f9b | |
Matti Pastell | c7918241f2 | |
Matti Pastell | 9dc99ba602 | |
Matti Pastell | a7cd923e27 | |
Matti Pastell | e10f27b26f | |
Matti Pastell | a4cfebcc17 | |
Matti Pastell | f63fe62445 | |
Matti Pastell | 3da8865a15 | |
Matti Pastell | 7c5fcd24c6 | |
Matti Pastell | 458ef30e90 | |
Matti Pastell | 7c69ce9b0c | |
Matti Pastell | 4d499da343 | |
Matti Pastell | 68b9bfda08 | |
Matti Pastell | d75ae6d86b | |
Matti Pastell | ff79618182 | |
Matti Pastell | c0f3bac70a | |
Matti Pastell | 89859c0898 | |
Matti Pastell | b14cd13063 | |
Matti Pastell | a2b63b8f07 | |
Matti Pastell | 57629c1547 | |
Matti Pastell | 0f66b0cbae | |
David Anthoff | f8fff02777 | |
David Anthoff | 3542374d92 | |
Matti Pastell | d8ba7316fe | |
Matti Pastell | 360713458c | |
Matti Pastell | 832b87d92a | |
Matti Pastell | 0234b3d059 | |
David Anthoff | 2191794f38 | |
Matti Pastell | 33fb6db33c | |
Matti Pastell | 3cbc63b7c3 | |
Matti Pastell | a4891b01a8 | |
Matti Pastell | 96f4fd03b8 | |
Matti Pastell | ad08d4c4ae | |
Matti Pastell | 7222bfa9ab | |
Matti Pastell | c62fb709d1 | |
Matti Pastell | e2c40262dd | |
Matti Pastell | 82cc021f3c | |
Matti Pastell | e3051a7525 | |
Matti Pastell | 13e40cefa8 | |
Matti Pastell | 8a6aac0129 | |
Matti Pastell | db2de48133 | |
Matti Pastell | a6b74156f6 | |
Matti Pastell | 05b0c04b6d | |
Matti Pastell | b2932f1b86 | |
Matti Pastell | c11b390533 | |
Matti Pastell | 262589cfdc | |
Matti Pastell | 606bf9147f | |
Matti Pastell | 84dbf05b3e | |
Matti Pastell | 5fb5a7ab3f | |
Matti Pastell | 277c6f3e0f | |
Matti Pastell | d5bbf4f678 | |
Matti Pastell | 9664acbe85 | |
Matti Pastell | 50127eaa90 | |
Matti Pastell | 6de5ba342c | |
Matti Pastell | 2afd25fd09 | |
Matti Pastell | 1753da1016 | |
Matti Pastell | 434d5d4286 | |
Matti Pastell | d27ba7879c | |
Matti Pastell | 37787be647 | |
Matti Pastell | e0199b2e6e | |
Matti Pastell | daafd8e911 | |
Matti Pastell | ded6ce2c2a | |
Matti Pastell | 9b170349d1 | |
Matti Pastell | d683625444 | |
Matti Pastell | f0bcaf546a | |
Matti Pastell | 718cfc7338 | |
Matti Pastell | 975bd14635 | |
Matti Pastell | 7d556beb11 | |
Matti Pastell | 985b3b1972 | |
Matti Pastell | 76bec5c438 | |
Matti Pastell | 6a68be5161 | |
Matti Pastell | 15157a213a | |
Matti Pastell | 85b661f2cd | |
Matti Pastell | c61adf1230 | |
Matti Pastell | 99fbfeca90 | |
Matti Pastell | 9308081714 | |
Matti Pastell | 6b87fbeb90 | |
Matti Pastell | 7fad94eeb6 | |
Matti Pastell | 56e92c648c | |
Matti Pastell | afb9fabef3 | |
Matti Pastell | 43e850f113 | |
Matti Pastell | 544ae925e2 | |
Matti Pastell | 82e56aa9f3 | |
Matti Pastell | 901050a32f | |
Matti Pastell | 93f9e9ac02 | |
Matti Pastell | 3d30e4fcfc | |
Matti Pastell | 4bc881378b | |
Matti Pastell | 827934dfa6 | |
Matti Pastell | 7bccdd2ab1 | |
Matti Pastell | 10e089379b | |
Matti Pastell | 3bf251bc0d | |
Stephen Eglen | 60ba918a7a | |
Matti Pastell | 8922124d21 | |
Matti Pastell | cbdf0e2886 | |
Matti Pastell | bfd163e50f | |
Matti Pastell | 0ce73efeaa | |
Matti Pastell | 68a8fbdcf4 | |
Matti Pastell | d50770abe1 | |
Matti Pastell | b7908bc2ea | |
Matti Pastell | d2fe2a82e2 | |
Matti Pastell | 00b5829fe9 | |
Matti Pastell | fd1f13eb33 | |
Tony Kelman | 8324d32f01 | |
bramtayl | 7bd1dfa044 | |
Tony Kelman | e1dc9926e0 | |
Tony Kelman | 3ad6d7ae56 | |
Matti Pastell | f48b61c776 | |
Matti Pastell | a11c9eead0 | |
Matti Pastell | d5749ecd7d | |
Michael Hatherly | ef59d52698 | |
Giuseppe Ragusa | bec1cd08d3 | |
= | 0698165193 | |
Matti Pastell | 181869a663 | |
Giuseppe Ragusa | fd3e7e4c87 | |
Giuseppe Ragusa | bd300ed881 | |
Giuseppe Ragusa | 6ab484848d | |
= | e097c2c01e | |
= | 95cfdaf04d | |
= | da5ffa7794 | |
= | 5e929b7ef6 | |
Matti Pastell | 0dd0d3d8af | |
Giuseppe Ragusa | 1834b93cb3 | |
Giuseppe Ragusa | eecef35305 | |
Giuseppe Ragusa | 1d72309959 | |
Giuseppe Ragusa | 4a2062644b | |
Giuseppe Ragusa | cffbb7ff5c | |
Giuseppe Ragusa | 60a234a95d | |
Giuseppe Ragusa | 7a0958cf13 | |
= | a760def865 | |
Matti Pastell | 9caf014c07 | |
Giuseppe Ragusa | bc1d88c8d3 | |
Matti Pastell | 699f5b46e7 | |
Matti Pastell | 30a83667ee | |
Matti Pastell | d5f1fd4d19 | |
Matti Pastell | 3d8bccdb52 | |
Matti Pastell | 244cb9ab17 | |
Matti Pastell | 81bca0543f | |
= | 9f5a141701 | |
= | b6031cd111 | |
= | daa645ac58 | |
= | 2681f19c19 | |
Matti Pastell | e2da54fa54 | |
Matti Pastell | 9d4e68ca5c | |
Matti Pastell | dca852ed89 | |
Matti Pastell | 64fd4daa1d | |
Matti Pastell | 506f48f4dd | |
Matti Pastell | 31392a067f | |
Matti Pastell | da5001bd31 | |
Matti Pastell | 45f8871740 | |
Matti Pastell | 37f0c7f796 | |
Matti Pastell | f24b2157a6 |
|
@ -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,33 +1,29 @@
|
|||
|
||||
src/*.cov
|
||||
test.jl
|
||||
examples/figures/
|
||||
examples/*.md
|
||||
examples/*.pdf
|
||||
examples/*.html
|
||||
examples/*.rst
|
||||
examples/*.tex
|
||||
test/documents/figures
|
||||
test/documents/cache
|
||||
test/documents/output/figures
|
||||
test/documents/output/gadfly_formats_test.txt
|
||||
test/documents/*.tex
|
||||
test/documents/*.md
|
||||
test/documents/*.rst
|
||||
test/documents/*.html
|
||||
test/documents/*.pdf
|
||||
test/documents/chunk_options.jl
|
||||
!test/documents/*ref.*
|
||||
|
||||
doc/build
|
||||
doc/site
|
||||
stable/
|
||||
|
||||
tmp/
|
||||
.idea
|
||||
*.*~
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
\#*\#
|
||||
.juliahistory
|
||||
Manifest.toml
|
||||
|
||||
examples/figures/
|
||||
examples/*.md
|
||||
examples/*.pdf
|
||||
examples/*.html
|
||||
examples/*.rst
|
||||
examples/*.tex
|
||||
test/**/cache
|
||||
test/**/figures
|
||||
test/documents/output/gadfly_formats_test.txt
|
||||
test/**/*.tex
|
||||
test/**/*.md
|
||||
test/**/*.rst
|
||||
test/**/*.html
|
||||
test/**/*.pdf
|
||||
test/**/*.png
|
||||
test/**/chunk_options.jl
|
||||
test/**/*.ipynb
|
||||
!test/**/*ref.*
|
||||
|
||||
doc/build
|
||||
doc/site
|
||||
|
||||
.idea
|
||||
*.*~
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
|
|
33
.travis.yml
33
.travis.yml
|
@ -1,25 +1,14 @@
|
|||
|
||||
language: julia
|
||||
julia:
|
||||
- release
|
||||
- nightly
|
||||
matrix:
|
||||
allow_failures:
|
||||
- julia: nightly
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: "Documentation"
|
||||
julia: 1.5
|
||||
os: linux
|
||||
script:
|
||||
- julia --project=doc/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
|
||||
- julia --project=doc/ doc/make.jl
|
||||
after_success: skip
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
before_install:
|
||||
#- sudo apt-get update -qq -y
|
||||
#- sudo apt-get install python-matplotlib -y
|
||||
- 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/miniconda2/bin:$PATH
|
||||
- conda update --yes conda
|
||||
- conda install --yes matplotlib
|
||||
script:
|
||||
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
|
||||
- julia --check-bounds=yes -e 'Pkg.clone(pwd()); Pkg.build("Weave")'
|
||||
- xvfb-run julia -e 'Pkg.test("Weave", coverage=true)'
|
||||
after_success:
|
||||
- julia -e 'cd(Pkg.dir("Weave")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
|
||||
|
|
40
LICENSE.md
40
LICENSE.md
|
@ -1,22 +1,20 @@
|
|||
The Weave.jl package is licensed under the MIT "Expat" License:
|
||||
Copyright (c) 2020: Contributors
|
||||
|
||||
> Copyright (c) 2014: Matti Pastell.
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining
|
||||
> a copy of this software and associated documentation files (the
|
||||
> "Software"), to deal in the Software without restriction, including
|
||||
> without limitation the rights to use, copy, modify, merge, publish,
|
||||
> distribute, sublicense, and/or sell copies of the Software, and to
|
||||
> permit persons to whom the Software is furnished to do so, subject to
|
||||
> the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be
|
||||
> included in all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
122
NEWS.md
122
NEWS.md
|
@ -1,5 +1,111 @@
|
|||
## 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
|
||||
|
||||
# Release notes for Weave.jl
|
||||
|
||||
### v0.1.2
|
||||
|
||||
|
@ -10,6 +116,7 @@
|
|||
* 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.
|
||||
|
@ -25,6 +132,7 @@
|
|||
* Autodetect input and output formats based on filename
|
||||
* Allow `out_path` be a file or directory.
|
||||
|
||||
|
||||
### v0.1.0
|
||||
|
||||
19th April 2016
|
||||
|
@ -41,6 +149,7 @@
|
|||
- Chunks are now represented with their own type. Allows multiple dispatch
|
||||
and easier implementation of new chunks.
|
||||
|
||||
|
||||
### 0.0.4
|
||||
|
||||
4th January 2015
|
||||
|
@ -50,6 +159,7 @@
|
|||
* 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
|
||||
|
@ -65,8 +175,8 @@
|
|||
|
||||
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
|
||||
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"]
|
172
README.md
172
README.md
|
@ -1,70 +1,104 @@
|
|||
# Weave
|
||||
|
||||
[![Build Status](https://travis-ci.org/mpastell/Weave.jl.svg?branch=master)](https://travis-ci.org/mpastell/Weave.jl)[![Coverage Status](https://img.shields.io/coveralls/mpastell/Weave.jl.svg)](https://coveralls.io/r/mpastell/Weave.jl?branch=master)
|
||||
|
||||
Weave is a scientific report generator/literate programming tool
|
||||
for Julia. It resembles [Pweave](http://mpastell.com/pweave) and, Knitr
|
||||
and Sweave.
|
||||
|
||||
You can write your documentation and code in input document using Nowed or Markdown syntax and use `weave` function to execute to document to capture results and figures.
|
||||
|
||||
**Current features**
|
||||
|
||||
* Noweb, markdown or script syntax for input documents.
|
||||
* Execute code as terminal or "script" chunks.
|
||||
* Capture Gadfly, PyPlot and Winston figures.
|
||||
* Supports LaTex, Pandoc, Github markdown, MultiMarkdown, Asciidoc and reStructuredText output
|
||||
* Publish markdown directly to html and pdf using Pandoc.
|
||||
* Simple caching of results
|
||||
# Weave
|
||||
|
||||
## Usage
|
||||
|
||||
Run from julia using Gadfly for plots:
|
||||
|
||||
```julia
|
||||
using Weave
|
||||
weave(Pkg.dir("Weave","examples","gadfly_sample.mdw"))
|
||||
```
|
||||
|
||||
If you have Pandoc installed you can also weave directly to html and pdf.
|
||||
|
||||
```julia
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), informat="markdown",
|
||||
out_path = :pwd, doctype = "md2html")
|
||||
```
|
||||
|
||||
![Weave code and output](http://mpastell.com/images/weave_demo.png)
|
||||
|
||||
## Documentation
|
||||
|
||||
Documenter.jl with MKDocs generated documentation:
|
||||
|
||||
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://mpastell.github.io/Weave.jl/stable)
|
||||
[![](https://img.shields.io/badge/docs-latest-blue.svg)](https://mpastell.github.io/Weave.jl/latest)
|
||||
|
||||
## Editor support
|
||||
|
||||
I have made [language-weave](https://atom.io/packages/language-weave) package
|
||||
for Atom to do the syntax highlighting correctly.
|
||||
|
||||
Noweb documents work well with ESS as well, to set doc-mode for .mdw files to markdown
|
||||
and code to Julia you can do:
|
||||
|
||||
```clojure
|
||||
(defun mdw-mode ()
|
||||
(ess-noweb-mode)
|
||||
(setq ess-noweb-default-code-mode 'ess-julia-mode)
|
||||
(setq ess-noweb-doc-mode 'markdown-mode))
|
||||
|
||||
(setq auto-mode-alist (append (list (cons "\\.mdw$" 'mdw-mode))
|
||||
auto-mode-alist))
|
||||
```
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
I will probably add new features to Weave when I need them myself or if they are requested and not too difficult to implement. You can contribute by opening issues on Github or implementing things yourself and making a pull request. I'd also appreciate example documents written using Weave to add to examples.
|
||||
|
||||
## Contributors
|
||||
|
||||
You can see the list of contributors on Github: https://github.com/mpastell/Weave.jl/graphs/contributors. Thanks for the important additions, fixes and comments.
|
||||
![CI](https://github.com/JunoLab/Weave.jl/workflows/CI/badge.svg)
|
||||
[![codecov](https://codecov.io/gh/JunoLab/Weave.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JunoLab/Weave.jl)
|
||||
[![](https://img.shields.io/badge/docs-stable-blue.svg)](http://weavejl.mpastell.com/stable/)
|
||||
[![](https://img.shields.io/badge/docs-dev-blue.svg)](http://weavejl.mpastell.com/dev/)
|
||||
[![](http://joss.theoj.org/papers/10.21105/joss.00204/status.svg)](http://dx.doi.org/10.21105/joss.00204)
|
||||
|
||||
Weave is a scientific report generator/literate programming tool for the [Julia programming language](https://julialang.org/).
|
||||
It resembles
|
||||
[Pweave](http://mpastell.com/pweave),
|
||||
[knitr](https://yihui.org/knitr/),
|
||||
[R Markdown](https://rmarkdown.rstudio.com/),
|
||||
and [Sweave](https://stat.ethz.ch/R-manual/R-patched/library/utils/doc/Sweave.pdf).
|
||||
|
||||
You can write your documentation and code in input document using Markdown, Noweb or ordinal Julia script syntax,
|
||||
and then use `weave` function to execute code and generate an output document while capturing results and figures.
|
||||
|
||||
**Current features**
|
||||
|
||||
- Publish markdown directly to HTML and PDF using Julia or [Pandoc](https://pandoc.org/MANUAL.html)
|
||||
- Execute code as in terminal or in a unit of code chunk
|
||||
- Capture [Plots.jl](https://github.com/JuliaPlots/Plots.jl) or [Gadfly.jl](https://github.com/GiovineItalia/Gadfly.jl) figures
|
||||
- Supports various input format: Markdown, [Noweb](https://www.cs.tufts.edu/~nr/noweb/), [Jupyter Notebook](https://jupyter.org/), and ordinal Julia script
|
||||
- Conversions between those input formats
|
||||
- Supports various output document formats: HTML, PDF, GitHub markdown, Jupyter Notebook, MultiMarkdown, Asciidoc and reStructuredText
|
||||
- Simple caching of results
|
||||
|
||||
**Citing Weave:** *Pastell, Matti. 2017. Weave.jl: Scientific Reports Using Julia. The Journal of Open Source Software. http://dx.doi.org/10.21105/joss.00204*
|
||||
|
||||
![Weave in Juno demo](https://user-images.githubusercontent.com/40514306/76081328-32f41900-5fec-11ea-958a-375f77f642a2.png)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
You can install the latest release using Julia package manager:
|
||||
|
||||
```julia
|
||||
using Pkg
|
||||
Pkg.add("Weave")
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```julia
|
||||
using Weave
|
||||
|
||||
# add depencies for the example
|
||||
using Pkg; Pkg.add(["Plots", "DSP"])
|
||||
|
||||
filename = normpath(Weave.EXAMPLE_FOLDER, "FIR_design.jmd")
|
||||
weave(filename, out_path = :pwd)
|
||||
```
|
||||
|
||||
If you have LaTeX installed you can also weave directly to pdf.
|
||||
|
||||
```julia
|
||||
filename = normpath(Weave.EXAMPLE_FOLDER, "FIR_design.jmd")
|
||||
weave(filename, out_path = :pwd, doctype = "md2pdf")
|
||||
```
|
||||
|
||||
NOTE: `Weave.EXAMPLE_FOLDER` just points to [`examples` directory](./examples).
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
Documenter.jl with MKDocs generated documentation:
|
||||
|
||||
[![](https://img.shields.io/badge/docs-stable-blue.svg)](http://weavejl.mpastell.com/stable/)
|
||||
[![](https://img.shields.io/badge/docs-dev-blue.svg)](http://weavejl.mpastell.com/dev/)
|
||||
|
||||
|
||||
## Editor support
|
||||
|
||||
Install [language-weave](https://atom.io/packages/language-weave) to add Weave support to Juno.
|
||||
It allows running code from Weave documents with usual keybindings and allows preview of
|
||||
html and pdf output.
|
||||
|
||||
The [Julia extension for Visual Studio Code](https://www.julia-vscode.org/)
|
||||
adds Weave support to [Visual Studio Code](https://code.visualstudio.com/).
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
You can contribute to this package by opening issues on GitHub or implementing things yourself and making a pull request.
|
||||
We'd also appreciate more example documents written using Weave.
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
You can see the list of contributors on GitHub: https://github.com/JunoLab/Weave.jl/graphs/contributors .
|
||||
Thanks for the important additions, fixes and comments.
|
||||
|
||||
|
||||
## Example projects using Weave
|
||||
|
||||
- [DiffEqTutorials.jl](https://github.com/JuliaDiffEq/DiffEqTutorials.jl) uses Weave to output tutorials (`.jmd` documents) to html, pdf and Jupyter notebooks.
|
||||
- [TuringTutorials](https://github.com/TuringLang/TuringTutorials) uses Weave to convert notebooks to html.
|
||||
|
||||
## Related packages
|
||||
|
||||
- [Literate.jl](https://github.com/fredrikekre/Literate.jl) can be used to generate Markdown and Jupyter notebooks directly from Julia source files with markdown in comments.
|
||||
- [Quarto](https://quarto.org) can generate Jupyter notebooks, HTML, or PDF directly from a Markdown format containing Julia code blocks, and also works with R and Python.
|
||||
|
|
|
@ -14,14 +14,14 @@ ap = ArgParseSettings("Weave Julia documents using Weave.jl",
|
|||
help = "source document(s)"
|
||||
required = true
|
||||
"--doctype"
|
||||
default = :auto
|
||||
default = nothing
|
||||
help = "output format"
|
||||
"--plotlib"
|
||||
arg_type = String
|
||||
default = "Gadfly"
|
||||
help = "output format"
|
||||
"--informat"
|
||||
default = :auto
|
||||
default = nothing
|
||||
help = "output format"
|
||||
"--out_path"
|
||||
arg_type = String
|
||||
|
@ -43,9 +43,6 @@ args_col = []
|
|||
|
||||
#Check for special values of out_path
|
||||
|
||||
#args["informat"] == ":auto" && (args["informat"] = :auto)
|
||||
#args["doctype"] == ":auto" && (args["informat"] = :auto)
|
||||
|
||||
if args["out_path"] == ":doc"
|
||||
args["out_path"] = :doc
|
||||
elseif args["out_path"] == ":pwd"
|
||||
|
@ -53,7 +50,7 @@ elseif args["out_path"] == ":pwd"
|
|||
end
|
||||
|
||||
for (key, val) in args
|
||||
push!(args_col, (parse(key), val))
|
||||
push!(args_col, (Meta.parse(key), val))
|
||||
end
|
||||
|
||||
for s=source
|
||||
|
|
|
@ -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.
28
doc/make.jl
28
doc/make.jl
|
@ -1,3 +1,29 @@
|
|||
using Documenter, Weave
|
||||
|
||||
makedocs(modules = 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,
|
||||
)
|
||||
|
|
|
@ -1,22 +1,30 @@
|
|||
using Weave
|
||||
|
||||
let start_dir = pwd()
|
||||
cd(@__DIR__)
|
||||
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"),
|
||||
informat="markdown", out_path = "build/examples", doctype = "pandoc")
|
||||
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")
|
||||
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"),
|
||||
informat="markdown", out_path = "build/examples", doctype = "md2html")
|
||||
# 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
|
||||
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"),
|
||||
informat="markdown", out_path = "build/examples", doctype = "md2pdf")
|
||||
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)
|
||||
|
||||
cp(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"),
|
||||
"build/examples/gadfly_md_sample.jmd", remove_destination = true)
|
||||
|
||||
cp("build/examples/gadfly_md_sample.md",
|
||||
"build/examples/gadfly_md_sample.txt", remove_destination = true)
|
||||
|
||||
weave(Pkg.dir("Weave","examples","FIR_design.jl"), out_path = "build/examples")
|
||||
weave(Pkg.dir("Weave","examples","FIR_design.jl"), doctype = "md2pdf", out_path = "build/examples")
|
||||
cp(Pkg.dir("Weave","examples","FIR_design.jl"),
|
||||
"build/examples/FIR_design.jl", remove_destination = true)
|
||||
cd(start_dir)
|
||||
end
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
site_name: Weave.jl - Scientific Reports Using Julia
|
||||
site_author: Matti Pastell
|
||||
copyright: Matti Pastell 2016
|
||||
repo_url: https://github.com/mpastell/Weave.jl
|
||||
|
||||
theme: material
|
||||
|
||||
extra:
|
||||
palette:
|
||||
primary: 'indigo'
|
||||
accent: 'blue'
|
||||
|
||||
extra_css:
|
||||
- assets/Documenter.css
|
||||
|
||||
#extra_javascript:
|
||||
# - https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML
|
||||
# - assets/mathjaxhelper.js
|
||||
|
||||
markdown_extensions:
|
||||
- extra
|
||||
- tables
|
||||
- fenced_code
|
||||
# - mdx_math
|
||||
|
||||
docs_dir: 'build'
|
||||
|
||||
pages:
|
||||
- Home: index.md
|
||||
- Getting started: getting_started.md
|
||||
- Using Weave: usage.md
|
||||
- Publishing scripts: publish.md
|
||||
- Chunk options: chunk_options.md
|
||||
- Function index: function_index.md
|
|
@ -1,63 +1,81 @@
|
|||
# Chunk options
|
||||
# [Chunk Options](@id chunk-options)
|
||||
|
||||
I've mostly followed [Knitr](http://yihui.name/knitr/options)'s naming for chunk options, but not all options are implemented.
|
||||
|
||||
Options are separated using ";" and need to be valid Julia expressions. Example: A code chunk that saves and displays a 12 cm wide image and hides the source code:
|
||||
|
||||
```julia
|
||||
<<fig_width=5; echo=false >>=
|
||||
using Gadfly
|
||||
x = linspace(0, 2π, 200)
|
||||
plot(x=x, y = sin(x), Geom.line)
|
||||
@
|
||||
```
|
||||
|
||||
Weave currently supports the following chunk options with the following defaults:
|
||||
|
||||
## Options for code
|
||||
|
||||
* `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 wan’t to e.g. create tables from code chunks.
|
||||
* `eval = true`. Evaluate the code chunk. If false the chunk won’t be executed.
|
||||
* `term=false`. If true the output emulates a REPL session. Otherwise only stdout and figures will be included in output.
|
||||
* `label`. Chunk label, will be used for figure labels in Latex as fig:label
|
||||
* `wrap = true`. Wrap long lines from output.
|
||||
* `line_width = 75`. Line width for wrapped lines.
|
||||
* `cache = false`. Cache results, depends on `cache` parameter on `weave` function.
|
||||
* `hold = false`. Hold all results until the end of the chunk.
|
||||
* `tangle = true`. Set tangle to false to exclude chunk from tangled code.
|
||||
|
||||
## Options for figures
|
||||
|
||||
* `fig_width`. Figure width defined in markup, default depends on the output format.
|
||||
* `out_width`. Width of saved figure.
|
||||
* `out_height`. Height of saved figure.
|
||||
* `dpi`=96. Resolution of saved figures.
|
||||
* `fig_cap`. Figure caption.
|
||||
* `label`. Chunk label, will be used for figure labels in Latex as fig:label
|
||||
* `fig_ext`. File extension (format) of saved figures.
|
||||
* `fig_pos="htpb"`. Figure position in Latex.
|
||||
* `fig_env="figure"`. Figure environment in Latex.
|
||||
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).
|
||||
|
||||
|
||||
## Set default chunk options
|
||||
## Syntax
|
||||
|
||||
You can set or alter the default chunk options for a document either before
|
||||
running weave or inside the weaved document. You can e.g. use a hidden chunk
|
||||
in the beginning of the source document to set the options:
|
||||
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 (`,`)
|
||||
|
||||
```
|
||||
<<echo = false>>=
|
||||
import Weave
|
||||
Weave.set_chunk_defaults(Dict{Symbol, Any}(
|
||||
:out_width => "\\0.5linewidth",
|
||||
:results => "tex"
|
||||
))
|
||||
@
|
||||
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"}
|
||||
```
|
||||
|
||||
|
||||
{docs}
|
||||
set_chunk_defaults(opts)
|
||||
get_chunk_defaults()
|
||||
restore_chunk_defaults()
|
||||
## 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!
|
||||
```
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
# Function index
|
||||
|
||||
{index}
|
||||
```@index
|
||||
```
|
||||
|
|
|
@ -1,30 +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 packages `examples` directory.
|
||||
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 Gadfly for
|
||||
figures: [gadfly_md_sample.jmd](examples/gadfly_md_sample.jmd) and then see the
|
||||
output in different formats:
|
||||
First have a look at source document using markdown code chunks and [Plots.jl](https://github.com/JuliaPlots/Plots.jl) for figures:
|
||||
|
||||
- Pandoc markdown: [gadfly_md_sample.md](examples/gadfly_md_sample.txt)
|
||||
- HTML: [gadfly_md_sample.html](examples/gadfly_md_sample.html)
|
||||
- pdf: [gadfly_md_sample.pdf](examples/gadfly_md_sample.pdf)
|
||||
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)
|
||||
|
||||
*Producing HTML and pdf output requires that you have Pandoc and XeLatex (for pdf) installed.*
|
||||
!!! note
|
||||
Producing PDF output requires that you have XeLateX installed.
|
||||
|
||||
You can Weave the files to your working directory using:
|
||||
Add dependencies for the example if needed:
|
||||
|
||||
```julia
|
||||
using Pkg; Pkg.add.(["Plots", "DSP"])
|
||||
```
|
||||
|
||||
Weave the files to your working directory:
|
||||
|
||||
```julia
|
||||
using Weave
|
||||
#Markdown
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), out_path = :pwd,
|
||||
doctype = "pandoc")
|
||||
#HTML
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), out_path = :pwd,
|
||||
doctype = "md2html")
|
||||
#pdf
|
||||
weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), out_path = :pwd,
|
||||
doctype = "md2pdf")
|
||||
|
||||
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
|
||||
---
|
||||
```
|
|
@ -1,22 +1,38 @@
|
|||
# Weave.jl - Scientific Reports Using Julia
|
||||
|
||||
# Intro
|
||||
|
||||
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) and, Knitr
|
||||
and Sweave.
|
||||
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**
|
||||
|
||||
* Noweb, markdown or script syntax for input documents.
|
||||
* Execute code as terminal or "script" chunks.
|
||||
* Capture Gadfly, PyPlot and Winston figures.
|
||||
* Supports LaTex, Pandoc, Github markdown, MultiMarkdown, Asciidoc and reStructuredText output
|
||||
* Publish markdown directly to html and pdf using Pandoc.
|
||||
* Simple caching of results
|
||||
- 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 code and output](http://mpastell.com/images/weave_demo.png)
|
||||
![Weave in Juno demo](https://user-images.githubusercontent.com/40514306/76081328-32f41900-5fec-11ea-958a-375f77f642a2.png)
|
||||
|
||||
## Contents
|
||||
|
||||
{contents}
|
||||
## 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
|
||||
```
|
|
@ -1,36 +1,67 @@
|
|||
# Publishing scripts
|
||||
# Publishing to HTML and PDF
|
||||
|
||||
You can also also publish html and pdf
|
||||
documents from Julia scripts with a specific format. Producing HTML and pdf output
|
||||
requires that you have Pandoc and XeLatex (for pdf) installed and in your path.
|
||||
You can also publish any supported input format to HTML and PDF documents.
|
||||
|
||||
These scripts can be executed normally using Julia or published with Weave.
|
||||
Documentation is written in markdown in lines starting with ``#'``, ``#%%`` or ``# %%`` ,
|
||||
and code is executed and results are included in the published document.
|
||||
|
||||
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.
|
||||
|
||||
All lines that are not documentation are treated as code. You can set chunk options
|
||||
using lines starting with ``#+``, ``#%%`` or ``# %%`` just before code
|
||||
e.g. ``#+ term=True, caption='Fancy plots.'``. See the example below for the markup.
|
||||
|
||||
The scripts can be published using the `pypublish` scipts:
|
||||
|
||||
[FIR_design.jl](examples/FIR_design.jl), [FIR_design.html](examples/FIR_design.html) , [FIR_design.pdf](examples/FIR_design.pdf).
|
||||
!!! 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.:
|
||||
```
|
||||
weave("FIR_design.jl")
|
||||
weave("FIR_design.jl", docformat = "md2pdf")
|
||||
---
|
||||
title : Weave example
|
||||
author : Matti Pastell
|
||||
date: 15th December 2016
|
||||
---
|
||||
```
|
||||
|
||||
## Other mark ups with scripts
|
||||
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)
|
||||
|
||||
You can also use any Weave supported format in the comments and set the output format
|
||||
as you would for noweb and markdown inputs. e.g for LaTeX you can use:
|
||||
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:
|
||||
|
||||
```
|
||||
weave("latex_doc.jl", docformat = "texminted")
|
||||
$$
|
||||
x^2 = x*x
|
||||
$$
|
||||
```
|
||||
|
|
201
doc/src/usage.md
201
doc/src/usage.md
|
@ -1,105 +1,182 @@
|
|||
# Using Weave
|
||||
|
||||
You can write your documentation and code in input document using Noweb or Markdown syntax and use `weave` function to execute to document to capture results and figures.
|
||||
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`
|
||||
|
||||
Weave document with markup and julia code using Gadfly for plots,
|
||||
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(Pkg.dir("Weave","examples","gadfly_sample.mdw"), out_path = :pwd)
|
||||
weave(Weave.SAMPLE_JL_DOC; out_path=:pwd)
|
||||
```
|
||||
|
||||
Using PyPlot:
|
||||
|
||||
```julia
|
||||
weave(Pkg.dir("Weave","examples","julia_sample.mdw"), plotlib="PyPlot", out_path = :pwd)
|
||||
```@docs
|
||||
weave
|
||||
```
|
||||
|
||||
{docs}
|
||||
weave(source)
|
||||
|
||||
## Weave from shell
|
||||
|
||||
You can also use the `weave.jl` script under bin directory to weave documents
|
||||
from the shell:
|
||||
|
||||
```
|
||||
$ ./weave.jl
|
||||
usage: weave.jl [--doctype DOCTYPE] [--plotlib PLOTLIB]
|
||||
[--informat INFORMAT] [--out_path OUT_PATH]
|
||||
[--fig_path FIG_PATH] [--fig_ext FIG_EXT] source...
|
||||
```
|
||||
|
||||
## Tangle
|
||||
## `tangle`
|
||||
|
||||
Tangling extracts the code from document:
|
||||
|
||||
{docs}
|
||||
tangle(source)
|
||||
```@docs
|
||||
tangle
|
||||
```
|
||||
|
||||
## Supported Output Formats
|
||||
|
||||
## Supported formats
|
||||
|
||||
Weave sets the output format based on the file extension, but you can also set
|
||||
it using `doctype` option. The rules for detecting the format are:
|
||||
Weave automatically detects the output format based on the file extension.
|
||||
The auto output format detection is handled by `detect_doctype(path::AbstractString)`:
|
||||
|
||||
```julia
|
||||
ext == ".jl" && return "md2html"
|
||||
contains(ext, ".md") && return "md2html"
|
||||
contains(ext, ".rst") && return "rst"
|
||||
contains(ext, ".tex") && return "texminted"
|
||||
contains(ext, ".txt") && return "asciidoc"
|
||||
return "pandoc"
|
||||
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:
|
||||
|
||||
```
|
||||
julia> list_out_formats()
|
||||
pandoc: Pandoc markdown
|
||||
rst: reStructuredText and Sphinx
|
||||
texminted: Latex using minted for highlighting
|
||||
github: Github markdown
|
||||
md2html: Markdown to HTML (requires Pandoc)
|
||||
md2pdf: Markdown to pdf (requires Pandoc and xelatex)
|
||||
asciidoc: AsciiDoc
|
||||
tex: Latex with custom code environments
|
||||
```@docs
|
||||
list_out_formats
|
||||
```
|
||||
|
||||
{docs}
|
||||
list_out_formats()
|
||||
```@example
|
||||
using Weave # hide
|
||||
list_out_formats()
|
||||
```
|
||||
|
||||
## Document syntax
|
||||
## [Document Syntax](@id document-syntax)
|
||||
|
||||
Weave uses noweb, markdown or script syntax for defining the code chunks and
|
||||
documentation chunks. The format is detected based on the file extension, but
|
||||
you can also set it manually using the `informat` parameter.
|
||||
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
|
||||
|
||||
## Noweb
|
||||
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
|
||||
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. See for options below.
|
||||
|
||||
### Documentation chunks
|
||||
### [Code Chunks](@id code-chunks)
|
||||
|
||||
Are the rest of the document (between `@` and `<<>>=` lines and the first chunk be default) and can be written with several different markup languages.
|
||||
Code chunks are written in different ways in different formats.
|
||||
|
||||
[Sample document]( https://github.com/mpastell/Weave.jl/blob/master/examples/julia_sample.mdw)
|
||||
#### Markdown Format
|
||||
|
||||
## Markdown
|
||||
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
|
||||
...
|
||||
```
|
||||
```
|
||||
|
||||
Markdown code chunks are defined using fenced code blocks. [See sample document:](https://github.com/mpastell/Weave.jl/blob/master/examples/gadfly_sample.jmd)
|
||||
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
|
||||
```
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#' % FIR filter design with Julia
|
||||
#' % Matti Pastell
|
||||
#' % 21th April 2016
|
||||
#' ---
|
||||
#' 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://mpastell.github.io/Weave.jl/latest/usage/).
|
||||
#' [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
|
||||
|
@ -32,9 +34,9 @@
|
|||
|
||||
using Gadfly, DSP
|
||||
|
||||
function FIRfreqz(b::Array, w = linspace(0, π, 1024))
|
||||
function FIRfreqz(b::Array, w = range(0, stop=π, length=1024))
|
||||
n = length(w)
|
||||
h = Array{Complex64}(n)
|
||||
h = Array{ComplexF32}(n)
|
||||
sw = 0
|
||||
for i = 1:n
|
||||
for j = 1:length(b)
|
||||
|
@ -56,10 +58,9 @@ end
|
|||
#' 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 = linspace(0, pi, 1024)
|
||||
w = range(0, stop=pi, length=1024)
|
||||
h = FIRfreqz(f, w)
|
||||
|
||||
#' ## Plot the frequency and impulse response
|
||||
|
@ -67,13 +68,16 @@ h = FIRfreqz(f, w)
|
|||
#' The next code chunk is executed in term mode, see the [script](FIR_design.jl) for syntax.
|
||||
#+ term=true
|
||||
|
||||
h_db = log10(abs(h))
|
||||
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(-atan2(imag(h),real(h)))
|
||||
h_phase = unwrap(-atan(imag(h),real(h)))
|
||||
plot(y = h_phase, x = ws, Geom.line,
|
||||
Guide.xlabel("Frequency (Hz)"), Guide.ylabel("Phase (radians)"))
|
||||
|
|
|
@ -1,42 +1,58 @@
|
|||
% FIR filter design with Julia
|
||||
% Matti Pastell
|
||||
% 21th April 2016
|
||||
---
|
||||
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://mpastell.github.io/Weave.jl/latest/usage/).
|
||||
[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.
|
||||
[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()
|
||||
|
||||
~~~~{.julia}
|
||||
using Gadfly, DSP
|
||||
|
||||
function FIRfreqz(b::Array, w = linspace(0, π, 1024))
|
||||
function FIRfreqz(b::Array, w = range(0, stop=π, length=1024))
|
||||
n = length(w)
|
||||
h = Array{Complex64}(n)
|
||||
h = Array{ComplexF32}(undef, n)
|
||||
sw = 0
|
||||
for i = 1:n
|
||||
for j = 1:length(b)
|
||||
|
@ -47,13 +63,11 @@ function FIRfreqz(b::Array, w = linspace(0, π, 1024))
|
|||
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
|
||||
|
@ -61,68 +75,32 @@ 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}
|
||||
```julia
|
||||
fs = 20
|
||||
f = digitalfilter(Lowpass(5, fs = fs), FIRWindow(hamming(61)))
|
||||
w = linspace(0, pi, 1024)
|
||||
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}
|
||||
julia>
|
||||
h_db = log10(abs(h))
|
||||
|
||||
1024-element Array{Float32,1}:
|
||||
0.0
|
||||
-1.52727e-6
|
||||
-6.03147e-6
|
||||
-1.35386e-5
|
||||
-2.39452e-5
|
||||
-3.71738e-5
|
||||
-5.31213e-5
|
||||
-7.16583e-5
|
||||
-9.25781e-5
|
||||
-0.000115803
|
||||
⋮
|
||||
-3.21659
|
||||
-3.18342
|
||||
-3.15605
|
||||
-3.13379
|
||||
-3.11615
|
||||
-3.10275
|
||||
-3.09335
|
||||
-3.08778
|
||||
-3.08593
|
||||
julia> ws = w/pi*(fs/2)
|
||||
|
||||
linspace(0.0,10.0,1024)
|
||||
julia> plot(y = h_db, x = ws, Geom.line,
|
||||
Guide.xlabel("Frequency (Hz)"), Guide.ylabel("Magnitude (db)"))
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
![](figures/FIR_design_3_1.png)\
|
||||
|
||||
```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(-atan2(imag(h),real(h)))
|
||||
plot(y = h_phase, x = ws, Geom.line,
|
||||
Guide.xlabel("Frequency (Hz)"), Guide.ylabel("Phase (radians)"))
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
![](figures/FIR_design_4_1.png)\
|
||||
|
||||
```julia
|
||||
h_phase = unwrap(-atan.(imag.(h),real.(h)))
|
||||
plot(ws, h_phase,
|
||||
xlabel = "Frequency (Hz)", ylabel = "Phase (radians)")
|
||||
```
|
|
@ -1,11 +1,13 @@
|
|||
#' % FIR filter design with Julia
|
||||
#' % Matti Pastell
|
||||
#' % 21th April 2016
|
||||
#' ---
|
||||
#' 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://mpastell.github.io/Weave.jl/latest/usage/).
|
||||
#' [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
|
||||
|
@ -14,7 +16,7 @@
|
|||
#' 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.
|
||||
#' [source](FIR_design_plots.jl) to see the markup.
|
||||
|
||||
|
||||
#' # FIR Filter Design
|
||||
|
@ -30,11 +32,12 @@
|
|||
#' 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
|
||||
using Plots, DSP
|
||||
gr()
|
||||
|
||||
function FIRfreqz(b::Array, w = linspace(0, π, 1024))
|
||||
function FIRfreqz(b::Array, w = range(0, stop=π, length=1024))
|
||||
n = length(w)
|
||||
h = Array{Complex64}(n)
|
||||
h = Array{ComplexF32}(undef, n)
|
||||
sw = 0
|
||||
for i = 1:n
|
||||
for j = 1:length(b)
|
||||
|
@ -59,7 +62,7 @@ end
|
|||
|
||||
fs = 20
|
||||
f = digitalfilter(Lowpass(5, fs = fs), FIRWindow(hamming(61)))
|
||||
w = linspace(0, pi, 1024)
|
||||
w = range(0, stop=pi, length=1024)
|
||||
h = FIRfreqz(f, w)
|
||||
|
||||
#' ## Plot the frequency and impulse response
|
||||
|
@ -67,13 +70,16 @@ h = FIRfreqz(f, w)
|
|||
#' The next code chunk is executed in term mode, see the [script](FIR_design.jl) for syntax.
|
||||
#+ term=true
|
||||
|
||||
h_db = log10(abs(h))
|
||||
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)"))
|
||||
|
||||
#+
|
||||
|
||||
plot(ws, h_db,
|
||||
xlabel = "Frequency (Hz)", ylabel = "Magnitude (db)")
|
||||
|
||||
#' And again with default options
|
||||
|
||||
h_phase = unwrap(-atan2(imag(h),real(h)))
|
||||
plot(y = h_phase, x = ws, Geom.line,
|
||||
Guide.xlabel("Frequency (Hz)"), Guide.ylabel("Phase (radians)"))
|
||||
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}
|
|
@ -1,18 +1,21 @@
|
|||
% Intro to Weave.jl with Gadfly
|
||||
% Matti Pastell
|
||||
% 20th April 2016
|
||||
---
|
||||
title : Intro to Weave.jl with Gadfly
|
||||
author : Matti Pastell
|
||||
date : 13th December 2016
|
||||
---
|
||||
|
||||
# Introduction
|
||||
# Intro
|
||||
|
||||
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||
be executed using [Weave.jl](https://github.com/mpastell/Weave.jl).
|
||||
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)
|
||||
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.
|
||||
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
|
||||
You can create markdown output or pdf (with xelatex) and HTML directly using
|
||||
the weave command as follows:
|
||||
|
||||
```{julia; eval=false}
|
||||
|
@ -28,8 +31,11 @@ weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), informat="markdown",
|
|||
out_path = :pwd, doctype = "md2pdf")
|
||||
```
|
||||
|
||||
*The documents will be written to the Julia working directory when you
|
||||
use the `out_path = :pwd`.*
|
||||
*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
|
||||
|
||||
|
@ -40,7 +46,7 @@ output will be captured.
|
|||
using Gadfly
|
||||
x = linspace(0, 2*pi)
|
||||
println(x)
|
||||
plot(x = x, y = sin(x))
|
||||
plot(x = x, y = sin.(x))
|
||||
```
|
||||
|
||||
You can also control the way the results are captured, plot size etc.
|
||||
|
@ -56,7 +62,7 @@ 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=8; fig_height=4}
|
||||
```{julia;echo=false; fig_cap="A random walk."; label="random"; fig_width=7; fig_height=4}
|
||||
plot(y = cumsum(randn(1000, 1)), Geom.line)
|
||||
```
|
||||
|
||||
|
@ -64,7 +70,7 @@ plot(y = cumsum(randn(1000, 1)), Geom.line)
|
|||
|
||||
Read the documentation:
|
||||
|
||||
- stable: <http://mpastell.github.io/Weave.jl/stable/>
|
||||
- latest: <http://mpastell.github.io/Weave.jl/latest/>
|
||||
- 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: <https://github.com/mpastell/Weave.jl/tree/master/examples>
|
||||
See other examples in the [GitHub repo](https://github.com/JunoLab/Weave.jl/tree/master/examples)
|
||||
|
|
|
@ -29,10 +29,10 @@
|
|||
\section{Intro}
|
||||
|
||||
This is a minimal example on using PGF format with Gadfly plots in
|
||||
\href{https://github.com/mpastell/Weave.jl}{Weave.jl} document.
|
||||
\href{https://github.com/JunoLab/Weave.jl}{Weave.jl} document.
|
||||
The source is in github:
|
||||
|
||||
\url{https://github.com/mpastell/Weave.jl/blob/master/examples/gadfly_pgf.texw}.
|
||||
\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:
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# Introduction
|
||||
|
||||
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||
be executed using [Weave.jl](https://github.com/mpastell/Weave.jl).
|
||||
be executed using [Weave.jl](https://github.com/JunoLab/Weave.jl).
|
||||
|
||||
The code is delimited from docs using `<<>>=` and `@` markup which can be seen
|
||||
looking at the source document `gadfly_sample.mdw` in the examples directory
|
||||
|
@ -65,6 +65,6 @@ plot(y = cumsum(randn(1000, 1)), Geom.line)
|
|||
Read the documentation:
|
||||
|
||||
- stable: <http://mpastell.github.io/Weave.jl/stable/>
|
||||
- latest: <http://mpastell.github.io/Weave.jl/latest/>
|
||||
- latest: <http://weavejl.mpastell.com/dev/>
|
||||
|
||||
See other examples in: <https://github.com/mpastell/Weave.jl/tree/master/examples>
|
||||
See other examples in: <https://github.com/JunoLab/Weave.jl/tree/master/examples>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||
be executed using Weave. Output from code chunks and PyPlot
|
||||
plots will be included in the weaved document. You also need to install Pweave from Github in order to use Weave.
|
||||
plots will be included in the weaved document. You also need to install Pweave from GitHub in order to use Weave.
|
||||
|
||||
This documented can be turned into Pandoc markdown with captured
|
||||
result from Julia prompt.
|
||||
|
@ -17,7 +17,7 @@ weave("examples/julia_sample.mdw")
|
|||
|
||||
<<term=true>>=
|
||||
x = 1:10
|
||||
d = {"Weave" => "testing"}
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
@
|
||||
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
title: A minimal beamer example using Weave markdown
|
||||
author: Matti Pastell
|
||||
weave_options:
|
||||
doctype : md2pdf
|
||||
out_path : pdf
|
||||
template : beamer.tpl
|
||||
---
|
||||
|
||||
```julia; echo=false
|
||||
struct Begin
|
||||
text
|
||||
title
|
||||
end
|
||||
|
||||
struct End
|
||||
text
|
||||
end
|
||||
Base.show(io::IO, m::MIME"text/latex", b::Begin) = write(io, "\\begin{$(b.text)}[fragile]\n\\frametitle{$(b.title)}\n")
|
||||
Base.show(io::IO, m::MIME"text/latex", e::End) = write(io, "\\end{$(e.text)}")
|
||||
```
|
||||
|
||||
! Begin("frame", "Random plot")
|
||||
|
||||
```julia; out_width="0.5\\textwidth"
|
||||
using Plots
|
||||
scatter(randn(1000), randn(1000))
|
||||
```
|
||||
! End("frame")
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
<<>>=
|
||||
using Plots
|
||||
pyplot()
|
||||
x = linspace(0, 2π, 2056)
|
||||
@
|
||||
|
||||
<<>>=
|
||||
plot(sinc(x))
|
||||
@
|
||||
|
||||
<<>>=
|
||||
plot(-sinc(x))
|
||||
@
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
<<>>=
|
||||
using Plots
|
||||
plotly()
|
||||
x = linspace(0, 2π, 2056)
|
||||
@
|
||||
|
||||
<<>>=
|
||||
plot(sinc(x))
|
||||
@
|
||||
|
||||
<<>>=
|
||||
plot(-sinc(x))
|
||||
@
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
# Introducion to Weave
|
||||
|
||||
This a sample [Julia](http://julialang.org/) noweb document that can
|
||||
be executed using Weave. Output from code chunks and Winston
|
||||
plots will be included in the weaved document. You also need to install Pweave from Github in order to use Weave.
|
||||
|
||||
This documented can be turned into Pandoc markdown with captured
|
||||
result from Julia prompt.
|
||||
|
||||
~~~~{.julia}
|
||||
using Weave
|
||||
weave(Pkg.dir("Weave","examples","winston_sample.mdw"), plotlib="Winston")
|
||||
~~~~
|
||||
|
||||
## Terminal chunk
|
||||
|
||||
<<term=true>>=
|
||||
x = 1:10
|
||||
d = Dict("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
|
434
src/Weave.jl
434
src/Weave.jl
|
@ -1,154 +1,344 @@
|
|||
module Weave
|
||||
using Compat
|
||||
|
||||
#Contains report global properties
|
||||
type Report <: Display
|
||||
cwd::AbstractString
|
||||
basename::AbstractString
|
||||
formatdict::Dict{Symbol,Any}
|
||||
pending_code::AbstractString
|
||||
cur_result::AbstractString
|
||||
fignum::Int
|
||||
figures::Array{AbstractString}
|
||||
term_state::Symbol
|
||||
cur_chunk
|
||||
using Highlights, Mustache, Requires, Pkg, REPL, RelocatableFolders, Base64
|
||||
|
||||
# directories
|
||||
const PKG_DIR = normpath(@__DIR__, "..")
|
||||
const TEMPLATE_DIR = @path joinpath(PKG_DIR, "templates")
|
||||
const STYLESHEET_DIR = @path joinpath(PKG_DIR, "stylesheets")
|
||||
# keeps paths of sample documents for easy try
|
||||
const EXAMPLE_FOLDER = @path joinpath(PKG_DIR, "examples")
|
||||
|
||||
# constant names
|
||||
const WEAVE_OPTION_NAME = "weave_options"
|
||||
const WEAVE_OPTION_NAME_DEPRECATED = "options" # remove this when tagging v0.11
|
||||
const WEAVE_OPTION_DEPRECATE_ID = "weave_option_duplicate_id"
|
||||
const DEFAULT_FIG_PATH = "figures"
|
||||
|
||||
const WEAVE_VERSION = try
|
||||
'v' * Pkg.TOML.parsefile(normpath(PKG_DIR, "Project.toml"))["version"]
|
||||
catch
|
||||
""
|
||||
end
|
||||
weave_info() = WEAVE_VERSION, string(Date(now()))
|
||||
|
||||
function __init__()
|
||||
@require Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" include("plots.jl")
|
||||
@require Gadfly = "c91e804a-d5a3-530f-b6f0-dfbca275c004" include("gadfly.jl")
|
||||
end
|
||||
|
||||
function Report(cwd, basename, formatdict)
|
||||
Report(cwd, basename, formatdict, "", "", 1, AbstractString[], :text, nothing)
|
||||
# utilitity functions
|
||||
take2string!(io) = String(take!(io))
|
||||
joinlines(lines) = join(lines, '\n')
|
||||
|
||||
|
||||
include("types.jl")
|
||||
include("config.jl")
|
||||
include("WeaveMarkdown/markdown.jl")
|
||||
include("display_methods.jl")
|
||||
include("reader/reader.jl")
|
||||
include("run.jl")
|
||||
include("cache.jl")
|
||||
include("rendering/rendering.jl")
|
||||
include("writer/writer.jl")
|
||||
include("converter.jl")
|
||||
|
||||
|
||||
get_format(doctype::AbstractString) = FORMATS[doctype]
|
||||
|
||||
"""
|
||||
list_out_formats()
|
||||
|
||||
List supported output formats with its description.
|
||||
"""
|
||||
list_out_formats() = [k => v.description for (k,v) in FORMATS]
|
||||
|
||||
"""
|
||||
tangle(source::AbstractString; kwargs...)
|
||||
|
||||
Tangle source code from input document to .jl file.
|
||||
|
||||
## Keyword options
|
||||
|
||||
- `informat::Union{Nothing,AbstractString} = nothing`: Input document format. By default (i.e. given `nothing`), Weave will set it automatically based on file extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
|
||||
- `out_path::Union{Symbol,AbstractString} = :doc`: Path where the output is generated can be either of:
|
||||
* `:doc`: Path of the source document (default)
|
||||
* `:pwd`: Julia working directory
|
||||
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
||||
"""
|
||||
function tangle(
|
||||
source::AbstractString;
|
||||
out_path::Union{Symbol,AbstractString} = :doc,
|
||||
informat::Union{Nothing,AbstractString} = nothing,
|
||||
)
|
||||
doc = WeaveDoc(source, informat)
|
||||
doc.cwd = get_cwd(doc, out_path)
|
||||
|
||||
out_path = get_out_path(doc, out_path, "jl")
|
||||
|
||||
open(out_path, "w") do io
|
||||
for chunk in doc.chunks
|
||||
if typeof(chunk) == CodeChunk
|
||||
options = merge(doc.chunk_defaults, chunk.options)
|
||||
options[:tangle] && write(io, chunk.content * "\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@info "Tangled to $(out_path)"
|
||||
end
|
||||
|
||||
"""
|
||||
weave(source::AbstractString; kwargs...)
|
||||
|
||||
#const report = Report()
|
||||
Weave an input document to output file.
|
||||
|
||||
const supported_mime_types =
|
||||
[MIME"image/png",
|
||||
MIME"text/plain"]
|
||||
## Keyword options
|
||||
|
||||
function Base.display(doc::Report, data)
|
||||
for m in supported_mime_types
|
||||
if mimewritable(m(), data)
|
||||
display(doc, m(), data)
|
||||
break
|
||||
- `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
|
||||
|
||||
"""
|
||||
`list_out_formats()`
|
||||
|
||||
List supported output formats
|
||||
"""
|
||||
function list_out_formats()
|
||||
for format = keys(formats)
|
||||
println(string(format,": ", formats[format].description))
|
||||
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
|
||||
|
||||
|
||||
"""
|
||||
`tangle(source ; out_path=:doc, informat="noweb")`
|
||||
notebook(source::AbstractString; kwargs...)
|
||||
|
||||
Tangle source code from input document to .jl file.
|
||||
Convert Weave document `source` to Jupyter Notebook and execute the code
|
||||
using [`nbconvert`](https://nbconvert.readthedocs.io/en/latest/).
|
||||
**Ignores** all chunk options.
|
||||
|
||||
* `informat`: `"noweb"` of `"markdown"`
|
||||
* `out_path`: Path where the output is generated. Can be: `:doc`: Path of the source document, `:pwd`: Julia working directory, `"somepath"`, directory name as a string e.g `"/home/mpastell/weaveout"`
|
||||
or filename as string e.g. ~/outpath/outfile.jl.
|
||||
## 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 tangle(source ; out_path=:doc, informat=:auto)
|
||||
doc = read_doc(source, informat)
|
||||
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")
|
||||
|
||||
outname = get_outname(out_path, doc, ext = "jl")
|
||||
|
||||
open(outname, "w") do io
|
||||
for chunk in doc.chunks
|
||||
if typeof(chunk) == CodeChunk
|
||||
options = merge(rcParams[:chunk_defaults], chunk.options)
|
||||
if options[:tangle]
|
||||
write(io, chunk.content*"\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
doc.cwd == pwd() && (outname = basename(outname))
|
||||
info("Writing to file $outname")
|
||||
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
|
||||
|
||||
|
||||
"""
|
||||
`function weave(source ; doctype = :auto, plotlib="Gadfly",
|
||||
informat=:auto, out_path=:doc, fig_path = "figures", fig_ext = nothing,
|
||||
cache_path = "cache", cache=:off)`
|
||||
include_weave(source::AbstractString, informat::Union{Nothing,AbstractString} = nothing)
|
||||
include_weave(m::Module, source::AbstractString, informat::Union{Nothing,AbstractString} = nothing)
|
||||
|
||||
Weave an input document to output file.
|
||||
|
||||
* `doctype`: :auto = set based on file extension or specify one of the supported formats.
|
||||
See `list_out_formats()`
|
||||
* `plotlib`: `"PyPlot"`, `"Gadfly"` or `nothing`
|
||||
* `informat`: :auto = set based on file extension or set to `"noweb"`, `"markdown"` or `script`
|
||||
* `out_path`: Path where the output is generated. Can be: `:doc`: Path of the source document, `:pwd`: Julia working directory, `"somepath"`: output directory as a String e.g `"/home/mpastell/weaveout"` or filename as string e.g. ~/outpath/outfile.tex.
|
||||
* `fig_path`: where figures will be generated, relative to out_path
|
||||
* `fig_ext`: Extension for saved figures e.g. `".pdf"`, `".png"`. Default setting depends on `doctype`.
|
||||
* `cache_path`: where of cached output will be saved.
|
||||
* `cache`: controls caching of code: `:off` = no caching, `:all` = cache everything,
|
||||
`:user` = cache based on chunk options, `:refresh`, run all code chunks and save new cache.
|
||||
|
||||
**Note:** Run Weave from terminal and not using IJulia, Juno or ESS, they tend to mess with capturing output.
|
||||
Include code from Weave document calling `include_string` on all code from doc.
|
||||
Code is run in the path of the include document.
|
||||
"""
|
||||
function weave(source ; doctype = :auto, plotlib="Gadfly",
|
||||
informat=:auto, out_path=:doc, fig_path = "figures", fig_ext = nothing,
|
||||
cache_path = "cache", cache=:off)
|
||||
|
||||
doc = read_doc(source, informat)
|
||||
doc = run(doc, doctype = doctype, plotlib=plotlib,
|
||||
out_path=out_path,
|
||||
fig_path = fig_path, fig_ext = fig_ext, cache_path = cache_path, cache=cache)
|
||||
formatted = format(doc)
|
||||
|
||||
formatted = join(formatted, "\n")
|
||||
|
||||
outname = get_outname(out_path, doc)
|
||||
|
||||
open(outname, "w") do io
|
||||
write(io, formatted)
|
||||
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
|
||||
|
||||
#Convert using pandoc
|
||||
if doc.doctype == "md2html"
|
||||
outname = get_outname(out_path, doc, ext = "html")
|
||||
pandoc2html(formatted, doc, outname)
|
||||
elseif doc.doctype == "md2pdf"
|
||||
outname = get_outname(out_path, doc, ext = "pdf")
|
||||
pandoc2pdf(formatted, doc, outname)
|
||||
end
|
||||
|
||||
doc.cwd == pwd() && (outname = basename(outname))
|
||||
|
||||
info("Report weaved to $outname")
|
||||
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
|
||||
|
||||
function Base.display(report::Report, m::MIME"text/plain", data)
|
||||
s = reprmime(m, data)
|
||||
print("\n" * s)
|
||||
#report.cur_result *= "\n" * s
|
||||
end
|
||||
|
||||
function weave(doc::AbstractString, doctype::AbstractString)
|
||||
weave(doc, doctype=doctype)
|
||||
end
|
||||
|
||||
export weave, list_out_formats, tangle,
|
||||
set_chunk_defaults, get_chunk_defaults, restore_chunk_defaults
|
||||
|
||||
include("config.jl")
|
||||
include("chunks.jl")
|
||||
include("readers.jl")
|
||||
include("run.jl")
|
||||
include("cache.jl")
|
||||
include("formatters.jl")
|
||||
include("pandoc.jl")
|
||||
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
|
70
src/cache.jl
70
src/cache.jl
|
@ -1,38 +1,64 @@
|
|||
import JLD
|
||||
# Serialization is imported only if cache is used
|
||||
|
||||
function write_cache(doc::WeaveDoc, cache_path)
|
||||
cache_dir = "$(doc.cwd)/$cache_path"
|
||||
isdir(cache_dir) || mkpath(cache_dir)
|
||||
JLD.save("$cache_dir/$(doc.basename).jld", Dict("doc" => doc))
|
||||
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 = "$(doc.cwd)/$cache_path/$(doc.basename).jld"
|
||||
isfile(name) || return nothing
|
||||
return JLD.load(name)["doc"]
|
||||
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)
|
||||
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 = Any[]
|
||||
# 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.result_no = c.result_no
|
||||
newc.figures = c.figures
|
||||
newc.result = c.result
|
||||
newc.output = c.output
|
||||
push!(new_chunks, newc)
|
||||
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
|
||||
|
||||
#Could be used to restore inline code in future
|
||||
function restore_chunk(chunk::DocChunk, cached)
|
||||
return chunk
|
||||
# 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,52 +0,0 @@
|
|||
|
||||
type WeaveDoc
|
||||
source::AbstractString
|
||||
basename::AbstractString
|
||||
path::AbstractString
|
||||
chunks::Array
|
||||
cwd::AbstractString
|
||||
format
|
||||
doctype::AbstractString
|
||||
function WeaveDoc(source, chunks)
|
||||
path, fname = splitdir(abspath(source))
|
||||
basename = splitext(fname)[1]
|
||||
new(source, basename, path, chunks, "", nothing, "")
|
||||
end
|
||||
end
|
||||
|
||||
immutable ChunkOutput
|
||||
code::AbstractString
|
||||
stdout::AbstractString
|
||||
displayed::AbstractString
|
||||
figures::Array{AbstractString}
|
||||
end
|
||||
|
||||
type CodeChunk
|
||||
content::AbstractString
|
||||
number::Int
|
||||
result_no::Int
|
||||
start_line::Int
|
||||
optionstring::AbstractString
|
||||
options::Dict{Symbol, Any}
|
||||
output::AbstractString
|
||||
figures::Array{AbstractString}
|
||||
result::Array{ChunkOutput}
|
||||
function CodeChunk(content, number, start_line, optionstring, options)
|
||||
new(content, number, 0, start_line, optionstring, options, "", AbstractString[], ChunkOutput[])
|
||||
end
|
||||
end
|
||||
|
||||
type DocChunk
|
||||
content::AbstractString
|
||||
number::Int
|
||||
start_line::Int
|
||||
end
|
||||
|
||||
type TermResult
|
||||
end
|
||||
|
||||
type ScriptResult
|
||||
end
|
||||
|
||||
type CollectResult
|
||||
end
|
142
src/config.jl
142
src/config.jl
|
@ -1,84 +1,58 @@
|
|||
|
||||
|
||||
#Default options
|
||||
const defaultParams =
|
||||
@compat Dict{Symbol,Any}(:plotlib => "Gadfly",
|
||||
:storeresults => false,
|
||||
:doc_number => 0,
|
||||
:chunk_defaults =>
|
||||
Dict{Symbol,Any}(
|
||||
:echo=> true,
|
||||
:results=> "markup",
|
||||
:hold => false,
|
||||
:fig=> true,
|
||||
:include=> true,
|
||||
:eval => true,
|
||||
:tangle => true,
|
||||
:cache => false,
|
||||
:fig_cap=> nothing,
|
||||
#Size in inches
|
||||
:fig_width => 6,
|
||||
:fig_height => 4,
|
||||
:fig_path=> "figures",
|
||||
:dpi => 96,
|
||||
:term=> false,
|
||||
:name=> nothing,
|
||||
:wrap=> true,
|
||||
:line_width => 75,
|
||||
:engine=> "julia",
|
||||
#:option_AbstractString=> "",
|
||||
#Defined in formats
|
||||
:fig_ext => nothing,
|
||||
:fig_pos=> nothing,
|
||||
:fig_env=> nothing,
|
||||
:out_width=> nothing,
|
||||
:out_height=> nothing,
|
||||
)
|
||||
)
|
||||
#This one can be changed at runtime, initially a copy of defaults
|
||||
const rcParams = deepcopy(defaultParams)
|
||||
|
||||
#Parameters set per document
|
||||
const docParams =Dict{Symbol,Any}(
|
||||
:fig_path=> nothing,
|
||||
:fig_ext => nothing,
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
`set_chunk_defaults(opts::Dict{Symbol, Any})`
|
||||
|
||||
Set default options for code chunks, use get_chunk_defaults
|
||||
to see the current values.
|
||||
|
||||
e.g. set default dpi to 200 and fig_width to 8
|
||||
|
||||
```
|
||||
julia> set_chunk_defaults(Dict{Symbol, Any}(:dpi => 200, fig_width => 8))
|
||||
```
|
||||
"""
|
||||
function set_chunk_defaults(opts::Dict{Symbol, Any})
|
||||
merge!(rcParams[:chunk_defaults], opts)
|
||||
end
|
||||
|
||||
"""
|
||||
`get_chunk_defaults()`
|
||||
|
||||
Get default options used for code chunks.
|
||||
"""
|
||||
function get_chunk_defaults()
|
||||
return(rcParams[:chunk_defaults])
|
||||
end
|
||||
|
||||
"""
|
||||
`restore_chunk_defaults()`
|
||||
|
||||
Restore Weave.jl default chunk options
|
||||
"""
|
||||
function restore_chunk_defaults()
|
||||
rcParams[:chunk_defaults] = defaultParams[:chunk_defaults]
|
||||
merge!(rcParams[:chunk_defaults], docParams)
|
||||
return nothing
|
||||
end
|
||||
# TODO: follow RMarkdown convention more
|
||||
const _DEFAULT_PARAMS = Dict{Symbol,Any}(
|
||||
:echo => true,
|
||||
:results => "markup",
|
||||
:hold => false,
|
||||
:fig => true,
|
||||
:eval => true,
|
||||
:error => true,
|
||||
:tangle => true,
|
||||
:cache => false,
|
||||
:fig_cap => nothing,
|
||||
# NOTE: size in inches
|
||||
:fig_width => 6,
|
||||
:fig_height => 4,
|
||||
:fig_path => DEFAULT_FIG_PATH,
|
||||
:dpi => 96,
|
||||
:term => false,
|
||||
:prompt => "julia>",
|
||||
:label => nothing,
|
||||
:wrap => true,
|
||||
:line_width => 75,
|
||||
:fig_ext => nothing,
|
||||
:fig_pos => nothing,
|
||||
:fig_env => nothing,
|
||||
:out_width => nothing,
|
||||
:out_height => nothing,
|
||||
)
|
||||
const DEFAULT_PARAMS = deepcopy(_DEFAULT_PARAMS) # might be changed at runtime
|
||||
|
||||
"""
|
||||
set_chunk_defaults!(k, v)
|
||||
set_chunk_defaults!(kv::Pair...)
|
||||
set_chunk_defaults!(opts::AbstractDict)
|
||||
|
||||
Set default options for code chunks, use [`get_chunk_defaults`](@ref) to see the current values.
|
||||
|
||||
E.g.: all the three examples below will set default `dpi` to `200` and `fig_width` to `8`:
|
||||
- `set_chunk_defaults!(:dpi, 200); set_chunk_defaults!(:fig_width, 8)`
|
||||
- `set_chunk_defaults!(:dpi => 200, :fig_width => 8)`
|
||||
- `set_chunk_defaults!(Dict(:dpi => 200, :fig_width => 8))`
|
||||
"""
|
||||
set_chunk_defaults!(k, v) = DEFAULT_PARAMS[k]= v
|
||||
set_chunk_defaults!(kv::Pair...) = for (k,v) in kv; set_chunk_defaults!(k, v); end
|
||||
set_chunk_defaults!(opts::AbstractDict) = merge!(DEFAULT_PARAMS, opts)
|
||||
|
||||
"""
|
||||
get_chunk_defaults()
|
||||
|
||||
Get default options used for code chunks.
|
||||
"""
|
||||
get_chunk_defaults() = DEFAULT_PARAMS
|
||||
|
||||
"""
|
||||
restore_chunk_defaults!()
|
||||
|
||||
Restore Weave.jl default chunk options.
|
||||
"""
|
||||
restore_chunk_defaults!() = for (k,v) in _DEFAULT_PARAMS; DEFAULT_PARAMS[k] = v; end
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
using JSON, Mustache
|
||||
|
||||
"""
|
||||
convert_doc(infile::AbstractString, outfile::AbstractString; outformat::Union{Nothing,AbstractString} = nothing)
|
||||
|
||||
Convert Weave documents between different formats
|
||||
|
||||
- `infile`: Path of the input document
|
||||
- `outfile`: Path of the output document
|
||||
- `outformat = nothing`: Output document format (optional). By default (i.e. given `nothing`) Weave will try to automatically detect it from the `outfile`'s extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
|
||||
"""
|
||||
function convert_doc(
|
||||
infile::AbstractString,
|
||||
outfile::AbstractString;
|
||||
outformat::Union{Nothing,AbstractString} = nothing,
|
||||
)
|
||||
doc = WeaveDoc(infile)
|
||||
|
||||
if isnothing(outformat)
|
||||
ext = lowercase(splitext(outfile)[2])
|
||||
outformat =
|
||||
ext == ".jl" ? "script" :
|
||||
ext == ".jmd" ? "markdown" :
|
||||
ext == ".ipynb" ? "notebook" :
|
||||
"noweb" # fallback
|
||||
end
|
||||
|
||||
converted = _convert_doc(doc, outformat)
|
||||
|
||||
open(outfile, "w") do f
|
||||
write(f, converted)
|
||||
end
|
||||
return outfile
|
||||
end
|
||||
|
||||
function _convert_doc(doc, outformat)
|
||||
outformat == "script" ? convert_to_script(doc) :
|
||||
outformat == "markdown" ? convert_to_markdown(doc) :
|
||||
outformat == "notebook" ? convert_to_notebook(doc) :
|
||||
convert_to_noweb(doc)
|
||||
end
|
||||
|
||||
function convert_to_script(doc)
|
||||
output = ""
|
||||
for chunk in doc.chunks
|
||||
if typeof(chunk) == Weave.DocChunk
|
||||
content = join([repr(c) for c in chunk.content], "")
|
||||
output *= join(["#' " * s for s in split(content, "\n")], "\n")
|
||||
else
|
||||
output *= "\n#+ "
|
||||
isempty(chunk.optionstring) || (output *= strip(chunk.optionstring))
|
||||
output *= "\n\n" * lstrip(chunk.content)
|
||||
output *= "\n"
|
||||
end
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
function convert_to_markdown(doc)
|
||||
output = ""
|
||||
for chunk in doc.chunks
|
||||
if isa(chunk, DocChunk)
|
||||
output *= join([repr(c) for c in chunk.content], "")
|
||||
else
|
||||
output *= "\n" * "```julia"
|
||||
isempty(chunk.optionstring) || (output *= ";" * chunk.optionstring)
|
||||
output *= "\n" * lstrip(chunk.content)
|
||||
output *= "```\n"
|
||||
end
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
function convert_to_notebook(doc)
|
||||
nb = Dict()
|
||||
nb["nbformat"] = 4
|
||||
nb["nbformat_minor"] = 2
|
||||
metadata = Dict()
|
||||
kernelspec = Dict()
|
||||
kernelspec["language"] = "julia"
|
||||
kernelspec["name"] = "julia-$(VERSION.major).$(VERSION.minor)"
|
||||
kernelspec["display_name"] = "Julia $(VERSION.major).$(VERSION.minor).$(VERSION.patch)"
|
||||
metadata["kernelspec"] = kernelspec
|
||||
language_info = Dict()
|
||||
language_info["file_extension"] = ".jl"
|
||||
language_info["mimetype"] = "application/julia"
|
||||
language_info["name"] = "julia"
|
||||
language_info["version"] = "$(VERSION.major).$(VERSION.minor).$(VERSION.patch)"
|
||||
metadata["language_info"] = language_info
|
||||
cells = []
|
||||
ex_count = 1
|
||||
|
||||
for chunk in doc.chunks
|
||||
if isa(chunk, DocChunk)
|
||||
push!(
|
||||
cells,
|
||||
Dict(
|
||||
"cell_type" => "markdown",
|
||||
"metadata" => Dict(),
|
||||
"source" => [strip(join([repr(c) for c in chunk.content], ""))],
|
||||
),
|
||||
)
|
||||
else
|
||||
push!(
|
||||
cells,
|
||||
Dict(
|
||||
"cell_type" => "code",
|
||||
"metadata" => Dict(),
|
||||
"source" => [strip(chunk.content)],
|
||||
"execution_count" => nothing,
|
||||
"outputs" => [],
|
||||
),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
nb["cells"] = cells
|
||||
nb["metadata"] = metadata
|
||||
|
||||
json_nb = JSON.json(nb, 2)
|
||||
return json_nb
|
||||
end
|
||||
|
||||
function convert_to_noweb(doc)
|
||||
output = ""
|
||||
for chunk in doc.chunks
|
||||
if isa(chunk, DocChunk)
|
||||
output *= join([repr(c) for c in chunk.content], "")
|
||||
else
|
||||
output *= "\n" * "<<"
|
||||
isempty(chunk.optionstring) || (output *= strip(chunk.optionstring))
|
||||
output *= ">>="
|
||||
output *= "\n" * lstrip(chunk.content)
|
||||
output *= "@\n"
|
||||
end
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
Base.repr(c::InlineText) = c.content
|
||||
Base.repr(c::InlineCode) = "`j $(c.content)`"
|
|
@ -0,0 +1,133 @@
|
|||
using Markdown, .WeaveMarkdown
|
||||
|
||||
# Contains report global properties
|
||||
mutable struct Report <: AbstractDisplay
|
||||
cwd::String
|
||||
basename::String
|
||||
format::WeaveFormat
|
||||
rich_output::String
|
||||
fignum::Int
|
||||
figures::Vector{String}
|
||||
cur_chunk::Union{Nothing,CodeChunk}
|
||||
mimetypes::Vector{String}
|
||||
first_plot::Bool
|
||||
header_script::String
|
||||
end
|
||||
|
||||
Report(cwd, basename, format, mimetypes) =
|
||||
Report(cwd, basename, format, "", 1, String[], nothing, mimetypes, true, "")
|
||||
|
||||
# Default mimetypes in order, can be overridden for some inside `run method` formats
|
||||
const default_mime_types = ["image/svg+xml", "image/png", "text/html", "text/plain"]
|
||||
# const default_mime_types = ["image/png", "image/svg+xml", "text/html", "text/plain"]
|
||||
# From IJulia as a reminder
|
||||
# const supported_mime_types = [ "text/html", "text/latex", "image/svg+xml", "image/png", "image/jpeg", "text/plain", "text/markdown" ]
|
||||
|
||||
const mimetype_ext = Dict(
|
||||
".png" => "image/png",
|
||||
".jpg" => "image/jpeg",
|
||||
".jpeg" => "image/jpeg",
|
||||
".svg" => "image/svg+xml",
|
||||
".js.svg" => "image/svg+xml",
|
||||
".pdf" => "application/pdf",
|
||||
".ps" => "application/postscript",
|
||||
".tex" => "text/latex",
|
||||
)
|
||||
|
||||
function Base.display(report::Report, data)
|
||||
# Set preferred mimetypes for report based on format
|
||||
fig_ext = report.cur_chunk.options[:fig_ext]
|
||||
for m in unique([mimetype_ext[fig_ext]; report.mimetypes])
|
||||
if Base.invokelatest(showable, m, data)
|
||||
try
|
||||
if !istextmime(m)
|
||||
Base.invokelatest(display, report, m, data)
|
||||
elseif report.cur_chunk.options[:term]
|
||||
Base.invokelatest(display, report, "text/plain", data)
|
||||
else
|
||||
Base.invokelatest(display, report, m, data)
|
||||
end
|
||||
catch e
|
||||
throw(e)
|
||||
@warn("Failed to display data in \"$m\" format")
|
||||
continue
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Base.display(report::Report, m::MIME"image/png", data) = add_figure(report, data, m, ".png")
|
||||
|
||||
Base.display(report::Report, m::MIME"image/svg+xml", data) = add_figure(report, data, m, ".svg")
|
||||
|
||||
Base.display(report::Report, m::MIME"application/pdf", data) = add_figure(report, data, m, ".pdf")
|
||||
|
||||
# Text is written to stdout, called from "term" mode chunks
|
||||
function Base.display(report::Report, m::MIME"text/plain", data)
|
||||
io = PipeBuffer()
|
||||
show(IOContext(io, :limit => true), m, data)
|
||||
flush(io)
|
||||
s = read(io, String)
|
||||
close(io)
|
||||
println(s)
|
||||
end
|
||||
|
||||
function Base.display(report::Report, m::MIME"text/plain", data::Exception)
|
||||
println("Error: " * sprint(showerror, data))
|
||||
end
|
||||
|
||||
function Base.display(report::Report, m::MIME"text/html", data::Exception)
|
||||
report.rich_output = sprint(show, m, data)
|
||||
end
|
||||
|
||||
function Base.show(io, m::MIME"text/html", data::Exception)
|
||||
println(io, "<pre class=\"julia-error\">")
|
||||
println(io, Markdown.htmlesc("ERROR: " * sprint(showerror, data)))
|
||||
println(io, "</pre>")
|
||||
end
|
||||
|
||||
# Catch "rich_output"
|
||||
function Base.display(report::Report, m::MIME"text/html", data)
|
||||
io = IOBuffer()
|
||||
show(IOContext(io, :limit => true), m, data)
|
||||
report.rich_output *= string('\n', take2string!(io))
|
||||
end
|
||||
|
||||
# Catch "rich_output"
|
||||
function Base.display(report::Report, m::MIME"text/markdown", data)
|
||||
s = repr(m, data)
|
||||
# Convert to "richer" type of possible
|
||||
for m in report.mimetypes
|
||||
if m == "text/html" || m == "text/latex"
|
||||
display(Markdown.parse(s, flavor = WeaveMarkdown.weavemd))
|
||||
break
|
||||
elseif m == "text/markdown"
|
||||
report.rich_output *= "\n" * s
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Base.display(report::Report, m::MIME"text/latex", data)
|
||||
s = repr(m, data)
|
||||
report.rich_output *= string('\n', s)
|
||||
end
|
||||
|
||||
"""Add saved figure name to results and return the name"""
|
||||
function add_figure(report::Report, data, m, ext)
|
||||
chunk = report.cur_chunk
|
||||
full_name, rel_name = get_figname(report, chunk, ext = ext)
|
||||
|
||||
open(full_name, "w") do io
|
||||
if ext == ".pdf"
|
||||
write(io, repr(m, data))
|
||||
else
|
||||
show(io, m, data)
|
||||
end
|
||||
end
|
||||
|
||||
push!(report.figures, rel_name)
|
||||
report.fignum += 1
|
||||
return full_name
|
||||
end
|
|
@ -1,465 +0,0 @@
|
|||
|
||||
function format(doc::WeaveDoc)
|
||||
formatted = AbstractString[]
|
||||
docformat = doc.format
|
||||
|
||||
#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(doc.chunks)
|
||||
result = format_chunk(chunk, formatdict, docformat)
|
||||
push!(formatted, result)
|
||||
end
|
||||
|
||||
return formatted
|
||||
end
|
||||
|
||||
|
||||
function format_chunk(chunk::DocChunk, formatdict, docformat)
|
||||
return chunk.content
|
||||
end
|
||||
|
||||
|
||||
function format_chunk(chunk::CodeChunk, formatdict, docformat)
|
||||
#Fill undefined options with format specific defaults
|
||||
chunk.options[:out_width] == nothing &&
|
||||
(chunk.options[:out_width] = formatdict[:out_width])
|
||||
chunk.options[:fig_pos] == nothing &&
|
||||
(chunk.options[:fig_pos] = formatdict[:fig_pos])
|
||||
|
||||
#Only use floats if chunk has caption or sets fig_env
|
||||
if chunk.options[:fig_cap] != nothing && chunk.options[:fig_env] == nothing
|
||||
(chunk.options[:fig_env] = formatdict[:fig_env])
|
||||
end
|
||||
|
||||
|
||||
if haskey(formatdict, :indent)
|
||||
chunk.content = indent(chunk.content, formatdict[:indent])
|
||||
end
|
||||
|
||||
if !chunk.options[:eval]
|
||||
if chunk.options[:echo]
|
||||
result = "$(formatdict[:codestart])$(chunk.content)\n$(formatdict[:codeend])"
|
||||
return result
|
||||
else
|
||||
r = ""
|
||||
return r
|
||||
end
|
||||
end
|
||||
|
||||
if chunk.options[:term]
|
||||
result = format_termchunk(chunk, formatdict)
|
||||
else
|
||||
|
||||
if chunk.options[:echo]
|
||||
result = "$(formatdict[:codestart])$(chunk.content)\n$(formatdict[:codeend])\n"
|
||||
else
|
||||
result = ""
|
||||
end
|
||||
|
||||
if (strip(chunk.output)!= "") && (chunk.options[:results] != "hidden")
|
||||
if chunk.options[:results] != "markup" && chunk.options[:results] != "hold"
|
||||
result *= "$(chunk.output)\n"
|
||||
else
|
||||
if chunk.options[:wrap]
|
||||
chunk.output = "\n" * wraplines(chunk.output,
|
||||
chunk.options[:line_width])
|
||||
end
|
||||
|
||||
if haskey(formatdict, :indent)
|
||||
chunk.output = indent(chunk.output, formatdict[:indent])
|
||||
end
|
||||
result *= "$(formatdict[:outputstart])$(chunk.output)\n$(formatdict[:outputend])\n"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#Handle figures
|
||||
if chunk.options[:fig] && length(chunk.figures) > 0
|
||||
if chunk.options[:include]
|
||||
result *= formatfigures(chunk, docformat)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function format_termchunk(chunk, formatdict)
|
||||
if chunk.options[:echo] && chunk.options[:results] != "hidden"
|
||||
result = "$(formatdict[:termstart])$(chunk.output)\n" * "$(formatdict[:termend])\n"
|
||||
#chunk.options[: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
|
||||
|
||||
|
||||
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 result
|
||||
return strip(join(result, "\n"))
|
||||
end
|
||||
|
||||
function wrapline(text, line_width=75)
|
||||
result = ""
|
||||
while length(text) > line_width
|
||||
result*= text[1:line_width] * "\n"
|
||||
text = text[(line_width+1):end]
|
||||
end
|
||||
result *= text
|
||||
end
|
||||
|
||||
|
||||
type Tex
|
||||
description::AbstractString
|
||||
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 Pandoc
|
||||
description::AbstractString
|
||||
formatdict::Dict{Symbol,Any}
|
||||
end
|
||||
|
||||
|
||||
const pandoc = Pandoc("Pandoc markdown",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => "~~~~{.julia}",
|
||||
:codeend=>"~~~~~~~~~~~~~\n\n",
|
||||
:outputstart=>"~~~~{.julia}",
|
||||
:outputend=>"~~~~~~~~~~~~~\n\n",
|
||||
:fig_ext=>".png",
|
||||
:out_width=>nothing,
|
||||
:extension=>"md",
|
||||
:doctype=>"pandoc"
|
||||
))
|
||||
|
||||
|
||||
const md2html = Pandoc("Markdown to HTML (requires Pandoc)",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => "````julia",
|
||||
:codeend=> "````\n\n",
|
||||
:outputstart=> "````julia",
|
||||
:outputend=> "````\n\n",
|
||||
:fig_ext=> ".svg",
|
||||
:extension=> "md",
|
||||
:doctype=> "md2html"))
|
||||
|
||||
const md2pdf = Pandoc("Markdown to pdf (requires Pandoc and xelatex)",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => "````julia",
|
||||
:codeend=> "````\n\n",
|
||||
:outputstart=> "````julia",
|
||||
:outputend=> "````\n\n",
|
||||
:fig_ext=> ".pdf",
|
||||
:extension=> "md",
|
||||
:doctype=> "md2pdf"))
|
||||
|
||||
|
||||
|
||||
type Markdown
|
||||
description::AbstractString
|
||||
formatdict::Dict{Symbol,Any}
|
||||
end
|
||||
|
||||
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 MultiMarkdown
|
||||
description::AbstractString
|
||||
formatdict::Dict{Symbol,Any}
|
||||
end
|
||||
|
||||
const multimarkdown = MultiMarkdown("MultiMarkdown",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => "````julia",
|
||||
:codeend=> "````\n\n",
|
||||
:outputstart=> "````julia",
|
||||
:outputend=> "````\n\n",
|
||||
:fig_ext=> ".png",
|
||||
:extension=> "md",
|
||||
:doctype=> "github"
|
||||
))
|
||||
|
||||
|
||||
type Rest
|
||||
description::AbstractString
|
||||
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"
|
||||
))
|
||||
|
||||
type AsciiDoc
|
||||
description::AbstractString
|
||||
formatdict::Dict{Symbol,Any}
|
||||
end
|
||||
|
||||
#asciidoc -b html5 -a source-highlighter=pygments ...
|
||||
const adoc = AsciiDoc("AsciiDoc",
|
||||
@compat Dict{Symbol,Any}(
|
||||
:codestart => "[source,julia]\n--------------------------------------",
|
||||
:codeend => "--------------------------------------\n\n",
|
||||
:outputstart => "--------------------------------------",
|
||||
:outputend => "--------------------------------------\n\n",
|
||||
:fig_ext => ".png",
|
||||
:extension => "txt",
|
||||
:out_width => "600",
|
||||
:doctype => "asciidoc"
|
||||
))
|
||||
|
||||
|
||||
function formatfigures(chunk, docformat::Tex)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
width = chunk.options[:out_width]
|
||||
f_pos = chunk.options[:fig_pos]
|
||||
f_env = chunk.options[:fig_env]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
|
||||
|
||||
if f_env != nothing
|
||||
result *= """\\begin{$f_env}[$f_pos]\n"""
|
||||
end
|
||||
|
||||
|
||||
for fig = fignames
|
||||
if splitext(fig)[2] == ".tex" #Tikz figures
|
||||
figstring *= "\\resizebox{$width}{!}{\\input{$fig}}\n"
|
||||
else
|
||||
figstring *= "\\includegraphics[width=$width]{$fig}\n"
|
||||
end
|
||||
end
|
||||
|
||||
# Figure environment
|
||||
if caption != nothing
|
||||
result *= string("\\center\n",
|
||||
"$figstring",
|
||||
"\\caption{$caption}\n")
|
||||
else
|
||||
result *= figstring
|
||||
end
|
||||
|
||||
if chunk.options[:name] != nothing && f_env !=nothing
|
||||
label = chunk.options[:name]
|
||||
result *= "\\label{fig:$label}\n"
|
||||
end
|
||||
|
||||
|
||||
if f_env != nothing
|
||||
result *= "\\end{$f_env}\n"
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function formatfigures(chunk, docformat::Pandoc)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
result = ""
|
||||
figstring = ""
|
||||
attribs = ""
|
||||
width = chunk.options[:out_width]
|
||||
width == nothing || (attribs = "{width=$width}")
|
||||
|
||||
length(fignames) > 0 || (return "")
|
||||
|
||||
if caption != nothing
|
||||
result *= "![$caption]($(fignames[1]))$attribs\n"
|
||||
for fig = 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
|
||||
|
||||
function formatfigures(chunk, docformat::Markdown)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[: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::MultiMarkdown)
|
||||
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 caption != nothing
|
||||
result *= "![$caption][$(fignames[1])]\n\n"
|
||||
result *= "[$(fignames[1])]: $(fignames[1]) $width\n"
|
||||
for fig = 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
|
||||
|
||||
|
||||
function formatfigures(chunk, docformat::Rest)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
width = chunk.options[: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
|
||||
|
||||
|
||||
function formatfigures(chunk, docformat::AsciiDoc)
|
||||
fignames = chunk.figures
|
||||
caption = chunk.options[:fig_cap]
|
||||
width = chunk.options[:out_width]
|
||||
result = ""
|
||||
figstring = ""
|
||||
|
||||
|
||||
for fig=fignames
|
||||
figstring *= @sprintf("image::%s[width=%s]\n", fig, width)
|
||||
end
|
||||
|
||||
|
||||
if caption != nothing
|
||||
result *= string("image::$(fignames[1])",
|
||||
"[width=$width,",
|
||||
"title=\"$caption\"]")
|
||||
else
|
||||
result *= figstring
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#Add new supported formats here
|
||||
const formats = @compat Dict{AbstractString, Any}("tex" => tex,
|
||||
"texminted" => texminted,
|
||||
"pandoc" => pandoc,
|
||||
"md2html" => md2html,
|
||||
"md2pdf" => md2pdf,
|
||||
"github" => github,
|
||||
"multimarkdown" => multimarkdown,
|
||||
"rst" => rst,
|
||||
"asciidoc" => adoc
|
||||
)
|
|
@ -1,41 +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
|
||||
full_name, rel_name = get_figname(report, chunk)
|
||||
|
||||
docformat = formats[report.formatdict[:doctype]]
|
||||
push!(report.figures, rel_name)
|
||||
|
||||
report.fignum += 1
|
||||
|
||||
w = chunk.options[:fig_width]inch
|
||||
h = chunk.options[:fig_height]inch
|
||||
w = chunk.options[:fig_width] * Gadfly.inch
|
||||
h = chunk.options[:fig_height] * Gadfly.inch
|
||||
format = chunk.options[:fig_ext]
|
||||
dpi = chunk.options[:dpi]
|
||||
|
||||
#This is probably not the correct way to handle different formats, but it works.
|
||||
if format == ".png"
|
||||
try
|
||||
draw(PNG(full_name, w, h, dpi=dpi), p)
|
||||
catch
|
||||
draw(PNG(full_name, w, h), p) #Compose < 0.3.1, Gadfly < 0.3.1
|
||||
end
|
||||
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)
|
||||
full_name, rel_name = Weave.get_figname(report, chunk, ext = format)
|
||||
|
||||
push!(report.figures, rel_name)
|
||||
report.fignum += 1
|
||||
|
||||
if format == ".svg"
|
||||
Gadfly.draw(Gadfly.SVG(full_name, w, h), p)
|
||||
elseif format == ".js.svg"
|
||||
draw(SVGJS(full_name, w, h), p)
|
||||
Gadfly.draw(Gadfly.SVGJS(full_name, w, h), p)
|
||||
elseif format == ".png"
|
||||
Gadfly.draw(Gadfly.PNG(full_name, w, h, dpi = dpi), p)
|
||||
elseif format == ".pdf"
|
||||
Gadfly.draw(Gadfly.PDF(full_name, w, h), p)
|
||||
elseif format == ".ps"
|
||||
Gadfly.draw(Gadfly.PS(full_name, w, h), p)
|
||||
elseif format == ".tex"
|
||||
draw(PGF(full_name, w, h, true ), p)
|
||||
else:
|
||||
warn("Can't save figure. Unsupported format")
|
||||
Gadfly.draw(Gadfly.PGF(full_name, w, h, true), p)
|
||||
else
|
||||
@warn("Can't save figure. Unsupported format, $format")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
|
||||
|
||||
"""
|
||||
`pandoc2html(formatted::AbstractString, doc::WeaveDoc)`
|
||||
|
||||
Convert output from pandoc markdown to html using Weave.jl template
|
||||
"""
|
||||
function pandoc2html(formatted::AbstractString, doc::WeaveDoc, outname::AbstractString)
|
||||
html_template = joinpath(Pkg.dir("Weave"), "templates/pandoc_skeleton.html")
|
||||
css_template = joinpath(Pkg.dir("Weave"), "templates/pandoc_skeleton.css")
|
||||
|
||||
path, wsource = splitdir(abspath(doc.source))
|
||||
wversion = string(Pkg.installed("Weave"))
|
||||
wtime = Date(now())
|
||||
|
||||
#Change path for pandoc
|
||||
old_wd = pwd()
|
||||
cd(doc.cwd)
|
||||
html =""
|
||||
outname = basename(outname)
|
||||
|
||||
try
|
||||
open(`pandoc -R -s --mathjax="" --self-contained --highlight-style=tango
|
||||
--template $html_template --include-in-header=$css_template
|
||||
-V wversion=$wversion -V wtime=$wtime -V wsource=$wsource
|
||||
-o $outname`, "w", STDOUT) do io
|
||||
println(io, formatted)
|
||||
end
|
||||
cd(old_wd)
|
||||
catch
|
||||
cd(old_wd)
|
||||
error("Unable to convert to html, check that you have pandoc installed and in your path")
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
`pandoc2pdf(formatted::AbstractString, doc::WeaveDoc)`
|
||||
|
||||
Convert output from pandoc markdown to pdf using Weave.jl template
|
||||
"""
|
||||
function pandoc2pdf(formatted::AbstractString, doc::WeaveDoc, outname::AbstractString)
|
||||
|
||||
header_template = joinpath(Pkg.dir("Weave"), "templates/pandoc_header.txt")
|
||||
|
||||
path, wsource = splitdir(abspath(doc.source))
|
||||
wversion = string(Pkg.installed("Weave"))
|
||||
wtime = Date(now())
|
||||
outname = basename(outname)
|
||||
|
||||
#Change path for pandoc
|
||||
old_wd = pwd()
|
||||
cd(doc.cwd)
|
||||
html =""
|
||||
|
||||
info("Done executing code. Running xelatex")
|
||||
try
|
||||
open(`pandoc -R -s --latex-engine=xelatex --highlight-style=tango
|
||||
--include-in-header=$header_template
|
||||
-V fontsize=12pt
|
||||
-o $outname`, "w", STDOUT) do io
|
||||
println(io, formatted)
|
||||
end
|
||||
cd(old_wd)
|
||||
catch
|
||||
cd(old_wd)
|
||||
error("Unable to convert to pdf, check that you have pandoc and xelatex installed and in your path")
|
||||
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
|
|
@ -1,22 +0,0 @@
|
|||
using PyPlot
|
||||
|
||||
function savefigs_pyplot(report::Report)
|
||||
chunk = report.cur_chunk
|
||||
fignames = AbstractString[]
|
||||
ext = report.formatdict[:fig_ext]
|
||||
figpath = joinpath(report.cwd, chunk.options[:fig_path])
|
||||
isdir(figpath) || mkdir(figpath)
|
||||
chunkid = (chunk.options[:name] == nothing) ? chunk.number : chunk.options[: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.options[:dpi])
|
||||
push!(report.figures, rel_name)
|
||||
report.fignum += 1
|
||||
plt[:draw]()
|
||||
plt[:close]()
|
||||
end
|
||||
#return fignames
|
||||
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
|
226
src/readers.jl
226
src/readers.jl
|
@ -1,226 +0,0 @@
|
|||
pushopt(options::Dict,expr::Expr) = Base.Meta.isexpr(expr,:(=)) && (options[expr.args[1]] = expr.args[2])
|
||||
|
||||
type MarkupInput
|
||||
codestart::Regex
|
||||
codeend::Regex
|
||||
end
|
||||
|
||||
type ScriptInput
|
||||
doc_line::Regex
|
||||
doc_start::Regex
|
||||
opt_line::Regex
|
||||
opt_start::Regex
|
||||
end
|
||||
|
||||
const input_formats = Dict{AbstractString, Any}(
|
||||
"noweb" => MarkupInput(r"^<<(.*?)>>=\s*$",
|
||||
r"^@\s*$"),
|
||||
"markdown" => MarkupInput(
|
||||
r"^[`~]{3,}(?:\{|\{\.|)julia(?:;|)\s*(.*?)(\}|\s*)$",
|
||||
r"^[`~]{3,}\s*$"),
|
||||
"script" => ScriptInput(
|
||||
r"(^#'.*)|(^#%%.*)|(^# %%.*)",
|
||||
r"(^#')|(^#%%)|(^# %%)",
|
||||
r"(^#\+.*$)|(^#%%\+.*$)|(^# %%\+.*$)",
|
||||
r"(^#\+)|(^#%%\+)|(^# %%\+)")
|
||||
)
|
||||
|
||||
"""Detect the input format based on file extension"""
|
||||
function detect_informat(source::AbstractString)
|
||||
ext = lowercase(splitext(source)[2])
|
||||
|
||||
ext == ".jl" && return "script"
|
||||
ext == ".jmd" && return "markdown"
|
||||
return "noweb"
|
||||
end
|
||||
|
||||
|
||||
|
||||
"""Read and parse input document"""
|
||||
function read_doc(source::AbstractString, format=:auto)
|
||||
format == :auto && (format = detect_informat(source))
|
||||
document = @compat readstring(source)
|
||||
parsed = parse_doc(document, format)
|
||||
doc = WeaveDoc(source, parsed)
|
||||
end
|
||||
|
||||
function parse_doc(document::AbstractString, format="noweb"::AbstractString)
|
||||
return parse_doc(document, input_formats[format])
|
||||
end
|
||||
|
||||
"""Parse documents with Weave.jl markup"""
|
||||
function parse_doc(document::AbstractString, format::MarkupInput)
|
||||
lines = split(document, "\n")
|
||||
|
||||
codestart = format.codestart
|
||||
codeend = format.codeend
|
||||
state = "doc"
|
||||
|
||||
docno = 1
|
||||
codeno = 1
|
||||
content = ""
|
||||
start_line = 0
|
||||
|
||||
options = Dict()
|
||||
optionString = ""
|
||||
parsed = Any[]
|
||||
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 optionAbstractString
|
||||
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)
|
||||
#options = merge(rcParams[:chunk_defaults], options)
|
||||
#@show options
|
||||
chunk = DocChunk(content, docno, start_line)
|
||||
#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 = CodeChunk(content, codeno, start_line, optionString, options)
|
||||
#chunk = @compat Dict{Symbol,Any}(:type => "code", :content => content,
|
||||
# :number => codeno, :options => options,
|
||||
# :optionAbstractString => optionAbstractString,
|
||||
# :start_line => start_line)
|
||||
|
||||
codeno+=1
|
||||
start_line = lineno
|
||||
content = ""
|
||||
state = "doc"
|
||||
push!(parsed, chunk)
|
||||
continue
|
||||
end
|
||||
|
||||
if lineno == 1
|
||||
content *= line
|
||||
else
|
||||
content *= "\n" * line
|
||||
end
|
||||
end
|
||||
|
||||
#Remember the last chunk
|
||||
if strip(content) != ""
|
||||
chunk = DocChunk(content, docno, start_line)
|
||||
#chunk = @compat Dict{Symbol,Any}(:type => "doc", :content => content,
|
||||
# :number => docno, :start_line => start_line)
|
||||
push!(parsed, chunk)
|
||||
end
|
||||
return parsed
|
||||
end
|
||||
|
||||
"""Parse .jl scripts with Weave.jl markup"""
|
||||
function parse_doc(document::AbstractString, format::ScriptInput)
|
||||
lines = split(document, "\n")
|
||||
|
||||
doc_line = format.doc_line
|
||||
doc_start = format.doc_start
|
||||
opt_line = format.opt_line
|
||||
opt_start = format.opt_start
|
||||
|
||||
read = ""
|
||||
chunks = []
|
||||
docno = 1
|
||||
codeno = 1
|
||||
content = ""
|
||||
start_line = 1
|
||||
options = Dict{Symbol,Any}()
|
||||
optionString = ""
|
||||
parsed = Any[]
|
||||
state = "code"
|
||||
lineno = 1
|
||||
n_emptylines = 0
|
||||
|
||||
|
||||
|
||||
for lineno in 1:length(lines)
|
||||
line = lines[lineno]
|
||||
if (m = match(doc_line, line)) != nothing && (m = match(opt_line, line)) == nothing
|
||||
line = replace(line, doc_start, "", 1)
|
||||
if startswith(line, " ")
|
||||
line = replace(line, " ", "", 1)
|
||||
end
|
||||
if state == "code" && strip(read) != ""
|
||||
chunk = CodeChunk("\n" * rstrip(read), codeno, start_line, optionString, options)
|
||||
push!(parsed, chunk)
|
||||
codeno +=1
|
||||
read = ""
|
||||
start_line = lineno
|
||||
end
|
||||
state = "doc"
|
||||
elseif (m = match(opt_line, line)) != nothing
|
||||
start_line = lineno
|
||||
if state == "code" && strip(read) !=""
|
||||
chunk = CodeChunk("\n" * rstrip(read), codeno, start_line, optionString, options)
|
||||
push!(parsed, chunk)
|
||||
read = ""
|
||||
codeno +=1
|
||||
end
|
||||
if state == "doc" && strip(read) != ""
|
||||
(docno > 1) && (read = "\n" * read) # Add whitespace to doc chunk. Needed for markdown output
|
||||
chunk = DocChunk(read, docno, start_line)
|
||||
push!(parsed, chunk)
|
||||
read = ""
|
||||
docno += 1
|
||||
end
|
||||
|
||||
optionString = replace(line, opt_start, "", 1)
|
||||
#Get options
|
||||
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)
|
||||
|
||||
state = "code"
|
||||
continue
|
||||
elseif state == "doc" && strip(line) != "" && strip(read) != ""
|
||||
state = "code"
|
||||
(docno > 1) && (read = "\n" * read) # Add whitespace to doc chunk. Needed for markdown output
|
||||
chunk = DocChunk(read, docno, start_line)
|
||||
push!(parsed, chunk)
|
||||
options = Dict{Symbol,Any}()
|
||||
start_line = lineno
|
||||
read = ""
|
||||
docno += 1
|
||||
end
|
||||
read *= line * "\n"
|
||||
|
||||
if strip(line) == ""
|
||||
n_emptylines += 1
|
||||
else
|
||||
n_emptylines = 0
|
||||
end
|
||||
end
|
||||
|
||||
# Handle the last chunk
|
||||
if state == "code"
|
||||
chunk = CodeChunk("\n" * rstrip(read), codeno, start_line, optionString, options)
|
||||
push!(parsed, chunk)
|
||||
else
|
||||
chunk = DocChunk(read, docno, 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
|
628
src/run.jl
628
src/run.jl
|
@ -1,367 +1,451 @@
|
|||
"""
|
||||
`run(doc::WeaveDoc; doctype = :auto, plotlib="Gadfly",
|
||||
out_path=:doc, fig_path = "figures", fig_ext = nothing,
|
||||
cache_path = "cache", cache = :off)`
|
||||
|
||||
Run code chunks and capture output from parsed document.
|
||||
|
||||
* `doctype`: :auto = set based on file extension or specify one of the supported formats.
|
||||
See `list_out_formats()`
|
||||
* `plotlib`: `"PyPlot"`, `"Gadfly"`, or `"Winston"`
|
||||
* `out_path`: Path where the output is generated. Can be: `:doc`: Path of the source document, `:pwd`: Julia working directory,
|
||||
`"somepath"`: Path as a AbstractString e.g `"/home/mpastell/weaveout"`
|
||||
* `fig_path`: where figures will be generated, relative to out_path
|
||||
* `fig_ext`: Extension for saved figures e.g. `".pdf"`, `".png"`. Default setting depends on `doctype`.
|
||||
* `cache_path`: where of cached output will be saved.
|
||||
* `cache`: controls caching of code: `:off` = no caching, `:all` = cache everything,
|
||||
`:user` = cache based on chunk options, `:refresh`, run all code chunks and save new cache.
|
||||
|
||||
**Note:** Run command from terminal and not using IJulia, Juno or ESS, they tend to mess with capturing output.
|
||||
"""
|
||||
function Base.run(doc::WeaveDoc; doctype = :auto, plotlib="Gadfly",
|
||||
out_path=:doc, fig_path = "figures", fig_ext = nothing,
|
||||
cache_path = "cache", cache = :off)
|
||||
#cache :all, :user, :off, :refresh
|
||||
|
||||
doc.cwd = get_cwd(doc, out_path)
|
||||
doctype == :auto && (doctype = detect_doctype(doc.source))
|
||||
doc.doctype = doctype
|
||||
|
||||
doc.format = formats[doctype]
|
||||
set_rc_params(doc.format.formatdict, fig_path, fig_ext)
|
||||
using Base64
|
||||
|
||||
|
||||
#New sandbox for each document
|
||||
sandbox = "ReportSandBox$(rcParams[:doc_number])"
|
||||
eval(parse("module $sandbox\nend"))
|
||||
SandBox = eval(parse(sandbox))
|
||||
rcParams[:doc_number] += 1
|
||||
const PROGRESS_ID = "weave_progress"
|
||||
|
||||
init_plotting(plotlib)
|
||||
report = Report(doc.cwd, doc.basename, doc.format.formatdict)
|
||||
pushdisplay(report)
|
||||
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
|
||||
|
||||
if cache != :off && cache != :refresh
|
||||
cached = read_cache(doc, cache_path)
|
||||
cached == nothing && info("No cached results found, running code")
|
||||
else
|
||||
cached = nothing
|
||||
end
|
||||
doc.doctype = isnothing(doctype) ? (doctype = detect_doctype(doc.source)) : doctype
|
||||
doc.format = deepcopy(get_format(doctype))
|
||||
|
||||
executed = Any[]
|
||||
n = length(doc.chunks)
|
||||
cwd = doc.cwd = get_cwd(doc, out_path)
|
||||
mkpath(cwd)
|
||||
|
||||
for i = 1:n
|
||||
chunk = doc.chunks[i]
|
||||
|
||||
if typeof(chunk) == CodeChunk
|
||||
options = merge(rcParams[:chunk_defaults], chunk.options)
|
||||
merge!(chunk.options, options)
|
||||
end
|
||||
|
||||
restore = (cache ==:user && typeof(chunk) == CodeChunk && chunk.options[:cache])
|
||||
|
||||
if cached != nothing && (cache == :all || restore)
|
||||
result_chunks = restore_chunk(chunk, cached)
|
||||
# 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
|
||||
result_chunks = run_chunk(chunk, report, SandBox)
|
||||
DEFAULT_FIG_PATH
|
||||
end
|
||||
executed = [executed; result_chunks]
|
||||
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
|
||||
|
||||
popdisplay(report)
|
||||
# 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)))
|
||||
|
||||
#Clear variables from used sandbox
|
||||
clear_sandbox(SandBox)
|
||||
doc.chunks = executed
|
||||
mimetypes = doc.format.mimetypes
|
||||
|
||||
if cache != :off
|
||||
write_cache(doc, cache_path)
|
||||
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
|
||||
|
||||
"""Detect the output format based on file extension"""
|
||||
function detect_doctype(source::AbstractString)
|
||||
ext = lowercase(splitext(source)[2])
|
||||
ext == ".jl" && return "md2html"
|
||||
contains(ext, "md") && return "md2html"
|
||||
contains(ext, "rst") && return "rst"
|
||||
contains(ext, "tex") && return "texminted"
|
||||
contains(ext, "txt") && return "asciidoc"
|
||||
run_doc(doc::WeaveDoc, doctype::Union{Nothing,AbstractString}; kwargs...) =
|
||||
run_doc(doc; doctype = doctype, kwargs...)
|
||||
|
||||
return "pandoc"
|
||||
"""
|
||||
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 run_chunk(chunk::CodeChunk, report::Report, SandBox::Module)
|
||||
result_chunk = eval_chunk(chunk, report, SandBox)
|
||||
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::DocChunk, report::Report, SandBox::Module)
|
||||
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
|
||||
|
||||
function reset_report(report::Report)
|
||||
report.cur_result = ""
|
||||
report.figures = AbstractString[]
|
||||
report.term_state = :text
|
||||
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(chunk::CodeChunk, report::Report, SandBox::Module)
|
||||
expressions = parse_input(chunk.content)
|
||||
#@show expressions
|
||||
result_no = 1
|
||||
results = ChunkOutput[ ]
|
||||
|
||||
for (str_expr, expr) = expressions
|
||||
reset_report(report)
|
||||
(obj, out) = capture_output(expr, SandBox, chunk.options[:term], rcParams[:plotlib])
|
||||
displayed = report.cur_result #Not needed?
|
||||
figures = report.figures #Captured figures
|
||||
result = ChunkOutput(str_expr, out, displayed, figures)
|
||||
push!(results, result)
|
||||
end
|
||||
|
||||
#Save figures only in the end of chunk for PyPlot
|
||||
if rcParams[:plotlib] == "PyPlot"
|
||||
savefigs_pyplot(report::Report)
|
||||
end
|
||||
|
||||
return results
|
||||
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 capture_output(expr::Expr, SandBox::Module, term, plotlib)
|
||||
oldSTDOUT = STDOUT
|
||||
out = nothing
|
||||
obj = nothing
|
||||
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()
|
||||
try
|
||||
obj = eval(SandBox, expr)
|
||||
if term
|
||||
obj != nothing && display(obj)
|
||||
elseif plotlib == "Gadfly" && typeof(obj) == Gadfly.Plot
|
||||
obj != nothing && display(obj)
|
||||
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
|
||||
|
||||
finally
|
||||
redirect_stdout(oldSTDOUT)
|
||||
close(wr)
|
||||
out = @compat readstring(rw)
|
||||
close(rw)
|
||||
end
|
||||
return (obj, out)
|
||||
|
||||
return ChunkOutput(code, remove_ansi_control_chars(out), report.rich_output, report.figures)
|
||||
end
|
||||
|
||||
|
||||
#Parse chunk input to array of expressions
|
||||
function parse_input(input::AbstractString)
|
||||
parsed = Tuple{AbstractString, Expr}[]
|
||||
n = length(input)
|
||||
pos = 2 #The first character is extra line end
|
||||
while pos < n
|
||||
oldpos = pos
|
||||
code, pos = parse(input, pos)
|
||||
push!(parsed, (input[oldpos:pos-1] , code ))
|
||||
end
|
||||
parsed
|
||||
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
|
||||
|
||||
function eval_chunk(chunk::CodeChunk, report::Report, SandBox::Module)
|
||||
info("Weaving chunk $(chunk.number) from line $(chunk.start_line)")
|
||||
# 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 haskey(report.formatdict, :out_width) && chunk.options[:out_width] == nothing
|
||||
chunk.options[:out_width] = report.formatdict[:out_width]
|
||||
if hasproperty(report.format, :out_width) && isnothing(chunk.options[:out_width])
|
||||
chunk.options[:out_width] = report.format.out_width
|
||||
end
|
||||
|
||||
chunk.result = run_code(chunk, report, SandBox)
|
||||
if chunk.options[:term]
|
||||
chunks = collect_results(chunk, TermResult())
|
||||
elseif chunk.options[:hold]
|
||||
chunks = collect_results(chunk, CollectResult())
|
||||
else
|
||||
chunks = collect_results(chunk, ScriptResult())
|
||||
end
|
||||
chunk.result = run_code(doc, chunk, report, mod)
|
||||
|
||||
#else
|
||||
# chunk.options[:fig] && (chunk.figures = copy(report.figures))
|
||||
#end
|
||||
execute_posthooks!(chunk)
|
||||
|
||||
chunks
|
||||
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
|
||||
|
||||
#function eval_chunk(chunk::DocChunk, report::Report, SandBox)
|
||||
# chunk
|
||||
#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
|
||||
|
||||
#Set all variables to nothing
|
||||
function clear_sandbox(SandBox::Module)
|
||||
for name = names(SandBox, true)
|
||||
if name != :eval && name != names(SandBox)[1]
|
||||
try eval(SandBox, parse(AbstractString(AbstractString(name), "=nothing"))) 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)
|
||||
|
||||
function get_figname(report::Report, chunk; fignum = nothing)
|
||||
figpath = joinpath(report.cwd, chunk.options[:fig_path])
|
||||
isdir(figpath) || mkpath(figpath)
|
||||
ext = chunk.options[:fig_ext]
|
||||
fignum == nothing && (fignum = report.fignum)
|
||||
|
||||
chunkid = (chunk.options[:name] == nothing) ? chunk.number : chunk.options[:name]
|
||||
full_name = joinpath(report.cwd, chunk.options[:fig_path],
|
||||
"$(report.basename)_$(chunkid)_$(fignum)$ext")
|
||||
rel_name = "$(chunk.options[:fig_path])/$(report.basename)_$(chunkid)_$(fignum)$ext" #Relative path is used in output
|
||||
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 init_plotting(plotlib)
|
||||
if plotlib == nothing
|
||||
rcParams[:chunk_defaults][:fig] = false
|
||||
rcParams[:plotlib] = nothing
|
||||
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(parse("""include(Pkg.dir("Weave","src","pyplot.jl"))"""))
|
||||
rcParams[:plotlib] = "PyPlot"
|
||||
elseif l_plotlib == "gadfly"
|
||||
eval(parse("""include(Pkg.dir("Weave","src","gadfly.jl"))"""))
|
||||
rcParams[:plotlib] = "Gadfly"
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
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 get_cwd(doc::WeaveDoc, out_path)
|
||||
#Set the output directory
|
||||
if out_path == :doc
|
||||
cwd = doc.path
|
||||
elseif out_path == :pwd
|
||||
cwd = pwd()
|
||||
else
|
||||
#If there is no extension, use as path
|
||||
splitted = splitext(out_path)
|
||||
if splitted[2] == ""
|
||||
cwd = expanduser(out_path)
|
||||
else
|
||||
cwd = splitdir(expanduser(out_path))[1]
|
||||
end
|
||||
end
|
||||
return cwd
|
||||
end
|
||||
|
||||
|
||||
"""Get output file name based on out_path"""
|
||||
function get_outname(out_path::Symbol, doc::WeaveDoc; ext = nothing)
|
||||
ext == nothing && (ext = doc.format.formatdict[:extension])
|
||||
outname = "$(doc.cwd)/$(doc.basename).$ext"
|
||||
end
|
||||
|
||||
|
||||
"""Get output file name based on out_path"""
|
||||
function get_outname(out_path::AbstractString, doc::WeaveDoc; ext = nothing)
|
||||
ext == nothing && (ext = doc.format.formatdict[:extension])
|
||||
splitted = splitext(out_path)
|
||||
if (splitted[2]) == ""
|
||||
outname = "$(doc.cwd)/$(doc.basename).$ext"
|
||||
else
|
||||
outname = expanduser(out_path)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function set_rc_params(formatdict, fig_path, fig_ext)
|
||||
if fig_ext == nothing
|
||||
rcParams[:chunk_defaults][:fig_ext] = formatdict[:fig_ext]
|
||||
docParams[:fig_ext] = formatdict[:fig_ext]
|
||||
else
|
||||
rcParams[:chunk_defaults][:fig_ext] = fig_ext
|
||||
docParams[:fig_ext] = fig_ext
|
||||
end
|
||||
rcParams[:chunk_defaults][:fig_path] = fig_path
|
||||
docParams[:fig_path] = fig_path
|
||||
return nothing
|
||||
end
|
||||
|
||||
function collect_results(chunk::CodeChunk, fmt::ScriptResult)
|
||||
function collect_results(chunk::CodeChunk)
|
||||
content = ""
|
||||
result_no = 1
|
||||
result_chunks = CodeChunk[ ]
|
||||
for r = chunk.result
|
||||
if strip(r.stdout) == "" && isempty(r.figures) && r.displayed == ""
|
||||
content *= r.code
|
||||
else
|
||||
content = "\n" * content * r.code
|
||||
rchunk = CodeChunk(content, chunk.number, chunk.start_line, chunk.optionstring, copy(chunk.options))
|
||||
content = ""
|
||||
rchunk.result_no = result_no
|
||||
result_no *=1
|
||||
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
|
||||
rchunk.output = r.stdout * r.displayed
|
||||
push!(result_chunks, rchunk)
|
||||
content = ""
|
||||
end
|
||||
end
|
||||
if content != ""
|
||||
startswith(content, "\n") || (content = "\n" * content)
|
||||
rchunk = CodeChunk(content, chunk.number, chunk.start_line, chunk.optionstring, copy(chunk.options))
|
||||
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_results(chunk::CodeChunk, fmt::TermResult)
|
||||
function collect_term_results(chunk::CodeChunk)
|
||||
output = ""
|
||||
result_no = 1
|
||||
prompt = "\njulia> "
|
||||
result_chunks = CodeChunk[ ]
|
||||
for r =chunk.result
|
||||
output *= prompt * r.code
|
||||
output *= r.displayed * r.stdout
|
||||
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 = 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 output != ""
|
||||
rchunk = CodeChunk("", chunk.number, chunk.start_line, chunk.optionstring, copy(chunk.options))
|
||||
rchunk.output = output
|
||||
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 collect_results(chunk::CodeChunk, fmt::CollectResult)
|
||||
result_no = 1
|
||||
for r =chunk.result
|
||||
chunk.output *= r.stdout
|
||||
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,22 +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]]
|
||||
push!(report.figures, rel_name)
|
||||
report.fignum += 1
|
||||
vector_fmts = [".pdf"; ".svg"]
|
||||
|
||||
#Don't use dpi for vector formats
|
||||
if chunk.options[:fig_ext] in vector_fmts
|
||||
Winston.savefig(data, full_name, width=chunk.options[:fig_width]*100,
|
||||
height=chunk.options[:fig_height]*100)
|
||||
else
|
||||
Winston.savefig(data, full_name,
|
||||
width=chunk.options[:fig_width]*chunk.options[:dpi],
|
||||
height=chunk.options[:fig_height]*chunk.options[:dpi])
|
||||
end
|
||||
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")
|
|
@ -1,30 +1,15 @@
|
|||
|
||||
|
||||
<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>
|
||||
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family: 'Raleway';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local('Raleway Light'), local('Raleway-Light'), url(http://fonts.gstatic.com/s/raleway/v9/-_Ctzj9b56b8RgXW8FArifk_vArhqVIZ0nv9q090hN8.woff2) format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Raleway';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Raleway'), url(http://fonts.gstatic.com/s/raleway/v9/0dTEPzkLWceF7z0koJaX1A.woff2) format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Raleway';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local('Raleway SemiBold'), local('Raleway-SemiBold'), url(http://fonts.gstatic.com/s/raleway/v9/xkvoNo9fC8O2RDydKj12b_k_vArhqVIZ0nv9q090hN8.woff2) format('woff2');
|
||||
}
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
|
@ -196,6 +181,8 @@ optgroup {
|
|||
font-weight: bold;
|
||||
}
|
||||
table {
|
||||
font-family: monospace, monospace;
|
||||
font-size : 0.8em;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
@ -203,7 +190,13 @@ 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
|
||||
|
@ -506,10 +499,29 @@ pre {
|
|||
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,
|
||||
|
@ -517,13 +529,16 @@ samp {
|
|||
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
}
|
||||
code {
|
||||
padding: 2px 4px;
|
||||
font-size: 90%;
|
||||
|
||||
background-color: #f9f2f4;
|
||||
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) {}
|
||||
|
@ -531,5 +546,5 @@ code {
|
|||
@media (min-width: 1200px) {}
|
||||
|
||||
h1.title {margin-top : 20px}
|
||||
img {max-width : 100%%}
|
||||
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}
|
|
@ -15,21 +15,35 @@ $if(keywords)$
|
|||
$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)$
|
||||
$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">
|
||||
|
@ -71,8 +85,8 @@ $endfor$
|
|||
|
||||
<HR/>
|
||||
<div class="footer"><p>
|
||||
Published from <a href="$wsource$">$wsource$</a> using
|
||||
<a href="http://github.com/mpastell/Weave.jl">Weave.jl</a> $wversion$ on $wtime$.
|
||||
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>
|
|
@ -1,6 +0,0 @@
|
|||
julia 0.4
|
||||
Cairo
|
||||
Gadfly
|
||||
PyPlot
|
||||
Winston
|
||||
DSP
|
|
@ -1,33 +1,28 @@
|
|||
using Weave, Compat
|
||||
using Base.Test
|
||||
|
||||
#Test if running document with and without cache works
|
||||
# Test if running document with and without cache works
|
||||
isdir("documents/cache") && rm("documents/cache", recursive = true)
|
||||
weave("documents/chunk_options.noweb", plotlib=nothing, cache=:all)
|
||||
result = @compat readstring(open("documents/chunk_options.md"))
|
||||
weave("documents/chunk_options.noweb", cache=:all)
|
||||
result = read("documents/chunk_options.md", String)
|
||||
rm("documents/chunk_options.md")
|
||||
weave("documents/chunk_options.noweb", plotlib=nothing, cache=:all)
|
||||
cached_result = @compat readstring(open("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", plotlib=nothing, cache=:user);
|
||||
result = @compat readstring(open(out))
|
||||
Weave.weave("documents/chunk_cache.noweb", cache=:user);
|
||||
result = read(out, String)
|
||||
rm(out)
|
||||
Weave.weave("documents/chunk_cache.noweb", plotlib=nothing, cache=:user);
|
||||
cached_result = @compat readstring(open(out))
|
||||
Weave.weave("documents/chunk_cache.noweb", cache=:user);
|
||||
cached_result = read(out, String)
|
||||
@test result == cached_result
|
||||
|
||||
if VERSION.minor == 3
|
||||
using Gadfly
|
||||
isdir("documents/cache") && rm("documents/cache", recursive = true)
|
||||
#Caching with Gadfly
|
||||
weave("documents/gadfly_formats_test.txt", doctype="tex", plotlib="gadfly", cache=:all)
|
||||
result = @compat readstring(open("documents/gadfly_formats_test.tex"))
|
||||
rm("documents/gadfly_formats_test.tex")
|
||||
weave("documents/gadfly_formats_test.txt", doctype="tex", plotlib="gadfly", cache=:all)
|
||||
cached_result = @compat readstring(open("documents/gadfly_formats_test.tex"))
|
||||
@test result == cached_result
|
||||
end
|
||||
# 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,59 +0,0 @@
|
|||
using Weave, Compat
|
||||
using Base.Test
|
||||
|
||||
cleanup = true
|
||||
|
||||
#Test chunk options and output formats
|
||||
weave("documents/chunk_options.noweb", plotlib=nothing)
|
||||
result = @compat readstring(open("documents/chunk_options.md"))
|
||||
ref = @compat readstring(open("documents/chunk_options_ref.md"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/chunk_options.md")
|
||||
|
||||
weave("documents/chunk_options.noweb", doctype="tex", plotlib=nothing)
|
||||
result = @compat readstring(open("documents/chunk_options.tex"))
|
||||
ref = @compat readstring(open("documents/chunk_options_ref.tex"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/chunk_options.tex")
|
||||
|
||||
weave("documents/chunk_options.noweb", doctype="texminted", plotlib=nothing)
|
||||
result = @compat readstring(open("documents/chunk_options.tex"))
|
||||
ref = @compat readstring(open("documents/chunk_options_ref.texminted"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/chunk_options.tex")
|
||||
|
||||
weave("documents/chunk_options.noweb", doctype="rst", plotlib=nothing)
|
||||
result = @compat readstring(open("documents/chunk_options.rst"))
|
||||
ref = @compat readstring(open("documents/chunk_options_ref.rst"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/chunk_options.rst")
|
||||
|
||||
#Test out_path
|
||||
weave("documents/chunk_options.noweb", doctype="rst",
|
||||
out_path="documents/outpath_options.rst" , plotlib=nothing)
|
||||
result = @compat readstring(open("documents/outpath_options.rst"))
|
||||
ref = @compat readstring(open("documents/chunk_options_ref.rst"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/outpath_options.rst")
|
||||
|
||||
#Test tangle
|
||||
tangle("documents/chunk_options.noweb")
|
||||
result = @compat readstring(open("documents/chunk_options.jl"))
|
||||
ref = @compat readstring(open("documents/chunk_options_ref.jl"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/chunk_options.jl")
|
||||
|
||||
|
||||
tangle("documents/chunk_options.noweb", out_path = "documents/outoptions.jl")
|
||||
result = @compat readstring(open("documents/outoptions.jl"))
|
||||
ref = @compat readstring(open("documents/chunk_options_ref.jl"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/outoptions.jl")
|
||||
|
||||
|
||||
#Test functions and sandbox clearing
|
||||
weave("documents/chunk_func.noweb", plotlib=nothing)
|
||||
result = @compat readstring(open("documents/chunk_func.md"))
|
||||
ref = @compat readstring(open("documents/chunk_func_ref.md"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/chunk_func.md")
|
|
@ -1,18 +0,0 @@
|
|||
using Weave, Compat
|
||||
using Base.Test
|
||||
|
||||
cleanup = true
|
||||
|
||||
#Test hold and term options
|
||||
weave("documents/test_hold.mdw", doctype="pandoc", plotlib="Gadfly")
|
||||
result = @compat readstring(open("documents/test_hold.md"))
|
||||
ref = @compat readstring(open("documents/test_hold_ref.md"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/test_hold.md")
|
||||
|
||||
#Test setting and restoring chunk options
|
||||
Weave.weave("documents/default_opts.noweb", doctype = "tex")
|
||||
result = @compat readstring(open("documents/default_opts.tex"))
|
||||
ref = @compat readstring(open("documents/default_opts_ref.tex"))
|
||||
@test result == ref
|
||||
cleanup && rm("documents/default_opts.tex")
|
|
@ -3,6 +3,7 @@
|
|||
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]
|
||||
|
@ -26,6 +27,7 @@ y = 1:5
|
|||
println(y)
|
||||
@
|
||||
|
||||
`j y`
|
||||
|
||||
<<cache=true>>=
|
||||
y = 1:5
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
Functions:
|
||||
|
||||
<<>>=
|
||||
f(x)=x^2
|
||||
println(f(2))
|
||||
@
|
|
@ -1,13 +0,0 @@
|
|||
Functions:
|
||||
|
||||
~~~~{.julia}
|
||||
f(x)=x^2
|
||||
println(f(2))
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
4
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y= [2, 5, 12]"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"x = [12, 10]\nprintln(y)\nprintln(x)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(\"Results without code\")\nprintln(x)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y = randn(5)\nprintln(\"Don't eval, but show code\")"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"y = 1:5\nprintln(y)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"a = \"Don't print me\"\nprintln(a)"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(\"No markup for results.\")"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Test wrapping:"
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"outputs": [],
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"println(collect(0:10:1000))"
|
||||
],
|
||||
"metadata": {},
|
||||
"execution_count": null
|
||||
}
|
||||
],
|
||||
"nbformat_minor": 2,
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "0.5.0"
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "julia-0.5",
|
||||
"display_name": "Julia 0.5.0",
|
||||
"language": "julia"
|
||||
}
|
||||
},
|
||||
"nbformat": 4
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
#+ term=true
|
||||
|
||||
y= [2, 5, 12]
|
||||
|
||||
|
||||
#+ term=true
|
||||
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
|
||||
|
||||
#+
|
||||
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
println(x)
|
||||
|
||||
|
||||
#+ echo=false
|
||||
|
||||
println("Results without code")
|
||||
println(x)
|
||||
|
||||
|
||||
#+ eval=false; tangle=false
|
||||
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
|
||||
|
||||
#+
|
||||
|
||||
y = 1:5
|
||||
println(y)
|
||||
|
||||
|
||||
#+ results="hidden"
|
||||
|
||||
a = "Don't print me"
|
||||
println(a)
|
||||
|
||||
|
||||
#+ results="as_is"
|
||||
|
||||
println("No markup for results.")
|
||||
|
||||
#'
|
||||
#'
|
||||
#' Test wrapping:
|
||||
#'
|
||||
#+
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
#+ wrap=false
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
||||
|
||||
#+ line_width=60
|
||||
|
||||
println(collect(0:10:1000))
|
||||
|
|
@ -3,6 +3,12 @@
|
|||
y= [2, 5, 12]
|
||||
@
|
||||
|
||||
<<term=true>>=
|
||||
x = 1:10
|
||||
d = Dict("Weave" => "testing")
|
||||
y = [2, 4 ,8]
|
||||
@
|
||||
|
||||
<<>>=
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
|
|
|
@ -1,26 +1,41 @@
|
|||
|
||||
~~~~{.julia}
|
||||
julia> y= [2, 5, 12]
|
||||
3-element Array{Int64,1}:
|
||||
2
|
||||
5
|
||||
12
|
||||
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
julia> x = 1:10
|
||||
1:10
|
||||
|
||||
julia> d = Dict("Weave" => "testing")
|
||||
Dict{String,String} with 1 entry:
|
||||
"Weave" => "testing"
|
||||
|
||||
julia> y = [2, 4 ,8]
|
||||
3-element Array{Int64,1}:
|
||||
2
|
||||
4
|
||||
8
|
||||
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
x = [12, 10]
|
||||
println(y)
|
||||
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
[2,5,12]
|
||||
~~~~~~~~~~~~~
|
||||
~~~~
|
||||
[2, 4, 8]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
@ -29,50 +44,40 @@ println(x)
|
|||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
[12,10]
|
||||
~~~~~~~~~~~~~
|
||||
~~~~
|
||||
[12, 10]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
~~~~
|
||||
Results without code
|
||||
~~~~~~~~~~~~~
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
~~~~
|
||||
[12, 10]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
[12,10]
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
y = randn(5)
|
||||
println("Don't eval, but show code")
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
y = 1:5
|
||||
println(y)
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
~~~~
|
||||
1:5
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
@ -83,8 +88,6 @@ println(a)
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
println("No markup for results.")
|
||||
~~~~~~~~~~~~~
|
||||
|
@ -102,16 +105,15 @@ println(collect(0:10:1000))
|
|||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
[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]
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~
|
||||
[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]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
@ -120,11 +122,9 @@ println(collect(0:10:1000))
|
|||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}[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]
|
||||
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~
|
||||
[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]
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
@ -133,14 +133,16 @@ println(collect(0:10:1000))
|
|||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
~~~~{.julia}
|
||||
[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]
|
||||
~~~~~~~~~~~~~
|
||||
~~~~
|
||||
[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]
|
||||
~~~~
|
||||
|
||||
|
||||
|
|
|
@ -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,30 +0,0 @@
|
|||
|
||||
|
||||
<<>>=
|
||||
using Gadfly
|
||||
print(1:10)
|
||||
plot(x = 1:10)
|
||||
@
|
||||
|
||||
<<>>=
|
||||
import Weave
|
||||
Weave.set_chunk_defaults(Dict{Symbol, Any}(
|
||||
:out_width => "\\0.5linewidth",
|
||||
:results => "tex"
|
||||
))
|
||||
@
|
||||
|
||||
<<>>=
|
||||
print(1:10)
|
||||
plot(x = 1:10)
|
||||
@
|
||||
|
||||
|
||||
<<echo = false>>=
|
||||
Weave.restore_chunk_defaults()
|
||||
@
|
||||
|
||||
<<>>=
|
||||
print(1:10)
|
||||
plot(x = 1:10)
|
||||
@
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
|
||||
\begin{juliacode}
|
||||
using Gadfly
|
||||
print(1:10)
|
||||
|
||||
\end{juliacode}
|
||||
\begin{juliaout}
|
||||
1:10
|
||||
\end{juliaout}
|
||||
|
||||
\begin{juliacode}
|
||||
plot(x = 1:10)
|
||||
\end{juliacode}
|
||||
\includegraphics[width=\linewidth]{figures/default_opts_1_1.pdf}
|
||||
|
||||
|
||||
|
||||
\begin{juliacode}
|
||||
import Weave
|
||||
Weave.set_chunk_defaults(Dict{Symbol, Any}(
|
||||
:out_width => "\\0.5linewidth",
|
||||
:results => "tex"
|
||||
))
|
||||
\end{juliacode}
|
||||
|
||||
|
||||
|
||||
\begin{juliacode}
|
||||
print(1:10)
|
||||
|
||||
\end{juliacode}
|
||||
1:10
|
||||
|
||||
\begin{juliacode}
|
||||
plot(x = 1:10)
|
||||
\end{juliacode}
|
||||
\includegraphics[width=\0.5linewidth]{figures/default_opts_3_1.pdf}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\begin{juliacode}
|
||||
print(1:10)
|
||||
|
||||
\end{juliacode}
|
||||
\begin{juliaout}
|
||||
1:10
|
||||
\end{juliaout}
|
||||
|
||||
\begin{juliacode}
|
||||
plot(x = 1:10)
|
||||
\end{juliacode}
|
||||
\includegraphics[width=\linewidth]{figures/default_opts_5_1.pdf}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue