Skip to content

Commit

Permalink
Refactor duplicated code
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobjpeters committed Jun 9, 2024
1 parent 82286b3 commit 78eac7c
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 142 deletions.
41 changes: 41 additions & 0 deletions src/rendering/pdf_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,45 @@ Crop a PDF file using Ghostscript. This alters the crop box but does not
actually remove elements.
"""
function crop_pdf(path::String; margin = _PDFCROP_DEFAULT_MARGINS[])
# if pdf_num_pages("temp.pdf") > 1
# @warn("The PDF has more than 1 page! Choosing the first page.")
# end

# Generate the cropping margins
bbox = get_pdf_bbox(path)
crop_box = (
bbox[1] - margin[1],
bbox[2] - margin[2],
bbox[3] + margin[3],
bbox[4] + margin[4]
)
crop_cmd = join(crop_box, " ")


out = Pipe()
err = Pipe()
try
redirect_stderr(err) do
redirect_stdout(out) do
Ghostscript_jll.gs() do gs_exe
run(`$gs_exe -o temp_cropped.pdf -sDEVICE=pdfwrite -c "[/CropBox [$crop_cmd]" -c "/PAGES pdfmark" -f $path`)
end
end
end
catch e
finally
close(out.in)
close(err.in)
if !isfile("temp_cropped.pdf")
println("`gs` failed to crop the PDF!")
println("Files in temp directory are:\n" * join(readdir(), ','))
printstyled("Stdout\n", bold=true, color = :blue)
println(read(out, String))
printstyled("Stderr\n", bold=true, color = :red)
println(read(err, String))
error()
end
end

return isfile("temp_cropped.pdf") ? read("temp_cropped.pdf", String) : read(path, String)
end
47 changes: 4 additions & 43 deletions src/rendering/tex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function compile_latex(

# First, create the tex file and write the document to it.
touch("temp.tex")
path = "temp.pdf"
file = open("temp.tex", "w")
print(file, document)
close(file)
Expand All @@ -48,8 +49,8 @@ function compile_latex(
suc = success(latex)
close(out.in)
close(err.in)
if !isfile("temp.pdf")
println("Latex did not write temp.pdf! Using the $(tex_engine) engine.")
if !isfile(path)
println("Latex did not write $(path)! Using the $(tex_engine) engine.")
println("Files in temp directory are:\n" * join(readdir(), ','))
printstyled("Stdout\n", bold=true, color = :blue)
println(read(out, String))
Expand All @@ -58,47 +59,7 @@ function compile_latex(
error()
end
finally

# if pdf_num_pages("temp.pdf") > 1
# @warn("The PDF has more than 1 page! Choosing the first page.")
# end

# Generate the cropping margins
bbox = get_pdf_bbox("temp.pdf")
crop_box = (
bbox[1] - _PDFCROP_DEFAULT_MARGINS[][1],
bbox[2] - _PDFCROP_DEFAULT_MARGINS[][2],
bbox[3] + _PDFCROP_DEFAULT_MARGINS[][3],
bbox[4] + _PDFCROP_DEFAULT_MARGINS[][4],
)
crop_cmd = join(crop_box, " ")


out = Pipe()
err = Pipe()
try
redirect_stderr(err) do
redirect_stdout(out) do
Ghostscript_jll.gs() do gs_exe
run(`$gs_exe -o temp_cropped.pdf -sDEVICE=pdfwrite -c "[/CropBox [$crop_cmd]" -c "/PAGES pdfmark" -f temp.pdf`)
end
end
end
catch e
finally
close(out.in)
close(err.in)
if !isfile("temp_cropped.pdf")
println("`gs` failed to crop the PDF!")
println("Files in temp directory are:\n" * join(readdir(), ','))
printstyled("Stdout\n", bold=true, color = :blue)
println(read(out, String))
printstyled("Stderr\n", bold=true, color = :red)
println(read(err, String))
error()
end
end
return isfile("temp_cropped.pdf") ? read("temp_cropped.pdf", String) : read("temp.pdf", String)
return crop_pdf(path)
end
end
end
Expand Down
47 changes: 4 additions & 43 deletions src/rendering/typst.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ function compile_typst(document::AbstractString)
# First, create the typst file and write the document to it.
touch("temp.typ")
file = open("temp.typ", "w")
path = "temp.pdf"
print(file, document)
close(file)

Expand All @@ -43,8 +44,8 @@ function compile_typst(document::AbstractString)

close(out.in)
close(err.in)
if !isfile("temp.pdf")
println("Typst did not write temp.pdf! Using Typst_jll.jl.")
if !isfile(path)
println("Typst did not write $(path)! Using Typst_jll.jl.")
println("Files in temp directory are:\n" * join(readdir(), ','))
printstyled("Stdout\n", bold=true, color = :blue)
println(read(out, String))
Expand All @@ -53,47 +54,7 @@ function compile_typst(document::AbstractString)
error()
end
finally

# if pdf_num_pages("temp.pdf") > 1
# @warn("The PDF has more than 1 page! Choosing the first page.")
# end

# Generate the cropping margins
bbox = get_pdf_bbox("temp.pdf")
crop_box = (
bbox[1] - _PDFCROP_DEFAULT_MARGINS[][1],
bbox[2] - _PDFCROP_DEFAULT_MARGINS[][2],
bbox[3] + _PDFCROP_DEFAULT_MARGINS[][3],
bbox[4] + _PDFCROP_DEFAULT_MARGINS[][4],
)
crop_cmd = join(crop_box, " ")


out = Pipe()
err = Pipe()
try
redirect_stderr(err) do
redirect_stdout(out) do
Ghostscript_jll.gs() do gs_exe
run(`$gs_exe -o temp_cropped.pdf -sDEVICE=pdfwrite -c "[/CropBox [$crop_cmd]" -c "/PAGES pdfmark" -f temp.pdf`)
end
end
end
catch e
finally
close(out.in)
close(err.in)
if !isfile("temp_cropped.pdf")
println("`gs` failed to crop the PDF!")
println("Files in temp directory are:\n" * join(readdir(), ','))
printstyled("Stdout\n", bold=true, color = :blue)
println(read(out, String))
printstyled("Stderr\n", bold=true, color = :red)
println(read(err, String))
error()
end
end
return isfile("temp_cropped.pdf") ? read("temp_cropped.pdf", String) : read("temp.pdf", String)
return crop_pdf(path)
end
end
end
Expand Down
80 changes: 24 additions & 56 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -450,23 +450,7 @@ $(FIELDS)
It is also possible to manually construct a `CachedTEX` with `nothing` in the `doc` field,
if you just want to insert a pre-rendered PDF into your figure.
"""
function CachedTEX(doc::TEXDocument; kwargs...)

