Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .agents/skills/proofread_markdown/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
name: proofread-markdown
description: Proofreads Markdown files against Google guidelines.
---

# Proofreading Markdown

## Overview

Help us transform technical text into clear, concise,
and machine-readable Markdown. We follow the
Google Developer Documentation Style Guide.

## Workflow

### 1. Check line length

- [ ] Wrap lines semantically and keep them generally under 80 characters using
[scripts/wrap_lines.dart](scripts/wrap_lines.dart)
- [ ] Verify that the file was wrapped correctly, preserving headings and
code blocks

### 2. Fix voice and tone

- [ ] Use active voice.
- [ ] Use present tense.
- [ ] Use second person ("you"). No "we".

### 3. Check word choice

- [ ] Replace forbidden terms: "e.g.", "i.e.", "etc.", "should", "would",
"could".
- [ ] Use Oxford comma and American spelling.

### 4. Check style of headings

- [ ] Use Sentence case for headings.
- If you change a heading, add an id after the heading like this:
"## Configure the project {: #project-configuration }"
- [ ] Put a blank line after all headings.

### 5. Check style of lists

- [ ] Numbered lists MUST use `1.` for every item to allow easy reordering.
- [ ] How-to sections must have active voice in headings.
- No: "## Project Configuration"
- Yes: "## Configure the project"

### 6. Use less words in sections with steps

- [ ] Ask the user if they would like the steps to be more concise.
If yes, update the steps to be brief. Keep it short, simple, and
accurate.
128 changes: 128 additions & 0 deletions .agents/skills/proofread_markdown/scripts/wrap_lines.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import 'dart:io';
Comment thread
antfitch marked this conversation as resolved.

/// A script to wrap markdown lines at 80 columns, preserving headings and code blocks.
void main(List<String> arguments) {
if (arguments.isEmpty) {
print('Usage: dart wrap_lines.dart <file_path>');
exit(1);
}

final filePath = arguments[0];
final file = File(filePath);

if (!file.existsSync()) {
print('File not found: $filePath');
exit(1);
}

final content = file.readAsStringSync();
final wrappedContent = wrapMarkdown(content);
file.writeAsStringSync(wrappedContent);

print('Successfully wrapped markdown for $filePath');
}

String wrapMarkdown(String content, {int width = 80}) {
final lines = content.split('\n');
final output = <String>[];
bool inCodeBlock = false;

for (final line in lines) {
final stripped = line.trim();

// Handle code blocks
if (stripped.startsWith('```') || stripped.startsWith('~~~')) {
inCodeBlock = !inCodeBlock;
output.add(line);
continue;
}

if (inCodeBlock) {
output.add(line);
continue;
}

// Handle headings
if (stripped.startsWith('#')) {
output.add(line);
continue;
}

// Handle empty lines
if (stripped.isEmpty) {
output.add('');
continue;
}

// Handle lists or quotes (matching python script's simple approach)
if (stripped.startsWith('-') ||
stripped.startsWith('*') ||
RegExp(r'^\d+\.').hasMatch(stripped)) {
output.addAll(wrapText(line, width));
continue;
}

// Normal text paragraph
output.addAll(wrapText(line, width));
}

return output.join('\n');
}

List<String> wrapText(String text, int width) {
final leadingSpace = RegExp(r'^\s*').stringMatch(text) ?? '';
final content = text.trim();

if (content.isEmpty) return [leadingSpace];

// Split by spaces that follow punctuation (.,;:!?)
// We use a lookbehind to keep the punctuation with the preceding chunk.
final chunks = content.split(RegExp(r'(?<=[.,;:!?])\s+'));
final lines = <String>[];
var currentLine = leadingSpace;

for (final chunk in chunks) {
// If the chunk itself is longer than width, fallback to word wrapping for this chunk
if (chunk.length > width) {
// Flush current line if not empty
if (currentLine != leadingSpace) {
lines.add(currentLine);
currentLine = leadingSpace;
}

// Word wrap the chunk
final words = chunk.split(RegExp(r'\s+'));
for (final word in words) {
final space = currentLine == leadingSpace ? '' : ' ';
if ((currentLine.length + space.length + word.length) > width) {
if (currentLine != leadingSpace) {
lines.add(currentLine);
currentLine = leadingSpace + word;
} else {
lines.add(leadingSpace + word);
currentLine = leadingSpace;
}
} else {
currentLine += space + word;
}
}
continue;
}

final space = currentLine == leadingSpace ? '' : ' ';
if ((currentLine.length + space.length + chunk.length) > width) {
if (currentLine != leadingSpace) {
lines.add(currentLine);
}
currentLine = leadingSpace + chunk;
} else {
currentLine += space + chunk;
}
}

if (currentLine != leadingSpace) {
lines.add(currentLine);
}

return lines;
}
Comment thread
antfitch marked this conversation as resolved.
Loading