Documentation Writer
This skill provides guidance for writing effective documentation for SkiaSharp.Extended.
Documentation Principles
Goals
- •Help new developers discover features
- •Help experienced developers find advanced features and customization
- •Be helpful, consistent, and informative - not verbose
- •This is a community docs page - impress and help users
Style Guidelines
- •Friendly feature names in TOC and titles (e.g., "Blur Hash" not "SKBlurHash")
- •Conceptual first - explain why/when, then how
- •Conversational tone - write as if explaining to a colleague
- •Concise code examples - show primary overloads, not all variants
- •Research origins - credit creators, link to official resources
- •Strategic visuals - screenshots that add clarity, not decoration
- •Second person - use "you can..." not "users can..."
What Makes Good Docs
- •Explain the problem it solves before showing how to use it
- •Show before/after comparisons where applicable
- •Include real-world usage patterns (API responses, MAUI bindings)
- •Provide customization options with visual comparisons when helpful
- •Link to authoritative sources for external technologies
API Documentation
- •Link to generated API docs using xref syntax:
[API Reference](xref:SkiaSharp.Extended.SKBlurHash) - •Include summary tables only when they reduce redirects and add clarity
- •Don't reproduce the full API docs in conceptual pages
Images
- •Keep existing images; use descriptive names for new ones (e.g.,
components-comparison.png) - •Store in
docs/images/extended/<feature>/ordocs/images/ui/controls/<control>/ - •Use PNGs for UI screenshots, can use GIFs for animations
Page Structure
Each documentation page follows this pattern:
# Feature Name Brief intro - what it is, the problem it solves (1-2 sentences) [Hero image or comparison - e.g., before/after, original vs processed] ## Quick Start - Encode/create: one code example - Decode/use: one code example ## How It Works - Brief explanation of underlying concepts - Credit original creators if external technology - Visual showing key concept if helpful ## Customization - Key parameters and options with explanations - Tables for parameters when helpful (reduces need to check API docs) - Visual comparisons showing effect of different parameter values ## Usage Patterns - Real-world integration examples (API responses, data models) - MAUI binding/converter examples where applicable - Brief XAML usage example ## Learn More - Link to official site (if external technology like BlurHash, Lottie) - Link to GitHub/source repository - Link to origin story or detailed explanations - Link to API reference using xref
Example: External Technology Attribution
For features based on external technologies (BlurHash, Lottie, etc.):
## Learn More - [BlurHash.sh](https://blurha.sh/) — Official demo and explanation - [BlurHash GitHub](https://github.com/woltapp/blurhash) — Original algorithm by Dag Ågren at Wolt - [How Wolt created BlurHash](https://careers.wolt.com/en/blog/tech/...) — The origin story - [API Reference](xref:SkiaSharp.Extended.SKBlurHash) — Full method documentation
Example: Parameter Table
When parameters need explanation:
| Components | String Length | Best For | | :--------: | :-----------: | :------- | | 2x2 | ~12 chars | Simple gradients | | 4x3 | ~28 chars | Most images (recommended) | | 6x6 | ~76 chars | Complex images with fine detail |
Screenshot Generation
Base Library Features
Generate screenshots using a temporary console app in /tmp/:
mkdir -p /tmp/docs-screenshots cd /tmp/docs-screenshots
Create a minimal .csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="/path/to/source/SkiaSharp.Extended/SkiaSharp.Extended.csproj" />
</ItemGroup>
</Project>
Write Program.cs to generate comparison images, then run:
dotnet run
Screenshot Best Practices
- •Generate side-by-side comparisons (e.g., different parameter values)
- •Add labels to images using SKPaint/SKFont
- •Use white background for consistency
- •Cell size around 200x200 pixels works well
- •Save directly to
docs/images/extended/<feature>/
Example: Comparison Image Generator
using SkiaSharp;
var configs = new[] { (2, 2), (4, 3), (6, 6) };
var cellWidth = 200;
var padding = 10;
using var surface = SKSurface.Create(new SKImageInfo(totalWidth, totalHeight));
var canvas = surface.Canvas;
canvas.Clear(SKColors.White);
// Draw each variant side-by-side with labels
for (int i = 0; i < configs.Length; i++)
{
// Generate image for this config
// Draw to canvas at position
// Add label below
}
using var image = surface.Snapshot();
using var data = image.Encode(SKEncodedImageFormat.Png, 100);
File.WriteAllBytes("comparison.png", data.ToArray());
MAUI Controls
Discuss approach case-by-case - may require running on actual platforms. Existing GIFs in the repo can be kept.
MAUI Integration Examples
Always test MAUI code in a real project before including in docs.
Test Project Setup
mkdir -p /tmp/maui-test cd /tmp/maui-test dotnet new maui -n TestApp cd TestApp dotnet add package SkiaSharp.Views.Maui.Controls dotnet add reference /path/to/source/SkiaSharp.Extended/SkiaSharp.Extended.csproj dotnet build -f net9.0-maccatalyst # or net9.0-android
SKBitmap to ImageSource
Use the implicit conversion to SKBitmapImageSource (cross-platform, not Windows-specific):
using SkiaSharp; using SkiaSharp.Views.Maui.Controls; SKBitmap bitmap = /* ... */; ImageSource source = (SKBitmapImageSource)bitmap;
Do NOT use ToWriteableBitmap() - that's Windows-only.
Value Converter Pattern
Include configurable properties for flexibility:
using System.Globalization;
using SkiaSharp;
using SkiaSharp.Extended;
using SkiaSharp.Views.Maui.Controls;
public class BlurHashConverter : IValueConverter
{
public int Width { get; set; } = 32;
public int Height { get; set; } = 32;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string hash && !string.IsNullOrEmpty(hash))
{
var bitmap = SKBlurHash.DeserializeBitmap(hash, Width, Height);
return (SKBitmapImageSource)bitmap;
}
return null;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
XAML Usage
Always show how to use the converter in XAML:
<ContentPage.Resources>
<local:BlurHashConverter x:Key="BlurHashConverter" Width="32" Height="32" />
</ContentPage.Resources>
<Image Source="{Binding BlurHash, Converter={StaticResource BlurHashConverter}}" />
Building and Previewing Docs
cd docs docfx build # Build docs docfx serve _site --port 8080 # Serve locally docfx --serve # Build and serve in one command
Verify pages render correctly:
curl -s http://localhost:8080/docs/blurhash.html | grep -o '<h1[^>]*>.*</h1>'
Code Block Language Tags
Use consistent language tags for syntax highlighting:
- •
xmlfor XAML/XML content (notxaml- docfx highlightsxmlbetter) - •
csharpfor C# code - •
bashfor shell commands - •
yamlfor YAML files
TOC Structure
For small documentation sites, use a flat TOC with section headings:
items:
- name: Overview
href: ../index.md
- name: SkiaSharp.Extended # Heading only (no href = visual separator)
- name: Blur Hash
href: blurhash.md
- name: Geometry Helpers
href: geometry.md
- name: Path Interpolation
href: path-interpolation.md
- name: SkiaSharp.Extended.UI.Maui # Heading only
- name: Confetti Effects
href: confetti.md
- name: Lottie Animations
href: lottie.md
- name: Resources # Catch-all for non-essential items
- name: Migration Guides
items:
- name: SVG Migration
href: svg-migration.md
TOC Guidelines
- •Headings without href become visual section separators
- •Use friendly feature names (not type names)
- •Put migration guides and other non-essential content under a "Resources" heading
- •Nested items only when there are true sub-pages (like Migration Guides)
File Naming
When renaming doc files for friendlier URLs:
- •
skblurhash.md→blurhash.md - •
skgeometry.md→geometry.md(if renaming) - •Update TOC href references accordingly
Research Checklist
When documenting external technologies:
- •Who invented/created it?
- •Is there an official website or demo?
- •Is there a GitHub repository?
- •Is there an origin story or blog post?
- •What problem does it solve?
- •Are there alternatives? (mention if relevant)
Testing Doc Code Snippets
Always test code snippets before including in docs.
Create a Test Project
For each doc page, create a minimal test project in /tmp/:
mkdir -p /tmp/docs-code-test cd /tmp/docs-code-test
Create .csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="/path/to/source/SkiaSharp.Extended/SkiaSharp.Extended.csproj" />
</ItemGroup>
</Project>
Test All Code Snippets
Create Program.cs that exercises all code from the doc page:
// Test all code snippets from [Feature] docs
using SkiaSharp;
using SkiaSharp.Extended;
Console.WriteLine("Testing [Feature] doc code snippets...\n");
// === Quick Start: Encode ===
Console.WriteLine("1. Quick Start - Encode:");
// Copy code from docs here
// Verify it compiles and runs
// === Quick Start: Decode ===
Console.WriteLine("2. Quick Start - Decode:");
// Copy code from docs here
Console.WriteLine("\n✅ All code snippets compile and run correctly!");
Run the test:
dotnet run
For MAUI Code
Test in a separate MAUI project (see MAUI Integration Examples section).
Quality Checklist
Before finalizing a doc page:
- • Friendly title (not type name)
- • Brief intro explaining the value proposition
- • Hero image or comparison
- • Quick start with working code
- • Customization options explained
- • MAUI integration example (if applicable)
- • Learn More links (official resources + API reference)
- • All code snippets tested in /tmp/ project
- • Build docs and verify no warnings
- • Check rendered page in browser
CI and Deployment
Workflow Requirements
The docs workflow (builds-docs.yml) requires:
- •MAUI workloads installed with explicit nuget.org source:
yaml
dotnet workload install maui --source https://api.nuget.org/v3/index.json
PR Best Practices
- •Never merge with failing CI - always wait for green checks
- •Workflow failures related to workload installation often need the nuget.org source fix
- •Check job logs to understand the actual failure before dismissing as transient