# paperdoorknob: Print glowfic # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, version 3. from argparse import ArgumentParser from contextlib import contextmanager import os.path from sys import stderr from typing import Iterator from xdg_base_dirs import xdg_cache_home from domfilter import ApplyDOMFilters, DOMFilters from fetch import CachingFetcher from glowfic import BesideIconLayout, BelowIconLayout, Layout from htmlfilter import ApplyHTMLFilters, HTMLFilters from texfilter import ApplyTexFilters, TexFilters from images import DiskImageStore from spec import Spec from texify import PandocTexifier def _print_status(msg: str) -> None: print(msg, file=stderr, end='' if msg.endswith('\r') else '\n') def _command_line_parser() -> ArgumentParser: parser = ArgumentParser(prog='paperdoorknob', description='Print glowfic') parser.add_argument( '--cache-path', metavar='PATH', help='Where to keep the http cache (instead of %(default)s)', default=os.path.join(xdg_cache_home(), "paperdoorknob")) parser.add_argument( '--domfilters', help='Which DOM filters to use (default: %(default)s)', default=','.join(f[0] for f in DOMFilters)) parser.add_argument( '--geometry', help='''Page size and margin control See https://faculty.bard.edu/bloch/geometry.pdf for details (default: %(default)s)''', default='paperwidth=5.5in,paperheight=8.5in,nohead,' + 'tmargin=15mm,hmargin=15mm,bmargin=17mm,foot=4mm') parser.add_argument( '--htmlfilters', help='Which HTML filters to use (default: %(default)s)', default=','.join(f[0] for f in HTMLFilters)) parser.add_argument( '--image-size', help='How large the icon images are, in mm', default=20) parser.add_argument( '--layout', default='beside', help='Whether to put character and author information `beside` or `below` the icon ' + '(default: beside)') parser.add_argument( '--out', help='The filename stem at which to write output ' + '(eg: "%(default)s" produces %(default)s.tex, %(default)s.pdf, etc.)', default='book') parser.add_argument('--pandoc', help='Location of the pandoc executable') parser.add_argument( '--quiet', action='store_true', help='Suppress progress messages') parser.add_argument( '--texfilters', help='Which TeX filters to use (default: %(default)s)', default=','.join(f[0] for f in TexFilters)) parser.add_argument( '--timeout', help='How long to wait for HTTP requests, in seconds', default=30) parser.add_argument( 'url', help='URL to retrieve (example: https://www.projectlawful.com/posts/4582 )') return parser @contextmanager def spec_from_commandline_args() -> Iterator[Spec]: args = _command_line_parser().parse_args() texifier = PandocTexifier(args.pandoc or 'pandoc') layout: Layout if args.layout == 'below': layout = BelowIconLayout(texifier, args.image_size) elif args.layout == 'beside': layout = BesideIconLayout(texifier, args.image_size) else: raise ValueError(f'Unknown layout: {args.layout}') log = (lambda _: None) if args.quiet else _print_status with CachingFetcher(args.cache_path, args.timeout, log) as fetcher: with open(args.out + '.tex', 'wb') as texout: yield Spec( args.url, fetcher, DiskImageStore(args.out + '_images', fetcher), lambda x: ApplyHTMLFilters(args.htmlfilters, x), lambda x: ApplyDOMFilters(args.domfilters, x), lambda x: ApplyTexFilters(args.texfilters, x), layout, args.geometry, texout, log)