Commit b74e7989c34e041e7a6461e00ae045045273ca51

Authored by Jay Berkenbilt
1 parent e01bbccb

QPDFJob_json: implement handlers except pages

job.sums
@@ -6,12 +6,12 @@ include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf5 @@ -6,12 +6,12 @@ include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf5
6 include/qpdf/auto_job_c_main.hh 516adb23cc7e44e614e436880be870d0574e4ebbc706cd855a1360000eed31bb 6 include/qpdf/auto_job_c_main.hh 516adb23cc7e44e614e436880be870d0574e4ebbc706cd855a1360000eed31bb
7 include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671 7 include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671
8 include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50 8 include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50
9 -job.yml 7433861fa281197aa275d624a334aa324ec63839c5e56a24448ab64d0b75587c 9 +job.yml 6389b89c25f0f07fa54bfc3d9f24f814aac5566ace43666f81476781db616ea1
10 libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6 10 libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6
11 libqpdf/qpdf/auto_job_help.hh 23c79f1d2c02bda28f64aace17f69487205c797e7ae2234892cbbabab49d6d47 11 libqpdf/qpdf/auto_job_help.hh 23c79f1d2c02bda28f64aace17f69487205c797e7ae2234892cbbabab49d6d47
12 libqpdf/qpdf/auto_job_init.hh 8e9e31b6099a662497339b27f6e2d7f779f35011e88a834bee8811c33405a0fe 12 libqpdf/qpdf/auto_job_init.hh 8e9e31b6099a662497339b27f6e2d7f779f35011e88a834bee8811c33405a0fe
13 -libqpdf/qpdf/auto_job_json_decl.hh d315f920a32d7a5a2272807e6813d463c3e1877a9d735e44e8417b5f1461b87a  
14 -libqpdf/qpdf/auto_job_json_init.hh 08e6ee8a509bc592e3aa6f7a1d3a6d18cdf4803e6220147855caf675e0a299ce  
15 -libqpdf/qpdf/auto_job_schema.hh 6ec5b9dd3b4709b49fb3b928c4d9cde8b35ad938a0945f81c9a3da6c3bf9a3c1 13 +libqpdf/qpdf/auto_job_json_decl.hh 8a6e3b25e01969f1c8e2c9ec781f7f2e89b57e67e65d5dc7445ad9124b694b9a
  14 +libqpdf/qpdf/auto_job_json_init.hh 48888c602de4cc13040cff26569e162d6ebb5aec6ab959164d432cfe1058eb23
  15 +libqpdf/qpdf/auto_job_schema.hh 9e19fb0b8ddd6fe13da12f1f98c27f6d558fc4706a56a63697e529b3140a457c
16 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3 16 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3
17 manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882 17 manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882
@@ -318,19 +318,6 @@ json: @@ -318,19 +318,6 @@ json:
318 Enc256.print: 318 Enc256.print:
319 allow-insecure: 319 allow-insecure:
320 force-R5: 320 force-R5:
321 - _options:  
322 - allow-weak-crypto:  
323 - deterministic-id:  
324 - keep-files-open:  
325 - keep-files-open-threshold:  
326 - no-warn:  
327 - verbose:  
328 - warning-exit-0:  
329 - ignore-xref-streams:  
330 - password-is-hex-key:  
331 - password-mode:  
332 - suppress-password-recovery:  
333 - suppress-recovery:  
334 _inspect: 321 _inspect:
335 check: 322 check:
336 check-linearization: 323 check-linearization:
@@ -353,13 +340,24 @@ json: @@ -353,13 +340,24 @@ json:
353 - null 340 - null
354 json-object: 341 json-object:
355 - null 342 - null
356 - _transform: 343 + _options:
  344 + allow-weak-crypto:
  345 + deterministic-id:
  346 + keep-files-open:
  347 + keep-files-open-threshold:
  348 + no-warn:
  349 + verbose:
  350 + warning-exit-0:
  351 + ignore-xref-streams:
  352 + password-is-hex-key:
  353 + password-mode:
  354 + suppress-password-recovery:
  355 + suppress-recovery:
