In-chapter page numbers #120
Replies: 3 comments 3 replies
-
An alternative solution would be to extend/modify the page concept of the document. public class StandardReport : IDocument
{
// metadata
public void Compose(IDocumentContainer container)
{
container
.Page(page =>
{
page.SectionName("chapter1"); // <-- and here
page.MarginVertical(80);
page.MarginHorizontal(100);
page.Background(Colors.Grey.Medium); // transparent is default
page.Size(PageSizes.A3);
page.Header().Element(ComposeHeader);
page.Content().Element(ComposeBigContent);
page.Footer().AlignCenter().PageNumber();
})
.Page(page =>
{
// you can specify multiple page types in the document
// with independend configurations
page.SectionName("chapter2"); // <-- and here
page.Margin(50)
page.Size(PageSizes.A4);
page.Header().Element(ComposeHeader);
page.Content().Element(ComposeSmallContent);
page.Footer().AlignCenter().PageNumber();
});
}
// content implementation
} And call it like this: text.CurrentPageNumberWithinSection("chapter1");
text.TotalPagesOfSection("chapter2"); This way, we can clearly divide entire document into sections. The section content describes its beginning and end. The API looks promising but have a couple of limitations:
|
Beta Was this translation helpful? Give feedback.
-
I was thinking about this requirement and I am considering slightly different option:
.BeginPageNumberOfLocation("name");
.EndPageNumberOfLocation("name");
.PageNumberWithinLocation("name");
.PageLengthOfLocation("name");
// we now take into account begin AND end of the location
.PageNumberOfLocation("name");
// Func<int?, string> that maps page number to the its representation
// Nullable<int> because in the first rendering pass, we don't know exact page numbers, best to put a placeholder
// This approach also solves strange requirements where page numbering should start at value different than 1, just add proper mapping whenever calling page-related API
.PageLengthOfLocation("name", x => x == 1 ? "1 page long" : $"{x} pages long"); It is good to think about argument order or using overload: void PageLengthOfLocation(string locationName, TextStyle? style = null);
void PageLengthOfLocation(string locationName, Func<int?, string>? format = null, TextStyle style = null);
void PageLengthOfLocation(string locationName, TextStyle? style = null, Func<int?, string>? format = null); // best one in my opinion as I expect that custom format is very rarely used feature
Example usage: .Text(text =>
{
text.BeginPageNumberOfLocation(locationName);
text.Span(" - ");
text.EndPageNumberOfLocation(locationName);
var lengthStyle = TextStyle.Default.Color(Colors.Grey.Medium);
text.Span(" (", lengthStyle);
text.PageLengthOfLocation(locationName, x => x == 1 ? "1 page long" : $"{x} pages long", lengthStyle);
text.Span(")", lengthStyle);
}); What do you think? The goal is not only to add new features but also slowly refine the API so it is easier to discover. Sometimes however, it is challenging to find best direction of changes. @wesleigomes @marcianobandeira @qcz @lmingle @jcl-aadlab @donmurta @adaxer @pha3z I am allowing myself to include you to this discussion, thank you in advance for any suggestions. |
Beta Was this translation helpful? Give feedback.
-
That's exactly what I was thinking about! And the usage it's intuitive enough, both for new users of this library and old ones that updating to a new version. Just a question about points 2 and 5 though: by turning an Fully agree with your other points. Thanks. |
Beta Was this translation helpful? Give feedback.
-
Having the need for in-chapter page numbering, I tried taking existing classes and functions and turning them in what I needed, which resulted in something like the following.
In the ElementExtensions class I added a new method called 'ChapterStart', which leverages the possibility to add a location to the document, but automatically prefixing "Ch_" to have a clear distinction between these and 'regular' locations.
Then, in the TextDescriptor class I took 'CurrentPageNumber' and turned it into 'PageNumberInChapter':
which calls a modified version of 'PageNumber' called 'ChapterPageNumber'
that references to 'TextBlockChapterPageNumber', a modified 'TextBlockPageNumber' (who would have guessed), basically identical apart from the SetPageNumber function:
In the end, the user needs to set a ChapterStart location where a chapter starts in the document with
text.ChapterStart("Chapter5")
and thentext.PageNumberInChapter("Chapter5")
to get the page number relative to the start of chapter they set.I know, it's far from perfect, should probably use new elements instead of just reusing renamed InternalLocations, but I did it quickly and just wanted to give you my suggestion for something that might be helpful.
Also, the possibility to set an end to a chapter and calculate and print the total pages of it would be cool (something like 'Chapter 5: page 5 of 16' or something like that).
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions