Compare commits

...

623 Commits

Author SHA1 Message Date
Sebastian Pfitzner 77793c775c
Merge pull request #481 from dlfivefifty/patch-2
Mention Quarto in Related Packages
2024-04-16 12:50:53 +02:00
Sheehan Olver ad0885ce00
Update README.md 2024-04-16 11:43:11 +01:00
Sebastian Pfitzner e10aaefd94
Merge pull request #469 from laborg/master
Update RelocatableFolders dependency
2023-02-10 10:39:25 +01:00
Sebastian Pfitzner 8ad4e876d3
Merge pull request #448 from xgdgsc/patch-1
display example needs to be fixed
2023-02-10 10:32:25 +01:00
Sebastian Pfitzner af2a6e14c9
Merge pull request #462 from NicholasWMRitchie/nwmr
Force deletion of the temporary figure path to address Issue #440
2023-02-10 10:32:01 +01:00
Sebastian Pfitzner 20aaefec0a
Merge pull request #465 from newptcai/font-size
Removed hard coded font size for PDF
2023-02-10 10:29:31 +01:00
Gerhard Aigner 2a78676d41 update relocatablefolders.jl dependency 2023-02-10 09:04:49 +01:00
Gerhard Aigner 59332c1768 relax dataframe displayed row counting 2023-02-10 09:02:10 +01:00
Sebastian Pfitzner db28a69d94
Merge pull request #468 from dlfivefifty/patch-1
Mention Literate.jl in README.md
2023-01-18 16:55:11 +01:00
Sheehan Olver 0b96591f39
Mention Literate.jl in README.md 2023-01-18 14:52:44 +00:00
Sebastian Pfitzner a38cec95db
0.10.11 2022-12-12 10:02:01 +01:00
Sebastian Pfitzner 562f8e4ab3
v0.10.12 2022-12-12 09:17:50 +01:00
Sebastian Pfitzner 9f666b3bb5
Merge pull request #466 from KristofferC/kc/require
avoid warning when using Weave in a sysimage
2022-12-12 09:17:27 +01:00
KristofferC a63577f69c avoid warning when using Weave in a sysimage 2022-12-07 11:14:48 +01:00
Xing Shi Cai 7e0f5641c2 Removed hard coded font size for PDF 2022-10-19 14:37:58 +08:00
Nicholas W. M. Ritchie b022a54458 Add isnothing(fig_path) check 2022-07-13 09:51:59 -04:00
Nicholas W. M. Ritchie b669a14038 Force deletion of the temporary figure path to address Issue #440 2022-07-13 09:35:48 -04:00
Sebastian Pfitzner b7941c2811
Merge pull request #457 from ExpandingMan/em/highlightup
bumped highlights version
2022-05-19 16:09:14 +02:00
ExpandingMan d40e95a4bb bumped highlights version 2022-05-19 09:43:14 -04:00
xgdgsc df47ea191f
HTML( 2022-02-14 15:33:21 +08:00
Sebastian Pfitzner 381de22c7d
Merge pull request #428 from JunoLab/compathelper/new_version/2021-06-22-00-09-55-226-3473194155
CompatHelper: add new compat entry for "RelocatableFolders" at version "0.1"
2021-06-22 10:05:31 +02:00
github-actions[bot] 06b259a7b0 CompatHelper: add new compat entry for "RelocatableFolders" at version "0.1" 2021-06-22 00:09:55 +00:00
Sebastian Pfitzner 749c0c262c
v0.10.10 2021-06-21 09:49:07 +02:00
Sebastian Pfitzner 696db1d82b
Merge pull request #426 from MichaelHatherly/mh/package-compiler-friendly-assets
Make assets `PackageCompiler`-friendly
2021-06-21 09:48:51 +02:00
Mike d4c65729e4
Use `RelocatableFolders` for assets folders. 2021-06-18 09:50:38 +01:00
Mike 1dfb8d76d6
Make assets `PackageCompiler`-friendly
A possible solution to relocatablilty issues with the hardcoded paths.

Embeds the asset folder contents into the precompiled files. When the
original folder isn't available (due to relocation) creates a
scratchspace containing the original folder contents as uses that
instead.
2021-06-12 09:21:20 +01:00
Sebastian Pfitzner 48c99c791f
0.10.9 2021-06-01 10:14:36 +02:00
Sebastian Pfitzner ec3f464c37
Merge pull request #424 from MichaelHatherly/mh/latex-method-warning
Fix #388.
2021-06-01 09:56:04 +02:00
Mike 4c60bd8d64
Fix #388.
Replaces the `IO` argument with a `Union{IOBuffer,IOContext}` which
should be the only types that are actually reachable since the code
paths pass through `sprint`, which only uses either of those.

It's still not a perfect fix due to the type piracy, as noted in the
comments, but avoids the method overwrite warning at least.
2021-06-01 08:42:02 +01:00
Sebastian Pfitzner e1d31c2ef6
v0.10.8 2021-04-29 14:49:53 +02:00
Shuhei Kadowaki 99916dd70c
Merge pull request #423 from JunoLab/sp/fix-chunk-options
fix chunk options regression
2021-04-29 21:18:16 +09:00
Sebastian Pfitzner 6b6f82bed4 fix chunk options regression 2021-04-29 13:12:08 +02:00
Shuhei Kadowaki b1de7efede
Merge pull request #416 from nateybear/patch-1
Change tex escaping to tex comments
2021-03-14 03:53:00 +09:00
Nathan Hattersley 849cc20e88
Change tex escaping to tex comments
Take more opinionated stance on TeX inside julia blocks--LaTeX belongs in comments.
2021-03-12 14:43:38 -06:00
Shuhei Kadowaki 10de1057a3 version 0.10.7 2021-03-03 18:44:23 +09:00
Shuhei Kadowaki e753f70f7a
Merge pull request #413 from pgunnink/fix-out-path
Fix for out_path only working for directories
2021-03-03 18:43:06 +09:00
PGunnink 8dc0441b90 Fix for out_path only working for directories 2021-03-02 19:37:12 +01:00
Shuhei Kadowaki c9fc740d72
Merge pull request #380 from JonasIsensee/exportaswrapper
Export formats as wrapper
2020-10-03 16:32:35 +09:00
Shuhei Kadowaki cc5913e812
Update src/rendering/htmlformats.jl 2020-10-03 16:29:44 +09:00
JonasIsensee e02d5ce2fd
Update src/rendering/exportformat.jl
Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com>
2020-10-03 08:51:22 +02:00
Shuhei Kadowaki b583ac2e40 don't end2end test for `minted2pdf` 2020-10-03 13:50:41 +09:00
Shuhei Kadowaki 955675d89a Merge branch 'master' into exportaswrapper 2020-10-03 13:38:33 +09:00
Shuhei Kadowaki 196d4ca7ce don't decl const for `WEAVE_ARGS` 2020-10-03 13:17:39 +09:00
Shuhei Kadowaki d3a7f2aea7 version 0.10.6 2020-10-03 04:50:49 +09:00
Shuhei Kadowaki 7d361bb40d
Merge pull request #401 from JunoLab/avi/fix400
fixes #400
2020-10-03 04:49:15 +09:00
Shuhei Kadowaki e927495a62 fixes #400 2020-10-03 04:44:52 +09:00
Shuhei Kadowaki 78befc61b5 version 0.10.5 2020-09-30 19:07:26 +09:00
Shuhei Kadowaki c24a262135 allow arbitrary runtime argument 2020-09-30 18:43:15 +09:00
Shuhei Kadowaki 3e8200c2f8
Merge pull request #399 from JunoLab/avi/fixmkdir
fixes #398
2020-09-30 18:42:20 +09:00
Shuhei Kadowaki 8f23084471 fixes #398 2020-09-30 18:28:22 +09:00
Shuhei Kadowaki a1830e0502 triple quote for markdown output 2020-09-28 01:10:21 +09:00
Shuhei Kadowaki 0e662ecdec
Merge pull request #397 from baggepinnen/patch-2
Import Dates
2020-09-26 15:52:23 +09:00
Fredrik Bagge Carlson fa71830479
Import Dates
One must now `import Dates` for `now, Date` to be defined.
2020-09-26 08:41:42 +02:00
Shuhei Kadowaki 21d7fbdbea version 0.10.4 2020-09-25 00:41:30 +09:00
Shuhei Kadowaki fe3711074b
Merge pull request #396 from torfjelde/patch-1
Fix for #386
2020-09-25 00:39:11 +09:00
Tor Erlend Fjelde 766847ec65
fix for #386 2020-09-24 16:09:33 +01:00
Shuhei Kadowaki 46a0f8bff4
Merge pull request #393 from odow/patch-1
Fix typo in header.md
2020-09-04 13:13:52 +09:00
Oscar Dowson 51f905ca83
Fix typo in header.md 2020-09-04 16:03:58 +12:00
Sebastian Pfitzner b5ba227e75
0.10.3 2020-08-17 10:13:39 +02:00
Sebastian Pfitzner 74768a7e0f
Merge pull request #357 from baggepinnen/patch-2
[RFC] Do not define Markdown.latex using eval
2020-08-17 10:13:20 +02:00
Jonas Isensee 90d8c8430f do the same for pandoc exports 2020-06-15 20:41:46 +02:00
Jonas Isensee a61ade7778 implement general `ExportFormat` 2020-06-15 20:39:15 +02:00
Jonas Isensee 8ac94989f1 fix rendering bug in output 2020-06-15 20:38:53 +02:00
Jonas Isensee 191282c1e5 implement LaTeXPDF as wrapper 2020-06-15 20:19:36 +02:00
Shuhei Kadowaki d8eca00fd8 fix regression 2020-06-14 22:54:27 +09:00
Shuhei Kadowaki 957d12e751
Merge pull request #377 from JunoLab/avi/simpletest
add simple end2end test
2020-06-14 21:39:18 +09:00
Shuhei Kadowaki 82c7c2a8c6 rename formats 2020-06-14 21:33:55 +09:00
Shuhei Kadowaki ba5bc9ca08
Merge pull request #376 from JunoLab/avi/preserveheader
preserve header for pandoc formats
2020-06-14 21:33:30 +09:00
Shuhei Kadowaki 5f0d9d4627 add simple end2end test 2020-06-14 21:32:04 +09:00
Shuhei Kadowaki 676ecc64f9 preserve header for pandoc formats 2020-06-14 20:57:37 +09:00
Shuhei Kadowaki 2a509d8f96 reorganize things 2020-06-14 18:15:05 +09:00
Shuhei Kadowaki 9b2a1228cd fix terminology, reorder arguments 2020-06-14 18:10:31 +09:00
Shuhei Kadowaki 785768c728
Merge pull request #374 from JunoLab/avi/write
refactor document writing
2020-06-14 18:08:01 +09:00
Shuhei Kadowaki 7e9c4fb99d dispatch-base documentation generation 2020-06-14 16:36:51 +09:00
Shuhei Kadowaki 29546b7716 more generic name 2020-06-14 15:15:11 +09:00
Shuhei Kadowaki db5308b286 reorder function definition, rename `JMarkdown2tex` to `JMarkdown2PDF` 2020-06-14 14:49:48 +09:00
Shuhei Kadowaki 174585e504
Merge pull request #362 from JonasIsensee/texpipeline
Improvements to the tex rendering pipeline
2020-06-14 14:35:46 +09:00
Shuhei Kadowaki 8206ca2d14 fix `set_chunk_options!` 2020-06-14 14:25:21 +09:00
Shuhei Kadowaki 092adb6805 update test 2020-06-14 14:25:03 +09:00
Shuhei Kadowaki 872f7c7153 construct UNICODE2LATEX at precompile time 2020-06-14 13:56:59 +09:00
Shuhei Kadowaki 5ae1fd5cf1 Merge branch 'master' into texpipeline 2020-06-14 13:36:18 +09:00
Shuhei Kadowaki bd447ec8e3 update links 2020-06-14 13:34:43 +09:00
Jonas Isensee 3dfe817584 fix bug 2020-06-13 22:56:23 +02:00
Jonas Isensee 12e148af18 move unicode2tex escape characters to struct 2020-06-13 22:16:48 +02:00
Shuhei Kadowaki 03079a5dac update README 2020-06-14 04:19:20 +09:00
Shuhei Kadowaki e179bd098e replace CI badge 2020-06-14 04:17:34 +09:00
Shuhei Kadowaki 4a96f2c19a add codecov badge 2020-06-14 04:15:45 +09:00
Shuhei Kadowaki 7955308a0a
Merge pull request #314 from JunoLab/avi/actions
use GitHub actions for tests, enable faster CI cycle
2020-06-14 04:15:08 +09:00
Shuhei Kadowaki 21835644a0 enable GitHub actions CI for faster test cycle 2020-06-14 04:08:28 +09:00
Shuhei Kadowaki 5a585f845a improve ansi character removal 2020-06-14 04:06:25 +09:00
Shuhei Kadowaki f077609798 fix repository url 2020-06-14 04:05:28 +09:00
Shuhei Kadowaki 46a0da597d
Merge pull request #373 from JunoLab/avi/fixtermresult
improve term result
2020-06-14 02:52:33 +09:00
Shuhei Kadowaki 2070610a58 🔥 Plots.jl/Gadfly.jl integration test 2020-06-14 02:25:32 +09:00
Shuhei Kadowaki 7d6fddc749 improve term result 2020-06-14 01:53:17 +09:00
Shuhei Kadowaki dadce5110c
Merge pull request #372 from JunoLab/avi/fire
🔥
2020-06-14 01:43:55 +09:00
Shuhei Kadowaki 5d3dd15733 🔥 2020-06-14 01:43:32 +09:00
Shuhei Kadowaki 608bb3df4a
Merge pull request #371 from JunoLab/avi/error
follow RMarkdown more: make `throw_error` option into chunk option
2020-06-14 00:02:54 +09:00
Shuhei Kadowaki b569740915 rm tests with "tex" format 2020-06-14 00:02:05 +09:00
Shuhei Kadowaki 972869da47 Merge branch 'master' into pr-362/JonasIsensee/texpipeline 2020-06-13 23:45:43 +09:00
Shuhei Kadowaki e0a9d044cd
Merge pull request #370 from JunoLab/avi/type
fix `Report` typings, and hooks
2020-06-13 23:19:29 +09:00
Shuhei Kadowaki 912387c331 follow RMarkdown more: make `throw_error` option into chunk option 2020-06-13 23:09:51 +09:00
Jonas Isensee 1135c5ddfa Remove "tex" format 2020-06-13 15:50:04 +02:00
Shuhei Kadowaki c1bc2fd5c5 fix weird typings of `Report` 2020-06-13 22:44:13 +09:00
Shuhei Kadowaki d586c24792 clean up:
- unused `:display` chunk option
- rm `displayed` chunk field
- rm `cur_result`, `pendind_code`, `term_state` `Report` field
- rm `:skip` config option
- rm unfunctional `include` chunk option for now
2020-06-13 22:44:13 +09:00
Shuhei Kadowaki d468912332
Merge pull request #369 from JunoLab/avi/cleanup
clean up:
2020-06-13 22:39:34 +09:00
Shuhei Kadowaki 753afe24d7
Merge pull request #368 from JunoLab/avi/config
config powerup
2020-06-13 22:23:55 +09:00
Shuhei Kadowaki c0e7e66ec3 clean up:
- unused `:display` chunk option
- rm `displayed` chunk field
- rm `cur_result`, `pendind_code`, `term_state` `Report` field
- rm `:skip` config option
2020-06-13 21:59:09 +09:00
Shuhei Kadowaki fd07d2db3f
Merge pull request #367 from JunoLab/avi/fixpath
fix paths
2020-06-13 21:52:11 +09:00
Shuhei Kadowaki 8d95e159e2 config powerup 2020-06-13 21:42:09 +09:00
Shuhei Kadowaki 9fac56f681 why `get_outname` defined in run.jl 2020-06-13 21:14:44 +09:00
Shuhei Kadowaki b709ce8aef
Merge pull request #364 from JunoLab/avi/fix263
fixes #263
2020-06-13 21:14:02 +09:00
Shuhei Kadowaki 4a89b04759 fix `get_cwd` 2020-06-13 20:48:44 +09:00
Shuhei Kadowaki ec986b387b `cd` into doc's working directory 2020-06-13 20:42:57 +09:00
Jonas Isensee 5c853150c8 fix math escapes in code and output 2020-06-13 09:14:12 +02:00
Shuhei Kadowaki f8b1c5104b more test clean up 2020-06-11 20:28:55 +09:00
Shuhei Kadowaki d88675d521 rm rich_output test
will be replaced by per-format rendering test
2020-06-11 20:26:25 +09:00
Shuhei Kadowaki e52c30f72e add test 2020-06-11 20:20:42 +09:00
Shuhei Kadowaki 66c33e6679 fixes #263 2020-06-11 20:20:30 +09:00
Shuhei Kadowaki cdd653e028 make Weave.path really path 2020-06-10 01:24:08 +09:00
Shuhei Kadowaki 8515c0dcde SandBox -> mod 2020-06-10 00:36:40 +09:00
Shuhei Kadowaki 3a7cb360af
Merge pull request #363 from JunoLab/avi/fixregression
fix header regression, add test, update test
2020-06-05 19:56:30 +09:00
Shuhei Kadowaki c7b566aaaa fix header regression, add test, update test 2020-06-05 18:59:02 +09:00
Jonas Isensee 630ac466e7 Reapply improvements to the tex rendering pipeline 2020-06-03 14:13:07 +02:00
Shuhei Kadowaki 3e6cda8950
Merge pull request #361 from JunoLab/avi/list
make `list_out_formats` return return just data structure
2020-06-02 19:57:59 +09:00
Shuhei Kadowaki f1d8838bc5
Merge pull request #360 from JunoLab/avi/refc
yet another clean up:
2020-06-02 19:52:46 +09:00
Shuhei Kadowaki 3faa8e2d95 make `list_out_formats` return return just data structure 2020-06-02 19:35:07 +09:00
Shuhei Kadowaki 3ddb1375eb yet another clean up:
- remove weird dispatches
- rm unused `result_no` field
2020-06-02 19:25:34 +09:00
Shuhei Kadowaki 73bf7fe77f
Merge pull request #350 from JonasIsensee/texexports
Reworking format.jl
2020-06-02 19:24:13 +09:00
Shuhei Kadowaki 533667b9ad type annotate API 2020-06-02 19:03:30 +09:00
Shuhei Kadowaki aa7fd311d8 use isnothing & isempty 2020-06-02 19:00:40 +09:00
Shuhei Kadowaki 0760591021 bump up to julia 1.2 2020-06-02 15:48:02 +09:00
Shuhei Kadowaki 04b24ea83b a bit more reorder 2020-06-02 15:45:38 +09:00
Shuhei Kadowaki 4b12f3da99 reorder functions again 2020-06-02 15:40:04 +09:00
Shuhei Kadowaki c6b23d4541 drop LTS support:
- first, it's really dull to keep compatibility with LTS
- and now we want to use `Base.@kwdef` for creating types with 
supertypes, and LTS can't have that for reasons
2020-06-02 15:33:17 +09:00
Shuhei Kadowaki ae48729cff use type field to restore header check 2020-06-02 15:31:41 +09:00
Shuhei Kadowaki 19b4a7974f reorder WeaveFormat field defs 2020-06-02 15:31:18 +09:00
Shuhei Kadowaki 0bdab33630 Merge branch 'master' into texexports 2020-06-01 22:45:32 +09:00
Shuhei Kadowaki 55d2c975cd set rendering options with dispatch:
- remove unused field defs
- in theory extensible, once documented
- fix test
- start to change terminology, `format` -> `render`
2020-06-01 22:36:48 +09:00
Shuhei Kadowaki ae0dc70ffa refactoring:
- reorder/move things so that format-specific rendering methods are 
defined close to the format
- separate common rendering methods from format specific methods
- fix using location
2020-06-01 21:32:18 +09:00
Jonas Isensee 543f99a915 rename files and include location + move texify 2020-05-31 18:04:40 +02:00
Jonas Isensee b5477d27ff revert improvements to tex rendering 2020-05-31 17:33:11 +02:00
Jonas Isensee 9875bc10f7 pass fewer arguments and bugfixes 2020-05-31 13:26:27 +02:00
Jonas Isensee 45adb8992f some cleanup 2020-05-31 12:07:26 +02:00
Jonas Isensee 3eba5de7f4 make `texminted` output valid texfile 2020-05-31 11:48:37 +02:00
Jonas Isensee 62d56846f4 fix lots of things I missed before 2020-05-31 09:49:20 +02:00
Jonas Isensee 770496b3af remove format dict - make everything a field of format <: WeaveFormat directly 2020-05-31 09:29:26 +02:00
Jonas Isensee 6e99822905 removing duplicate code 2020-05-30 18:02:49 +02:00
Jonas Isensee 119b3332aa move around code into separate files 2020-05-30 17:49:20 +02:00
Shuhei Kadowaki 9ccf3a2c5e
Merge pull request #359 from JunoLab/avi/figpath
respect specied `fig_path`
2020-05-30 23:57:53 +09:00
Shuhei Kadowaki db89118b4c fix typing and improve `@define_format` 2020-05-30 22:46:20 +09:00
Shuhei Kadowaki e7637de643 Merge branch 'master' into texexports 2020-05-30 22:22:10 +09:00
Shuhei Kadowaki e0e9ae8753 respect specied `fig_path`
- closes #358
2020-05-30 22:14:50 +09:00
Shuhei Kadowaki 5b959a972c
Merge pull request #355 from JunoLab/avi/refactorformatters
refactor formatters.jl
2020-05-30 22:14:38 +09:00
Shuhei Kadowaki 788f926067 move description field into `formatdict` 2020-05-30 21:16:03 +09:00
Fredrik Bagge Carlson c87782f451
[RFC] Do not define Markdown.latex using eval
This PR solves #356 at the expense of a warning:
```
WARNING: Method definition latex(IO, Markdown.LaTeX) in module Markdown at /home/fredrikb/julia/usr/share/julia/stdlib/v1.5/Markdown/src/IPython/IPython.jl:28 overwritten in module WeaveMarkdown at /home/fredrikb/.julia/dev/Weave/src/WeaveMarkdown/markdown.jl:10.
  ** incremental compilation may be fatally broken for this module **
```
2020-05-27 13:04:51 +02:00
Shuhei Kadowaki 96de887308 basic assertion 2020-05-26 10:44:30 +09:00
Shuhei Kadowaki aa63b20e7c remove unncessary :doctype field 2020-05-25 22:39:59 +09:00
Shuhei Kadowaki cc936f5377 refactor formatters.jl 2020-05-25 22:39:37 +09:00
Shuhei Kadowaki f4ed10b625 define render_doc and dispatch on it with different formats
- and load minted package for TexMinted format

Co-Authored-By: null <JonasIsensee@users.noreply.github.com>
2020-05-25 20:29:57 +09:00
Shuhei Kadowaki 2fdd09b585 introduce WeaveFormat abstract type
well, we can do much more things using this, but this commit just 
introduces this type

Co-Authored-By: null <JonasIsensee@users.noreply.github.com>
2020-05-25 20:29:57 +09:00
Jonas Isensee e20042848d introduce common supertype for JMarkdown2tex and Tex 2020-05-25 20:29:57 +09:00
Shuhei Kadowaki 1e9ba19db4 fix wording 2020-05-25 12:22:33 +09:00
Shuhei Kadowaki 14b56f1667
Merge pull request #353 from JunoLab/avi/rmarkdownchunks
RMarkdown style chunk options
2020-05-25 12:13:28 +09:00
Shuhei Kadowaki 227ab2cbf8 informative test skipping 2020-05-25 11:46:54 +09:00
Shuhei Kadowaki 84e91104d5 maybe fix type errors 2020-05-25 11:44:09 +09:00
Shuhei Kadowaki 44ed8788d5 LTS compat ... 2020-05-25 11:44:09 +09:00
Shuhei Kadowaki 022bb216eb general documentation improvements 2020-05-25 11:44:09 +09:00
Shuhei Kadowaki e43a2843af descriptions for RMarkdown style chunk option specs 2020-05-25 11:44:09 +09:00
Shuhei Kadowaki bb4ebb105e add tests cases for RMarkdown styel chunk option passing 2020-05-25 11:44:09 +09:00
Shuhei Kadowaki b0db8b991c allow RMarkdown style chunk option passing:
e.g.:
- `julia, k1 = v1`
- `{julia, k1 = v1}`
- `julia k1 = v1`
2020-05-25 11:44:09 +09:00
Shuhei Kadowaki dd0c51b6e5 improve type definition of CodeChunk 2020-05-25 11:44:09 +09:00
Shuhei Kadowaki 3d4f04902c
Merge pull request #354 from JunoLab/avi/onlyci
trigger tests for Plots.jl and Gadfly.jl only on CI
2020-05-25 10:55:06 +09:00
Shuhei Kadowaki e9c9274896 trigger tests for Plots.jl and Gadfly.jl only on CI 2020-05-25 10:14:45 +09:00
Shuhei Kadowaki 542f3e3225
Merge pull request #351 from JunoLab/avi/refactorreader
refactor /reader/
2020-05-24 23:29:53 +09:00
Shuhei Kadowaki 976d822f58 refactor /reader/ 2020-05-24 22:54:58 +09:00
Shuhei Kadowaki 819079c0f6
Merge pull request #349 from JunoLab/avi/fixunicode
fixes #348
2020-05-24 21:38:57 +09:00
Shuhei Kadowaki b62a744dfe update tests:
- create new test_inline.jl
- add tests to check inline code parser handlers unicode correctly
- create end2end.jl, which temporarily keeps old end2end tests
2020-05-24 21:11:09 +09:00
Shuhei Kadowaki eca4ed2559 handle codeunits gracefully in inline chunks 2020-05-24 18:17:58 +09:00
Shuhei Kadowaki 9b55d7e924
Merge pull request #347 from JunoLab/avi/pandochighlight
fix no highlight style error on pandoc2(html|pdf) output
2020-05-24 18:16:17 +09:00
Shuhei Kadowaki 0fc915b748 use same logic 2020-05-24 17:06:31 +09:00
Shuhei Kadowaki 39d3d8d91c fix no highlight style error on pandoc2(html|pdf) output 2020-05-24 16:18:58 +09:00
Shuhei Kadowaki 125d73982e
Merge pull request #344 from JunoLab/avi/renames
more consistent templates names, move stylesheets into ./stylesheets
2020-05-24 15:50:57 +09:00
Shuhei Kadowaki 0bc0d3b510 more consistent templates names, move stylesheets into ./stylesheets 2020-05-24 14:16:37 +09:00
Shuhei Kadowaki b8b9b095b7 fix tests:
- revert changes introduced in 1fb4065 in test suite
2020-05-24 14:05:29 +09:00
Shuhei Kadowaki 48adeff932 serious fix 2020-05-24 03:38:32 +09:00
Shuhei Kadowaki a7de8f5f58 minor fix 2020-05-24 03:17:24 +09:00
Shuhei Kadowaki 60fc450c88
Merge pull request #341 from JunoLab/avi/preprefactor
pre #338
2020-05-24 03:14:11 +09:00
Shuhei Kadowaki 1fb40645ed refactors: almost just about code styles, doesn't change any behaviour 2020-05-24 02:36:32 +09:00
Shuhei Kadowaki 9ca328f468 add TODO 2020-05-23 23:50:28 +09:00
Shuhei Kadowaki d84504267b addspaces -> addlines 2020-05-23 23:49:29 +09:00
Shuhei Kadowaki 29ff436a00 consistent and clearer terminology:
- formatted -> body/rendered
- wdate -> weave_date
- wsource (or source) -> weave_source
- wdate -> weave_date
2020-05-23 23:05:36 +09:00
Shuhei Kadowaki c24920870d version 0.10.2 2020-05-23 22:51:33 +09:00
Shuhei Kadowaki f4caba1561 maxlog for deprecation warning 2020-05-23 22:51:17 +09:00
Shuhei Kadowaki 3c76b804dc separate format logic from WeaveDoc:
- this is just a first step, though
2020-05-23 22:16:56 +09:00
Shuhei Kadowaki f71a491847 rm unused stuff 2020-05-23 22:04:01 +09:00
Shuhei Kadowaki af45cc01ab even more clean up 2020-05-23 22:03:40 +09:00
Shuhei Kadowaki 31f670b74c
Merge pull request #339 from JunoLab/avi/pandoc
refactor pandoc code:
2020-05-23 21:59:42 +09:00
Shuhei Kadowaki 0cdcc72bfb version 0.10.1 2020-05-23 21:57:05 +09:00
Shuhei Kadowaki 3ee7dec864
Merge pull request #340 from JunoLab/avi/emptyheader
fix case when `weave_options` are empty
2020-05-23 21:55:38 +09:00
Shuhei Kadowaki 0f94c7b49c fix case when `weave_options` are empty 2020-05-23 21:18:16 +09:00
Shuhei Kadowaki 54ccd9b1ed refactor pandoc code:
- more sensible err handling
- annotate TODO comments
2020-05-23 21:15:05 +09:00
Shuhei Kadowaki 3f4ba672b3 Revert "rm unused dict push!"
This reverts commit ef295e9a24.
2020-05-23 20:07:59 +09:00
Shuhei Kadowaki 745abe176c Revert "rm unused field from WeaveDoc"
This reverts commit 301f9b2f27.
2020-05-23 20:07:41 +09:00
Shuhei Kadowaki 301f9b2f27 rm unused field from WeaveDoc 2020-05-23 20:03:38 +09:00
Shuhei Kadowaki ef295e9a24 rm unused dict push! 2020-05-23 19:52:00 +09:00
Shuhei Kadowaki a03a1d4c34 EXAMPLE_FOLDER 2020-05-23 19:42:19 +09:00
Shuhei Kadowaki daec0e618f version 0.10 2020-05-18 23:45:47 +09:00
Shuhei Kadowaki 129a654b1d
Merge pull request #334 from JunoLab/avi/deprecate
deprecate `options`, change to `weave_options`:
2020-05-18 23:44:15 +09:00
Shuhei Kadowaki 500d77c9ca
Merge pull request #335 from JunoLab/avi/doc
doc improvements
2020-05-18 23:15:35 +09:00
Shuhei Kadowaki 8aa8f0c4df easy doc access 2020-05-18 22:59:18 +09:00
Shuhei Kadowaki ec0c0a327f format NEWS.md 2020-05-18 22:14:41 +09:00
Shuhei Kadowaki b4c2bbea45 deprecate `options`, change to `weave_options`:
- avoid unexpected header stripping (`options` sounds too general)
- deprecated `options` support will be remove within ≥v0.11
2020-05-18 22:10:26 +09:00
Shuhei Kadowaki 5e5cb875cf fix doc generation, add issue template 2020-05-17 13:03:19 +09:00
Shuhei Kadowaki 576ca2b6c9 some doc fix:
- update functions
- only make examples in CI
2020-05-17 12:23:41 +09:00
Shuhei Kadowaki 4113402908 rename `latex_keep_unicode` to `keep_unicode`, handle this in `format` 2020-05-17 12:17:24 +09:00
Shuhei Kadowaki 249c94a5c1 avoid manipulation of global struct 2020-05-17 12:14:30 +09:00
Shuhei Kadowaki 101b170ea6 some support for dynamic YAML `weave` configuration 2020-05-17 11:45:39 +09:00
Shuhei Kadowaki 6d1732247a a bit refactor 2020-05-17 11:10:25 +09:00
Shuhei Kadowaki b7233b468e no `term` option for inline code chunk 2020-05-17 11:05:30 +09:00
Shuhei Kadowaki 405deb3681 reorder things 2020-05-17 10:30:33 +09:00
Shuhei Kadowaki 87ba87d2d1 resolve CSS theme path relative to a target document when given in YAML 2020-05-17 10:29:01 +09:00
Shuhei Kadowaki cec388e94f add Weave version 2020-05-17 01:16:59 +09:00
Shuhei Kadowaki 0831144393
Merge pull request #311 from JunoLab/avi/limitdisplay
limit display:
2020-05-17 00:18:12 +09:00
Shuhei Kadowaki e60f066d31 fix when a header value is not `String` 2020-05-16 23:45:41 +09:00
Shuhei Kadowaki f86f5a7bd0 preserve header when weaving to Hugo markdown 2020-05-16 23:31:27 +09:00
Shuhei Kadowaki f9daa3a289 add test for HTML display limit 2020-05-16 23:25:44 +09:00
Shuhei Kadowaki 91403b4ec0 fix typo 2020-05-16 23:11:05 +09:00
Shuhei Kadowaki 5fb3fae741 no ANSI chars 2020-05-16 23:11:05 +09:00
Shuhei Kadowaki 7b53eb8e9e limit display:
- for now if we try to render a "big object" like a table with many 
rows, Weave tries to render all of the result and it can lead to that a 
document can't even be opened
2020-05-16 23:11:05 +09:00
Shuhei Kadowaki 58bc741b7f detect doctype when running a doc 2020-05-16 23:10:44 +09:00
Shuhei Kadowaki a740ba3556
Merge pull request #331 from JunoLab/avi/progres
integrate with Juno progress bar
2020-05-16 21:29:33 +09:00
Shuhei Kadowaki bca3ee7dd1 LTS compat ... 2020-05-16 21:04:58 +09:00
Shuhei Kadowaki ba8e9f4724 fix header handling in noweb doc 2020-05-16 20:33:48 +09:00
Shuhei Kadowaki 6121d21bfb fix doc syntax highlight 2020-05-16 19:53:09 +09:00
Shuhei Kadowaki 99a50ad86f integrate with Juno progress bar 2020-05-16 19:52:56 +09:00
Shuhei Kadowaki 2a6ee38850 fix code chunk line numbers 2020-05-16 19:52:24 +09:00
Shuhei Kadowaki 11c720ad7f
Merge pull request #329 from JunoLab/avi/dynamic
dynamic YAML parsing
2020-05-16 18:57:07 +09:00
Shuhei Kadowaki c1cf566c53 refactor format.jl 2020-05-16 17:59:17 +09:00
Shuhei Kadowaki 0d3d3a8c19 rm code ... 2020-05-16 17:59:04 +09:00
Shuhei Kadowaki 6d91ab6512 no explicit header support in `convert_doc` 2020-05-16 17:53:46 +09:00
Shuhei Kadowaki 98abd5e92e write documentation for dynamic header 2020-05-16 17:52:17 +09:00
Shuhei Kadowaki 6100083c9e update test 2020-05-16 16:05:02 +09:00
Shuhei Kadowaki 6955ca6be2 add test for header processing 2020-05-16 01:49:55 +09:00
Shuhei Kadowaki 17c2151d86 a bit refactor:
- don't match slide `---` separator as header start/end
- recognize `doctype` in construction
2020-05-16 01:49:30 +09:00
Shuhei Kadowaki 492d1f330b dynamic YAML option specification 2020-05-16 01:47:52 +09:00
Shuhei Kadowaki 95c3dac962
Merge pull request #330 from JunoLab/avi/refactor
refactor
2020-05-16 01:25:25 +09:00
Shuhei Kadowaki 42115e7d52 rename writer.jl -> converter.jl 2020-05-16 00:43:33 +09:00
Shuhei Kadowaki 094ebea6cf simplify converter functions 2020-05-16 00:32:28 +09:00
Shuhei Kadowaki 7c2eb23bcd small refactors (mostly about code styles) 2020-05-16 00:32:09 +09:00
Shuhei Kadowaki 589e1ce3d1
Merge pull request #327 from JunoLab/avi/clean
more test clean up
2020-05-11 14:33:53 +09:00
Shuhei Kadowaki 1ddff9a1b7 more test clean up 2020-05-11 09:40:10 +09:00
Shuhei Kadowaki 636e3540c7
Merge pull request #325 from JunoLab/avi/header
rm header_args
2020-05-10 16:25:34 +09:00
Shuhei Kadowaki bc0f687352 rm header_args 2020-05-10 15:55:37 +09:00
Shuhei Kadowaki 2c7f3da7cc
Merge pull request #324 from JunoLab/avi/cleanup
rm unused tests
2020-05-10 15:54:46 +09:00
Shuhei Kadowaki 423146f981 rm unused tests 2020-05-10 15:27:14 +09:00
Shuhei Kadowaki 2e19930565
Merge pull request #323 from JunoLab/avi/bang
use bangs for destructive functions
2020-05-10 14:28:40 +09:00
Shuhei Kadowaki de2a6657ea rm appveyor 2020-05-10 14:11:10 +09:00
Shuhei Kadowaki 867ad7c954 update LICENSE 2020-05-10 14:10:46 +09:00
Shuhei Kadowaki 54e50a54cb users should load Cairo 2020-05-10 14:07:55 +09:00
Shuhei Kadowaki d809ddf703
Merge pull request #322 from JunoLab/avi/require
don't load Weave Plots submodules into user's module
2020-05-10 14:06:09 +09:00
Shuhei Kadowaki e459bfb87d use bangs for destructive functions 2020-05-10 13:56:09 +09:00
Shuhei Kadowaki 98e44db659
Merge pull request #321 from JunoLab/avi/noauto
internal API improvements
2020-05-10 13:49:33 +09:00
Shuhei Kadowaki ede31bcf74 don't load Weave Plots submodules into user's module 2020-05-10 13:35:54 +09:00
Shuhei Kadowaki e89d5da250 rm unncessary `Symbol` spec:
- change `informat` and `doctype` options to 
`Union{NothingAbstractString}`
2020-05-10 13:20:44 +09:00
Shuhei Kadowaki 4b6fc2d913 fix typings 2020-05-10 00:01:49 +09:00
Shuhei Kadowaki c825076e36 simplify imports 2020-05-10 00:01:41 +09:00
Shuhei Kadowaki 68f72bdfb3 small updates 2020-05-09 23:55:11 +09:00
Shuhei Kadowaki ca42e09f8d
Merge pull request #313 from JunoLab/avi/sandbox
internal refactor step 1
2020-05-09 23:53:49 +09:00
Shuhei Kadowaki a526cb8f15
Merge pull request #319 from JunoLab/avi/weavedoc
remove weird default constructor for `WeaveDoc`
2020-05-09 23:39:03 +09:00
Shuhei Kadowaki f1df02c2b7
Merge pull request #320 from JunoLab/avi/robusttest
more robust error rendering test
2020-05-09 23:17:24 +09:00
Shuhei Kadowaki 4dae2a0816 `WEAVE_OPTION_NAME` 2020-05-09 22:42:05 +09:00
Shuhei Kadowaki 8303311d59 more robust error rendering test 2020-05-09 22:35:45 +09:00
Shuhei Kadowaki 36bdd4f82b remove weird default constructor for `WeaveDoc` 2020-05-09 22:33:58 +09:00
Shuhei Kadowaki 5f7cf529b9 chunks.jl -> types.jl 2020-05-09 21:03:00 +09:00
Shuhei Kadowaki 66d32fabe8
Merge pull request #318 from JunoLab/avi/refactorreader
refactor readers.jl
2020-05-09 21:00:35 +09:00
Shuhei Kadowaki 750b7624e0 refactor readers.jl:
- avoid unnecessary overloading on `parse_doc`
- split readers.jl into multiple scripts
2020-05-09 20:17:53 +09:00
Shuhei Kadowaki 8b910c0d70
Merge pull request #317 from JunoLab/avi/clearsandbox
clear sandbox module correctly
2020-05-09 18:56:44 +09:00
Shuhei Kadowaki 3b8201df04 add test for `clear_module!` 2020-05-09 18:22:24 +09:00
Shuhei Kadowaki 79579053f1 refactor tests:
- simpler module evaluation test
- remove useless include_weave test
2020-05-09 17:27:51 +09:00
Shuhei Kadowaki d4413a1d78 clear sandbox module correctly 2020-05-09 16:09:11 +09:00
Shuhei Kadowaki 5dbe54316b isnothing utility 2020-05-09 11:26:32 +09:00
Shuhei Kadowaki e41202d3ff no weird Base.run overload 2020-05-09 11:25:19 +09:00
Shuhei Kadowaki 14e7635458 getvalue -> get 2020-05-09 11:25:19 +09:00
Shuhei Kadowaki ac486c5e1d
Merge pull request #316 from JunoLab/avi/dev
ensure Weave display pops out even if an internal err occurs
2020-05-09 11:16:03 +09:00
Shuhei Kadowaki 9a1b81a026
Merge pull request #315 from JunoLab/avi/bumpplot
bump Plots.jl version
2020-05-09 03:25:18 +09:00
Shuhei Kadowaki 4e7fda212d ensure Weave display pops out even if an internal err occurs 2020-05-09 02:48:56 +09:00
Shuhei Kadowaki b25300b269 bump Plots.jl version 2020-05-09 02:48:09 +09:00
Shuhei Kadowaki 0c59e92fd7
Merge pull request #312 from JunoLab/avi/format
format things
2020-05-09 01:10:44 +09:00
Shuhei Kadowaki 2376a9dae9 format things 2020-05-08 23:39:17 +09:00
Shuhei Kadowaki 020b4353a4 fix indents, Github -> GitHub 2020-05-06 23:37:04 +09:00
Shuhei Kadowaki 36bce9cf1f
Merge pull request #305 from JunoLab/avi/headers
more graceful header handling
2020-04-23 00:44:51 +09:00
Shuhei Kadowaki db13be44e3 fix no header case 2020-04-18 19:18:03 +09:00
Shuhei Kadowaki 95e32c4908 more graceful header handling 2020-04-18 19:10:07 +09:00
Shuhei Kadowaki 8bbe31324f
Merge pull request #302 from baggepinnen/keepfigures
Keep latex figures [replaces #274]
2020-04-17 18:59:16 +09:00
Fredrik Bagge Carlson f126e1c7a9 fix formatting 2020-04-17 12:16:56 +08:00
Fredrik Bagge Carlson 7e88052db3 keep latex figures 2020-04-17 12:16:56 +08:00
Shuhei Kadowaki 67126a515a update README 2020-04-01 19:04:55 +09:00
Shuhei Kadowaki 3a3385471b
Merge pull request #297 from JunoLab/avi/buildpdf
upload (locally) prebuilt PDF example outputs
2020-04-01 18:28:08 +09:00
Shuhei Kadowaki 20fd22ec75 upload prebuilt PDF examples 2020-04-01 18:26:59 +09:00
Shuhei Kadowaki f1e87123f4
Merge pull request #296 from JunoLab/avi/notebook
Specify HTML as a default output format for weaving notebooks
2020-03-28 01:14:17 +09:00
Shuhei Kadowaki d40e21ea35 improve documentations around notebooks 2020-03-27 20:43:33 +09:00
Shuhei Kadowaki a759dc10bd specify default output format (HMTL) for notebooks 2020-03-27 20:34:06 +09:00
Shuhei Kadowaki b6b4082977
Merge pull request #295 from JunoLab/avi/moretypes
more type annotate APIs
2020-03-27 19:12:51 +09:00
Shuhei Kadowaki 840f1b3b8f simpler doc APIs 2020-03-27 18:45:04 +09:00
Shuhei Kadowaki efccb5c7f1 more documentation improve 2020-03-27 10:16:57 +09:00
Shuhei Kadowaki dfb9e63d0e update travis 2020-03-26 21:42:31 +09:00
Shuhei Kadowaki 9e9fe45231 improve documentations 2020-03-26 21:41:54 +09:00
Shuhei Kadowaki 7a7d8f3dde update documentation source accordingly 2020-03-26 17:35:43 +09:00
Shuhei Kadowaki f8c32c865b more type annotate APIs 2020-03-26 17:35:05 +09:00
Shuhei Kadowaki 529edaf94e version 0.9.4 2020-03-18 18:19:23 +09:00
Shuhei Kadowaki e1365ba9b5
Merge pull request #294 from JunoLab/avi/rmcompat
rm Compat
2020-03-18 18:05:32 +09:00
Shuhei Kadowaki 16bc2d7be9 immutable structs for result trait 2020-03-18 10:50:01 +09:00
Shuhei Kadowaki 545baecdaa bump YAML (closes #291) 2020-03-18 10:23:27 +09:00
Shuhei Kadowaki 6339303569 rm Compat 2020-03-18 08:53:25 +09:00
Shuhei Kadowaki 62ae84d32d
Merge pull request #292 from JunoLab/avi/plotfix
fixes on plotting
2020-03-17 12:15:31 +09:00
Shuhei Kadowaki 1f8514a737 fixes: #105, #288
closes: #289
2020-03-17 10:57:36 +09:00
Shuhei Kadowaki 5fd0bcb9ee re: update image 2020-03-06 20:52:09 +09:00
Shuhei Kadowaki 47323b37f7 update Juno integration image 2020-03-06 20:23:44 +09:00
Shuhei Kadowaki d8595e266f more doc fixes 2020-03-06 10:14:21 +09:00
Shuhei Kadowaki 230a8c5454 more fix doc syntax 2020-03-06 09:59:32 +09:00
Shuhei Kadowaki db0aa06f38 fix doc syntax 2020-03-06 09:20:32 +09:00
Shuhei Kadowaki 32bddc543f add version compat for Compat 2020-03-06 09:19:00 +09:00
Shuhei Kadowaki 0f5e3df9aa
Merge pull request #285 from JunoLab/avi/docbuild
fix doc url and reenable doc build
2020-03-06 02:41:07 +09:00
Shuhei Kadowaki deeb54dc7c fix doc url and reenable doc build 2020-03-06 01:08:07 +09:00
Shuhei Kadowaki 372974e1ad
Merge pull request #281 from kleinschmidt/dfk/code-size
use 0.9em for code size instead of hard coding 13px
2020-03-05 20:25:40 +09:00
Sebastian Pfitzner 7c58a284ee
Merge pull request #283 from JunoLab/compathelper/new_version/2020-03-05-00-07-25-058-3363680067
CompatHelper: add new compat entry for "Requires" at version "1.0"
2020-03-05 10:49:53 +01:00
Sebastian Pfitzner 04ed58102d
Merge pull request #282 from JunoLab/compathelper/new_version/2020-03-05-00-07-19-291-3538927573
CompatHelper: add new compat entry for "JSON" at version "0.21"
2020-03-05 10:49:44 +01:00
github-actions[bot] a250a48499 CompatHelper: add new compat entry for "Requires" at version "1.0" 2020-03-05 00:07:25 +00:00
github-actions[bot] ae8812de51 CompatHelper: add new compat entry for "JSON" at version "0.21" 2020-03-05 00:07:19 +00:00
Dave Kleinschmidt 9ae54c80d6 bump patch version 2020-03-04 16:32:24 -05:00
Dave Kleinschmidt 048603ffe6 use 0.9em for code size instead of hard coding 13px 2020-03-04 16:29:32 -05:00
Sebastian Pfitzner ab5db9aa24
Merge pull request #279 from aviatesk/release
Release 0.9.2
2020-03-04 12:09:05 +01:00
Shuhei Kadowaki c020fea642 fix matrix&jobs 2020-03-04 19:37:36 +09:00
Shuhei Kadowaki 2aa7cb7ca5 several documentation updates 2020-03-04 19:23:48 +09:00
Shuhei Kadowaki 4dfa7da71f update doc deps 2020-03-04 19:20:03 +09:00
Shuhei Kadowaki 4cfcc61fb6 introduce compat helper 2020-03-04 18:01:36 +09:00
Shuhei Kadowaki d9b37f8244 fix compats 2020-03-04 18:01:26 +09:00
Sebastian Pfitzner 79a3d73882
Merge pull request #268 from aviatesk/update
updates
2020-03-04 09:25:52 +01:00
Shuhei Kadowaki d4ce8cdb6b update travis 2020-03-04 02:05:04 +09:00
Sebastian Pfitzner d108e4a1dc
Merge pull request #272 from JuliaTagBot/master
Install TagBot as a GitHub Action
2020-02-18 13:10:23 +01:00
Julia TagBot fd216ca1f5 Install TagBot as a GitHub Action 2020-02-08 20:51:08 +07:00
aviatesk e18c5f35e3 update comment 2020-01-07 23:51:55 +09:00
aviatesk d0ecc30f52 bump version 2020-01-05 16:11:19 +09:00
aviatesk 6ca6c51ea6 rm REQUIRE 2020-01-05 15:21:02 +09:00
aviatesk 652b19cd0f fixes #232 2020-01-05 15:18:41 +09:00
Sebastian Pfitzner 72e7ccfe8a
Merge pull request #257 from aminya/patch-1
Update old markdown link
2019-11-04 09:23:39 +01:00
Amin Yahyaabadi a64fccbf2c
Update old markdown link 2019-11-03 07:00:37 -06:00
Sebastian Pfitzner 585c4111b6
Merge pull request #255 from sebastianpech/fix-test
Fix inline tests after Highlights update
2019-10-23 09:04:01 +02:00
Sebastian Pech 05c93b8607 Fix inline tests after Highlights update 2019-10-22 20:10:27 +02:00
Sebastian Pfitzner 3d673d0338
Merge pull request #244 from sebastianpech/disable-unicode-escape
Add argument to weave function to disable unicode escape
2019-10-21 19:48:29 +02:00
Sebastian Pech c9e26d5638 Rename escape_unicode and move to tex based formatdicts 2019-10-15 21:48:05 +02:00
Sebastian Pech 0018f0e24c Fix new expected output in ref for new escape char 2019-10-15 17:18:50 +02:00
Sebastian Pech da66a8f272 Add escape_unicode to docstring 2019-10-15 14:20:11 +02:00
Sebastian Pfitzner d31d16581b
Merge pull request #247 from xiaodaigh/patch-1
Update usage.md
2019-09-29 10:57:02 +02:00
evalparse 31d3c2da56
Update usage.md 2019-09-28 17:41:54 +10:00
Sebastian Pfitzner b01b18ea2f
Merge pull request #241 from sebastianpech/figures
Improve usage of different figure environments in latex
2019-09-05 12:34:45 +02:00
Sebastian Pech bd5ff7031c Add argument for disabling unicode escaping 2019-09-05 10:13:49 +02:00
Sebastian Pfitzner 9fa28726ed
Merge pull request #243 from MatFi/patch-1
Fixed missing comma in example
2019-09-03 10:35:39 +02:00
MatFi 4fcee4d0e2
Update getting_started.md 2019-09-03 10:07:35 +02:00
Sebastian Pfitzner 3be6245820
Merge pull request #225 from devmotion/patch-1
Update badges
2019-08-29 12:39:48 +02:00
Sebastian Pech fa4a1a629d Add function to convert percentages to matching latex widths 2019-08-25 19:19:31 +02:00
Sebastian Pech 1b450b9e3d Fix docs \linewidth and fig_pos defaulting to !h 2019-08-25 17:16:59 +02:00
Sebastian Pech eeb723981d Fix printing [] if fig_env is empty string 2019-08-25 10:25:57 +02:00
Sebastian Pech 474cb6e4b2 Combine formatfigures for Tex and JMarkdown2tex 2019-08-25 09:39:03 +02:00
Tamas Nagy 51903c3df3
Merge pull request #239 from sebastianpech/Fixcaptureoutput
Fix displayed output produced by capture_output
2019-08-22 10:59:02 -07:00
Sebastian Pech 4d7a444246 Fix displayed output produced by capture_output 2019-08-21 15:03:22 +02:00
Tamas Nagy e7e5bd7c7f
explicitly add julia to compat section
see https://github.com/JuliaRegistries/General/pull/1616#issuecomment-506636070
2019-07-01 13:26:12 -07:00
David Widmann 18cce8472b
Update badges
The section "Documentation" in the README still contained the old broken links. Appveyor and Coveralls badges should be added again once the services are enabled for the moved repository.
2019-06-29 00:54:38 +02:00
Kevin Bonham 36464be927 Fix docs links in README (#224)
These links are giving 404 errors, so I thought I'd fix them :-)
2019-06-28 21:01:03 +03:00
ilia-kats 02134d29d5 use the minted jlcon lexer for terminal mode (#205) 2019-06-27 09:00:43 +03:00
Viral B. Shah 59edca786d
Create FUNDING.yml 2019-06-26 17:44:20 -04:00
Sebastian Pfitzner ed41be610a
Merge pull request #221 from thofma/master
Add html rendering of Markdown tables
2019-06-26 12:10:46 +02:00
Tommy Hofmann 1c0506342e Add html rendering of Markdown tables 2019-06-26 11:19:11 +02:00
Sebastian Pfitzner 9f664ba5a6
Merge pull request #202 from tshort/hook-fix
Fix hooks and add a push/pop hook to the test
2019-06-25 18:10:38 +02:00
Tamas Nagy 9e462a480b
bump version number for patch release
[ci skip]
2019-06-19 10:40:25 -07:00
Tamas Nagy df7f0d1f3c
Merge pull request #215 from Oblynx/patch-1
Fix mpastell/Weave.jl#214
2019-06-19 10:39:37 -07:00
Arnav Sood 5d3e05511e allow configuration of jupyter command while weaving notebooks, fixes #194
* notebook refactor and tests

* update PR

* add jupyter test jmd

* add back full warnings and remove debugging output

* Update test filename [ci skip]

* Conda for CI

* update for CI?

* remove Conda, IJulia, and tests for now

* Project.toml changes suggested by tinagly

* revive travis tests

* comment out nb tests
2019-06-19 10:26:13 -07:00
Tamas Nagy 6621920bec
Merge pull request #218 from davidanthoff/vscode
Mention VS Code extension in README
2019-06-12 11:48:05 -07:00
David Anthoff 975a67ad44 Mention VS Code extension in README 2019-06-10 11:23:01 -07:00
Konstantinos Samaras-Tsakiris ea1de0fb9e
Fix mpastell/Weave.jl#214
Fixes incorrect UTF-8 string handling as described in https://github.com/mpastell/Weave.jl/issues/214.
2019-06-04 21:02:40 +03:00
tshort bd69ef1f59 Fix hooks and add a push/pop hook to the test 2019-04-27 13:17:29 -04:00
Matti Pastell c9a814759d Release 0.9.0 2019-03-11 16:09:15 +02:00
Matti Pastell 95e860816c Restore .ps and .js.svg to Gadfly 2019-03-11 15:13:30 +02:00
Matti Pastell 99db6a9406 Actually fix include_weave 2019-03-11 14:25:17 +02:00
Matti Pastell 8194c8a1b8 Fix `include_weave`. Closes #152. 2019-03-11 14:05:06 +02:00
Matti Pastell 83e2e0ae20 Add tests for inline code 2019-03-11 13:39:21 +02:00
Matti Pastell 35addd2b50 Fixes to option parsing, gadfly pdf, stripping header, add tests 2019-03-11 10:23:31 +02:00
Matti Pastell c33309abf6 Tweak docs 2019-03-10 23:09:27 +02:00
Matti Pastell 4338fc4b07 Make out_path and template path relative to document 2019-03-10 22:53:00 +02:00
Matti Pastell 6f83f1abf5 Add example beamer document 2019-03-10 20:10:30 +02:00
Matti Pastell 3488af5534 Add docs for inline output, make figure output inline 2019-03-10 19:23:18 +02:00
Matti Pastell 4ab1c09b8c Allow using MustacheTokens as template directly 2019-03-10 17:51:19 +02:00
Matti Pastell e7a10eacdc Don't use isnothing 2019-03-10 17:20:43 +02:00
Matti Pastell 37aa0237a8 Add new syntax for inline code and fix output in md2* formats 2019-03-06 22:27:47 +02:00
Matti Pastell 371cec474f
Release 0.8.1 2019-03-06 10:54:54 +02:00
Matti Pastell 1de36fd1f5 Fix Jupyter header 2019-03-06 10:41:31 +02:00
Matti Pastell 4e70d32901 Don't run latex on travis 2019-03-05 20:18:58 +02:00
Matti Pastell 700e00b329 Add missing test document 2019-03-05 20:00:52 +02:00
Matti Pastell 6082786f92 Allow setting document options in YAML header 2019-03-05 19:36:27 +02:00
Matti Pastell 52f3a23d28 Allow format specific options in header 2019-03-05 16:44:10 +02:00
Matti Pastell d62172ad88 Update docs 2019-03-04 15:42:16 +02:00
Matti Pastell 6510ea0556
Documenter build (#191)
* Add documenter to travis
2019-03-04 15:10:03 +02:00
Matti Pastell efec59cdbf Add navigtation 2019-03-04 13:23:37 +02:00
Matti Pastell ecb66471a3 Set up documenter html build 2019-03-04 13:03:00 +02:00
Matti Pastell e9ea54bc1b Allow setting options in document header. Closes #189 2019-03-04 11:10:02 +02:00
Matti Pastell a14b7a8f80 Return weaved file path from weave function. Closes #190 2019-03-04 09:45:30 +02:00
Matti Pastell 0332137000 Release v0.8.0 2019-03-02 18:36:48 +02:00
Matti Pastell edd558de0e Add support for comments in Markdown. Closes #97 2019-02-28 16:17:03 +02:00
Matti Pastell badaaa7dea Decrease item and p spacing. Closes #162 2019-02-28 10:49:55 +02:00
Matti Pastell 710b67ca45 Add markdown flavor for improved math support. Closes #182 2019-02-27 18:21:05 +02:00
Matti Pastell f2773376d9 Merge branch 'noalign' 2019-02-27 16:43:15 +02:00
Matti Pastell 6a30aa20f2 Remove align environment from math output #182 2019-02-27 16:42:51 +02:00
Matti Pastell 73584edd34 Strip ANSI from text output #184 2019-02-27 16:19:14 +02:00
Matti Pastell 8d1bb63b0a Render markdown output in md2* formats. Fixes #156 2019-02-27 15:03:33 +02:00
Matti Pastell e52083c42a Display assigned objects from chunk's last line 2019-02-27 12:42:43 +02:00
Matti Pastell 73536707dc Change html colors closer to jupyter 2019-02-27 12:31:10 +02:00
Matti Pastell 056db5141a Add option to skip chunks in notebook 2019-02-27 10:15:56 +02:00
Matti Pastell bad5650027 Fix \bf and \frak symbols in md2tex. Improves #181 2019-02-26 17:38:28 +02:00
Matti Pastell 12f829a0ca Release 0.7.2 2019-02-26 10:47:43 +02:00
Toby Driscoll 26cf943d25 New output css class for md2html (#172)
* New output css class for md2html

* margins and padding taken from Highlights.jl
2019-02-26 09:16:27 +02:00
Matti Pastell 6e0daf9335 Render header in notebooks, fixes #179 2019-02-26 09:12:28 +02:00
Matti Pastell 7587b4f9cf
Fix line wrapping (#180)
* Fix line wrapping

* Don't chop from tail

* Test wrapping unicode
2019-02-26 00:09:40 +02:00
Matti Pastell cb791e8b69 Fix notebook support. Closes #173 2019-02-25 19:46:25 +02:00
Christopher Rackauckas 73f0e1e998 Remove precompile statement (#177) 2019-02-25 19:29:02 +02:00
schrimpf adf7338f34 Allow errors (#174)
* Added ability to pass aditional options to nbconvert. Main purpose is
to pass "--allow-errors"

* Changed IJulia.jupyter to IJulia.JUPYPTER to match change in IJulia.jl
2019-02-25 19:24:01 +02:00
Matti Pastell 1e630ed825
Update Project.toml 2019-02-08 16:16:07 +02:00
Matti Pastell f1a85d3726 Merge branch 'master' of https://github.com/mpastell/Weave.jl 2019-02-08 16:03:23 +02:00
Matti Pastell 972937e4a0 Merge branch 'kleinschmidt-dfk/figext' 2019-02-08 16:02:57 +02:00
Matti Pastell 4a7d63bc7e Clean up and fix svg embedding 2019-02-08 16:01:25 +02:00
Tamas Nagy caf64b2407 [WIP] Add Gadfly support back (#163)
* add back gadfly support

* fix svg embed encoding
2019-02-07 19:28:06 +02:00
Dave Kleinschmidt 4bf8e0e209 check fig_ext to choose preferred mimetype in display(::Report, d) 2019-02-01 10:59:39 -05:00
Matti Pastell 0a21a2ec90
v0.7.0 2019-01-29 09:01:11 +02:00
Matti Pastell 36339a07ff
v0.7.0 2019-01-29 08:53:52 +02:00
Dave Kleinschmidt d0c71ba556 use Base.show (#165)
* use Base.show

* drop offending show method altogether
2019-01-28 16:20:03 +02:00
Matti Pastell 921b9ec2ba Remove 0.7 from tests 2019-01-03 15:46:12 +02:00
schrimpf ab09bddcd8 change cache to work with figures (#158)
* Changed read/write cache to use serialize/deserialize instead of
JLD2. JLD2 fails to save strings longer than 2^16 characters, which
can occur in the stringmime() of large figures.

* Added test for cache with figures and html output.
Updated REQUIRE & Project.toml to include Serialization instead of
FileIO and JLD2

* Added "Import Pkg;" to expected output of errors, so that tests pass.
2019-01-03 15:40:32 +02:00
Matti Pastell bf57bf8a07
Use align for ```math blocks (#143)
* Use align for ```math blocks
* Fix deprecation from inline parsing
* Update tests
2018-08-23 08:22:08 +03:00
Matti Pastell 6d0779ca4d Enable equation numbers in MathJax, #142 2018-08-21 12:52:07 +03:00
Matti Pastell 246f7eef62 Remove tmp directories from md2pdf output, closes #140 2018-08-17 13:12:37 +03:00
Matti Pastell 73e9e71c3a Update travis 2018-08-17 12:07:54 +03:00
Matti Pastell aa4ba7ed52
Cleaning for Julia 1.0 (#141) 2018-08-17 10:28:12 +03:00
Matti Pastell b41b4b4d41 Fix deprecations from tests 2018-08-14 11:32:51 +02:00
Matti Pastell af7a6779a5
Fix appveyor config (#138) 2018-08-13 18:13:15 +03:00
Matti Pastell ecc02dcd55 Update docs 2018-08-13 14:51:08 +02:00
Matti Pastell d0a2291aa8 Update README and example 2018-08-13 14:30:06 +02:00
Matti Pastell 9aa01e4b89
Get CI running on 0.7 (#137) 2018-08-13 15:06:07 +03:00
Matti Pastell 2508268500 Update Plots dependency 2018-08-10 00:24:42 +03:00
Matti Pastell 6217f4fb72 Update tests rc2 2018-08-07 12:54:51 +03:00
Matti Pastell c72b7e7668 Add test depencies 2018-08-06 11:11:36 +03:00
Matti Pastell 2dbb5cc696 Bump highlights in deps 2018-08-06 11:04:11 +03:00
Matti Pastell 341edd3784 Allow custom fields in templates, closes #100 2018-07-27 14:39:53 +03:00
Matti Pastell 4cd0b92792 Fix pandoc support, add raw options to pandoc requires pandoc 2. Closes #132. 2018-07-27 14:18:33 +03:00
Matti Pastell 3fc3e3c6e0 Use :label consistently 2018-07-27 10:42:14 +03:00
Matti Pastell 3c81cd5bf2 Merge branch 'pandoc-crossref' 2018-07-27 10:22:56 +03:00
Matti Pastell 28428e0832 Add tests for pandoc labels, closes #127 2018-07-27 10:22:30 +03:00
Matti Pastell a5ba74dcd1 Makes Plots a depency in order to run tests 2018-07-27 09:21:57 +03:00
Matti Pastell 347ddbc45c Update figure options in docs 2018-07-27 01:30:21 +03:00
Matti Pastell 89e990b1dd Merge branch 'kleinschmidt-dfk/pandoc-crossref' into pandoc-crossref 2018-07-27 01:03:40 +03:00
Matti Pastell 5c803db6ae Merge branch 'dfk/pandoc-crossref' of https://github.com/kleinschmidt/Weave.jl into kleinschmidt-dfk/pandoc-crossref 2018-07-27 01:02:43 +03:00
Matti Pastell bb350ab334 Add Project.toml 2018-07-27 00:58:05 +03:00
Matti Pastell bd5e1d9a3b Eval requires in Main, add WeavePlots module 2018-07-26 21:29:46 +03:00
Matti Pastell 160017b6e8 Remove plot library hack and use Requires instead 2018-07-26 20:32:10 +03:00
Matti Pastell 44455a1fda Fix generic pdf support 2018-07-26 12:42:52 +03:00
Matti Pastell 973274bf22 Fix Plots support 2018-07-26 12:20:04 +03:00
Matti Pastell 93bb9ced2d Fix occursin bugs 2018-07-26 11:35:17 +03:00
Matti Pastell f90547cee6 Fix bug in Sandboxing, run code in sandbox module by default 2018-07-26 02:01:10 +03:00
Matti Pastell b136fa615d Fix header parsing, update example 2018-07-26 00:26:38 +03:00
Matti Pastell b5e02cad36 Add tests for running in Main or sandbox module. Closes #101 2018-07-26 00:12:48 +03:00
Matti Pastell e5d2045350 Clean formatters 2018-07-25 23:26:39 +03:00
Matti Pastell 373f5e9d37 Allow choosing where to eval code. 2018-07-25 23:24:25 +03:00
Matti Pastell d72734a828 Use testsets 2018-07-25 21:43:38 +03:00
Matti Pastell ac26ffe271 Fix formatter test 2018-07-25 11:22:12 +03:00
Matti Pastell 7c091ed034 Clean highlighting code 2018-07-25 01:33:24 +03:00
Matti Pastell 4523b3a58e Use Highlights.jl for md2tex output 2018-07-24 23:40:47 +02:00
Matti Pastell 57724aff67 Fix error handling test 2018-07-24 11:50:28 +02:00
Matti Pastell e6cea19d5e Update display tests 2018-07-24 10:46:04 +02:00
Matti Pastell 0956ce6dff Fix more deprecations 2018-07-23 19:35:15 +02:00
Matti Pastell 83c506252d Fix formatting deprecations 2018-07-23 19:29:07 +02:00
Matti Pastell 7a2150430d Remove test depencies 2018-07-23 18:52:08 +02:00
Matti Pastell 01f8810bc3 Run working tests with 0.7 2018-07-23 18:39:48 +02:00
Matti Pastell f8978eb560 Merge branch 'master' of https://github.com/mpastell/Weave.jl 2018-07-23 12:41:41 +02:00
Matti Pastell fb854a1d63 Update Mathjax CDN, closes #131 2018-07-23 12:41:25 +02:00
femtocleaner[bot] f04b67f69b Fix deprecations (#135)
* Fix deprecations

* Fix html output
2018-07-23 13:37:25 +03:00
Matti Pastell 53d76a61bb
Bump julia to 0.7 2018-07-23 10:22:17 +03:00
Dave Kleinschmidt 6ff3bee3e8 handle empty attribs 2018-05-21 15:20:15 -04:00
Tom Short 5e1d8c1976 Fix a glitch with `pop_preexecute_hook` (#124) 2018-03-17 12:14:33 +02:00
Matti Pastell 53c2a337f3 Use IJulia jupyter. Closes #122 2018-02-27 15:08:08 +02:00
Dave Kleinschmidt b4ebf0cd16 generate pandoc-crossref style labels for figures
also clean up attrib code
2018-02-01 13:13:11 -05:00
Matti Pastell ce43dea594 Add tests for markdown writer 2018-01-08 12:53:48 +02:00
Matti Pastell 8ab0d66dda Fix html list writer 2018-01-07 21:33:50 +02:00
Matti Pastell 1341aed3d0 Precompile 2018-01-07 20:36:46 +02:00
Matti Pastell b2b143c22e Add markdown2html writer, remove Documenter depency 2018-01-07 20:19:59 +02:00
Matti Pastell 88d8665e03 Load JLD2 and FileIO only when cache is used 2018-01-07 20:01:18 +02:00
Matti Pastell d19d6b6d81 Update docs for 0.5.1 2018-01-07 12:31:06 +02:00
Matti Pastell eead8f24a8
Added error handling with html display (#117)
* Implemented error handling and initial html display

* Improved html display and tests for error handling
2018-01-07 11:53:07 +02:00
Matti Pastell 51ea08ca88 Remove nbconvert timeout by default 2018-01-05 18:01:16 +02:00
Matti Pastell 048b484d83 Fix notebook doc string 2018-01-05 17:51:30 +02:00
Matti Pastell 57c17e05a3 Add notebook function for converting output to Jupyter notebooks 2018-01-05 17:42:47 +02:00
Matti Pastell 48327bd570 Embed Plots animated gifs to html output. Closes #105 2018-01-04 21:45:43 +02:00
Matti Pastell 742f00bf6a Fix image width for html output 2018-01-04 18:05:19 +02:00
Matti Pastell 965eb6dfe9 Fix world age bug with display 2018-01-04 18:02:09 +02:00
Matti Pastell be0ac321b3 Use Highlight.jl with pandoc2html 2018-01-04 18:00:01 +02:00
Matti Pastell 5b6d50cf72 Tweak CSS templates, fixes #61 2018-01-04 17:18:25 +02:00
Matti Pastell 484b1fdf23 FIx `term=true` for md2tex 2018-01-03 20:31:24 +02:00
Matti Pastell 6dc482d997 Fix term=true in "rich outputs", closes #113 2018-01-03 19:33:57 +02:00
Matti Pastell 15d4cdf512 Update md2tex format tests. Closes #107 2018-01-03 19:07:14 +02:00
Matti Pastell dc566fc69a Fix md2pdf output -> use minted and xelatex 2018-01-03 17:23:57 +02:00
Matti Pastell 6c149b383c Use compact output for IO 2018-01-03 15:48:14 +02:00
Matti Pastell 51641124b5 Fix output: html wrap bug, output from last line 2018-01-03 15:35:47 +02:00
Matti Pastell 83b5c8f276 More tests 2018-01-03 12:34:47 +02:00
Matti Pastell 2596670aa3 More tests for figure format 2018-01-03 12:34:13 +02:00
Matti Pastell 6ef6a0b739
Improve tests for "rich" output, remove decencies from tests (#114)
* Remove DataFrames as test depency

* New mimetype tests for output
2018-01-03 12:13:12 +02:00
Matti Pastell 65af831152 New mimetype tests for output 2018-01-03 11:59:43 +02:00
Matti Pastell e0cd57e6a9 Remove DataFrames as test depency 2018-01-03 10:57:27 +02:00
Matti Pastell 0f0e190dd6 More figure formats to tests 2018-01-03 10:21:04 +02:00
Matti Pastell 753402529e Add tests for figure formats 2018-01-03 10:14:32 +02:00
Matti Pastell 9e5ad966eb Add script reader test 2018-01-03 09:37:05 +02:00
Matti Pastell 361f404f95 Fix notebook test 2018-01-03 09:13:58 +02:00
Matti Pastell c1795e7310 Fix Gadfly tests 2018-01-03 08:48:01 +02:00
Matti Pastell eb87de143b Disable html publish test 2018-01-02 16:51:13 +02:00
Matti Pastell 8c5bc5633a Update appveyour build 2018-01-02 16:46:48 +02:00
Matti Pastell f8ffe9218d Merge branch 'fbot/deps' 2018-01-02 16:38:42 +02:00
Matti Pastell c54032d99a Fix REQUIRES 2018-01-02 16:35:44 +02:00
Matti Pastell 165f6e71bb Tests again 2018-01-02 16:34:47 +02:00
Matti Pastell 1536ad455a Fix DataFrames version for tests 2018-01-02 16:23:28 +02:00
Matti Pastell 5bb5e8994c Switch to JLD2 for caching docs 2018-01-02 16:21:45 +02:00
Matti Pastell c0ad60d138 Update test depencies 2018-01-02 16:16:48 +02:00
Matti Pastell 6a81c53af3 Disable notebook test 2018-01-02 16:02:51 +02:00
Matti Pastell c2f581a31d Merge branch 'master' of https://github.com/mpastell/Weave.jl into HEAD 2018-01-02 15:57:17 +02:00
Matti Pastell 45a3f46918 Update tests 2018-01-02 15:54:55 +02:00
Matti Pastell ebd4f6dbed Allow empty cells in scripts 2018-01-02 15:48:56 +02:00
femtocleaner[bot] 2693389a3a Fix deprecations 2017-12-31 12:02:28 +00:00
Matti Pastell 8c22b41920
Merge pull request #109 from baggepinnen/patch-1
Replace usepackage graphics with graphicx
2017-12-22 17:43:08 +02:00
Matti Pastell 95008e5704
Drop Julia 0.5 support
Drop Julia 0.5 support
2017-12-22 13:26:21 +02:00
Fredrik Bagge Carlson 3f42023b42
Replace usepackage graphics with graphicx
I had issues with the chunk option `out_width` unless I replaced the use of the old `graphics` package with the newer `graphicx`
See https://tex.stackexchange.com/questions/23075/packages-graphics-vs-graphicx for additional info
2017-10-30 09:40:31 +01:00
Matti Pastell a35d57e1cb Merge pull request #103 from tpoisot/patch-1
Use VERSION instead of hard-coding the version number when exporting to ipynb
2017-08-19 11:56:28 +03:00
Timothée Poisot 6b7e88d465 Attempt to solve #102 2017-07-17 11:32:33 -04:00
Matti Pastell c4c5eb11e3 Merge pull request #94 from staticfloat/updated_ci_url
Update CI URLs to point to new caching infrastructure
2017-05-17 13:35:40 +03:00
Elliot Saba b043542007 Update CI URLs to point to new caching infrastructure 2017-05-16 17:32:00 -07:00
Matti Pastell 96bc072619 Merge pull request #91 from c42f/lualatex-unicode-symbols
Add unicode symbol support based on CMU and Latin Modern fonts
2017-05-15 17:54:08 +03:00
Matti Pastell aaabc2cd4f Update README 2017-05-15 17:53:43 +03:00
Matti Pastell 0213c2f774 Fix publish test 2017-05-15 17:36:54 +03:00
Matti Pastell dffb554c8a Fix Gadfly tests 2017-05-15 17:28:10 +03:00
Matti Pastell 4bc5435e6d Fix figure display for Gadfly 2017-05-15 17:13:18 +03:00
Matti Pastell 2e65f08e0e Merge branch 'master' of https://github.com/mpastell/Weave.jl 2017-05-12 16:12:20 +03:00
Matti Pastell 5c83309aa3 Fix Gadfly and Plots, use Compat.invokelatest 2017-05-12 16:12:05 +03:00
Chris Foster da17ac2cc1 Add unicode symbol support based on CMU fonts 2017-04-07 00:22:37 +10:00
Matti Pastell 7edd8f8bc3 Merge pull request #88 from tpapp/hugo-trivial-fix
Removed superfluous space which broke the hugo parser.
2017-04-02 22:58:50 +03:00
Tamas K. Papp 0682ca8c59 Removed superfluous space which broke the hugo parser. 2017-04-02 20:30:29 +02:00
Matti Pastell 562968f9be Don't remove whitespace from start of inline output 2017-04-02 09:47:12 +03:00
Matti Pastell 93c2762653 Merge pull request #87 from maximsch2/fix-inline
Fix inline code snippets output
2017-04-02 09:43:43 +03:00
Maxim Grechkin 1ab37ae48c fix inline code snippets output 2017-04-01 16:07:15 -07:00
Matti Pastell bdedf37e5b Update README.md 2017-03-30 18:25:41 +03:00
Matti Pastell 5b7ac28e3c Merge pull request #86 from tpapp/flexible-fig-path
Added a formatter for Hugo.
2017-03-28 19:39:36 +03:00
Tamas K. Papp 3297d07102 Added caption for figure shortcode in Hugo. 2017-03-26 17:13:11 +02:00
Tamas K. Papp 3176ae88bf Added a formatter for Hugo.
Uses the figure shortcode [1]. Tested at [2].

[1] https://gohugo.io/extras/shortcodes/.
[2] https://tpapp.github.io/post/hugo-julia-weave/.
2017-03-24 19:57:02 +01:00
Matti Pastell 32f5728ad6 Add JOSS badge 2017-03-22 14:56:57 +02:00
Matti Pastell ebcee727aa Fix version numbers for patches 2017-03-15 17:15:41 +02:00
Matti Pastell 0131bae775 Updated citation #85 2017-03-15 17:07:25 +02:00
Matti Pastell 97f309af19 Fix test cleaning on windows 2017-03-14 21:45:46 +02:00
Matti Pastell 1915501026 More tests for 0.6 2017-03-14 21:27:26 +02:00
Matti Pastell 9d4817007e Fix world-age for display 2017-03-14 21:06:47 +02:00
Matti Pastell b4f5221e3a Fix mimetype order for md2html 2017-03-14 18:54:03 +02:00
Matti Pastell c179d3082c Update news and bump docs version 2017-03-14 18:15:49 +02:00
Matti Pastell 5513656f35 Add info about depencies #85 2017-03-14 18:08:15 +02:00
Matti Pastell 1a54d6a557 Add citeproc filter to pandoc, fixes #50 2017-03-14 16:08:52 +02:00
Matti Pastell 38d3b04363 Only strip header from md2* formats, fix pandoc2html 2017-03-14 15:34:27 +02:00
Matti Pastell bbad66d0b8 Fix plotting imports and tests 2017-03-14 09:27:16 +02:00
Matti Pastell 1b5c0f819c Fix tests for 0.6 2017-03-13 23:14:25 +02:00
Matti Pastell d729d4f878 Add 0.6 to Travis 2017-03-13 21:00:20 +02:00
Matti Pastell b2ffefdb27 Remove Winston support, closes #58 2017-03-13 20:57:39 +02:00
Matti Pastell 09ecdb6f2c Disable plots tests 2017-03-13 20:39:43 +02:00
Matti Pastell d3e0f31f9e More fixes to tests 2017-03-13 19:04:59 +02:00
Matti Pastell f39069e40a Merge branch 'fixterm'. Fixes term=true formatting 2017-03-13 19:03:11 +02:00
Matti Pastell 0ffa04b3fd Fix tests 2017-03-13 18:55:15 +02:00
Matti Pastell 2e6e83e467 Update LICENSE.md 2017-03-13 18:38:06 +02:00
Matti Pastell 70c850e79e Fix extra whitespace in convert_doc 2017-03-13 15:12:59 +02:00
Matti Pastell 888b732f86 Fix output for `term=true`. Closes #82. 2017-03-13 15:05:07 +02:00
Matti Pastell b0d2ccdba2 Cleaner world-age fix for pyplot 2017-03-11 11:31:17 +02:00
Matti Pastell 868efa8208 Use compat for abstract types 2017-03-10 13:09:13 +02:00
Matti Pastell c788f5f15e Fix PyPlot for 0.6 2017-03-09 22:09:36 +02:00
Matti Pastell b66ae83e37 Added JOSS paper 2017-03-06 17:57:45 +02:00
Matti Pastell bc1e8738a7 Update readme 2017-03-06 17:43:12 +02:00
Matti Pastell 1ec393dc05 Update docs version 2017-03-06 17:33:58 +02:00
Matti Pastell 6c2f0a7bb5 No need to patch latex writer in 0.6 2017-01-04 19:56:28 +02:00
Matti Pastell f1b42156e1 Fix a bug with out_path and tmp figure directory 2016-12-29 17:58:21 +02:00
Matti Pastell c5659c03bf Correct doc version 2016-12-29 17:30:31 +02:00
Matti Pastell a984b46b5b Add docs for #78 2016-12-29 17:06:29 +02:00
Matti Pastell 090ad87ed9 Merge pull request #80 from mpastell/inline_chunks
Support inline code
2016-12-29 16:44:36 +02:00
Matti Pastell 9a1d655681 Added docs for inline syntax 2016-12-29 16:34:39 +02:00
Matti Pastell 2715baa347 Add test to caching 2016-12-28 01:12:53 +02:00
Matti Pastell b61a2a01b0 Added tests for inline cache 2016-12-27 22:29:04 +02:00
Matti Pastell de1e08e1ef Add exception handling to weave 2016-12-27 22:22:32 +02:00
Matti Pastell 3837142f9b Add cache/restore for inline code 2016-12-27 21:46:23 +02:00
Matti Pastell c7918241f2 Fix convert and enable test 2016-12-27 01:48:00 +02:00
Matti Pastell 9dc99ba602 Fix format tests, disable cache, convert until fixed 2016-12-27 01:16:39 +02:00
Matti Pastell a7cd923e27 Format inline chunks 2016-12-27 00:59:15 +02:00
Matti Pastell e10f27b26f Fix weave messages 2016-12-26 21:28:57 +02:00
Matti Pastell a4cfebcc17 Initial version of running inline code 2016-12-26 21:21:55 +02:00
Matti Pastell f63fe62445 Added parsing of inline code 2016-12-26 20:06:03 +02:00
Matti Pastell 3da8865a15 Export include_weave 2016-12-26 13:45:33 +02:00
Matti Pastell 7c5fcd24c6 Pass data to documents #78 2016-12-26 13:26:36 +02:00
Matti Pastell 458ef30e90 Merge branch 'b-embed_figures' 2016-12-23 12:30:51 +02:00
Matti Pastell 7c69ce9b0c Fix to embedding figures 2016-12-23 12:27:10 +02:00
Matti Pastell 4d499da343 Embed images for html at runtime and cache result 2016-12-23 12:02:28 +02:00
Matti Pastell 68b9bfda08 Fix CRLF in rest of the files 2016-12-23 10:54:48 +02:00
Matti Pastell d75ae6d86b Fix cache_path and don't clean figures when caching.
Fixes #76
2016-12-23 10:25:23 +02:00
Matti Pastell ff79618182 Clean build artefacts for pandoc2* closes #69 2016-12-23 09:37:30 +02:00
Matti Pastell c0f3bac70a Clean extra files for pdf output #69 2016-12-23 09:25:44 +02:00
Matti Pastell 89859c0898 Rename weave_include to include_weave 2016-12-23 08:36:07 +02:00
Matti Pastell b14cd13063 Clean extra files for html output #69 2016-12-23 08:34:54 +02:00
Matti Pastell a2b63b8f07 Fix handling of \r #72 2016-12-22 21:40:07 +02:00
Matti Pastell 57629c1547 Merge pull request #68 from davidanthoff/appveyor-pyplot
Install PyPlot on appveyor
2016-12-21 18:53:24 +02:00
Matti Pastell 0f66b0cbae Merge pull request #67 from davidanthoff/fix-syntax-error
Fix syntax error in Base.display
2016-12-20 22:47:25 +02:00
David Anthoff f8fff02777 Install PyPlot on appveyor 2016-12-20 12:40:56 -08:00
David Anthoff 3542374d92 Fix syntax error in Base.display 2016-12-20 12:21:50 -08:00
Matti Pastell d8ba7316fe Add appveyor badge 2016-12-20 21:50:51 +02:00
Matti Pastell 360713458c Merge pull request #66 from davidanthoff/appveyor
Add appveyor testing
2016-12-20 21:44:36 +02:00
Matti Pastell 832b87d92a Fixed tests on Windows #65 2016-12-20 21:37:39 +02:00
Matti Pastell 0234b3d059 Added weave_include function to include code from Weave documents 2016-12-20 20:34:24 +02:00
David Anthoff 2191794f38 Add appveyor testing 2016-12-20 10:10:01 -08:00
Matti Pastell 33fb6db33c Update docs 2016-12-19 21:45:01 +02:00
Matti Pastell 3cbc63b7c3 Update release notes 2016-12-19 21:33:40 +02:00
162 changed files with 5168 additions and 5673 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text eol=lf

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
custom: https://numfocus.salsalabs.org/donate-to-julia/index.html

31
.github/ISSUE_TEMPLATE/bug.md vendored Normal file
View File

@ -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 -->

11
.github/ISSUE_TEMPLATE/enhancement.md vendored Normal file
View File

@ -0,0 +1,11 @@
---
name: enhancement
about: suggest an enhancement idea
title: "[FR]"
labels: enhancement
assignees: ''
---
<!-- Please search existing issues to avoid duplicates. -->
## description

19
.github/workflows/CompatHelper.yml vendored Normal file
View File

@ -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()'

11
.github/workflows/TagBot.yml vendored Normal file
View File

@ -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 }}

67
.github/workflows/ci.yml vendored Normal file
View File

@ -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 }}

62
.gitignore vendored
View File

@ -1,33 +1,29 @@
src/*.cov
test.jl
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/**/*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

View File

@ -1,25 +1,14 @@
language: julia
julia:
- 0.5
- 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())'

View File

@ -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.

90
NEWS.md
View File

@ -1,11 +1,83 @@
## 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
# Release notes for Weave.jl
### 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
@ -13,6 +85,7 @@
output in published HTML documents.
* Fix semicolons for `term=true`
### v0.2
* Move to Julia 0.5 only
@ -33,6 +106,7 @@
- Fix parsing of lone variables from chunks
- Fix error with md2html formatter and dates #38
### v0.1.2
27th April 2016
@ -42,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.
@ -57,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
@ -73,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
@ -82,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
@ -97,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

37
Project.toml Normal file
View File

@ -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"]

175
README.md
View File

@ -1,73 +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), Knitr, rmarkdown
and Sweave.
You can write your documentation and code in input document using Noweb,
Markdown, Script 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 Plots, Gadfly, PyPlot and Winston figures.
* Supports LaTex, Pandoc, Github markdown, MultiMarkdown, Asciidoc and reStructuredText output
* Publish markdown directly to html and pdf using Julia or Pandoc markdown.
* Simple caching of results
* Convert to and from IJulia notebooks
# 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.

View File

@ -1,8 +0,0 @@
julia 0.5
ArgParse
JLD
JSON
Highlights
Mustache
Documenter
YAML

View File

@ -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
@ -41,12 +41,8 @@ source = args["source"]
delete!(args, "source")
args_col = []
args["plotlib"] == "nothing" && (args["plotlib"] = nothing)
#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"
@ -54,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

4
doc/Project.toml Normal file
View File

@ -0,0 +1,4 @@
[deps]
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

BIN
doc/assets/FIR_design.pdf Normal file

Binary file not shown.

Binary file not shown.

View File

@ -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,
)

View File

@ -1,21 +1,30 @@
using Weave
weave("../examples/gadfly_md_sample.jmd",
informat="markdown", out_path = "build/examples", doctype = "pandoc")
let start_dir = pwd()
cd(@__DIR__)
weave("../examples/gadfly_md_sample.jmd",
informat="markdown", out_path = "build/examples", doctype = "md2html")
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("../examples/gadfly_md_sample.jmd",
informat="markdown", out_path = "build/examples", doctype = "md2pdf")
# PDF outputs
if haskey(ENV, "TRAVIS")
# in Travis, just cp already generated PDFs
cp("assets/FIR_design.pdf", "build/examples/FIR_design.pdf", force = true)
cp("assets/FIR_design_plots.pdf", "build/examples/FIR_design_plots.pdf", force = true)
else
# otherwise try to generate them
try
weave("../examples/FIR_design.jmd", doctype = "md2pdf", out_path = "assets")
weave("../examples/FIR_design_plots.jl", doctype = "md2pdf", out_path = "assets")
catch err
@error err
end
end
cp("../examples/gadfly_md_sample.jmd",
"build/examples/gadfly_md_sample.jmd", remove_destination = true)
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("build/examples/gadfly_md_sample.md",
"build/examples/gadfly_md_sample.txt", remove_destination = true)
weave("../examples/FIR_design.jl", out_path = "build/examples")
weave("../examples/FIR_design.jl", doctype = "md2pdf", out_path = "build/examples")
cp("../examples/FIR_design.jl",
"build/examples/FIR_design.jl", remove_destination = true)
cd(start_dir)
end

View File

@ -1,45 +0,0 @@
site_name: Weave.jl
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
- codehilite(css_class=code)
# - mdx_math
google_analytics:
- 'UA-6474352-10'
- 'auto'
extra:
version: 'v0.2.2+'
author:
twitter: 'mpastell'
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
- Working with Jupyter notebooks: notebooks.md
- Function index: function_index.md

View File

@ -1,64 +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.
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).
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)
@
## Syntax
Chunk options come after [code chunk](@ref code-chunks) header.
There are two (slightly) different syntax to write them:
- (Julia's toplevel expression) options are separated by semicolon (`;`)
- (RMarkdown style) options are separated by comma (`,`)
Let's take a look at examples. All the following code chunk header are valid,
and so configured to hide the source code from generated output (`echo = false`)
and displays figures with 12cm width (`out_width = "12cm"`):
```md
```julia; echo = false; out_width = "12cm"
```{julia; echo = false; out_width = "12cm"}
```julia, echo = false, out_width = "12cm"
```{julia, echo = false, out_width = "12cm"}
```
Weave currently supports the following chunk options with the following defaults:
## Options for code
## Weave Chunk Options
* `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.
* `eval = true`. Evaluate the code chunk. If false the chunk wont 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.
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.
## Options for figures
### Evaluation
* `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.
- `eval = true`: Evaluate the code chunk. If `false` the chunk wont 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.
## Set default chunk options
## Default Chunk Options
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:
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:
```julia
<<echo = false>>=
import Weave
Weave.set_chunk_defaults(Dict{Symbol, Any}(
:out_width => "\\0.5linewidth",
:results => "tex"
))
@
```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(opts)
get_chunk_defaults()
restore_chunk_defaults()
set_chunk_defaults!
get_chunk_defaults
restore_chunk_defaults!
```

View File

@ -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 pdf output requires that you have pdflatex 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).

101
doc/src/header.md Normal file
View File

@ -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
---
```

View File

@ -1,27 +1,38 @@
# Weave.jl - Scientific Reports Using Julia
This is the documentation of [Weave.jl](http://github.com/mpastell/weave.jl). Weave is a scientific report generator/literate programming tool
for Julia. It resembles [Pweave](http://mpastell.com/pweave), Knitr, rmarkdown
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 Plots, Gadfly, PyPlot and Winston figures.
* Supports LaTex, Pandoc, Github markdown, MultiMarkdown, Asciidoc and reStructuredText output
* Publish markdown directly to html and pdf using julia or Pandoc markdown.
* Simple caching of results
* Convert to and from IJulia notebooks
- 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
## Index
```@contents
Pages = ["getting_started.md", "usage.md",
"publish.md", "chunk_options.md", "notebooks.md",
"function_index.md"]
Pages = [
"index.md",
"getting_started.md",
"usage.md",
"publish.md",
"chunk_options.md",
"header.md",
"notebooks.md",
"function_index.md",
]
```

View File

@ -1,22 +1,36 @@
# Working with Jupyter notebooks
## Weaving
## Weaving from Jupyter notebooks
Weave supports using Jupyter notebooks as input format, this means you
can weave notebooks to any supported formats. You can't use chunk options with 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")
weave("notebook.ipynb") # will be weaved to HTML
```
In order to output notebooks from other formats you need to convert the
document to a notebook and run the code using IJulia.
!!! 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`
function.
You can convert between all supported input formats using the [`convert_doc`](@ref) function.
To convert from script to notebook:
@ -24,12 +38,12 @@ To convert from script to notebook:
convert_doc("examples/FIR_design.jl", "FIR_design.ipynb")
```
and from notebooks to markdown use:
and from notebook to Markdown use:
```julia
convert_doc("FIR_design.ipynb", "FIR_design.jmd")
```
```@docs
convert_doc(infile::String, outfile::String)
convert_doc
```

View File

@ -1,10 +1,12 @@
# Publishing to html and pdf
# Publishing to HTML and PDF
You can also publish any supported input format using markdown for doc chunks to html and pdf documents. Producing pdf output requires that you have pdflatex installed and in your path. *The markdown variant is [Julia markdown](http://docs.julialang.org/en/latest/manual/documentation.html#Markdown-syntax-1)*.
You can also publish any supported input format to HTML and PDF documents.
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.
!!! note
Producing PDF output requires that you have XeLaTex installed and in your path.
You can use a YAML header in the beginning of the input document delimited with `---`
to set the document title, author and date, e.g.:
```
---
title : Weave example
@ -13,14 +15,53 @@ date: 15th December 2016
---
```
Here is a a sample document and output:
[FIR_design.jl](examples/FIR_design.jl), [FIR_design.html](examples/FIR_design.html) , [FIR_design.pdf](examples/FIR_design.pdf).
Here are sample input and outputs:
- input (Julia markdown format): [`FIR_design_plots.jl`](../examples/FIR_design_plots.jl) (its path is bound to `Weave.SAMPLE_JL_DOC`)
- HTML output: [`FIR_design_plots.html`](../examples/FIR_design_plots.html)
- PDF output: [`FIR_design_plots.pdf`](../examples/FIR_design_plots.pdf)
They are generated as follows:
```julia
weave("FIR_design.jl")
weave("FIR_design.jl", docformat = "md2pdf")
weave(Weave.SAMPLE_JL_DOC)) # default to md2html output format
weave(Weave.SAMPLE_JL_DOC; doctype = "md2pdf")
```
**Note:** docformats `md2pdf` and `md2html` use Julia markdown and `pandoc2pdf` and `pandoc2html`
use Pandoc.
!!! tips
`Weave.SAMPLE_JL_DOC` is the path of [FIR_design.jl](../examples/FIR_design.jl).
!!! note
`"md2html"` and `"md2pdf"` assume Julia markdown format as an input,
while `pandoc2pdf` and `pandoc2html` assume Noweb input format (i.e. Pandoc markdown).
## Templates
You can use a custom template with `md2html` and `md2pdf` formats with `template` keyword option,
e.g.: `weave("FIR_design_plots.jl", template = "custom.tpl"`.
As starting point, you can use the existing templates:
- HTML (`md2html`): [`md2html.tpl`](https://github.com/JunoLab/Weave.jl/blob/master/templates/md2html.tpl)
- LaTex (`md2pdf`): [`md2pdf.tpl`](https://github.com/JunoLab/Weave.jl/blob/master/templates/md2pdf.tpl)
Templates are rendered using [Mustache.jl](https://github.com/jverzani/Mustache.jl).
## Supported Markdown syntax
The markdown variant used by Weave is [Julia markdown](https://docs.julialang.org/en/v1/stdlib/Markdown/#).
In addition Weave supports few additional Markdown features:
### Comments
You can add comments using html syntax: `<!-- -->`
### Multiline equations
You can add multiline equations using:
```
$$
x^2 = x*x
$$
```

View File

@ -1,77 +1,67 @@
# Using Weave
You can write your documentation and code in input document using Noweb, Markdown or script
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)
```
Using PyPlot:
```julia
weave(Pkg.dir("Weave","examples","julia_sample.mdw"), plotlib="PyPlot", out_path = :pwd)
weave(Weave.SAMPLE_JL_DOC; out_path=:pwd)
```
```@docs
weave(source)
weave
```
## 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)
tangle
```
## Supported formats
## Supported Output 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:
```@docs
list_out_formats
```
```@example
using Weave # hide
list_out_formats()
```
```@docs
list_out_formats()
```
## [Document Syntax](@id document-syntax)
## Document syntax
Weave uses noweb, markdown or script syntax for defining the code chunks and
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:
@ -83,40 +73,110 @@ ext == ".ipynb" && return "notebook"
return "noweb"
```
## 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. See [chunk options](../chunk_options/).
### Documentation Chunks
### Documentation chunks
In markdown and Noweb input formats documentation chunks are the parts that aren't inside code delimiters. Documentation chunks can be written with several different markup languages.
Are the rest of the document (between `@` and `<<>>=` lines and the first chunk be default) and can be written with several different markup languages.
[Sample document]( https://github.com/mpastell/Weave.jl/blob/master/examples/julia_sample.mdw)
### [Code Chunks](@id code-chunks)
## Markdown format
Code chunks are written in different ways in different formats.
Markdown code chunks are defined using fenced code blocks with options following on the same line. e.g. to hide code from output you can use:
#### Markdown Format
` ```julia; echo=false`
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
...
```
```
[See sample document:](https://github.com/mpastell/Weave.jl/blob/master/examples/gadfly_md_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
...
```
```
## Script format
#### Noweb Format
Weave also support script input format with a markup in comments.
These scripts can be executed normally using Julia or published with
Weave. Documentation is in lines starting with
`#'`, `#%%` or `# %%`, and code is executed and results are included
in the weaved document.
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.
All lines that are not documentation are treated as code. You can set chunk options
using lines starting with `#+` just before code e.g. `#+ term=true`.
### [Inline Code](@id inline-code)
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/).
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)
[See sample document:](https://github.com/mpastell/Weave.jl/blob/master/examples/FIR_design.jl)
## 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
```

View File

@ -7,7 +7,7 @@
#' # 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
@ -34,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)
@ -60,7 +60,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
@ -68,7 +68,7 @@ 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)
#+
@ -78,6 +78,6 @@ plot(y = h_db, x = ws, Geom.line,
#' 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)"))

View File

@ -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,50 +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
~~~~{.julia}
h_db = log10(abs(h))
ws = w/pi*(fs/2)
~~~~~~~~~~~~~
The next code chunk is executed in term mode, see the [script](FIR_design.jl) for syntax.
~~~~{.julia}
julia> plot(y = h_db, x = ws, Geom.line,
Guide.xlabel("Frequency (Hz)"), Guide.ylabel("Magnitude (db)"))
~~~~~~~~~~~~~
![](figures/FIR_design_4_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_5_1.png)\
```julia
h_phase = unwrap(-atan.(imag.(h),real.(h)))
plot(ws, h_phase,
xlabel = "Frequency (Hz)", ylabel = "Phase (radians)")
```

View File

@ -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
@ -31,11 +33,11 @@
#' the frequency response of a FIR filter so we define it:
using Plots, DSP
plotly()
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)
@ -60,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
@ -68,7 +70,7 @@ 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)
#+
@ -78,6 +80,6 @@ plot(ws, h_db,
#' And again with default options
h_phase = unwrap(-atan2(imag(h),real(h)))
h_phase = unwrap(-atan.(imag.(h),real.(h)))
plot(ws, h_phase,
xlabel = "Frequency (Hz)", ylabel = "Phase (radians)")

46
examples/beamer.tpl Normal file
View File

@ -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}

View File

@ -4,8 +4,10 @@ author : Matti Pastell
date : 13th December 2016
---
# Intro
This a sample [Julia](http://julialang.org/) markdown document that can
be executed using [Weave.jl](https://github.com/mpastell/Weave.jl).
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
@ -35,7 +37,7 @@ weave(Pkg.dir("Weave","examples","gadfly_md_sample.jmd"), informat="markdown",
The documents will be written to the Julia working directory when you
use the `out_path = :pwd`.
## Capturing code
# Capturing code
The basic code chunk will be run with default options and the code and
output will be captured.
@ -44,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.
@ -64,11 +66,11 @@ syntax from the source document):
plot(y = cumsum(randn(1000, 1)), Geom.line)
```
## Whats next
# Whats next
Read the documentation:
- stable: [http://mpastell.github.io/Weave.jl/stable/](http://mpastell.github.io/Weave.jl/stable/)
- latest: [http://mpastell.github.io/Weave.jl/latest/](http://mpastell.github.io/Weave.jl/latest/)
- latest: [http://weavejl.mpastell.com/dev/](http://weavejl.mpastell.com/dev/)
See other examples in the [Github repo](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)

View File

@ -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:

View File

@ -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>

View File

@ -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.

Binary file not shown.

View File

@ -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")

View File

@ -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)
@

21
paper/paper.bib Normal file
View File

@ -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/},
}

40
paper/paper.md Normal file
View File

@ -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

View File

@ -1,140 +1,344 @@
__precompile__()
module Weave
import Highlights
"""
`list_out_formats()`
using Highlights, Mustache, Requires, Pkg, REPL, RelocatableFolders, Base64
List supported output formats
"""
function list_out_formats()
for format = keys(formats)
println(string(format,": ", formats[format].description))
end
# 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
# 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]
"""
`tangle(source ; out_path=:doc, informat="noweb")`
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.
* `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
- `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 ; out_path=:doc, informat=:auto)
doc = read_doc(source, informat)
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)
outname = get_outname(out_path, doc, ext = "jl")
out_path = get_out_path(doc, out_path, "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
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
end
doc.cwd == pwd() && (outname = basename(outname))
info("Writing to file $outname")
@info "Tangled to $(out_path)"
end
"""
weave(source ; doctype = :auto, plotlib=:auto,
informat=:auto, out_path=:doc, fig_path = "figures", fig_ext = nothing,
cache_path = "cache", cache=:off,
template = nothing, highlight_theme = nothing, css = nothing
latex_cmd = "pdflatex")
weave(source::AbstractString; kwargs...)
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.
* `template` : Template (file path) for md2html or md2tex formats.
* `highlight_theme` : Theme (Highlights.AbstractTheme) for used syntax highlighting
* `css` : CSS (file path) used for md2html format
* `latex_cmd` the command used to make pdf from .tex
## Keyword options
**Note:** Run Weave from terminal and not using IJulia, Juno or ESS, they tend to mess with capturing output.
- `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 ; doctype = :auto, plotlib=:auto,
informat=:auto, out_path=:doc, fig_path = "figures", fig_ext = nothing,
cache_path = "cache", cache=:off,
template = nothing, highlight_theme = nothing, css = nothing,
latex_cmd = "pdflatex")
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)
doc = read_doc(source, informat)
highlight_theme != nothing && (doc.highlight_theme = highlight_theme) #Reserved for themes
#theme != nothing && (doc.theme = theme) #Reserved for themes
css != nothing && (doc.css = css)
template != nothing && (doc.template = template)
# run document
# ------------
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)
outname = get_outname(out_path, doc)
open(outname, "w") do io
write(io, formatted)
# 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
#Special for that need external programs
if doc.doctype == "pandoc2html"
outname = get_outname(out_path, doc, ext = "html")
pandoc2html(formatted, doc, outname)
elseif doc.doctype == "pandoc2pdf"
outname = get_outname(out_path, doc, ext = "pdf")
pandoc2pdf(formatted, doc, outname)
elseif doc.doctype == "md2pdf"
run_latex(doc, outname, latex_cmd)
outname = get_outname(out_path, doc, ext = "pdf")
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.cwd == pwd() && (outname = basename(outname))
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,
)
info("Report weaved to $outname")
# 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
function weave(doc::AbstractString, doctype::AbstractString)
weave(doc, doctype=doctype)
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
#Hooks to run before and after chunks, this is form IJulia,
#but note that Weave hooks take the chunk as input
const preexecute_hooks = Function[]
push_preexecute_hook(f::Function) = push!(preexecute_hooks, f)
pop_preexecute_hook(f::Function) = splice!(preexecute_hooks, findfirst(pretexecute_hooks, f))
const postexecute_hooks = Function[]
push_postexecute_hook(f::Function) = push!(postexecute_hooks, f)
pop_postexecute_hook(f::Function) = splice!(postexecute_hooks, findfirst(postexecute_hooks, f))
include("config.jl")
include("chunks.jl")
include("display_methods.jl")
include("readers.jl")
include("run.jl")
include("cache.jl")
include("formatters.jl")
include("format.jl")
include("pandoc.jl")
include("writers.jl")
export weave, list_out_formats, tangle, convert_doc,
set_chunk_defaults, get_chunk_defaults, restore_chunk_defaults
get_out_path(doc, out_path, ext::Nothing = nothing) = get_out_path(doc, out_path, doc.format.extension)
function get_out_path(doc, out_path, ext)
if (out_path === :doc) || (out_path === :pwd)
abspath(get_cwd(doc, out_path), string(doc.basename, '.', ext))
elseif isempty(splitext(out_path)[2]) # directory given
abspath(get_cwd(doc, out_path), string(doc.basename, '.', ext))
else
# out_path is given, but if extension is explitly provided override this will override the extension
abspath(string(splitext(out_path)[1], '.', ext))
end
end
"""
notebook(source::AbstractString; kwargs...)
Convert Weave document `source` to Jupyter Notebook and execute the code
using [`nbconvert`](https://nbconvert.readthedocs.io/en/latest/).
**Ignores** all chunk options.
## Keyword options
- `out_path::Union{Symbol,AbstractString} = :pwd`: Path where the output is generated can be either of:
* `:doc`: Path of the source document
* `:pwd`: Julia working directory (default)
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
- `timeout = -1`: nbconvert cell timeout in seconds. Defaults to `-1` (no timeout)
- `nbconvert_options::AbstractString = ""`: `String` of additional options to pass to nbconvert, such as `"--allow-errors"`
- `jupyter_path::AbstractString = "jupyter"`: Path/command for the Jupyter you want to use. Defaults to `"jupyter"`, which runs whatever is linked/alias to that
!!! warning
The code is _**not**_ executed by Weave, but by [`nbconvert`](https://nbconvert.readthedocs.io/en/latest/).
This means that the output doesn't necessarily always work properly; see [#116](https://github.com/JunoLab/Weave.jl/issues/116).
!!! note
In order to _just_ convert Weave document to Jupyter Notebook,
use [`convert_doc`](@ref) instead.
"""
function notebook(
source::AbstractString;
out_path::Union{Symbol,AbstractString} = :pwd,
timeout = -1,
nbconvert_options::AbstractString = "",
jupyter_path::AbstractString = "jupyter",
)
doc = WeaveDoc(source)
converted = convert_to_notebook(doc)
doc.cwd = get_cwd(doc, out_path)
out_path = get_out_path(doc, out_path, "ipynb")
write(out_path, converted)
@info "Running nbconvert ..."
return read(
`$jupyter_path nbconvert --ExecutePreprocessor.timeout=$timeout --to notebook --execute $(out_path) $nbconvert_options --output $(out_path)`,
String,
)
end
"""
include_weave(source::AbstractString, informat::Union{Nothing,AbstractString} = nothing)
include_weave(m::Module, source::AbstractString, informat::Union{Nothing,AbstractString} = nothing)
Include code from Weave document calling `include_string` on all code from doc.
Code is run in the path of the include document.
"""
function include_weave(
m::Module,
source::AbstractString,
informat::Union{Nothing,AbstractString} = nothing,
)
old_path = pwd()
doc = WeaveDoc(source, informat)
cd(dirname(doc.path))
try
code = join(
[x.content for x in filter(x -> isa(x, Weave.CodeChunk), doc.chunks)],
"\n",
)
include_string(m, code)
catch err
throw(err)
finally
cd(old_path)
end
return nothing
end
include_weave(source, informat = nothing) = include_weave(Main, source, informat)
export weave,
list_out_formats,
tangle,
convert_doc,
notebook,
set_chunk_defaults!,
get_chunk_defaults,
restore_chunk_defaults!,
include_weave
end

248
src/WeaveMarkdown/html.jl Normal file
View File

@ -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(
'<' => "&lt;",
'>' => "&gt;",
'"' => "&quot;",
'&' => "&amp;",
# ' '=>"&nbsp;",
)
for ch in "'`!\$%()=+{}[]"
_htmlescape_chars[ch] = "&#$(Int(ch));"
end
function htmlesc(io::IO, s::AbstractString)
# s1 = replace(s, r"&(?!(\w+|\#\d+);)" => "&amp;")
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)

View File

@ -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, "")

View File

@ -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

View File

@ -1,39 +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
newc.rich_output = c.rich_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

View File

@ -1,60 +0,0 @@
type WeaveDoc
source::AbstractString
basename::AbstractString
path::AbstractString
chunks::Array
cwd::AbstractString
format
doctype::AbstractString
header_script::String
header::Dict
template::AbstractString
css::AbstractString
highlight_theme
function WeaveDoc(source, chunks, header)
path, fname = splitdir(abspath(source))
basename = splitext(fname)[1]
new(source, basename, path, chunks, "", nothing, "", "", header,
"", "", Highlights.Themes.DefaultTheme)
end
end
immutable ChunkOutput
code::AbstractString
stdout::AbstractString
displayed::AbstractString
rich_output::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
rich_output::AbstractString
figures::Array{AbstractString}
result::Array{ChunkOutput}
function CodeChunk(content, number, start_line, optionstring, options)
new(rstrip(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

View File

@ -1,88 +1,58 @@
#Default options
const defaultParams =
Dict{Symbol,Any}(:plotlib => nothing,
:plotlib_set => false,
: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,
:display => false,
:prompt => "\njulia> ",
: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)
return nothing
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

144
src/converter.jl Normal file
View File

@ -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)`"

View File

@ -1,97 +1,133 @@
#Contains report global properties
type Report <: Display
cwd::AbstractString
basename::AbstractString
formatdict::Dict{Symbol,Any}
pending_code::AbstractString
cur_result::AbstractString
rich_output::AbstractString
fignum::Int
figures::Array{AbstractString}
term_state::Symbol
cur_chunk
mimetypes::Array{AbstractString}
first_plot::Bool
header_script::String
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
function Report(cwd, basename, formatdict, mimetypes)
Report(cwd, basename, formatdict, "", "", "", 1, AbstractString[], :text, nothing, mimetypes, true, "")
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
# 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 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
for m in report.mimetypes
if mimewritable(m, 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
display(report, m, data)
catch
warn("Failed to save image in \"$m\" format")
#rethrow()
continue
end
#Always show plain text as well for term mode
if m "text/plain" && report.cur_chunk.options[:term]
display(report, "text/plain", data)
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
function Base.display(report::Report, m::MIME"image/png", data)
figname = add_figure(report, data, m, ".png")
end
Base.display(report::Report, m::MIME"image/png", data) = add_figure(report, data, m, ".png")
function Base.display(report::Report, m::MIME"image/svg+xml", data)
figname = add_figure(report, data, m, ".svg")
end
Base.display(report::Report, m::MIME"image/svg+xml", data) = add_figure(report, data, m, ".svg")
function Base.display(report::Report, m::MIME"application/pdf", data)
figname = add_figure(report, m, data, ".pdf")
end
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
# Text is written to stdout, called from "term" mode chunks
function Base.display(report::Report, m::MIME"text/plain", data)
s = reprmime(m, data)
print("\n" * s)
io = PipeBuffer()
show(IOContext(io, :limit => true), m, data)
flush(io)
s = read(io, String)
close(io)
println(s)
end
#Catch "rich_output"
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)
s = reprmime(m, data)
report.rich_output *= "\n" * s
io = IOBuffer()
show(IOContext(io, :limit => true), m, data)
report.rich_output *= string('\n', take2string!(io))
end
#Catch "rich_output"
# Catch "rich_output"
function Base.display(report::Report, m::MIME"text/markdown", data)
s = reprmime(m, data)
report.rich_output *= "\n" * s
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 = reprmime(m, data)
report.rich_output *= "\n" * s
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)
chunk = report.cur_chunk
full_name, rel_name = get_figname(report, chunk, ext = ext)
open(full_name, "w") do io
show(io, m, data)
end
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
push!(report.figures, rel_name)
report.fignum += 1
return full_name
end

View File

@ -1,321 +0,0 @@
import Mustache, Highlights, Documenter
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)
docformat.formatdict[:cwd] = doc.cwd #pass wd to figure formatters
docformat.formatdict[:theme] = doc.highlight_theme
#strip header
if isa(doc.chunks[1], DocChunk)
doc.chunks[1] = strip_header(doc.chunks[1])
end
for chunk in copy(doc.chunks)
result = format_chunk(chunk, formatdict, docformat)
push!(formatted, result)
end
formatted = join(formatted, "\n")
# Render using a template if needed
rendered = render_doc(formatted, doc, doc.format)
return rendered
end
"""
render_doc(formatted::AbstractString, format)
Render formatted document to a template
"""
function render_doc(formatted, doc::WeaveDoc, format)
return formatted
end
function stylesheet(m::MIME, theme)
buf = PipeBuffer()
Highlights.stylesheet(buf, m, theme)
flush(buf)
style = readstring(buf)
close(buf)
return style
end
function render_doc(formatted, doc::WeaveDoc, format::JMarkdown2HTML)
css = stylesheet(MIME("text/html"), doc.highlight_theme)
title, author, date = get_titleblock(doc)
path, wsource = splitdir(abspath(doc.source))
wversion = string(Pkg.installed("Weave"))
wtime = string(Date(now()))
if isempty(doc.css)
theme_css = readstring(joinpath(dirname(@__FILE__), "../templates/skeleton_css.css"))
else
theme_css = readstring(doc.css)
end
if isempty(doc.template)
template = Mustache.template_from_file(joinpath(dirname(@__FILE__), "../templates/julia_html.tpl"))
else
template = Mustache.template_from_file(doc.template)
end
return Mustache.render(template, themecss = theme_css,
highlightcss = css, body = formatted, header_script = doc.header_script,
source = wsource, wtime = wtime, wversion = wversion,
title = title, author = author, date = date)
end
function render_doc(formatted, doc::WeaveDoc, format::JMarkdown2tex)
highlight = stylesheet(MIME("text/latex"), doc.highlight_theme)
title, author, date = get_titleblock(doc)
path, wsource = splitdir(abspath(doc.source))
wversion = string(Pkg.installed("Weave"))
wtime = string(Date(now()))
if isempty(doc.template)
template = Mustache.template_from_file(joinpath(dirname(@__FILE__), "../templates/julia_tex.tpl"))
else
template = Mustache.template_from_file(doc.template)
end
return Mustache.render(template, body = formatted,
highlight = highlight,
title = title, author = author, date = date)
end
function get_titleblock(doc::WeaveDoc)
title = get!(doc.header, "title", false)
author = get!(doc.header, "author", false)
date = get!(doc.header, "date", false)
return title, author, date
end
function strip_header(chunk::DocChunk)
if ismatch(r"^---$(?<header>.+)^---$"ms, chunk.content)
chunk.content = lstrip(replace(chunk.content, r"^---$(?<header>.+)^---$"ms, ""))
end
return chunk
end
function format_chunk(chunk::DocChunk, formatdict, docformat)
return chunk.content
end
function format_chunk(chunk::DocChunk, formatdict, docformat::JMarkdown2HTML)
m = Base.Markdown.parse(chunk.content)
return string(Documenter.Writers.HTMLWriter.mdconvert(m))
end
#Fixes to Base latex writer
function Base.Markdown.latex(io::IO, md::Base.Markdown.Paragraph)
println(io)
for md in md.content
Base.Markdown.latexinline(io, md)
end
println(io)
end
function wrapverb(f, io, cmd)
print(io, "\\", cmd, "|")
f()
print(io, "|")
end
function Base.Markdown.latexinline(io::IO, code::Base.Markdown.Code)
wrapverb(io, "verb") do
print(io, code.code)
end
end
function format_chunk(chunk::DocChunk, formatdict, docformat::JMarkdown2tex)
m = Base.Markdown.parse(chunk.content)
return Base.Markdown.latex(m)
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
chunk.content = format_code(chunk.content, docformat)
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, docformat)
else
if chunk.options[:echo]
#Convert to output format and highlight (html, tex...) if needed
result = "$(formatdict[:codestart])$(chunk.content)\n$(formatdict[:codeend])\n"
else
result = ""
end
if (strip(chunk.output)!= "" || strip(chunk.rich_output) != "") && (chunk.options[:results] != "hidden")
chunk.output = format_output(chunk.output, docformat)
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])
else
chunk.output = "\n" * rstrip(chunk.output)
end
if haskey(formatdict, :indent)
chunk.output = indent(chunk.output, formatdict[:indent])
end
strip(chunk.output) "" &&
(result *= "$(formatdict[:outputstart])$(chunk.output)\n$(formatdict[:outputend])\n")
strip(chunk.rich_output) "" && (result *= chunk.rich_output * "\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_output(result::AbstractString, docformat)
return(result)
end
function format_output(result::AbstractString, docformat::JMarkdown2HTML)
return(Base.Markdown.htmlesc(result))
end
function format_code(result::AbstractString, docformat)
return result
end
function format_code(result::AbstractString, docformat::JMarkdown2tex)
buf = PipeBuffer()
Highlights.highlight(buf, MIME("text/latex"), strip(result),
Highlights.Lexers.JuliaLexer, docformat.formatdict[:theme])
flush(buf)
highlighted = readstring(buf)
close(buf)
return highlighted
end
function format_code(result::AbstractString, docformat::JMarkdown2HTML)
buf = PipeBuffer()
Highlights.highlight(buf, MIME("text/html"), strip(result),
Highlights.Lexers.JuliaLexer, docformat.formatdict[:theme])
flush(buf)
highlighted = readstring(buf)
close(buf)
return highlighted
end
function format_termchunk(chunk, formatdict, docformat)
if chunk.options[:echo] && chunk.options[:results] != "hidden"
result = "$(formatdict[:termstart])$(chunk.output)\n" * "$(formatdict[:termend])\n"
else
result = ""
end
return result
end
function format_termchunk(chunk, formatdict, docformat::JMarkdown2HTML)
if chunk.options[:echo] && chunk.options[:results] != "hidden"
buf = PipeBuffer()
Highlights.highlight(buf, MIME("text/html"), strip(chunk.output), Highlights.Lexers.JuliaConsoleLexer)
flush(buf)
result = readstring(buf)
close(buf)
else
result = ""
end
return result
end
function format_termchunk(chunk, formatdict, docformat::JMarkdown2tex)
if chunk.options[:echo] && chunk.options[:results] != "hidden"
buf = PipeBuffer()
Highlights.highlight(buf, MIME("text/latex"), strip(chunk.output), Highlights.Lexers.JuliaConsoleLexer)
flush(buf)
result = readstring(buf)
close(buf)
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

View File

@ -1,503 +0,0 @@
type Tex
description::AbstractString
formatdict::Dict{Symbol,Any}
end
const tex = Tex("Latex with custom code environments",
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",
:mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"]
))
const texminted = Tex("Latex using minted for highlighting",
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",
:mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"]
))
type Pandoc
description::AbstractString
formatdict::Dict{Symbol,Any}
end
const pandoc = Pandoc("Pandoc markdown",
Dict{Symbol,Any}(
:codestart => "~~~~{.julia}",
:codeend=>"~~~~~~~~~~~~~\n\n",
:outputstart=>"~~~~",
:outputend=>"~~~~\n\n",
:fig_ext=>".png",
:out_width=>nothing,
:extension=>"md",
#Prefer png figures for markdown conversion, svg doesn't work with latex
:mimetypes => ["image/png", "image/jpg", "image/svg+xml", "text/markdown", "text/plain"],
:doctype=>"pandoc"
))
const pdoc2html = Pandoc("Markdown to HTML (requires Pandoc)",
Dict{Symbol,Any}(
:codestart => "````julia",
:codeend=> "````\n\n",
:outputstart=> "````",
:outputend=> "````\n\n",
:fig_ext=> ".svg",
:extension=> "md",
:mimetypes => ["image/svg+xml", "image/png", "image/jpg",
"text/html", "text/markdown", "text/plain"],
:doctype=> "md2html"))
type Markdown
description::AbstractString
formatdict::Dict{Symbol,Any}
end
const github = Markdown("Github markdown",
Dict{Symbol,Any}(
:codestart => "````julia",
:codeend=> "````\n\n",
:outputstart=> "````",
:outputend=> "````\n\n",
:fig_ext=> ".png",
:extension=> "md",
:doctype=> "github"
))
#Julia markdown
type JMarkdown2HTML
description::AbstractString
formatdict::Dict{Symbol,Any}
end
const md2html = JMarkdown2HTML("Julia markdown to html", Dict{Symbol,Any}(
:codestart => "\n",
:codeend=> "\n",
:outputstart=> "<pre class=\"hljl\">",
:outputend=> "</pre>\n",
:fig_ext=> ".png",
:mimetypes => ["image/png", "image/jpg", "image/svg+xml",
"text/latex", "text/plain"],
:extension=> "html",
:doctype=> "md2html"))
#Julia markdown
type JMarkdown2tex
description::AbstractString
formatdict::Dict{Symbol,Any}
end
const md2tex = JMarkdown2tex("Julia markdown to latex", Dict{Symbol,Any}(
:codestart => "",
:codeend=> "",
:outputstart=> "\\begin{lstlisting}",
:outputend=> "\\end{lstlisting}\n",
:fig_ext=> ".pdf",
:extension=> "tex",
:mimetypes => ["application/pdf", "image/png", "image/jpg",
"text/latex", "text/plain"],
:doctype=> "md2tex"))
type MultiMarkdown
description::AbstractString
formatdict::Dict{Symbol,Any}
end
function img_to_base64(fig, ext, cwd)
f = open(joinpath(cwd, fig), "r")
raw = read(f)
close(f)
if ext == ".png"
return "data:image/png;base64," * stringmime(MIME("image/png"), raw)
elseif ext == ".svg"
return "data:image/svg+xml;base64," * stringmime(MIME("image/svg+xml"), raw)
else
return(fig)
end
end
function formatfigures(chunk, docformat::JMarkdown2HTML)
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 = ""
width == nothing || (attribs = "width=\"$width\"")
(attribs != "" && height != nothing ) && (attribs *= ",")
height == nothing || (attribs *= " height=\"$height\" ")
if caption != nothing
result *= """<figure>\n"""
end
for fig = fignames
ext = splitext(fig)[2]
if ext == ".png" || ext == ".svg"
fig = img_to_base64(fig, ext, docformat.formatdict[:cwd])
end
figstring *= """<img src="$fig" $attribs />\n"""
end
result *= figstring
if caption != nothing
result *= """
<figcaption>$caption</figcaption>
"""
end
if caption != nothing
result *= "</figure>\n"
end
return result
end
const multimarkdown = MultiMarkdown("MultiMarkdown",
Dict{Symbol,Any}(
:codestart => "````julia",
:codeend=> "````\n\n",
:outputstart=> "````",
: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",
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",
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]
height = chunk.options[:out_height]
f_pos = chunk.options[:fig_pos]
f_env = chunk.options[:fig_env]
if f_env == nothing && caption != nothing
f_env = "figure"
end
f_pos == nothing && (f_pos = "!h")
result = ""
figstring = ""
#Set size
attribs = ""
width == nothing || (attribs = "width=$width")
(attribs != "" && height != nothing ) && (attribs *= ",")
height == nothing || (attribs *= "height=$height")
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[$attribs]{$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::JMarkdown2tex)
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 f_env == nothing && caption != nothing
f_env = "figure"
end
f_pos == nothing && (f_pos = "!h")
#Set size
attribs = ""
width == nothing || (attribs = "width=$width")
(attribs != "" && height != nothing ) && (attribs *= ",")
height == nothing || (attribs *= "height=$height")
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
if isempty(attribs)
figstring *= "\\includegraphics{$fig}\n"
else
figstring *= "\\includegraphics[$attribs]{$fig}\n"
end
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]
height = chunk.options[:out_height]
#Build figure attibutes
width == nothing || (attribs = "width=$width")
(attribs "" && height nothing ) && (attribs *= " ")
height == nothing || (attribs *= "height=$height")
attribs == "" || (attribs = "{$attribs}")
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 = Dict{AbstractString, Any}("tex" => tex,
"texminted" => texminted,
"pandoc" => pandoc,
"pandoc2html" => pdoc2html,
"pandoc2pdf" => pandoc,
"md2pdf" => md2tex,
"github" => github,
"multimarkdown" => multimarkdown,
"rst" => rst,
"asciidoc" => adoc,
"md2html" => md2html,
"md2tex" => md2tex
)

View File

@ -1,42 +1,51 @@
using Gadfly
module GadflyPlots
using ..Weave, ..Gadfly
Gadfly.set_default_plot_format(:svg)
#Gadfly doesn't call the default display methods, this catches
#all Gadfly plots
function Base.display(report::Report, m::MIME"image/svg+xml", p::Plot)
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

View File

@ -1,100 +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)
weavedir = dirname(@__FILE__)
html_template = joinpath(weavedir, "../templates/pandoc_skeleton.html")
css_template = joinpath(weavedir, "../templates/pandoc_skeleton.css")
path, wsource = splitdir(abspath(doc.source))
wversion = string(Pkg.installed("Weave"))
wtime = string(Date(now()))
#Header is inserted from displayed plots
header_script = doc.header_script
#info(doc.header_script)
if header_script ""
self_contained = []
else
self_contained = "--self-contained"
end
#Change path for pandoc
old_wd = pwd()
cd(doc.cwd)
html =""
outname = basename(outname)
try
pandoc_out, pandoc_in, proc = readandwrite(`pandoc -R -s --mathjax="" --highlight-style=tango
--template $html_template -H $css_template $self_contained
-V wversion=$wversion -V wtime=$wtime -V wsource=$wsource
-V headerscript=$header_script
-o $outname`)
println(pandoc_in, formatted)
close(pandoc_in)
proc_output = readstring(pandoc_out)
cd(old_wd)
catch e
cd(old_wd)
warn("Error converting document to HTML")
throw(e)
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)
weavedir = dirname(@__FILE__)
header_template = joinpath(weavedir, "../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
pandoc_out, pandoc_in, proc = readandwrite(`pandoc -R -s --latex-engine=xelatex --highlight-style=tango
--include-in-header=$header_template
-V fontsize=12pt -o $outname`)
println(pandoc_in, formatted)
close(pandoc_in)
proc_output = readall(pandoc_out)
cd(old_wd)
catch e
cd(old_wd)
warn("Error converting document to pdf")
throw(e)
end
end
function run_latex(doc::WeaveDoc, outname, latex_cmd = "pdflatex")
old_wd = pwd()
cd(doc.cwd)
xname = basename(outname)
info("Weaved code to $outname. Running $latex_cmd")
try
out = readstring(`$latex_cmd $xname`)
cd(old_wd)
catch e
cd(old_wd)
warn("Error converting document to pdf. Try running latex manually")
#throw(e)
end
end

View File

@ -1,75 +1,112 @@
import Plots
module WeavePlots
"""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))
return chunk
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
push_preexecute_hook(plots_set_size)
Weave.push_preexecution_hook!(plots_set_size!)
#PNG or SVG is not working, output html
function Base.display(report::Report, m::MIME"image/svg+xml", data::Plots.Plot{Plots.PlotlyBackend})#
#Remove extra spaces from start of line for pandoc
s = reprmime(MIME("text/html"), data)
splitted = split(s, "\n")
start = split(splitted[1], r"(?=<div)")
#script = lstrip(start[1]) #local
# 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")
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
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::Report, m::MIME"image/png", data::Plots.Plot{Plots.PlotlyBackend})#
display(report, MIME("image/svg+xml"), data)
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)
#PNG or SVG is not working, output html
function Base.display(report::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
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
report.rich_output *= "\n" * body
end
function Base.display(report::Report, m::MIME"image/png", plot::Plots.Plot{Plots.PlotlyJSBackend})
display(report, MIME("image/svg+xml"), data)
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::Report, plot::Plots.Plot, ext)
chunk = report.cur_chunk
full_name, rel_name = get_figname(report, chunk, ext = ext)
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
Plots.savefig(plot, full_name)
push!(report.figures, rel_name)
report.fignum += 1
return full_name
end
function Base.display(report::Report, m::MIME"application/pdf", plot::Plots.Plot)
function Base.display(report::Weave.Report, m::MIME"application/pdf", plot::Plots.Plot)
add_plots_figure(report, plot, ".pdf")
end
function Base.display(report::Report, m::MIME"image/png", plot::Plots.Plot)
function Base.display(report::Weave.Report, m::MIME"image/png", plot::Plots.Plot)
add_plots_figure(report, plot, ".png")
end
function Base.display(report::Report, m::MIME"image/svg+xml", plot::Plots.Plot)
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

View File

@ -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

95
src/reader/markdown.jl Normal file
View File

@ -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

23
src/reader/notebook.jl Normal file
View File

@ -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

128
src/reader/reader.jl Normal file
View File

@ -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")

67
src/reader/script.jl Normal file
View File

@ -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

View File

@ -1,275 +0,0 @@
import JSON, YAML
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
type NotebookInput
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"(^#\+)|(^#%%\+)|(^# %%\+)"),
"notebook" => NotebookInput()
)
"""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"
ext == ".ipynb" && return "notebook"
return "noweb"
end
"""Read and parse input document"""
function read_doc(source::AbstractString, format=:auto)
format == :auto && (format = detect_informat(source))
document = readstring(source)
parsed = parse_doc(document, format)
header = parse_header(parsed[1])
doc = WeaveDoc(source, parsed, header)
return doc
end
function parse_header(chunk::CodeChunk)
return Dict()
end
function parse_header(chunk::DocChunk)
m = match(r"^---$(?<header>.+)^---$"ms, chunk.content)
if m !== nothing
header = YAML.load(string(m[:header]))
else
header = Dict()
end
return header
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
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)
if !isempty(strip(content))
chunk = DocChunk(content, docno, start_line)
docno += 1
push!(parsed, chunk)
end
content = ""
start_line = lineno
continue
end
if ismatch(codeend, line) && state=="code"
chunk = CodeChunk(content, codeno, start_line, optionString, options)
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 = 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" * strip(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" * strip(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" * strip(read), codeno, start_line, optionString, options)
push!(parsed, chunk)
else
chunk = DocChunk(read, docno, start_line)
push!(parsed, chunk)
end
return parsed
end
"""Parse IJUlia notebook"""
function parse_doc(document::String, format::NotebookInput)
nb = JSON.parse(document)
parsed = Any[]
options = Dict{Symbol,Any}()
opt_string = ""
docno = 1
codeno = 1
for cell in nb["cells"]
srctext = "\n" * join(cell["source"], "")
if cell["cell_type"] == "code"
chunk = CodeChunk(rstrip(srctext), codeno, 0, opt_string, options)
push!(parsed, chunk)
codeno += 1
else
chunk = DocChunk(srctext * "\n", docno, 0)
push!(parsed, chunk)
docno +=1
end
end
return parsed
end

162
src/rendering/common.jl Normal file
View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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")

264
src/rendering/texformats.jl Normal file
View File

@ -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

View File

@ -1,429 +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=:auto,
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]
using Base64
set_rc_params(doc.format.formatdict, fig_path, fig_ext)
const PROGRESS_ID = "weave_progress"
#New sandbox for each document
sandbox = "ReportSandBox$(rcParams[:doc_number])"
eval(parse("module $sandbox\nend"))
SandBox = eval(parse(sandbox))
rcParams[:doc_number] += 1
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 haskey(doc.format.formatdict, :mimetypes)
mimetypes = doc.format.formatdict[:mimetypes]
else
mimetypes = default_mime_types
end
doc.doctype = isnothing(doctype) ? (doctype = detect_doctype(doc.source)) : doctype
doc.format = deepcopy(get_format(doctype))
#Reset plotting
rcParams[:plotlib_set] = false
plotlib == :auto || init_plotting(plotlib)
cwd = doc.cwd = get_cwd(doc, out_path)
mkpath(cwd)
report = Report(doc.cwd, doc.basename, doc.format.formatdict, mimetypes)
pushdisplay(report)
if cache != :off && cache != :refresh
cached = read_cache(doc, cache_path)
cached == nothing && info("No cached results found, running code")
else
cached = nothing
end
executed = Any[]
n = length(doc.chunks)
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
DEFAULT_FIG_PATH
end
end
mkpath(normpath(cwd, fig_path))
# This is needed for latex and should work on all output formats
@static Sys.iswindows() && (fig_path = replace(fig_path, "\\" => "/"))
set_rc_params(doc, fig_path, fig_ext)
result_chunks = run_chunk(chunk, report, SandBox)
cache === :off || @eval import Serialization # XXX: evaluate in a more sensible module
# New sandbox for each document with args exposed
isnothing(mod) && (mod = sandbox = Core.eval(Main, :(module $(gensym(:WeaveSandBox)) end))::Module)
Core.eval(mod, :(WEAVE_ARGS = $(args)))
mimetypes = doc.format.mimetypes
report = Report(cwd, doc.basename, doc.format, mimetypes)
cd_back = let d = pwd(); () -> cd(d); end
cd(cwd)
pushdisplay(report)
try
if cache !== :off && cache !== :refresh
cached = read_cache(doc, cache_path)
isnothing(cached) && @info "No cached results found, running code"
else
cached = nothing
end
executed = [executed; result_chunks]
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)
doc.header_script = report.header_script
@info "Weaving chunk $(chunk.number) from line $(chunk.start_line)" progress=(i)/n _id=PROGRESS_ID
i+=1
end
popdisplay(report)
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
#Clear variables from used sandbox
clear_sandbox(SandBox)
doc.chunks = executed
replace_header_inline!(doc, report, mod) # evaluate and replace inline code in header
if cache != :off
write_cache(doc, cache_path)
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)
N = length(expressions)
#@show expressions
result_no = 1
results = ChunkOutput[ ]
for (str_expr, expr) = expressions
reset_report(report)
lastline = (result_no == N)
rcParams[:plotlib_set] || detect_plotlib(chunk) #Try to autodetect plotting library
(obj, out) = capture_output(expr, SandBox, chunk.options[:term],
chunk.options[:display], rcParams[:plotlib], lastline)
figures = report.figures #Captured figures
result = ChunkOutput(str_expr, out, report.cur_result, report.rich_output, figures)
report.rich_output = ""
push!(results, result)
result_no += 1
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
getstdout() = Base.STDOUT
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(expr, SandBox::Module, term, disp, plotlib,
lastline)
#oldSTDOUT = STDOUT
oldSTDOUT = getstdout()
out = nothing
obj = nothing
function capture_output(code, mod, path, error, report)
reset_report!(report)
old = stdout
rw, wr = redirect_stdout()
reader = @async readstring(rw)
try
obj = eval(SandBox, expr)
if (term || disp) && typeof(expr) == Expr && expr.head != :toplevel
obj != nothing && display(obj)
elseif typeof(expr) == Symbol
display(obj)
elseif plotlib == "Gadfly" && typeof(obj) == Gadfly.Plot
obj != nothing && display(obj)
#This shows images and lone variables, result can
#Handle last line sepately
elseif lastline && obj != nothing
#elseif mimewritable("image/png", obj) && expr.head == :call
if expr.head == :call
display(obj)
end
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 = wait(reader)
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, Any}[]
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
#Run preexecute_hooks
for hook in preexecute_hooks
chunk = hook(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)
chunk.result = run_code(doc, chunk, report, mod)
#Run post_execute chunks
for hook in postexecute_hooks
chunk = hook(chunk)
end
execute_posthooks!(chunk)
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
#else
# chunk.options[:fig] && (chunk.figures = copy(report.figures))
#end
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)
figpath = joinpath(report.cwd, chunk.options[:fig_path])
isdir(figpath) || mkpath(figpath)
ext == nothing && (ext = chunk.options[:fig_ext])
fignum == nothing && (fignum = report.fignum)
isnothing(ext) && (ext = chunk.options[:fig_ext])
isnothing(fignum) && (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)
srcdir = escape_string(dirname(@__FILE__))
rcParams[:plotlib_set] = true
if plotlib == nothing
rcParams[:plotlib] = nothing
else
l_plotlib = lowercase(plotlib)
rcParams[:chunk_defaults][:fig] = true
if l_plotlib == "winston"
eval(parse("""include("$srcdir/winston.jl")"""))
rcParams[:plotlib] = "Winston"
elseif l_plotlib == "pyplot"
eval(parse("""include("$srcdir/pyplot.jl")"""))
rcParams[:plotlib] = "PyPlot"
elseif l_plotlib == "plots"
eval(parse("""include("$srcdir/plots.jl")"""))
rcParams[:plotlib] = "Plots"
elseif l_plotlib == "gadfly"
eval(parse("""include("$srcdir/gadfly.jl")"""))
rcParams[:plotlib] = "Gadfly"
end
end
return true
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
#Check if there is any output from chunk
if strip(r.stdout) == "" && isempty(r.figures) && strip(r.rich_output) == ""
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
rchunk.figures = r.figures
rchunk.output = r.stdout * r.displayed
result_chunks = CodeChunk[]
for r in chunk.result
content *= r.code
# Check if there is any output from chunk
if any(!isempty strip, (r.stdout, r.rich_output)) || !isempty(r.figures)
rchunk = CodeChunk(
content,
chunk.number,
chunk.start_line,
chunk.optionstring,
copy(chunk.options),
)
rchunk.output = r.stdout
rchunk.rich_output = r.rich_output
rchunk.figures = r.figures
push!(result_chunks, rchunk)
content = ""
end
end
if 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 = ""
prompt = chunk.options[:prompt]
result_no = 1
result_chunks = CodeChunk[ ]
for r = chunk.result
output *= prompt * r.code
output *= r.displayed * r.stdout
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
function detect_plotlib(chunk::CodeChunk)
if isdefined(:Plots)
init_plotting("Plots")
#Need to set size before plots are created
plots_set_size(chunk)
return
end
isdefined(:PyPlot) && init_plotting("PyPlot") && return
isdefined(:Gadfly) && init_plotting("Gadfly") && return
isdefined(:Winston) && init_plotting("Winston") && return
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

72
src/types.jl Normal file
View File

@ -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[])

View File

@ -1,47 +0,0 @@
import Winston
import Base.mimewritable
function save_winston(report, 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
function Base.display(report::Report, m::MIME"image/svg+xml", data::Winston.FramedPlot)
save_winston(report, data)
end
function Base.mimewritable(m::MIME"application/pdf", data::Winston.FramedPlot)
return true
end
function Base.mimewritable(m::MIME"image/svg+xml", data::Winston.FramedPlot)
return true
end
function Base.display(report::Report, m::MIME"application/pdf", data::Winston.FramedPlot)
save_winston(report, data)
end
function Base.display(report::Report, m::MIME"image/png", data::Winston.FramedPlot)
save_winston(report, data)
end
function Base.display(report::Report, m::MIME"image/jpg", data::Winston.FramedPlot)
save_winston(report, data)
end

19
src/writer/latex.jl Normal file
View File

@ -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

76
src/writer/pandoc.jl Normal file
View File

@ -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

11
src/writer/writer.jl Normal file
View File

@ -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")

View File

@ -1,160 +0,0 @@
import JSON
type NotebookOutput
end
type MarkdownOutput
end
type NowebOutput
end
type ScriptOutput
end
const output_formats = Dict{String, Any}(
"noweb" => NowebOutput(),
"notebook" => NotebookOutput(),
"markdown" => MarkdownOutput(),
"script" => ScriptOutput()
)
"""Autodetect format for converter"""
function detect_outformat(outfile::String)
ext = lowercase(splitext(outfile)[2])
ext == ".jl" && return "script"
ext == ".jmd" && return "markdown"
ext == ".ipynb" && return "notebook"
return "noweb"
end
"""
`convert_doc(infile::AbstractString, outfile::AbstractString; format = nothing)`
Convert Weave documents between different formats
* `infile` = Name of the input document
* `outfile` = Name of the output document
* `format` = Output format (optional). Detected from outfile extension, but can
be set to `"script"`, `"markdown"`, `"notebook"` or `"noweb"`.
"""
function convert_doc(infile::AbstractString, outfile::AbstractString; format = nothing)
doc = read_doc(infile)
if format == nothing
format = detect_outformat(outfile)
end
converted = convert_doc(doc, output_formats[format])
open(outfile, "w") do f
write(f, converted)
end
return nothing
end
"""Convert Weave document to Jupyter notebook format"""
function convert_doc(doc::WeaveDoc, format::NotebookOutput)
nb = Dict()
nb["nbformat"] = 4
nb["nbformat_minor"] = 2
metadata = Dict()
kernelspec = Dict()
kernelspec["language"] = "julia"
kernelspec["name"] = "julia-0.5"
kernelspec["display_name"] = "Julia 0.5.0"
metadata["kernelspec"] = kernelspec
language_info = Dict()
language_info["file_extension"] = ".jl"
language_info["mimetype"] = "application/julia"
language_info["name"]= "julia"
language_info["version"] = "0.5.0"
metadata["language_info"] = language_info
cells = []
ex_count = 1
doc.chunks[3].content
for chunk in doc.chunks
if typeof(chunk) == Weave.DocChunk
push!(cells,
Dict("cell_type" => "markdown",
"metadata" => Dict(),
"source" => [strip(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
"""Convert Weave document to Jupyter notebook format"""
function convert_doc(doc::WeaveDoc, format::MarkdownOutput)
output = ""
for chunk in doc.chunks
if typeof(chunk) == Weave.DocChunk
output *= chunk.content
else
output *= "\n" * "```julia"
isempty(chunk.optionstring) || (output *= ";" * chunk.optionstring)
output *= "\n" * lstrip(chunk.content)
output *= "\n```\n"
end
end
return output
end
"""Convert Weave document to noweb format"""
function convert_doc(doc::WeaveDoc, format::NowebOutput)
output = ""
for chunk in doc.chunks
if typeof(chunk) == Weave.DocChunk
output *= chunk.content
else
output *= "\n" * "<<"
isempty(chunk.optionstring) || (output *= strip(chunk.optionstring))
output *= ">>="
output *= "\n" * lstrip(chunk.content)
output *= "\n@\n"
end
end
return output
end
"""Convert Weave document to script format"""
function convert_doc(doc::WeaveDoc, format::ScriptOutput)
output = ""
for chunk in doc.chunks
if typeof(chunk) == Weave.DocChunk
output *= join(["#' " * s for s in split(chunk.content, "\n")], "\n")
else
output *= "\n#+ "
isempty(chunk.optionstring) || (output *= strip(chunk.optionstring))
output *= "\n\n" * lstrip(chunk.content)
output *= "\n\n"
end
end
return output
end

View File

@ -1,16 +1,13 @@
<style type="text/css">
@font-face {
font-family: 'Garamond';
font-style: normal;
font-weight: 300;
}
@font-face {
font-family: 'Garamond';
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: 'Garamond';
font-style: normal;
font-weight: 600;
}
@ -184,6 +181,8 @@ optgroup {
font-weight: bold;
}
table {
font-family: monospace, monospace;
font-size : 0.8em;
border-collapse: collapse;
border-spacing: 0;
}
@ -191,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
@ -503,7 +508,7 @@ pre.sourceCode.julia {
display: block;
padding: 9.5px;
margin: 0 0 10px;
font-size: 13px;
font-size: 12px;
line-height: 1.42857143;
color: #333;
word-break: break-all;
@ -513,6 +518,10 @@ pre.sourceCode.julia {
border-radius: 4px;
}
pre.julia-error {
color : red
}
code,
kbd,
pre,
@ -520,16 +529,11 @@ samp {
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
}
code {
padding: 2px 4px;
font-size: 90%;
background-color: #ffffff;
border-radius: 4px;
}
code.sourceCode.julia {
padding: 2px 4px;
font-size: 90%;
background-color: #f5f5f5;
border-radius: 4px;
}
@ -542,5 +546,5 @@ code.sourceCode.julia {
@media (min-width: 1200px) {}
h1.title {margin-top : 20px}
img {max-width : 100%%}
img {max-width : 100%}
</style>

View File

@ -180,6 +180,8 @@ optgroup {
font-weight: bold;
}
table {
font-family: monospace, monospace;
font-size : 0.8em;
border-collapse: collapse;
border-spacing: 0;
}
@ -187,6 +189,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);
}
/*
@ -425,8 +434,7 @@ ol ol,
ol ul {
margin: 1.5rem 0 1.5rem 3rem;
font-size: 90%; }
li {
margin-bottom: 1rem; }
li > p {margin : 0;}
th,
td {
padding: 12px 15px;
@ -455,7 +463,7 @@ p,
ul,
ol,
form {
margin-bottom: 2.5rem; }
margin-bottom: 1.0rem; }
.u-full-width {
width: 100%;
box-sizing: border-box; }
@ -484,26 +492,30 @@ pre {
margin: 0 0 10px;
font-size: 13px;
line-height: 1.42857143;
color: #333;
word-break: break-all;
word-wrap: break-word;
background-color: #ffffff;
border: 1px solid #ccc;
border-radius: 4px;
}
pre.sourceCode.julia {
display: block;
padding: 9.5px;
pre.hljl {
margin: 0 0 10px;
font-size: 13px;
line-height: 1.42857143;
color: #333;
word-break: break-all;
word-wrap: break-word;
background-color: #f5f5f5;
border: 1px solid #ccc;
display: block;
background: #f5f5f5;
border-radius: 4px;
padding : 5px;
}
pre.output {
background: #ffffff;
}
pre.code {
background: #ffffff;
}
pre.julia-error {
color : red
}
code,
@ -511,14 +523,9 @@ kbd,
pre,
samp {
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
font-size: 0.9em;
}
code {
padding: 2px 4px;
font-size: 90%;
background-color: #ffffff;
border-radius: 4px;
}
@media (min-width: 400px) {}
@media (min-width: 550px) {}
@ -527,5 +534,5 @@ code {
@media (min-width: 1200px) {}
h1.title {margin-top : 20px}
img {max-width : 100%%}
img {max-width : 100%}
div.title {text-align: center;}

View File

@ -1,50 +0,0 @@
<!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: [['$','$'], ['\\(','\\)']]}
});
</script>
<script src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
<style type="text/css">
{{{ :themecss }}}
</style>
{{{ :highlightcss }}}
</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="{{{:source}}}">{{{:source}}}</a> using
<a href="http://github.com/mpastell/Weave.jl">Weave.jl</a>
{{:wversion}} on {{:wtime}}.
<p></div>
</div>
</div>
</div>
</BODY>
</HTML>

50
templates/md2html.tpl Normal file
View File

@ -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>

View File

@ -3,13 +3,13 @@
\usepackage[a4paper,text={16.5cm,25.2cm},centering]{geometry}
\usepackage{lmodern}
\usepackage{amssymb,amsmath}
\usepackage{ifxetex}
\ifxetex
\usepackage{mathspec}
\fi
\usepackage{graphics}
\usepackage{bm}
\usepackage{graphicx}
\usepackage{microtype}
\usepackage{hyperref}
{{#:tex_deps}}
{{{ :tex_deps }}}
{{/:tex_deps}}
\setlength{\parindent}{0pt}
\setlength{\parskip}{1.2ex}
@ -22,7 +22,6 @@
urlcolor=blue
}
{{#:title}}
\title{ {{{ :title }}} }
{{/:title}}
@ -35,7 +34,7 @@
\date{ {{{ :date }}} }
{{/:date}}
{{{ :highlight }}}
{{ :highlight }}
\begin{document}

View File

@ -32,6 +32,8 @@ $for(header-includes)$
$header-includes$
$endfor$
$highlight_stylesheet$
$if(highlighting-css)$
<style type="text/css">
$highlighting-css$
@ -83,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>

View File

@ -1,8 +0,0 @@
julia 0.5
Cairo
Gadfly
PyPlot
#Winston
GR
DSP
Plots

View File

@ -1,33 +1,28 @@
using Weave
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 = 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 = 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 = 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 = 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 = 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 = 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

View File

@ -1,17 +0,0 @@
using Weave
using Base.Test
cleanup = true
weave("documents/chunk_options.noweb", plotlib=nothing)
result = readstring(open("documents/chunk_options.md"))
ref = readstring(open("documents/chunk_options_ref.md"))
@test result == ref
cleanup && rm("documents/chunk_options.md")
tangle("documents/chunk_options.noweb", out_path = "documents/tangle")
result = readstring(open("documents/tangle/chunk_options.jl"))
ref = readstring(open("documents/tangle/chunk_options.jl.ref"))
@test ref == result
cleanup && rm("documents/tangle/chunk_options.jl")

View File

@ -1,18 +0,0 @@
using Weave
using Base.Test
cleanup = true
#Test hold and term options
weave("documents/test_hold.mdw", doctype="pandoc", plotlib="Gadfly")
result = readstring(open("documents/test_hold.md"))
ref = 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 = readstring(open("documents/default_opts.tex"))
ref = readstring(open("documents/default_opts_ref.tex"))
@test result == ref
cleanup && rm("documents/default_opts.tex")

View File

@ -1,29 +0,0 @@
using Weave
using Base.Test
function convert_test(outfile)
outfile = joinpath("documents/convert", outfile)
infile = "documents/chunk_options.noweb"
convert_doc(infile, outfile)
result = readstring(open(outfile))
ref = readstring(open(outfile * ".ref"))
@test result == ref
rm(outfile)
end
convert_test("chunk_options.jmd")
convert_test("chunk_options.jl")
convert_test("chunk_options.mdw")
convert_test("chunk_options.ipynb")
function convert_test_nb(outfile)
outfile = joinpath("documents/convert", outfile)
infile = "documents/chunk_options.ipynb"
convert_doc(infile, outfile)
result = readstring(open(outfile))
ref = readstring(open(outfile * ".ref"))
rm(outfile)
@test result == ref
end
convert_test_nb("chunk_options_nb.mdw")

View File

@ -1,80 +0,0 @@
#' % FIR filter design with Julia
#' % Matti Pastell
#' % 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/).
#' The script can be executed normally using Julia
#' or published to HTML or pdf with Weave.
#' Text is written in markdown in lines starting with "`#'` " and code
#' is executed and results are included in the published document.
#' Notice that you don't need to define chunk options, but you can using
#' `#+`. just before code e.g. `#+ term=True, caption='Fancy plots.'`.
#' If you're viewing the published version have a look at the
#' [source](FIR_design.jl) to see the markup.
#' # FIR Filter Design
#' We'll implement lowpass, highpass and ' bandpass FIR filters. If
#' you want to read more about DSP I highly recommend [The Scientist
#' and Engineer's Guide to Digital Signal
#' Processing](http://www.dspguide.com/) which is freely available
#' online.
#' ## Calculating frequency response
#' DSP.jl package doesn't (yet) have a method to calculate the
#' the frequency response of a FIR filter so we define it:
using Gadfly, DSP
function FIRfreqz(b::Array, w = linspace(0, π, 1024))
n = length(w)
h = Array{Complex64}(n)
sw = 0
for i = 1:n
for j = 1:length(b)
sw += b[j]*exp(-im*w[i])^-j
end
h[i] = sw
sw = 0
end
return h
end
#' ## Design Lowpass FIR filter
#' Designing a lowpass FIR filter is very simple to do with DSP.jl, all you
#' need to do is to define the window length, cut off frequency and the
#' window. We will define a lowpass filter with cut off frequency at 5Hz for a signal
#' sampled at 20 Hz.
#' We will use the Hamming window, which is defined as:
#' $w(n) = \alpha - \beta\cos\frac{2\pi n}{N-1}$, where $\alpha=0.54$ and $\beta=0.46$
fs = 20
f = digitalfilter(Lowpass(5, fs = fs), FIRWindow(hamming(61)))
w = linspace(0, pi, 1024)
h = FIRfreqz(f, w)
#' ## Plot the frequency and impulse response
h_db = log10(abs(h))
ws = w/pi*(fs/2)
#' The next code chunk is executed in term mode, see the [script](FIR_design.jl) for syntax.
#+ term=true
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)))
plot(y = h_phase, x = ws, Geom.line,
Guide.xlabel("Frequency (Hz)"), Guide.ylabel("Phase (radians)"))

View File

@ -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

View File

@ -1,6 +0,0 @@
Functions:
<<>>=
f(x)=x^2
println(f(2))
@

View File

@ -1,13 +0,0 @@
Functions:
~~~~{.julia}
f(x)=x^2
println(f(2))
~~~~~~~~~~~~~
~~~~
4
~~~~

View File

@ -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))

View File

@ -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)

View File

@ -4,6 +4,25 @@ julia> y= [2, 5, 12]
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
~~~~~~~~~~~~~
@ -15,7 +34,7 @@ println(y)
~~~~
[2,5,12]
[2, 4, 8]
~~~~
@ -26,7 +45,7 @@ println(x)
~~~~
[12,10]
[12, 10]
~~~~
@ -38,12 +57,13 @@ Results without code
~~~~
[12,10]
[12, 10]
~~~~
~~~~{.julia}
y = randn(5)
println("Don't eval, but show code")
~~~~~~~~~~~~~
@ -86,12 +106,13 @@ println(collect(0:10:1000))
~~~~
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,2
10,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,
400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580
,590,600,610,620,630,640,650,660,670,680,690,700,710,720,730,740,750,760,77
0,780,790,800,810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,9
60,970,980,990,1000]
[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]
~~~~
@ -102,7 +123,7 @@ println(collect(0:10:1000))
~~~~
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580,590,600,610,620,630,640,650,660,670,680,690,700,710,720,730,740,750,760,770,780,790,800,810,820,830,840,850,860,870,880,890,900,910,920,930,940,950,960,970,980,990,1000]
[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]
~~~~
@ -113,13 +134,15 @@ println(collect(0:10:1000))
~~~~
[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,17
0,180,190,200,210,220,230,240,250,260,270,280,290,300,310,32
0,330,340,350,360,370,380,390,400,410,420,430,440,450,460,47
0,480,490,500,510,520,530,540,550,560,570,580,590,600,610,62
0,630,640,650,660,670,680,690,700,710,720,730,740,750,760,77
0,780,790,800,810,820,830,840,850,860,870,880,890,900,910,92
0,930,940,950,960,970,980,990,1000]
[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]
~~~~

View File

@ -9,6 +9,15 @@
"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",

View File

@ -4,6 +4,13 @@
y= [2, 5, 12]
#+ term=true
x = 1:10
d = Dict("Weave" => "testing")
y = [2, 4 ,8]
#+
x = [12, 10]

View File

@ -3,6 +3,12 @@
y= [2, 5, 12]
```
```julia;term=true
x = 1:10
d = Dict("Weave" => "testing")
y = [2, 4 ,8]
```
```julia
x = [12, 10]
println(y)

View File

@ -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)

View File

@ -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)
@

View File

@ -1,43 +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