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>');
lnOutput = lnOutput.replace(/\=\=([^\=]+)\=\=/g, '<span style="background-color: #FFFF00">$1</span>');
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>');
lnOutput = lnOutput.replace(/^\# (.*)/, '<h1>$1</h1>');
lnOutput = lnOutput.replace(/^\## (.*)/, '<h2>$1</h2>');
lnOutput = lnOutput.replace(/^\### (.*)/, '<h3>$1</h3>');
lnOutput = lnOutput.replace(/^\#### (.*)/, '<h4>$1</h4>');
lnOutput = lnOutput.replace(/^\##### (.*)/, '<h5>$1</h5>');
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
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](

- 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 ?


In obsidian it appears as


Copy link

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?

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.


I just added this and it works:

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

The second bullet suggestion is beyond my skills.

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

Copy link

dcoales commented Feb 13, 2022

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

Copy link

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?

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