mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-05 02:47:21 +00:00
Moved all extension methods into extension blocks (#1155)
This commit is contained in:
1 parent
acc7d09fa2
commit
c0a75f39ac
138 files changed
+5884
-4954
No files matched your search
@@ -7,20 +7,23 @@ internal static class LayoutPurposeAreaExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => PluginSystem.I18N.I.T(fallbackEN, typeof(LayoutPurposeAreaExtensions).Namespace, nameof(LayoutPurposeAreaExtensions));
|
||||
|
||||
/// <summary>
|
||||
/// The name of the area, as the forms show it above its kinds of slides.
|
||||
/// </summary>
|
||||
/// <param name="area">The area.</param>
|
||||
public static string Label(this LayoutPurposeArea area) => area switch
|
||||
extension(LayoutPurposeArea area)
|
||||
{
|
||||
LayoutPurposeArea.FRAMING => TB("Structure and framing"),
|
||||
LayoutPurposeArea.GENERAL => TB("General content"),
|
||||
LayoutPurposeArea.TEACHING => TB("Teaching and workshops"),
|
||||
LayoutPurposeArea.BUSINESS => TB("Business and projects"),
|
||||
LayoutPurposeArea.SCIENCE => TB("Science and research"),
|
||||
LayoutPurposeArea.MEDICINE => TB("Medicine"),
|
||||
LayoutPurposeArea.LAW => TB("Law"),
|
||||
/// <summary>
|
||||
/// The name of the area, as the forms show it above its kinds of slides.
|
||||
/// </summary>
|
||||
public string Label() => area switch
|
||||
{
|
||||
LayoutPurposeArea.FRAMING => TB("Structure and framing"),
|
||||
LayoutPurposeArea.GENERAL => TB("General content"),
|
||||
LayoutPurposeArea.TEACHING => TB("Teaching and workshops"),
|
||||
LayoutPurposeArea.BUSINESS => TB("Business and projects"),
|
||||
LayoutPurposeArea.SCIENCE => TB("Science and research"),
|
||||
LayoutPurposeArea.MEDICINE => TB("Medicine"),
|
||||
LayoutPurposeArea.LAW => TB("Law"),
|
||||
|
||||
_ => TB("Other kinds of slides"),
|
||||
};
|
||||
_ => TB("Other kinds of slides"),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -16,66 +16,63 @@ internal static partial class LayoutPurposeExtensions
|
||||
/// </summary>
|
||||
public static string NoPreference => TB("No preference (the LLM decides)");
|
||||
|
||||
/// <summary>
|
||||
/// The area the forms list a kind of slide in.
|
||||
/// </summary>
|
||||
/// <param name="purpose">The kind of slide.</param>
|
||||
public static LayoutPurposeArea Area(this LayoutPurpose purpose) => Describe(purpose).Area;
|
||||
|
||||
/// <summary>
|
||||
/// The short name of the choice, e.g., "Layout for chapters".
|
||||
/// </summary>
|
||||
/// <param name="purpose">The kind of slide.</param>
|
||||
public static string Label(this LayoutPurpose purpose) => Describe(purpose).Label;
|
||||
|
||||
/// <summary>
|
||||
/// The question the choice answers, which says which slides it applies to.
|
||||
/// </summary>
|
||||
/// <param name="purpose">The kind of slide.</param>
|
||||
public static string Question(this LayoutPurpose purpose) => 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>
|
||||
/// <param name="purpose">The kind of slide.</param>
|
||||
/// <returns>The description, e.g., "timelines, e.g., the course of a project".</returns>
|
||||
public static string PromptDescription(this LayoutPurpose purpose) => Describe(purpose).PromptDescription;
|
||||
|
||||
/// <summary>
|
||||
/// Whether choosing a layout for this kind of slide also puts such a slide into the presentation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For most kinds, a choice says only which layout such a slide uses, and whether the
|
||||
/// 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>
|
||||
/// <param name="purpose">The kind of slide.</param>
|
||||
public static bool ChoiceAddsSlide(this LayoutPurpose purpose) => 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>
|
||||
/// <param name="purpose">The kind of slide.</param>
|
||||
/// <returns>The rule, or null when a choice adds no slide of this kind.</returns>
|
||||
public static string? PromptPlacement(this LayoutPurpose purpose) => purpose switch
|
||||
extension(LayoutPurpose purpose)
|
||||
{
|
||||
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",
|
||||
LayoutPurpose.ACKNOWLEDGEMENTS => "near the end; where thanks concern a single chapter, also at the end of that chapter",
|
||||
LayoutPurpose.REFERENCES => "near the end; it lists only the sources the content names, or else the attached documents, and never a source of your own",
|
||||
LayoutPurpose.CLOSING => "at the end, before an appendix and the imprint",
|
||||
LayoutPurpose.IMPRINT => "as the very last slide; it holds only what the request, the content, or the profile state, e.g., the title, the authors, the organization, and today's date, and it leaves a slot empty rather than inventing anything",
|
||||
/// <summary>
|
||||
/// The area the forms list a kind of slide in.
|
||||
/// </summary>
|
||||
public LayoutPurposeArea Area() => Describe(purpose).Area;
|
||||
|
||||
_ => null,
|
||||
};
|
||||
/// <summary>
|
||||
/// The short name of the choice, e.g., "Layout for chapters".
|
||||
/// </summary>
|
||||
public string Label() => Describe(purpose).Label;
|
||||
|
||||
/// <summary>
|
||||
/// The help below the choice: its question, and whether a choice adds such a slide.
|
||||
/// </summary>
|
||||
/// <param name="purpose">The kind of slide.</param>
|
||||
public static string Help(this LayoutPurpose purpose) => purpose.ChoiceAddsSlide()
|
||||
? $"{purpose.Question()} {TB("Choosing a layout also adds such a slide to the presentation.")}"
|
||||
: purpose.Question();
|
||||
/// <summary>
|
||||
/// The question the choice answers, which says which slides it applies to.
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Whether choosing a layout for this kind of slide also puts such a slide into the presentation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For most kinds, a choice says only which layout such a slide uses, and whether the
|
||||
/// 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;
|
||||
|
||||
/// <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
|
||||
{
|
||||
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",
|
||||
LayoutPurpose.ACKNOWLEDGEMENTS => "near the end; where thanks concern a single chapter, also at the end of that chapter",
|
||||
LayoutPurpose.REFERENCES => "near the end; it lists only the sources the content names, or else the attached documents, and never a source of your own",
|
||||
LayoutPurpose.CLOSING => "at the end, before an appendix and the imprint",
|
||||
LayoutPurpose.IMPRINT => "as the very last slide; it holds only what the request, the content, or the profile state, e.g., the title, the authors, the organization, and today's date, and it leaves a slot empty rather than inventing anything",
|
||||
|
||||
_ => null,
|
||||
};
|
||||
|
||||
/// <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();
|
||||
}
|
||||
|
||||
private static LayoutPurposeInfo Describe(LayoutPurpose purpose) =>
|
||||
DescribeFraming(purpose)
|
||||
|
||||
@@ -42,54 +42,57 @@ internal static class PlaceholderRoleExtensions
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether content of the presentation goes into a placeholder of this role.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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 static bool IsSlot(this PlaceholderRole role) => role switch
|
||||
extension(PlaceholderRole role)
|
||||
{
|
||||
PlaceholderRole.TITLE => true,
|
||||
PlaceholderRole.SUBTITLE => true,
|
||||
PlaceholderRole.TEXT => true,
|
||||
PlaceholderRole.LABEL => true,
|
||||
PlaceholderRole.PICTURE => true,
|
||||
PlaceholderRole.TABLE => true,
|
||||
/// <summary>
|
||||
/// Whether content of the presentation goes into a placeholder of this role.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
{
|
||||
PlaceholderRole.TITLE => true,
|
||||
PlaceholderRole.SUBTITLE => true,
|
||||
PlaceholderRole.TEXT => true,
|
||||
PlaceholderRole.LABEL => true,
|
||||
PlaceholderRole.PICTURE => true,
|
||||
PlaceholderRole.TABLE => true,
|
||||
|
||||
_ => false,
|
||||
};
|
||||
_ => false,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Whether a placeholder of this role carries the content of a slide, rather than describing it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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 static bool CarriesContent(this PlaceholderRole role) => role switch
|
||||
{
|
||||
PlaceholderRole.SUBTITLE => true,
|
||||
PlaceholderRole.TEXT => true,
|
||||
PlaceholderRole.PICTURE => true,
|
||||
PlaceholderRole.TABLE => true,
|
||||
/// <summary>
|
||||
/// Whether a placeholder of this role carries the content of a slide, rather than describing it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
{
|
||||
PlaceholderRole.SUBTITLE => true,
|
||||
PlaceholderRole.TEXT => true,
|
||||
PlaceholderRole.PICTURE => true,
|
||||
PlaceholderRole.TABLE => true,
|
||||
|
||||
_ => false,
|
||||
};
|
||||
_ => false,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// How the role is called in the catalog the model reads.
|
||||
/// </summary>
|
||||
public static string CatalogName(this PlaceholderRole role) => role switch
|
||||
{
|
||||
PlaceholderRole.TITLE => "title",
|
||||
PlaceholderRole.SUBTITLE => "subtitle",
|
||||
PlaceholderRole.TEXT => "text",
|
||||
PlaceholderRole.LABEL => "label",
|
||||
PlaceholderRole.PICTURE => "picture",
|
||||
PlaceholderRole.TABLE => "table",
|
||||
/// <summary>
|
||||
/// How the role is called in the catalog the model reads.
|
||||
/// </summary>
|
||||
public string CatalogName() => role switch
|
||||
{
|
||||
PlaceholderRole.TITLE => "title",
|
||||
PlaceholderRole.SUBTITLE => "subtitle",
|
||||
PlaceholderRole.TEXT => "text",
|
||||
PlaceholderRole.LABEL => "label",
|
||||
PlaceholderRole.PICTURE => "picture",
|
||||
PlaceholderRole.TABLE => "table",
|
||||
|
||||
_ => "unsupported",
|
||||
};
|
||||
_ => "unsupported",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,20 +2,23 @@ namespace AIStudio.Tools.PowerPoint;
|
||||
|
||||
internal static class TemplateSlideElementKindExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// How the kind is called in the list of template slides the model reads.
|
||||
/// </summary>
|
||||
public static string CatalogName(this TemplateSlideElementKind kind) => kind switch
|
||||
extension(TemplateSlideElementKind kind)
|
||||
{
|
||||
TemplateSlideElementKind.TEXT_BOX => "text box",
|
||||
TemplateSlideElementKind.SHAPE => "shape",
|
||||
TemplateSlideElementKind.LINE => "line",
|
||||
TemplateSlideElementKind.PICTURE => "picture",
|
||||
TemplateSlideElementKind.TABLE => "table",
|
||||
TemplateSlideElementKind.CHART => "chart",
|
||||
TemplateSlideElementKind.DIAGRAM => "diagram",
|
||||
TemplateSlideElementKind.GROUP => "group",
|
||||
/// <summary>
|
||||
/// How the kind is called in the list of template slides the model reads.
|
||||
/// </summary>
|
||||
public string CatalogName() => kind switch
|
||||
{
|
||||
TemplateSlideElementKind.TEXT_BOX => "text box",
|
||||
TemplateSlideElementKind.SHAPE => "shape",
|
||||
TemplateSlideElementKind.LINE => "line",
|
||||
TemplateSlideElementKind.PICTURE => "picture",
|
||||
TemplateSlideElementKind.TABLE => "table",
|
||||
TemplateSlideElementKind.CHART => "chart",
|
||||
TemplateSlideElementKind.DIAGRAM => "diagram",
|
||||
TemplateSlideElementKind.GROUP => "group",
|
||||
|
||||
_ => "object",
|
||||
};
|
||||
_ => "object",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,27 +2,33 @@ namespace AIStudio.Tools.PowerPoint;
|
||||
|
||||
internal static class TemplateSlideUseListExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// What the user chose for one slide of the template.
|
||||
/// </summary>
|
||||
/// <param name="uses">What the user chose for each slide of the template, by its number.</param>
|
||||
/// <param name="number">The number of the slide, starting at 1.</param>
|
||||
/// <returns>The choice; TemplateSlideUse.OMIT for a slide the list does not cover.</returns>
|
||||
public static TemplateSlideUse UseOf(this IReadOnlyList<TemplateSlideUse> uses, int number) => number >= 1 && number <= uses.Count ? uses[number - 1] : TemplateSlideUse.OMIT;
|
||||
extension(IReadOnlyList<TemplateSlideUse> uses)
|
||||
{
|
||||
/// <summary>
|
||||
/// What the user chose for one slide of the template.
|
||||
/// </summary>
|
||||
/// <param name="number">The number of the slide, starting at 1.</param>
|
||||
/// <returns>The choice; TemplateSlideUse.OMIT for a slide the list does not cover.</returns>
|
||||
public TemplateSlideUse UseOf(int number) => number >= 1 && number <= uses.Count ? uses[number - 1] : TemplateSlideUse.OMIT;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// What the presentation does with each slide of a template, by the choices for some of its slides.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A slide without a choice is left out, as by default. A choice to edit a slide which the model
|
||||
/// cannot edit keeps the slide unchanged instead: such a choice may come from an organization,
|
||||
/// which the user cannot overrule, and it would block the form. A choice for a slide the template
|
||||
/// does not have is passed over.
|
||||
/// </remarks>
|
||||
/// <param name="choices">The choices by the number of the slide, starting at 1.</param>
|
||||
/// <param name="template">The template whose slides the choices number.</param>
|
||||
/// <returns>A choice for each slide of the template, in its order.</returns>
|
||||
public static List<TemplateSlideUse> ToTemplateSlideUses(this IReadOnlyDictionary<int, TemplateSlideUse> choices, PresentationTemplate template) => template.Slides
|
||||
.Select(slide => choices.TryGetValue(slide.Number, out var use) ? use is TemplateSlideUse.EDIT && !slide.IsEditable ? TemplateSlideUse.KEEP : use : TemplateSlideUse.OMIT)
|
||||
.ToList();
|
||||
extension(IReadOnlyDictionary<int, TemplateSlideUse> choices)
|
||||
{
|
||||
/// <summary>
|
||||
/// What the presentation does with each slide of a template, by the choices for some of its slides.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A slide without a choice is left out, as by default. A choice to edit a slide which the model
|
||||
/// cannot edit keeps the slide unchanged instead: such a choice may come from an organization,
|
||||
/// which the user cannot overrule, and it would block the form. A choice for a slide the template
|
||||
/// does not have is passed over.
|
||||
/// </remarks>
|
||||
/// <param name="template">The template whose slides the choices number.</param>
|
||||
/// <returns>A choice for each slide of the template, in its order.</returns>
|
||||
public List<TemplateSlideUse> ToTemplateSlideUses(PresentationTemplate template) => template.Slides
|
||||
.Select(slide => choices.TryGetValue(slide.Number, out var use) ? use is TemplateSlideUse.EDIT && !slide.IsEditable ? TemplateSlideUse.KEEP : use : TemplateSlideUse.OMIT)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user