Commit 1d099ab7439104759a421bc20c809e64fef29f03
1 parent
1c8d5346
QPDFJob: placeholder for initializeFromJson
Showing
8 changed files
with
181 additions
and
22 deletions
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 |
job.yml
| @@ -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("--pages", "modification", "begin page selection", R"(--pages f | @@ -280,15 +285,15 @@ ap.addOptionHelp("--pages", "modification", "begin page selection", R"(--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("--extract", "encryption", "restrict text/graphic extraction", | @@ -451,15 +456,15 @@ ap.addOptionHelp("--extract", "encryption", "restrict text/graphic extraction", | ||
| 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("--remove-attachment", "attachments", "remove an embedded file" | @@ -625,15 +630,15 @@ ap.addOptionHelp("--remove-attachment", "attachments", "remove an embedded file" | ||
| 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->ap.addBare("version", b(&ArgParser::argVersion)); | @@ -26,6 +26,7 @@ this->ap.addBare("version", b(&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->ap.addRequiredParameter("copy-encryption", p(&ArgParser::argCopyEncryption | @@ -85,6 +86,7 @@ this->ap.addRequiredParameter("copy-encryption", p(&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 |