Skip to content

Commit

Permalink
CLI: Use argparse subparsers (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
mara004 committed May 16, 2022
1 parent f059f50 commit 600e649
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 224 deletions.
8 changes: 8 additions & 0 deletions docs/source/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
# Changelog


## 1.9.0 (sched 2022-05-16)

- Updated PDFium from `5052` to `XXXX`.
- Significantly improved maintainability of the command-line interface by using argparse subparsers instead of a custom implementation.
- Integrated optional support for shell auto-completion using `argcomplete`.
- Added capabilities to determine bookmark state (open/closed) to the TOC parser. Thanks to PDFium Team for reviewing/merging the CL.


## 1.8.0 (2022-05-09)

- Updated PDFium from `5038` to `5052`.
Expand Down
24 changes: 12 additions & 12 deletions docs/source/shell_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,41 @@ pypdfium2 can also be used from the command-line.

Main help
*********
``pypdfium2 help``
``pypdfium2 --help``

.. program-output:: python3 -m pypdfium2 help
.. program-output:: pypdfium2 --help


Version
*******
``pypdfium2 version``
``pypdfium2 --version``

.. program-output:: python3 -m pypdfium2 version
.. program-output:: pypdfium2 --version


Renderer
********
``pypdfium2 render``
``pypdfium2 render --help``

.. program-output:: python3 -m pypdfium2 render
.. program-output:: pypdfium2 render --help


Table of Contents Reader
************************
``pypdfium2 toc``
``pypdfium2 toc --help``

.. program-output:: python3 -m pypdfium2 toc
.. program-output:: pypdfium2 toc --help


Merger
******
``pypdfium2 merge``
``pypdfium2 merge --help``

.. program-output:: python3 -m pypdfium2 merge
.. program-output:: pypdfium2 merge --help


Page Tiler
**********
``pypdfium2 tile``
``pypdfium2 tile --help``

.. program-output:: python3 -m pypdfium2 tile
.. program-output:: pypdfium2 tile --help
4 changes: 3 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ console_scripts =
pypdfium2 = pypdfium2._cli.main:main

[options.extras_require]
converters =
converters =
Pillow>=6.0
inserttext =
uharfbuzz
autocomplete =
argcomplete
test =
pytest
docs =
Expand Down
128 changes: 0 additions & 128 deletions src/pypdfium2/_cli/_parser.py

This file was deleted.

71 changes: 42 additions & 29 deletions src/pypdfium2/_cli/main.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,61 @@
# PYTHON_ARGCOMPLETE_OK
# SPDX-FileCopyrightText: 2022 geisserml <[email protected]>
# SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause

import sys
import argparse
from pypdfium2._version import (
V_PYPDFIUM2,
V_LIBPDFIUM,
)
from pypdfium2._cli._parser import CliParser
from pypdfium2._cli import (
renderer,
render,
toc,
merger,
tiler,
merge,
tile,
)

try:
import argcomplete
except ImportError:
have_argcomplete = False
else:
have_argcomplete = True

def main(argv=sys.argv[1:]):

Subcommands = dict(
render = render,
toc = toc,
merge = merge,
tile = tile,
)


def parse_args(argv=sys.argv[1:]):

parser = CliParser(
program = "pypdfium2",
version = "%s (libpdfium %s)" % (V_PYPDFIUM2, V_LIBPDFIUM),
parser = argparse.ArgumentParser(
prog = "pypdfium2",
description = "Command line interface to the pypdfium2 Python library",
argv = argv,
)

parser.add_subcommand(
"render",
method = renderer.main,
help = "Rasterise pages of a PDF file",
)
parser.add_subcommand(
"toc",
method = toc.main,
help = "Show the table of contents for a PDF document",
parser.add_argument(
"--version", "-v",
action = "version",
version = "pypdfium2 %s (libpdfium %s)" % (V_PYPDFIUM2, V_LIBPDFIUM),
)
parser.add_subcommand(
"merge",
method = merger.main,
help = "Concatenate PDF files",
)
parser.add_subcommand(
"tile",
method = tiler.main,
help = "Perform page tiling (N-up compositing)",

subparsers = parser.add_subparsers(
dest = "subcommand",
required = True,
)
for cmd in Subcommands.values():
cmd.attach_parser(subparsers)

if have_argcomplete:
argcomplete.autocomplete(parser)

parser.run()
return parser.parse_args(argv)


def main():
args = parse_args()
Subcommands[args.subcommand].main(args)
18 changes: 5 additions & 13 deletions src/pypdfium2/_cli/merger.py → src/pypdfium2/_cli/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import ctypes
from pypdfium2 import _namespace as pdfium
from pypdfium2._cli._parser import ArgParser


def _merge_pdfs(input_paths):
Expand All @@ -19,13 +18,11 @@ def _merge_pdfs(input_paths):
return dest_doc


def parse_args(argv, prog, desc):

parser = ArgParser(
prog = prog,
description = desc,
def attach_parser(subparsers):
parser = subparsers.add_parser(
'merge',
help = "Concatenate PDF files",
)

parser.add_argument(
'inputs',
nargs = '+',
Expand All @@ -36,14 +33,9 @@ def parse_args(argv, prog, desc):
required = True,
help = "Target path for the output document",
)

return parser.parse_args(argv)


def main(argv, prog, desc):

args = parse_args(argv, prog, desc)
def main(args):
merged_doc = _merge_pdfs(args.inputs)

with open(args.output, 'wb') as file_handle:
pdfium.save_pdf(merged_doc, file_handle)
19 changes: 6 additions & 13 deletions src/pypdfium2/_cli/renderer.py → src/pypdfium2/_cli/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import os
import ast
from pypdfium2 import _namespace as pdfium
from pypdfium2._cli._parser import ArgParser
from os.path import (
join,
abspath,
Expand Down Expand Up @@ -69,13 +68,11 @@ def pagetext_type(value):
return page_indices


def parse_args(argv, prog, desc):

parser = ArgParser(
prog = prog,
description = desc,
def attach_parser(subparsers):
parser = subparsers.add_parser(
"render",
help = "Rasterise pages of a PDF file",
)

parser.add_argument(
'inputs',
nargs = '+',
Expand Down Expand Up @@ -138,14 +135,10 @@ def parse_args(argv, prog, desc):
type = int,
help = "The number of processes to use for rendering (defaults to the number of CPU cores)"
)

return parser.parse_args(argv)


def main(argv, prog, desc):

args = parse_args(argv, prog, desc)

def main(args):

for input_path in args.inputs:

prefix = splitext(basename(input_path))[0] + '_'
Expand Down
Loading

0 comments on commit 600e649

Please sign in to comment.