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(
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='below',
+ help='Whether to put character and author information `beside` or `below` the icon ' +
+ '(default: below)')
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')
+ 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}')
with CachingFetcher(args.cache_path, args.timeout) as fetcher:
with open(args.out + '.tex', 'wb') as texout:
- yield Spec(args.url, fetcher, PandocTexifier(args.pandoc or 'pandoc'), 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,
+ (lambda _: None) if args.quiet else _print_status)