Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOGS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Change Logs
0.3.0
+++++

* :pr:`33`: add simple command line to convert images to pdf
* :pr:`28`: add syntax to check the readme syntax
* :pr:`27`: fix missing __text_signature__ in docassert

Expand Down
15 changes: 15 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Code of Conduct

We are a community based on openness, as well as friendly and didactic discussions.

We aspire to treat everybody equally, and value their contributions.

Decisions are made based on technical merit and consensus.

Code is not the only way to help the project. Reviewing pull requests,
answering questions to help others on mailing lists or issues, organizing and
teaching tutorials, working on the website, improving the documentation, are
all priceless contributions.

We abide by the principles of openness, respect, and consideration of others of
the Python Software Foundation: https://www.python.org/psf/codeofconduct/
Binary file added _unittests/ut_tools/data/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _unittests/ut_tools/data/img4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _unittests/ut_tools/data/mazures0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _unittests/ut_tools/data/mazures1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions _unittests/ut_tools/test_imgexport.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os
import unittest
from sphinx_runpython.ext_test_case import ExtTestCase
from sphinx_runpython.tools.img_export import images2pdf


class TestImgExport(ExtTestCase):

def test_export1(self):
dest = "test_export1.pdf"
data = os.path.join(os.path.dirname(__file__), "data", "mazures1.jpg")
datap = os.path.join(os.path.dirname(__file__), "data", "*.jpg")
res = images2pdf([data, datap], dest)
self.assertExists(dest)
self.assertEqual(len(res), 3)

def test_export2(self):
dest = "test_export2.pdf"
data = os.path.join(os.path.dirname(__file__), "data", "mazures1.jpg")
datap = os.path.join(os.path.dirname(__file__), "data", "*.jpg")
res = images2pdf(",".join([data, datap]), dest)
self.assertExists(dest)
self.assertEqual(len(res), 3)


if __name__ == "__main__":
unittest.main(verbosity=2)
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ black
coverage
flake8
furo
img2pdf
isort
matplotlib
numpydoc
Expand Down
16 changes: 14 additions & 2 deletions sphinx_runpython/_cmd_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os
from argparse import ArgumentParser
from tempfile import TemporaryDirectory
from .convert import convert_ipynb_to_gallery


def get_parser():
Expand All @@ -12,7 +11,8 @@ def get_parser():
epilog="",
)
parser.add_argument(
"command", help="Command to run, only 'nb2py' or 'readme' are available"
"command",
help="Command to run, only 'nb2py', 'readme', 'img2pdf' are available",
)
parser.add_argument(
"-p", "--path", help="Folder or file which contains the files to process"
Expand All @@ -23,11 +23,18 @@ def get_parser():
help="Recursive search.",
action="store_true",
)
parser.add_argument(
"-o",
"--output",
help="output",
)
parser.add_argument("-v", "--verbose", help="verbosity", default=1, type=int)
return parser


def nb2py(infolder: str, recursive: bool = False, verbose: int = 0):
from .convert import convert_ipynb_to_gallery

if not os.path.exists(infolder):
raise FileNotFoundError(f"Unable to find {infolder!r}.")
patterns = [infolder + "/*.ipynb", infolder + "/**/*.ipynb"]
Expand All @@ -47,6 +54,11 @@ def process_args(args):
if cmd == "nb2py":
nb2py(args.path, recursive=args.recursive, verbose=args.verbose)
return
if cmd == "img2pdf":
from .tools.img_export import images2pdf

images2pdf(args.path, args.output, verbose=args.verbose)
return
if cmd == "readme":
from .readme import check_readme_syntax

Expand Down
Empty file.
71 changes: 71 additions & 0 deletions sphinx_runpython/tools/img_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import glob
import os
from typing import List, Optional, Sequence, Union


def images2pdf(
images: Union[str, Sequence[str]], output: Optional[str], verbose: int = 0
) -> List[str]:
"""
Merges multiples images into one single pdf.
Relies on :epkg:`img2pdf`. If an image name contains
``'*'``, the function assumes it is a pattern and
uses :mod:`glob`.

:param images: images to merge, it can be a comma separated values or a folder
:param output: output filename or stream
:param verbose: verbosity
"""
from img2pdf import convert

if isinstance(images, str):
if "," in images:
images = images.split(",")
elif "*" in images:
images = [images]
elif os.path.exists(images):
images = [images]
else:
raise RuntimeError(f"Unable to deal with images={images!r}")
elif not isinstance(images, (list, tuple)):
raise TypeError("Images must be a list.") # pragma: no cover

all_images = []
for img in images:
if "*" in img:
if verbose:
print(f"[images2pdf] look into {img!r}")
names = glob.glob(img)
if verbose:
print(f"[images2pdf] add {len(names)} images")
all_images.extend(names)
else:
if verbose:
print(f"[images2pdf] add {img!r}")
all_images.append(img)

if verbose > 1:
for i, img in enumerate(all_images):
print(f"[images2pdf] {i + 1}/{len(all_images)} {img!r}")

st, close = (
(open(output, "wb"), True) if isinstance(output, str) else (output, False)
)

for img in all_images:
assert not isinstance(img, str) or os.path.exists(
img
), f"Unable to find image {img!r}."

try:
convert(all_images, outputstream=st, with_pdfrw=False)
except TypeError as e:
raise TypeError(
f"Unable to process container type {type(all_images)} "
f"and type {type(all_images[0])}."
) from e

if close:
st.close()

return all_images