pdf-auto-outline 0.1.6__tar.gz → 0.1.7__tar.gz
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-0.1.6 → pdf_auto_outline-0.1.7}/PKG-INFO +2 -2
- {pdf_auto_outline-0.1.6 → pdf_auto_outline-0.1.7}/README.md +1 -1
- {pdf_auto_outline-0.1.6 → pdf_auto_outline-0.1.7}/pyproject.toml +1 -1
- pdf_auto_outline-0.1.7/src/pdf_auto_outline/__init__.py +1 -0
- {pdf_auto_outline-0.1.6 → pdf_auto_outline-0.1.7}/src/pdf_auto_outline/main.py +32 -14
- pdf_auto_outline-0.1.7/src/pdf_auto_outline/test.py +10 -0
- pdf_auto_outline-0.1.7/src/pdf_auto_outline/test.txt +13 -0
- pdf_auto_outline-0.1.6/src/pdf_auto_outline/__init__.py +0 -1
- pdf_auto_outline-0.1.6/src/pdf_auto_outline/test.py +0 -4
- {pdf_auto_outline-0.1.6 → pdf_auto_outline-0.1.7}/src/pdf_auto_outline/__main__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pdf-auto-outline
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
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>
|
|
@@ -91,7 +91,7 @@ Example commands; add to `prefs_user.config`.
|
|
|
91
91
|
|
|
92
92
|
```
|
|
93
93
|
new_command _gen_toc pdfao "%{file_path}" --sioyek path/to/sioyek -mp 4
|
|
94
|
-
new_command _edit_toc pdfao "%{file_path}"
|
|
94
|
+
new_command _edit_toc pdfao "%{file_path}" -e
|
|
95
95
|
```
|
|
96
96
|
|
|
97
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.
|
|
@@ -74,7 +74,7 @@ Example commands; add to `prefs_user.config`.
|
|
|
74
74
|
|
|
75
75
|
```
|
|
76
76
|
new_command _gen_toc pdfao "%{file_path}" --sioyek path/to/sioyek -mp 4
|
|
77
|
-
new_command _edit_toc pdfao "%{file_path}"
|
|
77
|
+
new_command _edit_toc pdfao "%{file_path}" -e
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
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.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.1.7'
|
|
@@ -160,7 +160,7 @@ def generate_txtfile(toc_entries, txtfile=get_tmpfile()):
|
|
|
160
160
|
TABLE OF CONTENTS OUTLINE
|
|
161
161
|
4spaces/lvl text | pg# | {details dictionary} OR y-coord
|
|
162
162
|
|
|
163
|
-
Type '
|
|
163
|
+
Type '\\' as the first character of this file to cancel
|
|
164
164
|
============================================================
|
|
165
165
|
|
|
166
166
|
""")
|
|
@@ -183,39 +183,56 @@ def generate_txtfile(toc_entries, txtfile=get_tmpfile()):
|
|
|
183
183
|
|
|
184
184
|
def parse_txtfile(f, tablevel=2) -> list:
|
|
185
185
|
toc_entries = []
|
|
186
|
-
if (c := f.read(1)) == '
|
|
186
|
+
if (c := f.read(1)) == '\\':
|
|
187
187
|
log('Outline not written')
|
|
188
188
|
exit()
|
|
189
189
|
elif c == '=':
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
for _ in range(7):
|
|
191
|
+
f.readline()
|
|
192
|
+
else:
|
|
193
|
+
f.seek(0)
|
|
192
194
|
|
|
193
|
-
for i in
|
|
195
|
+
for ln, i in enumerate(f):
|
|
194
196
|
i = i.replace('\t', ' '*tablevel)
|
|
195
197
|
lvl = (len(i) - len(i.lstrip())) // 4 + 1
|
|
196
198
|
a = i.lstrip().split(' | ')
|
|
197
|
-
|
|
199
|
+
# print(i)
|
|
200
|
+
if (l := len(a)) == 2:
|
|
198
201
|
toc_entries.append(
|
|
199
202
|
[lvl, a[0], int(a[1])]
|
|
200
203
|
)
|
|
201
|
-
|
|
204
|
+
elif l == 3:
|
|
202
205
|
toc_entries.append(
|
|
203
206
|
[lvl, a[0], int(a[1]), eval(a[2])]
|
|
204
207
|
)
|
|
208
|
+
else:
|
|
209
|
+
log(f'Error parsing line {ln+1}: {i}')
|
|
210
|
+
exit()
|
|
205
211
|
|
|
206
212
|
f.close()
|
|
207
213
|
|
|
208
214
|
return toc_entries
|
|
209
215
|
|
|
210
|
-
def embed_toc(pdfpath, toc_entries, newfile=''):
|
|
216
|
+
def embed_toc(pdfpath, toc_entries, newfile='', offset=0):
|
|
217
|
+
if offset != 0:
|
|
218
|
+
toc_entries = [[a, b, c + offset, *d] for a, b, c, *d in toc_entries]
|
|
211
219
|
doc = pymupdf.open(pdfpath)
|
|
212
220
|
doc.set_toc(toc_entries, collapse=2)
|
|
213
221
|
if newfile:
|
|
214
222
|
doc.save(newfile)
|
|
215
223
|
log(f"toc written to '{newfile}'")
|
|
216
|
-
|
|
224
|
+
elif doc.can_save_incrementally():
|
|
217
225
|
doc.saveIncr()
|
|
218
226
|
log(f"toc saved to '{pdfpath}'")
|
|
227
|
+
else:
|
|
228
|
+
log('cannot save to original; saving to new file...')
|
|
229
|
+
new_path = '_new.'.join(pdfpath.split('.'))
|
|
230
|
+
try:
|
|
231
|
+
doc.save(new_path, garbage=4, deflate=True, use_objstms=True)
|
|
232
|
+
except KeyboardInterrupt as e:
|
|
233
|
+
log('Cancelled')
|
|
234
|
+
exit()
|
|
235
|
+
log(f"toc written to '{new_path}'")
|
|
219
236
|
|
|
220
237
|
def get_toc_custom(doc) -> list:
|
|
221
238
|
toc_entries = [[*i[:3], i[3].get('to')[1]] for i in doc.get_toc(False)]
|
|
@@ -238,8 +255,9 @@ def main():
|
|
|
238
255
|
parser.add_argument('-se', '--superedit', action='store_true', help='edit pdf toc (more attibutes available)')
|
|
239
256
|
parser.add_argument('-i', '--infile', type=str, metavar='<file>', help='write toc from file to pdf')
|
|
240
257
|
parser.add_argument('-t', '--tablevel', type=int, metavar='<n>', help='tab = n toc nesting levels (default 2)', default=2)
|
|
258
|
+
parser.add_argument('-os', '--offset', type=int, metavar='<n>', help='toc page offset; use with infile', default=0)
|
|
241
259
|
parser.add_argument('--sioyek', type=str, metavar='<path>', help='for users of the Sioyek pdf viewer')
|
|
242
|
-
parser.add_argument('--version', action='version', version='%(prog)s 0.1.
|
|
260
|
+
parser.add_argument('--version', action='version', version='%(prog)s 0.1.7')
|
|
243
261
|
|
|
244
262
|
args = parser.parse_args()
|
|
245
263
|
|
|
@@ -265,11 +283,11 @@ def main():
|
|
|
265
283
|
f = generate_txtfile(get_toc_custom(doc))
|
|
266
284
|
edit_txtfile(f)
|
|
267
285
|
toc_entries = parse_txtfile(f, args.tablevel)
|
|
268
|
-
embed_toc(args.filename, toc_entries, args.out)
|
|
286
|
+
embed_toc(args.filename, toc_entries, args.out, args.offset)
|
|
269
287
|
os.remove(f.name)
|
|
270
288
|
elif args.infile:
|
|
271
289
|
toc_entries = parse_txtfile(open(args.infile, encoding='utf-8'), args.tablevel)
|
|
272
|
-
embed_toc(args.filename, toc_entries, args.out)
|
|
290
|
+
embed_toc(args.filename, toc_entries, args.out, args.offset)
|
|
273
291
|
else: # generate toc
|
|
274
292
|
start = perf_counter()
|
|
275
293
|
toc_entries = generate_toc_nnet(args.filename, args.multiprocess)
|
|
@@ -278,12 +296,12 @@ def main():
|
|
|
278
296
|
log(f"finished in {end - start:<4.1f} s")
|
|
279
297
|
toc_entries = align_toc_lvls(toc_entries)
|
|
280
298
|
if args.straight:
|
|
281
|
-
embed_toc(args.filename, toc_entries, args.out)
|
|
299
|
+
embed_toc(args.filename, toc_entries, args.out, args.offset)
|
|
282
300
|
else:
|
|
283
301
|
f = generate_txtfile(toc_entries)
|
|
284
302
|
edit_txtfile(f)
|
|
285
303
|
toc_entries = parse_txtfile(f, args.tablevel)
|
|
286
|
-
embed_toc(args.filename, toc_entries, args.out)
|
|
304
|
+
embed_toc(args.filename, toc_entries, args.out, args.offset)
|
|
287
305
|
os.remove(f.name)
|
|
288
306
|
|
|
289
307
|
# if args.sioyek and not args.out:
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
============================================================
|
|
2
|
+
TABLE OF CONTENTS OUTLINE
|
|
3
|
+
4spaces/lvl text | pg# | {details dictionary} OR y-coord
|
|
4
|
+
|
|
5
|
+
Type '\\' as the first character of this file to cancel
|
|
6
|
+
============================================================
|
|
7
|
+
|
|
8
|
+
1
|
|
9
|
+
2
|
|
10
|
+
3
|
|
11
|
+
4
|
|
12
|
+
5
|
|
13
|
+
6
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.1.6'
|
|
File without changes
|