Commit e3506253f17137d6d4831b4615d74689446da72c

Authored by Jay Berkenbilt
1 parent b4fb9b4e

Add optional version to --json

ChangeLog
  1 +2022-01-31 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Allow optional version number or "latest" as parameter to
  4 + --json, allowing for future specification of json version.
  5 +
1 6 2022-01-28 Jay Berkenbilt <ejb@ql.org>
2 7  
3 8 * Add QPDFUsage exception, which is thrown by JSONHandler,
... ...
include/qpdf/QPDFJob.hh
... ... @@ -595,7 +595,7 @@ class QPDFJob
595 595 std::list<std::string> attachments_to_remove;
596 596 std::list<AddAttachment> attachments_to_add;
597 597 std::list<CopyAttachmentFrom> attachments_to_copy;
598   - bool json;
  598 + int json_version;
599 599 std::set<std::string> json_keys;
600 600 std::set<std::string> json_objects;
601 601 bool check;
... ...
include/qpdf/auto_job_c_main.hh
... ... @@ -15,7 +15,6 @@ QPDF_DLL Config* flattenRotation();
15 15 QPDF_DLL Config* generateAppearances();
16 16 QPDF_DLL Config* ignoreXrefStreams();
17 17 QPDF_DLL Config* isEncrypted();
18   -QPDF_DLL Config* json();
19 18 QPDF_DLL Config* keepInlineImages();
20 19 QPDF_DLL Config* linearize();
21 20 QPDF_DLL Config* listAttachments();
... ... @@ -76,3 +75,4 @@ QPDF_DLL Config* objectStreams(char const* parameter);
76 75 QPDF_DLL Config* passwordMode(char const* parameter);
77 76 QPDF_DLL Config* removeUnreferencedResources(char const* parameter);
78 77 QPDF_DLL Config* streamData(char const* parameter);
  78 +QPDF_DLL Config* json(char const* parameter);
... ...
job.sums
... ... @@ -3,15 +3,15 @@ generate_auto_job ef1b438aeebed7ca0afcbe4d1f9c54d3acf899aec8410ebc69cd15ec673dd1
3 3 include/qpdf/auto_job_c_att.hh 7ad43bb374c1370ef32ebdcdcb7b73a61d281f7f4e3f12755585872ab30fb60e
4 4 include/qpdf/auto_job_c_copy_att.hh 32275d03cdc69b703dd7e02ba0bbe15756e714e9ad185484773a6178dc09e1ee
5 5 include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf52f64c1d6be99265
6   -include/qpdf/auto_job_c_main.hh 516adb23cc7e44e614e436880be870d0574e4ebbc706cd855a1360000eed31bb
  6 +include/qpdf/auto_job_c_main.hh ff776dd643279330fbf59770d1abf5aaeb13f20bfc5f6a25997aaa72a0907b44
7 7 include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671
8 8 include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50
9   -job.yml 498459e6c2b7a9bc13168cd58fed75dbd24394fc187230ff7179a22288fa0de5
  9 +job.yml c3e714b3c3e2fc85390d983302ff398aa0992c621e85dbcaee20173b1bd3cb0b
10 10 libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6
11   -libqpdf/qpdf/auto_job_help.hh 23c79f1d2c02bda28f64aace17f69487205c797e7ae2234892cbbabab49d6d47
12   -libqpdf/qpdf/auto_job_init.hh 8e9e31b6099a662497339b27f6e2d7f779f35011e88a834bee8811c33405a0fe
  11 +libqpdf/qpdf/auto_job_help.hh a0ab6ab4dde2ad3d3f17ecae3ea274919119329e075061f3a3973535f5e367de
  12 +libqpdf/qpdf/auto_job_init.hh c244e03e8b83ed7db732920f40aff0134e5f2e78a6edb9473ea4dd1934a8953e
13 13 libqpdf/qpdf/auto_job_json_decl.hh 741a44106f7850b6cbc8af264b5b77bb605475c8d8dd8cd87011d5debbee6269
14   -libqpdf/qpdf/auto_job_json_init.hh 886dd8ed7ae7691eaa97a0e5b3f1445f4cccab88ed372f530a8524d198c8f1d9
  14 +libqpdf/qpdf/auto_job_json_init.hh 63bbe1c3d673cd56196ec42ec7ede7b531563667d83564aa6680634fcb2cf259
15 15 libqpdf/qpdf/auto_job_schema.hh a764050cc99f1cc95645fd1ea2f020c4b778957abc64fbc55c12eac3a369dc92
16 16 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3
17   -manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882
  17 +manual/cli.rst a75a7e34aa9aba4f06e9c88cae9a2d9a2aa4e55a08521dde1478e8f2d80aadab
... ...
... ... @@ -29,6 +29,9 @@ choices:
29 29 - all
30 30 - print
31 31 - screen
  32 + json_version:
  33 + - 1
  34 + - latest
32 35 json_key:
33 36 # The list of selectable top-level keys id duplicated in the
34 37 # following places: job.yml, QPDFJob::json_schema, and
... ... @@ -88,7 +91,6 @@ options:
88 91 - generate-appearances
89 92 - ignore-xref-streams
90 93 - is-encrypted
91   - - json
92 94 - keep-inline-images
93 95 - linearize
94 96 - list-attachments
... ... @@ -156,6 +158,8 @@ options:
156 158 password-mode: password_mode
157 159 remove-unreferenced-resources: remove_unref
158 160 stream-data: stream_data
  161 + optional_choices:
  162 + json: json_version
159 163 - table: pages
160 164 config: c_pages
161 165 prefix: Pages
... ...
libqpdf/QPDFJob.cc
... ... @@ -420,7 +420,7 @@ QPDFJob::Members::Members() :
420 420 collate(0),
421 421 flatten_rotation(false),
422 422 list_attachments(false),
423   - json(false),
  423 + json_version(0),
424 424 check(false),
425 425 optimize_images(false),
426 426 externalize_inline_images(false),
... ... @@ -1924,7 +1924,7 @@ QPDFJob::doInspection(QPDF&amp; pdf)
1924 1924 {
1925 1925 doCheck(pdf);
1926 1926 }
1927   - if (m->json)
  1927 + if (m->json_version)
1928 1928 {
1929 1929 doJSON(pdf);
1930 1930 }
... ...
libqpdf/QPDFJob_config.cc
... ... @@ -235,9 +235,27 @@ QPDFJob::Config::isEncrypted()
235 235 }
236 236  
237 237 QPDFJob::Config*
238   -QPDFJob::Config::json()
  238 +QPDFJob::Config::json(char const* parameter)
239 239 {
240   - o.m->json = true;
  240 + if (parameter)
  241 + {
  242 + if (strcmp(parameter, "latest") == 0)
  243 + {
  244 + o.m->json_version = 1;
  245 + }
  246 + else
  247 + {
  248 + o.m->json_version = QUtil::string_to_int(parameter);
  249 + }
  250 + }
  251 + else
  252 + {
  253 + o.m->json_version = 1;
  254 + }
  255 + if (o.m->json_version != 1)
  256 + {
  257 + usage(std::string("unsupported json version ") + parameter);
  258 + }
241 259 o.m->require_outfile = false;
242 260 return this;
243 261 }
... ...
libqpdf/qpdf/auto_job_help.hh
... ... @@ -788,8 +788,11 @@ output as binary data. Get the key with --list-attachments.
788 788 ap.addHelpTopic("json", "JSON output for PDF information", R"(Show information about the PDF file in JSON format. Please see the
789 789 JSON chapter in the qpdf manual for details.
790 790 )");
791   -ap.addOptionHelp("--json", "json", "show file in json format", R"(Generate a JSON representation of the file. This is described in
792   -depth in the JSON section of the manual.
  791 +ap.addOptionHelp("--json", "json", "show file in json format", R"(--json[=version]
  792 +
  793 +Generate a JSON representation of the file. This is described in
  794 +depth in the JSON section of the manual. "version" may be a
  795 +specific version or "latest".
793 796 )");
794 797 ap.addOptionHelp("--json-help", "json", "show format of json output", R"(Describe the format of the JSON output.
795 798 )");
... ...
libqpdf/qpdf/auto_job_init.hh
... ... @@ -17,6 +17,7 @@ static char const* decode_level_choices[] = {&quot;none&quot;, &quot;generalized&quot;, &quot;specialized
17 17 static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};
18 18 static char const* remove_unref_choices[] = {"auto", "yes", "no", 0};
19 19 static char const* flatten_choices[] = {"all", "print", "screen", 0};
  20 +static char const* json_version_choices[] = {"1", "latest", 0};
20 21 static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};
21 22 static char const* print128_choices[] = {"full", "low", "none", 0};
22 23 static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
... ... @@ -45,7 +46,6 @@ this-&gt;ap.addBare(&quot;flatten-rotation&quot;, [this](){c_main-&gt;flattenRotation();});
45 46 this->ap.addBare("generate-appearances", [this](){c_main->generateAppearances();});
46 47 this->ap.addBare("ignore-xref-streams", [this](){c_main->ignoreXrefStreams();});
47 48 this->ap.addBare("is-encrypted", [this](){c_main->isEncrypted();});
48   -this->ap.addBare("json", [this](){c_main->json();});
49 49 this->ap.addBare("keep-inline-images", [this](){c_main->keepInlineImages();});
50 50 this->ap.addBare("linearize", [this](){c_main->linearize();});
51 51 this->ap.addBare("list-attachments", [this](){c_main->listAttachments();});
... ... @@ -110,6 +110,7 @@ this-&gt;ap.addChoices(&quot;object-streams&quot;, [this](char *x){c_main-&gt;objectStreams(x);}
110 110 this->ap.addChoices("password-mode", [this](char *x){c_main->passwordMode(x);}, true, password_mode_choices);
111 111 this->ap.addChoices("remove-unreferenced-resources", [this](char *x){c_main->removeUnreferencedResources(x);}, true, remove_unref_choices);
112 112 this->ap.addChoices("stream-data", [this](char *x){c_main->streamData(x);}, true, stream_data_choices);
  113 +this->ap.addChoices("json", [this](char *x){c_main->json(x);}, false, json_version_choices);
113 114 this->ap.registerOptionTable("pages", b(&ArgParser::argEndPages));
114 115 this->ap.addPositional(p(&ArgParser::argPagesPositional));
115 116 this->ap.addRequiredParameter("password", p(&ArgParser::argPagesPassword), "password");
... ...
libqpdf/qpdf/auto_job_json_init.hh
... ... @@ -10,6 +10,7 @@ static char const* decode_level_choices[] = {&quot;none&quot;, &quot;generalized&quot;, &quot;specialized
10 10 static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};
11 11 static char const* remove_unref_choices[] = {"auto", "yes", "no", 0};
12 12 static char const* flatten_choices[] = {"all", "print", "screen", 0};
  13 +static char const* json_version_choices[] = {"1", "latest", 0};
13 14 static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};
14 15 static char const* print128_choices[] = {"full", "low", "none", 0};
15 16 static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
... ... @@ -248,7 +249,7 @@ pushKey(&quot;showAttachment&quot;);
248 249 addParameter([this](char const* p) { c_main->showAttachment(p); });
249 250 popHandler(); // key: showAttachment
250 251 pushKey("json");
251   -addBare([this]() { c_main->json(); });
  252 +addChoices(json_version_choices, [this](char const* p) { c_main->json(p); });
252 253 popHandler(); // key: json
253 254 pushKey("jsonKey");
254 255 beginArray(bindJSON(&Handlers::beginInspectJsonKeyArray), bindBare(&Handlers::endInspectJsonKeyArray)); // .inspect.jsonKey[]
... ...
manual/cli.rst
... ... @@ -3136,15 +3136,21 @@ See :ref:`json` for details about the qpdf JSON format.
3136 3136 Related Options
3137 3137 ~~~~~~~~~~~~~~~
3138 3138  
3139   -.. qpdf:option:: --json
  3139 +.. qpdf:option:: --json[=version]
3140 3140  
3141 3141 .. help: show file in json format
3142 3142  
3143 3143 Generate a JSON representation of the file. This is described in
3144   - depth in the JSON section of the manual.
  3144 + depth in the JSON section of the manual. "version" may be a
  3145 + specific version or "latest".
3145 3146  
3146 3147 Generate a JSON representation of the file. This is described in
3147   - depth in :ref:`json`.
  3148 + depth in :ref:`json`. The version parameter can be used to specify
  3149 + which json version should be output. The only supported value is
  3150 + ``1``, but it's possible that a new json output version will be
  3151 + added in a future version. You can also specify ``latest`` to use
  3152 + the latest json version. For backward compatibility, the default
  3153 + value is ``1``.
3148 3154  
3149 3155 .. qpdf:option:: --json-help
3150 3156  
... ...
qpdf/qtest/qpdf.test
... ... @@ -617,7 +617,7 @@ $td-&gt;runtest(&quot;list attachments verbose&quot;,
617 617 {$td->FILE => "test76-list-verbose.out", $td->EXIT_STATUS => 0},
618 618 $td->NORMALIZE_NEWLINES);
619 619 $td->runtest("attachments json",
620   - {$td->COMMAND => "qpdf --json --json-key=attachments a.pdf"},
  620 + {$td->COMMAND => "qpdf --json=1 --json-key=attachments a.pdf"},
621 621 {$td->FILE => "test76-json.out", $td->EXIT_STATUS => 0},
622 622 $td->NORMALIZE_NEWLINES);
623 623 $td->runtest("remove attachment (test_driver)",
... ... @@ -2705,7 +2705,7 @@ $td-&gt;runtest(&quot;show direct pages&quot;,
2705 2705 foreach my $f (qw(page_api_2 direct-pages))
2706 2706 {
2707 2707 $td->runtest("json for $f",
2708   - {$td->COMMAND => "qpdf --json $f.pdf"},
  2708 + {$td->COMMAND => "qpdf --json=latest $f.pdf"},
2709 2709 {$td->FILE => "$f-json.out", $td->EXIT_STATUS => 0},
2710 2710 $td->NORMALIZE_NEWLINES);
2711 2711 }
... ...