Skip to content

Add template doctor workflow to analyze and repair real-world PowerPoint templates#132

Merged
jongalloway merged 3 commits intomainfrom
copilot/add-template-doctor-workflow
Mar 15, 2026
Merged

Add template doctor workflow to analyze and repair real-world PowerPoint templates#132
jongalloway merged 3 commits intomainfrom
copilot/add-template-doctor-workflow

Conversation

Copy link
Contributor

Copilot AI commented Mar 14, 2026

Closes #86.

Summary

Adds a template doctor workflow that goes beyond diagnostics to identify and optionally repair structural issues in real-world PPTX templates that degrade MarpToPptx output.

What's new

New types in MarpToPptx.Pptx/Diagnostics/

Type Purpose
IssueSeverity Info / Warning / Fixable
TemplateDoctorIssue Per-issue record: layout name, severity, machine-readable code, description, optional proposed fix
TemplateDoctorReport Top-level report: issues, applied fixes, output path
TemplateDoctor Analysis engine with optional write-back to a repaired copy

Checks implemented

Code Severity What it catches
DuplicateLayoutName Warning Multiple layouts with the same name
EmptyLayoutName Warning Layout with no usable name
ContentLayoutMissingTitlePlaceholder Warning Content layout without title placeholder identity
ContentLayoutMissingBodyPlaceholder Warning Content layout without body placeholder identity
PlaceholderGeometryInherited Fixable Placeholder identity present but position/size inherited from slide master; the renderer already recovers via master fallback but materializing the geometry improves template portability
TypelessIndexedBodyPlaceholder Info Body accessible only via typeless indexed placeholder — fully supported, reported for awareness
UnmappableLayoutRole Info Picture-caption or comparison layout that can't yet be auto-selected
VisuallyRedundantLayouts Info Layouts sharing a role with no distinct shapes

Safe write-back

When --write-fixed-template <path> is supplied the doctor:

  1. Copies the original file to the output path (original is never mutated)
  2. Materializes inherited placeholder geometry by deep-cloning slide-master transforms onto the corresponding layout shapes
  3. Reports every fix applied

MarpToPptx.TemplateDiagnostics CLI extended

Now supports two subcommands (backward-compatible — a bare path still runs diagnose):

# Existing behavior
dotnet run --project src/MarpToPptx.TemplateDiagnostics -- diagnose conference.pptx

# New: dry-run doctor report
dotnet run --project src/MarpToPptx.TemplateDiagnostics -- doctor conference.pptx

# New: write repaired copy
dotnet run --project src/MarpToPptx.TemplateDiagnostics -- \
  doctor conference.pptx --write-fixed-template conference-fixed.pptx

# New: JSON output for tool integration
dotnet run --project src/MarpToPptx.TemplateDiagnostics -- \
  doctor conference.pptx --json

Tests

12 new tests in TemplateDoctorTests.cs covering:

  • Smoke / non-null report
  • Issue well-formedness (non-empty code/description, proposed-fix present on Fixable issues)
  • Severity enum validity
  • Dry-run does not write any file
  • Write mode creates the output file
  • Write mode does not modify the original
  • Output file is a valid PresentationDocument
  • Template path stored in report
  • Applied fixes are non-empty strings
  • Issue codes are from the known set

All 339 tests pass (327 pre-existing + 12 new).

Documentation

doc/using-templates.md updated with:

  • diagnose usage and invocation
  • template doctor section with issue-code reference table and example CLI invocations for all three modes (dry-run, write, JSON)

Security

CodeQL: 0 alerts.

Copilot AI and others added 2 commits March 14, 2026 23:17
Co-authored-by: jongalloway <68539+jongalloway@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a “template doctor” capability to MarpToPptx for inspecting PPTX templates for structural issues that affect rendering, optionally applying safe fix-ups, and exposing the feature via the TemplateDiagnostics CLI.

