Commit 9c723aeb56351e20203f0c0058e5f718f44dee22

Authored by Jay Berkenbilt
1 parent 34f013c1

Allow --file with --overlay and --underlay

ChangeLog
  1 +2024-01-09 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Add new command-line arguments --file and --range which can be
  4 + used within --pages in place of positional arguments. Allow --file
  5 + to be used inside of --overlay and --underlay as well. These new
  6 + options can be freely intermixed with positional arguments. Also
  7 + add file(), range(), and password() to QPDFJob::PagesConfig as an
  8 + alternative to pageSpec.
  9 +
1 2024-01-08 Jay Berkenbilt <ejb@ql.org> 10 2024-01-08 Jay Berkenbilt <ejb@ql.org>
2 11
3 * 11.8.0: release 12 * 11.8.0: release
include/qpdf/QPDFJob.hh
@@ -266,8 +266,6 @@ class QPDFJob @@ -266,8 +266,6 @@ class QPDFJob
266 public: 266 public:
267 QPDF_DLL 267 QPDF_DLL
268 Config* endUnderlayOverlay(); 268 Config* endUnderlayOverlay();
269 - QPDF_DLL  
270 - UOConfig* file(std::string const& parameter);  
271 269
272 #include <qpdf/auto_job_c_uo.hh> 270 #include <qpdf/auto_job_c_uo.hh>
273 271
include/qpdf/auto_job_c_uo.hh
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
5 // 5 //
6 // clang-format off 6 // clang-format off
7 // 7 //
  8 +QPDF_DLL UOConfig* file(std::string const& parameter);
8 QPDF_DLL UOConfig* to(std::string const& parameter); 9 QPDF_DLL UOConfig* to(std::string const& parameter);
9 QPDF_DLL UOConfig* from(std::string const& parameter); 10 QPDF_DLL UOConfig* from(std::string const& parameter);
10 QPDF_DLL UOConfig* repeat(std::string const& parameter); 11 QPDF_DLL UOConfig* repeat(std::string const& parameter);
job.sums
@@ -6,15 +6,15 @@ include/qpdf/auto_job_c_copy_att.hh 50609012bff14fd82f0649185940d617d05d530cdc52 @@ -6,15 +6,15 @@ include/qpdf/auto_job_c_copy_att.hh 50609012bff14fd82f0649185940d617d05d530cdc52
6 include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a349e0cd4ae17ddd5 6 include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a349e0cd4ae17ddd5
7 include/qpdf/auto_job_c_main.hh dbfc221d1533120d1aa9c361d8d2483dea5fcb1c0fd95144d98d305e64ed32a6 7 include/qpdf/auto_job_c_main.hh dbfc221d1533120d1aa9c361d8d2483dea5fcb1c0fd95144d98d305e64ed32a6
8 include/qpdf/auto_job_c_pages.hh 09ca15649cc94fdaf6d9bdae28a20723f2a66616bf15aa86d83df31051d82506 8 include/qpdf/auto_job_c_pages.hh 09ca15649cc94fdaf6d9bdae28a20723f2a66616bf15aa86d83df31051d82506
9 -include/qpdf/auto_job_c_uo.hh ae21b69a1efa9333050f4833d465f6daff87e5b38e5106e49bbef5d4132e4ed1  
10 -job.yml 45761edeca048c7aa3e99340fcda1b6cd8efe4cc4c8b8a6628580243a4f49b57 9 +include/qpdf/auto_job_c_uo.hh 9c2f98a355858dd54d0bba444b73177a59c9e56833e02fa6406f429c07f39e62
  10 +job.yml 790dd0f62f124a6cc97cc54bae992a1f1b1f3a9b4f0294bcf123868f3d3b39d3
