Created
February 11, 2025 22:26
-
-
Save ColonelBuendia/dcde965405a2426d545209a4b09c7b26 to your computer and use it in GitHub Desktop.
Ferdium userscript to conver markdown to nicelyt formatted html on keypress specifically for fastmail
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = (config, Ferdium) => { | |
// Write your scripts here | |
// ░█▀█░█░█░█▀▀░█▀▄░█░░░█▀█░█░█ | |
// ░█░█░▀▄▀░█▀▀░█▀▄░█░░░█▀█░░█░ | |
// ░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀░▀░░▀░ | |
function createOverlay() { | |
const overlay = document.createElement('div'); | |
overlay.innerHTML = ` | |
<div id="markdown-shortcut-reminder" style=" | |
position: fixed; | |
bottom: 20px; | |
right: 20px; | |
background-color: rgba(0, 0, 0, 0.7); | |
color: white; | |
padding: 8px 12px; | |
border-radius: 4px; | |
font-size: 16px; | |
z-index: 10000; | |
opacity: 0.7; | |
font-family: Arial, sans-serif; | |
cursor: pointer; | |
transition: opacity 0.3s; | |
"> | |
Markdown Selection: Ctrl+Alt+M | |
</div> | |
`; | |
// Add hover effect | |
const reminder = overlay.firstElementChild; | |
reminder.addEventListener('mouseover', () => { | |
reminder.style.opacity = '1'; | |
}); | |
reminder.addEventListener('mouseout', () => { | |
reminder.style.opacity = '0.7'; | |
}); | |
// Add click to hide functionality | |
reminder.addEventListener('click', () => { | |
reminder.style.display = 'none'; | |
}); | |
document.body.appendChild(overlay.firstElementChild); | |
} | |
createOverlay(); | |
// ░█▀▀░█▀█░█▀▄░░ | |
// ░█▀▀░█░█░█░█░░ | |
// ░▀▀▀░▀░▀░▀▀░░░ | |
// ░█▀█░█░█░█▀▀░█▀▄░█░░░█▀█░█░█ | |
// ░█░█░▀▄▀░█▀▀░█▀▄░█░░░█▀█░░█░ | |
// ░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀░▀░░▀░ | |
// ░█▄█░█▀█░█▀▄░█░█░█▀▄░█▀█░█░█░█▀█ | |
// ░█░█░█▀█░█▀▄░█▀▄░█░█░█░█░█▄█░█░█ | |
// ░▀░▀░▀░▀░▀░▀░▀░▀░▀▀░░▀▀▀░▀░▀░▀░▀ | |
function convertToMarkdown(text) { | |
let markdown = text; | |
// Keyboard tags | |
markdown = markdown.replace(/<((?!\/)[^>]+)>/g, '<kbd style="display:inline-block; padding: .1em .2em; text-shadow: 0 1px 0 hsl(0,0%,100%); background-color: hsl(210,8%,90%); color:black;border: 1px solid hsl(210,8%,65%); border-radius: 3px; box-shadow: 0 1px 1px hsla(210,8%,5%,0.15),inset 0 1px 0 0 hsl(0,0%,100%); white-space:nowrap; margin-top:3px; font-size:88%;">$1</kbd>'); | |
// Triple backtick code blocks (more permissive regex) | |
markdown = markdown.replace(/```([\s\S]*?)```/g, (match, p1) => { | |
const code = p1.trim().replace(/</g, '<').replace(/>/g, '>'); | |
return `<pre style="border: 1px solid #EAEAEA; border-radius: 6px; padding: 16px; overflow: auto; font-size: 85%; line-height: 1.45; font-family: Consolas, Inconsolata, Courier, monospace;"><code style="font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre;">${code}</code></pre>`; | |
}); | |
// Headers with CSS | |
markdown = markdown.replace(/^# (.*?)$/gm, (match, p1) => | |
`<h1 style="font-size: 1.75em; color: #d04255; margin: 1.3em 0 1em; padding: 0; font-weight: bold;">${p1.trim()}</h1>` | |
); | |
markdown = markdown.replace(/^## (.*?)$/gm, (match, p1) => | |
`<h2 style="font-size: 1.45em;padding-bottom: .3em;border-bottom: 1px dotted rgba(244, 176, 255, 0.26); color: #9e86c8; margin: 1.3em 0 1em; padding: 0; font-weight: bold;">${p1.trim()}</h2>` | |
); | |
markdown = markdown.replace(/^### (.*?)$/gm, (match, p1) => | |
`<h3 style="font-size: 1.2em; margin: 1.3em 0 1em; padding: 0;color: #a8c373; font-weight: bold;">${p1.trim()}</h3>` | |
); | |
// Single backtick inline code | |
markdown = markdown.replace(/`([^`]+)`/g, (match, p1) => | |
`<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0 0.15em; padding: 0 0.3em; white-space: pre-wrap; border: 1px solid #EAEAEA; color: #d14; border-radius: 3px; display: inline;">${p1.trim()}</code>` | |
); | |
// Bold and Italic with CSS (including underscore support) | |
markdown = markdown.replace(/\*\*\*(.*?)\*\*\*/g, (match, p1) => `<strong><em>${p1.trim()}</em></strong>`); | |
markdown = markdown.replace(/___(?!_)(.*?)___/g, (match, p1) => `<strong><em>${p1.trim()}</em></strong>`); | |
markdown = markdown.replace(/\*\*(.*?)\*\*/g, (match, p1) => `<strong>${p1.trim()}</strong>`); | |
markdown = markdown.replace(/__(?!_)(.*?)__/g, (match, p1) => `<strong>${p1.trim()}</strong>`); | |
markdown = markdown.replace(/\*(.*?)\*/g, (match, p1) => `<em>${p1.trim()}</em>`); | |
markdown = markdown.replace(/_(?!_)(.*?)_/g, (match, p1) => `<em>${p1.trim()}</em>`); | |
// Links with CSS | |
markdown = markdown.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (match, p1, p2) => | |
`<a href="${p2.trim()}" style="color: #4183C4; text-decoration: none;">${p1.trim()}</a>` | |
); | |
// Blockquotes with CSS | |
markdown = markdown.replace(/^> (.*?)$/gm, (match, p1) => | |
`<blockquote style="border-left: 4px solid #DDD; padding: 0 1em; color: #777;">${p1.trim()}</blockquote>` | |
); | |
// Lists with CSS | |
markdown = markdown.replace(/^- (.*?)$/gm, (match, p1) => | |
`<li style="margin: 0.5em 0;">${p1.trim()}</li>` | |
); | |
// Wrap the content in a div with proper styling | |
markdown = `<div style="white-space: pre-wrap;">${markdown.trim()}</div>`; | |
return markdown; | |
} | |
// Function to get selected text and its container | |
function getSelectedText() { | |
if (window.getSelection) { | |
const selection = window.getSelection(); | |
if (selection.rangeCount > 0) { | |
return { | |
text: selection.toString(), | |
range: selection.getRangeAt(0) | |
}; | |
} | |
} | |
return null; | |
} | |
// Function to handle the keyboard shortcut | |
function handleKeyPress(event) { | |
// Check if Ctrl+Alt+M was pressed | |
if (event.ctrlKey && event.altKey && event.key === 'm') { | |
event.preventDefault(); | |
const selection = getSelectedText(); | |
if (selection && selection.text) { | |
const convertedText = convertToMarkdown(selection.text); | |
// Create a new element to hold the converted HTML | |
const tempDiv = document.createElement('div'); | |
tempDiv.innerHTML = convertedText; | |
// Replace the selected content with the converted HTML | |
selection.range.deleteContents(); | |
selection.range.insertNode(tempDiv); | |
// Clean up any empty text nodes | |
tempDiv.normalize(); | |
} | |
} | |
} | |
document.addEventListener('keydown', handleKeyPress); | |
// ░█▀▀░█▀█░█▀▄░░ | |
// ░█▀▀░█░█░█░█░░ | |
// ░▀▀▀░▀░▀░▀▀░░░ | |
// ░█▄█░█▀█░█▀▄░█░█░█▀▄░█▀█░█░█░█▀█ | |
// ░█░█░█▀█░█▀▄░█▀▄░█░█░█░█░█▄█░█░█ | |
// ░▀░▀░▀░▀░▀░▀░▀░▀░▀▀░░▀▀▀░▀░▀░▀░▀ | |
console.log("Hello, World!", config); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment