Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save GitMurf/ec35c81003b172ce01044993d9849505 to your computer and use it in GitHub Desktop.
Save GitMurf/ec35c81003b172ce01044993d9849505 to your computer and use it in GitHub Desktop.
<%*
const editor = app.workspace.activeLeaf.view.editor;
if(editor.somethingSelected() === true) {
let selectedText = editor.getSelection();
let splitLines = selectedText.split('\n');
let finalOutput = '';
let listItem = false;
let codeBlock = false;
splitLines.forEach(eachLine => {
let lnOutput = eachLine;
const listMatch = lnOutput.match(/^[ \t]*[\-\*] /);
if(listItem === false) {
if(listMatch) {
listItem = true;
finalOutput = `${finalOutput}<ul>`;
}
} else {
if(!listMatch) {
listItem = false;
finalOutput = `${finalOutput}</ul>`;
}
}
//remove tags
lnOutput = lnOutput.replace(/#[^\s\#]+/g, '');
//replace a [ ] task checkbox
lnOutput = lnOutput.replace(/\[ \]/g, '<span style="background-color: #FFFF00"><strong>ACTION ITEM:</strong></span>');
//Parse out alias from wiki links
lnOutput = lnOutput.replace(/\[\[[^\[\]]+\|([^\[\]]+)\]\]/g, '$1');
//Parse out regular wiki bracket links
lnOutput = lnOutput.replace(/\[\[([^\[\]]+)\]\]/g, '$1');
//Parse out markdown style URLs
lnOutput = lnOutput.replace(/\[([^\[\]]*)\]\(([^ ]+)\)/g, '<a href="$2">$1</a>');
//Bold asterisk
lnOutput = lnOutput.replace(/\*\*([^\*]+)\*\*/g, '<strong>$1</strong>');
//Bold underscore
lnOutput = lnOutput.replace(/\_\_([^\_]+)\_\_/g, '<strong>$1</strong>');
//Italics asterisk
lnOutput = lnOutput.replace(/\*([^\*]+)\*/g, '<em>$1</em>');
//Italics underscore
lnOutput = lnOutput.replace(/\_([^\_]+)\_/g, '<em>$1</em>');
//Highlights
lnOutput = lnOutput.replace(/\=\=([^\=]+)\=\=/g, '<span style="background-color: #FFFF00">$1</span>');
//Strikethrough
lnOutput = lnOutput.replace(/\~\~([^\~]+)\~\~/g, '<strike>$1</strike>');
//Inline code
let backTickChar = "`";
let regExpStr = `${backTickChar}+([^${backTickChar}]+)${backTickChar}+`;
let regReplace = new RegExp(regExpStr, "g");
lnOutput = lnOutput.replace(regReplace, '<code>$1</code>');
//Full code blocks
if(lnOutput.indexOf("```") > -1) {
let backTickChar = "`";
let regExpStr = `${backTickChar}+[^${backTickChar}]*`;
let regReplace = new RegExp(regExpStr, "g");
if(codeBlock === false) {
codeBlock = true;
lnOutput = lnOutput.replace(regReplace, '<code>');
} else {
codeBlock = false;
lnOutput = lnOutput.replace(regReplace, '</code>');
}
}
//HEADERS
//H1
lnOutput = lnOutput.replace(/^\# (.*)/, '<h1>$1</h1>');
//H2
lnOutput = lnOutput.replace(/^\## (.*)/, '<h2>$1</h2>');
//H3
lnOutput = lnOutput.replace(/^\### (.*)/, '<h3>$1</h3>');
//H4
lnOutput = lnOutput.replace(/^\#### (.*)/, '<h4>$1</h4>');
//H5
lnOutput = lnOutput.replace(/^\##### (.*)/, '<h5>$1</h5>');
//H6
lnOutput = lnOutput.replace(/^\###### (.*)/, '<h6>$1</h6>');
//Remove extra whitespace
lnOutput = lnOutput.replace(/(\S)[ ]+/g, '$1 ');
//Formatting for paste into tools like Microsoft Word, OneNote, Outlook to match their bullet styles
lnOutput = lnOutput.replace(/^[\-\*] (.*)/, '<li>$1</li>');
lnOutput = lnOutput.replace(/^( |\t)[\-\*] (.*)/, '<ul><li>$2</li></ul>');
lnOutput = lnOutput.replace(/^( |\t\t)[\-\*] (.*)/, '<ul><ul><li>$2</li></ul></ul>');
lnOutput = lnOutput.replace(/^( |\t\t\t)[\-\*] (.*)/, '<ul><ul><ul><li>$2</li></ul></ul></ul>');
lnOutput = lnOutput.replace(/^( |\t\t\t\t)[\-\*] (.*)/, '<ul><ul><ul><ul><li>$2</li></ul></ul></ul></ul>');
lnOutput = lnOutput.replace(/^( |\t\t\t\t\t)[\-\*] (.*)/, '<ul><ul><ul><ul><ul><li>$2</li></ul></ul></ul></ul></ul>');
if(listItem === false) {
finalOutput = `${finalOutput}<br>${lnOutput}`
} else {
finalOutput = `${finalOutput}${lnOutput}`
}
})
if(listItem === true) {
finalOutput = `${finalOutput}</ul>`;
}
let newString = finalOutput.trim();
newString = newString.replace(/\<\/ul\>(\<br\>)+/g, '</ul>');
newString = newString.replace(/\<\/h([123456])\>(\<br\>)+/g, '</h$1>');
//This was keeping the previous clipboard item in the plaintext of the clipboard
//No longer using this as kind of confusing
//const plainText = await navigator.clipboard.readText();
const plainText = newString;
const blobPlain = new Blob([plainText], { type: "text/plain" });
const blobHtml = new Blob([`${newString}`], { type: "text/html" });
let data = [new ClipboardItem({
[blobPlain.type]: blobPlain,
[blobHtml.type]: blobHtml,
})];
await navigator.clipboard.write(data);
new Notice("Copied the cleaned and formatted text to your Clipboard for pasting into Outlook / Word!", 15000);
new Notice("Make sure you do a regular 'Full' paste and NOT paste as plain text!", 15000);
} else {
new Notice("Doing NOTHING because no text was selected!", 15000);
}
//By doing a return then it will not try to replace the selected text / apply the tR variable
return;
%>
@dcoales
Copy link

dcoales commented Feb 13, 2022

@GitMurf That's perfect for me. Thank you so much for doing this I really appreciate it.

@GitMurf
Copy link
Author

GitMurf commented Feb 14, 2022

@apoc527 i tried block quotes but Word and Outlook weren’t interpreting the html for it so I didn’t add it.

For the ordered lists do you just mean handle numbered lists?

@apoc527
Copy link

apoc527 commented Feb 14, 2022

Yea numbered lists is what I meant. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment