| name | docs-writer |
| description | Guide for writing and improving documentation for SkiaSharp.Extended. Use this skill when creating, updating, or reviewing documentation pages, writing code examples for docs, generating screenshots for documentation, or improving existing docs. |
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>/ or docs/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>net10.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);
for (int i = 0; i < configs.Length; i++)
{
}
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 net10.0-maccatalyst
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
docfx serve _site --port 8080
docfx --serve
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:
xml for XAML/XML content (not xaml - docfx highlights xml better)
csharp for C# code
bash for shell commands
yaml for YAML files
TOC Structure
For small documentation sites, use a flat TOC with section headings:
items:
- name: Overview
href: ../index.md
- name: SkiaSharp.Extended
- name: Blur Hash
href: blurhash.md
- name: Geometry Helpers
href: geometry.md
- name: Path Interpolation
href: path-interpolation.md
- name: SkiaSharp.Extended.UI.Maui
- name: Confetti Effects
href: confetti.md
- name: Lottie Animations
href: lottie.md
- name: Resources
- 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>net10.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:
using SkiaSharp;
using SkiaSharp.Extended;
Console.WriteLine("Testing [Feature] doc code snippets...\n");
Console.WriteLine("1. Quick Start - Encode:");
Console.WriteLine("2. Quick Start - Decode:");
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:
CI and Deployment
Workflow Requirements
The docs workflow (builds-docs.yml) requires:
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