Skip to content

Commit 7287351

Browse files
committed
Added PageRanges.
Updated examples with newer calls.
1 parent 07d513c commit 7287351

4 files changed

Lines changed: 136 additions & 10 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,9 @@ public async Task<Stream> CreateFromMarkdown()
164164
.AddAsyncHeaderFooter(async
165165
b => b.SetHeader(await System.IO.File.ReadAllTextAsync(headerPath))
166166
.SetFooter(await System.IO.File.ReadAllBytesAsync(footerPath))
167-
).WithDimensions(dimBuilder =>
167+
).WithPageProperties(pp =>
168168
{
169-
dimBuilder.SetPaperSize(PaperSizes.A4)
169+
pp.SetPaperSize(PaperSizes.A4)
170170
.SetMargins(Margins.None)
171171
.SetScale(.90)
172172
.SetLandscape();
@@ -213,9 +213,9 @@ IEnumerable<UrlRequestBuilder> CreateBuilders(IEnumerable<Uri> uris)
213213
docBuilder.SetHeader(GetHeadFoot(uri.Host.Replace("www.", string.Empty).ToUpper()))
214214
.SetFooter(GetHeadFoot(uri.ToString()));
215215
})
216-
.WithDimensions(dimBuilder =>
216+
.WithPageProperties(pp =>
217217
{
218-
dimBuilder.UseChromeDefaults()
218+
pp.UseChromeDefaults()
219219
.SetScale(.90)
220220
.SetLandscape()
221221
.SetMarginLeft(.5)

lib/Domain/Builders/Faceted/ConfigBuilder.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16+
using Gotenberg.Sharp.API.Client.Domain.Pages;
17+
1618
namespace Gotenberg.Sharp.API.Client.Domain.Builders.Faceted;
1719

1820
public sealed class ConfigBuilder
@@ -25,12 +27,16 @@ internal ConfigBuilder(RequestConfig requestConfig)
2527
}
2628

2729

28-
public ConfigBuilder SetPageRanges(string pageRanges)
30+
public ConfigBuilder SetPageRanges(string? pageRanges)
2931
{
30-
if (pageRanges.IsNotSet())
31-
throw new ArgumentException("Cannot be null or empty", nameof(pageRanges));
32+
this._requestConfig.PageRanges = Pages.PageRanges.Create(pageRanges);
3233

33-
this._requestConfig.PageRanges = pageRanges;
34+
return this;
35+
}
36+
37+
public ConfigBuilder SetPageRanges(PageRanges? pageRanges)
38+
{
39+
this._requestConfig.PageRanges = pageRanges ?? Pages.PageRanges.All;
3440

3541
return this;
3642
}

lib/Domain/Pages/PageRanges.cs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright 2019-2025 Chris Mohan, Jaben Cargman
2+
// and GotenbergSharpApiClient Contributors
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
using System.Text.RegularExpressions;
17+
18+
namespace Gotenberg.Sharp.API.Client.Domain.Pages;
19+
20+
public sealed class PageRanges : IEquatable<PageRanges>
21+
{
22+
private static readonly Regex PageRangePattern =
23+
new(@"^\s*(\d+(-\d+)?)(\s*,\s*(\d+(-\d+)?))*\s*$");
24+
25+
private PageRanges(IReadOnlyCollection<int> pages)
26+
{
27+
Pages = pages.OrderBy(p => p).ToArray();
28+
}
29+
30+
public static PageRanges All { get; } = new(Array.Empty<int>());
31+
32+
public IReadOnlyCollection<int> Pages { get; }
33+
34+
public bool Equals(PageRanges? other)
35+
{
36+
return other is not null && Pages.SequenceEqual(other.Pages);
37+
}
38+
39+
public static PageRanges Create(string? input)
40+
{
41+
if (string.IsNullOrWhiteSpace(input))
42+
{
43+
return All;
44+
}
45+
46+
if (!PageRangePattern.IsMatch(input))
47+
{
48+
throw new ArgumentOutOfRangeException(nameof(input),
49+
"Invalid page range format. Expected format: '1-5, 8, 11-13'.");
50+
}
51+
52+
var pages = new SortedSet<int>();
53+
foreach (var part in input!.Split([','], StringSplitOptions.RemoveEmptyEntries))
54+
{
55+
var trimmed = part.Trim();
56+
if (trimmed.Contains('-'))
57+
{
58+
var bounds = trimmed.Split('-').Select(int.Parse).ToArray();
59+
if (bounds.Length == 2 && bounds[0] <= bounds[1])
60+
{
61+
for (var i = bounds[0]; i <= bounds[1]; i++)
62+
{
63+
pages.Add(i);
64+
}
65+
}
66+
}
67+
else if (int.TryParse(trimmed, out var singlePage))
68+
{
69+
pages.Add(singlePage);
70+
}
71+
}
72+
73+
return new PageRanges(pages);
74+
}
75+
76+
private string GetPageRangeString()
77+
{
78+
// empty is "all"
79+
if (Pages.Count == 0)
80+
{
81+
return "";
82+
}
83+
84+
var ranges = new List<string>();
85+
int start = Pages.First(), end = start;
86+
87+
foreach (var page in Pages.Skip(1))
88+
{
89+
if (page == end + 1)
90+
{
91+
end = page;
92+
}
93+
else
94+
{
95+
ranges.Add(start == end ? start.ToString() : $"{start}-{end}");
96+
start = end = page;
97+
}
98+
}
99+
100+
ranges.Add(start == end ? start.ToString() : $"{start}-{end}");
101+
return string.Join(", ", ranges);
102+
}
103+
104+
public override string ToString()
105+
{
106+
return GetPageRangeString();
107+
}
108+
109+
public override bool Equals(object? obj)
110+
{
111+
return obj is PageRanges other && Pages.SequenceEqual(other.Pages);
112+
}
113+
114+
public override int GetHashCode()
115+
{
116+
return Pages.Aggregate(0, (hash, page) => hash ^ page.GetHashCode());
117+
}
118+
}

lib/Domain/Requests/Facets/RequestConfig.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16+
using Gotenberg.Sharp.API.Client.Domain.Pages;
17+
1618
namespace Gotenberg.Sharp.API.Client.Domain.Requests.Facets;
1719

1820
/// <summary>
@@ -29,7 +31,7 @@ public sealed class RequestConfig : IConvertToHttpContent
2931
// ReSharper disable once MethodTooLong
3032
public IEnumerable<HttpContent> ToHttpContent()
3133
{
32-
if (this.PageRanges.IsSet())
34+
if (this.PageRanges?.Pages.Any() ?? false)
3335
yield return BuildRequestBase.CreateFormDataItem(
3436
this.PageRanges,
3537
Constants.Gotenberg.Chromium.Shared.PageProperties.PageRanges);
@@ -64,7 +66,7 @@ public void Validate()
6466
/// The format is the same as the one from the print options of Google Chrome, e.g. 1-5,8,11-13.
6567
/// This may move...
6668
/// </remarks>
67-
public string? PageRanges { get; set; }
69+
public PageRanges? PageRanges { get; set; }
6870

6971
/// <summary>
7072
/// If provided, the API will return the resulting PDF file with the given filename. Otherwise a random filename is

0 commit comments

Comments
 (0)