From cc936f53775b039da1d54cbe8cf39d7eccda1d04 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Mon, 25 May 2020 22:22:15 +0900 Subject: [PATCH 1/4] refactor formatters.jl --- src/Weave.jl | 12 +- src/{formatters.jl => formats.jl} | 413 ++++++++++++++---------------- src/run.jl | 2 +- test/figureformatter_test.jl | 56 ++-- test/formatter_test.jl | 6 +- 5 files changed, 238 insertions(+), 251 deletions(-) rename src/{formatters.jl => formats.jl} (78%) diff --git a/src/Weave.jl b/src/Weave.jl index 2b354f5..e74e653 100644 --- a/src/Weave.jl +++ b/src/Weave.jl @@ -27,15 +27,11 @@ end take2string!(io) = String(take!(io)) """ - list_out_formats() + list_out_formats(io = stdout) List supported output formats """ -function list_out_formats() - for format in keys(formats) - println(string(format, ": ", formats[format].description)) - end -end +list_out_formats(io = stdout) = for (k, v) in FORMATS; println(io, string(k, ": ", v.description)); end """ tangle(source::AbstractString; kwargs...) @@ -228,7 +224,7 @@ weave(doc::AbstractString, doctype::Union{Symbol,AbstractString}; kwargs...) = weave(doc; doctype = doctype, kwargs...) function specific_options!(weave_options, doctype) - fmts = keys(formats) + fmts = keys(FORMATS) for (k,v) in weave_options if k in fmts k == doctype && merge!(weave_options, v) @@ -335,7 +331,7 @@ include("display_methods.jl") include("reader/reader.jl") include("run.jl") include("cache.jl") -include("formatters.jl") +include("formats.jl") include("format.jl") include("pandoc.jl") include("converter.jl") diff --git a/src/formatters.jl b/src/formats.jl similarity index 78% rename from src/formatters.jl rename to src/formats.jl index f3cf809..551df24 100644 --- a/src/formatters.jl +++ b/src/formats.jl @@ -1,16 +1,105 @@ -# so dirty, refactor - -using Printf +# TODO: +# - 1. turn each `.formatdict` value into fields +# - 2. do assertions for definition mandatory fields in `@define_format` macro +# - 3. export as public API -struct Tex - description::AbstractString - formatdict::Dict{Symbol,Any} +abstract type WeaveFormat end +const FORMATS = Dict{String,WeaveFormat}() +register_format!(format_name::AbstractString, format::WeaveFormat) = push!(FORMATS, format_name => format) + +macro define_format(type_name, supertype = WeaveFormat) + return quote + struct $(type_name) <: $(supertype) + description::String + formatdict::Dict{Symbol,Any} + end + end end -const tex = Tex( + +# HTML +# ---- + +@define_format JMarkdown2HTML +register_format!("md2html", JMarkdown2HTML( + "Julia markdown to html", + Dict( + :codestart => "\n", + :codeend => "\n", + :outputstart => "
",
+        :outputend => "
\n", + :fig_ext => ".png", + :mimetypes => [ + "image/png", + "image/jpg", + "image/svg+xml", + "text/html", + "text/markdown", + "text/plain", + ], + :extension => "html", + :doctype => "md2html", + ), +)) + +@define_format Pandoc2HTML +register_format!("pandoc2html", Pandoc2HTML( + "Markdown to HTML (requires Pandoc 2)", + Dict( + :codestart => "\n", + :codeend => "\n", + :outputstart => "\n", + :outputend => "\n", + :fig_ext => ".png", + :extension => "md", + :mimetypes => [ + "image/png", + "image/svg+xml", + "image/jpg", + "text/html", + "text/markdown", + "text/plain", + ], + :doctype => "pandoc2html", + ), +)) + + +# PDF and Tex +# ----------- + +@define_format JMarkdown2tex +let t = JMarkdown2tex( + "Julia markdown to latex", + Dict( + :codestart => "", + :codeend => "", + :outputstart => "\\begin{lstlisting}", + :outputend => "\\end{lstlisting}\n", + :fig_ext => ".pdf", + :extension => "tex", + :out_width => "\\linewidth", + :mimetypes => [ + "application/pdf", + "image/png", + "image/jpg", + "text/latex", + "text/markdown", + "text/plain", + ], + :doctype => "md2tex", + :keep_unicode => false, + ) + ) + register_format!("md2pdf", t) + register_format!("md2tex", t) +end + +@define_format Tex +register_format!("tex", Tex( "Latex with custom code environments", - Dict{Symbol,Any}( + Dict( :codestart => "\\begin{juliacode}", :codeend => "\\end{juliacode}", :outputstart => "\\begin{juliaout}", @@ -26,11 +115,10 @@ const tex = Tex( :mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"], :keep_unicode => false, ), -) - -const texminted = Tex( +)) +register_format!("texminted", Tex( "Latex using minted for highlighting", - Dict{Symbol,Any}( + Dict( :codestart => "\\begin{minted}[mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}", :codeend => "\\end{minted}", @@ -49,64 +137,41 @@ const texminted = Tex( :mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"], :keep_unicode => false, ), -) +)) -struct Pandoc - description::AbstractString - formatdict::Dict{Symbol,Any} + +# pandoc +# ------ + +@define_format Pandoc +let p = Pandoc( + "Pandoc markdown", + Dict( + :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", + ), + ) + register_format!("pandoc", p) + register_format!("pandoc2pdf", p) 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", - ), -) -struct Pandoc2HTML - description::AbstractString - formatdict::Dict{Symbol,Any} -end +# markdown +# -------- -const pdoc2html = Pandoc2HTML( - "Markdown to HTML (requires Pandoc 2)", - Dict{Symbol,Any}( - :codestart => "\n", - :codeend => "\n", - :outputstart => "\n", - :outputend => "\n", - :fig_ext => ".png", - :extension => "md", - :mimetypes => [ - "image/png", - "image/svg+xml", - "image/jpg", - "text/html", - "text/markdown", - "text/plain", - ], - :doctype => "pandoc2html", - ), -) - -struct GitHubMarkdown - description::AbstractString - formatdict::Dict{Symbol,Any} -end - -const github = GitHubMarkdown( +@define_format GitHubMarkdown +register_format!("github", GitHubMarkdown( "GitHub markdown", - Dict{Symbol,Any}( + Dict( :codestart => "````julia", :codeend => "````\n\n", :outputstart => "````", @@ -117,22 +182,12 @@ const github = GitHubMarkdown( ["image/png", "image/svg+xml", "image/jpg", "text/markdown", "text/plain"], :doctype => "github", ), -) +)) -""" -Formatter for Hugo: https://gohugo.io/ - -When `uglyURLs` is `false`, prepend figure path by `..`. -""" -struct Hugo - description::AbstractString - formatdict::Dict{Symbol,Any} - uglyURLs::Bool -end - -const hugo = Hugo( +@define_format Hugo +register_format!("hugo", Hugo( "Hugo markdown (using shortcodes)", - Dict{Symbol,Any}( + Dict( :codestart => "````julia", :codeend => "````\n\n", :outputstart => "````", @@ -140,69 +195,79 @@ const hugo = Hugo( :fig_ext => ".png", :extension => "md", :doctype => "hugo", + :uglyURLs => false, # if `false`, prepend figure path by `..` ), - false, -) +)) -# Julia markdown -struct JMarkdown2HTML - description::AbstractString - formatdict::Dict{Symbol,Any} -end - -const md2html = JMarkdown2HTML( - "Julia markdown to html", - Dict{Symbol,Any}( - :codestart => "\n", - :codeend => "\n", - :outputstart => "
",
-        :outputend => "
\n", +@define_format MultiMarkdown +register_format!("multimarkdown", MultiMarkdown( + "MultiMarkdown", + Dict( + :codestart => "````julia", + :codeend => "````\n\n", + :outputstart => "````", + :outputend => "````\n\n", :fig_ext => ".png", - :mimetypes => [ - "image/png", - "image/jpg", - "image/svg+xml", - "text/html", - "text/markdown", - "text/plain", - ], - :extension => "html", - :doctype => "md2html", + :extension => "md", + :doctype => "github", ), -) +)) -# Julia markdown -struct 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", - :out_width => "\\linewidth", - :mimetypes => [ - "application/pdf", - "image/png", - "image/jpg", - "text/latex", - "text/markdown", - "text/plain", - ], - :doctype => "md2tex", - :keep_unicode => false, +# Rest +# ---- + +@define_format Rest +register_format!("rst", Rest( + "reStructuredText and Sphinx", + Dict( + :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", ), -) +)) -struct MultiMarkdown - description::AbstractString - formatdict::Dict{Symbol,Any} + +# Ansii +# ----- + +# asciidoc -b html5 -a source-highlighter=pygments ... +@define_format AsciiDoc +register_format!("asciidoc", AsciiDoc( + "AsciiDoc", + Dict( + :codestart => "[source,julia]\n--------------------------------------", + :codeend => "--------------------------------------\n\n", + :outputstart => "--------------------------------------", + :outputend => "--------------------------------------\n\n", + :fig_ext => ".png", + :extension => "txt", + :out_width => "600", + :doctype => "asciidoc", + ), +)) + + +# TODO: move this functions where used +# ------------------------------------ + +using Printf + + +function md_length_to_latex(def, reference) + if occursin("%", def) + _def = tryparse(Float64, replace(def, "%" => "")) + _def == nothing && return def + perc = round(_def / 100, digits = 2) + return "$perc$reference" + end + return def end function formatfigures(chunk, docformat::JMarkdown2HTML) @@ -244,69 +309,6 @@ function formatfigures(chunk, docformat::JMarkdown2HTML) 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", - ), -) - -struct 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", - ), -) - -struct 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 md_length_to_latex(def, reference) - if occursin("%", def) - _def = tryparse(Float64, replace(def, "%" => "")) - _def == nothing && return def - perc = round(_def / 100, digits = 2) - return "$perc$reference" - end - return def -end - function formatfigures(chunk, docformat::Union{Tex,JMarkdown2tex}) fignames = chunk.figures caption = chunk.options[:fig_cap] @@ -423,7 +425,7 @@ function formatfigures(chunk, docformat::GitHubMarkdown) end function formatfigures(chunk, docformat::Hugo) - relpath = docformat.uglyURLs ? "" : ".." + relpath = docformat.formatdict[:uglyURLs] ? "" : ".." function format_shortcode(index_and_fig) index, fig = index_and_fig if index > 1 @@ -510,20 +512,3 @@ function formatfigures(chunk, docformat::AsciiDoc) return result end end - -# Add new supported formats here -const formats = Dict( - "tex" => tex, - "texminted" => texminted, - "pandoc" => pandoc, - "pandoc2html" => pdoc2html, - "pandoc2pdf" => pandoc, - "md2pdf" => md2tex, - "github" => github, - "hugo" => hugo, - "multimarkdown" => multimarkdown, - "rst" => rst, - "asciidoc" => adoc, - "md2html" => md2html, - "md2tex" => md2tex, -) diff --git a/src/run.jl b/src/run.jl index 47f296b..8e07b26 100644 --- a/src/run.jl +++ b/src/run.jl @@ -45,7 +45,7 @@ function run_doc( # cache :all, :user, :off, :refresh doc.doctype = isnothing(doctype) ? (doctype = detect_doctype(doc.source)) : doctype - doc.format = deepcopy(formats[doctype]) + doc.format = deepcopy(FORMATS[doctype]) doc.cwd = get_cwd(doc, out_path) isdir(doc.cwd) || mkpath(doc.cwd) diff --git a/test/figureformatter_test.jl b/test/figureformatter_test.jl index 0a54ae5..26facec 100644 --- a/test/figureformatter_test.jl +++ b/test/figureformatter_test.jl @@ -1,5 +1,5 @@ -using Weave -using Test +test_formatfigures(chunk, format) = Weave.formatfigures(chunk, Weave.FORMATS[format]) + # Make a dummy codehunk with figure chunk = Weave.CodeChunk("plot(x)", 1, 1, "", Dict()) @@ -7,43 +7,49 @@ options = merge(Weave.get_chunk_defaults(), chunk.options) merge!(chunk.options, options) chunk.figures = ["figs/figures_plot1.png"] -@test Weave.formatfigures(chunk, Weave.md2tex) == "\\includegraphics{figs/figures_plot1.png}\n" -@test Weave.formatfigures(chunk, Weave.tex) == "\\includegraphics{figs/figures_plot1.png}\n" -@test Weave.formatfigures(chunk, Weave.texminted) == "\\includegraphics{figs/figures_plot1.png}\n" -@test Weave.formatfigures(chunk, Weave.pandoc) == "![](figs/figures_plot1.png)\\ \n\n" -@test Weave.formatfigures(chunk, Weave.github) == "![](figs/figures_plot1.png)\n" -@test Weave.formatfigures(chunk, Weave.hugo) == "{{< figure src=\"../figs/figures_plot1.png\" >}}" -@test Weave.formatfigures(chunk, Weave.multimarkdown) == "![][figs/figures_plot1.png]\n\n[figs/figures_plot1.png]: figs/figures_plot1.png \n" -@test Weave.formatfigures(chunk, Weave.md2html) == "\n" + +@test test_formatfigures(chunk, "md2tex") == "\\includegraphics{figs/figures_plot1.png}\n" +@test test_formatfigures(chunk, "tex") == "\\includegraphics{figs/figures_plot1.png}\n" +@test test_formatfigures(chunk, "texminted") == "\\includegraphics{figs/figures_plot1.png}\n" +@test test_formatfigures(chunk, "pandoc") == "![](figs/figures_plot1.png)\\ \n\n" +@test test_formatfigures(chunk, "github") == "![](figs/figures_plot1.png)\n" +@test test_formatfigures(chunk, "hugo") == "{{< figure src=\"../figs/figures_plot1.png\" >}}" +@test test_formatfigures(chunk, "multimarkdown") == "![][figs/figures_plot1.png]\n\n[figs/figures_plot1.png]: figs/figures_plot1.png \n" +@test test_formatfigures(chunk, "md2html") == "\n" + chunk.options[:out_width] = "100%" -@test Weave.formatfigures(chunk, Weave.adoc) == "image::figs/figures_plot1.png[width=100%]\n" -@test Weave.formatfigures(chunk, Weave.rst) == ".. image:: figs/figures_plot1.png\n :width: 100%\n\n" +@test test_formatfigures(chunk, "asciidoc") == "image::figs/figures_plot1.png[width=100%]\n" +@test test_formatfigures(chunk, "rst") == ".. image:: figs/figures_plot1.png\n :width: 100%\n\n" + chunk.options[:fig_cap] = "Nice plot" -@test Weave.formatfigures(chunk, Weave.tex) == "\\begin{figure}[!h]\n\\center\n\\includegraphics[width=1.0\\linewidth]{figs/figures_plot1.png}\n\\caption{Nice plot}\n\\end{figure}\n" -@test Weave.formatfigures(chunk, Weave.pandoc) == "![Nice plot](figs/figures_plot1.png){width=100%}\n" -@test Weave.formatfigures(chunk, Weave.md2tex) == "\\begin{figure}[!h]\n\\center\n\\includegraphics[width=1.0\\linewidth]{figs/figures_plot1.png}\n\\caption{Nice plot}\n\\end{figure}\n" -@test Weave.formatfigures(chunk, Weave.md2html) == "
\n\n
Nice plot
\n
\n" -@test Weave.formatfigures(chunk, Weave.rst) == ".. figure:: figs/figures_plot1.png\n :width: 100%\n\n Nice plot\n\n" -@test Weave.formatfigures(chunk, Weave.multimarkdown) == "![Nice plot][figs/figures_plot1.png]\n\n[figs/figures_plot1.png]: figs/figures_plot1.png width=100%\n" -@test Weave.formatfigures(chunk, Weave.adoc) == "image::figs/figures_plot1.png[width=100%,title=\"Nice plot\"]" +@test test_formatfigures(chunk, "tex") == "\\begin{figure}[!h]\n\\center\n\\includegraphics[width=1.0\\linewidth]{figs/figures_plot1.png}\n\\caption{Nice plot}\n\\end{figure}\n" +@test test_formatfigures(chunk, "pandoc") == "![Nice plot](figs/figures_plot1.png){width=100%}\n" +@test test_formatfigures(chunk, "md2tex") == "\\begin{figure}[!h]\n\\center\n\\includegraphics[width=1.0\\linewidth]{figs/figures_plot1.png}\n\\caption{Nice plot}\n\\end{figure}\n" +@test test_formatfigures(chunk, "md2html") == "
\n\n
Nice plot
\n
\n" +@test test_formatfigures(chunk, "rst") == ".. figure:: figs/figures_plot1.png\n :width: 100%\n\n Nice plot\n\n" +@test test_formatfigures(chunk, "multimarkdown") == "![Nice plot][figs/figures_plot1.png]\n\n[figs/figures_plot1.png]: figs/figures_plot1.png width=100%\n" +@test test_formatfigures(chunk, "asciidoc") == "image::figs/figures_plot1.png[width=100%,title=\"Nice plot\"]" + chunk.options[:label] = "somefig" -@test Weave.formatfigures(chunk, Weave.pandoc) == "![Nice plot](figs/figures_plot1.png){width=100% #fig:somefig}\n" -@test Weave.formatfigures(chunk, Weave.tex) == "\\begin{figure}[!h]\n\\center\n\\includegraphics[width=1.0\\linewidth]{figs/figures_plot1.png}\n\\caption{Nice plot}\n\\label{fig:somefig}\n\\end{figure}\n" -@test Weave.formatfigures(chunk, Weave.tex) == Weave.formatfigures(chunk, Weave.md2tex) +@test test_formatfigures(chunk, "pandoc") == "![Nice plot](figs/figures_plot1.png){width=100% #fig:somefig}\n" +@test test_formatfigures(chunk, "tex") == "\\begin{figure}[!h]\n\\center\n\\includegraphics[width=1.0\\linewidth]{figs/figures_plot1.png}\n\\caption{Nice plot}\n\\label{fig:somefig}\n\\end{figure}\n" + chunk.options[:label] = nothing chunk.options[:fig_cap] = nothing chunk.options[:fig_env] = "center" chunk.options[:fig_pos] = "" -@test Weave.formatfigures(chunk, Weave.tex) == "\\begin{center}\n\\includegraphics[width=1.0\\linewidth]{figs/figures_plot1.png}\n\\end{center}\n" +@test test_formatfigures(chunk, "tex") == "\\begin{center}\n\\includegraphics[width=1.0\\linewidth]{figs/figures_plot1.png}\n\\end{center}\n" + chunk.options[:out_width] = "50%" chunk.options[:out_height] = "75 %" -@test Weave.formatfigures(chunk, Weave.tex) == "\\begin{center}\n\\includegraphics[width=0.5\\linewidth,height=0.75\\paperheight]{figs/figures_plot1.png}\n\\end{center}\n" +@test test_formatfigures(chunk, "tex") == "\\begin{center}\n\\includegraphics[width=0.5\\linewidth,height=0.75\\paperheight]{figs/figures_plot1.png}\n\\end{center}\n" + chunk.options[:out_width] = "A%" chunk.options[:out_height] = "0.5\\textwidth" -@test Weave.formatfigures(chunk, Weave.tex) == "\\begin{center}\n\\includegraphics[width=A%,height=0.5\\textwidth]{figs/figures_plot1.png}\n\\end{center}\n" +@test test_formatfigures(chunk, "tex") == "\\begin{center}\n\\includegraphics[width=A%,height=0.5\\textwidth]{figs/figures_plot1.png}\n\\end{center}\n" diff --git a/test/formatter_test.jl b/test/formatter_test.jl index de4a379..5093752 100644 --- a/test/formatter_test.jl +++ b/test/formatter_test.jl @@ -11,11 +11,11 @@ Test rendering \$\alpha\$ dchunk = Weave.DocChunk(content, 1, 1) -pformat = Weave.formats["github"] +pformat = Weave.FORMATS["github"] f = Weave.format_chunk(dchunk, pformat) @test f == content -docformat = Weave.formats["md2html"] +docformat = Weave.FORMATS["md2html"] f_check = "

Test chunk

\n

Test rendering \$\alpha\$

\n" f = Weave.format_chunk(dchunk, docformat) @test f_check == f @@ -88,7 +88,7 @@ content = """ α """ chunk = Weave.DocChunk(content, 1, 1) -fmt = deepcopy(Weave.formats["md2tex"]) +fmt = deepcopy(Weave.FORMATS["md2tex"]) f = Weave.format_chunk(chunk, fmt) @test f == "\\section{Test chunk}\n\\ensuremath{\\alpha}\n\n" From aa63b20e7cd88a7ecda15197d503e7a00e1e1d31 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Mon, 25 May 2020 22:39:59 +0900 Subject: [PATCH 2/4] remove unncessary :doctype field --- src/formats.jl | 11 ----------- src/run.jl | 4 ++-- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/formats.jl b/src/formats.jl index 551df24..87e16e4 100644 --- a/src/formats.jl +++ b/src/formats.jl @@ -39,7 +39,6 @@ register_format!("md2html", JMarkdown2HTML( "text/plain", ], :extension => "html", - :doctype => "md2html", ), )) @@ -61,7 +60,6 @@ register_format!("pandoc2html", Pandoc2HTML( "text/markdown", "text/plain", ], - :doctype => "pandoc2html", ), )) @@ -88,7 +86,6 @@ let t = JMarkdown2tex( "text/markdown", "text/plain", ], - :doctype => "md2tex", :keep_unicode => false, ) ) @@ -111,7 +108,6 @@ register_format!("tex", Tex( :out_width => "\\linewidth", :fig_env => "figure", :fig_pos => "htpb", - :doctype => "tex", :mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"], :keep_unicode => false, ), @@ -133,7 +129,6 @@ register_format!("texminted", Tex( :out_width => "\\linewidth", :fig_env => "figure", :fig_pos => "htpb", - :doctype => "texminted", :mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"], :keep_unicode => false, ), @@ -157,7 +152,6 @@ let p = Pandoc( # 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", ), ) register_format!("pandoc", p) @@ -180,7 +174,6 @@ register_format!("github", GitHubMarkdown( :extension => "md", :mimetypes => ["image/png", "image/svg+xml", "image/jpg", "text/markdown", "text/plain"], - :doctype => "github", ), )) @@ -194,7 +187,6 @@ register_format!("hugo", Hugo( :outputend => "````\n\n", :fig_ext => ".png", :extension => "md", - :doctype => "hugo", :uglyURLs => false, # if `false`, prepend figure path by `..` ), )) @@ -209,7 +201,6 @@ register_format!("multimarkdown", MultiMarkdown( :outputend => "````\n\n", :fig_ext => ".png", :extension => "md", - :doctype => "github", ), )) @@ -229,7 +220,6 @@ register_format!("rst", Rest( :fig_ext => ".png", :extension => "rst", :out_width => "15 cm", - :doctype => "rst", ), )) @@ -249,7 +239,6 @@ register_format!("asciidoc", AsciiDoc( :fig_ext => ".png", :extension => "txt", :out_width => "600", - :doctype => "asciidoc", ), )) diff --git a/src/run.jl b/src/run.jl index 8e07b26..f853fb0 100644 --- a/src/run.jl +++ b/src/run.jl @@ -136,7 +136,7 @@ end function run_chunk(chunk::CodeChunk, doc, report, mod) result = eval_chunk(chunk, report, mod) - occursin("2html", report.formatdict[:doctype]) && (embed_figures!(result, report.cwd)) + occursin("2html", doc.doctype) && (embed_figures!(result, report.cwd)) return result end @@ -188,7 +188,7 @@ function run_inline(inline::InlineCode, doc::WeaveDoc, report::Report, SandBox:: merge!(chunk.options, options) chunks = eval_chunk(chunk, report, SandBox) - occursin("2html", report.formatdict[:doctype]) && (embed_figures!(chunks, report.cwd)) + occursin("2html", doc.doctype) && (embed_figures!(chunks, report.cwd)) output = chunks[1].output endswith(output, "\n") && (output = output[1:end-1]) From 96de887308258fffd8996a8e71fad9177eeb4c34 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Tue, 26 May 2020 10:44:30 +0900 Subject: [PATCH 3/4] basic assertion --- src/formats.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/formats.jl b/src/formats.jl index 87e16e4..4908e27 100644 --- a/src/formats.jl +++ b/src/formats.jl @@ -9,6 +9,7 @@ const FORMATS = Dict{String,WeaveFormat}() register_format!(format_name::AbstractString, format::WeaveFormat) = push!(FORMATS, format_name => format) macro define_format(type_name, supertype = WeaveFormat) + @assert supertype <: WeaveFormat "$type_name should be subtype of WeaveFormat" return quote struct $(type_name) <: $(supertype) description::String From 788f9260674d5eadb3ced24cb56cdf10d31b5617 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Sat, 30 May 2020 21:16:03 +0900 Subject: [PATCH 4/4] move description field into `formatdict` --- src/Weave.jl | 2 +- src/formats.jl | 341 +++++++++++++++++++++++-------------------------- 2 files changed, 160 insertions(+), 183 deletions(-) diff --git a/src/Weave.jl b/src/Weave.jl index e74e653..7bb8e9f 100644 --- a/src/Weave.jl +++ b/src/Weave.jl @@ -31,7 +31,7 @@ take2string!(io) = String(take!(io)) List supported output formats """ -list_out_formats(io = stdout) = for (k, v) in FORMATS; println(io, string(k, ": ", v.description)); end +list_out_formats(io = stdout) = for (k, v) in FORMATS; println(io, string(k, ": ", v.formatdict[:description])); end """ tangle(source::AbstractString; kwargs...) diff --git a/src/formats.jl b/src/formats.jl index 4908e27..41a4d71 100644 --- a/src/formats.jl +++ b/src/formats.jl @@ -1,160 +1,147 @@ # TODO: -# - 1. turn each `.formatdict` value into fields -# - 2. do assertions for definition mandatory fields in `@define_format` macro -# - 3. export as public API +# - 1. do assertions for definition mandatory fields in `@define_format` macro +# - 2. implement fallback format/rendering functions in format.jl +# - 3. export this as public API abstract type WeaveFormat end const FORMATS = Dict{String,WeaveFormat}() -register_format!(format_name::AbstractString, format::WeaveFormat) = push!(FORMATS, format_name => format) -macro define_format(type_name, supertype = WeaveFormat) - @assert supertype <: WeaveFormat "$type_name should be subtype of WeaveFormat" +macro define_format(type_name, supertype = :WeaveFormat) return quote + @assert $(supertype) <: WeaveFormat "$($(supertype)) should be subtype of WeaveFormat" struct $(type_name) <: $(supertype) - description::String formatdict::Dict{Symbol,Any} end end end - +# TODO: do some assertion for necessary fields of `formatdict` +register_format!(format_name::AbstractString, format::WeaveFormat) = push!(FORMATS, format_name => format) # HTML # ---- @define_format JMarkdown2HTML -register_format!("md2html", JMarkdown2HTML( - "Julia markdown to html", - Dict( - :codestart => "\n", - :codeend => "\n", - :outputstart => "
",
-        :outputend => "
\n", - :fig_ext => ".png", - :mimetypes => [ - "image/png", - "image/jpg", - "image/svg+xml", - "text/html", - "text/markdown", - "text/plain", - ], - :extension => "html", - ), -)) +register_format!("md2html", JMarkdown2HTML(Dict( + :description => "Julia markdown to html", + :codestart => "\n", + :codeend => "\n", + :outputstart => "
",
+    :outputend => "
\n", + :fig_ext => ".png", + :mimetypes => [ + "image/png", + "image/jpg", + "image/svg+xml", + "text/html", + "text/markdown", + "text/plain", + ], + :extension => "html", +))) @define_format Pandoc2HTML -register_format!("pandoc2html", Pandoc2HTML( - "Markdown to HTML (requires Pandoc 2)", - Dict( - :codestart => "\n", - :codeend => "\n", - :outputstart => "\n", - :outputend => "\n", - :fig_ext => ".png", - :extension => "md", - :mimetypes => [ - "image/png", - "image/svg+xml", - "image/jpg", - "text/html", - "text/markdown", - "text/plain", - ], - ), -)) +register_format!("pandoc2html", Pandoc2HTML(Dict( + :description => "Markdown to HTML (requires Pandoc 2)", + :codestart => "\n", + :codeend => "\n", + :outputstart => "\n", + :outputend => "\n", + :fig_ext => ".png", + :extension => "md", + :mimetypes => [ + "image/png", + "image/svg+xml", + "image/jpg", + "text/html", + "text/markdown", + "text/plain", + ], +))) # PDF and Tex # ----------- @define_format JMarkdown2tex -let t = JMarkdown2tex( - "Julia markdown to latex", - Dict( - :codestart => "", - :codeend => "", - :outputstart => "\\begin{lstlisting}", - :outputend => "\\end{lstlisting}\n", - :fig_ext => ".pdf", - :extension => "tex", - :out_width => "\\linewidth", - :mimetypes => [ - "application/pdf", - "image/png", - "image/jpg", - "text/latex", - "text/markdown", - "text/plain", - ], - :keep_unicode => false, - ) - ) +let t = JMarkdown2tex(Dict( + :description => "Julia markdown to latex", + :codestart => "", + :codeend => "", + :outputstart => "\\begin{lstlisting}", + :outputend => "\\end{lstlisting}\n", + :fig_ext => ".pdf", + :extension => "tex", + :out_width => "\\linewidth", + :mimetypes => [ + "application/pdf", + "image/png", + "image/jpg", + "text/latex", + "text/markdown", + "text/plain", + ], + :keep_unicode => false, + )) register_format!("md2pdf", t) register_format!("md2tex", t) end @define_format Tex -register_format!("tex", Tex( - "Latex with custom code environments", - Dict( - :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", - :mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"], - :keep_unicode => false, - ), -)) -register_format!("texminted", Tex( - "Latex using minted for highlighting", - Dict( - :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]{jlcon}", - :termend => "\\end{minted}", - :fig_ext => ".pdf", - :extension => "tex", - :out_width => "\\linewidth", - :fig_env => "figure", - :fig_pos => "htpb", - :mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"], - :keep_unicode => false, - ), -)) +register_format!("tex", Tex(Dict( + :description => "Latex with custom code environments", + :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", + :mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"], + :keep_unicode => false, +))) +register_format!("texminted", Tex(Dict( + :description => "Latex using minted for highlighting", + :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]{jlcon}", + :termend => "\\end{minted}", + :fig_ext => ".pdf", + :extension => "tex", + :out_width => "\\linewidth", + :fig_env => "figure", + :fig_pos => "htpb", + :mimetypes => ["application/pdf", "image/png", "text/latex", "text/plain"], + :keep_unicode => false, +))) # pandoc # ------ @define_format Pandoc -let p = Pandoc( - "Pandoc markdown", - Dict( - :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"], - ), - ) +let p = Pandoc(Dict( + :description => "Pandoc markdown", + :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"], + )) register_format!("pandoc", p) register_format!("pandoc2pdf", p) end @@ -164,65 +151,57 @@ end # -------- @define_format GitHubMarkdown -register_format!("github", GitHubMarkdown( - "GitHub markdown", - Dict( - :codestart => "````julia", - :codeend => "````\n\n", - :outputstart => "````", - :outputend => "````\n\n", - :fig_ext => ".png", - :extension => "md", - :mimetypes => - ["image/png", "image/svg+xml", "image/jpg", "text/markdown", "text/plain"], - ), -)) +register_format!("github", GitHubMarkdown(Dict( + :description => "GitHub markdown", + :codestart => "````julia", + :codeend => "````\n\n", + :outputstart => "````", + :outputend => "````\n\n", + :fig_ext => ".png", + :extension => "md", + :mimetypes => + ["image/png", "image/svg+xml", "image/jpg", "text/markdown", "text/plain"], +))) @define_format Hugo -register_format!("hugo", Hugo( - "Hugo markdown (using shortcodes)", - Dict( - :codestart => "````julia", - :codeend => "````\n\n", - :outputstart => "````", - :outputend => "````\n\n", - :fig_ext => ".png", - :extension => "md", - :uglyURLs => false, # if `false`, prepend figure path by `..` - ), -)) +register_format!("hugo", Hugo(Dict( + :description => "Hugo markdown (using shortcodes)", + :codestart => "````julia", + :codeend => "````\n\n", + :outputstart => "````", + :outputend => "````\n\n", + :fig_ext => ".png", + :extension => "md", + :uglyURLs => false, # if `false`, prepend figure path by `..` +))) @define_format MultiMarkdown -register_format!("multimarkdown", MultiMarkdown( - "MultiMarkdown", - Dict( - :codestart => "````julia", - :codeend => "````\n\n", - :outputstart => "````", - :outputend => "````\n\n", - :fig_ext => ".png", - :extension => "md", - ), -)) +register_format!("multimarkdown", MultiMarkdown(Dict( + :description => "MultiMarkdown", + :codestart => "````julia", + :codeend => "````\n\n", + :outputstart => "````", + :outputend => "````\n\n", + :fig_ext => ".png", + :extension => "md", +))) # Rest # ---- @define_format Rest -register_format!("rst", Rest( - "reStructuredText and Sphinx", - Dict( - :codestart => ".. code-block:: julia\n", - :codeend => "\n\n", - :outputstart => "::\n", - :outputend => "\n\n", - :indent => 4, - :fig_ext => ".png", - :extension => "rst", - :out_width => "15 cm", - ), -)) +register_format!("rst", Rest(Dict( + :description => "reStructuredText and Sphinx", + :codestart => ".. code-block:: julia\n", + :codeend => "\n\n", + :outputstart => "::\n", + :outputend => "\n\n", + :indent => 4, + :fig_ext => ".png", + :extension => "rst", + :out_width => "15 cm", +))) # Ansii @@ -230,18 +209,16 @@ register_format!("rst", Rest( # asciidoc -b html5 -a source-highlighter=pygments ... @define_format AsciiDoc -register_format!("asciidoc", AsciiDoc( - "AsciiDoc", - Dict( - :codestart => "[source,julia]\n--------------------------------------", - :codeend => "--------------------------------------\n\n", - :outputstart => "--------------------------------------", - :outputend => "--------------------------------------\n\n", - :fig_ext => ".png", - :extension => "txt", - :out_width => "600", - ), -)) +register_format!("asciidoc", AsciiDoc(Dict( + :description => "AsciiDoc", + :codestart => "[source,julia]\n--------------------------------------", + :codeend => "--------------------------------------\n\n", + :outputstart => "--------------------------------------", + :outputend => "--------------------------------------\n\n", + :fig_ext => ".png", + :extension => "txt", + :out_width => "600", +))) # TODO: move this functions where used