357 coalesce-contents: 356 coalesce-contents:
358 compression-level: 357 compression-level:
359 externalize-inline-images: 358 externalize-inline-images:
360 ii-min-bytes: 359 ii-min-bytes:
361 remove-unreferenced-resources: 360 remove-unreferenced-resources:
362 - _modify:  
363 add-attachment: 361 add-attachment:
364 - path: "attachment to add" 362 - path: "attachment to add"
365 creationdate: 363 creationdate:
libqpdf/QPDFJob_json.cc
@@ -229,7 +229,9 @@ Handlers::setupInputFilename(std::string const& key) @@ -229,7 +229,9 @@ Handlers::setupInputFilename(std::string const& key)
229 void 229 void
230 Handlers::setupInputPassword(std::string const& key) 230 Handlers::setupInputPassword(std::string const& key)
231 { 231 {
232 - // QXXXQ 232 + addParameter(key, [this](char const* p) {
  233 + c_main->password(p);
  234 + });
233 } 235 }
234 236
235 void 237 void
@@ -281,21 +283,53 @@ Handlers::endOutputOptions() @@ -281,21 +283,53 @@ Handlers::endOutputOptions()
281 } 283 }
282 284
283 void 285 void
284 -Handlers::beginOutputOptionsEncrypt(JSON) 286 +Handlers::beginOutputOptionsEncrypt(JSON j)
285 { 287 {
286 - // QXXXQ  
287 -// if (this->keylen_seen == 0)  
288 -// {  
289 -// usage("exactly one of 40bit, 128bit, or 256bit must be given;"  
290 -// " an empty dictionary may be supplied for one of them"  
291 -// " to set the key length without imposing any restrictions");  
292 -// } 288 + // This method is only called if the overall JSON structure
  289 + // matches the schema, so we already know that keys that are
  290 + // present have the right types.
  291 + int key_len = 0;
  292 + std::string user_password;
  293 + std::string owner_password;
  294 + bool user_password_seen = false;
  295 + bool owner_password_seen = false;
  296 + j.forEachDictItem([&](std::string const& key, JSON value){
  297 + if ((key == "40bit") || (key == "128bit") || (key == "256bit"))
  298 + {
  299 + if (key_len != 0)
  300 + {
  301 + usage("exactly one of 40bit, 128bit, or 256bit must be given");
  302 + }
  303 + key_len = QUtil::string_to_int(key.c_str());
  304 + }
  305 + else if (key == "userPassword")
  306 + {
  307 + user_password_seen = value.getString(user_password);
  308 + }
  309 + else if (key == "ownerPassword")
  310 + {
  311 + owner_password_seen = value.getString(owner_password);
  312 + }
  313 + });
  314 + if (key_len == 0)
  315 + {
  316 + usage("exactly one of 40bit, 128bit, or 256bit must be given;"
  317 + " an empty dictionary may be supplied for one of them"
  318 + " to set the key length without imposing any restrictions");
  319 + }
  320 + if (! (user_password_seen && owner_password_seen))
  321 + {
  322 + usage("the user and owner password are both required; use the empty"
  323 + " string for the user password if you don't want a password");
  324 + }
  325 + this->c_enc = c_main->encrypt(key_len, user_password, owner_password);
293 } 326 }
294 327
295 void 328 void
296 Handlers::endOutputOptionsEncrypt() 329 Handlers::endOutputOptionsEncrypt()
297 { 330 {
298 - // QXXXQ 331 + this->c_enc->endEncrypt();
  332 + this->c_enc = nullptr;
299 } 333 }
300 334
301 void 335 void
@@ -371,147 +405,141 @@ Handlers::endInspect() @@ -371,147 +405,141 @@ Handlers::endInspect()
371 } 405 }
372 406
373 void 407 void
374 -Handlers::beginTransform(JSON)  
375 -{  
376 - // nothing needed  
377 -}  
378 -  
379 -void  
380 -Handlers::endTransform()  
381 -{  
382 - // nothing needed  
383 -}  
384 -  
385 -void  
386 -Handlers::beginModify(JSON)  
387 -{  
388 - // nothing needed  
389 -}  
390 -  
391 -void  
392 -Handlers::endModify() 408 +Handlers::beginOptionsAddAttachment(JSON)
393 { 409 {
394 - // nothing needed 410 + this->c_att = c_main->addAttachment();
395 } 411 }
396 412
397 void 413 void
398 -Handlers::beginModifyAddAttachment(JSON) 414 +Handlers::endOptionsAddAttachment()
399 { 415 {
400 - // QXXXQ 416 + this->c_att->endAddAttachment();
  417 + this->c_att = nullptr;
401 } 418 }
402 419
403 void 420 void
404 -Handlers::endModifyAddAttachment() 421 +Handlers::setupOptionsAddAttachmentPath(std::string const& key)
405 { 422 {
406 - // QXXXQ  
407 -}  
408 -  
409 -void  
410 -Handlers::setupModifyAddAttachmentPath(std::string const& key)  
411 -{  
412 - // QXXXQ setup 423 + addParameter(key, [this](char const* p) {
  424 + c_att->path(p);
  425 + });
