aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDFJob_config.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2024-01-05 22:11:09 +0100
committerJay Berkenbilt <ejb@ql.org>2024-01-05 23:12:12 +0100
commit7cac433e2d9256fb8361aa53d136d4eaacfda6fe (patch)
tree91e18e06655d5d83dd745032641cdd7406785ced /libqpdf/QPDFJob_config.cc
parent543038c52a3e0dc166565142ed7efb183e461948 (diff)
downloadqpdf-7cac433e2d9256fb8361aa53d136d4eaacfda6fe.tar.zst
Implement --set-page-labels and supporting API (fixes #939)
Diffstat (limited to 'libqpdf/QPDFJob_config.cc')
-rw-r--r--libqpdf/QPDFJob_config.cc49
1 files changed, 45 insertions, 4 deletions
diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc
index 9651c3b9..e48d7e31 100644
--- a/libqpdf/QPDFJob_config.cc
+++ b/libqpdf/QPDFJob_config.cc
@@ -1,5 +1,7 @@
#include <qpdf/QPDFJob.hh>
+#include <regex>
+
#include <qpdf/QPDFLogger.hh>
#include <qpdf/QTC.hh>
#include <qpdf/QUtil.hh>
@@ -1062,11 +1064,50 @@ QPDFJob::Config::encrypt(
QPDFJob::Config*
QPDFJob::Config::setPageLabels(const std::vector<std::string>& specs)
{
- // XXX validate
- for (auto const& xxx: specs) {
- std::cout << "XXX config: spec: " << xxx << std::endl;
+ static std::regex page_label_re(R"(^(z|r?\d+):([DaArR])?(?:/(\d+)?(?:/(.+)?)?)?$)");
+ o.m->page_label_specs.clear();
+ for (auto const& spec: specs) {
+ std::smatch match;
+ if (!std::regex_match(spec, match, page_label_re)) {
+ usage("page label spec must be n:[D|a|A|r|R][/start[/prefix]]");
+ }
+ auto first_page_str = match[1].str();
+ int first_page;
+ if (first_page_str == "z") {
+ first_page = -1;
+ } else if (first_page_str.at(0) == 'r') {
+ first_page = -QUtil::string_to_int(first_page_str.substr(1).c_str());
+ } else {
+ first_page = QUtil::string_to_int(first_page_str.c_str());
+ }
+ auto label_type_ch = match[2].matched ? match[2].str().at(0) : '\0';
+ qpdf_page_label_e label_type;
+ switch (label_type_ch) {
+ case 'D':
+ label_type = pl_digits;
+ break;
+ case 'a':
+ label_type = pl_alpha_lower;
+ break;
+ case 'A':
+ label_type = pl_alpha_upper;
+ break;
+ case 'r':
+ label_type = pl_roman_lower;
+ break;
+ case 'R':
+ label_type = pl_roman_upper;
+ break;
+ default:
+ label_type = pl_none;
+ }
+
+ auto start_num = match[3].matched ? QUtil::string_to_int(match[3].str().c_str()) : 1;
+ auto prefix = match[4].matched ? match[4].str() : "";
+ // We can't check ordering until we know how many pages there are, so that is delayed until
+ // near the end.
+ o.m->page_label_specs.emplace_back(first_page, label_type, start_num, prefix);
}
- o.m->page_label_specs = specs;
return this;
}