mirror of
https://github.com/tailormade-eu/obsidian-task-export-plugin.git
synced 2026-07-22 06:41:42 +00:00
Enhance documentation for task export plugin with detailed implementation guidelines and cross-platform support information
This commit is contained in:
parent
1ad834e2ca
commit
6bccfa7c4e
2 changed files with 201 additions and 48 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue