aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/QUtil.cc18
-rw-r--r--libqpdf/qpdf/auto_job_help.hh19
2 files changed, 29 insertions, 8 deletions
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index 5e88ff88..c0aca105 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -1303,6 +1303,10 @@ QUtil::str_compare_nocase(char const* s1, char const* s2)
std::vector<int>
QUtil::parse_numrange(char const* range, int max)
{
+ // Performance note: this implementation aims to be straightforward, not efficient. Numeric
+ // range parsing is used only during argument processing. It is not used during processing of
+ // PDF files.
+
static std::regex group_re(R"((x)?(z|r?\d+)(?:-(z|r?\d+))?)");
auto parse_num = [&max](std::string const& s) -> int {
if (s == "z") {
@@ -1375,12 +1379,22 @@ QUtil::parse_numrange(char const* range, int max)
first = false;
auto first_num = parse_num(m[2].str());
auto is_span = m[3].matched;
- int last_num;
+ int last_num{0};
if (is_span) {
last_num = parse_num(m[3].str());
}
if (is_exclude) {
- // XXX
+ std::vector<int> work;
+ populate(work, first_num, is_span, last_num);
+ std::set<int> exclusions;
+ exclusions.insert(work.begin(), work.end());
+ work = last_group;
+ last_group.clear();
+ for (auto n: work) {
+ if (exclusions.count(n) == 0) {
+ last_group.emplace_back(n);
+ }
+ }
} else {
result.insert(result.end(), last_group.begin(), last_group.end());
populate(last_group, first_num, is_span, last_num);
diff --git a/libqpdf/qpdf/auto_job_help.hh b/libqpdf/qpdf/auto_job_help.hh
index da6520c5..4ee0f56e 100644
--- a/libqpdf/qpdf/auto_job_help.hh
+++ b/libqpdf/qpdf/auto_job_help.hh
@@ -286,12 +286,19 @@ 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<n> where <n> represents a number is the <n>th page from the end
-- z the last page, same as r1
+found in the manual. In summary, a range is a comma-separated list
+of groups. A group is a number or a range of numbers separated by a
+dash. A group may be prepended by x to exclude its members from the
+previous group. A number may be one of
+
+- <n> where <n> represents a number is the <n>th page
+- r<n> is the <n>th page from the end
+- z the last page, same as r1
+
+- a,b,c pages a, b, and c
+- a-b pages a through b inclusive; if a > b, this counts down
+- a-b,xc pages a through b except page c
+- a-b,xc-d pages a through b except pages c through d
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