Skip to content

Commit

Permalink
Added PageRanges.
Browse files Browse the repository at this point in the history
Updated examples with newer calls.
  • Loading branch information
Jaben committed Feb 16, 2025
1 parent 07d513c commit 7287351
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 10 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ public async Task<Stream> CreateFromMarkdown()
.AddAsyncHeaderFooter(async
b => b.SetHeader(await System.IO.File.ReadAllTextAsync(headerPath))
.SetFooter(await System.IO.File.ReadAllBytesAsync(footerPath))
).WithDimensions(dimBuilder =>
).WithPageProperties(pp =>
{
dimBuilder.SetPaperSize(PaperSizes.A4)
pp.SetPaperSize(PaperSizes.A4)
.SetMargins(Margins.None)
.SetScale(.90)
.SetLandscape();
Expand Down Expand Up @@ -213,9 +213,9 @@ IEnumerable<UrlRequestBuilder> CreateBuilders(IEnumerable<Uri> uris)
docBuilder.SetHeader(GetHeadFoot(uri.Host.Replace("www.", string.Empty).ToUpper()))
.SetFooter(GetHeadFoot(uri.ToString()));
})
.WithDimensions(dimBuilder =>
.WithPageProperties(pp =>
{
dimBuilder.UseChromeDefaults()
pp.UseChromeDefaults()
.SetScale(.90)
.SetLandscape()
.SetMarginLeft(.5)
Expand Down
14 changes: 10 additions & 4 deletions lib/Domain/Builders/Faceted/ConfigBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Gotenberg.Sharp.API.Client.Domain.Pages;

namespace Gotenberg.Sharp.API.Client.Domain.Builders.Faceted;

public sealed class ConfigBuilder
Expand All @@ -25,12 +27,16 @@ internal ConfigBuilder(RequestConfig requestConfig)
}


public ConfigBuilder SetPageRanges(string pageRanges)
public ConfigBuilder SetPageRanges(string? pageRanges)
{
if (pageRanges.IsNotSet())
throw new ArgumentException("Cannot be null or empty", nameof(pageRanges));
this._requestConfig.PageRanges = Pages.PageRanges.Create(pageRanges);

this._requestConfig.PageRanges = pageRanges;
return this;
}

public ConfigBuilder SetPageRanges(PageRanges? pageRanges)
{
this._requestConfig.PageRanges = pageRanges ?? Pages.PageRanges.All;

return this;
}
Expand Down
118 changes: 118 additions & 0 deletions lib/Domain/Pages/PageRanges.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright 2019-2025 Chris Mohan, Jaben Cargman
// and GotenbergSharpApiClient Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System.Text.RegularExpressions;

namespace Gotenberg.Sharp.API.Client.Domain.Pages;

public sealed class PageRanges : IEquatable<PageRanges>
{
private static readonly Regex PageRangePattern =
new(@"^\s*(\d+(-\d+)?)(\s*,\s*(\d+(-\d+)?))*\s*$");

private PageRanges(IReadOnlyCollection<int> pages)
{
Pages = pages.OrderBy(p => p).ToArray();
}

public static PageRanges All { get; } = new(Array.Empty<int>());

public IReadOnlyCollection<int> Pages { get; }

public bool Equals(PageRanges? other)
{
return other is not null && Pages.SequenceEqual(other.Pages);
}

public static PageRanges Create(string? input)
{
if (string.IsNullOrWhiteSpace(input))
{
return All;
}

if (!PageRangePattern.IsMatch(input))
{
throw new ArgumentOutOfRangeException(nameof(input),
"Invalid page range format. Expected format: '1-5, 8, 11-13'.");
}

var pages = new SortedSet<int>();
foreach (var part in input!.Split([','], StringSplitOptions.RemoveEmptyEntries))
{
var trimmed = part.Trim();
if (trimmed.Contains('-'))
{
var bounds = trimmed.Split('-').Select(int.Parse).ToArray();
if (bounds.Length == 2 && bounds[0] <= bounds[1])
{
for (var i = bounds[0]; i <= bounds[1]; i++)
{
pages.Add(i);
}
}
}
else if (int.TryParse(trimmed, out var singlePage))
{
pages.Add(singlePage);
}
}

return new PageRanges(pages);
}

private string GetPageRangeString()
{
// empty is "all"
if (Pages.Count == 0)
{
return "";
}

var ranges = new List<string>();
int start = Pages.First(), end = start;

foreach (var page in Pages.Skip(1))
{
if (page == end + 1)
{
end = page;
}
else
{
ranges.Add(start == end ? start.ToString() : $"{start}-{end}");
start = end = page;
}
}

ranges.Add(start == end ? start.ToString() : $"{start}-{end}");
return string.Join(", ", ranges);
}

public override string ToString()
{
return GetPageRangeString();
}

public override bool Equals(object? obj)
{
return obj is PageRanges other && Pages.SequenceEqual(other.Pages);
}

public override int GetHashCode()
{
return Pages.Aggregate(0, (hash, page) => hash ^ page.GetHashCode());
}
}
6 changes: 4 additions & 2 deletions lib/Domain/Requests/Facets/RequestConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Gotenberg.Sharp.API.Client.Domain.Pages;

namespace Gotenberg.Sharp.API.Client.Domain.Requests.Facets;

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

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

0 comments on commit 7287351

Please sign in to comment.