diff options
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/QUtil.cc | 18 | ||||
-rw-r--r-- | libqpdf/qpdf/auto_job_help.hh | 19 |
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 |