pdf-auto-outline 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pdf_auto_outline/__init__.py +1 -1
- pdf_auto_outline/main.py +53 -46
- pdf_auto_outline/test.py +4 -0
- {pdf_auto_outline-0.1.5.dist-info → pdf_auto_outline-0.1.6.dist-info}/METADATA +4 -3
- pdf_auto_outline-0.1.6.dist-info/RECORD +8 -0
- pdf_auto_outline-0.1.5.dist-info/RECORD +0 -7
- {pdf_auto_outline-0.1.5.dist-info → pdf_auto_outline-0.1.6.dist-info}/WHEEL +0 -0
- {pdf_auto_outline-0.1.5.dist-info → pdf_auto_outline-0.1.6.dist-info}/entry_points.txt +0 -0
pdf_auto_outline/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '0.1.
|
|
1
|
+
__version__ = '0.1.6'
|
pdf_auto_outline/main.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import pymupdf.layout
|
|
2
|
-
from pymupdf import Point
|
|
3
2
|
from time import perf_counter
|
|
4
3
|
from multiprocessing import Pool
|
|
5
4
|
import os
|
|
6
5
|
import subprocess
|
|
7
6
|
import argparse
|
|
7
|
+
import tempfile
|
|
8
8
|
|
|
9
9
|
SIOYEK = None
|
|
10
10
|
|
|
@@ -148,7 +148,12 @@ def align_toc_lvls(toc_entries: list) -> list:
|
|
|
148
148
|
|
|
149
149
|
return toc_entries
|
|
150
150
|
|
|
151
|
-
def
|
|
151
|
+
def get_tmpfile():
|
|
152
|
+
return tempfile.NamedTemporaryFile(
|
|
153
|
+
mode='w+', encoding='utf-8', delete=False, suffix='.txt'
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
def generate_txtfile(toc_entries, txtfile=get_tmpfile()):
|
|
152
157
|
import textwrap
|
|
153
158
|
txt = textwrap.dedent("""\
|
|
154
159
|
============================================================
|
|
@@ -168,34 +173,37 @@ def generate_txtfile(toc_entries, txtfile='outline.txt') -> str:
|
|
|
168
173
|
txt += '\n'.join(f"{' '*4 * (i[0] - 1)}{i[1]} | {i[2]}"
|
|
169
174
|
for i in toc_entries)
|
|
170
175
|
|
|
171
|
-
|
|
172
|
-
|
|
176
|
+
txtfile.write(txt)
|
|
177
|
+
txtfile.flush()
|
|
178
|
+
txtfile.seek(0)
|
|
173
179
|
|
|
174
180
|
return txtfile
|
|
175
181
|
|
|
176
182
|
|
|
177
|
-
|
|
183
|
+
|
|
184
|
+
def parse_txtfile(f, tablevel=2) -> list:
|
|
178
185
|
toc_entries = []
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
186
|
+
if (c := f.read(1)) == 'C':
|
|
187
|
+
log('Outline not written')
|
|
188
|
+
exit()
|
|
189
|
+
elif c == '=':
|
|
190
|
+
lines = f.readlines()[7:]
|
|
191
|
+
else: lines = f.read()
|
|
192
|
+
|
|
193
|
+
for i in lines:
|
|
194
|
+
i = i.replace('\t', ' '*tablevel)
|
|
195
|
+
lvl = (len(i) - len(i.lstrip())) // 4 + 1
|
|
196
|
+
a = i.lstrip().split(' | ')
|
|
197
|
+
if len(a) < 3:
|
|
198
|
+
toc_entries.append(
|
|
199
|
+
[lvl, a[0], int(a[1])]
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
toc_entries.append(
|
|
203
|
+
[lvl, a[0], int(a[1]), eval(a[2])]
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
f.close()
|
|
199
207
|
|
|
200
208
|
return toc_entries
|
|
201
209
|
|
|
@@ -213,15 +221,12 @@ def get_toc_custom(doc) -> list:
|
|
|
213
221
|
toc_entries = [[*i[:3], i[3].get('to')[1]] for i in doc.get_toc(False)]
|
|
214
222
|
return toc_entries
|
|
215
223
|
|
|
216
|
-
def edit_txtfile(
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
name = os.name
|
|
220
|
-
if name == 'nt':
|
|
221
|
-
subprocess.run(['start', '/WAIT', txtfile], shell=True)
|
|
224
|
+
def edit_txtfile(f):
|
|
225
|
+
if os.name == 'nt':
|
|
226
|
+
subprocess.run(['start', '/WAIT', f.name], shell=True)
|
|
222
227
|
else: # name == 'posix':
|
|
223
228
|
editor = os.environ.get('EDITOR', 'vi')
|
|
224
|
-
subprocess.run([editor,
|
|
229
|
+
subprocess.run([editor, f.name])
|
|
225
230
|
|
|
226
231
|
def main():
|
|
227
232
|
parser = argparse.ArgumentParser(prog='pdfao')
|
|
@@ -234,19 +239,19 @@ def main():
|
|
|
234
239
|
parser.add_argument('-i', '--infile', type=str, metavar='<file>', help='write toc from file to pdf')
|
|
235
240
|
parser.add_argument('-t', '--tablevel', type=int, metavar='<n>', help='tab = n toc nesting levels (default 2)', default=2)
|
|
236
241
|
parser.add_argument('--sioyek', type=str, metavar='<path>', help='for users of the Sioyek pdf viewer')
|
|
237
|
-
parser.add_argument('--version', action='version', version='%(prog)s 0.1.
|
|
242
|
+
parser.add_argument('--version', action='version', version='%(prog)s 0.1.6')
|
|
238
243
|
|
|
239
244
|
args = parser.parse_args()
|
|
240
245
|
|
|
246
|
+
if args.out:
|
|
247
|
+
args.out = os.path.join(
|
|
248
|
+
os.path.dirname(args.filename),
|
|
249
|
+
args.out)
|
|
250
|
+
|
|
241
251
|
if args.sioyek:
|
|
242
252
|
from sioyek.sioyek import Sioyek
|
|
243
253
|
global SIOYEK
|
|
244
254
|
SIOYEK = Sioyek(args.sioyek)
|
|
245
|
-
if args.out:
|
|
246
|
-
args.out = os.path.join(
|
|
247
|
-
os.path.dirname(args.filename),
|
|
248
|
-
args.out
|
|
249
|
-
)
|
|
250
255
|
# local_db = args.sioyek[1]
|
|
251
256
|
# shared_db = args.sioyek[2]
|
|
252
257
|
# pdf_path = args.sioyek[3]
|
|
@@ -255,14 +260,15 @@ def main():
|
|
|
255
260
|
if args.edit or args.superedit:
|
|
256
261
|
doc = pymupdf.Document(args.filename)
|
|
257
262
|
if args.superedit:
|
|
258
|
-
generate_txtfile(doc.get_toc(False))
|
|
263
|
+
f = generate_txtfile(doc.get_toc(False))
|
|
259
264
|
else:
|
|
260
|
-
generate_txtfile(get_toc_custom(doc))
|
|
261
|
-
edit_txtfile()
|
|
262
|
-
toc_entries = parse_txtfile(
|
|
265
|
+
f = generate_txtfile(get_toc_custom(doc))
|
|
266
|
+
edit_txtfile(f)
|
|
267
|
+
toc_entries = parse_txtfile(f, args.tablevel)
|
|
263
268
|
embed_toc(args.filename, toc_entries, args.out)
|
|
269
|
+
os.remove(f.name)
|
|
264
270
|
elif args.infile:
|
|
265
|
-
toc_entries = parse_txtfile(args.infile, args.tablevel)
|
|
271
|
+
toc_entries = parse_txtfile(open(args.infile, encoding='utf-8'), args.tablevel)
|
|
266
272
|
embed_toc(args.filename, toc_entries, args.out)
|
|
267
273
|
else: # generate toc
|
|
268
274
|
start = perf_counter()
|
|
@@ -274,10 +280,11 @@ def main():
|
|
|
274
280
|
if args.straight:
|
|
275
281
|
embed_toc(args.filename, toc_entries, args.out)
|
|
276
282
|
else:
|
|
277
|
-
generate_txtfile(toc_entries)
|
|
278
|
-
edit_txtfile()
|
|
279
|
-
toc_entries = parse_txtfile(
|
|
283
|
+
f = generate_txtfile(toc_entries)
|
|
284
|
+
edit_txtfile(f)
|
|
285
|
+
toc_entries = parse_txtfile(f, args.tablevel)
|
|
280
286
|
embed_toc(args.filename, toc_entries, args.out)
|
|
287
|
+
os.remove(f.name)
|
|
281
288
|
|
|
282
289
|
# if args.sioyek and not args.out:
|
|
283
290
|
# to_hash = get_md5_hash(args.filename)
|
pdf_auto_outline/test.py
ADDED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pdf-auto-outline
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Automatically generate and edit PDF table of contents / outline
|
|
5
5
|
Author: Rossikos
|
|
6
6
|
Author-email: Rossikos <216631970+rossikos@users.noreply.github.com>
|
|
@@ -82,7 +82,6 @@ The optional part can be one of:
|
|
|
82
82
|
```
|
|
83
83
|
| None same as not including it
|
|
84
84
|
| 241.2 y-ordinate
|
|
85
|
-
| Point(72.0, 363.9) x and y coords
|
|
86
85
|
| {<dictionary>} dictionary with more attributes for the ToC entry
|
|
87
86
|
```
|
|
88
87
|
|
|
@@ -92,8 +91,10 @@ Example commands; add to `prefs_user.config`.
|
|
|
92
91
|
|
|
93
92
|
```
|
|
94
93
|
new_command _gen_toc pdfao "%{file_path}" --sioyek path/to/sioyek -mp 4
|
|
95
|
-
new_command _edit_toc pdfao "%{file_path}"
|
|
94
|
+
new_command _edit_toc pdfao "%{file_path}"
|
|
96
95
|
```
|
|
97
96
|
|
|
97
|
+
The sioyek library and flag are optional; they allow logging to the status bar. This is more useful for ToC generation where you may want a progress bar.
|
|
98
|
+
|
|
98
99
|
If you don't wish to install from PyPI, download source and use `python3 -m path/to/src/pdf_auto_outline` in place of `pdfao`.
|
|
99
100
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
pdf_auto_outline/__init__.py,sha256=gW5NUxwGdPsiQjn0cOuuQT11pfthByI5DITDg_HMhLQ,22
|
|
2
|
+
pdf_auto_outline/__main__.py,sha256=mRKsAFeG5R17vTYubIKregAve4vnKc-nk7jY3tcK4wI,78
|
|
3
|
+
pdf_auto_outline/main.py,sha256=AWbXZNVw5e34v005qtoCGyTzNbT3T1mOo6xeLl-Q82k,9883
|
|
4
|
+
pdf_auto_outline/test.py,sha256=2wIjM8xqnDjHiokFF0WUNw0o_oTGW91V-MifHoLw4Rw,47
|
|
5
|
+
pdf_auto_outline-0.1.6.dist-info/WHEEL,sha256=5w2T7AS2mz1-rW9CNagNYWRCaB0iQqBMYLwKdlgiR4Q,78
|
|
6
|
+
pdf_auto_outline-0.1.6.dist-info/entry_points.txt,sha256=HBvhmxJs8hHqbbpJmVTbBH3xy19Hk655O_ySwFC_53w,100
|
|
7
|
+
pdf_auto_outline-0.1.6.dist-info/METADATA,sha256=Rw9x1kQxghKSGVu31qbnLASX87QMjAeUzg2JMAecupU,3287
|
|
8
|
+
pdf_auto_outline-0.1.6.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
pdf_auto_outline/__init__.py,sha256=DQiXHqQ3C29f_--ye7aVMDPnITrl9M0zMU42LYY48zE,22
|
|
2
|
-
pdf_auto_outline/__main__.py,sha256=mRKsAFeG5R17vTYubIKregAve4vnKc-nk7jY3tcK4wI,78
|
|
3
|
-
pdf_auto_outline/main.py,sha256=d5D6qlnWKU1_bGiUKc82mLDwxhH6D-0WRBoxiDHzHsU,10020
|
|
4
|
-
pdf_auto_outline-0.1.5.dist-info/WHEEL,sha256=5w2T7AS2mz1-rW9CNagNYWRCaB0iQqBMYLwKdlgiR4Q,78
|
|
5
|
-
pdf_auto_outline-0.1.5.dist-info/entry_points.txt,sha256=HBvhmxJs8hHqbbpJmVTbBH3xy19Hk655O_ySwFC_53w,100
|
|
6
|
-
pdf_auto_outline-0.1.5.dist-info/METADATA,sha256=cAkatx-gjHs3-Sg9cQNeCQosrxHikoPjo1Q2AYbHVHw,3198
|
|
7
|
-
pdf_auto_outline-0.1.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|