413 } 426 }
414 427
415 void 428 void
416 -Handlers::beginModifyCopyAttachmentsFrom(JSON) 429 +Handlers::beginOptionsCopyAttachmentsFrom(JSON)
417 { 430 {
418 - // QXXXQ 431 + this->c_copy_att = c_main->copyAttachmentsFrom();
419 } 432 }
420 433
421 void 434 void
422 -Handlers::endModifyCopyAttachmentsFrom() 435 +Handlers::endOptionsCopyAttachmentsFrom()
423 { 436 {
424 - // QXXXQ 437 + this->c_copy_att->endCopyAttachmentsFrom();
  438 + this->c_copy_att = nullptr;
425 } 439 }
426 440
427 void 441 void
428 -Handlers::setupModifyCopyAttachmentsFromPath(std::string const& key) 442 +Handlers::setupOptionsCopyAttachmentsFromPath(std::string const& key)
429 { 443 {
430 - // QXXXQ setup 444 + addParameter(key, [this](char const* p) {
  445 + c_copy_att->path(p);
  446 + });
431 } 447 }
432 448
433 void 449 void
434 -Handlers::setupModifyCopyAttachmentsFromPassword(std::string const& key) 450 +Handlers::setupOptionsCopyAttachmentsFromPassword(std::string const& key)
435 { 451 {
436 - // QXXXQ setup 452 + addParameter(key, [this](char const* p) {
  453 + c_copy_att->password(p);
  454 + });
437 } 455 }
438 456
439 void 457 void
440 -Handlers::beginModifyPages(JSON) 458 +Handlers::beginOptionsPages(JSON)
441 { 459 {
442 // QXXXQ 460 // QXXXQ
443 } 461 }
444 462
445 void 463 void
446 -Handlers::endModifyPages() 464 +Handlers::endOptionsPages()
447 { 465 {
448 // QXXXQ 466 // QXXXQ
449 } 467 }
450 468
451 void 469 void
452 -Handlers::setupModifyPagesFile(std::string const& key) 470 +Handlers::setupOptionsPagesFile(std::string const& key)
453 { 471 {
454 - // QXXXQ setup 472 + // handled in beginOptionsPages
455 } 473 }
456 474
457 void 475 void
458 -Handlers::setupModifyPagesPassword(std::string const& key) 476 +Handlers::setupOptionsPagesPassword(std::string const& key)
459 { 477 {
460 - // QXXXQ setup 478 + // handled in beginOptionsPages
461 } 479 }
462 480
463 void 481 void
464 -Handlers::setupModifyPagesRange(std::string const& key) 482 +Handlers::setupOptionsPagesRange(std::string const& key)
465 { 483 {
466 - // QXXXQ setup 484 + // handled in beginOptionsPages
467 } 485 }
468 486
469 void 487 void
470 -Handlers::beginModifyOverlay(JSON) 488 +Handlers::beginOptionsOverlay(JSON)
471 { 489 {
472 - // QXXXQ 490 + this->c_uo = c_main->overlay();
473 } 491 }
474 492
475 void 493 void
476 -Handlers::endModifyOverlay() 494 +Handlers::endOptionsOverlay()
477 { 495 {
478 - // QXXXQ 496 + c_uo->endUnderlayOverlay();
  497 + c_uo = nullptr;
479 } 498 }
480 499
481 void 500 void
482 -Handlers::setupModifyOverlayFile(std::string const& key) 501 +Handlers::setupOptionsOverlayFile(std::string const& key)
483 { 502 {
484 - // QXXXQ setup 503 + addParameter(key, [this](char const* p) {
  504 + c_uo->path(p);
  505 + });
485 } 506 }
486 507
487 void 508 void
488 -Handlers::setupModifyOverlayPassword(std::string const& key) 509 +Handlers::setupOptionsOverlayPassword(std::string const& key)
489 { 510 {
490 - // QXXXQ setup 511 + addParameter(key, [this](char const* p) {
  512 + c_uo->password(p);
  513 + });
491 } 514 }
492 515
493 void 516 void
494 -Handlers::beginModifyUnderlay(JSON) 517 +Handlers::beginOptionsUnderlay(JSON)
495 { 518 {
496 - // QXXXQ 519 + this->c_uo = c_main->underlay();
497 } 520 }
498 521
499 void 522 void
500 -Handlers::endModifyUnderlay() 523 +Handlers::endOptionsUnderlay()
501 { 524 {
502 - // QXXXQ 525 + c_uo->endUnderlayOverlay();
  526 + c_uo = nullptr;
503 } 527 }
504 528
505 void 529 void
506 -Handlers::setupModifyUnderlayFile(std::string const& key) 530 +Handlers::setupOptionsUnderlayFile(std::string const& key)
507 { 531 {
508 - // QXXXQ setup 532 + addParameter(key, [this](char const* p) {
  533 + c_uo->path(p);
  534 + });
509 } 535 }
510 536
511 void 537 void
512 -Handlers::setupModifyUnderlayPassword(std::string const& key) 538 +Handlers::setupOptionsUnderlayPassword(std::string const& key)
513 { 539 {
514 - // QXXXQ setup 540 + addParameter(key, [this](char const* p) {
  541 + c_uo->password(p);
  542 + });
515 } 543 }
516 544
517 void 545 void
libqpdf/qpdf/auto_job_json_decl.hh
@@ -24,31 +24,27 @@ void beginOutputOptionsEncrypt128bit(JSON); @@ -24,31 +24,27 @@ void beginOutputOptionsEncrypt128bit(JSON);
24 void endOutputOptionsEncrypt128bit(); 24 void endOutputOptionsEncrypt128bit();
25 void beginOutputOptionsEncrypt256bit(JSON); 25 void beginOutputOptionsEncrypt256bit(JSON);
26 void endOutputOptionsEncrypt256bit(); 26 void endOutputOptionsEncrypt256bit();
27 -void beginOptions(JSON);  
28 -void endOptions();  
29 void beginInspect(JSON); 27 void beginInspect(JSON);
30 void endInspect(); 28 void endInspect();
31 -void beginTransform(JSON);  
32 -void endTransform();  
33 -void beginModify(JSON);  
34 -void endModify();  
35 -void beginModifyAddAttachment(JSON);  
36 -void endModifyAddAttachment();  
37 -void setupModifyAddAttachmentPath(std::string const&);  
38 -void beginModifyCopyAttachmentsFrom(JSON);  
39 -void endModifyCopyAttachmentsFrom();  
40 -void setupModifyCopyAttachmentsFromPath(std::string const&);  
41 -void setupModifyCopyAttachmentsFromPassword(std::string const&);  
42 -void beginModifyPages(JSON);  
43 -void endModifyPages();  
44 -void setupModifyPagesFile(std::string const&);  
45 -void setupModifyPagesPassword(std::string const&);  
46 -void setupModifyPagesRange(std::string const&);  
47 -void beginModifyOverlay(JSON);  
48 -void endModifyOverlay();  
49 -void setupModifyOverlayFile(std::string const&);  
50 -void setupModifyOverlayPassword(std::string const&);  
51 -void beginModifyUnderlay(JSON);  
52 -void endModifyUnderlay();  
53 -void setupModifyUnderlayFile(std::string const&);  
54 -void setupModifyUnderlayPassword(std::string const&); 29 +void beginOptions(JSON);
  30 +void endOptions();
  31 +void beginOptionsAddAttachment(JSON);
  32 +void endOptionsAddAttachment();
  33 +void setupOptionsAddAttachmentPath(std::string const&);
  34 +void beginOptionsCopyAttachmentsFrom(JSON);
  35 +void endOptionsCopyAttachmentsFrom();
  36 +void setupOptionsCopyAttachmentsFromPath(std::string const&);
  37 +void setupOptionsCopyAttachmentsFromPassword(std::string const&);
  38 +void beginOptionsPages(JSON);
  39 +void endOptionsPages();
  40 +void setupOptionsPagesFile(std::string const&);
  41 +void setupOptionsPagesPassword(std::string const&);
  42 +void setupOptionsPagesRange(std::string const&);
  43 +void beginOptionsOverlay(JSON);
  44 +void endOptionsOverlay();
  45 +void setupOptionsOverlayFile(std::string const&);
  46 +void setupOptionsOverlayPassword(std::string const&);
  47 +void beginOptionsUnderlay(JSON);
  48 +void endOptionsUnderlay();
  49 +void setupOptionsUnderlayFile(std::string const&);
  50 +void setupOptionsUnderlayPassword(std::string const&);
