frappe/env/lib/python3.12/site-packages/weasyprint/__main__.py

214 lines
7.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Command-line interface to WeasyPrint."""
import argparse
import logging
import platform
import sys
from warnings import warn
import pydyf
from . import DEFAULT_OPTIONS, HTML, LOGGER, __version__
from .pdf import VARIANTS
from .text.ffi import pango
class PrintInfo(argparse.Action):
def __call__(*_, **__):
uname = platform.uname()
print('System:', uname.system)
print('Machine:', uname.machine)
print('Version:', uname.version)
print('Release:', uname.release)
print()
print('WeasyPrint version:', __version__)
print('Python version:', sys.version.split()[0])
print('Pydyf version:', pydyf.__version__)
print('Pango version:', pango.pango_version())
sys.exit()
class Parser(argparse.ArgumentParser):
def __init__(self, *args, **kwargs):
self._arguments = {}
super().__init__(*args, **kwargs)
def add_argument(self, *args, **kwargs):
super().add_argument(*args, **kwargs)
key = args[-1].lstrip('-')
kwargs['flags'] = args
kwargs['positional'] = args[-1][0] != '-'
self._arguments[key] = kwargs
@property
def docstring(self):
self._arguments['help'] = self._arguments.pop('help')
data = []
for key, args in self._arguments.items():
data.append('.. option:: ')
action = args.get('action', 'store')
for flag in args['flags']:
data.append(flag)
if not args['positional'] and action in ('store', 'append'):
data.append(f' <{key}>')
data.append(', ')
data[-1] = '\n\n'
data.append(f' {args["help"][0].upper()}{args["help"][1:]}.\n\n')
if 'choices' in args:
choices = ", ".join(args['choices'])
data.append(f' Possible choices: {choices}.\n\n')
if action == 'append':
data.append(' This option can be passed multiple times.\n\n')
return ''.join(data)
PARSER = Parser(
prog='weasyprint', description='Render web pages to PDF.')
PARSER.add_argument(
'input', help='URL or filename of the HTML input, or - for stdin')
PARSER.add_argument(
'output', help='filename where output is written, or - for stdout')
PARSER.add_argument(
'-e', '--encoding', help='force the input character encoding')
PARSER.add_argument(
'-s', '--stylesheet', action='append', dest='stylesheets',
help='URL or filename for a user CSS stylesheet')
PARSER.add_argument(
'-m', '--media-type',
help='media type to use for @media, defaults to print')
PARSER.add_argument(
'-u', '--base-url',
help='base for relative URLs in the HTML input, defaults to the '
'input’s own filename or URL or the current directory for stdin')
PARSER.add_argument(
'-a', '--attachment', action='append', dest='attachments',
help='URL or filename of a file to attach to the PDF document')
PARSER.add_argument('--pdf-identifier', help='PDF file identifier')
PARSER.add_argument(
'--pdf-variant', choices=VARIANTS, help='PDF variant to generate')
PARSER.add_argument('--pdf-version', help='PDF version number')
PARSER.add_argument(
'--pdf-forms', action='store_true', help='include PDF forms')
PARSER.add_argument(
'--uncompressed-pdf', action='store_true',
help='do not compress PDF content, mainly for debugging purpose')
PARSER.add_argument(
'--custom-metadata', action='store_true',
help='include custom HTML meta tags in PDF metadata')
PARSER.add_argument(
'-p', '--presentational-hints', action='store_true',
help='follow HTML presentational hints')
PARSER.add_argument(
'--optimize-images', action='store_true',
help='optimize size of embedded images with no quality loss')
PARSER.add_argument(
'-j', '--jpeg-quality', type=int,
help='JPEG quality between 0 (worst) to 95 (best)')
PARSER.add_argument(
'--full-fonts', action='store_true',
help='embed unmodified font files when possible')
PARSER.add_argument(
'--hinting', action='store_true',
help='keep hinting information in embedded fonts')
PARSER.add_argument(
'-c', '--cache-folder', dest='cache',
help='store cache on disk instead of memory, folder is '
'created if needed and cleaned after the PDF is generated')
PARSER.add_argument(
'-D', '--dpi', type=int,
help='set maximum resolution of images embedded in the PDF')
PARSER.add_argument(
'-v', '--verbose', action='store_true',
help='show warnings and information messages')
PARSER.add_argument(
'-d', '--debug', action='store_true', help='show debugging messages')
PARSER.add_argument(
'-q', '--quiet', action='store_true', help='hide logging messages')
PARSER.add_argument(
'--version', action='version',
version=f'WeasyPrint version {__version__}',
help='print WeasyPrint’s version number and exit')
PARSER.add_argument(
'-i', '--info', action=PrintInfo, nargs=0,
help='print system information and exit')
PARSER.add_argument(
'-O', '--optimize-size', action='append',
help='deprecated, use other options instead',
choices=('images', 'fonts', 'hinting', 'pdf', 'all', 'none'))
PARSER.set_defaults(**DEFAULT_OPTIONS)
def main(argv=None, stdout=None, stdin=None, HTML=HTML):
"""The ``weasyprint`` program takes at least two arguments:
.. code-block:: sh
weasyprint [options] <input> <output>
"""
args = PARSER.parse_args(argv)
if args.input == '-':
source = stdin or sys.stdin.buffer
if args.base_url is None:
args.base_url = '.' # current directory
elif args.base_url == '':
args.base_url = None # no base URL
else:
source = args.input
if args.output == '-':
output = stdout or sys.stdout.buffer
else:
output = args.output
# TODO: to be removed when --optimize-size is removed
optimize_size = {'fonts', 'hinting', 'pdf'}
if args.optimize_size is not None:
warn(
'The --optimize-size option is now deprecated '
'and will be removed in next version. '
'Please use the other options available in --help instead.',
category=FutureWarning)
for arg in args.optimize_size:
if arg == 'none':
optimize_size.clear()
elif arg == 'all':
optimize_size |= {'images', 'fonts', 'hinting', 'pdf'}
else:
optimize_size.add(arg)
del args.optimize_size
options = vars(args)
# TODO: to be removed when --optimize-size is removed
if 'images' in optimize_size:
options['optimize_images'] = True
if 'fonts' not in optimize_size:
options['full_fonts'] = True
if 'hinting' not in optimize_size:
options['hinting'] = True
if 'pdf' not in optimize_size:
options['uncompressed_pdf'] = True
# Default to logging to stderr.
if args.debug:
LOGGER.setLevel(logging.DEBUG)
elif args.verbose:
LOGGER.setLevel(logging.INFO)
if not args.quiet:
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
LOGGER.addHandler(handler)
html = HTML(
source, base_url=args.base_url, encoding=args.encoding,
media_type=args.media_type)
html.write_pdf(output, **options)
main.__doc__ += '\n\n' + PARSER.docstring
if __name__ == '__main__': # pragma: no cover
main()