Skip to content

Instantly share code, notes, and snippets.

@olliecheng
Last active September 30, 2024 16:26
Show Gist options
  • Save olliecheng/8a5e434bd97154fba81ea91e79a8c99b to your computer and use it in GitHub Desktop.
Save olliecheng/8a5e434bd97154fba81ea91e79a8c99b to your computer and use it in GitHub Desktop.
Notion - Inline Math for the Desktop App (credit https://www.notion.so/Notion-Hacks-27b92f71afcd4ae2ac9a4d14fef0ce47)
// ==UserScript==
// @name Inline Math for Notion.so
// @homepageURL https://www.notion.so/evertheylen/Notion-Inline-Math-9c5047a4e7c84643848b3630db8d5a5e
// @version 0.2.1
// @match https://www.notion.so/*
// @grant GM_addStyle
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.js
// ==/UserScript==
// Instructions for use:
// - Make sure you have at least one normal math block on your page
// - Use inline code starting with "math:". For example: `math: f(x) = x^2`
// - Press F2 to rerender all inline math. You can of course change the shortcut in the code below.
// - The inline math will revert to inline code when the block becomes active.
const subscript = /_(?!{)(.+?)(?:_|(\^|$| ))/g
const superscript = /\^(?!{)(.+?)(?:\^|(_|$| ))/g
GM_addStyle(`
.notion-frame span .katex {
padding-right: 0 !important;
font-size: 1.3em;
}
`)
function rerender_all(e) {
document.querySelectorAll("body").innerHTML = "";
var code = document.querySelectorAll('span[style*="monospace"]');
code.forEach(function(el) {
if (document.activeElement.contains(el)) {
if (e.key != "F2") {
return;
}
}
var s = el.textContent;
if (s.startsWith("math:")) {
el.style.color = null;
el.style.background = null;
s = s.slice(5).trim();
katex.render(s, el, {throwOnError: true, font: "mathit"});
} else if (s.startsWith(",")) {
el.style.color = null;
el.style.background = null;
s = "\\mathrm{" + s.slice(1).trim() + "}";
var match;
while (match = s.match(subscript)) {
s = s.replace(subscript, "_{$1}$2");
}
while (match = s.match(superscript)) {
s = s.replace(superscript, "^{$1}$2");
}
katex.render(s, el, {throwOnError: true, font: "mathit"});
} else if (s.startsWith("$")) {
el.style.color = null;
el.style.background = null;
s = s.slice(1).trim();
katex.render(s, el, {throwOnError: true, font: "mathit"});
}
});
}
function rerender() {
rerender_all({key: "discard"});
setTimeout(rerender, 500);
}
setTimeout(rerender, 5000);
window.addEventListener("mousedown", rerender_all);
window.addEventListener("keydown", rerender_all, true);
const subscript = /_(?!{)(.+?)(?:_|(\^|$| ))/g
const superscript = /\^(?!{)(.+?)(?:\^|(_|$| ))/g
window.onload = function(e) {
loadJS(
"https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js",
function() {
rerender_all();
},
document.body
);
let customCSS = document.createElement("style");
customCSS.innerHTML = `.notion-frame span .katex {
padding-right: 0 !important;
font-size: 1.3em;
}`;
document.getElementsByTagName("head")[0].appendChild(customCSS);
};
var loadJS = function(url, implementationCode, location) {
//url is URL of external file, implementationCode is the code
//to be called from the file, location is the location to
//insert the <script> element
var scriptTag = document.createElement("script");
scriptTag.src = url;
scriptTag.onload = implementationCode;
scriptTag.onreadystatechange = implementationCode;
location.appendChild(scriptTag);
};
function rerender_all(e) {
document.querySelectorAll("body").innerHTML = "";
var code = document.querySelectorAll('span[style*="monospace"]');
code.forEach(function(el) {
if (document.activeElement.contains(el)) {
if (e.key != "F2") {
return;
}
}
var s = el.textContent;
if (s.startsWith("math:")) {
el.style.color = null;
el.style.background = null;
s = s.slice(5).trim();
katex.render(s, el, {throwOnError: true, font: "mathit"});
} else if (s.startsWith(",")) {
el.style.color = null;
el.style.background = null;
s = "\\mathrm{" + s.slice(1).trim() + "}";
var match;
while (match = s.match(subscript)) {
s = s.replace(subscript, "_{$1}$2");
}
while (match = s.match(superscript)) {
s = s.replace(superscript, "^{$1}$2");
}
katex.render(s, el, {throwOnError: true, font: "mathit"});
} else if (s.startsWith("$")) {
el.style.color = null;
el.style.background = null;
s = s.slice(1).trim();
katex.render(s, el, {throwOnError: true, font: "mathit"});
}
});
}
function rerender() {
rerender_all({key: "discard"});
setTimeout(rerender, 500);
}
setTimeout(rerender, 5000);
window.addEventListener("mousedown", rerender_all);
window.addEventListener("keydown", rerender_all, true);
( cd /Applications/Notion.app/Contents/Resources; asar extract app.asar app )
# cp inlinemath.js /Applications/Notion.app/Contents/Resources/app/renderer/inlinemath.js
# sed -i '' 's/<\/head>/<script src="inlinemath.js"><\/script><\/head>/g' /Applications/Notion.app/Contents/Resources/app/renderer/index.html
echo "\n" >> /Applications/Notion.app/Contents/Resources/app/renderer/preload.js
cat inlinemath.js >> /Applications/Notion.app/Contents/Resources/app/renderer/preload.js
@AxelBremer
Copy link

Hi!

How do I add this to the desktop app when using Windows? Thanks a lot!

@ruochiz
Copy link

ruochiz commented Nov 13, 2019

Hi!

How do I add this to the desktop app when using Windows? Thanks a lot!

I think this is for MacOS, which is implied by the path. To install it, first make sure you have home-brew installed.
Then,

brew install npm
npm install -g asar.

After that, download all three code files upper,

./patcher.sh

Then, you are good to go.

If you run into any permission error, try chmod 777 ./patcher.sh before running it. The usage of these are in: https://www.notion.so/Notion-Inline-Math-9c5047a4e7c84643848b3630db8d5a5e

@AxelBremer
Copy link

Thanks! I'm running Windows though, but we've found the app.asar file in the notion appdata folder and wrote the script to it using node. Still, thanks for replying!

@hsusanoo
Copy link

Thanks! I'm running Windows though, but we've found the app.asar file in the notion Appdata folder and wrote the script to it using node. Still, thanks for replying!

Hi!
How do I do the same thing using node ? I'm able to find app.asar file but no idea how to proceed.

@sqrtpapi2001
Copy link

Excellent improvement to the original script. Great job!

@wtangdev
Copy link

Thanks! I'm running Windows though, but we've found the app.asar file in the notion Appdata folder and wrote the script to it using node. Still, thanks for replying!

Hi!
How do I do the same thing using node ? I'm able to find app.asar file but no idea how to proceed.

Follow rouchiz's instruction step by step, it's really work for me! you can paste the message if you got some error.

@alanzchen
Copy link

alanzchen commented May 24, 2020

When would Notion load files from local? It seems like for me Notion is always using the online app.js. Would it be possible to patch content in app.js?

@olliecheng
Copy link
Author

The desktop Notion app loads file contents from the app.azar. By editing app.azar, we can edit the code which loads the Notion webpage (it's not just a frame around the web app, there's also a little bit of wrapper code). @alanzchen

@davidwud
Copy link

davidwud commented Jun 7, 2020

Can someone please walk me through installing this? I have no idea what to do, thanks.

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