Enhance documentation for task export plugin with detailed implementation guidelines and cross-platform support information

This commit is contained in:
Raoul Jacobs 2025-11-14 12:01:11 +01:00
parent 1ad834e2ca
commit 6bccfa7c4e
2 changed files with 201 additions and 48 deletions

View file

@ -6,6 +6,21 @@ Create an Obsidian plugin that extracts outstanding tasks from Markdown files an
This iteration builds upon Iteration 1 (C# Console App) by integrating the task export functionality directly into Obsidian as a plugin, providing on-demand and automatic export capabilities.
**Related Repository**: [markdown-task-export](https://github.com/tailormade-eu/markdown-task-export) - C# Console Application (Iteration 1)
**⚠️ IMPORTANT FOR IMPLEMENTATION:**
The C# console application is a **fully working reference implementation** with:
- ✅ Complete task extraction logic (`MarkdownParser.cs`)
- ✅ Hierarchical header parsing with unlimited depth
- ✅ CSV generation with compression support (`CsvExporter.cs`)
- ✅ Customer/Project name extraction (`TaskExtractor.cs`)
- ✅ All edge cases handled (nested tasks, special characters, escaping)
**Use the C# code as a reference** for implementing the TypeScript plugin. The logic should be **identical**, just ported to TypeScript/Obsidian API.
**📋 Detailed Specifications:**
See `docs/REQUIREMENTS.md` for comprehensive technical requirements, API usage, cross-platform considerations, and project structure.
## Requirements
### 1. Plugin Features
@ -39,11 +54,13 @@ Find all unchecked tasks marked with `- [ ]` (checkbox syntax in markdown)
### 5. CSV Output Format (Same as Iteration 1)
- Header row: `CustomerName,ProjectName,Header1,Header2,Header3,Task`
- **Only include header columns that have values** (no empty trailing commas)
- If Header2 doesn't exist, row should be: `CustomerName,ProjectName,Header1,Task` (skip empty Header2 and Header3 columns)
- Header row: `CustomerName,ProjectName,Level1,Level2,Level3,...,Task`
- **Dynamic columns**: Automatically adapts to maximum header depth
- **Compression mode**: Optional removal of empty hierarchy columns (--compress-levels equivalent)
- **Header control**: Option to include or exclude CSV header row
- Handle commas within task text by properly escaping with quotes
- Handle quotes within task text by doubling them
- UTF-8 with BOM encoding for Excel compatibility
### 6. Output File
@ -60,12 +77,15 @@ Create `outstanding_tasks.csv` in the configurable location (default: vault root
```typescript
interface TaskExportSettings {
outputPath: string; // Path for CSV output
outputPath: string; // Path for CSV output (relative to vault)
customersFolder: string; // Root folder for customer files
autoExport: boolean; // Enable automatic export
exportOnSave: boolean; // Export when files are saved
exportOnModify: boolean; // Export when files are modified
showNotifications: boolean; // Show notifications on export
compressLevels: boolean; // Compress empty levels (like --compress-levels)
includeHeader: boolean; // Include CSV header row (like --no-header)
debounceDelay: number; // Debounce delay in seconds (1-30)
}
```
@ -85,24 +105,64 @@ interface TaskExportSettings {
## Technical Details
- Use **TypeScript** with Obsidian API
### Cross-Platform Support
**Platform Compatibility:**
- ✅ Windows, macOS, Linux (desktop)
- ✅ Android, iOS (mobile)
- ✅ Web version
- **One codebase works everywhere** - Obsidian uses web technologies on all platforms
**Technology Stack:**
- **TypeScript** - Primary language
- **Obsidian Plugin API** - Use exclusively for file operations
- **Node.js** - Development only (not required by users)
- **esbuild** - Fast bundling
**Important API Usage:**
- ✅ Use `this.app.vault.adapter.write()` for file operations
- ✅ Use `this.app.vault.adapter.read()` for reading files
- ✅ Use `normalizePath()` for cross-platform path handling
- ❌ Avoid Node.js modules (`fs`, `path`, `os`) - desktop only
- ❌ Never use absolute paths outside vault on mobile
**Platform Detection:**
```typescript
if (Platform.isMobile) {
// Mobile: limit to vault directory
} else {
// Desktop: allow custom paths
}
```
### Best Practices
- Follow Obsidian plugin development best practices
- Use `obsidian` module for API access
- Properly handle file system operations through Obsidian's API
- Properly handle file system operations through Obsidian's API only
- Implement proper error handling and logging
- Add progress indicators for large exports
- Test on multiple platforms before release
## Plugin Structure
```
task-export-plugin/
├── main.ts // Plugin entry point
├── settings.ts // Settings interface and tab
├── export.ts // Core export logic
├── parser.ts // Markdown parsing logic
├── csv-writer.ts // CSV generation
├── manifest.json // Plugin manifest
└── styles.css // Optional styling
obsidian-task-export-plugin/
├── src/
│ ├── main.ts // Plugin entry point
│ ├── settings.ts // Settings interface and tab
│ ├── exporter.ts // Core export logic
│ ├── parser.ts // Markdown parsing logic
│ ├── csv-writer.ts // CSV generation
│ ├── file-watcher.ts // File monitoring
│ └── types.ts // TypeScript interfaces
├── manifest.json // Plugin metadata
├── versions.json // Version compatibility
├── package.json // Dependencies
├── tsconfig.json // TypeScript config
├── esbuild.config.mjs // Build configuration
├── styles.css // Optional styling
├── README.md
└── LICENSE
```
## Example User Workflows

View file

@ -6,6 +6,17 @@ Automatically export outstanding tasks from Obsidian vault to CSV for ManicTime
An Obsidian plugin that integrates task export functionality directly into Obsidian, providing both on-demand and automatic export capabilities with a native user experience.
**Related Repository**: [markdown-task-export](https://github.com/tailormade-eu/markdown-task-export) - C# Console Application (Iteration 1)
**⚠️ REFERENCE IMPLEMENTATION:**
This plugin is a **port of the working C# console application**. Use the C# codebase as a reference:
- `src/MarkdownParser.cs` - Complete parsing logic with all edge cases
- `src/CsvExporter.cs` - CSV generation with compression and header control
- `src/TaskExtractor.cs` - Customer/Project extraction and file enumeration
- `src/Models/TaskItem.cs` - Data structure for tasks
The TypeScript implementation should produce **identical CSV output** to the C# version.
## Functional Requirements
### 1. Plugin Integration
@ -61,10 +72,18 @@ An Obsidian plugin that integrates task export functionality directly into Obsid
- Multi-line task descriptions
**Parsing Logic**
- Use same extraction rules as console app
- Extract hierarchical headers (##, ###, ####)
- Use same extraction rules as console app (reference: `MarkdownParser.cs`)
- Extract hierarchical headers (##, ###, ####, etc.) - unlimited depth
- Associate tasks with parent headers
- Handle nested task patterns
- Preserve hierarchy when parent tasks have sub-tasks
**Key Parsing Details from C# Implementation:**
- Headers start at `##` (H2), `#` (H1) is ignored
- Empty header levels are tracked to preserve structure
- Parent tasks (tasks with sub-tasks) become additional header levels
- Indentation-based nesting detection
- Skip tasks with checkmark emojis in the text
### 4. Export Functionality
@ -101,6 +120,8 @@ interface TaskExportSettings {
exportOnSave: boolean; // Trigger on file save
exportOnModify: boolean; // Trigger on file modify
showNotifications: boolean; // Show export notifications
compressLevels: boolean; // Remove empty hierarchy columns
includeHeader: boolean; // Include CSV header row
debounceDelay: number; // Debounce delay in seconds (1-30)
}
```
@ -112,6 +133,8 @@ interface TaskExportSettings {
- exportOnSave: `true`
- exportOnModify: `false`
- showNotifications: `true`
- compressLevels: `false`
- includeHeader: `true`
- debounceDelay: `3`
**Settings Persistence**
@ -123,16 +146,26 @@ interface TaskExportSettings {
### 6. CSV Output (Same as Console App)
**Format**
- Header: `CustomerName,ProjectName,Header1,Header2,Header3,Task`
- Dynamic columns (no empty trailing commas)
- Proper CSV escaping
- UTF-8 with BOM
- Header: `CustomerName,ProjectName,Level1,Level2,Level3,...,Task`
- **Dynamic columns**: Unlimited depth support (Level1, Level2, Level3, etc.)
- **Compression mode**: Optional `compressLevels` setting to remove empty columns
- When enabled: Each row only outputs non-empty levels (no padding)
- When disabled: All rows padded to maximum depth with empty columns
- **Header control**: Optional `includeHeader` setting to exclude header row
- Proper CSV escaping (commas, quotes, newlines)
- UTF-8 with BOM encoding for Excel compatibility
**CSV Escaping Rules (from C# implementation):**
- Wrap in quotes if field contains: comma, quote, newline, or carriage return
- Double any quotes inside the field: `"` becomes `""`
- Example: `Task with "quotes"` becomes `"Task with ""quotes"""`
**File Writing**
- Use Obsidian's `vault.adapter.write()` API
- Atomic write (write to temp, then rename)
- Use Obsidian's `vault.adapter.write()` API (cross-platform compatible)
- Atomic write (write to temp, then rename) - optional for reliability
- Handle write failures gracefully
- Output path relative to vault root
- Output path relative to vault root (mobile-friendly)
- Support absolute paths on desktop only
### 7. Error Handling
@ -176,16 +209,26 @@ interface TaskExportSettings {
**Obsidian Version**
- Minimum: Obsidian 1.0.0
- Tested on latest stable release
- API compatibility with mobile (future consideration)
- Full API compatibility across all platforms
**Operating Systems**
- Windows 10/11
- macOS 11+
- Linux (major distributions)
**Platforms (Cross-Platform Support)**
- ✅ Windows 10/11
- ✅ macOS 11+
- ✅ Linux (major distributions)
- ✅ Android 8.0+
- ✅ iOS 13+
- ✅ Web version
- **One codebase works on all platforms**
**Platform-Specific Considerations:**
- Desktop: Full file system access (can save CSV outside vault)
- Mobile: Limited to vault directory only
- Use Obsidian's Vault API exclusively (not Node.js `fs` module)
- Detect platform with `Platform.isMobile`, `Platform.isDesktop`
**Vault Types**
- Local vaults
- Synced vaults (Dropbox, OneDrive, etc.)
- Synced vaults (Dropbox, OneDrive, iCloud, etc.)
- Git-based vaults
### Usability
@ -221,40 +264,83 @@ interface TaskExportSettings {
### Technology Stack
**Development Environment**
- **Visual Studio Code** - Primary IDE
- **Microsoft Stack** - Preferred tooling where applicable
- **Extensions**:
- ESLint - Code quality
- Prettier - Code formatting
- TypeScript - Language support
- Obsidian Plugin Dev Tools (if available)
**Required**
- TypeScript 4.0+
- Obsidian Plugin API (latest)
- Node.js 16+ (development only)
- Rollup (bundling)
- Node.js 16+ (development only, not needed by users)
- esbuild (fast bundling, replaces Rollup)
**Cross-Platform Compatibility**
- ✅ Use Obsidian's Vault API exclusively
- ✅ Use `normalizePath()` for path handling
- ✅ Use `app.vault.adapter.read()` for file reading
- ✅ Use `app.vault.adapter.write()` for file writing
- ❌ Avoid Node.js modules: `fs`, `path`, `os` (desktop-only)
- ❌ Never use absolute paths outside vault on mobile
**API Examples:**
```typescript
// ✅ Good - cross-platform
const content = await this.app.vault.adapter.read(filePath);
await this.app.vault.adapter.write(outputPath, csvContent);
const normalized = normalizePath(userPath);
// ❌ Bad - desktop only
import * as fs from 'fs';
fs.readFileSync(filePath);
```
**Optional Libraries**
- None required (use vanilla TypeScript/Obsidian API)
- Consider: `csv-stringify` for robust CSV generation
- Consider: Built-in CSV generation (no external dependencies)
### Project Structure
**Directory Layout:**
```
obsidian-task-export-plugin/
├── src/
│ ├── main.ts # Plugin entry, command registration
│ ├── settings.ts # Settings interface and tab
│ ├── exporter.ts # Core export logic
│ ├── parser.ts # Markdown parsing
│ ├── csv-writer.ts # CSV generation
│ ├── file-watcher.ts # File monitoring and debouncing
│ └── types.ts # TypeScript interfaces
obsidian-task-export-plugin/ ← Repository root
├── .vscode/ ← VS Code settings
│ ├── settings.json
│ └── extensions.json
├── src/ ← All source code here
│ ├── main.ts # Plugin entry, command registration
│ ├── settings.ts # Settings interface and tab
│ ├── exporter.ts # Core export logic
│ ├── parser.ts # Markdown parsing
│ ├── csv-writer.ts # CSV generation
│ ├── file-watcher.ts # File monitoring and debouncing
│ └── types.ts # TypeScript interfaces
├── tests/
│ ├── exporter.test.ts
│ ├── parser.test.ts
│ └── fixtures/ # Test markdown files
├── manifest.json # Plugin metadata
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
├── rollup.config.js # Build configuration
│ └── fixtures/ # Test markdown files
├── manifest.json ← Plugin metadata (root level)
├── versions.json ← Version compatibility (root level)
├── package.json ← Dependencies (root level)
├── tsconfig.json ← TypeScript config (root level)
├── esbuild.config.mjs ← Build configuration (root level)
├── styles.css ← Optional styling (root level)
├── .eslintrc.json ← Linting config
├── .prettierrc ← Formatting config
├── README.md
└── LICENSE
```
**Project Structure Rules:**
- ✅ All source code in `src/` folder
- ✅ Configuration files at root level
- ✅ No solution file needed (TypeScript project, not .NET)
- ✅ Use VS Code workspace for development
### Build System
**Development**
@ -273,6 +359,8 @@ npm test # Run unit tests
npm run test:coverage # Generate coverage report
```
**Build Tool**: esbuild (fast, modern bundler)
### Plugin Manifest
```json
@ -297,6 +385,7 @@ npm run test:coverage # Generate coverage report
- Registers commands, ribbon icon, status bar
- Manages file watcher lifecycle
- Handles settings loading/saving
- Reference C# `Program.cs` for command-line argument patterns
**TaskExportSettings (settings.ts)**
- Extends `PluginSettingTab`
@ -310,17 +399,21 @@ npm run test:coverage # Generate coverage report
- Calls parser for each file
- Aggregates results
- Writes CSV output
- Reference C# `TaskExtractor.cs` for logic
**MarkdownParser (parser.ts)**
- Parses markdown content
- Extracts headers and tasks
- Maintains hierarchical context
- Returns structured data
- **Port directly from C# `MarkdownParser.cs`** - proven logic with all edge cases
**CsvWriter (csv-writer.ts)**
- Formats data as CSV
- Handles escaping
- Handles escaping (use RFC 4180 standard)
- Writes to file via Obsidian API
- Implements compression mode
- **Port directly from C# `CsvExporter.cs`**
**FileWatcher (file-watcher.ts)**
- Subscribes to file events