QPDFJob: convert under/overlay and rotate

This commit is contained in:
Jay Berkenbilt 2022-01-26 09:38:34 -05:00
parent 1cc532dc91
commit b5d41b16b8
11 changed files with 145 additions and 121 deletions

View File

@ -32,30 +32,6 @@ def write_file(filename):
os.rename(tmpfile, filename)
# QXXXQ
# These are trivial but not in main and so need a different config
# object. Some are in more than one table.
not_yet = set([
'accessibility',
'allow-insecure',
'annotate',
'assemble',
'cleartext-metadata',
'extract',
'force-R5',
'force-V4',
'form',
'from',
'modify',
'modify-other',
'print',
'repeat',
'rotate',
'to',
'use-aes',
])
class Main:
SOURCES = [
whoami,
@ -447,8 +423,7 @@ class Main:
for i, [kind, v] in flags.items():
self.options_without_help.add(f'--{i}')
add_jdata(i, table_prefix or table)
# QXXXQ not_yet
if i in not_yet or config is None or i in o.get('manual', []):
if config is None or i in o.get('manual', []):
identifier = self.to_identifier(i, arg_prefix, False)
self.handle_flag(i, identifier, kind, v)
else:

View File

@ -201,6 +201,22 @@ class QPDFJob
Config& config;
};
class UOConfig
{
friend class QPDFJob;
friend class Config;
public:
QPDF_DLL UOConfig& path(char const* parameter);
# include <qpdf/auto_job_c_uo.hh>
private:
UOConfig(Config&);
UOConfig(PagesConfig const&) = delete;
Config& config;
};
// Configuration is performed by calling methods XXX QXXXQ document
class Config
{
@ -210,6 +226,8 @@ class QPDFJob
std::shared_ptr<CopyAttConfig> copyAttachmentsFrom();
std::shared_ptr<AttConfig> addAttachment();
std::shared_ptr<PagesConfig> pages();
std::shared_ptr<UOConfig> overlay();
std::shared_ptr<UOConfig> underlay();
# include <qpdf/auto_job_c_main.hh>
@ -422,16 +440,12 @@ class QPDFJob
bool check_requires_password;
std::shared_ptr<char> infilename;
std::shared_ptr<char> outfilename;
// Helper functions
void parseRotationParameter(std::string const&);
std::vector<int> parseNumrange(char const* range, int max,
bool throw_error = false);
// QXXXQ END-PUBLIC
private:
// Helper functions
void parseRotationParameter(std::string const&);
std::vector<int> parseNumrange(char const* range, int max);
// Basic file processing
std::shared_ptr<QPDF> processFile(

View File

@ -65,6 +65,7 @@ QPDF_DLL Config& oiMinWidth(char const* parameter);
QPDF_DLL Config& password(char const* parameter);
QPDF_DLL Config& passwordFile(char const* parameter);
QPDF_DLL Config& removeAttachment(char const* parameter);
QPDF_DLL Config& rotate(char const* parameter);
QPDF_DLL Config& showAttachment(char const* parameter);
QPDF_DLL Config& showObject(char const* parameter);
QPDF_DLL Config& compressStreams(char const* parameter);

View File

@ -0,0 +1,10 @@
//
// This file is automatically generated by generate_auto_job.
// Edits will be automatically overwritten if the build is
// run in maintainer mode.
//
QPDF_DLL Config& end();
QPDF_DLL UOConfig& to(char const* parameter);
QPDF_DLL UOConfig& from(char const* parameter);
QPDF_DLL UOConfig& repeat(char const* parameter);
QPDF_DLL UOConfig& password(char const* parameter);

View File

@ -1,13 +1,14 @@
# Generated by generate_auto_job
generate_auto_job d41f3092545906dcd9a82f88ff41939bf695a36ecaebfe8559c66bd92b7416fb
generate_auto_job 7a539a822d332e33e08495a82a3fb86ceed2da2bb92ca492dd7ed888d226ab6a
include/qpdf/auto_job_c_att.hh ecc3f8f711b486b491e811176362a90c022eb225ff12157df3a10ca021be87b1
include/qpdf/auto_job_c_copy_att.hh caffae3d1faf2cd92a07ba77da638cce31da3e074a047918834195c0f3ed508a
include/qpdf/auto_job_c_main.hh 1e060e9dd2029d21b29fed03e3a1e62164050b43684bd7434cc9e9707f73150d
include/qpdf/auto_job_c_main.hh 7f7c0a4d8e640a2d24908af348f7b658ca81d3d8aa5346cf4327f6c1d4021119
include/qpdf/auto_job_c_pages.hh 79ee6e52a36fedfd0e6ca60bd926bc25a3e975ab6fa984a7e798a48791e8ba86
job.yml 4cd60df0caa74b68cc39352910a8381c3411248bc3edef69f9d16d75e807f451
libqpdf/qpdf/auto_job_decl.hh f9f2a605fb8b5fed9b74c4cd07c07c3cdee60e2628d082250810c8074d5acd83
include/qpdf/auto_job_c_uo.hh 80404376f19fe57d67421ad0c5fb1755811758c73870df96f081f032b196deff
job.yml 1f508cb7108c55885fbe98537676573bbfddf7b476b2023fd10a975d47afc037
libqpdf/qpdf/auto_job_decl.hh dc9232ed6961d709abacbbf71eb7d19c5e6951894aec6f480afcd3b6ba463206
libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538
libqpdf/qpdf/auto_job_init.hh b776c87e61d56842f23cb46fb6d4e44f5740e64854844bcc454fd812f7b4f8d5
libqpdf/qpdf/auto_job_init.hh 25a93a4ded91e1faa2d6a9d2bb85d811b5b49ae54c9fbdccad65b94538365418
libqpdf/qpdf/auto_job_schema.hh 6e6d72e99dacd02c22d9ac70f4dc78a935f879d2a16c89f07f2bdfa936cc2ae3
manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d
manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1

View File

@ -205,6 +205,7 @@ options:
- force-R5
- allow-insecure
- table: underlay/overlay
config: c_uo
prefix: UO
positional: true
required_parameter:

View File

@ -507,7 +507,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter)
bool range_valid = false;
try
{
parseNumrange(range.c_str(), 0, true);
QUtil::parse_numrange(range.c_str(), 0);
range_valid = true;
}
catch (std::runtime_error const&)
@ -532,7 +532,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter)
}
std::vector<int>
QPDFJob::parseNumrange(char const* range, int max, bool throw_error)
QPDFJob::parseNumrange(char const* range, int max)
{
try
{
@ -540,14 +540,7 @@ QPDFJob::parseNumrange(char const* range, int max, bool throw_error)
}
catch (std::runtime_error& e)
{
if (throw_error)
{
throw(e);
}
else
{
throw ConfigError(e.what());
}
throw ConfigError(e.what());
}
return std::vector<int>();
}

View File

@ -36,7 +36,6 @@ namespace
void usage(std::string const& message);
void initOptionTables();
void doFinalChecks();
void parseUnderOverlayOptions(QPDFJob::UnderOverlay*);
QPDFArgParser ap;
QPDFJob& o;
@ -44,6 +43,7 @@ namespace
std::shared_ptr<QPDFJob::CopyAttConfig> c_copy_att;
std::shared_ptr<QPDFJob::AttConfig> c_att;
std::shared_ptr<QPDFJob::PagesConfig> c_pages;
std::shared_ptr<QPDFJob::UOConfig> c_uo;
std::vector<char*> accumulated_args; // points to member in ap
char* pages_password;
};
@ -321,7 +321,7 @@ ArgParser::argPagesPositional(char* arg)
{
try
{
o.parseNumrange(range, 0, true);
QUtil::parse_numrange(range, 0);
}
catch (std::runtime_error& e1)
{
@ -369,19 +369,15 @@ ArgParser::argEndPages()
void
ArgParser::argUnderlay()
{
parseUnderOverlayOptions(&o.underlay);
this->c_uo = c_main->underlay();
this->ap.selectOptionTable(O_UNDERLAY_OVERLAY);
}
void
ArgParser::argOverlay()
{
parseUnderOverlayOptions(&o.overlay);
}
void
ArgParser::argRotate(char* parameter)
{
o.parseRotationParameter(parameter);
this->c_uo = c_main->overlay();
this->ap.selectOptionTable(O_UNDERLAY_OVERLAY);
}
void
@ -576,57 +572,14 @@ ArgParser::argEnd256BitEncryption()
void
ArgParser::argUOPositional(char* arg)
{
if (! o.under_overlay->filename.empty())
{
usage(o.under_overlay->which + " file already specified");
}
else
{
o.under_overlay->filename = arg;
}
}
void
ArgParser::argUOTo(char* parameter)
{
o.parseNumrange(parameter, 0);
o.under_overlay->to_nr = parameter;
}
void
ArgParser::argUOFrom(char* parameter)
{
if (strlen(parameter))
{
o.parseNumrange(parameter, 0);
}
o.under_overlay->from_nr = parameter;
}
void
ArgParser::argUORepeat(char* parameter)
{
if (strlen(parameter))
{
o.parseNumrange(parameter, 0);
}
o.under_overlay->repeat_nr = parameter;
}
void
ArgParser::argUOPassword(char* parameter)
{
o.under_overlay->password = QUtil::make_shared_cstr(parameter);
c_uo->path(arg);
}
void
ArgParser::argEndUnderlayOverlay()
{
if (o.under_overlay->filename.empty())
{
usage(o.under_overlay->which + " file not specified");
}
o.under_overlay = 0;
c_uo->end();
c_uo = nullptr;
}
void
@ -667,13 +620,6 @@ ArgParser::usage(std::string const& message)
this->ap.usage(message);
}
void
ArgParser::parseUnderOverlayOptions(QPDFJob::UnderOverlay* uo)
{
o.under_overlay = uo;
this->ap.selectOptionTable(O_UNDERLAY_OVERLAY);
}
void
ArgParser::parseOptions()
{

View File

@ -688,6 +688,13 @@ QPDFJob::Config::jobJsonFile(char const* parameter)
return *this;
}
QPDFJob::Config&
QPDFJob::Config::rotate(char const* parameter)
{
o.parseRotationParameter(parameter);
return *this;
}
std::shared_ptr<QPDFJob::CopyAttConfig>
QPDFJob::Config::copyAttachmentsFrom()
{
@ -875,3 +882,84 @@ QPDFJob::PagesConfig::pageSpec(std::string const& filename,
QPDFJob::PageSpec(filename, password, range));
return *this;
}
std::shared_ptr<QPDFJob::UOConfig>
QPDFJob::Config::overlay()
{
o.under_overlay = &o.overlay;
return std::shared_ptr<UOConfig>(new UOConfig(*this));
}
std::shared_ptr<QPDFJob::UOConfig>
QPDFJob::Config::underlay()
{
o.under_overlay = &o.underlay;
return std::shared_ptr<UOConfig>(new UOConfig(*this));
}
QPDFJob::UOConfig::UOConfig(Config& c) :
config(c)
{
}
QPDFJob::Config&
QPDFJob::UOConfig::end()
{
if (config.o.under_overlay->filename.empty())
{
usage(config.o.under_overlay->which + " file not specified");
}
config.o.under_overlay = 0;
return this->config;
}
QPDFJob::UOConfig&
QPDFJob::UOConfig::path(char const* parameter)
{
if (! config.o.under_overlay->filename.empty())
{
usage(config.o.under_overlay->which + " file already specified");
}
else
{
config.o.under_overlay->filename = parameter;
}
return *this;
}
QPDFJob::UOConfig&
QPDFJob::UOConfig::to(char const* parameter)
{
config.o.parseNumrange(parameter, 0);
config.o.under_overlay->to_nr = parameter;
return *this;
}
QPDFJob::UOConfig&
QPDFJob::UOConfig::from(char const* parameter)
{
if (strlen(parameter))
{
config.o.parseNumrange(parameter, 0);
}
config.o.under_overlay->from_nr = parameter;
return *this;
}
QPDFJob::UOConfig&
QPDFJob::UOConfig::repeat(char const* parameter)
{
if (strlen(parameter))
{
config.o.parseNumrange(parameter, 0);
}
config.o.under_overlay->repeat_nr = parameter;
return *this;
}
QPDFJob::UOConfig&
QPDFJob::UOConfig::password(char const* parameter)
{
config.o.under_overlay->password = QUtil::make_shared_cstr(parameter);
return *this;
}

View File

@ -24,7 +24,6 @@ void argEncrypt();
void argOverlay();
void argPages();
void argUnderlay();
void argRotate(char *);
void argPagesPositional(char*);
void argPagesPassword(char *);
void argEndPages();
@ -51,10 +50,6 @@ void argEnc256ForceR5();
void argEnc256AllowInsecure();
void argEnd256BitEncryption();
void argUOPositional(char*);
void argUOTo(char *);
void argUOFrom(char *);
void argUORepeat(char *);
void argUOPassword(char *);
void argEndUnderlayOverlay();
void argAttPositional(char*);
void argEndAttachment();

View File

@ -97,7 +97,7 @@ this->ap.addRequiredParameter("oi-min-width", [this](char *x){c_main->oiMinWidth
this->ap.addRequiredParameter("password", [this](char *x){c_main->password(x);}, "password");
this->ap.addRequiredParameter("password-file", [this](char *x){c_main->passwordFile(x);}, "password");
this->ap.addRequiredParameter("remove-attachment", [this](char *x){c_main->removeAttachment(x);}, "attachment");
this->ap.addRequiredParameter("rotate", p(&ArgParser::argRotate), "[+|-]angle");
this->ap.addRequiredParameter("rotate", [this](char *x){c_main->rotate(x);}, "[+|-]angle");
this->ap.addRequiredParameter("show-attachment", [this](char *x){c_main->showAttachment(x);}, "attachment");
this->ap.addRequiredParameter("show-object", [this](char *x){c_main->showObject(x);}, "trailer");
this->ap.addChoices("compress-streams", [this](char *x){c_main->compressStreams(x);}, true, yn_choices);
@ -137,10 +137,10 @@ this->ap.addBare("force-R5", b(&ArgParser::argEnc256ForceR5));
this->ap.addBare("allow-insecure", b(&ArgParser::argEnc256AllowInsecure));
this->ap.registerOptionTable("underlay/overlay", b(&ArgParser::argEndUnderlayOverlay));
this->ap.addPositional(p(&ArgParser::argUOPositional));
this->ap.addRequiredParameter("to", p(&ArgParser::argUOTo), "page-range");
this->ap.addRequiredParameter("from", p(&ArgParser::argUOFrom), "page-range");
this->ap.addRequiredParameter("repeat", p(&ArgParser::argUORepeat), "page-range");
this->ap.addRequiredParameter("password", p(&ArgParser::argUOPassword), "password");
this->ap.addRequiredParameter("to", [this](char *x){c_uo->to(x);}, "page-range");
this->ap.addRequiredParameter("from", [this](char *x){c_uo->from(x);}, "page-range");
this->ap.addRequiredParameter("repeat", [this](char *x){c_uo->repeat(x);}, "page-range");
this->ap.addRequiredParameter("password", [this](char *x){c_uo->password(x);}, "password");
this->ap.registerOptionTable("attachment", b(&ArgParser::argEndAttachment));
this->ap.addPositional(p(&ArgParser::argAttPositional));
this->ap.addBare("replace", [this](){c_att->replace();});