pdf = Vector{UInt8}(latex2pdf(convert(String, doc); kwargs...))
ptr = load_pdf(pdf)
surf = page2recordsurf(ptr, doc.page)
dims = (pdf_get_page_size(ptr, doc.page))

ct = CachedTEX(
doc,
pdf,
Ref(ptr),
surf,
dims# .+ (1, 1),
)

return ct
end
CachedTEX(doc::TEXDocument; kwargs...) = cached_doc(CachedTEX, latex2pdf, doc; kwargs...)

function CachedTEX(str::String; kwargs...)
return CachedTEX(implant_text(str); kwargs...)
Expand All @@ -481,20 +465,7 @@ function CachedTEX(x::LaTeXString; kwargs...)
end
end

function CachedTEX(pdf::Vector{UInt8}; kwargs...)
ptr = load_pdf(pdf)
surf = firstpage2recordsurf(ptr)
dims = pdf_get_page_size(ptr, 0)

ct = CachedTEX(
nothing,
pdf,
Ref(ptr),
surf,
dims# .+ (1, 1),
)
return ct
end
CachedTEX(pdf::Vector{UInt8}; kwargs...) = cached_pdf(CachedTEX, pdf; kwargs...)

# do not rerun the pipeline on CachedTEX
CachedTEX(ct::CachedTEX) = ct
Expand Down Expand Up @@ -533,13 +504,24 @@ $(FIELDS)
It is also possible to manually construct a `CachedTypst` with `nothing` in the `doc` field,
if you just want to insert a pre-rendered PDF into your figure.
"""
function CachedTypst(doc::TypstDocument)
pdf = Vector{UInt8}(typst2pdf(convert(String, doc)))
CachedTypst(doc::TypstDocument) = cached_doc(CachedTypst, typst2pdf, doc)

function CachedTypst(str::Union{String, TypstString}; kwargs...)
CachedTypst(TypstDocument(str); kwargs...)
end

CachedTypst(pdf::Vector{UInt8}; kwargs...) = cached_pdf(CachedTypst, pdf; kwargs...)

# do not rerun the pipeline on CachedTypst
CachedTypst(ct::CachedTypst) = ct

function cached_doc(T, f, doc; kwargs...)
pdf = Vector{UInt8}(f(convert(String, doc); kwargs...))
ptr = load_pdf(pdf)
surf = page2recordsurf(ptr, doc.page)
dims = (pdf_get_page_size(ptr, doc.page))

ct = CachedTypst(
ct = T(
doc,
pdf,
Ref(ptr),
Expand All @@ -550,16 +532,12 @@ function CachedTypst(doc::TypstDocument)
return ct
end

function CachedTypst(str::Union{String, TypstString}; kwargs...)
CachedTypst(TypstDocument(str); kwargs...)
end

function CachedTypst(pdf::Vector{UInt8}; kwargs...)
function cached_pdf(T, pdf; kwargs...)
ptr = load_pdf(pdf)
surf = firstpage2recordsurf(ptr)
dims = pdf_get_page_size(ptr, 0)

ct = CachedTypst(
ct = T(
nothing,
pdf,
Ref(ptr),
Expand All @@ -569,9 +547,6 @@ function CachedTypst(pdf::Vector{UInt8}; kwargs...)
return ct
end

# do not rerun the pipeline on CachedTypst
CachedTypst(ct::CachedTypst) = ct

function update_handle!(ct::Union{CachedTEX, CachedTypst})
ct.ptr[] = load_pdf(ct.pdf)
return ct.ptr[]
Expand All @@ -580,25 +555,18 @@ end
Base.convert(::Type{CachedPDF}, ct::Union{CachedTEX, CachedTypst}) = CachedPDF(PDFDocument(String(deepcopy(ct.pdf)), ct.doc.page), ct.ptr, ct.dims, ct.surf, Ref{Tuple{Matrix{ARGB32}, Float64}}((Matrix{ARGB32}(undef, 0, 0), 0)))
Base.convert(::Type{PDFDocument}, ct::Union{CachedTEX, CachedTypst}) = PDFDocument(String(deepcopy(ct.pdf)), ct.doc.page)

function Base.show(io::IO, ct::CachedTEX)
function _show(io, ct, x, y)
if isnothing(ct.doc)
println(io, "CachedTEX(no document, $(ct.ptr), $(ct.dims))")
println(io, x, "(no document, $(ct.ptr), $(ct.dims))")
elseif length(ct.doc.contents) > 1000
println(io, "CachedTEX(TexDocument(...), $(ct.ptr), $(ct.dims))")
println(io, x, "(", y, "(...), $(ct.ptr), $(ct.dims))")
else
println(io, "CachedTEX($(ct.doc), $(ct.ptr), $(ct.dims))")
println(io, x, "($(ct.doc), $(ct.ptr), $(ct.dims))")
end
end

function Base.show(io::IO, ct::CachedTypst)
if isnothing(ct.doc)
println(io, "CachedTypst(no document, $(ct.ptr), $(ct.dims))")
elseif length(ct.doc.contents) > 1000
println(io, "CachedTypst(TypstDocument(...), $(ct.ptr), $(ct.dims))")
else
println(io, "CachedTypst($(ct.doc), $(ct.ptr), $(ct.dims))")
end
end
Base.show(io::IO, ct::CachedTEX) = _show(io, ct, "CachedTEX", "TEXDocument")
Base.show(io::IO, ct::CachedTypst) = _show(io, ct, "CachedTypst", "TypstDocument")

function implant_math(str)
return TEXDocument(
Expand Down

0 comments on commit 78eac7c

Please sign in to comment.