11 libqpdf/qpdf/auto_job_decl.hh 20d6affe1e260f5a1af4f1d82a820b933835440ff03020e877382da2e8dac6c6 11 libqpdf/qpdf/auto_job_decl.hh 20d6affe1e260f5a1af4f1d82a820b933835440ff03020e877382da2e8dac6c6
12 -libqpdf/qpdf/auto_job_help.hh b19f8a7433c70df70b42f893a8964c801aa2bb78eecaa13cffab7add2ff81e0a  
13 -libqpdf/qpdf/auto_job_init.hh d74759d4999201a89dafddf6f0c855e9151bbf77ea91a92d6806510292950123  
14 -libqpdf/qpdf/auto_job_json_decl.hh 485540cde820987cfbed0aa7642a6416f2bd37164c8d4f2322f1381e73edf903  
15 -libqpdf/qpdf/auto_job_json_init.hh c8de8658daa82115b49bf084cebe1be0b8aea73f864a219d7349acc0982b56fe  
16 -libqpdf/qpdf/auto_job_schema.hh 3e000b87255bee62ba29b794d67b2ae97cbbdfdb78be3878c51786913564901e 12 +libqpdf/qpdf/auto_job_help.hh 5808d936f6cd41af278ca298ed0c0762ce0a16956cbe1757a40e4443485cf31e
  13 +libqpdf/qpdf/auto_job_init.hh 19d1da7c4c0c635bd1c5db8d5f17df8edad3442f8eba006adb075cec295fa158
  14 +libqpdf/qpdf/auto_job_json_decl.hh 7c7fbf9f7fdf7a1f5f7cedb09af16b8dcf30b6860947bd38c970385b05d22fc1
  15 +libqpdf/qpdf/auto_job_json_init.hh 436567565691252d62a1852564729925ef996e78eba9ea3d947829c05f72a309
  16 +libqpdf/qpdf/auto_job_schema.hh 30dcb22bfa76d731dfa2cc2a226d7deaa25145f964b19ab44161356c909e4dc1
17 manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580 17 manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580
18 -manual/cli.rst 408e17dc13d37befe34badc400dd34d3c283952d17ee3bf9a9d44898af3dabc7  
19 -manual/qpdf.1 c99d66833aee7a2294176875ca2e9ddf2531d4ab8fb282ea5c45cb82a5d028ea 18 +manual/cli.rst 0e6a957defa4839abb9a69414de6a5ec5524fd6ff56fe9abf8f241bee54813e2
  19 +manual/qpdf.1 9833f7d93f66889413545ebac9b762cfd522bd632e5df3ad0b415daa55eac3a0
20 manual/qpdf.1.in 436ecc85d45c4c9e2dbd1725fb7f0177fb627179469f114561adf3cb6cbb677b 20 manual/qpdf.1.in 436ecc85d45c4c9e2dbd1725fb7f0177fb627179469f114561adf3cb6cbb677b
@@ -260,6 +260,7 @@ options: @@ -260,6 +260,7 @@ options:
260 prefix: UO 260 prefix: UO
261 positional: true 261 positional: true
262 required_parameter: 262 required_parameter:
  263 + file: file
263 to: page-range 264 to: page-range
264 from: page-range 265 from: page-range
265 repeat: page-range 266 repeat: page-range
@@ -436,7 +437,7 @@ json: @@ -436,7 +437,7 @@ json:
436 oi-min-width: 437 oi-min-width:
437 optimize-images: 438 optimize-images:
438 pages: 439 pages:
439 - - file: 440 + - Pages.file:
440 Pages.password: 441 Pages.password:
441 range: 442 range:
442 remove-page-labels: 443 remove-page-labels:
@@ -445,13 +446,13 @@ json: @@ -445,13 +446,13 @@ json:
445 set-page-labels: 446 set-page-labels:
446 - null 447 - null
447 overlay: 448 overlay:
448 - _file: "source file for overlay" 449 + UO.file:
449 UO.password: 450 UO.password:
450 from: 451 from:
451 repeat: 452 repeat:
452 to: 453 to:
453 underlay: 454 underlay:
454 - _file: "source file for underlay" 455 + UO.file:
455 UO.password: 456 UO.password:
456 from: 457 from:
457 repeat: 458 repeat:
libqpdf/QPDFJob_json.cc
@@ -487,6 +487,12 @@ Handlers::endPages() @@ -487,6 +487,12 @@ Handlers::endPages()
487 } 487 }
488 488
489 void 489 void
  490 +Handlers::setupPagesFile()
  491 +{
  492 + addParameter([this](char const* p) { c_pages->file(p); });
  493 +}
  494 +
  495 +void
