mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-31 10:58:25 +00:00
Allow odd/even modifiers in numeric range (fixes #364)
This commit is contained in:
parent
c9cc83621b
commit
c4478e5249
@ -1116,6 +1116,8 @@ QUtil::parse_numrange(char const* range, int max)
|
||||
std::vector<int> work;
|
||||
static int const comma = -1;
|
||||
static int const dash = -2;
|
||||
size_t start_idx = 0;
|
||||
size_t skip = 1;
|
||||
|
||||
enum { st_top,
|
||||
st_in_number,
|
||||
@ -1182,6 +1184,14 @@ QUtil::parse_numrange(char const* range, int max)
|
||||
work.push_back(dash);
|
||||
}
|
||||
}
|
||||
else if (ch == ':')
|
||||
{
|
||||
if (! ((state == st_in_number) || (state == st_after_number)))
|
||||
{
|
||||
throw std::runtime_error("unexpected colon");
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("unexpected character");
|
||||
@ -1197,6 +1207,22 @@ QUtil::parse_numrange(char const* range, int max)
|
||||
{
|
||||
throw std::runtime_error("number expected");
|
||||
}
|
||||
if (*p == ':')
|
||||
{
|
||||
if (strcmp(p, ":odd") == 0)
|
||||
{
|
||||
skip = 2;
|
||||
}
|
||||
else if (strcmp(p, ":even") == 0)
|
||||
{
|
||||
skip = 2;
|
||||
start_idx = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("unexpected even/odd modifier");
|
||||
}
|
||||
}
|
||||
|
||||
p = 0;
|
||||
for (size_t i = 0; i < work.size(); i += 2)
|
||||
@ -1245,6 +1271,15 @@ QUtil::parse_numrange(char const* range, int max)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((start_idx > 0) || (skip != 1))
|
||||
{
|
||||
auto t = result;
|
||||
result.clear();
|
||||
for (size_t i = start_idx; i < t.size(); i += skip)
|
||||
{
|
||||
result.push_back(t.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error const& e)
|
||||
{
|
||||
|
@ -49,6 +49,24 @@ my @nrange_tests = (
|
||||
"numeric range r1-r15" .
|
||||
" -> 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1",
|
||||
0],
|
||||
["1-10:quack",
|
||||
"error at * in numeric range 1-10*:quack: unexpected even/odd modifier",
|
||||
2],
|
||||
["1-10:",
|
||||
"error at * in numeric range 1-10*:: unexpected even/odd modifier",
|
||||
2],
|
||||
["1-10,r:",
|
||||
"error at * in numeric range 1-10,r*:: unexpected even/odd modifier",
|
||||
2],
|
||||
["1-10,:",
|
||||
"error at * in numeric range 1-10,*:: unexpected colon",
|
||||
2],
|
||||
["1-6,8-12:odd",
|
||||
"numeric range 1-6,8-12:odd -> 1 3 5 8 10 12",
|
||||
0],
|
||||
["1-6,8-12:even",
|
||||
"numeric range 1-6,8-12:even -> 2 4 6 9 11",
|
||||
0],
|
||||
);
|
||||
foreach my $d (@nrange_tests)
|
||||
{
|
||||
|
@ -1391,9 +1391,12 @@ make
|
||||
<literal>r3-r1</literal> would be the last three pages of the
|
||||
document. Pages can appear in any order. Ranges can appear with a
|
||||
high number followed by a low number, which causes the pages to
|
||||
appear in reverse. Repeating a number will cause an error, but you
|
||||
can use the workaround discussed above should you really want to
|
||||
include the same page twice.
|
||||
appear in reverse. Numbers may be repeated in a page range. A page
|
||||
range may be optionally appended with <literal>:even</literal> or
|
||||
<literal>:odd</literal> to indicate only the even or odd pages in
|
||||
the given range. Note that even and odd refer to the positions
|
||||
within the specified, range, not whether the original number is
|
||||
even or odd.
|
||||
</para>
|
||||
<para>
|
||||
Example page ranges:
|
||||
@ -1420,6 +1423,18 @@ make
|
||||
in reverse order
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>1-20:even</literal>: even pages from 2 to 20
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>5,7-9,12:odd</literal>: pages 5, 8, and, 12, which are
|
||||
the pages in odd positions from among the original range, which
|
||||
represents pages 5, 7, 8, 9, and 12.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
@ -4663,6 +4678,13 @@ print "\n";
|
||||
<xref linkend="ref.crypto"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Allow <literal>:even</literal> or <literal>:odd</literal> to
|
||||
be appended to numeric ranges for specification of the even
|
||||
or odd pages from among the pages specified in the range.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
@ -1286,8 +1286,9 @@ ArgParser::argHelp()
|
||||
<< "to count from the end, so \"r3-r1\" would be the last three pages of the\n"
|
||||
<< "document. Pages can appear in any order. Ranges can appear with a\n"
|
||||
<< "high number followed by a low number, which causes the pages to appear in\n"
|
||||
<< "reverse. Repeating a number will cause an error, but the manual discusses\n"
|
||||
<< "a workaround should you really want to include the same page twice.\n"
|
||||
<< "reverse. Numbers may be repeated. A page range may be appended with :odd\n"
|
||||
<< "to indicate odd pages in the selected range or :even to indicate even\n"
|
||||
<< "pages.\n"
|
||||
<< "\n"
|
||||
<< "If the page range is omitted, the range of 1-z is assumed. qpdf decides\n"
|
||||
<< "that the page range is omitted if the range argument is either -- or a\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user