From c8729398ddb9ac82b00bbafaf24e8d37543e5b9e Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Tue, 11 Jan 2022 11:49:33 -0500 Subject: Generate help content from manual This is a massive rewrite of the help text and cli.rst section of the manual. All command-line flags now have their own help and are specifically index. qpdf --help is completely redone. --- libqpdf/QPDFArgParser.cc | 9 +- libqpdf/QPDFJob_argv.cc | 511 +------------------------- libqpdf/qpdf/auto_job_help.hh | 822 ++++++++++++++++++++++++++++++++++++++++++ libqpdf/qpdf/auto_job_init.hh | 1 - 4 files changed, 830 insertions(+), 513 deletions(-) create mode 100644 libqpdf/qpdf/auto_job_help.hh (limited to 'libqpdf') diff --git a/libqpdf/QPDFArgParser.cc b/libqpdf/QPDFArgParser.cc index 69a97a5c..8d7c978c 100644 --- a/libqpdf/QPDFArgParser.cc +++ b/libqpdf/QPDFArgParser.cc @@ -967,21 +967,20 @@ void QPDFArgParser::getAllHelp(std::ostringstream& msg) { getTopHelp(msg); - auto show = [this, &msg](std::map& topics, - std::string const& label) { + auto show = [this, &msg](std::map& topics) { for (auto const& i: topics) { auto const& topic = i.first; msg << std::endl - << "== " << label << " " << topic + << "== " << topic << " (" << i.second.short_text << ") ==" << std::endl << std::endl; getTopicHelp(topic, i.second, msg); } }; - show(this->m->help_topics, "topic"); - show(this->m->option_help, "option"); + show(this->m->help_topics); + show(this->m->option_help); msg << std::endl << "====" << std::endl; } diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index 9b678257..da0bcd4a 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -48,6 +48,8 @@ ArgParser::ArgParser(QPDFArgParser& ap, QPDFJob& o) : initOptionTables(); } +#include + void ArgParser::initOptionTables() { @@ -55,6 +57,8 @@ ArgParser::initOptionTables() # include this->ap.addFinalCheck( QPDFArgParser::bindBare(&ArgParser::doFinalChecks, this)); + // add_help is defined in auto_job_help.hh + add_help(this->ap); } void @@ -127,513 +131,6 @@ ArgParser::argCopyright() << std::endl; } -#if 0 -void -ArgParser::argHelp() -{ - // QXXXQ - std::cout - // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 - << "Usage: qpdf [options] {infile | --empty} [page_selection_options] outfile\n" - << "\n" - << "An option summary appears below. Please see the documentation for details.\n" - << "\n" - << "If @filename appears anywhere in the command-line, each line of filename\n" - << "will be interpreted as an argument. No interpolation is done. Line\n" - << "terminators are stripped, but leading and trailing whitespace is\n" - << "intentionally preserved. @- can be specified to read from standard input.\n" - << "\n" - << "The output file can be - to indicate writing to standard output, or it can\n" - << "be --replace-input to cause qpdf to replace the input file with the output.\n" - << "\n" - << "Note that when contradictory options are provided, whichever options are\n" - << "provided last take precedence.\n" - << "\n" - << "\n" - << "Basic Options\n" - << "-------------\n" - << "\n" - << "--version show version of qpdf\n" - << "--copyright show qpdf's copyright and license information\n" - << "--help show command-line argument help\n" - << "--show-crypto show supported crypto providers; default is first\n" - << "--completion-bash output a bash complete command you can eval\n" - << "--completion-zsh output a zsh complete command you can eval\n" - << "--password=password specify a password for accessing encrypted files\n" - << "--password-file=file get the password the first line \"file\"; use \"-\"\n" - << " to read the password from stdin (without prompt or\n" - << " disabling echo, so use with caution)\n" - << "--is-encrypted silently exit 0 if the file is encrypted or 2\n" - << " if not; useful for shell scripts\n" - << "--requires-password silently exit 0 if a password (other than as\n" - << " supplied) is required, 2 if the file is not\n" - << " encrypted, or 3 if the file is encrypted\n" - << " but requires no password or the supplied password\n" - << " is correct; useful for shell scripts\n" - << "--verbose provide additional informational output\n" - << "--progress give progress indicators while writing output\n" - << "--no-warn suppress warnings\n" - << "--warning-exit-0 exit with code 0 instead of 3 if there are warnings\n" - << "--linearize generated a linearized (web optimized) file\n" - << "--replace-input use in place of specifying an output file; qpdf will\n" - << " replace the input file with the output\n" - << "--copy-encryption=file copy encryption parameters from specified file\n" - << "--encryption-file-password=password\n" - << " password used to open the file from which encryption\n" - << " parameters are being copied\n" - << "--allow-weak-crypto allow creation of files using weak cryptographic\n" - << " algorithms\n" - << "--encrypt options -- generate an encrypted file\n" - << "--decrypt remove any encryption on the file\n" - << "--password-is-hex-key treat primary password option as a hex-encoded key\n" - << "--suppress-password-recovery\n" - << " do not attempt recovering from password string\n" - << " encoding errors\n" - << "--password-mode=mode control qpdf's encoding of passwords\n" - << "--pages options -- select specific pages from one or more files\n" - << "--collate=n causes files specified in --pages to be collated\n" - << " in groups of n pages (default 1) rather than\n" - << " concatenated\n" - << "--flatten-rotation move page rotation from /Rotate key to content\n" - << "--rotate=[+|-]angle[:page-range]\n" - << " rotate each specified page 0, 90, 180, or 270\n" - << " degrees; rotate all pages if no page range is given\n" - << "--split-pages=[n] write each output page to a separate file\n" - << "--overlay options -- overlay pages from another file\n" - << "--underlay options -- underlay pages from another file\n" - << "\n" - << "Note that you can use the @filename or @- syntax for any argument at any\n" - << "point in the command. This provides a good way to specify a password without\n" - << "having to explicitly put it on the command line. @filename or @- must be a\n" - << "word by itself. Syntax such as --arg=@filename doesn't work.\n" - << "\n" - << "If none of --copy-encryption, --encrypt or --decrypt are given, qpdf will\n" - << "preserve any encryption data associated with a file.\n" - << "\n" - << "Note that when copying encryption parameters from another file, all\n" - << "parameters will be copied, including both user and owner passwords, even\n" - << "if the user password is used to open the other file. This works even if\n" - << "the owner password is not known.\n" - << "\n" - << "The --password-is-hex-key option overrides the normal computation of\n" - << "encryption keys. It only applies to the password used to open the main\n" - << "file. This option is not ordinarily useful but can be helpful for forensic\n" - << "or investigatory purposes. See manual for further discussion.\n" - << "\n" - << "The --rotate flag can be used to specify pages to rotate pages either\n" - << "0, 90, 180, or 270 degrees. The page range is specified in the same\n" - << "format as with the --pages option, described below. Repeat the option\n" - << "to rotate multiple groups of pages. If the angle is preceded by + or -,\n" - << "it is added to or subtracted from the original rotation. Otherwise, the\n" - << "rotation angle is set explicitly to the given value. You almost always\n" - << "want to use + or - unless you are certain about the internals of the PDF\n" - << "you are working with.\n" - << "\n" - << "If --split-pages is specified, each page is written to a separate output\n" - << "file. File names are generated as follows:\n" - << "* If the string %d appears in the output file name, it is replaced with a\n" - << " zero-padded page range starting from 1\n" - << "* Otherwise, if the output file name ends in .pdf (case insensitive), a\n" - << " zero-padded page range, preceded by a dash, is inserted before the file\n" - << " extension\n" - << "* Otherwise, the file name is appended with a zero-padded page range\n" - << " preceded by a dash.\n" - << "Page ranges are single page numbers for single-page groups or first-last\n" - << "for multipage groups.\n" - << "\n" - << "\n" - << "Encryption Options\n" - << "------------------\n" - << "\n" - << " --encrypt user-password owner-password key-length flags --\n" - << "\n" - << "Note that -- terminates parsing of encryption flags.\n" - << "\n" - << "Either or both of the user password and the owner password may be\n" - << "empty strings.\n" - << "\n" - << "key-length may be 40, 128, or 256\n" - << "\n" - << "Additional flags are dependent upon key length.\n" - << "\n" - << " If 40:\n" - << "\n" - << " --print=[yn] allow printing\n" - << " --modify=[yn] allow document modification\n" - << " --extract=[yn] allow text/graphic extraction\n" - << " --annotate=[yn] allow comments and form fill-in and signing\n" - << "\n" - << " If 128:\n" - << "\n" - << " --accessibility=[yn] allow accessibility to visually impaired\n" - << " --extract=[yn] allow other text/graphic extraction\n" - << " --print=print-opt control printing access\n" - << " --assemble=[yn] allow document assembly\n" - << " --annotate=[yn] allow commenting/filling form fields\n" - << " --form=[yn] allow filling form fields\n" - << " --modify-other=[yn] allow other modifications\n" - << " --modify=modify-opt control modify access (old way)\n" - << " --cleartext-metadata prevents encryption of metadata\n" - << " --use-aes=[yn] indicates whether to use AES encryption\n" - << " --force-V4 forces use of V=4 encryption handler\n" - << "\n" - << " If 256, options are the same as 128 with these exceptions:\n" - << " --force-V4 this option is not available with 256-bit keys\n" - << " --use-aes this option is always on with 256-bit keys\n" - << " --force-R5 forces use of deprecated R=5 encryption\n" - << " --allow-insecure allow the owner password to be empty when the\n" - << " user password is not empty\n" - << "\n" - << " print-opt may be:\n" - << "\n" - << " full allow full printing\n" - << " low allow only low-resolution printing\n" - << " none disallow printing\n" - << "\n" - << " modify-opt may be:\n" - << "\n" - << " all allow full document modification\n" - << " annotate allow comment authoring and form operations\n" - << " form allow form field fill-in and signing\n" - << " assembly allow document assembly only\n" - << " none allow no modifications\n" - << "\n" - << "The default for each permission option is to be fully permissive. Please\n" - << "refer to the manual for more details on the modify options.\n" - << "\n" - << "Specifying cleartext-metadata forces the PDF version to at least 1.5.\n" - << "Specifying use of AES forces the PDF version to at least 1.6. These\n" - << "options are both off by default.\n" - << "\n" - << "The --force-V4 flag forces the V=4 encryption handler introduced in PDF 1.5\n" - << "to be used even if not otherwise needed. This option is primarily useful\n" - << "for testing qpdf and has no other practical use.\n" - << "\n" - << "A warning will be issued if you attempt to encrypt a file with a format that\n" - << "uses a weak cryptographic algorithm such as RC4. To suppress the warning,\n" - << "specify the option --allow-weak-crypto. This option is outside of encryption\n" - << "options (e.g. --allow-week-crypto --encrypt u o 128 --)\n" - << "\n" - << "\n" - << "Password Modes\n" - << "--------------\n" - << "\n" - << "The --password-mode controls how qpdf interprets passwords supplied\n" - << "on the command-line. qpdf's default behavior is correct in almost all\n" - << "cases, but you can fine-tune with this option.\n" - << "\n" - << " bytes: use the password literally as supplied\n" - << " hex-bytes: interpret the password as a hex-encoded byte string\n" - << " unicode: interpret the password as a UTF-8 encoded string\n" - << " auto: attempt to infer the encoding and adjust as needed\n" - << "\n" - << "This is a complex topic. See the manual for a complete discussion.\n" - << "\n" - << "\n" - << "Page Selection Options\n" - << "----------------------\n" - << "\n" - << "These options allow pages to be selected from one or more PDF files.\n" - << "Whatever file is given as the primary input file is used as the\n" - << "starting point, but its pages are replaced with pages as specified.\n" - << "\n" - << "--keep-files-open=[yn]\n" - << "--keep-files-open-threshold=count\n" - << "--pages file [ --password=password ] [ page-range ] ... --\n" - << "\n" - << "For each file that pages should be taken from, specify the file, a\n" - << "password needed to open the file (if any), and a page range. The\n" - << "password needs to be given only once per file. If any of the input\n" - << "files are the same as the primary input file or the file used to copy\n" - << "encryption parameters (if specified), you do not need to repeat the\n" - << "password here. The same file can be repeated multiple times. The\n" - << "filename \".\" may be used to refer to the current input file. All\n" - << "non-page data (info, outlines, page numbers, etc. are taken from the\n" - << "primary input file. To discard this, use --empty as the primary\n" - << "input.\n" - << "\n" - << "By default, when more than 200 distinct files are specified, qpdf will\n" - << "close each file when not being referenced. With 200 files or fewer, all\n" - << "files will be kept open at the same time. This behavior can be overridden\n" - << "by specifying --keep-files-open=[yn]. Closing and opening files can have\n" - << "very high overhead on certain file systems, especially networked file\n" - << "systems. The threshold of 200 can be modified with\n" - << "--keep-files-open-threshold\n" - << "\n" - << "The page range is a set of numbers separated by commas, ranges of\n" - << "numbers separated dashes, or combinations of those. The character\n" - << "\"z\" represents the last page. A number preceded by an \"r\" indicates\n" - << "to count from the end, so \"r3-r1\" would be the last three pages of the\n" - << "document. Pages can appear in any order. Ranges can appear with a\n" - << "high number followed by a low number, which causes the pages to appear in\n" - << "reverse. Numbers may be repeated. A page range may be appended with :odd\n" - << "to indicate odd pages in the selected range or :even to indicate even\n" - << "pages.\n" - << "\n" - << "If the page range is omitted, the range of 1-z is assumed. qpdf decides\n" - << "that the page range is omitted if the range argument is either -- or a\n" - << "valid file name and not a valid range.\n" - << "\n" - << "The usual behavior of --pages is to add all pages from the first file,\n" - << "then all pages from the second file, and so on. If the --collate option\n" - << "is specified, then pages are collated instead. In other words, qpdf takes\n" - << "the first page from the first file, the first page from the second file,\n" - << "and so on until it runs out of files; then it takes the second page from\n" - << "each file, etc. When a file runs out of pages, it is skipped until all\n" - << "specified pages are taken from all files.\n" - << "\n" - << "See the manual for examples and a discussion of additional subtleties.\n" - << "\n" - << "\n" - << "Overlay and Underlay Options\n" - << "----------------------------\n" - << "\n" - << "These options allow pages from another file to be overlaid or underlaid\n" - << "on the primary output. Overlaid pages are drawn on top of the destination\n" - << "page and may obscure the page. Underlaid pages are drawn below the\n" - << "destination page.\n" - << "\n" - << "{--overlay | --underlay } file\n" - " [ --password=password ]\n" - " [ --to=page-range ]\n" - " [ --from=[page-range] ]\n" - " [ --repeat=page-range ]\n" - " --\n" - << "\n" - << "For overlay and underlay, a file and optional password are specified, along\n" - << "with a series of optional page ranges. The default behavior is that each\n" - << "page of the overlay or underlay file is imposed on the corresponding page\n" - << "of the primary output until it runs out of pages, and any extra pages are\n" - << "ignored. The page range options all take page ranges in the same form as\n" - << "the --pages option. They have the following meanings:\n" - << "\n" - << " --to: the pages in the primary output to which overlay/underlay is\n" - << " applied\n" - << " --from: the pages from the overlay/underlay file that are used\n" - << " --repeat: pages from the overlay/underlay that are repeated after\n" - << " any \"from\" pages have been exhausted\n" - << "\n" - << "\n" - << "Embedded Files/Attachments Options\n" - << "----------------------------------\n" - << "\n" - << "These options can be used to work with embedded files, also known as\n" - << "attachments.\n" - << "\n" - << "--list-attachments show key and stream number for embedded files;\n" - << " combine with --verbose for more detailed information\n" - << "--show-attachment=key write the contents of the specified attachment to\n" - << " standard output as binary data\n" - << "--add-attachment file options --\n" - << " add or replace an attachment\n" - << "--remove-attachment=key remove the specified attachment; repeatable\n" - << "--copy-attachments-from file options --\n" - << " copy attachments from another file\n" - << "\n" - << "The \"key\" option is the unique name under which the attachment is registered\n" - << "within the PDF file. You can get this using the --list-attachments option. This\n" - << "is usually the same as the filename, but it doesn't have to be.\n" - << "\n" - << "Options for adding attachments:\n" - << "\n" - << " file path to the file to attach\n" - << " --key=key the name of this in the embedded files table;\n" - << " defaults to the last path element of file\n" - << " --filename=name the file name of the attachment; this is what is\n" - << " usually displayed to the user; defaults to the\n" - << " last path element of file\n" - << " --creationdate=date creation date in PDF format; defaults to the\n" - << " current time\n" - << " --moddate=date modification date in PDF format; defaults to the\n" - << " current time\n" - << " --mimetype=type/subtype mime type of attachment (e.g. application/pdf)\n" - << " --description=\"text\" attachment description\n" - << " --replace replace any existing attachment with the same key\n" - << "\n" - << "Options for copying attachments:\n" - << "\n" - << " file file whose attachments should be copied\n" - << " --password=password password to open the other file, if needed\n" - << " --prefix=prefix a prefix to insert in front of each key;\n" - << " required if needed to ensure each attachment\n" - << " has a unique key\n" - << "\n" - << "Date format: D:yyyymmddhhmmss where is either Z for UTC or a timezone\n" - << "offset in the form -hh'mm' or +hh'mm'.\n" - << "Examples: D:20210207161528-05'00', D:20210207211528Z\n" - << "\n" - << "\n" - << "Advanced Parsing Options\n" - << "------------------------\n" - << "\n" - << "These options control aspects of how qpdf reads PDF files. Mostly these are\n" - << "of use to people who are working with damaged files. There is little reason\n" - << "to use these options unless you are trying to solve specific problems.\n" - << "\n" - << "--suppress-recovery prevents qpdf from attempting to recover damaged files\n" - << "--ignore-xref-streams tells qpdf to ignore any cross-reference streams\n" - << "\n" - << "\n" - << "Advanced Transformation Options\n" - << "-------------------------------\n" - << "\n" - << "These transformation options control fine points of how qpdf creates\n" - << "the output file. Mostly these are of use only to people who are very\n" - << "familiar with the PDF file format or who are PDF developers.\n" - << "\n" - << "--stream-data=option controls transformation of stream data (below)\n" - << "--compress-streams=[yn] controls whether to compress streams on output\n" - << "--decode-level=option controls how to filter streams from the input\n" - << "--recompress-flate recompress streams already compressed with Flate\n" - << "--compression-level=n set zlib compression level; most effective with\n" - << " --recompress-flate --object-streams=generate\n" - << "--normalize-content=[yn] enables or disables normalization of content streams\n" - << "--object-streams=mode controls handing of object streams\n" - << "--preserve-unreferenced preserve unreferenced objects\n" - << "--remove-unreferenced-resources={auto,yes,no}\n" - << " whether to remove unreferenced page resources\n" - << "--preserve-unreferenced-resources\n" - << " synonym for --remove-unreferenced-resources=no\n" - << "--newline-before-endstream always put a newline before endstream\n" - << "--coalesce-contents force all pages' content to be a single stream\n" - << "--flatten-annotations=option\n" - << " incorporate rendering of annotations into page\n" - << " contents including those for interactive form\n" - << " fields; may also want --generate-appearances\n" - << "--generate-appearances generate appearance streams for form fields\n" - << "--optimize-images compress images with DCT (JPEG) when advantageous\n" - << "--oi-min-width=w do not optimize images whose width is below w;\n" - << " default is 128. Use 0 to mean no minimum\n" - << "--oi-min-height=h do not optimize images whose height is below h\n" - << " default is 128. Use 0 to mean no minimum\n" - << "--oi-min-area=a do not optimize images whose pixel count is below a\n" - << " default is 16,384. Use 0 to mean no minimum\n" - << "--externalize-inline-images convert inline images to regular images; by\n" - << " default, images of at least 1,024 bytes are\n" - << " externalized\n" - << "--ii-min-bytes=bytes specify minimum size of inline images to be\n" - << " converted to regular images\n" - << "--keep-inline-images exclude inline images from image optimization\n" - << "--remove-page-labels remove any page labels present in the output file\n" - << "--qdf turns on \"QDF mode\" (below)\n" - << "--linearize-pass1=file write intermediate pass of linearized file\n" - << " for debugging\n" - << "--min-version=version sets the minimum PDF version of the output file\n" - << "--force-version=version forces this to be the PDF version of the output file\n" - << "\n" - << "Options for --flatten-annotations are all, print, or screen. If the option\n" - << "is print, only annotations marked as print are included. If the option is\n" - << "screen, options marked as \"no view\" are excluded. Otherwise, annotations\n" - << "are flattened regardless of the presence of print or NoView flags. It is\n" - << "common for PDF files to have a flag set that appearance streams need to be\n" - << "regenerated. This happens when someone changes a form value with software\n" - << "that does not know how to render the new value. qpdf will not flatten form\n" - << "fields in files like this. If you get this warning, you have two choices:\n" - << "either use qpdf's --generate-appearances flag to tell qpdf to go ahead and\n" - << "regenerate appearances, or use some other tool to generate the appearances.\n" - << "qpdf does a pretty good job with most forms when only ASCII and \"Windows\n" - << "ANSI\" characters are used in form field values, but if your form fields\n" - << "contain other characters, rich text, or are other than left justified, you\n" - << "will get better results first saving with other software.\n" - << "\n" - << "Version numbers may be expressed as major.minor.extension-level, so 1.7.3\n" - << "means PDF version 1.7 at extension level 3.\n" - << "\n" - << "Values for stream data options:\n" - << "\n" - << " compress recompress stream data when possible (default)\n" - << " preserve leave all stream data as is\n" - << " uncompress uncompress stream data when possible\n" - << "\n" - << "Values for object stream mode:\n" - << "\n" - << " preserve preserve original object streams (default)\n" - << " disable don't write any object streams\n" - << " generate use object streams wherever possible\n" - << "\n" - << "When --compress-streams=n is specified, this overrides the default behavior\n" - << "of qpdf, which is to attempt compress uncompressed streams. Setting\n" - << "stream data mode to uncompress or preserve has the same effect.\n" - << "\n" - << "The --decode-level parameter may be set to one of the following values:\n" - << " none do not decode streams\n" - << " generalized decode streams compressed with generalized filters\n" - << " including LZW, Flate, and the ASCII encoding filters.\n" - << " specialized additionally decode streams with non-lossy specialized\n" - << " filters including RunLength\n" - << " all additionally decode streams with lossy filters\n" - << " including DCT (JPEG)\n" - << "\n" - << "In qdf mode, by default, content normalization is turned on, and the\n" - << "stream data mode is set to uncompress. QDF mode does not support\n" - << "linearized files. The --linearize flag disables qdf mode.\n" - << "\n" - << "Setting the minimum PDF version of the output file may raise the version\n" - << "but will never lower it. Forcing the PDF version of the output file may\n" - << "set the PDF version to a lower value than actually allowed by the file's\n" - << "contents. You should only do this if you have no other possible way to\n" - << "open the file or if you know that the file definitely doesn't include\n" - << "features not supported later versions.\n" - << "\n" - << "Testing, Inspection, and Debugging Options\n" - << "------------------------------------------\n" - << "\n" - << "These options can be useful for digging into PDF files or for use in\n" - << "automated test suites for software that uses the qpdf library.\n" - << "\n" - << "--deterministic-id generate deterministic /ID\n" - << "--static-id generate static /ID: FOR TESTING ONLY!\n" - << "--static-aes-iv use a static initialization vector for AES-CBC\n" - << " This is option is not secure! FOR TESTING ONLY!\n" - << "--no-original-object-ids suppress original object ID comments in qdf mode\n" - << "--show-encryption quickly show encryption parameters\n" - << "--show-encryption-key when showing encryption, reveal the actual key\n" - << "--check-linearization check file integrity and linearization status\n" - << "--show-linearization check and show all linearization data\n" - << "--show-xref show the contents of the cross-reference table\n" - << "--show-object=trailer|obj[,gen]\n" - << " show the contents of the given object\n" - << " --raw-stream-data show raw stream data instead of object contents\n" - << " --filtered-stream-data show filtered stream data instead of object contents\n" - << "--show-npages print the number of pages in the file\n" - << "--show-pages shows the object/generation number for each page\n" - << " --with-images also shows the object IDs for images on each page\n" - << "--check check file structure + encryption, linearization\n" - << "--json generate a json representation of the file\n" - << "--json-help describe the format of the json representation\n" - << "--json-key=key repeatable; prune json structure to include only\n" - << " specified keys. If absent, all keys are shown\n" - << "--json-object=trailer|[obj,gen]\n" - << " repeatable; include only specified objects in the\n" - << " \"objects\" section of the json. If absent, all\n" - << " objects are shown\n" - << "\n" - << "The json representation generated by qpdf is designed to facilitate\n" - << "processing of qpdf from other programming languages that have a hard\n" - << "time calling C++ APIs. Run qpdf --json-help for details on the format.\n" - << "The manual has more in-depth information about the json representation\n" - << "and certain compatibility guarantees that qpdf provides.\n" - << "\n" - << "The --raw-stream-data and --filtered-stream-data options are ignored\n" - << "unless --show-object is given. Either of these options will cause the\n" - << "stream data to be written to standard output.\n" - << "\n" - << "If --filtered-stream-data is given and --normalize-content=y is also\n" - << "given, qpdf will attempt to normalize the stream data as if it is a\n" - << "page content stream. This attempt will be made even if it is not a\n" - << "page content stream, in which case it will produce unusable results.\n" - << "\n" - << "Ordinarily, qpdf exits with a status of 0 on success or a status of 2\n" - << "if any errors occurred. If there were warnings but not errors, qpdf\n" - << "exits with a status of 3. If warnings would have been issued but --no-warn\n" - << "was given, an exit status of 3 is still used. If you want qpdf to exit\n" - << "with status 0 when there are warnings, use the --warning-exit-0 flag.\n" - << "When --no-warn and --warning-exit-0 are used together, the effect is for\n" - << "qpdf to completely ignore warnings. qpdf does not use exit status 1,\n" - << "since that is used by the shell if it can't execute qpdf.\n"; -} -#endif - void ArgParser::argJsonHelp() { diff --git a/libqpdf/qpdf/auto_job_help.hh b/libqpdf/qpdf/auto_job_help.hh new file mode 100644 index 00000000..81e8325b --- /dev/null +++ b/libqpdf/qpdf/auto_job_help.hh @@ -0,0 +1,822 @@ +// +// This file is automatically generated by generate_auto_job. +// Edits will be automatically overwritten if the build is +// run in maintainer mode. +// +static void add_help_1(QPDFArgParser& ap) +{ +ap.addHelpTopic("usage", "basic invocation", R"(Read a PDF file, apply transformations or modifications, and write +a new PDF file. + +Usage: qpdf infile [options] [outfile] + OR qpdf help-option + +- infile, options, and outfile may be in any order as long as infile + precedes outfile. +- Use --empty in place of an input file for a zero-page, empty input +- Use --replace-input in place of an output file to overwrite the + input file with the output +- outfile may be - to write to stdout; reading from stdin is not supported +- @filename is an argument file; each line is treated as a separate + command-line argument +- @- may be used to read arguments from stdin +- Later options may override earlier options if contradictory +)"); +ap.addOptionHelp("--empty", "usage", "empty input file", R"(Use in place of infile for an empty input. Especially useful +with --pages. +)"); +ap.addOptionHelp("--replace-input", "usage", "replace input with output", R"(Use in place of outfile to overwrite the input file with the output. +)"); +ap.addHelpTopic("exit-status", "meanings of qpdf's exit codes", R"(Meaning of exit codes: + +0: no errors or warnings +1: not used by qpdf but may be used by the shell if unable to invoke qpdf +2: errors detected +3: warnings detected, unless --warning-exit-0 is given +)"); +ap.addOptionHelp("--warning-exit-0", "exit-status", "exit 0 even with warnings", R"(Use exit status 0 instead of 3 when warnings are present. When +combined with --no-warn, warnings are completely ignored. +)"); +ap.addHelpTopic("completion", "shell completion", R"(Shell completion is supported with bash and zsh. Use +eval $(qpdf --completion-bash) or eval $(qpdf --completion-zsh) +to enable. The QPDF_EXECUTABLE environment variable overrides the +path to qpdf that these commands output. +)"); +ap.addOptionHelp("--completion-bash", "completion", "enable bash completion", R"(Output a command that enables bash completion +)"); +ap.addOptionHelp("--completion-zsh", "completion", "enable zsh completion", R"(Output a command that enables zsh completion +)"); +ap.addHelpTopic("help", "information about qpdf", R"(Help options provide some information about qpdf itself. Help +options are only valid as the first and only command-line argument. +)"); +ap.addOptionHelp("--help", "help", "provide help", R"(Display help information. Run qpdf --help for information about +how to get help on various topics. +)"); +ap.addOptionHelp("--version", "help", "show qpdf version", R"(Display the version of qpdf. +)"); +ap.addOptionHelp("--copyright", "help", "show copyright information", R"(Display copyright and license information. +)"); +ap.addOptionHelp("--show-crypto", "help", "show available crypto providers", R"(Show a list of available crypto providers, one per line. The +default provider is shown first. +)"); +ap.addHelpTopic("general", "general options", R"(General options control qpdf's behavior in ways that are not +directly related to the operation it is performing. +)"); +ap.addOptionHelp("--password", "general", "specify password", R"(--password=password + +Specify a password for an encrypted, password-protected file. +Not needed for encrypted files with no password. +)"); +ap.addOptionHelp("--password-file", "general", "read password from a file", R"(--password-file=filename + +The first line of the specified file is used as the password. +This is used in place of the --password option. +)"); +ap.addOptionHelp("--verbose", "general", "print additional information", R"(Output additional information about various things qpdf is +doing, including information about files created and operations +performed. +)"); +ap.addOptionHelp("--progress", "general", "show progress when writing", R"(Indicate progress when writing files. +)"); +ap.addOptionHelp("--no-warn", "general", "suppress printing warning messages", R"(Suppress printing warning messages. If warnings were +encountered, qpdf still exits with exit status 3. +Use --warning-exit-0 with --no-warn to completely ignore +warnings. +)"); +} +static void add_help_2(QPDFArgParser& ap) +{ +ap.addOptionHelp("--deterministic-id", "general", "generate ID deterministically", R"(Generate a secure, random document ID only using static +information, such as the page contents. Does not use the file's +name or attributes or the current time. +)"); +ap.addOptionHelp("--allow-weak-crypto", "general", "allow insecure cryptographic algorithms", R"(All creation of files with weak cryptographic algorithms. This +option is necessary to create 40-bit files or 128-bit files that +use RC4 encryption. +)"); +ap.addOptionHelp("--keep-files-open", "general", "manage keeping multiple files open", R"(--keep-files-open=[yn] + +When qpdf needs to work with many files, as when merging large +numbers of files, explicitly indicate whether files should be +kept open. The default behavior is to determine this based on +the number of files. +)"); +ap.addOptionHelp("--keep-files-open-threshold", "general", "set threshold for --keep-files-open", R"(--keep-files-open-threshold=count + +Set the threshold used by --keep-files-open, overriding the +default value of 200. +)"); +ap.addHelpTopic("advanced-control", "tweak qpdf's behavior", R"(Advanced control options control qpdf's behavior in ways that would +normally never be needed by a user but that may be useful to +developers or people investigating problems with specific files. +)"); +ap.addOptionHelp("--password-is-hex-key", "advanced-control", "provide hex-encoded encryption key", R"(Provide the underlying file encryption key has a hex-encoded +string rather than supplying a password. This is an expert +option. +)"); +ap.addOptionHelp("--suppress-password-recovery", "advanced-control", "don't try different password encodings", R"(Suppress qpdf's behavior of attempting different encodings of a +password that contains non-ASCII Unicode characters if the first +attempt doesn't succeed. +)"); +ap.addOptionHelp("--password-mode", "advanced-control", "tweak how qpdf encodes passwords", R"(--password-mode={mode} + +Fine-tune how qpdf controls encoding of Unicode passwords. Valid +options are auto, bytes, hex-bytes, and unicode. +)"); +ap.addOptionHelp("--suppress-recovery", "advanced-control", "suppress error recovery", R"(Avoid attempting to recover when errors are found in a file's +cross reference table or stream lengths. +)"); +ap.addOptionHelp("--ignore-xref-streams", "advanced-control", "use xref tables rather than streams", R"(Ignore any cross-reference streams in the file, falling back to +cross-reference tables or triggering document recovery. +)"); +ap.addHelpTopic("transformation", "make structural PDF changes", R"(The options below tell qpdf to apply transformations that change +the structure without changing the content. +)"); +ap.addOptionHelp("--linearize", "transformation", "linearize (web-optimize) output", R"(Create linearized (web-optimized) output files. +)"); +ap.addOptionHelp("--encrypt", "transformation", "start encryption options", R"(--encrypt user owner key-length [ options ] -- + +Run qpdf --help=encryption for details. +)"); +ap.addOptionHelp("--decrypt", "transformation", "remove encryption from input file", R"(Create an unencrypted output file even if the input file was +encrypted. Normally qpdf preserves whatever encryption was +present on the input file. This option overrides that behavior. +)"); +ap.addOptionHelp("--copy-encryption", "transformation", "copy another file's encryption details", R"(--copy-encryption=file + +Copy encryption details from the specified file instead of +preserving the input file's encryption. Use --encryption-file-password +to specify the encryption file's password. +)"); +ap.addOptionHelp("--encryption-file-password", "transformation", "supply password for --copy-encryption", R"(--encryption-file-password=password + +If the file named in --copy-encryption requires a password, use +this option to specify the password. +)"); +ap.addOptionHelp("--qdf", "transformation", "enable viewing PDF code in a text editor", R"(Create a PDF file suitable for viewing in a text editor and even +editing. This is to edit the PDF code, not the page contents. +All streams that can be uncompressed are uncompressed, and +content streams are normalized, among other changes. The +companion tool "fix-qdf" can be used to repair hand-edited QDF +files. QDF is a feature specific to the qpdf tool. There is a +chapter about it in the manual. +)"); +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 +had in the original file. +)"); +ap.addOptionHelp("--compress-streams", "transformation", "compress uncompressed streams", R"(--compress-streams=[yn] + +Setting --compress-streams=n prevents qpdf from compressing +uncompressed streams. This can be useful if you are leaving some +streams uncompressed intentionally. +)"); +} +static void add_help_3(QPDFArgParser& ap) +{ +ap.addOptionHelp("--decode-level", "transformation", "control which streams to uncompress", R"(--decode-level=option + +When uncompressing streams, control which types of compression +schemes should be uncompressed: +- none: don't uncompress anything +- generalized: uncompress streams compressed with a + general-purpose compression algorithm. This is the default. +- specialized: in addition to generalized, also uncompress + streams compressed with a special-purpose but non-lossy + compression scheme +- all: in addition to specialized, uncompress streams compressed + with lossy compression schemes like JPEG (DCT) +qpdf does not know how to uncompress all compression schemes. +)"); +ap.addOptionHelp("--stream-data", "transformation", "control stream compression", R"(--stream-data=option + +This option controls how streams are compressed in the output. +It is less granular than the newer options, --compress-streams +and --decode-level. + +Options: +- compress: same as --compress-streams=y --decode-level=generalized +- preserve: same as --compress-streams=n --decode-level=none +- uncompress: same as --compress-streams=n --decode-level=generalized +)"); +ap.addOptionHelp("--recompress-flate", "transformation", "uncompress and recompress flate", R"(The default generalized compression scheme used by PDF is flate, +which is the same as used by zip and gzip. Usually qpdf just +leaves these alone. This option tells qpdf to uncompress and +recompress streams compressed with flate. This can be useful +when combined with --compression-level. +)"); +ap.addOptionHelp("--compression-level", "transformation", "set compression level for flate", R"(--compression-level=level + +Set a compression level from 1 (least, fastest) to 9 (most, +slowest) when compressing files with flate (used in zip and +gzip), which is the default compression for most PDF files. +You need --recompress-flate with this option if you want to +change already compressed streams. +)"); +ap.addOptionHelp("--normalize-content", "transformation", "fix newlines in content streams", R"(--normalize-content=[yn] + +Normalize newlines to UNIX-style newlines in PDF content +streams, which is useful for viewing them in a programmer's text +editor across multiple platforms. This is also turned on by +--qdf. +)"); +ap.addOptionHelp("--object-streams", "transformation", "control use of object streams", R"(--object-streams=mode + +Control what qpdf does regarding object streams. Options: +- preserve: preserve original object streams, if any (the default) +- disable: create output files with no object streams +- generate: create object streams, and compress objects when possible +)"); +ap.addOptionHelp("--preserve-unreferenced", "transformation", "preserve unreferenced objects", R"(Preserve all objects from the input even if not referenced. +)"); +ap.addOptionHelp("--remove-unreferenced-resources", "transformation", "remove unreferenced page resources", R"(--remove-unreferenced-resources=option + +Remove from a page's resource dictionary any resources that are +not referenced in the page's contents. Options: "auto" +(default), "yes", "no". +)"); +ap.addOptionHelp("--preserve-unreferenced-resources", "transformation", "use --remove-unreferenced-resources=no", R"(Synonym for --remove-unreferenced-resources=no. Use that instead. +)"); +ap.addOptionHelp("--newline-before-endstream", "transformation", "force a newline before endstream", R"(For an extra newline before endstream. Using this option enables +qpdf to preserve PDF/A when rewriting such files. +)"); +ap.addOptionHelp("--coalesce-contents", "transformation", "combine content streams", R"(If a page has an array of content streams, concatenate them into +a single content stream. +)"); +ap.addOptionHelp("--externalize-inline-images", "transformation", "convert inline to regular images", R"(Convert inline images to regular images. +)"); +ap.addOptionHelp("--ii-min-bytes", "transformation", "set minimum size for --externalize-inline-images", R"(--ii-min-bytes=size-in-bytes + +Don't externalize inline images smaller than this size. The +default is 1,024. Use 0 for no minimum. +)"); +ap.addOptionHelp("--min-version", "transformation", "set minimum PDF version", R"(--min-version=version + +Force the PDF version of the output to be at least the +specified version. +)"); +ap.addOptionHelp("--force-version", "transformation", "set output PDF version", R"(--force-version=version + +Force the output PDF file's PDF version header to be the specified +value, even if the file uses features that may not be available +in that version. +)"); +ap.addHelpTopic("page-ranges", "page range syntax", R"(A full description of the page range syntax, with examples, can be +found in the manual. Summary: + +- a,b,c pages a, b, and c +- a-b pages a through b inclusive; if a > b, this counts down +- r where represents a number is the th page from the end +- z the last page, same as r1 + +You can append :even or :odd to select every other page from the +resulting set of pages, where :odd starts with the first page and +:even starts with the second page. These are odd and even pages +from the resulting set, not based on the original page numbers. +)"); +ap.addHelpTopic("modification", "change parts of the PDF", R"(Modification options make systematic changes to certain parts of +the PDF, causing the PDF to render differently from the original. +)"); +ap.addOptionHelp("--pages", "modification", "begin page selection", R"(--pages file [ --password=password ] [ page-range ] [ ... ] -- + +Run qpdf --help=page-selection for details. +)"); +ap.addOptionHelp("--collate", "modification", "collate with --pages", R"(--collate=n + +Collate rather than concatenate pages specified with --pages. +With a numeric argument, collate in groups of n. The default +is 1. Run qpdf --help=page-selection for additional details. +)"); +} +static void add_help_4(QPDFArgParser& ap) +{ +ap.addOptionHelp("--split-pages", "modification", "write pages to separate files", R"(--split-pages=[n] + +This option causes qpdf to create separate output files for each +page or group of pages rather than a single output file. + +File names are generated from the specified output file as follows: + +- If the string %d appears in the output file name, it is replaced with a + zero-padded page range starting from 1 +- Otherwise, if the output file name ends in .pdf (case insensitive), a + zero-padded page range, preceded by a dash, is inserted before the file + extension +- Otherwise, the file name is appended with a zero-padded page range + preceded by a dash. + +Page ranges are single page numbers for single-page groups or first-last +for multi-page groups. +)"); +ap.addOptionHelp("--overlay", "modification", "begin overlay options", R"(--overlay file [ options ] -- + +Overlay pages from another file on the output. +Run qpdf --help=overlay-underlay for details. +)"); +ap.addOptionHelp("--underlay", "modification", "begin underlay options", R"(--underlay file [ options ] -- + +Underlay pages from another file on the output. +Run qpdf --help=overlay-underlay for details. +)"); +ap.addOptionHelp("--flatten-rotation", "modification", "remove rotation from page dictionary", R"(Rotate a page using content commands instead of page-level +metadata. This can be useful if a broken PDF viewer fails to +properly consider page rotation metadata. +)"); +ap.addOptionHelp("--flatten-annotations", "modification", "push annotations into content", R"(--flatten-annotations=option + +Push page annotations into the content streams. This may be +necessary in some case when printing or splitting files. +Options: "all", "print", "screen". +)"); +ap.addOptionHelp("--rotate", "modification", "rotate pages", R"(--rotate=[+|-]angle[:page-range] + +Rotate specified pages by multiples of 90 degrees specifying +either absolute or relative angles. "angle" may be 0, 90, 180, +or 270. You almost always want to use +angle or -angle rather +than just angle, as discussed in the manual. Run +qpdf --help=page-ranges for help with page ranges. +)"); +ap.addOptionHelp("--generate-appearances", "modification", "generate appearances for form fields", R"(PDF form fields consist of values and appearances, which may be +inconsistent with each other if a form field value has been +modified without updating its appearance. This option tells qpdf +to generate new appearance streams. There are some limitations, +which are discussed in the manual. +)"); +ap.addOptionHelp("--optimize-images", "modification", "use efficient compression for images", R"(Attempt to use DCT (JPEG) compression for images that fall +within certain constraints as long as doing so decreases the +size in bytes of the image. See also help for the following +options: + --oi-min-width + --oi-min-height + --oi-min-area + --keep-inline-images + +The --verbose flag is useful with this option. +)"); +ap.addOptionHelp("--oi-min-width", "modification", "minimum width for --optimize-images", R"(--oi-min-width=width + +Don't optimize images whose width is below the specified value. +)"); +ap.addOptionHelp("--oi-min-height", "modification", "minimum height for --optimize-images", R"(--oi-min-height=height + +Don't optimize images whose height is below the specified value. +)"); +ap.addOptionHelp("--oi-min-area", "modification", "minimum area for --optimize-images", R"(--oi-min-area=area-in-pixels + +Don't optimize images whose area in pixels is below the specified value. +)"); +ap.addOptionHelp("--keep-inline-images", "modification", "exclude inline images from optimization", R"(Prevent inline images from being considered by --optimize-images. +)"); +ap.addOptionHelp("--remove-page-labels", "modification", "remove page labels (numbers)", R"(Exclude page labels (explicit page numbers) from the output file. +)"); +ap.addHelpTopic("encryption", "create encrypted files", R"(Create encrypted files. Usage: + +--encrypt user-password owner-password key-length [ options ] -- + +Either or both of user-password and owner-password may be empty +strings. key-length may be 40, 128, or 256. Encryption options are +terminated by "--" by itself. + +40-bit encryption is insecure, as is 128-bit encryption without +AES. Use 256-bit encryption unless you have a specific reason to +use an insecure format, such as testing or compatibility with very +old viewers. You must use the --allow-weak-crypto to create +encrypted files that use insecure cryptographic algorithms. The +--allow-weak-crypto flag appears outside of --encrypt ... -- +(before --encrypt or after --). + +Available options vary by key length. Not all readers respect all +restrictions. Different PDF readers respond differently to various +combinations of options. Sometimes a PDF viewer may show you +restrictions that differ from what you selected. This is probably +not a bug in qpdf. + +Options for 40-bit only: + --annotate=[yn] restrict comments, filling forms, and signing + --extract=[yn] restrict text/graphic extraction + --modify=[yn] restrict document modification + --print=[yn] restrict printing + +Options for 128-bit or 256-bit: + --accessibility=[yn] restrict accessibility (usually ignored) + --annotate=[yn] restrict commenting/filling form fields + --assemble=[yn] restrict document assembly + --extract=[yn] restrict text/graphic extraction + --form=[yn] restrict filling form fields + --modify-other=[yn] restrict other modifications + --modify=modify-opt control modify access by level + --print=print-opt control printing access + --cleartext-metadata prevent encryption of metadata + +For 128-bit only: + --use-aes=[yn] indicates whether to use AES encryption + --force-V4 forces use of V=4 encryption handler + +For 256-bit only: + --force-R5 forces use of deprecated R=5 encryption + --allow-insecure allow user password with empty owner password + +Values for print-opt: + none disallow printing + low allow only low-resolution printing + full allow full printing + +Values for modify-opt: + none allow no modifications + assembly allow document assembly only + form assembly + filling in form fields and signing + annotate form + commenting and modifying forms + all allow full document modification +)"); +ap.addOptionHelp("--accessibility", "encryption", "restrict document accessibility", R"(--accessibility=[yn] + +This option is ignored except with very old encryption formats. +The current PDF specification does not allow restriction of +document accessibility. This option is not available with 40-bit +encryption. +)"); +ap.addOptionHelp("--annotate", "encryption", "restrict document annotation", R"(--annotate=[yn] + +Enable/disable modifying annotations including making comments +and filling in form fields. For 128-bit and 256-bit encryption, +this also enables editing, creating, and deleting form fields +unless --modify-other=n or --modify=none is also specified. +)"); +ap.addOptionHelp("--assemble", "encryption", "restrict document assembly", R"(--assemble=[yn] + +Enable/disable document assembly (rotation and reordering of +pages). This option is not available with 40-bit encryption. +)"); +ap.addOptionHelp("--extract", "encryption", "restrict text/graphic extraction", R"(--extract=[yn] + +Enable/disable text/graphic extraction for purposes other than +accessibility. +)"); +ap.addOptionHelp("--form", "encryption", "restrict form filling", R"(--form=[yn] + +Enable/disable whether filling form fields is allowed even if +modification of annotations is disabled. This option is not +available with 40-bit encryption. +)"); +} +static void add_help_5(QPDFArgParser& ap) +{ +ap.addOptionHelp("--modify-other", "encryption", "restrict other modifications", R"(--modify-other=[yn] + +Enable/disable modifications not controlled by --assemble, +--annotate, or --form. --modify-other=n is implied by any of the +other --modify options. This option is not available with 40-bit +encryption. +)"); +ap.addOptionHelp("--modify", "encryption", "restrict document modification", R"(--modify=modify-opt + +For 40-bit files, modify-opt may only be y or n and controls all +aspects of document modification. + +For 128-bit and 256-bit encryption, modify-opt values allow +enabling and disabling levels of restriction in a manner similar +to how some PDF creation tools do it. modify-opt values map to +other combinations of options as follows: + +all: allow full modification (the default) +annotate: --modify-other=n +form: --modify-other=n --annotate=n +assembly: --modify-other=n --annotate=n --form=n +none: --modify-other=n --annotate=n --form=n --assemble=n +)"); +ap.addOptionHelp("--print", "encryption", "restrict printing", R"(--print=print-opt + +Control what kind of printing is allowed. For 40-bit encryption, +print-opt may only be y or n and enables or disables all +printing. For 128-bit and 256-bit encryption, print-opt may have +the following values: + +none: disallow printing +low: allow low-resolution printing only +full: allow full printing (the default) +)"); +ap.addOptionHelp("--cleartext-metadata", "encryption", "don't encrypt metadata", R"(If specified, don't encrypt document metadata even when +encrypting the rest of the document. This option is not +available with 40-bit encryption. +)"); +ap.addOptionHelp("--use-aes", "encryption", "use AES with 128-bit encryption", R"(--use-aes=[yn] + +Enables/disables use of the more secure AES encryption with +128-bit encryption. Specifying --use-aes=y forces the PDF +version to be at least 1.6. This option is only available with +128-bit encryption. The default is "n" for compatibility +reasons. Use 256-bit encryption instead. +)"); +ap.addOptionHelp("--allow-insecure", "encryption", "allow empty owner passwords", R"(Allow creation of PDF files with empty owner passwords and +non-empty user passwords when using 256-bit encryption. +)"); +ap.addOptionHelp("--force-V4", "encryption", "force V=4 in encryption dictionary", R"(This option is for testing and is never needed in practice since +qpdf does this automatically when needed. +)"); +ap.addOptionHelp("--force-R5", "encryption", "use unsupported R=5 encryption", R"(Use an undocumented, unsupported, deprecated encryption +algorithm that existed only in Acrobat version IX. This option +should not be used except for compatibility testing. +)"); +ap.addHelpTopic("page-selection", "select pages from one or more files", R"(Use the --pages option to select pages from multiple files. Usage: + +qpdf in.pdf --pages input-file [ --password=password ] [ page-range ] \ + [ ... ] -- out.pdf + +Between --pages and the -- that terminates pages option, repeat +the following: + +filename [ --password=password ] [ page-range ] + +Document-level information, such as outlines, tags, etc., is taken +from in.pdf is preserved in out.pdf. You can use --empty in place +of an input file to start from an empty file and just copy pages +equally from all files. You can use "." as a shorthand for the +primary input file (if not --empty). In the above example, "." +would refer to in.pdf. + +Use --password=password to specify the password for a +password-protected input file. If the same input file is used more +than once, you only need to supply the password the first time. If +the page range is omitted, all pages are selected. + +Run qpdf --help=page-ranges for help with page ranges. + +Use --collate=n to cause pages to be collated in groups of n pages +(default 1) instead of concatenating the input. + +Examples: + +- Start with in.pdf and append all pages from a.pdf and the even + pages from b.pdf, and write the output to out.pdf. Document-level + information from in.pdf is retained. Note the use of "." to refer + to in.pdf. + + qpdf in.pdf --pages . a.pdf b.pdf:even -- out.pdf + +- Take all the pages from a.pdf, all the pages from b.pdf in + reverse, and only pages 3 and 6 from c.pdf and write the result + to out.pdf. Use password "x" to open b.pdf: + + qpdf --empty --pages a.pdf b.pdf --password=x z-1 c.pdf 3,6 + +More examples are in the manual. +)"); +ap.addHelpTopic("overlay-underlay", "overlay/underlay pages from other files", R"(These options allow pages from another file to be overlaid or +underlaid on the primary output. Overlaid pages are drawn on top of +the destination page and may obscure the page. Underlaid pages are +drawn below the destination page. Usage: + +{--overlay | --underlay } file + [ --password=password ] + [ --to=page-range ] + [ --from=[page-range] ] + [ --repeat=page-range ] + -- + +Note the use of "--" by itself to terminate overlay/underlay options. + +For overlay and underlay, a file and optional password are specified, along +with a series of optional page ranges. The default behavior is that each +page of the overlay or underlay file is imposed on the corresponding page +of the primary output until it runs out of pages, and any extra pages are +ignored. You can also give a page range with --repeat to cause +those pages to be repeated after the original pages are exhausted. + +Run qpdf --help=page-ranges for help with page ranges. +)"); +ap.addOptionHelp("--to", "overlay-underlay", "destination pages for underlay/overlay", R"(--to=page-range + +Specify the range of pages in the primary output to apply +overlay/underlay to. See qpdf --help=page-ranges for help with +the page range syntax. +)"); +ap.addOptionHelp("--from", "overlay-underlay", "source pages for underlay/overlay", R"(--from=[page-range] + +Specify pages from the overlay/underlay file that are applied to +the destination pages. See qpdf --help=page-ranges for help +with the page range syntax. The page range may be omitted +if --repeat is used. +)"); +ap.addOptionHelp("--repeat", "overlay-underlay", "overlay/underlay pages to repeat", R"(--repeat=page-range + +Specify pages from the overlay/underlay that are repeated after +"from" pages have been exhausted. See qpdf --help=page-ranges +for help with the page range syntax. +)"); +ap.addHelpTopic("attachments", "work with embedded files", R"(It is possible to list, add, or delete embedded files (also known +as attachments) and to copy attachments from other files. See help +on individual options for details. Run qpdf --help=add-attachment +for additional details about adding attachments. +)"); +ap.addOptionHelp("--list-attachments", "attachments", "list embedded files", R"(Show the key and stream number for each embedded file. Combine +with --verbose for more detailed information. +)"); +ap.addOptionHelp("--show-attachment", "attachments", "export an embedded file", R"(--show-attachment=key + +Write the contents of the specified attachment to standard +output as binary data. Get the key with --list-attachments. +)"); +ap.addOptionHelp("--add-attachment", "attachments", "start add attachment options", R"(--add-attachment file options -- + +The --add-attachment flag and its options may be repeated to add +multiple attachments. Run qpdf --help=add-attachment for details. +)"); +ap.addOptionHelp("--remove-attachment", "attachments", "remove an embedded file", R"(--remove-attachment=key + +Remove an embedded file using its key. Get the key with +--list-attachments. +)"); +ap.addOptionHelp("--copy-attachments-from", "attachments", "start copy attachment options", R"(--copy-attachments-from file options -- + +The --copy-attachments-from flag and its options may be repeated +to copy attachments from multiple files. Run +qpdf --help=copy-attachments for details. +)"); +} +static void add_help_6(QPDFArgParser& ap) +{ +ap.addHelpTopic("pdf-dates", "PDF date format", R"(When a date is required, the date should conform to the PDF date +format specification, which is "D:yyyymmddhhmmssz" where "z" is +either literally upper case "Z" for UTC or a timezone offset in +the form "-hh'mm'" or "+hh'mm'". Negative timezone offsets indicate +time before UTC. Positive offsets indicate how far after. For +example, US Eastern Standard Time (America/New_York) is "-05'00'", +and Indian Standard Time (Asia/Calcutta) is "+05'30'". + +Examples: +- D:20210207161528-05'00' February 7, 2021 at 4:15:28 p.m. +- D:20210207211528Z February 7, 2021 at 21:15:28 UTC +)"); +ap.addHelpTopic("add-attachment", "attach (embed) files", R"(The options listed below appear between --add-attachment and its +terminating "--". +)"); +ap.addOptionHelp("--key", "add-attachment", "specify attachment key", R"(--key=key + +Specify the key to use for the attachment in the embedded files +table. It defaults to the last element of the attached file's +filename. +)"); +ap.addOptionHelp("--filename", "add-attachment", "set attachment's displayed filename", R"(--filename=name + +Specify the filename to be used for the attachment. This is what +is usually displayed to the user and is the name most graphical +PDF viewers will use when saving a file. It defaults to the last +element of the attached file's filename. +)"); +ap.addOptionHelp("--creationdate", "add-attachment", "set attachment's creation date", R"(--creationdate=date + +Specify the attachment's creation date in PDF format; defaults +to the current time. Run qpdf --help=pdf-dates for information +about the date format. +)"); +ap.addOptionHelp("--moddate", "add-attachment", "set attachment's modification date", R"(--moddate=date + +Specify the attachment's modification date in PDF format; +defaults to the current time. Run qpdf --help=pdf-dates for +information about the date format. +)"); +ap.addOptionHelp("--mimetype", "add-attachment", "attachment mime type (e.g. application/pdf)", R"(--mimetype=type/subtype + +Specify the mime type for the attachment, such as text/plain, +application/pdf, image/png, etc. +)"); +ap.addOptionHelp("--description", "add-attachment", "set attachment's description", R"(--description="text" + +Supply descriptive text for the attachment, displayed by some +PDF viewers. +)"); +ap.addOptionHelp("--replace", "add-attachment", "replace attachment with same key", R"(Indicate that any existing attachment with the same key should +be replaced by the new attachment. Otherwise, qpdf gives an +error if an attachment with that key is already present. +)"); +ap.addHelpTopic("copy-attachments", "copy attachments from another file", R"(The options listed below appear between --copy-attachments-from and +its terminating "--". + +To copy attachments from a password-protected file, use +the --password option after the file name. +)"); +ap.addOptionHelp("--prefix", "copy-attachments", "key prefix for copying attachments", R"(--prefix=prefix + +Prepend a prefix to each key; may be needed if there are +duplicate attachment keys. This affects the key only, not the +file name. +)"); +ap.addOptionHelp("--is-encrypted", "copy-attachments", "silently test whether a file is encrypted", R"(Silently exit with a code indicating the file's encryption status: + +0: the file is encrypted +1: not used +2: the file is not encrypted + +This can be used with password-protected files even if you don't +know the password. +)"); +ap.addOptionHelp("--requires-password", "copy-attachments", "silently test a file's password", R"(Silently exit with a code indicating the file's password status: + +0: a password, other than as supplied, is required +1: not used +2: the file is not encrypted +3: the file is encrypted, and correct password (if any) has been supplied +)"); +ap.addOptionHelp("--check", "copy-attachments", "partially check whether PDF is valid", R"(Check the structure of the PDF file as well as a number of other +aspects of the file, and write information about the file to +standard output. Note that qpdf does not perform any validation +of the actual PDF page content or semantic correctness of the +PDF file. It merely checks that the PDF file is syntactically +valid. +)"); +ap.addOptionHelp("--show-encryption", "copy-attachments", "information about encrypted files", R"(Show document encryption parameters. Also show the document's +user password if the owner password is given and the file was +encrypted using older encryption formats that allow user +password recovery. +)"); +ap.addOptionHelp("--show-encryption-key", "copy-attachments", "show key with --show-encryption", R"(When used with --show-encryption, causes the underlying +encryption key to be displayed. +)"); +ap.addOptionHelp("--check-linearization", "copy-attachments", "check linearization tables", R"(Check to see whether a file is linearized and, if so, whether +the linearization hint tables are correct. +)"); +ap.addOptionHelp("--show-linearization", "copy-attachments", "show linearization hint tables", R"(Check and display all data in the linearization hint tables. +)"); +ap.addOptionHelp("--show-xref", "copy-attachments", "show cross reference data", R"(Show the contents of the cross-reference table or stream (object +locations in the file) in a human-readable form. This is +especially useful for files with cross-reference streams, which +are stored in a binary format. +)"); +} +static void add_help_7(QPDFArgParser& ap) +{ +ap.addOptionHelp("--show-object", "copy-attachments", "show contents of an object", R"(--show-object=trailer|obj[,gen] + +Show the contents of the given object. This is especially useful +for inspecting objects that are inside of object streams (also +known as "compressed objects"). +)"); +ap.addOptionHelp("--raw-stream-data", "copy-attachments", "show raw stream data", R"(When used with --show-object, if the object is a stream, write +the raw (compressed) binary stream data to standard output +instead of the object's contents. See also +--filtered-stream-data. +)"); +ap.addOptionHelp("--filtered-stream-data", "copy-attachments", "show filtered stream data", R"(When used with --show-object, if the object is a stream, write +the filtered (uncompressed, potentially binary) stream data to +standard output instead of the object's contents. See also +--raw-stream-data. +)"); +ap.addOptionHelp("--show-npages", "copy-attachments", "show number of pages", R"(Print the number of pages in the input file on a line by itself. +Useful for scripts. +)"); +ap.addOptionHelp("--show-pages", "copy-attachments", "display page dictionary information", R"(Show the object and generation number for each page dictionary +object and for each content stream associated with the page. +)"); +ap.addOptionHelp("--with-images", "copy-attachments", "include image details with --show-pages", R"(When used with --show-pages, also shows the object and +generation numbers for the image objects on each page. +)"); +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. +)"); +ap.addOptionHelp("--json", "json", "show file in json format", R"(Generate a JSON representation of the file. This is described in +depth in the JSON section of the manual. +)"); +ap.addOptionHelp("--json-help", "json", "show format of json output", R"(Describe the format of the JSON output. +)"); +ap.addOptionHelp("--json-key", "json", "restrict which keys are in json output", R"(--json-key=key + +This option is repeatable. If given, only the specified +top-level keys will be included in the JSON output. Otherwise, +all keys will be included. +)"); +ap.addOptionHelp("--json-object", "json", "restrict which objects are in JSON", R"(--json-object=trailer|obj[,gen] + +This option is repeatable. If given, only specified objects will +be shown in the "objects" key of the JSON output. Otherwise, all +objects will be shown. +)"); +ap.addHelpTopic("testing", "options for testing or debugging", R"(The options below are useful when writing automated test code that +includes files created by qpdf or when testing qpdf itself. +)"); +ap.addOptionHelp("--static-id", "testing", "use a fixed document ID", R"(Use a fixed value for the document ID. This is intended for +testing only. Never use it for production files. See also +qpdf --help=--deterministic-id. +)"); +ap.addOptionHelp("--static-aes-iv", "testing", "use a fixed AES vector", R"(Use a static initialization vector for AES-CBC. This is intended +for testing only so that output files can be reproducible. Never +use it for production files. This option is not secure since it +significantly weakens the encryption. +)"); +ap.addOptionHelp("--linearize-pass1", "testing", "save pass 1 of linearization", R"(--linearize-pass1=file + +Write the first pass of linearization to the named file. The +resulting file is not a valid PDF file. This option is useful only +for debugging qpdf. +)"); +} +static void add_help(QPDFArgParser& ap) +{ + add_help_1(ap); + add_help_2(ap); + add_help_3(ap); + add_help_4(ap); + add_help_5(ap); + add_help_6(ap); + add_help_7(ap); +ap.addHelpFooter("For detailed help, visit the qpdf manual: https://qpdf.readthedocs.io\n"); +} + diff --git a/libqpdf/qpdf/auto_job_init.hh b/libqpdf/qpdf/auto_job_init.hh index b19b2cc9..3d7cdd7b 100644 --- a/libqpdf/qpdf/auto_job_init.hh +++ b/libqpdf/qpdf/auto_job_init.hh @@ -162,4 +162,3 @@ this->ap.copyFromOtherTable("annotate", "128-bit encryption"); this->ap.copyFromOtherTable("form", "128-bit encryption"); this->ap.copyFromOtherTable("modify-other", "128-bit encryption"); this->ap.copyFromOtherTable("modify", "128-bit encryption"); -this->ap.addHelpFooter("For detailed help, visit the qpdf manual: https://qpdf.readthedocs.io\n"); -- cgit v1.2.3-70-g09d2