Commit 1d099ab7439104759a421bc20c809e64fef29f03

Authored by Jay Berkenbilt
1 parent 1c8d5346

QPDFJob: placeholder for initializeFromJson

include/qpdf/QPDFJob.hh
@@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
35 #include <map> 35 #include <map>
36 #include <iostream> 36 #include <iostream>
37 #include <functional> 37 #include <functional>
  38 +#include <memory>
38 39
39 class QPDFWriter; 40 class QPDFWriter;
40 41
@@ -67,6 +68,10 @@ class QPDFJob @@ -67,6 +68,10 @@ class QPDFJob
67 void initializeFromArgv(int argc, char* argv[], 68 void initializeFromArgv(int argc, char* argv[],
68 char const* progname_env = nullptr); 69 char const* progname_env = nullptr);
69 70
  71 + // QXXXQ
  72 + QPDF_DLL
  73 + void initializeFromJson(std::string const& json);
  74 +
70 // Set name that is used to prefix verbose messages, progress 75 // Set name that is used to prefix verbose messages, progress
71 // messages, and other things that the library writes to output 76 // messages, and other things that the library writes to output
72 // and error streams on the caller's behalf. Defaults to "qpdf". 77 // and error streams on the caller's behalf. Defaults to "qpdf".
job.sums
1 # Generated by generate_auto_job 1 # Generated by generate_auto_job
2 generate_auto_job 0758b244fc4e2d3e440883072d2740bc4cdb26c5aa8de938f028afd7d83fad79 2 generate_auto_job 0758b244fc4e2d3e440883072d2740bc4cdb26c5aa8de938f028afd7d83fad79
3 -job.yml 2856c2635d42f0a58717d3ffce3125816d8f98ff17245c4b7a0669d70cd68b84  
4 -libqpdf/qpdf/auto_job_decl.hh 97395ecbe590b23ae04d6cce2080dbd0e998917ff5eeaa5c6aafa91041d3cd6a  
5 -libqpdf/qpdf/auto_job_help.hh 2653faaf59415bec81c3a85d426239d52b609ac24faba34ec2d26f00710dd2c6  
6 -libqpdf/qpdf/auto_job_init.hh 465bf46769559ceb77110d1b9d3293ba9b3595850b49848c31aeabd10aadb4ad 3 +job.yml 78d3b655abe70c0baaa31e51b74931f97084632bca5961fdbae89d7a57f34a67
  4 +libqpdf/qpdf/auto_job_decl.hh 9fda0ebd93bce6e308a3f26181293ad7b0d88a3503d4955cbf8e1db9a884d8ee
  5 +libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538
  6 +libqpdf/qpdf/auto_job_init.hh a16e89fc7be3ca200d47391d949628a92113533135758068b944b64d0d54793d
7 libqpdf/qpdf/auto_job_schema.hh c91a4e182e088797b70dda94af03ca32d360f3564890132da2a8bdc3c4432423 7 libqpdf/qpdf/auto_job_schema.hh c91a4e182e088797b70dda94af03ca32d360f3564890132da2a8bdc3c4432423
8 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d 8 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d
9 -manual/cli.rst b136c7f33a538c580b081a7e802c27635aad2a4229efa0eb0736466116b7aa90 9 +manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1
@@ -58,6 +58,7 @@ options: @@ -58,6 +58,7 @@ options:
58 - copyright 58 - copyright
59 - json-help 59 - json-help
60 - show-crypto 60 - show-crypto
  61 + - job-json-help
61 - table: main 62 - table: main
62 positional: true 63 positional: true
63 bare: 64 bare:
@@ -120,6 +121,7 @@ options: @@ -120,6 +121,7 @@ options:
120 encryption-file-password: password 121 encryption-file-password: password
121 force-version: version 122 force-version: version
122 ii-min-bytes: minimum 123 ii-min-bytes: minimum
  124 + job-json-file: file
123 json-object: trailer 125 json-object: trailer
124 keep-files-open-threshold: count 126 keep-files-open-threshold: count
125 linearize-pass1: filename 127 linearize-pass1: filename
@@ -219,6 +221,7 @@ options: @@ -219,6 +221,7 @@ options:
219 password: password 221 password: password
220 no-json: 222 no-json:
221 - preserve-unreferenced-resources 223 - preserve-unreferenced-resources
  224 + - job-json-file