Changes:

  • Introduce TemplateDoctor + report/issue models to analyze templates and optionally materialize placeholder geometry from slide masters.
  • Extend MarpToPptx.TemplateDiagnostics into a subcommand-based CLI (diagnose + doctor) with human-readable and JSON output modes.
  • Add xUnit tests covering doctor reports, issue shapes, and write-vs-dry-run behavior; update template usage documentation.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/MarpToPptx.Tests/TemplateDoctorTests.cs Adds coverage for TemplateDoctor report shape and write/dry-run behaviors.
src/MarpToPptx.TemplateDiagnostics/Program.cs Adds diagnose/doctor subcommands and reporting output (text/JSON).
src/MarpToPptx.Pptx/Diagnostics/TemplateDoctorReport.cs Defines the top-level TemplateDoctor report contract.
src/MarpToPptx.Pptx/Diagnostics/TemplateDoctorIssue.cs Defines per-issue records (severity/code/description/proposed fix).
src/MarpToPptx.Pptx/Diagnostics/TemplateDoctor.cs Implements template analysis and optional fix-up application.
src/MarpToPptx.Pptx/Diagnostics/IssueSeverity.cs Introduces severity enum for doctor issues.
doc/using-templates.md Documents how to run diagnostics/doctor and explains issue codes.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +472 to +485
// For typed placeholders, match by type.
if (placeholder.Type is { } phType)
{
if (masterTypes.Any(t => ph.Type?.Value == t))
{
return shape;
}

continue;
}

// For typeless placeholders, look for body/content type on master.
if (masterTypes.Any(t => ph.Type?.Value == t) || ph.Type?.Value is null)
{
Comment on lines +141 to +152
var layout = layouts[i].SlideLayout;
var hasMatchingName = layout?.MatchingName?.Value is { Length: > 0 };
var hasCsdName = layout?.CommonSlideData?.Name?.Value is { Length: > 0 };

if (!hasMatchingName && !hasCsdName)
{
issues.Add(new TemplateDoctorIssue(
LayoutName: null,
Severity: IssueSeverity.Warning,
Code: "EmptyLayoutName",
Description: $"Layout at position {i + 1} has no name and will be referenced as \"Layout {i + 1}\". " +
"Unnamed layouts are hard to target by name in Markdown directives."));
Comment on lines +103 to +109
// There should be no such issue on the built-in content layout (which has a body).
foreach (var issue in missingBodyIssues)
{
// If any are reported, they must not be for the content layout.
Assert.NotEqual("Title and Content", issue.LayoutName,
StringComparer.OrdinalIgnoreCase);
}
/// </summary>
/// <param name="TemplatePath">Path of the template that was inspected.</param>
/// <param name="Issues">
/// All structural issues and observations found, ordered by severity then by layout order.
default:
if (arg.StartsWith('-'))
{
Console.Error.WriteLine($"Unknown option '{arg}'. Run 'doctor --help' for usage.");
@jongalloway
Copy link
Owner

@copilot apply changes based on the comments in this thread

Co-authored-by: jongalloway <68539+jongalloway@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 15, 2026

@copilot apply changes based on the comments in this thread

Applied all 5 review items in fd1d79f:

  • FindMasterPlaceholderShape: now filters on placeholder.Index first (before the type match), so when a master has multiple placeholders the correct one is selected.
  • EmptyLayoutName: LayoutName is now set to the computed fallback name ("Layout {i+1}") instead of null, so consumers can associate the warning with the specific layout.
  • Test: replaced the permissive foreach guard with Assert.Empty(missingBodyIssues).
  • TemplateDoctorReport.Issues doc comment: updated to describe the actual ordering (check order, not sorted by severity).
  • CLI error message: now says template-diagnostics doctor --help so the full invocation path is unambiguous.

@jongalloway jongalloway merged commit 78e12bb into main Mar 15, 2026
5 checks passed
@jongalloway jongalloway deleted the copilot/add-template-doctor-workflow branch March 15, 2026 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add template doctor workflow to analyze and repair real-world PowerPoint templates

3 participants