|
11 | 11 | 2019-2020 Albert Krewinkel <[email protected]>
|
12 | 12 | License: MIT – see LICENSE file for details
|
13 | 13 | ]]
|
| 14 | +-- Module pandoc.system is required and was added in version 2.7.3 |
| 15 | +PANDOC_VERSION:must_be_at_least '2.7.3' |
| 16 | + |
| 17 | +local system = require 'pandoc.system' |
| 18 | +local with_temporary_directory = system.with_temporary_directory |
| 19 | +local with_working_directory = system.with_working_directory |
14 | 20 |
|
15 | 21 | -- The PlantUML path. If set, uses the environment variable PLANTUML or the
|
16 | 22 | -- value "plantuml.jar" (local PlantUML version). In order to define a
|
@@ -93,83 +99,90 @@ local function graphviz(code, filetype)
|
93 | 99 | return final
|
94 | 100 | end
|
95 | 101 |
|
96 |
| --- Compile LaTeX with Tikz code to an image: |
97 |
| -local function tikz2image(src, filetype, additionalPackages) |
98 |
| - |
99 |
| - -- Define file names: |
100 |
| - local outfile = string.format("./tmp-latex/file.%s", filetype) |
101 |
| - local tmp = "./tmp-latex/file" |
102 |
| - local tmpDir = "./tmp-latex/" |
103 |
| - |
104 |
| - -- Ensure, that the tmp directory exists: |
105 |
| - os.execute("mkdir -p tmp-latex") |
106 |
| - |
107 |
| - -- Build and write the LaTeX document: |
108 |
| - local f = io.open(tmp .. ".tex", 'w') |
109 |
| - f:write("\\documentclass{standalone}\n\\usepackage{tikz}\n") |
110 |
| - |
111 |
| - -- Any additional package(s) are desired? |
112 |
| - if additionalPackages then |
113 |
| - f:write(additionalPackages) |
114 |
| - end |
115 |
| - |
116 |
| - f:write("\\begin{document}\n") |
117 |
| - f:write(src) |
118 |
| - f:write("\n\\end{document}\n") |
119 |
| - f:close() |
120 |
| - |
121 |
| - -- Execute the LaTeX compiler: |
122 |
| - pandoc.pipe(pdflatexPath, {'-output-directory', tmpDir, tmp}, '') |
123 |
| - |
124 |
| - -- Build the basic Inkscape command for the conversion: |
125 |
| - local baseCommand = " --without-gui --file=" .. tmp .. ".pdf" |
126 |
| - local knownFormat = false |
127 |
| - |
128 |
| - if filetype == "png" then |
129 |
| - |
130 |
| - -- Append the subcommands to convert into a PNG file: |
131 |
| - baseCommand = baseCommand .. " --export-png=" |
132 |
| - .. tmp .. ".png --export-dpi=300" |
133 |
| - knownFormat = true |
134 |
| - |
135 |
| - elseif filetype == "svg" then |
136 |
| - |
137 |
| - -- Append the subcommands to convert into a SVG file: |
138 |
| - baseCommand = baseCommand .. " --export-plain-svg=" .. tmp .. ".svg" |
139 |
| - knownFormat = true |
140 |
| - |
141 |
| - end |
142 |
| - |
143 |
| - -- Unfortunately, continuation is only possible, if we know the actual |
144 |
| - -- format: |
145 |
| - if not knownFormat then |
146 |
| - error(string.format("Don't know how to convert pdf to %s.", filetype)) |
147 |
| - end |
148 |
| - |
149 |
| - local imgData = nil |
150 |
| - |
151 |
| - -- We know the desired format. Thus, execute Inkscape: |
152 |
| - os.execute("\"" .. inkscapePath .. "\"" .. baseCommand) |
| 102 | +-- |
| 103 | +-- TikZ |
| 104 | +-- |
| 105 | + |
| 106 | +--- LaTeX template used to compile TikZ images. Takes additional |
| 107 | +--- packages as the first, and the actual TikZ code as the second |
| 108 | +--- argument. |
| 109 | +local tikz_template = [[ |
| 110 | +\documentclass{standalone} |
| 111 | +\usepackage{tikz} |
| 112 | +%% begin: additional packages |
| 113 | +%s |
| 114 | +%% end: additional packages |
| 115 | +\begin{document} |
| 116 | +%s |
| 117 | +\end{document} |
| 118 | +]] |
153 | 119 |
|
154 |
| - -- Try to open the image: |
155 |
| - local r = io.open(tmp .. "." .. filetype, 'rb') |
| 120 | +--- Returns a function which takes the filename of a PDF and a |
| 121 | +-- target filename, and writes the input as the given format. |
| 122 | +-- Returns `nil` if conversion into the target format is not |
| 123 | +-- possible. |
| 124 | +local function convert_from_pdf(filetype) |
| 125 | + -- Build the basic Inkscape command for the conversion |
| 126 | + local inkscape_output_args |
| 127 | + if filetype == 'png' then |
| 128 | + inkscape_output_args = '--export-png="%s" --export-dpi=300' |
| 129 | + elseif filetype == 'svg' then |
| 130 | + inkscape_output_args = '--export-plain-svg="%s"' |
| 131 | + else |
| 132 | + return nil |
| 133 | + end |
| 134 | + return function (pdf_file, outfile) |
| 135 | + local inkscape_command = string.format( |
| 136 | + '"%s" --without-gui --file="%s" ' .. inkscape_output_args, |
| 137 | + inkscapePath, |
| 138 | + pdf_file, |
| 139 | + outfile |
| 140 | + ) |
| 141 | + io.stderr:write(inkscape_command .. '\n') |
| 142 | + local command_output = io.popen(inkscape_command) |
| 143 | + -- TODO: print output when debugging. |
| 144 | + command_output:close() |
| 145 | + end |
| 146 | +end |
156 | 147 |
|
157 |
| - -- Read the image, if available: |
158 |
| - if r then |
159 |
| - imgData = r:read("*all") |
| 148 | +--- Compile LaTeX with Tikz code to an image |
| 149 | +local function tikz2image(src, filetype, additional_packages) |
| 150 | + local convert = convert_from_pdf(filetype) |
| 151 | + -- Bail if there is now known way from PDF to the target format. |
| 152 | + if not convert then |
| 153 | + error(string.format("Don't know how to convert pdf to %s.", filetype)) |
| 154 | + end |
| 155 | + return with_temporary_directory("tikz2image", function (tmpdir) |
| 156 | + return with_working_directory(tmpdir, function () |
| 157 | + -- Define file names: |
| 158 | + local file_template = "%s/tikz-image.%s" |
| 159 | + local tikz_file = file_template:format(tmpdir, "tex") |
| 160 | + local pdf_file = file_template:format(tmpdir, "pdf") |
| 161 | + local outfile = file_template:format(tmpdir, filetype) |
| 162 | + |
| 163 | + -- Build and write the LaTeX document: |
| 164 | + local f = io.open(tikz_file, 'w') |
| 165 | + f:write(tikz_template:format(additional_packages or '', src)) |
| 166 | + f:close() |
| 167 | + |
| 168 | + -- Execute the LaTeX compiler: |
| 169 | + pandoc.pipe(pdflatexPath, {'-output-directory', tmpdir, tikz_file}, '') |
| 170 | + |
| 171 | + convert(pdf_file, outfile) |
| 172 | + |
| 173 | + -- Try to open and read the image: |
| 174 | + local img_data |
| 175 | + local r = io.open(outfile, 'rb') |
| 176 | + if r then |
| 177 | + img_data = r:read("*all") |
160 | 178 | r:close()
|
161 |
| - end |
| 179 | + else |
| 180 | + -- TODO: print warning |
| 181 | + end |
162 | 182 |
|
163 |
| - -- Delete the image tmp file: |
164 |
| - os.remove(outfile) |
165 |
| - |
166 |
| - -- Remove the temporary files: |
167 |
| - os.remove(tmp .. ".tex") |
168 |
| - os.remove(tmp .. ".pdf") |
169 |
| - os.remove(tmp .. ".log") |
170 |
| - os.remove(tmp .. ".aux") |
171 |
| - |
172 |
| - return imgData |
| 183 | + return img_data |
| 184 | + end) |
| 185 | + end) |
173 | 186 | end
|
174 | 187 |
|
175 | 188 | -- Run Python to generate an image:
|
|
0 commit comments