Mercurial > cgi-bin > hgweb.cgi > curlyq
annotate curlyq @ 23:dc30266d4d5b
Add --backtick mode.
author | David Barts <n5jrn@me.com> |
---|---|
date | Wed, 15 Jan 2020 09:06:55 -0800 |
parents | a771878f6cf4 |
children | f4cc6d8cafe8 |
rev | line source |
---|---|
3 | 1 #!/usr/bin/env python3 |
2 # -*- coding: utf-8 -*- | |
3 | |
22
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
4 # I m p o r t s |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
5 |
3 | 6 import os, sys |
7 import argparse | |
8 import codecs | |
9 | |
4 | 10 from curlers import TextCurler, HtmlCurler, uncurl |
10 | 11 from runes import Workspace |
3 | 12 |
13 # V a r i a b l e s | |
14 | |
15 # Name invoked by | |
16 MYNAME = os.path.basename(sys.argv[0]) | |
17 | |
18 # Streams | |
19 input_fp = None | |
20 output_fp = None | |
21 | |
22
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
22 # Codecs we support |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
23 CODECS_TO_NAME = {} |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
24 for i in [ "UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE", "UTF-32", "UTF-32LE", "UTF-32BE" ]: |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
25 CODECS_TO_NAME[codecs.lookup(i)] = i |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
26 del i |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
27 |
23 | 28 # For feet/inches/min/sec |
29 BACKT = "`" | |
30 FTMIN = "'" | |
31 INSEC = '"' | |
32 | |
22
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
33 # C l a s s e s |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
34 |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
35 class SafeWorkspace(Workspace): |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
36 def __getitem__(self, key): |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
37 try: |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
38 return super().__getitem__(key) |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
39 except IndexError: |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
40 return "" |
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
41 |
3 | 42 # F u n c t i o n s |
43 | |
44 def normal(): | |
4 | 45 global input_fp, output_fp, args |
22
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
46 ws = SafeWorkspace() |
10 | 47 curler = TextCurler(ws) |
48 while True: | |
49 line = input_fp.readline() | |
50 ws.append(line) | |
51 if line == "" or line == "\n": | |
52 if args.force: uncurl(ws) | |
53 curler.feed() | |
23 | 54 if args.backtick: fims(ws) |
10 | 55 output_fp.write(str(ws)) |
56 ws.clear() | |
57 if line == "": | |
58 break | |
3 | 59 |
60 def flowed(): | |
61 global input_fp, output_fp, args | |
22
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
62 ws = SafeWorkspace() |
10 | 63 curler = TextCurler(ws) |
64 while True: | |
65 line = input_fp.readline() | |
66 if line == "": | |
67 break | |
68 ws.append(line) | |
69 if args.force: uncurl(ws) | |
70 curler.feed() | |
23 | 71 if args.backtick: fims(ws) |
10 | 72 output_fp.write(str(ws)) |
73 ws.clear() | |
3 | 74 |
75 def html(): | |
76 global input_fp, output_fp | |
22
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
77 ws = SafeWorkspace(input_fp.read()) |
10 | 78 curler = HtmlCurler(ws) |
79 if args.force: uncurl(ws) | |
80 curler.feed() | |
81 output_fp.write(str(ws)) | |
3 | 82 |
5 | 83 def do_uncurl(): |
84 global input_fp, output_fp | |
22
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
85 ws = SafeWorkspace(input_fp.read()) |
10 | 86 uncurl(ws) |
87 output_fp.write(str(ws)) | |
5 | 88 |
23 | 89 def fims(buf): |
90 pos = 0 | |
91 while True: | |
92 pos = buf.find(BACKT) | |
93 if pos < 0: | |
94 break | |
95 if buf[pos+1] == BACKT: | |
96 buf[pos:pos+2] = INSEC | |
97 else: | |
98 buf[pos] = FTMIN | |
99 pos += 1 | |
100 | |
3 | 101 # M a i n P r o g r a m |
102 | |
103 # Parse arguments | |
8 | 104 parser = argparse.ArgumentParser( |
105 description='Make straight quotes curly.', prog=MYNAME) | |
3 | 106 group = parser.add_mutually_exclusive_group() |
23 | 107 parser.add_argument("--backtick", action="store_true", help="Use backticks on input for ft/in/min/sec.") |
3 | 108 group.add_argument("--flowed", action="store_true", help="Input is flowed text.") |
109 group.add_argument("--html", action="store_true", help="Input is HTML.") | |
5 | 110 group.add_argument("--uncurl", action="store_true", help="Uncurl quotes instead of curling them.") |
3 | 111 parser.add_argument("--force", action="store_true", help="Force all quotes to straight ones first.") |
8 | 112 parser.add_argument("--icoding", default="UTF-8", help="Input encoding (default UTF-8).") |
3 | 113 parser.add_argument("--inplace", action="store_true", help="Edit file in-place.") |
8 | 114 parser.add_argument("--ocoding", default="UTF-8", help="Output encoding (default UTF-8).") |
3 | 115 parser.add_argument("input", nargs="?", help="Input file.") |
116 parser.add_argument("output", nargs="?", help="Output file.") | |
117 try: | |
118 args = parser.parse_args() | |
119 except SystemExit: | |
120 sys.exit(2) | |
121 | |
23 | 122 # Sanity check |
123 if args.html and args.backtick: | |
124 sys.stderr.write(MYNAME + ": --backtick not supported in --html mode\n") | |
125 sys.exit(2) | |
126 | |
3 | 127 # Sanity-check codings |
128 try: | |
129 codec = codecs.lookup(args.icoding) | |
130 codec = codecs.lookup(args.ocoding) | |
131 except LookupError as e: | |
132 sys.stderr.write("{0}: {1!s}\n".format(MYNAME, e)) | |
133 sys.exit(2) | |
22
a771878f6cf4
Remove deadwood, update runes.py.
David Barts <n5jrn@me.com>
parents:
10
diff
changeset
|
134 if codec not in CODECS_TO_NAME: |
8 | 135 sys.stderr.write("{0}: {1!r} output coding does not support Unicode\n".format(MYNAME, args.ocoding)) |
3 | 136 sys.exit(1) |
137 del codec | |
138 | |
139 # Get streams | |
140 try: | |
141 if args.input and (not args.output) and args.inplace: | |
142 args.output = args.input | |
143 args.input += "~" | |
5 | 144 os.rename(args.output, args.input) |
3 | 145 if args.input: |
146 input_fp = open(args.input, "r", encoding=args.icoding) | |
147 else: | |
148 input_fp = open(0, "r", encoding=args.icoding) | |
149 if args.output: | |
150 output_fp = open(args.output, "w", encoding=args.ocoding) | |
151 else: | |
152 output_fp = open(1, "w", encoding=args.ocoding) | |
153 except (OSError, LookupError) as e: | |
154 sys.stderr.write("{0}: {1!s}\n".format(MYNAME, e)) | |
155 sys.exit(1) | |
156 | |
157 # Choose our mode | |
158 if args.flowed: | |
159 flowed() | |
160 elif args.html: | |
161 html() | |
5 | 162 elif args.uncurl: |
163 do_uncurl() | |
3 | 164 else: |
165 normal() |