joplin-publisher
Import markdown documents and mermaid diagrams into Joplin using the Joplin CLI.
What this skill does
# Joplin Publisher Skill
## Purpose
Import markdown documents and mermaid diagrams into Joplin using the Joplin CLI.
## When to Use
- Exporting research to Joplin notebooks
- Creating documentation in Joplin
- Generating diagrams for Joplin knowledge base
- Syncing analysis results to Joplin
## Overview
Joplin uses a database-backed system. Content is imported via the Joplin CLI or API. This skill focuses on CLI-based imports.
## Prerequisites
### Install Joplin CLI
```bash
# Using npm
npm install -g joplin
# Verify installation
joplin version
```
### Configure Joplin CLI
```bash
# Set sync target (if needed)
joplin config sync.target 2 # Filesystem
joplin config sync.2.path /path/to/sync/folder
# Or connect to Joplin Server/Cloud
joplin config sync.target 9
joplin config sync.9.path https://your-joplin-server.com
joplin config sync.9.username your-username
```
## Joplin CLI Commands
### List Notebooks
```bash
joplin ls / # List top-level notebooks
joplin ls /Notebook # List notes in notebook
```
### Create Notebook
```bash
joplin mkbook "Notebook Name"
joplin mkbook "Parent/Child" # Nested notebook
```
### Import Markdown
```bash
# Import single file to notebook
joplin import /path/to/file.md --notebook "Notebook Name"
# Import directory
joplin import /path/to/folder --notebook "Notebook Name"
# Import with format specification
joplin import /path/to/file.md --format md --notebook "Notebook Name"
```
### Create Note Directly
```bash
# Create note from stdin
echo "# Title
Content" | joplin mknote "Note Title" --notebook "Notebook Name"
# Create from file content
cat file.md | joplin mknote "Note Title" --notebook "Notebook Name"
```
## Publishing Workflow
### Step 1: Validate Notebook Exists
```python
import subprocess
def notebook_exists(notebook: str) -> bool:
"""Check if a Joplin notebook exists."""
result = subprocess.run(
["joplin", "ls", "/"],
capture_output=True,
text=True
)
notebooks = result.stdout.strip().split('
')
return notebook in notebooks
def create_notebook_if_missing(notebook: str):
"""Create notebook if it doesn't exist."""
if not notebook_exists(notebook):
subprocess.run(
["joplin", "mkbook", notebook],
check=True
)
```
### Step 2: Prepare Content
```python
def prepare_markdown(
title: str,
content: str,
tags: list = None
) -> str:
"""
Prepare markdown content for Joplin import.
Joplin supports YAML frontmatter for metadata.
"""
lines = [f"# {title}", ""]
if tags:
lines.extend([
"---",
f"tags: {', '.join(tags)}",
"---",
""
])
lines.append(content)
return '
'.join(lines)
```
### Step 3: Write Temporary File
```python
import tempfile
from pathlib import Path
def write_temp_markdown(content: str, filename: str) -> Path:
"""Write content to a temporary markdown file."""
temp_dir = Path(tempfile.mkdtemp())
file_path = temp_dir / f"{filename}.md"
file_path.write_text(content, encoding='utf-8')
return file_path
```
### Step 4: Import to Joplin
```python
def import_to_joplin(
file_path: Path,
notebook: str
) -> bool:
"""Import markdown file to Joplin notebook."""
result = subprocess.run(
[
"joplin", "import",
str(file_path),
"--notebook", notebook
],
capture_output=True,
text=True
)
if result.returncode != 0:
raise JoplinImportError(f"Import failed: {result.stderr}")
return True
```
### Complete Publishing Function
```python
def publish_to_joplin(
notebook: str,
title: str,
content: str,
tags: list = None
) -> bool:
"""
Publish markdown content to a Joplin notebook.
Args:
notebook: Target notebook name
title: Note title
content: Markdown content (can include mermaid)
tags: Optional list of tags
Returns:
True if successful
"""
# Ensure notebook exists
create_notebook_if_missing(notebook)
# Prepare content
full_content = prepare_markdown(title, content, tags)
# Write to temp file
temp_file = write_temp_markdown(full_content, title)
try:
# Import to Joplin
import_to_joplin(temp_file, notebook)
return True
finally:
# Cleanup
temp_file.unlink()
temp_file.parent.rmdir()
```
## Document Formats
### Basic Note
```markdown
# Note Title
Content goes here.
## Section
More content.
```
### Note with Tags
```markdown
# Note Title
Content here.
```
### Note with Mermaid
Joplin supports mermaid diagrams natively in markdown:
```markdown
# System Architecture
```mermaid
flowchart TD
A[Client] --> B[Server]
B --> C[(Database)]
```
## Description
The system consists of...
```
## Notebook Organization
### Flat Structure
```
Notebooks/
├── Research
├── Projects
├── Meetings
└── Archive
```
### Nested Structure
```
Notebooks/
├── Work/
│ ├── Project Alpha
│ └── Project Beta
├── Personal/
│ ├── Notes
│ └── Ideas
└── Archive/
```
Create nested notebooks:
```bash
joplin mkbook "Work"
joplin mkbook "Work/Project Alpha"
```
## Usage Examples
### Publish Research Note
```python
publish_to_joplin(
notebook="Research",
title="API Design Patterns",
content="""
## Overview
Key findings from API design research.
## REST Best Practices
1. Use nouns for resources
2. Use HTTP methods correctly
3. Version your API
## GraphQL Considerations
- Schema-first design
- Query optimization
""",
tags=["api", "research", "design"]
)
```
### Publish Diagram
```python
publish_to_joplin(
notebook="Architecture",
title="System Overview Diagram",
content="""
## Architecture Diagram
```mermaid
flowchart TB
subgraph Frontend
A[Web App]
B[Mobile App]
end
subgraph Backend
C[API Server]
D[Worker]
end
subgraph Data
E[(PostgreSQL)]
F[(Redis)]
end
A --> C
B --> C
C --> E
C --> F
D --> E
```
## Components
| Component | Technology | Purpose |
|-----------|------------|---------|
| Web App | React | User interface |
| API Server | FastAPI | REST API |
| Worker | Celery | Background jobs |
""",
tags=["architecture", "diagram"]
)
```
### Publish Meeting Notes
```python
publish_to_joplin(
notebook="Meetings/2024",
title="Project Sync - Jan 15",
content="""
## Attendees
- Alice
- Bob
- Charlie
## Agenda
1. Sprint review
2. Blockers
3. Next steps
## Notes
### Sprint Review
- Feature X completed
- Bug Y in progress
### Blockers
- Waiting on API access
### Action Items
- [ ] Alice: Follow up on API access
- [ ] Bob: Complete bug fix
- [ ] Charlie: Update documentation
""",
tags=["meeting", "project-alpha"]
)
```
## Batch Import
For importing multiple documents:
```python
def batch_import(
notebook: str,
documents: list[dict]
) -> dict:
"""
Import multiple documents to Joplin.
Args:
notebook: Target notebook
documents: List of {title, content, tags} dicts
Returns:
{success: int, failed: int, errors: list}
"""
results = {"success": 0, "failed": 0, "errors": []}
for doc in documents:
try:
publish_to_joplin(
notebook=notebook,
title=doc["title"],
content=doc["content"],
tags=doc.get("tags", [])
)
results["success"] += 1
except Exception as e:
results["failed"] += 1
results["errors"].append({
"title": doc["title"],
"error": str(e)
})
return results
```
## Error Handling
```python
class JoplinError(Exception):
"""Base exception for Joplin operations."""
pass
class JoplinNotInstalledError(JoplinError):
"""Joplin CLI not found."""
paRelated in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.