2018-01-07 19:19:59 +01:00
|
|
|
import Mustache, Highlights
|
|
|
|
import .Markdown2HTML
|
2017-05-12 15:12:05 +02:00
|
|
|
using Compat
|
2016-12-13 12:26:34 +01:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2016-12-13 14:30:23 +01:00
|
|
|
docformat.formatdict[:cwd] = doc.cwd #pass wd to figure formatters
|
2016-12-15 14:49:21 +01:00
|
|
|
docformat.formatdict[:theme] = doc.highlight_theme
|
2016-12-13 12:26:34 +01:00
|
|
|
|
2016-12-14 20:50:29 +01:00
|
|
|
#strip header
|
|
|
|
if isa(doc.chunks[1], DocChunk)
|
2017-03-14 14:34:27 +01:00
|
|
|
if contains(doc.doctype, "md2")
|
|
|
|
doc.chunks[1] = strip_header(doc.chunks[1])
|
|
|
|
end
|
2016-12-14 20:50:29 +01:00
|
|
|
end
|
|
|
|
|
2016-12-13 12:26:34 +01:00
|
|
|
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
|
2016-12-13 14:43:37 +01:00
|
|
|
rendered = render_doc(formatted, doc, doc.format)
|
2016-12-13 12:26:34 +01:00
|
|
|
|
|
|
|
return rendered
|
|
|
|
end
|
|
|
|
|
|
|
|
"""
|
|
|
|
render_doc(formatted::AbstractString, format)
|
|
|
|
|
|
|
|
Render formatted document to a template
|
|
|
|
"""
|
2016-12-13 14:43:37 +01:00
|
|
|
function render_doc(formatted, doc::WeaveDoc, format)
|
2016-12-13 12:26:34 +01:00
|
|
|
return formatted
|
|
|
|
end
|
|
|
|
|
2016-12-15 14:49:21 +01:00
|
|
|
function stylesheet(m::MIME, theme)
|
2016-12-13 12:26:34 +01:00
|
|
|
buf = PipeBuffer()
|
2016-12-15 14:49:21 +01:00
|
|
|
Highlights.stylesheet(buf, m, theme)
|
2016-12-13 12:26:34 +01:00
|
|
|
flush(buf)
|
2016-12-14 15:07:04 +01:00
|
|
|
style = readstring(buf)
|
2016-12-13 12:26:34 +01:00
|
|
|
close(buf)
|
2016-12-14 15:07:04 +01:00
|
|
|
return style
|
|
|
|
end
|
2016-12-13 12:26:34 +01:00
|
|
|
|
2016-12-14 15:07:04 +01:00
|
|
|
function render_doc(formatted, doc::WeaveDoc, format::JMarkdown2HTML)
|
2016-12-15 14:49:21 +01:00
|
|
|
css = stylesheet(MIME("text/html"), doc.highlight_theme)
|
2016-12-14 23:07:56 +01:00
|
|
|
title, author, date = get_titleblock(doc)
|
2016-12-13 14:52:33 +01:00
|
|
|
path, wsource = splitdir(abspath(doc.source))
|
|
|
|
wversion = string(Pkg.installed("Weave"))
|
|
|
|
wtime = string(Date(now()))
|
|
|
|
|
2016-12-15 14:49:21 +01:00
|
|
|
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
|
2016-12-13 12:26:34 +01:00
|
|
|
|
2016-12-13 13:20:40 +01:00
|
|
|
return Mustache.render(template, themecss = theme_css,
|
2016-12-13 14:52:33 +01:00
|
|
|
highlightcss = css, body = formatted, header_script = doc.header_script,
|
2016-12-13 19:51:34 +01:00
|
|
|
source = wsource, wtime = wtime, wversion = wversion,
|
2016-12-14 23:07:56 +01:00
|
|
|
title = title, author = author, date = date)
|
2016-12-13 19:51:34 +01:00
|
|
|
end
|
|
|
|
|
2016-12-14 15:07:04 +01:00
|
|
|
function render_doc(formatted, doc::WeaveDoc, format::JMarkdown2tex)
|
2016-12-15 14:49:21 +01:00
|
|
|
highlight = stylesheet(MIME("text/latex"), doc.highlight_theme)
|
2016-12-14 23:07:56 +01:00
|
|
|
|
|
|
|
title, author, date = get_titleblock(doc)
|
|
|
|
|
2016-12-14 15:07:04 +01:00
|
|
|
path, wsource = splitdir(abspath(doc.source))
|
|
|
|
wversion = string(Pkg.installed("Weave"))
|
|
|
|
wtime = string(Date(now()))
|
2016-12-15 14:49:21 +01:00
|
|
|
|
|
|
|
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
|
2016-12-14 15:07:04 +01:00
|
|
|
|
|
|
|
return Mustache.render(template, body = formatted,
|
|
|
|
highlight = highlight,
|
2016-12-14 23:07:56 +01:00
|
|
|
title = title, author = author, date = date)
|
2016-12-14 15:07:04 +01:00
|
|
|
end
|
|
|
|
|
2016-12-14 23:07:56 +01:00
|
|
|
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
|
2016-12-13 12:26:34 +01:00
|
|
|
end
|
|
|
|
|
2016-12-14 20:50:29 +01:00
|
|
|
function strip_header(chunk::DocChunk)
|
2016-12-26 23:59:15 +01:00
|
|
|
if ismatch(r"^---$(?<header>.+)^---$"ms, chunk.content[1].content)
|
|
|
|
chunk.content[1].content = lstrip(replace(chunk.content[1].content, r"^---$(?<header>.+)^---$"ms, ""))
|
2016-12-15 11:39:41 +01:00
|
|
|
end
|
2016-12-14 20:50:29 +01:00
|
|
|
return chunk
|
|
|
|
end
|
|
|
|
|
2016-12-13 12:26:34 +01:00
|
|
|
function format_chunk(chunk::DocChunk, formatdict, docformat)
|
2016-12-26 23:59:15 +01:00
|
|
|
return join([format_inline(c) for c in chunk.content], "")
|
|
|
|
end
|
|
|
|
|
2017-01-04 18:56:28 +01:00
|
|
|
function format_inline(inline::InlineText)
|
2016-12-26 23:59:15 +01:00
|
|
|
return inline.content
|
|
|
|
end
|
|
|
|
|
|
|
|
function format_inline(inline::InlineCode)
|
|
|
|
isempty(inline.rich_output) || return inline.rich_output
|
|
|
|
isempty(inline.figures) || return inline.figures[end]
|
|
|
|
isempty(inline.output) || return inline.output
|
2016-12-13 12:26:34 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function format_chunk(chunk::DocChunk, formatdict, docformat::JMarkdown2HTML)
|
2017-01-04 18:56:28 +01:00
|
|
|
text = format_chunk(chunk, formatdict, nothing)
|
2017-05-12 15:12:05 +02:00
|
|
|
#invokelatest seems to be needed here
|
|
|
|
#to fix "invalid age range" on 0.6 #21653
|
2017-12-31 13:02:28 +01:00
|
|
|
m = Compat.invokelatest(Base.Markdown.parse, text)
|
2018-01-07 19:19:59 +01:00
|
|
|
|
|
|
|
return string(Markdown2HTML.html(m))
|
2016-12-13 12:26:34 +01:00
|
|
|
end
|
|
|
|
|
2016-12-15 21:14:18 +01:00
|
|
|
|
2016-12-14 15:07:04 +01:00
|
|
|
|
|
|
|
function format_chunk(chunk::DocChunk, formatdict, docformat::JMarkdown2tex)
|
2017-01-04 18:56:28 +01:00
|
|
|
text = format_chunk(chunk, formatdict, nothing)
|
2016-12-26 23:59:15 +01:00
|
|
|
m = Base.Markdown.parse(text)
|
2016-12-14 15:07:04 +01:00
|
|
|
return Base.Markdown.latex(m)
|
|
|
|
end
|
2016-12-13 12:26:34 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2016-12-13 14:30:23 +01:00
|
|
|
chunk.content = format_code(chunk.content, docformat)
|
|
|
|
|
2016-12-13 12:26:34 +01:00
|
|
|
if !chunk.options[:eval]
|
|
|
|
if chunk.options[:echo]
|
2017-03-13 14:05:07 +01:00
|
|
|
result = "$(formatdict[:codestart])\n$(chunk.content)$(formatdict[:codeend])"
|
2016-12-13 12:26:34 +01:00
|
|
|
return result
|
|
|
|
else
|
|
|
|
r = ""
|
|
|
|
return r
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if chunk.options[:term]
|
2016-12-13 13:20:40 +01:00
|
|
|
result = format_termchunk(chunk, formatdict, docformat)
|
2016-12-13 12:26:34 +01:00
|
|
|
else
|
|
|
|
|
|
|
|
if chunk.options[:echo]
|
|
|
|
#Convert to output format and highlight (html, tex...) if needed
|
2017-03-13 14:05:07 +01:00
|
|
|
result = "$(formatdict[:codestart])$(chunk.content)$(formatdict[:codeend])\n"
|
2016-12-13 12:26:34 +01:00
|
|
|
else
|
|
|
|
result = ""
|
|
|
|
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]
|
2018-01-03 14:35:47 +01:00
|
|
|
chunk.output = "\n" * wraplines(chunk.output, chunk.options[:line_width])
|
|
|
|
chunk.output = format_output(chunk.output, docformat)
|
2016-12-19 17:42:00 +01:00
|
|
|
else
|
2018-01-03 14:35:47 +01:00
|
|
|
chunk.output = "\n" * rstrip(chunk.output)
|
|
|
|
chunk.output = format_output(chunk.output, docformat)
|
2016-12-13 12:26:34 +01:00
|
|
|
end
|
2018-01-03 16:23:57 +01:00
|
|
|
|
2016-12-13 12:26:34 +01:00
|
|
|
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
|
|
|
|
|
2016-12-14 15:07:04 +01:00
|
|
|
function format_code(result::AbstractString, docformat::JMarkdown2tex)
|
2018-01-03 16:23:57 +01:00
|
|
|
#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
|
|
|
|
return "\\begin{minted}[mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}\n$result\n\\end{minted}\n"
|
2016-12-14 15:07:04 +01:00
|
|
|
end
|
|
|
|
|
2016-12-13 12:26:34 +01:00
|
|
|
function format_code(result::AbstractString, docformat::JMarkdown2HTML)
|
|
|
|
buf = PipeBuffer()
|
2016-12-15 14:49:21 +01:00
|
|
|
Highlights.highlight(buf, MIME("text/html"), strip(result),
|
|
|
|
Highlights.Lexers.JuliaLexer, docformat.formatdict[:theme])
|
2016-12-13 12:26:34 +01:00
|
|
|
flush(buf)
|
|
|
|
highlighted = readstring(buf)
|
|
|
|
close(buf)
|
|
|
|
return highlighted
|
|
|
|
end
|
|
|
|
|
2018-01-04 17:00:01 +01:00
|
|
|
function format_code(result::AbstractString, docformat::Pandoc2HTML)
|
|
|
|
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
|
|
|
|
|
|
|
|
|
2016-12-13 13:20:40 +01:00
|
|
|
function format_termchunk(chunk, formatdict, docformat)
|
2016-12-13 12:26:34 +01:00
|
|
|
if chunk.options[:echo] && chunk.options[:results] != "hidden"
|
|
|
|
result = "$(formatdict[:termstart])$(chunk.output)\n" * "$(formatdict[:termend])\n"
|
2016-12-13 13:20:40 +01:00
|
|
|
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)
|
2016-12-13 12:26:34 +01:00
|
|
|
else
|
|
|
|
result = ""
|
|
|
|
end
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
|
2018-01-04 17:00:01 +01:00
|
|
|
function format_termchunk(chunk, formatdict, docformat::Pandoc2HTML)
|
|
|
|
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
|
|
|
|
|
|
|
|
|
2016-12-16 19:18:37 +01:00
|
|
|
function format_termchunk(chunk, formatdict, docformat::JMarkdown2tex)
|
|
|
|
if chunk.options[:echo] && chunk.options[:results] != "hidden"
|
2018-01-03 16:23:57 +01:00
|
|
|
#buf = PipeBuffer()
|
|
|
|
#Highlights.highlight(buf, MIME("text/latex"), strip(chunk.output), Highlights.Lexers.JuliaConsoleLexer)
|
|
|
|
#flush(buf)
|
|
|
|
#result = readstring(buf)
|
|
|
|
#close(buf)
|
2018-01-03 19:31:24 +01:00
|
|
|
result = strip(chunk.output)
|
2018-01-03 16:23:57 +01:00
|
|
|
return "\\begin{minted}[mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}\n$result\n\\end{minted}\n"
|
2016-12-16 19:18:37 +01:00
|
|
|
else
|
|
|
|
result = ""
|
|
|
|
end
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
|
2016-12-13 12:26:34 +01:00
|
|
|
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
|