Commit 681ad729 authored by Ingo Heimbach's avatar Ingo Heimbach

Merge branch 'develop'

parents e23e4fe8 a56876bd
......@@ -21,7 +21,8 @@ with the standard versions but offer additional features:
- Images can be embedded into the generated document (`embedded-image` directive, HTML only; for LaTeX this is already
the default behavior)
- Support for TikZ images by `tikz` and `tikz-figure` directives. TikZ code can be loaded from an external file or
written as embedded source.
written as embedded source. `rst2html-extended` needs either `pdf2svg` or `mupdf-tools` to support TikZ pictures.
`pdf2svg` is recommended because it produces SVG images without any quality loss.
## Files
......
__version_info__ = (0, 1, 5)
__version_info__ = (0, 1, 7)
__version__ = '.'.join(map(str, __version_info__))
......@@ -46,6 +46,8 @@ TMP_PDF_FILENAME = "tikz_picture.pdf"
OUT_PDF_FILENAME = "_tikz_rendered{:04d}.pdf"
TMP_PNG_FILENAME = "tikz_picture.png"
OUT_PNG_FILENAME = "_tikz_rendered{:04d}.png"
TMP_SVG_FILENAME = "tikz_picture.svg"
OUT_SVG_FILENAME = "_tikz_rendered{:04d}.svg"
VALID_OUTPUT_MODES = ("latex", "html")
......@@ -77,7 +79,7 @@ class TemporaryDirectory(object):
self.tmp_dir = None
def render_tikz(tikz_code, options, output_png=False):
def render_tikz(tikz_code, options, output_png=False, output_svg=False):
self = render_tikz
if not hasattr(self, "image_number"):
self.image_number = 1
......@@ -91,10 +93,12 @@ def render_tikz(tikz_code, options, output_png=False):
latex_output = template.render(tikz_code=tikz_code, **options)
out_pdf_filename = OUT_PDF_FILENAME.format(self.image_number)
out_png_filename = OUT_PNG_FILENAME.format(self.image_number)
out_svg_filename = OUT_SVG_FILENAME.format(self.image_number)
with TemporaryDirectory() as tmp_dir:
tmp_latex_path = os.path.join(tmp_dir, TMP_LATEX_FILENAME)
tmp_pdf_path = os.path.join(tmp_dir, TMP_PDF_FILENAME)
tmp_png_path = os.path.join(tmp_dir, TMP_PNG_FILENAME)
tmp_svg_path = os.path.join(tmp_dir, TMP_SVG_FILENAME)
with codecs.open(tmp_latex_path, "w", "utf-8") as f:
f.write(latex_output)
with open(os.devnull, "w") as devnull:
......@@ -111,6 +115,15 @@ def render_tikz(tikz_code, options, output_png=False):
) as f:
sys.stderr.write(f.read())
raise
if output_svg:
try:
subprocess.check_call(
["pdf2svg", TMP_PDF_FILENAME, TMP_SVG_FILENAME], cwd=tmp_dir, stdout=devnull, stderr=devnull
)
output_png = False
except (OSError, subprocess.CalledProcessError):
output_png = True
output_svg = False
if output_png:
for command in (["mudraw"], ["mutool", "draw"]):
try:
......@@ -125,17 +138,27 @@ def render_tikz(tikz_code, options, output_png=False):
last_exception = e
else:
raise last_exception
if output_png:
if output_svg:
shutil.move(tmp_svg_path, out_svg_filename)
out_filename = out_svg_filename
elif output_png:
shutil.move(tmp_png_path, out_png_filename)
out_filename = out_png_filename
else:
shutil.move(tmp_pdf_path, out_pdf_filename)
return out_png_filename if output_png else out_pdf_filename
out_filename = out_pdf_filename
return out_filename
def convert_png_to_html_base64(png_filepath):
with open(png_filepath.encode(sys.getfilesystemencoding()), "rb") as image_file:
def convert_image_to_html_base64(image_filepath):
filetype = os.path.splitext(image_filepath)[1].lower()
if filetype.startswith("."):
filetype = filetype[1:]
if filetype == "svg":
filetype = "svg+xml"
with open(image_filepath.encode(sys.getfilesystemencoding()), "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
return "data:image/png;base64," + encoded_string
return "data:image/{format};base64,".format(format=filetype) + encoded_string
class Tikz(Directive):
......@@ -182,9 +205,9 @@ class Tikz(Directive):
content = f.read()
else:
content = self.content
rendered_tikz_filename = render_tikz("\n".join(content), self.options, output_png=is_output_mode_html)
rendered_tikz_filename = render_tikz("\n".join(content), self.options, output_svg=is_output_mode_html)
if is_output_mode_html:
reference = directives.uri(convert_png_to_html_base64(rendered_tikz_filename))
reference = directives.uri(convert_image_to_html_base64(rendered_tikz_filename))
else:
reference = directives.uri(rendered_tikz_filename)
self.options["uri"] = reference
......
......@@ -19,6 +19,7 @@ except:
from docutils.core import publish_cmdline
from docutils.parsers.rst import directives
from docutils.parsers.rst.directives.images import Image
from ..directives import CodeBlock, Tikz, TikzFigure, set_output_mode
......@@ -36,6 +37,7 @@ def main():
set_output_mode("latex")
for directive_name in ("code", "code-block"):
directives.register_directive(directive_name, CodeBlock)
directives.register_directive("embedded-image", Image)
directives.register_directive("tikz", Tikz)
directives.register_directive("tikz-figure", TikzFigure)
publish_cmdline(writer_name="latex", description=description)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment