]> git.scottworley.com Git - paperdoorknob/blob - args.py
c5506729797f32ac2e8aaa9b050aae065da81082
[paperdoorknob] / args.py
1 # paperdoorknob: Print glowfic
2 #
3 # This program is free software: you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License as published by the
5 # Free Software Foundation, version 3.
6
7
8 from argparse import ArgumentParser
9 from contextlib import contextmanager
10 import os.path
11 from sys import stderr
12
13 from typing import Iterator
14
15 from xdg_base_dirs import xdg_cache_home
16
17 from domfilter import ApplyDOMFilters, DOMFilters
18 from fetch import CachingFetcher
19 from glowfic import BesideIconLayout, BelowIconLayout, Layout
20 from htmlfilter import ApplyHTMLFilters, HTMLFilters
21 from texfilter import ApplyTexFilters, TexFilters
22 from images import DiskImageStore
23 from spec import Spec
24 from texify import PandocTexifier
25
26
27 def _print_status(msg: str) -> None:
28 print(msg, file=stderr, end='' if msg.endswith('\r') else '\n')
29
30
31 def _command_line_parser() -> ArgumentParser:
32 parser = ArgumentParser(prog='paperdoorknob', description='Print glowfic')
33 parser.add_argument(
34 '--cache_path',
35 metavar='PATH',
36 help='Where to keep the http cache (instead of %(default)s)',
37 default=os.path.join(xdg_cache_home(), "paperdoorknob"))
38 parser.add_argument(
39 '--domfilters',
40 help='Which DOM filters to use (default: %(default)s)',
41 default=','.join(f[0] for f in DOMFilters))
42 parser.add_argument(
43 '--geometry',
44 help='''Page size and margin control
45 See https://faculty.bard.edu/bloch/geometry.pdf for details
46 (default: %(default)s)''',
47 default='paperwidth=5.5in,paperheight=8.5in,nohead,' +
48 'tmargin=15mm,hmargin=15mm,bmargin=17mm,foot=4mm')
49 parser.add_argument(
50 '--htmlfilters',
51 help='Which HTML filters to use (default: %(default)s)',
52 default=','.join(f[0] for f in HTMLFilters))
53 parser.add_argument(
54 '--image_size',
55 help='How large the icon images are, in mm',
56 default=20)
57 parser.add_argument(
58 '--layout',
59 default='below',
60 help='Whether to put character and author information `beside` or `below` the icon ' +
61 '(default: below)')
62 parser.add_argument(
63 '--out',
64 help='The filename stem at which to write output ' +
65 '(eg: "%(default)s" produces %(default)s.tex, %(default)s.pdf, etc.)',
66 default='book')
67 parser.add_argument('--pandoc', help='Location of the pandoc executable')
68 parser.add_argument(
69 '--quiet',
70 action='store_true',
71 help='Suppress progress messages')
72 parser.add_argument(
73 '--texfilters',
74 help='Which TeX filters to use (default: %(default)s)',
75 default=','.join(f[0] for f in TexFilters))
76 parser.add_argument(
77 '--timeout',
78 help='How long to wait for HTTP requests, in seconds',
79 default=30)
80 parser.add_argument(
81 'url',
82 help='URL to retrieve (example: https://www.projectlawful.com/posts/4582 )')
83 return parser
84
85
86 @contextmanager
87 def spec_from_commandline_args() -> Iterator[Spec]:
88 args = _command_line_parser().parse_args()
89 texifier = PandocTexifier(args.pandoc or 'pandoc')
90 layout: Layout
91 if args.layout == 'below':
92 layout = BelowIconLayout(texifier, args.image_size)
93 elif args.layout == 'beside':
94 layout = BesideIconLayout(texifier, args.image_size)
95 else:
96 raise ValueError(f'Unknown layout: {args.layout}')
97 with CachingFetcher(args.cache_path, args.timeout) as fetcher:
98 with open(args.out + '.tex', 'wb') as texout:
99 yield Spec(
100 args.url,
101 fetcher,
102 DiskImageStore(args.out + '_images', fetcher),
103 lambda x: ApplyHTMLFilters(args.htmlfilters, x),
104 lambda x: ApplyDOMFilters(args.domfilters, x),
105 lambda x: ApplyTexFilters(args.texfilters, x),
106 layout,
107 args.geometry,
108 texout,
109 (lambda _: None) if args.quiet else _print_status)