diff options
author | Norbert Preining <norbert@preining.info> | 2023-01-12 03:01:29 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2023-01-12 03:01:29 +0000 |
commit | 6a7900c93acc16d1bbd2f1e26286c7dd7387e6c0 (patch) | |
tree | 76196287351cba68a51934c49468bf1a7846aa76 /dviware/dvisvgm/src/PageRanges.cpp | |
parent | c1c19023b4b1d43cb874f84df5102b485853e672 (diff) |
CTAN sync 202301120301
Diffstat (limited to 'dviware/dvisvgm/src/PageRanges.cpp')
-rw-r--r-- | dviware/dvisvgm/src/PageRanges.cpp | 48 |
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; |