Turned getter-like extension methods into extension properties (#1157)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-04 13:00:56 +01:00
1 parent 0375318b1b
commit f649febf88
286 files changed
+1379 -1109

No files matched your search

@@ -46,7 +46,7 @@ internal sealed record ChosenLayouts(IReadOnlyDictionary<LayoutPurpose, LayoutFa
/// <summary>
/// The kinds of slides the presentation has to have, because the user chose a layout for them.
/// </summary>
public IEnumerable<LayoutPurpose> AddedSlides => Enum.GetValues<LayoutPurpose>().Where(purpose => purpose.ChoiceAddsSlide() && this.Families.ContainsKey(purpose));
public IEnumerable<LayoutPurpose> AddedSlides => Enum.GetValues<LayoutPurpose>().Where(purpose => purpose.ChoiceAddsSlide && this.Families.ContainsKey(purpose));
/// <summary>
/// Writes the choices as rules for the model, one line per kind of slide, in the order of the kinds.
@@ -64,14 +64,14 @@ internal sealed record ChosenLayouts(IReadOnlyDictionary<LayoutPurpose, LayoutFa
var rules = new StringBuilder(" - The user chose layouts for some kinds of slides. A choice decides which layout such a slide uses, and it comes before every other rule on choosing layouts. Whether the presentation has such a slide follows from the content and the occasion, except for the slides the next rule requires. Vary the layouts only where no choice applies:");
foreach (var purpose in Enum.GetValues<LayoutPurpose>())
if (this.For(purpose) is { } family)
rules.Append('\n').Append(" - ").Append(family.Id).Append(" for ").Append(purpose.PromptDescription()).Append('.');
rules.Append('\n').Append(" - ").Append(family.Id).Append(" for ").Append(purpose.PromptDescription).Append('.');
var addedSlides = this.AddedSlides.ToList();
if (addedSlides.Count > 0)
{
rules.Append('\n').Append(" - The presentation has at least one slide of each of these kinds, on its layout:");
foreach (var purpose in addedSlides)
rules.Append('\n').Append(" - ").Append(this.Families[purpose].Id).Append(": ").Append(purpose.PromptDescription()).Append(", ").Append(purpose.PromptPlacement()).Append('.');
rules.Append('\n').Append(" - ").Append(this.Families[purpose].Id).Append(": ").Append(purpose.PromptDescription).Append(", ").Append(purpose.PromptPlacement).Append('.');
}
return rules.ToString();
@@ -13,7 +13,7 @@ internal static class LayoutPurposeAreaExtensions
/// <summary>
/// The name of the area, as the forms show it above its kinds of slides.
/// </summary>
public string Label() => area switch
public string Label => area switch
{
LayoutPurposeArea.FRAMING => TB("Structure and framing"),
LayoutPurposeArea.GENERAL => TB("General content"),
@@ -22,23 +22,23 @@ internal static partial class LayoutPurposeExtensions
/// <summary>
/// The area the forms list a kind of slide in.
/// </summary>
public LayoutPurposeArea Area() => Describe(purpose).Area;
public LayoutPurposeArea Area => Describe(purpose).Area;
/// <summary>
/// The short name of the choice, e.g., "Layout for chapters".
/// </summary>
public string Label() => Describe(purpose).Label;
public string Label => Describe(purpose).Label;
/// <summary>
/// The question the choice answers, which says which slides it applies to.
/// </summary>
public string Question() => Describe(purpose).Question;
public string Question => Describe(purpose).Question;
/// <summary>
/// Describes the slides of this kind for the model, so that it knows which of its slides a choice applies to.
/// </summary>
/// <returns>The description, e.g., "timelines, e.g., the course of a project".</returns>
public string PromptDescription() => Describe(purpose).PromptDescription;
/// <value>The description, e.g., "timelines, e.g., the course of a project".</value>
public string PromptDescription => Describe(purpose).PromptDescription;
/// <summary>
/// Whether choosing a layout for this kind of slide also puts such a slide into the presentation.
@@ -48,13 +48,13 @@ internal static partial class LayoutPurposeExtensions
/// presentation has one follows from its content. The slides which frame a presentation are
/// different: whoever chooses a layout for the table of contents or the imprint expects them.
/// </remarks>
public bool ChoiceAddsSlide() => purpose.PromptPlacement() is not null;
public bool ChoiceAddsSlide => purpose.PromptPlacement is not null;
/// <summary>
/// Where a slide goes which a choice puts into the presentation, and what it holds, for the model.
/// </summary>
/// <returns>The rule, or null when a choice adds no slide of this kind.</returns>
public string? PromptPlacement() => purpose switch
/// <value>The rule, or null when a choice adds no slide of this kind.</value>
public string? PromptPlacement => purpose switch
{
LayoutPurpose.TABLE_OF_CONTENTS => "right after the title slide",
LayoutPurpose.Q_AND_A => "near the end, before the closing slide; where the occasion suits it, e.g., in a lecture or a workshop, also at the end of chapters, then naming the topic of the chapter",
@@ -69,9 +69,9 @@ internal static partial class LayoutPurposeExtensions
/// <summary>
/// The help below the choice: its question, and whether a choice adds such a slide.
/// </summary>
public string Help() => purpose.ChoiceAddsSlide()
? $"{purpose.Question()} {TB("Choosing a layout also adds such a slide to the presentation.")}"
: purpose.Question();
public string Help => purpose.ChoiceAddsSlide
? $"{purpose.Question} {TB("Choosing a layout also adds such a slide to the presentation.")}"
: purpose.Question;
}
private static LayoutPurposeInfo Describe(LayoutPurpose purpose) =>
@@ -27,7 +27,7 @@ internal static class PlaceholderRoleExtensions
foreach (var candidate in SLOT_ROLES)
{
if (!string.Equals(words[0], candidate.CatalogName(), StringComparison.OrdinalIgnoreCase))
if (!string.Equals(words[0], candidate.CatalogName, StringComparison.OrdinalIgnoreCase))
continue;
var number = 1;
@@ -51,7 +51,7 @@ internal static class PlaceholderRoleExtensions
/// Footer, slide number and date are filled as well, but by the presentation as a whole rather
/// than by a single slide, so they are no slots of a layout.
/// </remarks>
public bool IsSlot() => role switch
public bool IsSlot => role switch
{
PlaceholderRole.TITLE => true,
PlaceholderRole.SUBTITLE => true,
@@ -70,7 +70,7 @@ internal static class PlaceholderRoleExtensions
/// A layout offering nothing but a title and some labels has no room for content. Such layouts are
/// samples or blank pages, and they are left out of the catalog.
/// </remarks>
public bool CarriesContent() => role switch
public bool CarriesContent => role switch
{
PlaceholderRole.SUBTITLE => true,
PlaceholderRole.TEXT => true,
@@ -83,7 +83,7 @@ internal static class PlaceholderRoleExtensions
/// <summary>
/// How the role is called in the catalog the model reads.
/// </summary>
public string CatalogName() => role switch
public string CatalogName => role switch
{
PlaceholderRole.TITLE => "title",
PlaceholderRole.SUBTITLE => "subtitle",
@@ -185,7 +185,7 @@ internal sealed partial class PresentationTemplate
/// <returns>The entry, e.g., <c>element 2 (text box, right, middle, overlaps picture 1) "Image source"</c>.</returns>
private string DescribeElement(TemplateSlideElement element, IReadOnlyList<TemplateSlot> slotsOnSlide)
{
var details = new List<string> { element.Kind.CatalogName() };
var details = new List<string> { element.Kind.CatalogName };
if (element.Bounds is { } bounds)
{
if (bounds.Area >= (double)this.SlideWidth * this.SlideHeight * BACKGROUND_AREA_SHARE)
@@ -280,7 +280,7 @@ internal sealed partial class PresentationTemplate
private static string NameOf(TemplateSlot slot, IReadOnlyList<TemplateSlot> slots)
{
var isOnlyOne = slot.Role is (PlaceholderRole.TITLE or PlaceholderRole.SUBTITLE) && slots.Count(other => other.Role == slot.Role) == 1;
return isOnlyOne ? slot.Role.CatalogName() : $"{slot.Role.CatalogName()} {slot.Ordinal}";
return isOnlyOne ? slot.Role.CatalogName : $"{slot.Role.CatalogName} {slot.Ordinal}";
}
private string DescribePlace(SlotBounds bounds)
@@ -24,7 +24,7 @@ internal sealed partial class PresentationTemplate
/// </remarks>
private static GroupedLayouts GroupIntoFamilies(IReadOnlyList<TemplateLayout> layouts, long slideWidth, long slideHeight)
{
var usableLayouts = layouts.Where(layout => layout.Slots.Any(slot => slot.Role.CarriesContent())).ToList();
var usableLayouts = layouts.Where(layout => layout.Slots.Any(slot => slot.Role.CarriesContent)).ToList();
var byFirstWord = Group(usableLayouts, VariantWord.FIRST, slideWidth, slideHeight);
var byLastWord = Group(usableLayouts, VariantWord.LAST, slideWidth, slideHeight);
var groups = CountVariants(byLastWord) > CountVariants(byFirstWord) ? byLastWord : byFirstWord;
@@ -148,7 +148,7 @@ internal sealed partial class PresentationTemplate
continue;
var role = RoleOf(placeholder.Type, bounds, slideArea);
if (!role.IsSlot())
if (!role.IsSlot)
continue;
//
@@ -159,7 +159,7 @@ internal static class SlideDeckSpecValidator
{
var familyId = chosen.Families[purpose].Id;
if (!newSlideFamilyIds.Contains(familyId))
issues.Add($"The presentation has no slide on layout {familyId} for {purpose.PromptDescription()}. Add one {purpose.PromptPlacement()}.");
issues.Add($"The presentation has no slide on layout {familyId} for {purpose.PromptDescription}. Add one {purpose.PromptPlacement}.");
}
if (chosen.For(LayoutPurpose.IMPRINT) is { } imprintFamily && newSlideFamilyIds.Contains(imprintFamily.Id) && newSlideFamilyIds[^1] != imprintFamily.Id)
@@ -431,12 +431,12 @@ internal static class SlideDeckSpecValidator
var slot = SlotOf(slots, role, 1);
if (slot is null)
{
issues.Add($"Slide {number} has a {role.CatalogName()}, but layout {layoutId} has none. Choose a layout with a {role.CatalogName()}, or leave it empty.");
issues.Add($"Slide {number} has a {role.CatalogName}, but layout {layoutId} has none. Choose a layout with a {role.CatalogName}, or leave it empty.");
return;
}
if (slot.Capacity is { } capacity)
ValidateCapacity([new SlideParagraph(text, 0)], capacity, $"Slide {number}: the {role.CatalogName()}", issues);
ValidateCapacity([new SlideParagraph(text, 0)], capacity, $"Slide {number}: the {role.CatalogName}", issues);
}
/// <summary>
@@ -450,7 +450,7 @@ internal static class SlideDeckSpecValidator
return true;
issues.Add(slotCount == 0
? $"Slide {number} has {count} {PluralOf(role, count)}, but layout {layoutId} has no {role.CatalogName()}. Choose a layout which has one."
? $"Slide {number} has {count} {PluralOf(role, count)}, but layout {layoutId} has no {role.CatalogName}. Choose a layout which has one."
: $"Slide {number} has {count} {PluralOf(role, count)}, but layout {layoutId} has only {slotCount}. Merge them, or choose a layout with more.");
return false;
@@ -517,5 +517,5 @@ internal static class SlideDeckSpecValidator
return Math.Max(1, (int)Math.Ceiling(paragraph.Text.Length / (double)width));
}
private static string PluralOf(PlaceholderRole role, int count) => count == 1 ? role.CatalogName() : $"{role.CatalogName()}s";
private static string PluralOf(PlaceholderRole role, int count) => count == 1 ? role.CatalogName : $"{role.CatalogName}s";
}
@@ -7,7 +7,7 @@ internal static class TemplateSlideElementKindExtensions
/// <summary>
/// How the kind is called in the list of template slides the model reads.
/// </summary>
public string CatalogName() => kind switch
public string CatalogName => kind switch
{
TemplateSlideElementKind.TEXT_BOX => "text box",
TemplateSlideElementKind.SHAPE => "shape",