Skip to content

Instantly share code, notes, and snippets.

@yigitkonur
Created December 8, 2025 21:29
Show Gist options
  • Select an option

  • Save yigitkonur/6c010fe14cb8b92c13bbbfe98b4c8795 to your computer and use it in GitHub Desktop.

Select an option

Save yigitkonur/6c010fe14cb8b92c13bbbfe98b4c8795 to your computer and use it in GitHub Desktop.
Raycast script: Clipboard HTML to Markdown converter - converts rich HTML from clipboard to clean Markdown
#!/usr/bin/python3
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title Clipboard HTML to Markdown
# @raycast.mode compact
# Optional parameters:
# @raycast.icon πŸ“‹
# @raycast.packageName Clipboard Tools
# Documentation:
# @raycast.author Yigit Konur
# @raycast.authorURL https://github.com/yigitkonur
# @raycast.description Converts HTML from clipboard to Markdown, like StackEdit does
import sys
import subprocess
import traceback
def get_clipboard_html():
"""Read HTML content from macOS clipboard using native pasteboard."""
try:
from AppKit import NSPasteboard, NSPasteboardTypeHTML
pasteboard = NSPasteboard.generalPasteboard()
html_content = pasteboard.stringForType_(NSPasteboardTypeHTML)
return html_content
except ImportError:
print("❌ Missing dependency: pyobjc-framework-Cocoa")
print("πŸ’‘ Install with: uv pip install --system pyobjc-framework-Cocoa")
sys.exit(1)
def get_clipboard_text():
"""Read plain text from clipboard as fallback."""
try:
from AppKit import NSPasteboard, NSStringPboardType
pasteboard = NSPasteboard.generalPasteboard()
return pasteboard.stringForType_(NSStringPboardType)
except:
# Fallback to pbpaste
try:
result = subprocess.run(['pbpaste'], capture_output=True, text=True)
return result.stdout
except:
return None
def set_clipboard_text(text):
"""Write text to macOS clipboard."""
try:
from AppKit import NSPasteboard, NSStringPboardType
pasteboard = NSPasteboard.generalPasteboard()
pasteboard.clearContents()
pasteboard.setString_forType_(text, NSStringPboardType)
return True
except:
# Fallback to pbcopy
try:
subprocess.run(['pbcopy'], input=text, text=True, check=True)
return True
except:
return False
def html_to_markdown(html):
"""Convert HTML to clean Markdown."""
try:
from markdownify import markdownify as md
except ImportError:
print("❌ Missing dependency: markdownify")
print("πŸ’‘ Install with: uv pip install --system markdownify")
sys.exit(1)
# Configure markdownify for clean output
markdown = md(
html,
heading_style="ATX", # Use # for headings
bullets="-", # Use - for bullets
strip=['script', 'style'], # Remove scripts and styles
escape_asterisks=False,
escape_underscores=False,
)
# Clean up extra whitespace
markdown = '\n'.join(line.rstrip() for line in markdown.split('\n'))
# Remove excessive blank lines
while '\n\n\n' in markdown:
markdown = markdown.replace('\n\n\n', '\n\n')
return markdown.strip()
def main():
"""Main function to convert clipboard HTML to Markdown."""
try:
# Try to get HTML from clipboard
html_content = get_clipboard_html()
if not html_content:
text_content = get_clipboard_text()
if text_content:
print("⚠️ No HTML found, only plain text")
print("πŸ’‘ Copy from browser with links/formatting")
else:
print("❌ Clipboard is empty")
sys.exit(1)
# Convert to Markdown
markdown = html_to_markdown(html_content)
# Copy back to clipboard
if set_clipboard_text(markdown):
# Show brief stats
original_kb = len(html_content) / 1024
markdown_kb = len(markdown) / 1024
if original_kb > 1:
print(f"βœ… Converted to Markdown ({original_kb:.1f}KB β†’ {markdown_kb:.1f}KB)")
else:
print(f"βœ… Converted to Markdown ({len(markdown)} chars)")
else:
print("❌ Failed to copy to clipboard")
sys.exit(1)
except ImportError as e:
print(f"❌ Missing dependency: {e}")
print("πŸ’‘ Install required packages:")
print(" uv pip install --system pyobjc-framework-Cocoa markdownify")
sys.exit(1)
except Exception as e:
print(f"❌ Error: {e}")
if "--debug" in sys.argv:
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment