2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 19:08:59 +00:00

Add optional version to --json

This commit is contained in:
Jay Berkenbilt 2022-01-31 14:20:06 -05:00
parent b4fb9b4ec3
commit e3506253f1
12 changed files with 60 additions and 22 deletions

View File

@ -1,3 +1,8 @@
2022-01-31 Jay Berkenbilt <ejb@ql.org>
* Allow optional version number or "latest" as parameter to
--json, allowing for future specification of json version.
2022-01-28 Jay Berkenbilt <ejb@ql.org> 2022-01-28 Jay Berkenbilt <ejb@ql.org>
* Add QPDFUsage exception, which is thrown by JSONHandler, * Add QPDFUsage exception, which is thrown by JSONHandler,

View File

@ -595,7 +595,7 @@ class QPDFJob
std::list<std::string> attachments_to_remove; std::list<std::string> attachments_to_remove;
std::list<AddAttachment> attachments_to_add; std::list<AddAttachment> attachments_to_add;
std::list<CopyAttachmentFrom> attachments_to_copy; std::list<CopyAttachmentFrom> attachments_to_copy;
bool json; int json_version;
std::set<std::string> json_keys; std::set<std::string> json_keys;
std::set<std::string> json_objects; std::set<std::string> json_objects;
bool check; bool check;

View File

@ -15,7 +15,6 @@ QPDF_DLL Config* flattenRotation();
QPDF_DLL Config* generateAppearances(); QPDF_DLL Config* generateAppearances();
QPDF_DLL Config* ignoreXrefStreams(); QPDF_DLL Config* ignoreXrefStreams();
QPDF_DLL Config* isEncrypted(); QPDF_DLL Config* isEncrypted();
QPDF_DLL Config* json();
QPDF_DLL Config* keepInlineImages(); QPDF_DLL Config* keepInlineImages();
QPDF_DLL Config* linearize(); QPDF_DLL Config* linearize();
QPDF_DLL Config* listAttachments(); QPDF_DLL Config* listAttachments();
@ -76,3 +75,4 @@ QPDF_DLL Config* objectStreams(char const* parameter);
QPDF_DLL Config* passwordMode(char const* parameter); QPDF_DLL Config* passwordMode(char const* parameter);
QPDF_DLL Config* removeUnreferencedResources(char const* parameter); QPDF_DLL Config* removeUnreferencedResources(char const* parameter);
QPDF_DLL Config* streamData(char const* parameter); QPDF_DLL Config* streamData(char const* parameter);
QPDF_DLL Config* json(char const* parameter);

View File

@ -3,15 +3,15 @@ generate_auto_job ef1b438aeebed7ca0afcbe4d1f9c54d3acf899aec8410ebc69cd15ec673dd1
include/qpdf/auto_job_c_att.hh 7ad43bb374c1370ef32ebdcdcb7b73a61d281f7f4e3f12755585872ab30fb60e include/qpdf/auto_job_c_att.hh 7ad43bb374c1370ef32ebdcdcb7b73a61d281f7f4e3f12755585872ab30fb60e
include/qpdf/auto_job_c_copy_att.hh 32275d03cdc69b703dd7e02ba0bbe15756e714e9ad185484773a6178dc09e1ee include/qpdf/auto_job_c_copy_att.hh 32275d03cdc69b703dd7e02ba0bbe15756e714e9ad185484773a6178dc09e1ee
include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf52f64c1d6be99265 include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf52f64c1d6be99265
include/qpdf/auto_job_c_main.hh 516adb23cc7e44e614e436880be870d0574e4ebbc706cd855a1360000eed31bb include/qpdf/auto_job_c_main.hh ff776dd643279330fbf59770d1abf5aaeb13f20bfc5f6a25997aaa72a0907b44
include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671 include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671
include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50 include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50
job.yml 498459e6c2b7a9bc13168cd58fed75dbd24394fc187230ff7179a22288fa0de5 job.yml c3e714b3c3e2fc85390d983302ff398aa0992c621e85dbcaee20173b1bd3cb0b
libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6 libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6
libqpdf/qpdf/auto_job_help.hh 23c79f1d2c02bda28f64aace17f69487205c797e7ae2234892cbbabab49d6d47 libqpdf/qpdf/auto_job_help.hh a0ab6ab4dde2ad3d3f17ecae3ea274919119329e075061f3a3973535f5e367de
libqpdf/qpdf/auto_job_init.hh 8e9e31b6099a662497339b27f6e2d7f779f35011e88a834bee8811c33405a0fe libqpdf/qpdf/auto_job_init.hh c244e03e8b83ed7db732920f40aff0134e5f2e78a6edb9473ea4dd1934a8953e
libqpdf/qpdf/auto_job_json_decl.hh 741a44106f7850b6cbc8af264b5b77bb605475c8d8dd8cd87011d5debbee6269 libqpdf/qpdf/auto_job_json_decl.hh 741a44106f7850b6cbc8af264b5b77bb605475c8d8dd8cd87011d5debbee6269
libqpdf/qpdf/auto_job_json_init.hh 886dd8ed7ae7691eaa97a0e5b3f1445f4cccab88ed372f530a8524d198c8f1d9 libqpdf/qpdf/auto_job_json_init.hh 63bbe1c3d673cd56196ec42ec7ede7b531563667d83564aa6680634fcb2cf259
libqpdf/qpdf/auto_job_schema.hh a764050cc99f1cc95645fd1ea2f020c4b778957abc64fbc55c12eac3a369dc92 libqpdf/qpdf/auto_job_schema.hh a764050cc99f1cc95645fd1ea2f020c4b778957abc64fbc55c12eac3a369dc92
manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3
manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882 manual/cli.rst a75a7e34aa9aba4f06e9c88cae9a2d9a2aa4e55a08521dde1478e8f2d80aadab

View File

@ -29,6 +29,9 @@ choices:
- all - all
- print - print
- screen - screen
json_version:
- 1
- latest
json_key: json_key:
# The list of selectable top-level keys id duplicated in the # The list of selectable top-level keys id duplicated in the
# following places: job.yml, QPDFJob::json_schema, and # following places: job.yml, QPDFJob::json_schema, and
@ -88,7 +91,6 @@ options:
- generate-appearances - generate-appearances
- ignore-xref-streams - ignore-xref-streams
- is-encrypted - is-encrypted
- json
- keep-inline-images - keep-inline-images
- linearize - linearize
- list-attachments - list-attachments
@ -156,6 +158,8 @@ options:
password-mode: password_mode password-mode: password_mode
remove-unreferenced-resources: remove_unref remove-unreferenced-resources: remove_unref
stream-data: stream_data stream-data: stream_data
optional_choices:
json: json_version
- table: pages - table: pages
config: c_pages config: c_pages
prefix: Pages prefix: Pages

View File

@ -420,7 +420,7 @@ QPDFJob::Members::Members() :
collate(0), collate(0),
flatten_rotation(false), flatten_rotation(false),
list_attachments(false), list_attachments(false),
json(false), json_version(0),
check(false), check(false),
optimize_images(false), optimize_images(false),
externalize_inline_images(false), externalize_inline_images(false),
@ -1924,7 +1924,7 @@ QPDFJob::doInspection(QPDF& pdf)
{ {
doCheck(pdf); doCheck(pdf);
} }
if (m->json) if (m->json_version)
{ {
doJSON(pdf); doJSON(pdf);
} }

View File

@ -235,9 +235,27 @@ QPDFJob::Config::isEncrypted()
} }
QPDFJob::Config* QPDFJob::Config*
QPDFJob::Config::json() QPDFJob::Config::json(char const* parameter)
{ {
o.m->json = true; if (parameter)
{
if (strcmp(parameter, "latest") == 0)
{
o.m->json_version = 1;
}
else
{
o.m->json_version = QUtil::string_to_int(parameter);
}
}
else
{
o.m->json_version = 1;
}
if (o.m->json_version != 1)
{
usage(std::string("unsupported json version ") + parameter);
}
o.m->require_outfile = false; o.m->require_outfile = false;
return this; return this;
} }

View File

@ -788,8 +788,11 @@ output as binary data. Get the key with --list-attachments.
ap.addHelpTopic("json", "JSON output for PDF information", R"(Show information about the PDF file in JSON format. Please see the ap.addHelpTopic("json", "JSON output for PDF information", R"(Show information about the PDF file in JSON format. Please see the
JSON chapter in the qpdf manual for details. JSON chapter in the qpdf manual for details.
)"); )");
ap.addOptionHelp("--json", "json", "show file in json format", R"(Generate a JSON representation of the file. This is described in ap.addOptionHelp("--json", "json", "show file in json format", R"(--json[=version]
depth in the JSON section of the manual.
Generate a JSON representation of the file. This is described in
depth in the JSON section of the manual. "version" may be a
specific version or "latest".
)"); )");
ap.addOptionHelp("--json-help", "json", "show format of json output", R"(Describe the format of the JSON output. ap.addOptionHelp("--json-help", "json", "show format of json output", R"(Describe the format of the JSON output.
)"); )");

View File

@ -17,6 +17,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized
static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0}; static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};
static char const* remove_unref_choices[] = {"auto", "yes", "no", 0}; static char const* remove_unref_choices[] = {"auto", "yes", "no", 0};
static char const* flatten_choices[] = {"all", "print", "screen", 0}; static char const* flatten_choices[] = {"all", "print", "screen", 0};
static char const* json_version_choices[] = {"1", "latest", 0};
static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0}; static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};
static char const* print128_choices[] = {"full", "low", "none", 0}; static char const* print128_choices[] = {"full", "low", "none", 0};
static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
@ -45,7 +46,6 @@ this->ap.addBare("flatten-rotation", [this](){c_main->flattenRotation();});
this->ap.addBare("generate-appearances", [this](){c_main->generateAppearances();}); this->ap.addBare("generate-appearances", [this](){c_main->generateAppearances();});
this->ap.addBare("ignore-xref-streams", [this](){c_main->ignoreXrefStreams();}); this->ap.addBare("ignore-xref-streams", [this](){c_main->ignoreXrefStreams();});
this->ap.addBare("is-encrypted", [this](){c_main->isEncrypted();}); this->ap.addBare("is-encrypted", [this](){c_main->isEncrypted();});
this->ap.addBare("json", [this](){c_main->json();});
this->ap.addBare("keep-inline-images", [this](){c_main->keepInlineImages();}); this->ap.addBare("keep-inline-images", [this](){c_main->keepInlineImages();});
this->ap.addBare("linearize", [this](){c_main->linearize();}); this->ap.addBare("linearize", [this](){c_main->linearize();});
this->ap.addBare("list-attachments", [this](){c_main->listAttachments();}); this->ap.addBare("list-attachments", [this](){c_main->listAttachments();});
@ -110,6 +110,7 @@ this->ap.addChoices("object-streams", [this](char *x){c_main->objectStreams(x);}
this->ap.addChoices("password-mode", [this](char *x){c_main->passwordMode(x);}, true, password_mode_choices); this->ap.addChoices("password-mode", [this](char *x){c_main->passwordMode(x);}, true, password_mode_choices);
this->ap.addChoices("remove-unreferenced-resources", [this](char *x){c_main->removeUnreferencedResources(x);}, true, remove_unref_choices); this->ap.addChoices("remove-unreferenced-resources", [this](char *x){c_main->removeUnreferencedResources(x);}, true, remove_unref_choices);
this->ap.addChoices("stream-data", [this](char *x){c_main->streamData(x);}, true, stream_data_choices); this->ap.addChoices("stream-data", [this](char *x){c_main->streamData(x);}, true, stream_data_choices);
this->ap.addChoices("json", [this](char *x){c_main->json(x);}, false, json_version_choices);
this->ap.registerOptionTable("pages", b(&ArgParser::argEndPages)); this->ap.registerOptionTable("pages", b(&ArgParser::argEndPages));
this->ap.addPositional(p(&ArgParser::argPagesPositional)); this->ap.addPositional(p(&ArgParser::argPagesPositional));
this->ap.addRequiredParameter("password", p(&ArgParser::argPagesPassword), "password"); this->ap.addRequiredParameter("password", p(&ArgParser::argPagesPassword), "password");

View File

@ -10,6 +10,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized
static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0}; static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};
static char const* remove_unref_choices[] = {"auto", "yes", "no", 0}; static char const* remove_unref_choices[] = {"auto", "yes", "no", 0};
static char const* flatten_choices[] = {"all", "print", "screen", 0}; static char const* flatten_choices[] = {"all", "print", "screen", 0};
static char const* json_version_choices[] = {"1", "latest", 0};
static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0}; static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};
static char const* print128_choices[] = {"full", "low", "none", 0}; static char const* print128_choices[] = {"full", "low", "none", 0};
static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
@ -248,7 +249,7 @@ pushKey("showAttachment");
addParameter([this](char const* p) { c_main->showAttachment(p); }); addParameter([this](char const* p) { c_main->showAttachment(p); });
popHandler(); // key: showAttachment popHandler(); // key: showAttachment
pushKey("json"); pushKey("json");
addBare([this]() { c_main->json(); }); addChoices(json_version_choices, [this](char const* p) { c_main->json(p); });
popHandler(); // key: json popHandler(); // key: json
pushKey("jsonKey"); pushKey("jsonKey");
beginArray(bindJSON(&Handlers::beginInspectJsonKeyArray), bindBare(&Handlers::endInspectJsonKeyArray)); // .inspect.jsonKey[] beginArray(bindJSON(&Handlers::beginInspectJsonKeyArray), bindBare(&Handlers::endInspectJsonKeyArray)); // .inspect.jsonKey[]

View File

@ -3136,15 +3136,21 @@ See :ref:`json` for details about the qpdf JSON format.
Related Options Related Options
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
.. qpdf:option:: --json .. qpdf:option:: --json[=version]
.. help: show file in json format .. help: show file in json format
Generate a JSON representation of the file. This is described in Generate a JSON representation of the file. This is described in
depth in the JSON section of the manual. depth in the JSON section of the manual. "version" may be a
specific version or "latest".
Generate a JSON representation of the file. This is described in Generate a JSON representation of the file. This is described in
depth in :ref:`json`. depth in :ref:`json`. The version parameter can be used to specify
which json version should be output. The only supported value is
``1``, but it's possible that a new json output version will be
added in a future version. You can also specify ``latest`` to use
the latest json version. For backward compatibility, the default
value is ``1``.
.. qpdf:option:: --json-help .. qpdf:option:: --json-help

View File

@ -617,7 +617,7 @@ $td->runtest("list attachments verbose",
{$td->FILE => "test76-list-verbose.out", $td->EXIT_STATUS => 0}, {$td->FILE => "test76-list-verbose.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES); $td->NORMALIZE_NEWLINES);
$td->runtest("attachments json", $td->runtest("attachments json",
{$td->COMMAND => "qpdf --json --json-key=attachments a.pdf"}, {$td->COMMAND => "qpdf --json=1 --json-key=attachments a.pdf"},
{$td->FILE => "test76-json.out", $td->EXIT_STATUS => 0}, {$td->FILE => "test76-json.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES); $td->NORMALIZE_NEWLINES);
$td->runtest("remove attachment (test_driver)", $td->runtest("remove attachment (test_driver)",
@ -2705,7 +2705,7 @@ $td->runtest("show direct pages",
foreach my $f (qw(page_api_2 direct-pages)) foreach my $f (qw(page_api_2 direct-pages))
{ {
$td->runtest("json for $f", $td->runtest("json for $f",
{$td->COMMAND => "qpdf --json $f.pdf"}, {$td->COMMAND => "qpdf --json=latest $f.pdf"},
{$td->FILE => "$f-json.out", $td->EXIT_STATUS => 0}, {$td->FILE => "$f-json.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES); $td->NORMALIZE_NEWLINES);
} }