libqpdf/qpdf/auto_job_json_init.hh
@@ -83,20 +83,6 @@ endDict(); // .output.options.encrypt.256bit @@ -83,20 +83,6 @@ endDict(); // .output.options.encrypt.256bit
83 endDict(); // .output.options.encrypt 83 endDict(); // .output.options.encrypt
84 endDict(); // .output.options 84 endDict(); // .output.options
85 endDict(); // .output 85 endDict(); // .output
86 -beginDict("options", bindJSON(&Handlers::beginOptions), bindBare(&Handlers::endOptions)); // .options  
87 -addBare("allowWeakCrypto", [this]() { c_main->allowWeakCrypto(); });  
88 -addBare("deterministicId", [this]() { c_main->deterministicId(); });  
89 -addChoices("keepFilesOpen", yn_choices, [this](char const* p) { c_main->keepFilesOpen(p); });  
90 -addParameter("keepFilesOpenThreshold", [this](char const* p) { c_main->keepFilesOpenThreshold(p); });  
91 -addBare("noWarn", [this]() { c_main->noWarn(); });  
92 -addBare("verbose", [this]() { c_main->verbose(); });  
93 -addBare("warningExit0", [this]() { c_main->warningExit0(); });  
94 -addBare("ignoreXrefStreams", [this]() { c_main->ignoreXrefStreams(); });  
95 -addBare("passwordIsHexKey", [this]() { c_main->passwordIsHexKey(); });  
96 -addChoices("passwordMode", password_mode_choices, [this](char const* p) { c_main->passwordMode(p); });  
97 -addBare("suppressPasswordRecovery", [this]() { c_main->suppressPasswordRecovery(); });  
98 -addBare("suppressRecovery", [this]() { c_main->suppressRecovery(); });  
99 -endDict(); // .options  
100 beginDict("inspect", bindJSON(&Handlers::beginInspect), bindBare(&Handlers::endInspect)); // .inspect 86 beginDict("inspect", bindJSON(&Handlers::beginInspect), bindBare(&Handlers::endInspect)); // .inspect
101 addBare("check", [this]() { c_main->check(); }); 87 addBare("check", [this]() { c_main->check(); });
102 addBare("checkLinearization", [this]() { c_main->checkLinearization(); }); 88 addBare("checkLinearization", [this]() { c_main->checkLinearization(); });
@@ -118,16 +104,26 @@ addBare("json", [this]() { c_main->json(); }); @@ -118,16 +104,26 @@ addBare("json", [this]() { c_main->json(); });
118 addChoices("jsonKey", json_key_choices, [this](char const* p) { c_main->jsonKey(p); }); 104 addChoices("jsonKey", json_key_choices, [this](char const* p) { c_main->jsonKey(p); });
119 addParameter("jsonObject", [this](char const* p) { c_main->jsonObject(p); }); 105 addParameter("jsonObject", [this](char const* p) { c_main->jsonObject(p); });
120 endDict(); // .inspect 106 endDict(); // .inspect
121 -beginDict("transform", bindJSON(&Handlers::beginTransform), bindBare(&Handlers::endTransform)); // .transform 107 +beginDict("options", bindJSON(&Handlers::beginOptions), bindBare(&Handlers::endOptions)); // .options
  108 +addBare("allowWeakCrypto", [this]() { c_main->allowWeakCrypto(); });
  109 +addBare("deterministicId", [this]() { c_main->deterministicId(); });
  110 +addChoices("keepFilesOpen", yn_choices, [this](char const* p) { c_main->keepFilesOpen(p); });
  111 +addParameter("keepFilesOpenThreshold", [this](char const* p) { c_main->keepFilesOpenThreshold(p); });
  112 +addBare("noWarn", [this]() { c_main->noWarn(); });
  113 +addBare("verbose", [this]() { c_main->verbose(); });
  114 +addBare("warningExit0", [this]() { c_main->warningExit0(); });
  115 +addBare("ignoreXrefStreams", [this]() { c_main->ignoreXrefStreams(); });
  116 +addBare("passwordIsHexKey", [this]() { c_main->passwordIsHexKey(); });
  117 +addChoices("passwordMode", password_mode_choices, [this](char const* p) { c_main->passwordMode(p); });
  118 +addBare("suppressPasswordRecovery", [this]() { c_main->suppressPasswordRecovery(); });
  119 +addBare("suppressRecovery", [this]() { c_main->suppressRecovery(); });