222 json: 225 json:
223 # The structure of this section defines what the json input to 226 # The structure of this section defines what the json input to
224 # QPDFJob looks like. If a key starts with underscore or has a value 227 # QPDFJob looks like. If a key starts with underscore or has a value
libqpdf/QPDFJob_argv.cc
@@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
8 #include <cstdio> 8 #include <cstdio>
9 #include <ctype.h> 9 #include <ctype.h>
10 #include <memory> 10 #include <memory>
  11 +#include <sstream>
11 12
12 #include <qpdf/QUtil.hh> 13 #include <qpdf/QUtil.hh>
13 #include <qpdf/QTC.hh> 14 #include <qpdf/QTC.hh>
@@ -15,6 +16,10 @@ @@ -15,6 +16,10 @@
15 #include <qpdf/QPDFArgParser.hh> 16 #include <qpdf/QPDFArgParser.hh>
16 #include <qpdf/QPDFJob.hh> 17 #include <qpdf/QPDFJob.hh>
17 #include <qpdf/QIntC.hh> 18 #include <qpdf/QIntC.hh>
  19 +#include <qpdf/JSONHandler.hh>
  20 +
  21 +#include <qpdf/auto_job_schema.hh>
  22 +static JSON JOB_SCHEMA = JSON::parse(JOB_SCHEMA_DATA);
18 23
19 namespace 24 namespace
20 { 25 {
@@ -1329,6 +1334,31 @@ ArgParser::argEndCopyAttachment() @@ -1329,6 +1334,31 @@ ArgParser::argEndCopyAttachment()
1329 } 1334 }
1330 1335
1331 void 1336 void
  1337 +ArgParser::argJobJsonFile(char* parameter)
  1338 +{
  1339 + PointerHolder<char> file_buf;
  1340 + size_t size;
  1341 + QUtil::read_file_into_memory(parameter, file_buf, size);
  1342 + try
  1343 + {
  1344 + o.initializeFromJson(std::string(file_buf.getPointer(), size));
  1345 + }
  1346 + catch (std::exception& e)
  1347 + {
  1348 + throw std::runtime_error(
  1349 + "error with job-json file " + std::string(parameter) + " " +
  1350 + e.what() + "\nRun " + this->ap.getProgname() +
  1351 + "--job-json-help for information on the file format.");
  1352 + }
  1353 +}
  1354 +
  1355 +void
  1356 +ArgParser::argJobJsonHelp()
  1357 +{
  1358 + std::cout << JOB_SCHEMA_DATA << std::endl;
  1359 +}
  1360 +
  1361 +void
1332 ArgParser::usage(std::string const& message) 1362 ArgParser::usage(std::string const& message)
1333 { 1363 {
1334 this->ap.usage(message); 1364 this->ap.usage(message);
@@ -1534,3 +1564,93 @@ QPDFJob::initializeFromArgv(int argc, char* argv[], char const* progname_env) @@ -1534,3 +1564,93 @@ QPDFJob::initializeFromArgv(int argc, char* argv[], char const* progname_env)
1534 ArgParser ap(qap, *this); 1564 ArgParser ap(qap, *this);
1535 ap.parseOptions(); 1565 ap.parseOptions();
1536 } 1566 }
  1567 +
  1568 +void
  1569 +QPDFJob::initializeFromJson(std::string const& json)
  1570 +{
  1571 + std::list<std::string> errors;
  1572 + JSON j = JSON::parse(json);
  1573 + if (! j.checkSchema(JOB_SCHEMA, JSON::f_optional, errors))
  1574 + {
  1575 + std::ostringstream msg;
  1576 + msg << this->m->message_prefix
  1577 + << ": job json has errors:";
  1578 + for (auto const& error: errors)
  1579 + {
  1580 + msg << std::endl << " " << error;
  1581 + }
  1582 + throw std::runtime_error(msg.str());
  1583 + }
  1584 +
  1585 + JSONHandler jh;
  1586 + {
  1587 + jh.addDictHandlers(
  1588 + [](std::string const&){},
  1589 + [](std::string const&){});
  1590 +
  1591 + auto input = std::make_shared<JSONHandler>();
  1592 + auto input_file = std::make_shared<JSONHandler>();
  1593 + auto input_file_name = std::make_shared<JSONHandler>();
  1594 + auto output = std::make_shared<JSONHandler>();
  1595 + auto output_file = std::make_shared<JSONHandler>();
  1596 + auto output_file_name = std::make_shared<JSONHandler>();
  1597 + auto output_options = std::make_shared<JSONHandler>();
  1598 + auto output_options_qdf = std::make_shared<JSONHandler>();
  1599 +
  1600 + input->addDictHandlers(
  1601 + [](std::string const&){},
  1602 + [](std::string const&){});
  1603 + input_file->addDictHandlers(
  1604 + [](std::string const&){},
  1605 + [](std::string const&){});
  1606 + output->addDictHandlers(
  1607 + [](std::string const&){},
  1608 + [](std::string const&){});
  1609 + output_file->addDictHandlers(
  1610 + [](std::string const&){},
  1611 + [](std::string const&){});
  1612 + output_options->addDictHandlers(
  1613 + [](std::string const&){},
  1614 + [](std::string const&){});
  1615 +
  1616 + jh.addDictKeyHandler("input", input);
  1617 + input->addDictKeyHandler("file", input_file);
  1618 + input_file->addDictKeyHandler("name", input_file_name);
  1619 + jh.addDictKeyHandler("output", output);
  1620 + output->addDictKeyHandler("file", output_file);
  1621 + output_file->addDictKeyHandler("name", output_file_name);
  1622 + output->addDictKeyHandler("options", output_options);
  1623 + output_options->addDictKeyHandler("qdf", output_options_qdf);
  1624 +
  1625 + input_file_name->addStringHandler(
  1626 + [this](std::string const&, std::string const& v) {
  1627 + this->infilename = QUtil::make_shared_cstr(v);
  1628 + });
  1629 + output_file_name->addStringHandler(
  1630 + [this](std::string const&, std::string const& v) {
  1631 + this->outfilename = QUtil::make_shared_cstr(v);
  1632 + });
  1633 + output_options_qdf->addBoolHandler(
  1634 + [this](std::string const&, bool v) {
  1635 + this->qdf_mode = v;
  1636 + });
  1637 + }
  1638 +
  1639 + // {
  1640 + // "input": {
  1641 + // "file": {
  1642 + // "name": "/home/ejb/source/examples/pdf/minimal.pdf"
  1643 + // }
  1644 + // },
  1645 + // "output": {
  1646 + // "file": {
  1647 + // "name": "/tmp/a.pdf"
  1648 + // },
  1649 + // "options": {
  1650 + // "qdf": true
  1651 + // }
  1652 + // }
  1653 + // }
  1654 +
  1655 + jh.handle(".", j);
  1656 +}
libqpdf/qpdf/auto_job_decl.hh
@@ -16,6 +16,7 @@ void argVersion(); @@ -16,6 +16,7 @@ void argVersion();
16 void argCopyright(); 16 void argCopyright();
17 void argJsonHelp(); 17 void argJsonHelp();
18 void argShowCrypto(); 18 void argShowCrypto();
  19 +void argJobJsonHelp();
19 void argPositional(char*); 20 void argPositional(char*);
20 void argAddAttachment(); 21 void argAddAttachment();
21 void argAllowWeakCrypto(); 22 void argAllowWeakCrypto();
@@ -74,6 +75,7 @@ void argCopyEncryption(char *); @@ -74,6 +75,7 @@ void argCopyEncryption(char *);
74 void argEncryptionFilePassword(char *); 75 void argEncryptionFilePassword(char *);
75 void argForceVersion(char *); 76 void argForceVersion(char *);
76 void argIiMinBytes(char *); 77 void argIiMinBytes(char *);
  78 +void argJobJsonFile(char *);
77 void argJsonObject(char *); 79 void argJsonObject(char *);
78 void argKeepFilesOpenThreshold(char *); 80 void argKeepFilesOpenThreshold(char *);
79 void argLinearizePass1(char *); 81 void argLinearizePass1(char *);
libqpdf/qpdf/auto_job_help.hh
@@ -27,6 +27,11 @@ with --pages. @@ -27,6 +27,11 @@ with --pages.
27 )"); 27 )");
28 ap.addOptionHelp("--replace-input", "usage", "replace input with output", R"(Use in place of outfile to overwrite the input file with the output. 28 ap.addOptionHelp("--replace-input", "usage", "replace input with output", R"(Use in place of outfile to overwrite the input file with the output.
29 )"); 29 )");
  30 +ap.addOptionHelp("--job-json-file", "usage", "job JSON file", R"(--job-json-file=file
  31 +
  32 +Specify the name of a file whose contents are expected to
  33 +contain a QPDFJob json file.
  34 +)");
30 ap.addHelpTopic("exit-status", "meanings of qpdf's exit codes", R"(Meaning of exit codes: 35 ap.addHelpTopic("exit-status", "meanings of qpdf's exit codes", R"(Meaning of exit codes:
31 36
32 0: no errors or warnings 37 0: no errors or warnings
@@ -78,14 +83,14 @@ performed. @@ -78,14 +83,14 @@ performed.
78 )"); 83 )");
79 ap.addOptionHelp("--progress", "general", "show progress when writing", R"(Indicate progress when writing files. 84 ap.addOptionHelp("--progress", "general", "show progress when writing", R"(Indicate progress when writing files.
80 )"); 85 )");
  86 +}
  87 +static void add_help_2(QPDFArgParser& ap)
  88 +{
81 ap.addOptionHelp("--no-warn", "general", "suppress printing warning messages", R"(Suppress printing warning messages. If warnings were 89 ap.addOptionHelp("--no-warn", "general", "suppress printing warning messages", R"(Suppress printing warning messages. If warnings were
82 encountered, qpdf still exits with exit status 3. 90 encountered, qpdf still exits with exit status 3.
83 Use --warning-exit-0 with --no-warn to completely ignore 91 Use --warning-exit-0 with --no-warn to completely ignore
84 warnings. 92 warnings.
85 )"); 93 )");
86 -}  
87 -static void add_help_2(QPDFArgParser& ap)  
88 -{  
89 ap.addOptionHelp("--deterministic-id", "general", "generate ID deterministically", R"(Generate a secure, random document ID only using static 94 ap.addOptionHelp("--deterministic-id", "general", "generate ID deterministically", R"(Generate a secure, random document ID only using static
90 information, such as the page contents. Does not use the file's 95 information, such as the page contents. Does not use the file's
91 name or attributes or the current time. 96 name or attributes or the current time.
@@ -164,15 +169,15 @@ chapter about it in the manual. @@ -164,15 +169,15 @@ chapter about it in the manual.
164 ap.addOptionHelp("--no-original-object-ids", "transformation", "omit original object ID in qdf", R"(Omit comments in a QDF file indicating the object ID an object 169 ap.addOptionHelp("--no-original-object-ids", "transformation", "omit original object ID in qdf", R"(Omit comments in a QDF file indicating the object ID an object
165 had in the original file. 170 had in the original file.
166 )"); 171 )");
  172 +}
  173 +static void add_help_3(QPDFArgParser& ap)
  174 +{
167 ap.addOptionHelp("--compress-streams", "transformation", "compress uncompressed streams", R"(--compress-streams=[yn] 175 ap.addOptionHelp("--compress-streams", "transformation", "compress uncompressed streams", R"(--compress-streams=[yn]
168 176
169 Setting --compress-streams=n prevents qpdf from compressing 177 Setting --compress-streams=n prevents qpdf from compressing
170 uncompressed streams. This can be useful if you are leaving some 178 uncompressed streams. This can be useful if you are leaving some
171 streams uncompressed intentionally. 179 streams uncompressed intentionally.
172 )"); 180 )");
173 -}  
174 -static void add_help_3(QPDFArgParser& ap)  
175 -{  
176 ap.addOptionHelp("--decode-level", "transformation", "control which streams to uncompress", R"(--decode-level=parameter 181 ap.addOptionHelp("--decode-level", "transformation", "control which streams to uncompress", R"(--decode-level=parameter
177 182
178 When uncompressing streams, control which types of compression 183 When uncompressing streams, control which types of compression
@@ -280,15 +285,15 @@ ap.addOptionHelp(&quot;--pages&quot;, &quot;modification&quot;, &quot;begin page selection&quot;, R&quot;(--pages f @@ -280,15 +285,15 @@ ap.addOptionHelp(&quot;--pages&quot;, &quot;modification&quot;, &quot;begin page selection&quot;, R&quot;(--pages f
280 285
281 Run qpdf --help=page-selection for details. 286 Run qpdf --help=page-selection for details.
282 )"); 287 )");
  288 +}
  289 +static void add_help_4(QPDFArgParser& ap)
  290 +{
283 ap.addOptionHelp("--collate", "modification", "collate with --pages", R"(--collate=n 291 ap.addOptionHelp("--collate", "modification", "collate with --pages", R"(--collate=n
284 292
285 Collate rather than concatenate pages specified with --pages. 293 Collate rather than concatenate pages specified with --pages.
286 With a numeric parameter, collate in groups of n. The default 294 With a numeric parameter, collate in groups of n. The default
287 is 1. Run qpdf --help=page-selection for additional details. 295 is 1. Run qpdf --help=page-selection for additional details.
288 )"); 296 )");
289 -}  
290 -static void add_help_4(QPDFArgParser& ap)  
291 -{  
292 ap.addOptionHelp("--split-pages", "modification", "write pages to separate files", R"(--split-pages=[n] 297 ap.addOptionHelp("--split-pages", "modification", "write pages to separate files", R"(--split-pages=[n]
293 298
294 This option causes qpdf to create separate output files for each 299 This option causes qpdf to create separate output files for each
@@ -451,15 +456,15 @@ ap.addOptionHelp(&quot;--extract&quot;, &quot;encryption&quot;, &quot;restrict text/graphic extraction&quot;, @@ -451,15 +456,15 @@ ap.addOptionHelp(&quot;--extract&quot;, &quot;encryption&quot;, &quot;restrict text/graphic extraction&quot;,
451 Enable/disable text/graphic extraction for purposes other than 456 Enable/disable text/graphic extraction for purposes other than
452 accessibility. 457 accessibility.
453 )"); 458 )");
  459 +}
  460 +static void add_help_5(QPDFArgParser& ap)
  461 +{
454 ap.addOptionHelp("--form", "encryption", "restrict form filling", R"(--form=[yn] 462 ap.addOptionHelp("--form", "encryption", "restrict form filling", R"(--form=[yn]
455 463
456 Enable/disable whether filling form fields is allowed even if 464 Enable/disable whether filling form fields is allowed even if
457 modification of annotations is disabled. This option is not 465 modification of annotations is disabled. This option is not
458 available with 40-bit encryption. 466 available with 40-bit encryption.
459 )"); 467 )");
460 -}  
461 -static void add_help_5(QPDFArgParser& ap)  
462 -{  
463 ap.addOptionHelp("--modify-other", "encryption", "restrict other modifications", R"(--modify-other=[yn] 468 ap.addOptionHelp("--modify-other", "encryption", "restrict other modifications", R"(--modify-other=[yn]
464 469
465 Enable/disable modifications not controlled by --assemble, 470 Enable/disable modifications not controlled by --assemble,
@@ -625,15 +630,15 @@ ap.addOptionHelp(&quot;--remove-attachment&quot;, &quot;attachments&quot;, &quot;remove an embedded file&quot; @@ -625,15 +630,15 @@ ap.addOptionHelp(&quot;--remove-attachment&quot;, &quot;attachments&quot;, &quot;remove an embedded file&quot;
625 Remove an embedded file using its key. Get the key with 630 Remove an embedded file using its key. Get the key with
626 --list-attachments. 631 --list-attachments.
627 )"); 632 )");
  633 +}
  634 +static void add_help_6(QPDFArgParser& ap)
  635 +{
628 ap.addOptionHelp("--copy-attachments-from", "attachments", "start copy attachment options", R"(--copy-attachments-from file options -- 636 ap.addOptionHelp("--copy-attachments-from", "attachments", "start copy attachment options", R"(--copy-attachments-from file options --
629 637
630 The --copy-attachments-from flag and its options may be repeated 638 The --copy-attachments-from flag and its options may be repeated
631 to copy attachments from multiple files. Run 639 to copy attachments from multiple files. Run
632 qpdf --help=copy-attachments for details. 640 qpdf --help=copy-attachments for details.
633 )"); 641 )");
634 -}  
635 -static void add_help_6(QPDFArgParser& ap)  
636 -{  
637 ap.addHelpTopic("pdf-dates", "PDF date format", R"(When a date is required, the date should conform to the PDF date 642 ap.addHelpTopic("pdf-dates", "PDF date format", R"(When a date is required, the date should conform to the PDF date
638 format specification, which is "D:yyyymmddhhmmssz" where "z" is 643 format specification, which is "D:yyyymmddhhmmssz" where "z" is
639 either literally upper case "Z" for UTC or a timezone offset in 644 either literally upper case "Z" for UTC or a timezone offset in
@@ -738,11 +743,11 @@ encryption key to be displayed. @@ -738,11 +743,11 @@ encryption key to be displayed.
738 ap.addOptionHelp("--check-linearization", "inspection", "check linearization tables", R"(Check to see whether a file is linearized and, if so, whether 743 ap.addOptionHelp("--check-linearization", "inspection", "check linearization tables", R"(Check to see whether a file is linearized and, if so, whether
739 the linearization hint tables are correct. 744 the linearization hint tables are correct.
740 )"); 745 )");
741 -ap.addOptionHelp("--show-linearization", "inspection", "show linearization hint tables", R"(Check and display all data in the linearization hint tables.  
742 -)");  
743 } 746 }
744 static void add_help_7(QPDFArgParser& ap) 747 static void add_help_7(QPDFArgParser& ap)
745 { 748 {
  749 +ap.addOptionHelp("--show-linearization", "inspection", "show linearization hint tables", R"(Check and display all data in the linearization hint tables.
  750 +)");
746 ap.addOptionHelp("--show-xref", "inspection", "show cross reference data", R"(Show the contents of the cross-reference table or stream (object 751 ap.addOptionHelp("--show-xref", "inspection", "show cross reference data", R"(Show the contents of the cross-reference table or stream (object
747 locations in the file) in a human-readable form. This is 752 locations in the file) in a human-readable form. This is
748 especially useful for files with cross-reference streams, which 753 especially useful for files with cross-reference streams, which
@@ -793,6 +798,8 @@ This option is repeatable. If given, only specified objects will @@ -793,6 +798,8 @@ This option is repeatable. If given, only specified objects will
793 be shown in the "objects" key of the JSON output. Otherwise, all 798 be shown in the "objects" key of the JSON output. Otherwise, all
794 objects will be shown. 799 objects will be shown.
795 )"); 800 )");
  801 +ap.addOptionHelp("--job-json-help", "json", "show format of job json", R"(Describe the format of the QPDFJob JSON input.
  802 +)");
796 ap.addHelpTopic("testing", "options for testing or debugging", R"(The options below are useful when writing automated test code that 803 ap.addHelpTopic("testing", "options for testing or debugging", R"(The options below are useful when writing automated test code that
797 includes files created by qpdf or when testing qpdf itself. 804 includes files created by qpdf or when testing qpdf itself.
798 )"); 805 )");
libqpdf/qpdf/auto_job_init.hh
@@ -26,6 +26,7 @@ this-&gt;ap.addBare(&quot;version&quot;, b(&amp;ArgParser::argVersion)); @@ -26,6 +26,7 @@ this-&gt;ap.addBare(&quot;version&quot;, b(&amp;ArgParser::argVersion));
26 this->ap.addBare("copyright", b(&ArgParser::argCopyright)); 26 this->ap.addBare("copyright", b(&ArgParser::argCopyright));
27 this->ap.addBare("json-help", b(&ArgParser::argJsonHelp)); 27 this->ap.addBare("json-help", b(&ArgParser::argJsonHelp));
28 this->ap.addBare("show-crypto", b(&ArgParser::argShowCrypto)); 28 this->ap.addBare("show-crypto", b(&ArgParser::argShowCrypto));
  29 +this->ap.addBare("job-json-help", b(&ArgParser::argJobJsonHelp));
29 this->ap.selectMainOptionTable(); 30 this->ap.selectMainOptionTable();
30 this->ap.addPositional(p(&ArgParser::argPositional)); 31 this->ap.addPositional(p(&ArgParser::argPositional));
31 this->ap.addBare("add-attachment", b(&ArgParser::argAddAttachment)); 32 this->ap.addBare("add-attachment", b(&ArgParser::argAddAttachment));
@@ -85,6 +86,7 @@ this-&gt;ap.addRequiredParameter(&quot;copy-encryption&quot;, p(&amp;ArgParser::argCopyEncryption @@ -85,6 +86,7 @@ this-&gt;ap.addRequiredParameter(&quot;copy-encryption&quot;, p(&amp;ArgParser::argCopyEncryption
85 this->ap.addRequiredParameter("encryption-file-password", p(&ArgParser::argEncryptionFilePassword), "password"); 86 this->ap.addRequiredParameter("encryption-file-password", p(&ArgParser::argEncryptionFilePassword), "password");
86 this->ap.addRequiredParameter("force-version", p(&ArgParser::argForceVersion), "version"); 87 this->ap.addRequiredParameter("force-version", p(&ArgParser::argForceVersion), "version");
87 this->ap.addRequiredParameter("ii-min-bytes", p(&ArgParser::argIiMinBytes), "minimum"); 88 this->ap.addRequiredParameter("ii-min-bytes", p(&ArgParser::argIiMinBytes), "minimum");
  89 +this->ap.addRequiredParameter("job-json-file", p(&ArgParser::argJobJsonFile), "file");
88 this->ap.addRequiredParameter("json-object", p(&ArgParser::argJsonObject), "trailer"); 90 this->ap.addRequiredParameter("json-object", p(&ArgParser::argJsonObject), "trailer");
89 this->ap.addRequiredParameter("keep-files-open-threshold", p(&ArgParser::argKeepFilesOpenThreshold), "count"); 91 this->ap.addRequiredParameter("keep-files-open-threshold", p(&ArgParser::argKeepFilesOpenThreshold), "count");
90 this->ap.addRequiredParameter("linearize-pass1", p(&ArgParser::argLinearizePass1), "filename"); 92 this->ap.addRequiredParameter("linearize-pass1", p(&ArgParser::argLinearizePass1), "filename");
manual/cli.rst
@@ -157,6 +157,18 @@ Related Options @@ -157,6 +157,18 @@ Related Options
157 :file:`{infilename}.~qpdf-orig`. If there are errors, the input 157 :file:`{infilename}.~qpdf-orig`. If there are errors, the input
158 file is left untouched. 158 file is left untouched.
159 159
  160 +.. qpdf:option:: --job-json-file=file
  161 +
  162 + .. help: job JSON file
  163 +
  164 + Specify the name of a file whose contents are expected to
  165 + contain a QPDFJob json file.
  166 +
  167 + Specify the name of a file whose contents are expected to contain a
  168 + QPDFJob json file. QXXXQ ref. This file is read and treated as if
  169 + the equivalent command-line arguments were supplied. It can be
  170 + mixed freely with other options.
  171 +
160 .. _exit-status: 172 .. _exit-status:
161 173
162 Exit Status 174 Exit Status
@@ -3147,6 +3159,14 @@ Related Options @@ -3147,6 +3159,14 @@ Related Options
3147 be shown in the "``objects``" key of the JSON output. Otherwise, all 3159 be shown in the "``objects``" key of the JSON output. Otherwise, all
3148 objects will be shown. 3160 objects will be shown.
3149 3161
  3162 +.. qpdf:option:: --job-json-help
  3163 +
  3164 + .. help: show format of job json
  3165 +
  3166 + Describe the format of the QPDFJob JSON input.
  3167 +
  3168 + Describe the format of the QPDFJob JSON input. QXXXQ doc ref.
  3169 +
3150 .. _test-options: 3170 .. _test-options:
3151 3171
3152 Options for Testing or Debugging 3172 Options for Testing or Debugging