Initial commit
This commit is contained in:
319
skills/technical-writer/SKILL.md
Normal file
319
skills/technical-writer/SKILL.md
Normal file
@@ -0,0 +1,319 @@
|
||||
---
|
||||
name: technical-writer
|
||||
description: Expert in technical documentation (README, API docs, guides, tutorials, quickstarts, specs, release notes) that automatically activates when creating, editing, or reviewing .md files in docs/ directories, README files, or when discussing documentation structure, style guides, or content organization. Follows industry best practices for clear, accessible technical communication across all documentation types.
|
||||
---
|
||||
|
||||
# Technical Documentation Expert
|
||||
|
||||
## Overview
|
||||
|
||||
Provides expert guidance for creating clear, comprehensive, and user-friendly technical documentation following industry best practices and structured content models.
|
||||
|
||||
**Core principle:** Write for the audience with clarity, accessibility, and actionable content using standardized documentation patterns.
|
||||
|
||||
## When to Use
|
||||
|
||||
Automatically activates when:
|
||||
|
||||
- Working with `.md` files in `docs/` directories
|
||||
- Creating or editing README files
|
||||
- Editing documentation files or markup
|
||||
- Discussing documentation structure, information architecture, or style guides
|
||||
- Creating API documentation with examples and parameter tables
|
||||
- Writing user guides, tutorials, or quickstarts
|
||||
- Drafting release notes or change logs
|
||||
- Structuring specifications or technical proposals
|
||||
|
||||
Manual invocation when:
|
||||
|
||||
- User explicitly asks about documentation best practices
|
||||
- User needs guidance on content organization or structure
|
||||
- User requests help with technical writing style
|
||||
- User encounters documentation quality issues
|
||||
|
||||
## When NOT to Use This Skill
|
||||
|
||||
Do not use this skill for:
|
||||
|
||||
- Creative writing or marketing copy
|
||||
- Code implementation (documentation only)
|
||||
- Project management documentation
|
||||
- Internal team chat or informal notes
|
||||
- Academic papers or research documentation
|
||||
|
||||
## Core Expertise Areas
|
||||
|
||||
### Content Types
|
||||
|
||||
1. **Conceptual** - Explains what something is and why it's useful ("About..." articles)
|
||||
2. **Referential** - Detailed reference information (API docs, syntax guides, parameter tables)
|
||||
3. **Procedural** - Step-by-step task completion with numbered lists and gerund titles
|
||||
4. **Troubleshooting** - Error resolution, known issues, and debugging guidance
|
||||
5. **Quickstart** - Essential setup in 5 minutes/600 words maximum
|
||||
6. **Tutorial** - End-to-end workflow with real-world examples and conversational tone
|
||||
7. **Release Notes** - Version changes categorized by type (Features, Fixes, Breaking Changes)
|
||||
|
||||
### Documentation Structure
|
||||
|
||||
**Standard Article Elements:**
|
||||
|
||||
- Titles: Sentence case, gerund for procedures, character limits by level
|
||||
- Intros: 1-2 sentences explaining content
|
||||
- Prerequisites and permissions when applicable
|
||||
- Clear next steps
|
||||
|
||||
**Information Architecture:**
|
||||
|
||||
- Hierarchical structure with maximum 4 navigation levels
|
||||
- Content ordering: Conceptual → Referential → Procedural → Troubleshooting
|
||||
|
||||
**For detailed structure requirements:** See `./references/style-guide.md` section on Article Structure and Standard Elements.
|
||||
|
||||
### Style Guide Principles
|
||||
|
||||
Apply formatting and style rules from the comprehensive style guide:
|
||||
|
||||
- Language: Clear, simple, active voice, sentence case
|
||||
- Technical formatting: Code in backticks, UI in bold, placeholders in ALL-CAPS
|
||||
- Structure: Numbered lists for procedures, bullets for non-sequential info
|
||||
- Links: Descriptive text, no "click here"
|
||||
- Alerts: Use Note, Tip, Important, Warning, Caution sparingly
|
||||
|
||||
**For detailed formatting rules:** See `./references/style-guide.md` sections on Language and Tone, Technical Writing Conventions, and Structure and Format.
|
||||
|
||||
### Procedural Content Ordering
|
||||
|
||||
Follow standard procedural sequence: Enabling → Using → Managing → Disabling → Destructive
|
||||
|
||||
Within individual steps: Optional info → Reason → Location → Action
|
||||
|
||||
**For complete ordering guidelines:** See `./references/style-guide.md` section on Content Ordering Guidelines.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### 1. Understand the Audience
|
||||
|
||||
- Identify user expertise level (beginner, intermediate, advanced)
|
||||
- Determine user goals and tasks
|
||||
- Consider context where documentation will be used
|
||||
- Plan appropriate content depth and technical level
|
||||
|
||||
### 2. Choose Content Type
|
||||
|
||||
Select the appropriate content type:
|
||||
|
||||
- **Need to explain a concept?** → Conceptual
|
||||
- **Documenting API or syntax?** → Referential
|
||||
- **How-to for specific task?** → Procedural
|
||||
- **Debugging help?** → Troubleshooting
|
||||
- **Quick setup needed?** → Quickstart (≤5 minutes)
|
||||
- **End-to-end learning?** → Tutorial
|
||||
- **Version changes?** → Release Notes
|
||||
|
||||
### 3. Structure Content
|
||||
|
||||
**Standard content sequence:**
|
||||
|
||||
1. Title (sentence case, descriptive, within character limits)
|
||||
2. Brief intro (1-2 sentences)
|
||||
3. Prerequisites (if applicable)
|
||||
4. Permissions statement (if required)
|
||||
5. Main content (ordered appropriately by type)
|
||||
6. Troubleshooting (embedded when helpful)
|
||||
7. Next steps / Further reading
|
||||
|
||||
### 4. Apply Style Guide
|
||||
|
||||
Follow the comprehensive style guide for:
|
||||
|
||||
- Formatting code, UI elements, and placeholders
|
||||
- Writing clear procedures with proper structure
|
||||
- Adding accessibility features (alt text, sufficient contrast)
|
||||
- Ensuring proper link formatting and context
|
||||
- Using alerts appropriately
|
||||
|
||||
For complete style guide details, see: `./references/style-guide.md`
|
||||
|
||||
### 5. Content Accuracy
|
||||
|
||||
**Critical rule:** Do not invent or assume information not present in source material.
|
||||
|
||||
- If gaps exist, ask user for missing information
|
||||
- Do not create placeholder or speculative content
|
||||
- Verify technical accuracy with authoritative sources
|
||||
- Include working examples when possible
|
||||
|
||||
## Problem-Solving Approach
|
||||
|
||||
### 1. Analysis Phase
|
||||
|
||||
- Review existing documentation structure and patterns
|
||||
- Identify target audience and their needs
|
||||
- Assess information architecture and navigation
|
||||
- Check for consistency with project documentation standards
|
||||
|
||||
### 2. Solution Design
|
||||
|
||||
- Select appropriate content type for the task
|
||||
- Plan information hierarchy and flow
|
||||
- Consider accessibility and localization needs
|
||||
- Design for different user expertise levels
|
||||
|
||||
### 3. Implementation
|
||||
|
||||
- Write clear, concise content following style guide
|
||||
- Structure with appropriate headings and sections
|
||||
- Include concrete examples where helpful
|
||||
- Add tables for complex reference information
|
||||
- Ensure proper formatting of code, UI, and placeholders
|
||||
|
||||
### 4. Validation
|
||||
|
||||
- Verify content accuracy and completeness
|
||||
- Check that examples work as documented
|
||||
- Ensure style guide compliance
|
||||
- Validate accessibility (alt text, structure, contrast)
|
||||
- Confirm navigation and links work correctly
|
||||
|
||||
**Automated validation:** Use `./scripts/validate_markdown.py <file>` to check:
|
||||
- Proper heading hierarchy (no skipped levels)
|
||||
- Code block formatting (language tags, closing backticks)
|
||||
- Link syntax and descriptive link text
|
||||
- Basic document structure
|
||||
|
||||
## Communication Style
|
||||
|
||||
**Be Clear and Actionable:**
|
||||
|
||||
- Use simple, direct language
|
||||
- Provide specific examples and code snippets
|
||||
- Break complex topics into digestible sections
|
||||
- Include visual aids when they clarify concepts
|
||||
|
||||
**Serve Multiple Expertise Levels:**
|
||||
|
||||
- Layer content from simple to complex
|
||||
- Provide quick reference sections
|
||||
- Link to deeper explanations
|
||||
- Use prerequisites to set expectations
|
||||
|
||||
**Focus on User Goals:**
|
||||
|
||||
- Organize by tasks users want to accomplish
|
||||
- Use gerund titles for procedures ("Creating...", "Configuring...")
|
||||
- Include "what you'll learn" or "what you'll build" statements
|
||||
- Provide clear next steps after each article
|
||||
|
||||
## Reference Materials
|
||||
|
||||
This skill references the comprehensive style guide for detailed guidance on all formatting rules.
|
||||
|
||||
**See:** `./references/style-guide.md` for the complete technical writing style guide.
|
||||
|
||||
### Quick Discovery: Search Patterns
|
||||
|
||||
For specific formatting rules in the large style guide, use grep to search:
|
||||
|
||||
- **Alert formatting rules:** Search for `"alert"` in `./references/style-guide.md`
|
||||
- **Code block formatting:** Search for `"code"` or `"backticks"` in `./references/style-guide.md`
|
||||
- **Link formatting:** Search for `"link text"` in `./references/style-guide.md`
|
||||
- **Table formatting:** Search for `"table"` in `./references/style-guide.md`
|
||||
- **Heading hierarchy:** Search for `"heading"` in `./references/style-guide.md`
|
||||
- **Procedural step structure:** Search for `"step structure"` or `"Within Procedural"` in `./references/style-guide.md`
|
||||
- **Alt text requirements:** Search for `"alt text"` in `./references/style-guide.md`
|
||||
- **Placeholder conventions:** Search for `"placeholder"` or `"ALL-CAPS"` in `./references/style-guide.md`
|
||||
|
||||
## Success Criteria
|
||||
|
||||
Documentation is successful when:
|
||||
|
||||
- Content is accessible to the target audience
|
||||
- Structure follows the appropriate content type
|
||||
- Examples clarify complex concepts
|
||||
- Style guide rules are consistently applied
|
||||
- Users can complete tasks using the documentation
|
||||
- Information architecture supports easy navigation
|
||||
- Content is accurate and up-to-date
|
||||
|
||||
## Quick Reference: Common Patterns
|
||||
|
||||
### README Structure
|
||||
|
||||
```markdown
|
||||
# Project Title (sentence case)
|
||||
|
||||
Brief description in 1-2 sentences.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Item 1
|
||||
- Item 2
|
||||
|
||||
## Installation
|
||||
|
||||
1. Step one
|
||||
2. Step two
|
||||
|
||||
## Usage
|
||||
|
||||
Basic usage examples with code blocks.
|
||||
|
||||
## Documentation
|
||||
|
||||
Links to further reading.
|
||||
```
|
||||
|
||||
### API Documentation Pattern
|
||||
|
||||
```markdown
|
||||
## `functionName(param1, param2)`
|
||||
|
||||
Brief description of what the function does.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ------ | ----------- |
|
||||
| param1 | string | Description |
|
||||
| param2 | number | Description |
|
||||
|
||||
**Returns:** Description of return value
|
||||
|
||||
**Example:**
|
||||
\`\`\`language
|
||||
// Working code example
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Release Notes Pattern
|
||||
|
||||
```markdown
|
||||
# Version X.Y.Z
|
||||
|
||||
## Features
|
||||
|
||||
- New feature description
|
||||
|
||||
## Fixes
|
||||
|
||||
- Bug fix description
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- Breaking change with migration path
|
||||
|
||||
## Improvements
|
||||
|
||||
- Enhancement description
|
||||
```
|
||||
|
||||
## Remember
|
||||
|
||||
- Always consider the audience first
|
||||
- Choose the right content type for the task
|
||||
- Follow style guide consistently
|
||||
- Do not invent information - ask when unclear
|
||||
- Include working examples
|
||||
- Make content accessible
|
||||
- Structure for easy navigation
|
||||
- Validate before completion
|
||||
609
skills/technical-writer/references/style-guide.md
Normal file
609
skills/technical-writer/references/style-guide.md
Normal file
@@ -0,0 +1,609 @@
|
||||
# Comprehensive Technical Writing Style Guide
|
||||
|
||||
This reference provides detailed guidance for creating professional, accessible, and user-friendly technical documentation.
|
||||
|
||||
## Content Model
|
||||
|
||||
### Content Structure
|
||||
|
||||
- **Hierarchical organization**: Top-level doc sets → Categories → Map topics → Articles
|
||||
- **Category creation threshold**: 10+ articles required for new categories
|
||||
- **Navigation depth**: Maximum 4 levels deep
|
||||
- **Consistent content types**: Each with specific purposes and formats
|
||||
- **Standard elements**: Every article includes titles, intros, permissions, etc.
|
||||
|
||||
## Article Structure and Standard Elements
|
||||
|
||||
### Titles
|
||||
|
||||
**Character limits:**
|
||||
- Categories: 67 character limit
|
||||
- Map topics: 63 character limit
|
||||
- Articles: 80 character limit
|
||||
|
||||
**Formatting:**
|
||||
- Use sentence case (not title case)
|
||||
- Gerund titles for procedural content ("Creating...", "Configuring...")
|
||||
- Avoid "How to" prefix unless required by product convention
|
||||
|
||||
**Examples:**
|
||||
|
||||
✅ Do:
|
||||
- "Set up OAuth for a single-page app"
|
||||
- "Creating a service principal" (procedural/gerund)
|
||||
|
||||
❌ Don't:
|
||||
- "Setting Up OAuth for a Single-Page App" (title case)
|
||||
- "How to set up OAuth" (avoid "How to")
|
||||
|
||||
### Intros
|
||||
|
||||
**Length requirements:**
|
||||
- Articles: 1-2 sentences
|
||||
- Categories/Map topics: 1 sentence
|
||||
|
||||
**Content:**
|
||||
- Must explain what the content covers
|
||||
- Be specific and actionable
|
||||
- Avoid vague language
|
||||
|
||||
**Examples:**
|
||||
|
||||
✅ Do:
|
||||
"This guide shows you how to enable OAuth for single-page apps using PKCE. You'll configure an app, create secrets, and test the flow."
|
||||
|
||||
❌ Don't:
|
||||
"In this document, we will be covering OAuth for single-page applications in depth." (vague, long-winded)
|
||||
|
||||
### Permissions Statements
|
||||
|
||||
**Required for:** All tasks requiring specific permissions
|
||||
|
||||
**Format options:**
|
||||
|
||||
1. **Frontmatter** (preferred):
|
||||
```yaml
|
||||
---
|
||||
required-permissions:
|
||||
role: Owner
|
||||
scope: Subscription
|
||||
---
|
||||
```
|
||||
|
||||
2. **Inline**:
|
||||
"You need the Owner role at the subscription scope to complete these steps."
|
||||
|
||||
**Consistency:** Use the same language patterns across documentation.
|
||||
|
||||
### Required Sections
|
||||
|
||||
When applicable, include these sections:
|
||||
|
||||
**Prerequisites:**
|
||||
- Use structured list format
|
||||
- Be specific about versions, tools, access levels
|
||||
|
||||
Example:
|
||||
- An Azure subscription
|
||||
- The Azure CLI 2.60.0 or later
|
||||
- Owner role at the subscription scope
|
||||
|
||||
**Product callouts:**
|
||||
"This feature is available on the Enterprise plan only."
|
||||
|
||||
**Next steps and Further reading:**
|
||||
- Provide clear next actions
|
||||
- Link to related content
|
||||
- Use descriptive link text
|
||||
|
||||
## Content Types Detailed
|
||||
|
||||
### 1. Conceptual Content
|
||||
|
||||
**Purpose:** Explains what something is and why it's useful
|
||||
|
||||
**Characteristics:**
|
||||
- "About..." article pattern
|
||||
- Defines concepts and terminology
|
||||
- Explains when to use and tradeoffs
|
||||
- Provides context without step-by-step instructions
|
||||
|
||||
**Example:**
|
||||
"About service principals" — defines the concept, when to use it, and tradeoffs.
|
||||
|
||||
### 2. Referential Content
|
||||
|
||||
**Purpose:** Detailed information for active use
|
||||
|
||||
**Characteristics:**
|
||||
- Syntax guides with complete parameter lists
|
||||
- Tables for complex data relationships
|
||||
- Alphabetical or logical organization
|
||||
- Comprehensive but scannable format
|
||||
|
||||
**When to use tables vs. lists:**
|
||||
- **Tables**: Multiple related properties per item
|
||||
- **Lists**: Simple, single-dimension information
|
||||
|
||||
**Structure headers appropriately:**
|
||||
- Long reference content benefits from clear section breaks
|
||||
- Use consistent heading hierarchy
|
||||
- Enable quick scanning and search
|
||||
|
||||
**Example:**
|
||||
"CLI reference for `az ad sp`" — flags, options, examples.
|
||||
|
||||
### 3. Procedural Content
|
||||
|
||||
**Purpose:** Step-by-step task completion
|
||||
|
||||
**Characteristics:**
|
||||
- Numbered lists (sequential steps)
|
||||
- Gerund titles ("Creating...", "Configuring...")
|
||||
- One action per step
|
||||
- Clear prerequisites upfront
|
||||
|
||||
**Step structure:**
|
||||
1. Optional information (if applicable)
|
||||
2. Reason for the step (if not obvious)
|
||||
3. Location where to perform action
|
||||
4. Action to take
|
||||
|
||||
**Example:**
|
||||
"Creating a service principal" — numbered steps start-to-finish.
|
||||
|
||||
### 4. Troubleshooting Content
|
||||
|
||||
**Purpose:** Error resolution and known issues
|
||||
|
||||
**Types:**
|
||||
|
||||
**Known issues** (separate articles):
|
||||
- Complex problems requiring detailed explanation
|
||||
- Multiple potential causes
|
||||
- Ongoing or unresolved issues
|
||||
|
||||
**General troubleshooting** (embedded):
|
||||
- Common errors for specific tasks
|
||||
- Quick fixes and workarounds
|
||||
- Embedded in main task articles
|
||||
|
||||
**Structure:**
|
||||
- Symptom description
|
||||
- Cause explanation
|
||||
- Resolution steps
|
||||
- Prevention guidance
|
||||
|
||||
**Example:**
|
||||
"Fix: AADSTS700016 error" — symptoms, cause, resolution.
|
||||
|
||||
### 5. Quickstart Content
|
||||
|
||||
**Purpose:** Essential steps for quick setup
|
||||
|
||||
**Critical requirements:**
|
||||
- **Time limit**: 5 minutes / 600 words maximum
|
||||
- **Specific intro phrasing**: Must clarify audience and scope
|
||||
- **Audience clarification**: Required for complex products
|
||||
|
||||
**Structure:**
|
||||
1. Before you begin (2-3 prerequisites)
|
||||
2. Create resources (1-2 commands or clicks)
|
||||
3. Run and verify (1 command or screenshot)
|
||||
4. Clean up resources
|
||||
|
||||
**Intro pattern:**
|
||||
"In this quickstart, you [accomplish X]. This guide is for [audience] who want to [goal]."
|
||||
|
||||
**Example:**
|
||||
"Create and deploy your first function app" — 3-5 steps, done in 5 minutes.
|
||||
|
||||
### 6. Tutorial Content
|
||||
|
||||
**Purpose:** Detailed workflow guidance with real-world examples
|
||||
|
||||
**Requirements:**
|
||||
- **Conversational tone**: Required for engagement
|
||||
- **Real examples**: Must use actual, working examples (no placeholder code)
|
||||
- **Conclusion structure**: Specific requirements for wrap-up
|
||||
|
||||
**Characteristics:**
|
||||
- End-to-end scenario
|
||||
- Explains "why" not just "how"
|
||||
- Includes best practices
|
||||
- Shows complete, working solution
|
||||
|
||||
**Conclusion must include:**
|
||||
- Summary of what was accomplished
|
||||
- Link to related concepts
|
||||
- Suggested next steps
|
||||
- Resources for going deeper
|
||||
|
||||
**Example:**
|
||||
"Build a news summarizer with Functions and Cosmos DB" — end-to-end scenario.
|
||||
|
||||
### 7. Release Notes
|
||||
|
||||
**Purpose:** Version-specific changes and updates
|
||||
|
||||
**Requirements:**
|
||||
- **Comprehensive formatting**: Specific categorization rules
|
||||
- **Change categorization**: Features, fixes, improvements, breaking changes, etc.
|
||||
|
||||
**Categories (in order):**
|
||||
1. Breaking Changes (if any)
|
||||
2. Features (new capabilities)
|
||||
3. Improvements (enhancements to existing features)
|
||||
4. Fixes (bug fixes)
|
||||
5. Documentation (doc updates)
|
||||
6. Dependencies (version updates)
|
||||
|
||||
**Format:**
|
||||
```markdown
|
||||
## Version X.Y.Z - YYYY-MM-DD
|
||||
|
||||
### Breaking Changes
|
||||
- Change description with migration path
|
||||
|
||||
### Features
|
||||
- New feature description with brief example
|
||||
|
||||
### Improvements
|
||||
- Enhancement description
|
||||
|
||||
### Fixes
|
||||
- Bug fix description (can reference issue numbers)
|
||||
```
|
||||
|
||||
**Example:**
|
||||
"v1.8.0" — Features, fixes, breaking changes.
|
||||
|
||||
### Combining Content Types
|
||||
|
||||
**Guidelines:**
|
||||
- Longer articles can combine multiple content types
|
||||
- Follow content ordering guidelines
|
||||
- Use clear transitions between sections
|
||||
- Include troubleshooting information frequently
|
||||
|
||||
**Transition examples:**
|
||||
- "Now that you understand the key concepts, follow these steps to enable the feature."
|
||||
- "With the basics covered, let's explore advanced configurations."
|
||||
|
||||
## Content Ordering Guidelines
|
||||
|
||||
### Standard Content Sequence
|
||||
|
||||
1. **Conceptual** - What it is and why it's useful
|
||||
2. **Referential** - Detailed information for active use
|
||||
3. **Procedural** (in this specific order):
|
||||
- **Enabling** - Initial setup/activation
|
||||
- **Using** - Regular operational tasks
|
||||
- **Managing** - Administrative/configuration tasks
|
||||
- **Disabling** - Deactivation procedures
|
||||
- **Destructive** - Deletion/removal tasks
|
||||
4. **Troubleshooting** - Error resolution
|
||||
|
||||
### Within Procedural Steps
|
||||
|
||||
Order information within each step:
|
||||
|
||||
1. **Optional information** (if applicable)
|
||||
- "If you already have X, skip this step."
|
||||
2. **Reason** for the step (if not obvious)
|
||||
- "This keeps latency low."
|
||||
3. **Location** where to perform the action
|
||||
- "In the Azure portal, go to Resource groups..."
|
||||
4. **Action** to take
|
||||
- "...and select Create."
|
||||
|
||||
**Example:**
|
||||
"Create a resource group in the same region as your app. This keeps latency low. In the Azure portal, go to Resource groups and select Create. Name it `my-rg` and select a region."
|
||||
|
||||
## Style Guide Key Points
|
||||
|
||||
### Language and Tone
|
||||
|
||||
**Principles:**
|
||||
- Clear, simple, approachable language
|
||||
- Active voice preferred (passive acceptable when appropriate)
|
||||
- Sentence case for titles and headers
|
||||
- Avoid jargon, idioms, regional phrases
|
||||
- Write for global, multilingual audience
|
||||
|
||||
**Examples:**
|
||||
|
||||
✅ Do:
|
||||
"Run the command and wait for the confirmation message."
|
||||
|
||||
❌ Don't:
|
||||
"One could conceivably run said command prior to proceeding." (jargon, passive, unclear)
|
||||
|
||||
### Technical Writing Conventions
|
||||
|
||||
**Code formatting:**
|
||||
- Use `backticks` for code, file names, commands, parameters
|
||||
- Keep code blocks to ~60 character line length
|
||||
- Avoid command prompts in examples (just show commands)
|
||||
- Use syntax highlighting with proper language tags
|
||||
|
||||
**UI elements:**
|
||||
- Format UI text in **bold** (buttons, menu items, fields)
|
||||
- Use exact text from the interface
|
||||
- Use > for navigation paths: **File > Save As**
|
||||
|
||||
**Placeholders:**
|
||||
- ALL-CAPS with dashes: YOUR-PROJECT, YOUR-RESOURCE-GROUP
|
||||
- Must explain placeholders before or after use
|
||||
- Be consistent with placeholder naming
|
||||
|
||||
**Images:**
|
||||
- Include alt text for all images (40-150 characters)
|
||||
- Alt text describes what's shown, not just "screenshot"
|
||||
- Reference images in text: "as shown in the following image"
|
||||
|
||||
**Examples:**
|
||||
|
||||
✅ Good:
|
||||
- "Select **Create** and run `az group create --name MY-RG --location westus`."
|
||||
- "Replace YOUR-RG with the name of your resource group."
|
||||
- Alt text: "Screenshot of the Azure portal showing the Create resource group form with fields completed"
|
||||
|
||||
### Structure and Format
|
||||
|
||||
**Lists:**
|
||||
|
||||
**Numbered lists** (procedures):
|
||||
- Capitalize first word
|
||||
- Use periods for complete sentences
|
||||
- One action per step
|
||||
- Sequential order matters
|
||||
|
||||
**Bullet lists** (non-sequential):
|
||||
- Use asterisks (*) not dashes
|
||||
- Capitalize first word
|
||||
- Alphabetize when appropriate
|
||||
- Parallel structure
|
||||
|
||||
**Tables:**
|
||||
- Use consistent header formatting
|
||||
- Align content properly (left for text, right for numbers)
|
||||
- Include header row
|
||||
- Keep cells concise
|
||||
|
||||
**Alert Types** (use sparingly):
|
||||
|
||||
- **Note**: Neutral, supplementary information
|
||||
- "The CLI caches credentials for 1 hour."
|
||||
- **Tip**: Helpful shortcuts or best practices
|
||||
- "Use tags to organize resources across subscriptions."
|
||||
- **Important**: Critical information that affects outcomes
|
||||
- "Do not share client secrets. Rotate them every 90 days."
|
||||
- **Warning**: Potential risks or consequences
|
||||
- "Deleting the resource group removes all resources in it."
|
||||
- **Caution**: Actions that could cause data loss or damage
|
||||
- "Export data before disabling the feature to avoid loss."
|
||||
|
||||
### Links and References
|
||||
|
||||
**Internal links:**
|
||||
- Use appropriate formatting for your doc system
|
||||
- Link to specific sections when helpful
|
||||
- Keep link text descriptive
|
||||
|
||||
**Link text:**
|
||||
- Be descriptive (tell what user will find)
|
||||
- Never use "click here" or "read more"
|
||||
- Include context when needed
|
||||
|
||||
**External links:**
|
||||
- Provide full context
|
||||
- Explain why user should follow the link
|
||||
- Consider link rot (prefer stable URLs)
|
||||
|
||||
**Examples:**
|
||||
|
||||
✅ Do:
|
||||
- "See the authentication overview for background on OAuth 2.0."
|
||||
- "For the OAuth 2.1 draft, see the IETF working group page."
|
||||
|
||||
❌ Don't:
|
||||
- "Click here for more info."
|
||||
- "Read more." (no context)
|
||||
|
||||
## Process and Workflow Elements
|
||||
|
||||
### Topics (Metadata)
|
||||
|
||||
**Character limits:**
|
||||
- Keep topics concise
|
||||
- Follow selection criteria for your platform
|
||||
|
||||
**Forbidden patterns:**
|
||||
- Avoid duplicating title text
|
||||
- Don't use as keyword stuffing
|
||||
|
||||
### Tool Switchers
|
||||
|
||||
**When to use:**
|
||||
- Multiple interfaces for same task (Portal, CLI, PowerShell, Terraform)
|
||||
- All methods achieve same outcome
|
||||
- Each deserves equal treatment
|
||||
|
||||
**Format:**
|
||||
- Use tabbed interface when supported
|
||||
- Consistent ordering across docs
|
||||
- Complete examples in each tab
|
||||
|
||||
**Example:**
|
||||
"Portal | CLI | PowerShell | Terraform"
|
||||
|
||||
### Call to Action (CTA)
|
||||
|
||||
**Requirements:**
|
||||
- Consistent formatting
|
||||
- Clear, action-oriented language
|
||||
- Specific next step
|
||||
|
||||
**Examples:**
|
||||
- Next steps: "Next, secure your API keys with Key Vault."
|
||||
- CTA button text: "Save", "Create", "Deploy" (not "Click to save")
|
||||
|
||||
### Reusables and Variables
|
||||
|
||||
**When to use reusables:**
|
||||
- Content repeated verbatim across multiple articles
|
||||
- Maintenance efficiency matters
|
||||
- Content unlikely to need article-specific variations
|
||||
|
||||
**When to inline content:**
|
||||
- Article-specific variations likely
|
||||
- Better readability in source
|
||||
- Single-use content
|
||||
|
||||
**Variable usage:**
|
||||
- Define at document start or first use
|
||||
- Be consistent with variable names
|
||||
- Match placeholder conventions
|
||||
|
||||
**Examples:**
|
||||
- "Set `YOUR-RG`, `YOUR-LOCATION`, and `YOUR-APP-NAME`."
|
||||
- Reusable snippet: Common troubleshooting block for network timeouts
|
||||
|
||||
## Accessibility Requirements
|
||||
|
||||
### Alt Text
|
||||
|
||||
**Requirements:**
|
||||
- 40-150 characters
|
||||
- Describe what's shown, not "screenshot of..."
|
||||
- Include relevant text from image
|
||||
- Convey information, not aesthetics
|
||||
|
||||
**Examples:**
|
||||
✅ "Azure portal showing the Create resource group form with fields completed"
|
||||
❌ "Screenshot" (too vague)
|
||||
|
||||
### Structure
|
||||
|
||||
**Heading hierarchy:**
|
||||
- Use proper heading levels (H1 → H2 → H3)
|
||||
- Don't skip levels
|
||||
- One H1 per page (the title)
|
||||
|
||||
**Reading order:**
|
||||
- Content makes sense when read linearly
|
||||
- Screen reader compatible
|
||||
|
||||
**Color and contrast:**
|
||||
- Don't rely on color alone
|
||||
- Ensure sufficient contrast
|
||||
- Use patterns or labels in addition to color
|
||||
|
||||
### Links
|
||||
|
||||
**Descriptive link text:**
|
||||
- Tells where link goes
|
||||
- Makes sense out of context
|
||||
- Avoid "click here"
|
||||
|
||||
### ARIA (when applicable)
|
||||
|
||||
- Use ARIA labels for complex interactions
|
||||
- Ensure keyboard navigation works
|
||||
- Test with screen readers
|
||||
|
||||
## Localization Considerations
|
||||
|
||||
**Write for translation:**
|
||||
- Avoid idioms and colloquialisms
|
||||
- Use simple sentence structure
|
||||
- Be explicit (avoid implied information)
|
||||
- Watch for cultural references
|
||||
|
||||
**Date and number formatting:**
|
||||
- Use international formats
|
||||
- Provide context for ambiguous formats
|
||||
- Let localization system handle conversion
|
||||
|
||||
**Right-to-left (RTL) languages:**
|
||||
- Ensure UI accommodates RTL
|
||||
- Test with RTL languages
|
||||
- Avoid directional language ("left sidebar")
|
||||
|
||||
**String externalization:**
|
||||
- Use localization keys
|
||||
- Avoid concatenating strings
|
||||
- Plan for text expansion (some languages are longer)
|
||||
|
||||
## Quality Checklist
|
||||
|
||||
Use this checklist before publishing:
|
||||
|
||||
**Content:**
|
||||
- [ ] Accurate and technically correct
|
||||
- [ ] Appropriate content type for task
|
||||
- [ ] Complete (no missing steps or information)
|
||||
- [ ] Examples work as documented
|
||||
- [ ] Tone appropriate for audience
|
||||
|
||||
**Structure:**
|
||||
- [ ] Clear title (sentence case, within character limits)
|
||||
- [ ] Brief intro (1-2 sentences)
|
||||
- [ ] Prerequisites listed when needed
|
||||
- [ ] Logical flow and organization
|
||||
- [ ] Clear next steps
|
||||
|
||||
**Style:**
|
||||
- [ ] Sentence case for headers
|
||||
- [ ] Active voice (mostly)
|
||||
- [ ] Code formatted correctly
|
||||
- [ ] Placeholders explained
|
||||
- [ ] Links descriptive and working
|
||||
|
||||
**Accessibility:**
|
||||
- [ ] Alt text for all images
|
||||
- [ ] Proper heading hierarchy
|
||||
- [ ] Sufficient color contrast
|
||||
- [ ] Keyboard accessible
|
||||
|
||||
**Polish:**
|
||||
- [ ] Spell check passed
|
||||
- [ ] Grammar correct
|
||||
- [ ] Consistent terminology
|
||||
- [ ] No jargon or explained when necessary
|
||||
|
||||
## Summary: Quick Decision Tree
|
||||
|
||||
**What type of content do I need?**
|
||||
|
||||
- Explaining a concept? → **Conceptual**
|
||||
- Documenting API/syntax? → **Referential**
|
||||
- How to do a task? → **Procedural**
|
||||
- Fixing errors? → **Troubleshooting**
|
||||
- Quick start (< 5 min)? → **Quickstart**
|
||||
- Learning journey? → **Tutorial**
|
||||
- Version changes? → **Release Notes**
|
||||
|
||||
**How should I structure it?**
|
||||
|
||||
1. Title (sentence case, descriptive)
|
||||
2. Intro (1-2 sentences, specific)
|
||||
3. Prerequisites (if needed)
|
||||
4. Main content (type-appropriate)
|
||||
5. Troubleshooting (when helpful)
|
||||
6. Next steps
|
||||
|
||||
**What voice should I use?**
|
||||
|
||||
- Active, direct, clear
|
||||
- Simple language
|
||||
- Appropriate for global audience
|
||||
- Professional but approachable
|
||||
|
||||
**Did I make it accessible?**
|
||||
|
||||
- Alt text on images
|
||||
- Proper headings
|
||||
- Descriptive links
|
||||
- Sufficient contrast
|
||||
267
skills/technical-writer/scripts/validate_markdown.py
Executable file
267
skills/technical-writer/scripts/validate_markdown.py
Executable file
@@ -0,0 +1,267 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Markdown Documentation Validator
|
||||
|
||||
Validates markdown documentation files for common issues:
|
||||
- Proper heading hierarchy (no skipped levels)
|
||||
- Code block formatting (language tags, closing backticks)
|
||||
- Link syntax validation
|
||||
- Basic structure checks
|
||||
|
||||
Usage:
|
||||
python validate_markdown.py <file_path>
|
||||
python validate_markdown.py <directory_path>
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple
|
||||
|
||||
|
||||
class ValidationError:
|
||||
"""Represents a validation error with line number and description."""
|
||||
|
||||
def __init__(self, line_num: int, error_type: str, message: str):
|
||||
self.line_num = line_num
|
||||
self.error_type = error_type
|
||||
self.message = message
|
||||
|
||||
def __str__(self):
|
||||
return f"Line {self.line_num}: [{self.error_type}] {self.message}"
|
||||
|
||||
|
||||
class MarkdownValidator:
|
||||
"""Validates markdown documentation files."""
|
||||
|
||||
def __init__(self, file_path: Path):
|
||||
self.file_path = file_path
|
||||
self.errors: List[ValidationError] = []
|
||||
self.lines: List[str] = []
|
||||
self.heading_levels: List[int] = []
|
||||
|
||||
def validate(self) -> List[ValidationError]:
|
||||
"""Run all validation checks and return list of errors."""
|
||||
try:
|
||||
with open(self.file_path, 'r', encoding='utf-8') as f:
|
||||
self.lines = f.readlines()
|
||||
except Exception as e:
|
||||
return [ValidationError(0, "FILE_ERROR", f"Cannot read file: {e}")]
|
||||
|
||||
self._check_heading_hierarchy()
|
||||
self._check_code_blocks()
|
||||
self._check_links()
|
||||
self._check_basic_structure()
|
||||
|
||||
return sorted(self.errors, key=lambda e: e.line_num)
|
||||
|
||||
def _check_heading_hierarchy(self):
|
||||
"""Check that heading levels don't skip (e.g., h1 -> h3)."""
|
||||
prev_level = 0
|
||||
|
||||
for i, line in enumerate(self.lines, 1):
|
||||
# Match ATX-style headings (# Heading)
|
||||
match = re.match(r'^(#{1,6})\s+(.+)', line)
|
||||
if match:
|
||||
level = len(match.group(1))
|
||||
self.heading_levels.append(level)
|
||||
|
||||
# Check for skipped levels
|
||||
if level > prev_level + 1:
|
||||
self.errors.append(ValidationError(
|
||||
i,
|
||||
"HEADING_SKIP",
|
||||
f"Heading level skipped (h{prev_level} -> h{level}). Use h{prev_level + 1} instead."
|
||||
))
|
||||
|
||||
# Check for title case (common mistake)
|
||||
title = match.group(2).strip()
|
||||
if self._is_title_case(title) and level <= 3:
|
||||
self.errors.append(ValidationError(
|
||||
i,
|
||||
"TITLE_CASE",
|
||||
f"Heading appears to use title case. Use sentence case instead: '{title}'"
|
||||
))
|
||||
|
||||
prev_level = level
|
||||
|
||||
def _is_title_case(self, text: str) -> bool:
|
||||
"""Check if text appears to be in title case."""
|
||||
# Skip if too short or starts with code
|
||||
if len(text.split()) < 3 or text.startswith('`'):
|
||||
return False
|
||||
|
||||
words = text.split()
|
||||
# Articles and short words that should be lowercase in sentence case
|
||||
small_words = {'a', 'an', 'the', 'and', 'but', 'or', 'for', 'nor', 'on', 'at', 'to', 'from', 'by', 'with'}
|
||||
|
||||
capitalized_count = sum(1 for word in words[1:] if word and word[0].isupper() and word.lower() not in small_words)
|
||||
|
||||
# If more than 50% of non-first words are capitalized, likely title case
|
||||
return capitalized_count > len(words[1:]) * 0.5
|
||||
|
||||
def _check_code_blocks(self):
|
||||
"""Check code block formatting."""
|
||||
in_code_block = False
|
||||
code_block_start = 0
|
||||
|
||||
for i, line in enumerate(self.lines, 1):
|
||||
# Check for code block fences
|
||||
if line.strip().startswith('```'):
|
||||
if not in_code_block:
|
||||
# Starting a code block
|
||||
in_code_block = True
|
||||
code_block_start = i
|
||||
|
||||
# Check for language tag
|
||||
fence_content = line.strip()[3:].strip()
|
||||
if not fence_content:
|
||||
self.errors.append(ValidationError(
|
||||
i,
|
||||
"CODE_BLOCK_LANG",
|
||||
"Code block missing language identifier (e.g., ```python, ```bash, ```markdown)"
|
||||
))
|
||||
else:
|
||||
# Ending a code block
|
||||
in_code_block = False
|
||||
|
||||
# Check for unclosed code block
|
||||
if in_code_block:
|
||||
self.errors.append(ValidationError(
|
||||
code_block_start,
|
||||
"CODE_BLOCK_UNCLOSED",
|
||||
"Code block opened but never closed"
|
||||
))
|
||||
|
||||
def _check_links(self):
|
||||
"""Check link syntax."""
|
||||
for i, line in enumerate(self.lines, 1):
|
||||
# Find all markdown links [text](url)
|
||||
links = re.finditer(r'\[([^\]]+)\]\(([^)]+)\)', line)
|
||||
|
||||
for match in links:
|
||||
link_text = match.group(1)
|
||||
link_url = match.group(2)
|
||||
|
||||
# Check for "click here" anti-pattern
|
||||
if link_text.lower() in ['click here', 'here', 'read more', 'more']:
|
||||
self.errors.append(ValidationError(
|
||||
i,
|
||||
"LINK_TEXT",
|
||||
f"Non-descriptive link text: '{link_text}'. Use descriptive text that tells where the link goes."
|
||||
))
|
||||
|
||||
# Check for empty link text
|
||||
if not link_text.strip():
|
||||
self.errors.append(ValidationError(
|
||||
i,
|
||||
"LINK_EMPTY",
|
||||
"Link has empty text"
|
||||
))
|
||||
|
||||
# Check for empty URL
|
||||
if not link_url.strip():
|
||||
self.errors.append(ValidationError(
|
||||
i,
|
||||
"LINK_EMPTY_URL",
|
||||
f"Link '{link_text}' has empty URL"
|
||||
))
|
||||
|
||||
def _check_basic_structure(self):
|
||||
"""Check basic document structure."""
|
||||
# Check for at least one H1
|
||||
if not any(line.startswith('# ') for line in self.lines):
|
||||
self.errors.append(ValidationError(
|
||||
1,
|
||||
"NO_H1",
|
||||
"Document should have at least one top-level heading (# Title)"
|
||||
))
|
||||
|
||||
# Check for multiple H1s (often unintended)
|
||||
h1_count = sum(1 for line in self.lines if line.startswith('# '))
|
||||
if h1_count > 1:
|
||||
self.errors.append(ValidationError(
|
||||
1,
|
||||
"MULTIPLE_H1",
|
||||
f"Document has {h1_count} top-level headings. Consider using only one H1 as the document title."
|
||||
))
|
||||
|
||||
|
||||
def validate_file(file_path: Path) -> Tuple[Path, List[ValidationError]]:
|
||||
"""Validate a single markdown file."""
|
||||
validator = MarkdownValidator(file_path)
|
||||
errors = validator.validate()
|
||||
return file_path, errors
|
||||
|
||||
|
||||
def validate_directory(dir_path: Path) -> List[Tuple[Path, List[ValidationError]]]:
|
||||
"""Validate all markdown files in a directory."""
|
||||
results = []
|
||||
|
||||
for md_file in dir_path.rglob('*.md'):
|
||||
file_path, errors = validate_file(md_file)
|
||||
if errors:
|
||||
results.append((file_path, errors))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def print_results(results: List[Tuple[Path, List[ValidationError]]]):
|
||||
"""Print validation results."""
|
||||
if not results:
|
||||
print("✓ No validation errors found!")
|
||||
return
|
||||
|
||||
total_errors = sum(len(errors) for _, errors in results)
|
||||
|
||||
print(f"\n{'='*70}")
|
||||
print(f"Found {total_errors} validation error(s) in {len(results)} file(s)")
|
||||
print(f"{'='*70}\n")
|
||||
|
||||
for file_path, errors in results:
|
||||
print(f"\n{file_path}:")
|
||||
print("-" * 70)
|
||||
for error in errors:
|
||||
print(f" {error}")
|
||||
|
||||
print(f"\n{'='*70}")
|
||||
print(f"Total: {total_errors} error(s)")
|
||||
print(f"{'='*70}\n")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point."""
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: python validate_markdown.py <file_or_directory>")
|
||||
sys.exit(1)
|
||||
|
||||
path = Path(sys.argv[1])
|
||||
|
||||
if not path.exists():
|
||||
print(f"Error: Path does not exist: {path}")
|
||||
sys.exit(1)
|
||||
|
||||
results = []
|
||||
|
||||
if path.is_file():
|
||||
if path.suffix == '.md':
|
||||
file_path, errors = validate_file(path)
|
||||
if errors:
|
||||
results.append((file_path, errors))
|
||||
else:
|
||||
print(f"Error: Not a markdown file: {path}")
|
||||
sys.exit(1)
|
||||
elif path.is_dir():
|
||||
results = validate_directory(path)
|
||||
else:
|
||||
print(f"Error: Invalid path: {path}")
|
||||
sys.exit(1)
|
||||
|
||||
print_results(results)
|
||||
|
||||
# Exit with error code if validation errors found
|
||||
sys.exit(1 if results else 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user