diff --git a/dist/beamer-slider-0.0.1.tar.gz b/dist/beamer-slider-0.0.1.tar.gz deleted file mode 100644 index a26945b2d39023b8d9ed19da09975b97ca46c2ef..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.0.1.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.0.2.tar.gz b/dist/beamer-slider-0.0.2.tar.gz deleted file mode 100644 index 9d9de025e1ace90f2311c9c8c61c470313bf07ff..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.0.2.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.1.0.tar.gz b/dist/beamer-slider-0.1.0.tar.gz deleted file mode 100644 index 40da5b47506b6307af6bbf651e13de2b60f20102..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.1.0.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.1.1.tar.gz b/dist/beamer-slider-0.1.1.tar.gz deleted file mode 100644 index ffa7bb5958d82950f5a2b48b49cea5f9e393e6b0..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.1.1.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.1.2.tar.gz b/dist/beamer-slider-0.1.2.tar.gz deleted file mode 100644 index 54e42034655ad4046a5c2b565a3ddf9a528acfb6..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.1.2.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.1.3.tar.gz b/dist/beamer-slider-0.1.3.tar.gz deleted file mode 100644 index 88c9b913fe047dc5ccdbe443339b008e0783385c..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.1.3.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.1.4.tar.gz b/dist/beamer-slider-0.1.4.tar.gz deleted file mode 100644 index 8cc4c677db0a3c054128ddb89e9bff0aa1ea6fdc..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.1.4.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.1.5.tar.gz b/dist/beamer-slider-0.1.5.tar.gz deleted file mode 100644 index 881b585aa9d01c36434cf84b38cc4e71f04162ff..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.1.5.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.1.6.tar.gz b/dist/beamer-slider-0.1.6.tar.gz deleted file mode 100644 index d6b5dce5cf923876766c0bca8eec0faa890c9a28..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.1.6.tar.gz and /dev/null differ diff --git a/dist/beamer-slider-0.1.6b0.tar.gz b/dist/beamer-slider-0.1.6b0.tar.gz deleted file mode 100644 index c6e527ea3bd1349f5cf3883e9dbbe45196600bf7..0000000000000000000000000000000000000000 Binary files a/dist/beamer-slider-0.1.6b0.tar.gz and /dev/null differ diff --git a/dist/beamer_slider-0.0.1-py3-none-any.whl b/dist/beamer_slider-0.0.1-py3-none-any.whl deleted file mode 100644 index ef122db6efc3aac165213fb06b33f4bb086f2e45..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.0.1-py3-none-any.whl and /dev/null differ diff --git a/dist/beamer_slider-0.0.2-py3-none-any.whl b/dist/beamer_slider-0.0.2-py3-none-any.whl deleted file mode 100644 index 0604d04045a24f8f47236a17f450547931a20d48..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.0.2-py3-none-any.whl and /dev/null differ diff --git a/dist/beamer_slider-0.1.0-py3-none-any.whl b/dist/beamer_slider-0.1.0-py3-none-any.whl deleted file mode 100644 index a532586d2e0aadeb4a1b0ff37c5ea53e7cbf2a0e..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.1.0-py3-none-any.whl and /dev/null differ diff --git a/dist/beamer_slider-0.1.1-py3-none-any.whl b/dist/beamer_slider-0.1.1-py3-none-any.whl deleted file mode 100644 index 67de3649996bffeffa639dd4d6a68e6e2ff7780e..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.1.1-py3-none-any.whl and /dev/null differ diff --git a/dist/beamer_slider-0.1.3-py3-none-any.whl b/dist/beamer_slider-0.1.3-py3-none-any.whl deleted file mode 100644 index a7ccf62feaf543dcb511f50912cf7762e01d0f89..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.1.3-py3-none-any.whl and /dev/null differ diff --git a/dist/beamer_slider-0.1.4-py3-none-any.whl b/dist/beamer_slider-0.1.4-py3-none-any.whl deleted file mode 100644 index 3418f993ef843c7dc0afe9ee3ee3f15552803b24..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.1.4-py3-none-any.whl and /dev/null differ diff --git a/dist/beamer_slider-0.1.5-py3-none-any.whl b/dist/beamer_slider-0.1.5-py3-none-any.whl deleted file mode 100644 index 46a4ae2506ea28692b0cfa99f4b046494080c654..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.1.5-py3-none-any.whl and /dev/null differ diff --git a/dist/beamer_slider-0.1.5-py3.8.egg b/dist/beamer_slider-0.1.5-py3.8.egg deleted file mode 100644 index 3de6d15cc174916e7ef454b1fb906726fb1005f0..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.1.5-py3.8.egg and /dev/null differ diff --git a/dist/beamer_slider-0.1.6-py3-none-any.whl b/dist/beamer_slider-0.1.6-py3-none-any.whl deleted file mode 100644 index 9ab8cdc2e84be8aec172e27f6ed655f0f5deeff2..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.1.6-py3-none-any.whl and /dev/null differ diff --git a/dist/beamer_slider-0.1.6b0-py3-none-any.whl b/dist/beamer_slider-0.1.6b0-py3-none-any.whl deleted file mode 100644 index b927cbfae818875267a926707e1c66c3bd391c9b..0000000000000000000000000000000000000000 Binary files a/dist/beamer_slider-0.1.6b0-py3-none-any.whl and /dev/null differ diff --git a/setup.py b/setup.py index f4c5fb4b3417b419494786eaf885025411ef2cee..5c785187cce028cc3040fe4c01f164b62cacda8a 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ # Use: pipreqs.exe slider --no-pin --force for requirements.txt # https://packaging.python.org/tutorials/packaging-projects/ # py -m build && twine upload dist/* -# Linux> python -m build && twine upload dist/* +# Linux> python -m build && python -m twine upload dist/* # Local install: sudo pip install -e ./ import setuptools diff --git a/src/beamer_slider.egg-info/PKG-INFO b/src/beamer_slider.egg-info/PKG-INFO index 604eec007ea580a5de48901e31c7efbba037b7ac..094d8476809407722da8c08d3e2d303c1c6352a4 100644 --- a/src/beamer_slider.egg-info/PKG-INFO +++ b/src/beamer_slider.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: beamer-slider -Version: 0.1.26.1 +Version: 0.1.26.6 Summary: Software to create inkscape overlays in Beamer Home-page: https://lab.compute.dtu.dk/tuhe/slider Author: Tue Herlau diff --git a/src/jinjafy/jinjafy.py b/src/jinjafy/jinjafy.py index 5b7a696ac71f01affe299e7d2c3298bbc8ccee3f..c396e64a61f4388f1b70e33b297e6b0015dd8cc0 100644 --- a/src/jinjafy/jinjafy.py +++ b/src/jinjafy/jinjafy.py @@ -6,15 +6,15 @@ import numpy as np from jinjafy import jinja_env -def jinjafy_template(data,file_in,file_out=None, filters={},template_searchpath=None): +def jinjafy_template(data,file_in,file_out=None, filters={},template_searchpath=None, verbose=False): if template_searchpath: file_in = os.path.relpath(file_in, template_searchpath) - return jinjafy_comment(data, file_in=file_in, file_out=file_out,jinja_tag=None, filters=filters,template_searchpath=template_searchpath) + return jinjafy_comment(data, file_in=file_in, file_out=file_out,jinja_tag=None, filters=filters,template_searchpath=template_searchpath, verbose=verbose) def jinjafy_comment(data,file_in=None,file_out=None,jinja_tag="jinja",jinja_code=None,trim_whitespace=True,trim_comments=True,comment_char="#", - filters={},template_searchpath=None): + filters={},template_searchpath=None, verbose=False): # Extract all comments from the given file and jinjafy them. if file_in is None: frame = inspect.stack()[1] @@ -128,9 +128,8 @@ def jinjafy_comment(data,file_in=None,file_out=None,jinja_tag="jinja",jinja_code if file_out is not None: with open(file_out,'w',encoding='utf-8') as f: - # jinja_out = jinja_out.encode('utf-8') - f.write(jinja_out) + if verbose: print("Writing to: " + file_out) return jinja_out diff --git a/src/slider/__init__.py b/src/slider/__init__.py index d27a04fb4593fd0f477db3030dc20b5acb768c5d..91d6a79359c70bd0ad35d1a755658df4b509554d 100644 --- a/src/slider/__init__.py +++ b/src/slider/__init__.py @@ -1,2 +1,2 @@ # from jinjafy import execute_command -from slider.latexutils import latexmk +from slider.latexutils import latexmk, latexmk_async diff --git a/src/slider/latexutils.py b/src/slider/latexutils.py index 5ba36ed49a283944c9548b82fed9b674d10b80db..c44fa7a421ce943c47fb5a7ac9121a5ae1cf07ff 100644 --- a/src/slider/latexutils.py +++ b/src/slider/latexutils.py @@ -3,8 +3,9 @@ import os import shutil import subprocess import glob +import asyncio -def latexmk(texfile,pdf_out=None,shell=True,cleanup=False, Linux=False): +def latexmk(texfile, pdf_out=None,shell=True,cleanup=False, Linux=False): cdir = os.getcwd() texfile = os.path.abspath(texfile) dname = os.path.dirname(texfile) @@ -15,14 +16,6 @@ def latexmk(texfile,pdf_out=None,shell=True,cleanup=False, Linux=False): s = subprocess.check_output(CMD, shell=True) - # if Linux: - # CMD = "latexmk -f -g -pdf -interaction=nonstopmode " + texfile - # print("Running LaTeX command>> " + CMD) - # s = execute_command(CMD.split(" "), shell=shell) - # else: - # CMD = "latexmk -f -g -pdf -shell-escape -interaction=nonstopmode " + texfile - # s = execute_command(CMD.split(" "),shell=shell) - # if pdf_out: shutil.copyfile(texfile[:-4]+".pdf", pdf_out) else: @@ -38,5 +31,60 @@ def latexmk(texfile,pdf_out=None,shell=True,cleanup=False, Linux=False): os.chdir(cdir) return pdf_out +async def latexmk_async(texfile, pdf_out=None, cleanup=False): + cdir = os.getcwd() + texfile = os.path.abspath(texfile) + import tempfile + # with tempfile.TemporaryDirectory() as tmp: + # print('created temporary directory', tmpdirname) + # shutil.rmtree(tmp) + # shutil.copytree(os.path.dirname(texfile), tmp) + # tmp_texfile = tmp + "/" + os.path.basename(texfile) + tmp_texfile = texfile + compiled_pdf = tmp_texfile[:-4] + ".pdf" + if os.path.isfile(compiled_pdf): + os.remove(compiled_pdf) + + dname = os.path.dirname(tmp_texfile) + os.chdir(dname) + texfile_name = os.path.basename(tmp_texfile) + CMD = "latexmk -f -g -pdf -shell-escape -interaction=nonstopmode " + os.path.basename(tmp_texfile) + print("Running LaTeX command>> " + CMD) + # s = subprocess.check_output(CMD, shell=True) + + process = await asyncio.create_subprocess_shell(CMD, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) + stdout = await process.stdout.read() + stderr = await process.stderr.read() + state = await process.wait() + if state != 0: + print(stdout) + print(stderr) + raise Exception(f"Subprocess failed {state}") + + assert os.path.isfile(compiled_pdf) + + if pdf_out: + shutil.copyfile(compiled_pdf, pdf_out) + else: + # print("compiled pdf", compiled_pdf) + pdf_out = os.path.join( os.path.dirname(texfile), os.path.basename(compiled_pdf)) + # print("pdf out", pdf_out) + + # shutil.copyfile(compiled_pdf, pdf_out) + # shutil.copyfile( os.path.join(os.path.dirname(tmp_texfile), tmp_texfile[:-4] + ".pdf"), + # pdf_out = os.path.join(os.path.dirname(tmp_texfile), tmp_texfile[:-4] + ".pdf") + + if cleanup and os.path.exists(pdf_out): + bft = ['bbl', 'blg', 'fdb_latexmk', 'fls', 'aux', 'synctex.gz', 'log'] + for ex in bft: + fl = glob.glob(dname + "/*." + ex) + for f in fl: + os.remove(f) + + os.chdir(cdir) + + assert os.path.isfile(pdf_out) + print("RETURNING PDF FILE", pdf_out) + return pdf_out diff --git a/src/slider/slide.py b/src/slider/slide.py index 050924f1f0d833224746f29888916109db6d616a..89d2196056d2f30a737c7f802f2229aa90920504 100644 --- a/src/slider/slide.py +++ b/src/slider/slide.py @@ -32,6 +32,7 @@ def set_svg_background_images(lecture_tex, verbose=False, copy_template_resource_files=True, force_recompile=False, force_fix_broken_osvg_files = None, + max_thread_number=4, # For parallel slide compilation (SVG Conversion). ): ''' Main file for fixing/setting osvg background images in the given lecture .pdf. @@ -42,6 +43,13 @@ def set_svg_background_images(lecture_tex, verbose=False, :param lecture_tex: File to set background image in. :return: ''' + import time + class TT: + pass + tt = TT() + tt.t0 = time.time() + + MAIN_TEX_DIR = os.path.dirname(lecture_tex) SVG_TMP_DIR = MAIN_TEX_DIR + "/" + SVG_EDIT_RELPATH + "/" + SVG_TMP_RELPATH SVG_OSVG_DIR = MAIN_TEX_DIR + "/" + SVG_EDIT_RELPATH @@ -128,15 +136,18 @@ def set_svg_background_images(lecture_tex, verbose=False, cache_update_file(MAIN_TEX_DIR, lecture_tex_nosvg) ANY_CHANGES = True + tt.t0 = time.time() - tt.t0 + tt.t1 = time.time() # Make .png background images. import PyPDF2 # Import PyPDF2 here. There is a strange issue (possibly bad package version?) which makes it inappropriate as a top-level import (CI/CD Breaks). + with open(lecture_tex_nosvg_pdf, 'rb') as f: pdfdoc = PyPDF2.PdfReader(f) for i in range(len(pdfdoc.pages)): content = pdfdoc.pages[i].extract_text() for osvg_name, d in sinfo.items(): #enumerate(sinfo): - if d['pdf_label'] in content: + d['pdf_page'] = i d['png_bgimg'] = SVG_TMP_DIR + "/" + d['pdf_label'] + ".png" if not os.path.exists(d['svg_edit_file']): @@ -151,15 +162,34 @@ def set_svg_background_images(lecture_tex, verbose=False, legacy_importer.raw_svg_to_osvg(tmp_svg_file, overwrite_existing=True) ANY_CHANGES = True - if cache_contains_str(MAIN_TEX_DIR, key=d['pdf_label'], value=d['slide_tex']): - # print("slider> Cache contains slide tex; continuing: " + d['pdf_label'] ) - continue - legacy_importer.slide_to_image(lecture_tex_nosvg_pdf, d['png_bgimg'], i + 1) - ANY_CHANGES = True - cache_update_str(MAIN_TEX_DIR, key=d['pdf_label'], value=d['slide_tex']) - + if not cache_contains_str(MAIN_TEX_DIR, key=d['pdf_label'], value=d['slide_tex']): + legacy_importer.slide_to_image(lecture_tex_nosvg_pdf, d['png_bgimg'], i + 1) + ANY_CHANGES = True + cache_update_str(MAIN_TEX_DIR, key=d['pdf_label'], value=d['slide_tex']) + tt.t1 = time.time() - tt.t1 + tt.t2 = time.time() + threads = [] + import threading + results = [] # This is the step that actually fixes the svg files. i.e. squeeze fonts, etc. + # maximumNumberOfThreads = 4 + threadLimiter = threading.BoundedSemaphore(max_thread_number) + + class MyThread(threading.Thread): + # def __init__ + def __init__(self, target, args): + self.target = target + self.args = args + super().__init__() + + def run(self): + threadLimiter.acquire() + try: + self.target(*self.args) + finally: + threadLimiter.release() + for osvg_name, d in sinfo.items(): if (osvg_name+".svg") not in force_fix_broken_osvg_files: if cache_contains_file(MAIN_TEX_DIR, d['svg_edit_file']) and not force_recompile: @@ -167,14 +197,20 @@ def set_svg_background_images(lecture_tex, verbose=False, ''' Check if the svg image pass sanity checks: Does it exist and is it okay? ''' - if fix_broken_osvg_files: - print("Checking and fixing the potentially broken file", d['svg_edit_file']) - check_svg_file_and_fix_if_broken(d['svg_edit_file'], verbose=verbose) + # _do_slide_conversion(MAIN_TEX_DIR = MAIN_TEX_DIR, d=d, fix_broken_osvg_files=fix_broken_osvg_files, verbose=verbose) + # ANY_CHANGES = True + threads.append(MyThread(target=_do_slide_conversion, args=(MAIN_TEX_DIR, d, fix_broken_osvg_files, verbose ) ) ) + # threads.append( threading.Thread(target=_do_slide_conversion, args=(MAIN_TEX_DIR, d, fix_broken_osvg_files, verbose ) ) ) - legacy_importer.svg_edit_to_importable(d['svg_edit_file'], verbose=verbose) - # legacy_importer.svg_check_background_layer(d['svg_edit_file'], verbose=verbose) # This was an old check for BG img. - cache_update_file(MAIN_TEX_DIR, d['svg_edit_file']) - ANY_CHANGES = True + # thread_list.append(thread) + for thread in threads: + thread.start() + + for thread in threads: + thread.join() + + tt.t2 = time.time() - tt.t2 + tt.t3 = time.time() if ANY_CHANGES and recompile_on_change: latexmk(lecture_tex) @@ -191,11 +227,26 @@ def set_svg_background_images(lecture_tex, verbose=False, if os.path.isdir(DNE): shutil.rmtree(DNE) if not os.path.isdir(NO_SVG_TMP_DIR): - os.mkdir(NO_SVG_TMP_DIR) + os.makedirs(NO_SVG_TMP_DIR) for f in glob.glob(MAIN_TEX_DIR +"/*_NO_SVGS.*"): shutil.move(f, NO_SVG_TMP_DIR +"/" + os.path.basename(f)) + tt.t3 = time.time() - tt.t3 + print(f"Slider> Time on init {tt.t0}, time on import {tt.t1}, time on conversion {tt.t2}, time on cleanup {tt.t3} ({max_thread_number=})") + + +def _do_slide_conversion(MAIN_TEX_DIR, d, fix_broken_osvg_files, verbose): + if fix_broken_osvg_files: + print("Checking and fixing the potentially broken file", d['svg_edit_file']) + check_svg_file_and_fix_if_broken(d['svg_edit_file'], verbose=verbose) + legacy_importer.svg_edit_to_importable(d['svg_edit_file'], verbose=verbose) + # legacy_importer.svg_check_background_layer(d['svg_edit_file'], verbose=verbose) # This was an old check for BG img. + cache_update_file(MAIN_TEX_DIR, d['svg_edit_file']) + # ANY_CHANGES = True + # return ANY_CHANGES + + def slide_no_by_text(pdf_file, text): assert False # Make .png background images. diff --git a/src/slider/version.py b/src/slider/version.py index b9ffbe50f2a7f900c296e0c3b5b92477dcc40d83..dfb4a49dc0b8e621c72663a4d5849474e0543a0d 100644 --- a/src/slider/version.py +++ b/src/slider/version.py @@ -1 +1 @@ -__version__ = "0.1.26.1" \ No newline at end of file +__version__ = "0.1.26.6" \ No newline at end of file diff --git a/tests/tests_images/index.pdf b/tests/tests_images/index.pdf index 930f68c15e9ab81f4c46c13bbadae1a070f61e2b..b42355cc602ec0f8e2852a3ff53af64a8d194266 100644 Binary files a/tests/tests_images/index.pdf and b/tests/tests_images/index.pdf differ