summaryrefslogtreecommitdiff
path: root/dviware/dvisvgm/src/PageRanges.cpp
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-01-12 03:01:29 +0000
committerNorbert Preining <norbert@preining.info>2023-01-12 03:01:29 +0000
commit6a7900c93acc16d1bbd2f1e26286c7dd7387e6c0 (patch)
tree76196287351cba68a51934c49468bf1a7846aa76 /dviware/dvisvgm/src/PageRanges.cpp
parentc1c19023b4b1d43cb874f84df5102b485853e672 (diff)
CTAN sync 202301120301
Diffstat (limited to 'dviware/dvisvgm/src/PageRanges.cpp')
-rw-r--r--dviware/dvisvgm/src/PageRanges.cpp48
1 files changed, 41 insertions, 7 deletions
diff --git a/dviware/dvisvgm/src/PageRanges.cpp b/dviware/dvisvgm/src/PageRanges.cpp
index 4af8ff2bc4..e80aa4839b 100644
--- a/dviware/dvisvgm/src/PageRanges.cpp
+++ b/dviware/dvisvgm/src/PageRanges.cpp
@@ -2,7 +2,7 @@
** PageRanges.cpp **
** **
** This file is part of dvisvgm -- a fast DVI to SVG converter **
-** Copyright (C) 2005-2022 Martin Gieseking <martin.gieseking@uos.de> **
+** Copyright (C) 2005-2023 Martin Gieseking <martin.gieseking@uos.de> **
** **
** This program is free software; you can redistribute it and/or **
** modify it under the terms of the GNU General Public License as **
@@ -24,6 +24,11 @@
using namespace std;
+using FilterFunc = bool (*)(int);
+
+static bool is_even (int n) {return n % 2 == 0;}
+static bool is_odd (int n) {return n % 2 == 1;}
+
/** Analyzes a string describing a range sequence.
* Syntax: ([0-9]+(-[0-9]*)?)|(-[0-9]+)(,([0-9]+(-[0-9]*)?)|(-[0-9]+))*
@@ -33,32 +38,31 @@ using namespace std;
bool PageRanges::parse (const string &str, int max_page) {
StringInputBuffer ib(str);
BufferInputReader ir(ib);
- while (ir) {
+ while (ir && ir.peek() != ':') {
int first=1;
int last=max_page;
ir.skipSpace();
if (!isdigit(ir.peek()) && ir.peek() != '-')
return false;
-
if (isdigit(ir.peek()))
first = ir.getInt();
ir.skipSpace();
- if (ir.peek() == '-') {
+ if (ir.peek() != '-')
+ last = first;
+ else {
while (ir.peek() == '-')
ir.get();
ir.skipSpace();
if (isdigit(ir.peek()))
last = ir.getInt();
}
- else
- last = first;
ir.skipSpace();
if (ir.peek() == ',') {
ir.get();
if (ir.eof())
return false;
}
- else if (!ir.eof())
+ else if (!ir.eof() && ir.peek() != ':')
return false;
if (first > last)
swap(first, last);
@@ -70,10 +74,40 @@ bool PageRanges::parse (const string &str, int max_page) {
}
addRange(first, last);
}
+ // apply filter if present
+ if (ir.peek() == ':') {
+ ir.get();
+ string filterName = ir.getWord();
+ FilterFunc filterFunc;
+ if (filterName == "even")
+ filterFunc = &is_even;
+ else if (filterName == "odd")
+ filterFunc = &is_odd;
+ else
+ return false;
+ *this = filter(filterFunc);
+ }
return true;
}
+/** Returns a new PageRanges object that contains only the values
+ * for which the given filter function returns true. */
+PageRanges PageRanges::filter (FilterFunc filterFunc) const {
+ PageRanges newRanges;
+ if (filterFunc == nullptr)
+ newRanges = *this;
+ else {
+ for (const auto &range : *this) {
+ for (int i=range.first; i <= range.second; i++)
+ if (filterFunc(i))
+ newRanges.addRange(i, i);
+ }
+ }
+ return newRanges;
+}
+
+
/** Returns the number of pages. */
size_t PageRanges::numberOfPages () const {
size_t sum=0;