122 addBare("coalesceContents", [this]() { c_main->coalesceContents(); }); 120 addBare("coalesceContents", [this]() { c_main->coalesceContents(); });
123 addParameter("compressionLevel", [this](char const* p) { c_main->compressionLevel(p); }); 121 addParameter("compressionLevel", [this](char const* p) { c_main->compressionLevel(p); });
124 addBare("externalizeInlineImages", [this]() { c_main->externalizeInlineImages(); }); 122 addBare("externalizeInlineImages", [this]() { c_main->externalizeInlineImages(); });
125 addParameter("iiMinBytes", [this](char const* p) { c_main->iiMinBytes(p); }); 123 addParameter("iiMinBytes", [this](char const* p) { c_main->iiMinBytes(p); });
126 addChoices("removeUnreferencedResources", remove_unref_choices, [this](char const* p) { c_main->removeUnreferencedResources(p); }); 124 addChoices("removeUnreferencedResources", remove_unref_choices, [this](char const* p) { c_main->removeUnreferencedResources(p); });
127 -endDict(); // .transform  
128 -beginDict("modify", bindJSON(&Handlers::beginModify), bindBare(&Handlers::endModify)); // .modify  
129 -beginDict("addAttachment", bindJSON(&Handlers::beginModifyAddAttachment), bindBare(&Handlers::endModifyAddAttachment)); // .modify.addAttachment  
130 -doSetup("path", bindSetup(&Handlers::setupModifyAddAttachmentPath)); 125 +beginDict("addAttachment", bindJSON(&Handlers::beginOptionsAddAttachment), bindBare(&Handlers::endOptionsAddAttachment)); // .options.addAttachment
  126 +doSetup("path", bindSetup(&Handlers::setupOptionsAddAttachmentPath));
131 addParameter("creationdate", [this](char const* p) { c_att->creationdate(p); }); 127 addParameter("creationdate", [this](char const* p) { c_att->creationdate(p); });
132 addParameter("description", [this](char const* p) { c_att->description(p); }); 128 addParameter("description", [this](char const* p) { c_att->description(p); });
133 addParameter("filename", [this](char const* p) { c_att->filename(p); }); 129 addParameter("filename", [this](char const* p) { c_att->filename(p); });
@@ -135,13 +131,13 @@ addParameter("key", [this](char const* p) { c_att->key(p); }); @@ -135,13 +131,13 @@ addParameter("key", [this](char const* p) { c_att->key(p); });
135 addParameter("mimetype", [this](char const* p) { c_att->mimetype(p); }); 131 addParameter("mimetype", [this](char const* p) { c_att->mimetype(p); });
136 addParameter("moddate", [this](char const* p) { c_att->moddate(p); }); 132 addParameter("moddate", [this](char const* p) { c_att->moddate(p); });
137 addBare("replace", [this]() { c_att->replace(); }); 133 addBare("replace", [this]() { c_att->replace(); });
138 -endDict(); // .modify.addAttachment 134 +endDict(); // .options.addAttachment
139 addParameter("removeAttachment", [this](char const* p) { c_main->removeAttachment(p); }); 135 addParameter("removeAttachment", [this](char const* p) { c_main->removeAttachment(p); });
140 -beginDict("copyAttachmentsFrom", bindJSON(&Handlers::beginModifyCopyAttachmentsFrom), bindBare(&Handlers::endModifyCopyAttachmentsFrom)); // .modify.copyAttachmentsFrom  
141 -doSetup("path", bindSetup(&Handlers::setupModifyCopyAttachmentsFromPath));  
142 -doSetup("password", bindSetup(&Handlers::setupModifyCopyAttachmentsFromPassword)); 136 +beginDict("copyAttachmentsFrom", bindJSON(&Handlers::beginOptionsCopyAttachmentsFrom), bindBare(&Handlers::endOptionsCopyAttachmentsFrom)); // .options.copyAttachmentsFrom
  137 +doSetup("path", bindSetup(&Handlers::setupOptionsCopyAttachmentsFromPath));
  138 +doSetup("password", bindSetup(&Handlers::setupOptionsCopyAttachmentsFromPassword));
143 addParameter("prefix", [this](char const* p) { c_copy_att->prefix(p); }); 139 addParameter("prefix", [this](char const* p) { c_copy_att->prefix(p); });
144 -endDict(); // .modify.copyAttachmentsFrom 140 +endDict(); // .options.copyAttachmentsFrom
145 addParameter("collate", [this](char const* p) { c_main->collate(p); }); 141 addParameter("collate", [this](char const* p) { c_main->collate(p); });
146 addChoices("flattenAnnotations", flatten_choices, [this](char const* p) { c_main->flattenAnnotations(p); }); 142 addChoices("flattenAnnotations", flatten_choices, [this](char const* p) { c_main->flattenAnnotations(p); });
147 addBare("flattenRotation", [this]() { c_main->flattenRotation(); }); 143 addBare("flattenRotation", [this]() { c_main->flattenRotation(); });
@@ -151,25 +147,25 @@ addParameter("oiMinArea", [this](char const* p) { c_main->oiMinArea(p); }); @@ -151,25 +147,25 @@ addParameter("oiMinArea", [this](char const* p) { c_main->oiMinArea(p); });
151 addParameter("oiMinHeight", [this](char const* p) { c_main->oiMinHeight(p); }); 147 addParameter("oiMinHeight", [this](char const* p) { c_main->oiMinHeight(p); });
152 addParameter("oiMinWidth", [this](char const* p) { c_main->oiMinWidth(p); }); 148 addParameter("oiMinWidth", [this](char const* p) { c_main->oiMinWidth(p); });
153 addBare("optimizeImages", [this]() { c_main->optimizeImages(); }); 149 addBare("optimizeImages", [this]() { c_main->optimizeImages(); });
154 -beginDict("pages", bindJSON(&Handlers::beginModifyPages), bindBare(&Handlers::endModifyPages)); // .modify.pages  
155 -doSetup("file", bindSetup(&Handlers::setupModifyPagesFile));  
156 -doSetup("password", bindSetup(&Handlers::setupModifyPagesPassword));  
157 -doSetup("range", bindSetup(&Handlers::setupModifyPagesRange));  
158 -endDict(); // .modify.pages 150 +beginDict("pages", bindJSON(&Handlers::beginOptionsPages), bindBare(&Handlers::endOptionsPages)); // .options.pages
  151 +doSetup("file", bindSetup(&Handlers::setupOptionsPagesFile));
  152 +doSetup("password", bindSetup(&Handlers::setupOptionsPagesPassword));
  153 +doSetup("range", bindSetup(&Handlers::setupOptionsPagesRange));
  154 +endDict(); // .options.pages
159 addBare("removePageLabels", [this]() { c_main->removePageLabels(); }); 155 addBare("removePageLabels", [this]() { c_main->removePageLabels(); });
160 addParameter("rotate", [this](char const* p) { c_main->rotate(p); }); 156 addParameter("rotate", [this](char const* p) { c_main->rotate(p); });
161 -beginDict("overlay", bindJSON(&Handlers::beginModifyOverlay), bindBare(&Handlers::endModifyOverlay)); // .modify.overlay  
162 -doSetup("file", bindSetup(&Handlers::setupModifyOverlayFile));  
163 -doSetup("password", bindSetup(&Handlers::setupModifyOverlayPassword)); 157 +beginDict("overlay", bindJSON(&Handlers::beginOptionsOverlay), bindBare(&Handlers::endOptionsOverlay)); // .options.overlay
  158 +doSetup("file", bindSetup(&Handlers::setupOptionsOverlayFile));
  159 +doSetup("password", bindSetup(&Handlers::setupOptionsOverlayPassword));
164 addParameter("from", [this](char const* p) { c_uo->from(p); }); 160 addParameter("from", [this](char const* p) { c_uo->from(p); });
165 addParameter("repeat", [this](char const* p) { c_uo->repeat(p); }); 161 addParameter("repeat", [this](char const* p) { c_uo->repeat(p); });
166 addParameter("to", [this](char const* p) { c_uo->to(p); }); 162 addParameter("to", [this](char const* p) { c_uo->to(p); });
167 -endDict(); // .modify.overlay  
168 -beginDict("underlay", bindJSON(&Handlers::beginModifyUnderlay), bindBare(&Handlers::endModifyUnderlay)); // .modify.underlay  
169 -doSetup("file", bindSetup(&Handlers::setupModifyUnderlayFile));  
170 -doSetup("password", bindSetup(&Handlers::setupModifyUnderlayPassword)); 163 +endDict(); // .options.overlay
  164 +beginDict("underlay", bindJSON(&Handlers::beginOptionsUnderlay), bindBare(&Handlers::endOptionsUnderlay)); // .options.underlay
  165 +doSetup("file", bindSetup(&Handlers::setupOptionsUnderlayFile));
  166 +doSetup("password", bindSetup(&Handlers::setupOptionsUnderlayPassword));
171 addParameter("from", [this](char const* p) { c_uo->from(p); }); 167 addParameter("from", [this](char const* p) { c_uo->from(p); });
172 addParameter("repeat", [this](char const* p) { c_uo->repeat(p); }); 168 addParameter("repeat", [this](char const* p) { c_uo->repeat(p); });
173 addParameter("to", [this](char const* p) { c_uo->to(p); }); 169 addParameter("to", [this](char const* p) { c_uo->to(p); });
174 -endDict(); // .modify.underlay  
175 -endDict(); // .modify 170 +endDict(); // .options.underlay
  171 +endDict(); // .options
libqpdf/qpdf/auto_job_schema.hh
@@ -68,20 +68,6 @@ static constexpr char const* JOB_SCHEMA_DATA = R"({ @@ -68,20 +68,6 @@ static constexpr char const* JOB_SCHEMA_DATA = R"({
68 } 68 }
69 } 69 }
70 }, 70 },
71 - "options": {  
72 - "allowWeakCrypto": "allow insecure cryptographic algorithms",  
73 - "deterministicId": "generate ID deterministically",  
74 - "keepFilesOpen": "manage keeping multiple files open",  
75 - "keepFilesOpenThreshold": "set threshold for keepFilesOpen",  
76 - "noWarn": "suppress printing of warning messages",  
77 - "verbose": "print additional information",  
78 - "warningExit0": "exit 0 even with warnings",  
79 - "ignoreXrefStreams": "use xref tables rather than streams",  
80 - "passwordIsHexKey": "provide hex-encoded encryption key",  
81 - "passwordMode": "tweak how qpdf encodes passwords",  
82 - "suppressPasswordRecovery": "don't try different password encodings",  
83 - "suppressRecovery": "suppress error recovery"  
84 - },  
85 "inspect": { 71 "inspect": {
86 "check": "partially check whether PDF is valid", 72 "check": "partially check whether PDF is valid",
87 "checkLinearization": "check linearization tables", 73 "checkLinearization": "check linearization tables",
@@ -107,14 +93,24 @@ static constexpr char const* JOB_SCHEMA_DATA = R"({ @@ -107,14 +93,24 @@ static constexpr char const* JOB_SCHEMA_DATA = R"({
107 null 93 null
108 ] 94 ]
109 }, 95 },
110 - "transform": { 96 + "options": {
  97 + "allowWeakCrypto": "allow insecure cryptographic algorithms",
  98 + "deterministicId": "generate ID deterministically",
  99 + "keepFilesOpen": "manage keeping multiple files open",
  100 + "keepFilesOpenThreshold": "set threshold for keepFilesOpen",
  101 + "noWarn": "suppress printing of warning messages",
  102 + "verbose": "print additional information",
  103 + "warningExit0": "exit 0 even with warnings",
  104 + "ignoreXrefStreams": "use xref tables rather than streams",
  105 + "passwordIsHexKey": "provide hex-encoded encryption key",
  106 + "passwordMode": "tweak how qpdf encodes passwords",
  107 + "suppressPasswordRecovery": "don't try different password encodings",
  108 + "suppressRecovery": "suppress error recovery",
111 "coalesceContents": "combine content streams", 109 "coalesceContents": "combine content streams",
112 "compressionLevel": "set compression level for flate", 110 "compressionLevel": "set compression level for flate",
113 "externalizeInlineImages": "convert inline to regular images", 111 "externalizeInlineImages": "convert inline to regular images",
114 "iiMinBytes": "set minimum size for externalizeInlineImages", 112 "iiMinBytes": "set minimum size for externalizeInlineImages",
115 - "removeUnreferencedResources": "remove unreferenced page resources"  
116 - },  
117 - "modify": { 113 + "removeUnreferencedResources": "remove unreferenced page resources",
118 "addAttachment": [ 114 "addAttachment": [
119 { 115 {
120 "path": "attachment to add", 116 "path": "attachment to add",