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;
%>
@GitMurf
Copy link
Author

GitMurf commented Feb 12, 2022

Ok updated to add the following:

  • Headers
  • Bold markdown
  • Italics markdown
  • Highlight markdown
  • Inline code markdown
  • Strikethrough text markdown
  • Code blocks

cc @dcoales

BEFORE

image

AFTER

image

@GitMurf
Copy link
Author

GitMurf commented Feb 12, 2022

@dcoales when you have a chance please test and see if it is handling headers like you had hoped? Thanks!

@dcoales
Copy link

dcoales commented Feb 12, 2022

That's much better thank you.

I'm creating italics using foo but this is coming through unchanged i.e. not in italics. Am I doing it wrong.

I also added Google which came through as www.google.co.uk but wasn't clickable. Is there any chance of making this a clickable link. Sorry to be a pain :-)

Out of interest I checked out the plugin CopyToHtml which does create a clickable link using the the alias - but doesn't generate highlighted text properly so your script has the edge :-)

@GitMurf
Copy link
Author

GitMurf commented Feb 13, 2022

@dcoales can you please show a screenshot of both? The link thing I am literally just pasting the url so am not creating a link at all. It’s just the text. Whatever you paste it into should handle allowing it to be clickable. I’m not doing anything special.

@dcoales
Copy link

dcoales commented Feb 13, 2022

Here is the source text

## Heading 

### Sub Heading

This is some text with _Italilcs using underscore_ plus ==Highlighight== plus *italics using asterisks* plus __bold using underscore__ plus **bold using asterisks** 

This is a link to [Google](www.google.co.uk)

- And here are some bullets
	- And a nested bullet followed by a line separator

---

This renders as shown in the attached screenshot. It looks as though using underscores for bold and italic is the problem. If I use asterisks then it works fine.

With regards to the link - maybe an option to leaving it with the alias format rather than stripping out the part in the round brackets would work ?

image

In obsidian it appears as

image

@GitMurf
Copy link
Author

GitMurf commented Feb 13, 2022

@dcoales please test it now. The following should be implemented:

  • bold using underscores
  • italics using underscores
  • [markdown links](URL) now using HTML style a href element so link should be clickable and with alias still in MS products

Please confirm everything is now working as you hope?

@apoc527
Copy link

apoc527 commented Feb 13, 2022

This is amazing! A couple suggestions:

  • Change double-colons (for in-line DV metadata) to single colons
  • If there are headings in a list, try to apply same styling, else, simply delete the #s

This is SOOOO good.

EDIT:

I just added this and it works:

//Remove double colons
        lnOutput = lnOutput.replace(/::/g, ':')

The second bullet suggestion is beyond my skills.

@apoc527
Copy link

apoc527 commented Feb 13, 2022

A few more suggestions after using it to draft a client email:

  1. Ordered lists!
  2. Support for block quotes

@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