490 Handlers::setupPagesPassword() 496 Handlers::setupPagesPassword()
491 { 497 {
492 addParameter([this](char const* p) { c_pages->password(p); }); 498 addParameter([this](char const* p) { c_pages->password(p); });
libqpdf/qpdf/auto_job_help.hh
@@ -695,7 +695,7 @@ underlaid on the primary output. Overlaid pages are drawn on top of @@ -695,7 +695,7 @@ underlaid on the primary output. Overlaid pages are drawn on top of
695 the destination page and may obscure the page. Underlaid pages are 695 the destination page and may obscure the page. Underlaid pages are
696 drawn below the destination page. Usage: 696 drawn below the destination page. Usage:
697 697
698 -{--overlay|--underlay} file 698 +{--overlay|--underlay} [--file=]file
699 [--password=password] 699 [--password=password]
700 [--to=page-range] 700 [--to=page-range]
701 [--from=[page-range]] 701 [--from=[page-range]]
libqpdf/qpdf/auto_job_init.hh
@@ -166,6 +166,7 @@ this-&gt;ap.addChoices(&quot;modify-other&quot;, [this](std::string const&amp; x){c_enc-&gt;modifyOt @@ -166,6 +166,7 @@ this-&gt;ap.addChoices(&quot;modify-other&quot;, [this](std::string const&amp; x){c_enc-&gt;modifyOt
166 this->ap.addChoices("modify", [this](std::string const& x){c_enc->modify(x);}, true, modify128_choices); 166 this->ap.addChoices("modify", [this](std::string const& x){c_enc->modify(x);}, true, modify128_choices);
167 this->ap.registerOptionTable("underlay/overlay", b(&ArgParser::argEndUnderlayOverlay)); 167 this->ap.registerOptionTable("underlay/overlay", b(&ArgParser::argEndUnderlayOverlay));
168 this->ap.addPositional(p(&ArgParser::argUOPositional)); 168 this->ap.addPositional(p(&ArgParser::argUOPositional));
  169 +this->ap.addRequiredParameter("file", [this](std::string const& x){c_uo->file(x);}, "file");
169 this->ap.addRequiredParameter("to", [this](std::string const& x){c_uo->to(x);}, "page-range"); 170 this->ap.addRequiredParameter("to", [this](std::string const& x){c_uo->to(x);}, "page-range");
170 this->ap.addRequiredParameter("from", [this](std::string const& x){c_uo->from(x);}, "page-range"); 171 this->ap.addRequiredParameter("from", [this](std::string const& x){c_uo->from(x);}, "page-range");
171 this->ap.addRequiredParameter("repeat", [this](std::string const& x){c_uo->repeat(x);}, "page-range"); 172 this->ap.addRequiredParameter("repeat", [this](std::string const& x){c_uo->repeat(x);}, "page-range");
libqpdf/qpdf/auto_job_json_decl.hh
@@ -41,6 +41,7 @@ void beginPagesArray(JSON); @@ -41,6 +41,7 @@ void beginPagesArray(JSON);
41 void endPagesArray(); 41 void endPagesArray();
42 void beginPages(JSON); 42 void beginPages(JSON);
43 void endPages(); 43 void endPages();
  44 +void setupPagesFile();
44 void setupPagesPassword(); 45 void setupPagesPassword();
45 void beginSetPageLabelsArray(JSON); 46 void beginSetPageLabelsArray(JSON);
46 void endSetPageLabelsArray(); 47 void endSetPageLabelsArray();
libqpdf/qpdf/auto_job_json_init.hh
@@ -402,7 +402,7 @@ pushKey(&quot;pages&quot;); @@ -402,7 +402,7 @@ pushKey(&quot;pages&quot;);
402 beginArray(bindJSON(&Handlers::beginPagesArray), bindBare(&Handlers::endPagesArray)); // .pages[] 402 beginArray(bindJSON(&Handlers::beginPagesArray), bindBare(&Handlers::endPagesArray)); // .pages[]
403 beginDict(bindJSON(&Handlers::beginPages), bindBare(&Handlers::endPages)); // .pages 403 beginDict(bindJSON(&Handlers::beginPages), bindBare(&Handlers::endPages)); // .pages
404 pushKey("file"); 404 pushKey("file");
405 -addParameter([this](std::string const& p) { c_pages->file(p); }); 405 +setupPagesFile();
406 popHandler(); // key: file 406 popHandler(); // key: file
407 pushKey("password"); 407 pushKey("password");
408 setupPagesPassword(); 408 setupPagesPassword();
libqpdf/qpdf/auto_job_schema.hh
@@ -152,14 +152,14 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({ @@ -152,14 +152,14 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({
152 "number pages for the entire document" 152 "number pages for the entire document"
153 ], 153 ],
154 "overlay": { 154 "overlay": {
155 - "file": "source file for overlay", 155 + "file": "source for pages",
156 "password": "password for encrypted file", 156 "password": "password for encrypted file",
157 "from": "source pages for underlay/overlay", 157 "from": "source pages for underlay/overlay",
158 "repeat": "overlay/underlay pages to repeat", 158 "repeat": "overlay/underlay pages to repeat",
159 "to": "destination pages for underlay/overlay" 159 "to": "destination pages for underlay/overlay"
160 }, 160 },
161 "underlay": { 161 "underlay": {
162 - "file": "source file for underlay", 162 + "file": "source for pages",
163 "password": "password for encrypted file", 163 "password": "password for encrypted file",
164 "from": "source pages for underlay/overlay", 164 "from": "source pages for underlay/overlay",
165 "repeat": "overlay/underlay pages to repeat", 165 "repeat": "overlay/underlay pages to repeat",
manual/cli.rst
@@ -2789,7 +2789,7 @@ Overlay and Underlay @@ -2789,7 +2789,7 @@ Overlay and Underlay
2789 the destination page and may obscure the page. Underlaid pages are 2789 the destination page and may obscure the page. Underlaid pages are
2790 drawn below the destination page. Usage: 2790 drawn below the destination page. Usage:
2791 2791
2792 - {--overlay|--underlay} file 2792 + {--overlay|--underlay} [--file=]file
2793 [--password=password] 2793 [--password=password]
2794 [--to=page-range] 2794 [--to=page-range]
2795 [--from=[page-range]] 2795 [--from=[page-range]]
@@ -2813,7 +2813,7 @@ as follows: @@ -2813,7 +2813,7 @@ as follows:
2813 2813
2814 :: 2814 ::
2815 2815
2816 - {--overlay|--underlay} file [options] -- 2816 + {--overlay|--underlay} [--file=]file [options] --
2817 2817
2818 Overlay and underlay options are processed late, so they can be 2818 Overlay and underlay options are processed late, so they can be
2819 combined with other options like merging and will apply to the final 2819 combined with other options like merging and will apply to the final
@@ -2821,8 +2821,10 @@ output. The ``--overlay`` and ``--underlay`` options work the same @@ -2821,8 +2821,10 @@ output. The ``--overlay`` and ``--underlay`` options work the same
2821 way, except underlay pages are drawn underneath the page to which they 2821 way, except underlay pages are drawn underneath the page to which they
2822 are applied, possibly obscured by the original page, and overlay files 2822 are applied, possibly obscured by the original page, and overlay files
2823 are drawn on top of the page to which they are applied, possibly 2823 are drawn on top of the page to which they are applied, possibly
2824 -obscuring the page. You can combine overlay and underlay, but you can  
2825 -only specify each option at most one time. 2824 +obscuring the page. The ability to specify the file using the
  2825 +:qpdf:ref:`--file` option was added in qpdf 11.9.0. You can combine
  2826 +overlay and underlay, but you can only specify each option at most one
  2827 +time.
2826 2828
2827 The default behavior of overlay and underlay is that pages are taken 2829 The default behavior of overlay and underlay is that pages are taken
2828 from the overlay/underlay file in sequence and applied to 2830 from the overlay/underlay file in sequence and applied to
manual/qpdf.1
@@ -833,7 +833,7 @@ underlaid on the primary output. Overlaid pages are drawn on top of @@ -833,7 +833,7 @@ underlaid on the primary output. Overlaid pages are drawn on top of
833 the destination page and may obscure the page. Underlaid pages are 833 the destination page and may obscure the page. Underlaid pages are
834 drawn below the destination page. Usage: 834 drawn below the destination page. Usage:
835 835
836 -{--overlay|--underlay} file 836 +{--overlay|--underlay} [--file=]file
837 [--password=password] 837 [--password=password]
838 [--to=page-range] 838 [--to=page-range]
839 [--from=[page-range]] 839 [--from=[page-range]]
manual/release-notes.rst
@@ -38,6 +38,21 @@ Planned changes for future 12.x (subject to change): @@ -38,6 +38,21 @@ Planned changes for future 12.x (subject to change):
38 38
39 .. x.y.z: not yet released 39 .. x.y.z: not yet released
40 40
  41 +11.9.0: not yet released
  42 + - CLI Enhancements
  43 +
  44 + - Add new command-line arguments :qpdf:ref:`--file` and
  45 + :qpdf:ref:`--range` which can be used within :qpdf:ref:`--pages`
  46 + in place of positional arguments. Allow :qpdf:ref:`--file` to be
  47 + used inside of :qpdf:ref:`--overlay` and :qpdf:ref:`--underlay`
  48 + as well. These new options can be freely intermixed with
  49 + positional arguments.
  50 +
  51 + - Library Enhancements
  52 +
  53 + - Add ``file()``, ``range()``, and ``password()`` to
  54 + ``QPDFJob::PagesConfig`` as an alternative to ``pageSpec``.
  55 +
41 11.8.0: January 8, 2024 56 11.8.0: January 8, 2024
42 - Bug fixes: 57 - Bug fixes:
43 58
qpdf/qtest/form-xobject.test
@@ -51,9 +51,9 @@ foreach (my $i = 64; $i &lt;= 67; ++$i) @@ -51,9 +51,9 @@ foreach (my $i = 64; $i &lt;= 67; ++$i)
51 51
52 my @uo_cases = ( 52 my @uo_cases = (
53 '--underlay fxo-green.pdf --repeat=z --to=1-14 --' . 53 '--underlay fxo-green.pdf --repeat=z --to=1-14 --' .
54 - ' --overlay fxo-blue.pdf --', # 1 54 + ' --overlay --file=fxo-blue.pdf --', # 1
55 '--overlay fxo-green.pdf --from= --repeat=r2,r1 --' . 55 '--overlay fxo-green.pdf --from= --repeat=r2,r1 --' .
56 - ' --underlay fxo-blue.pdf --from=z-1 --', # 2 56 + ' --underlay --file=fxo-blue.pdf --from=z-1 --', # 2
57 '--overlay fxo-green.pdf --from= --repeat=r2,r1 --' . 57 '--overlay fxo-green.pdf --from= --repeat=r2,r1 --' .
58 ' --underlay fxo-blue.pdf --from=z-1 -- --coalesce-contents', # 3 58 ' --underlay fxo-blue.pdf --from=z-1 -- --coalesce-contents', # 3
59 '--overlay fxo-green.pdf --', # 4 59 '--overlay fxo-green.pdf --', # 4