swarnam-obsidian/main.ts

142 lines
3.2 KiB
TypeScript
Raw Normal View History

2024-04-04 21:39:27 +00:00
import { Plugin } from "obsidian";
const PREFIX = "swarnam";
function base64ToBytes(base64: string) {
const binString = atob(base64);
// @ts-expect-error
return Uint8Array.from(binString, (m) => m.codePointAt(0));
2022-04-15 18:13:31 +00:00
}
2024-04-04 21:39:27 +00:00
function bytesToBase64(bytes: Uint8Array) {
const binString = Array.from(bytes, (byte) =>
String.fromCodePoint(byte)
).join("");
return btoa(binString);
}
2022-04-15 18:13:31 +00:00
2024-04-04 21:39:27 +00:00
function asBase64(text: string) {
const b64 = bytesToBase64(new TextEncoder().encode(text));
return b64;
}
2022-04-15 18:13:31 +00:00
2024-04-04 21:39:27 +00:00
function getIframeDoc(htmlSource: string, cssSource: string, jsSource: string) {
const isDarkMode = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
return `
<style>
body { font-family: sans-serif; color: ${isDarkMode ? "#fff" : "#000"} }
</style>
<style>
${cssSource}
</style>
2024-04-04 22:03:36 +00:00
<div class="${PREFIX}-html-container">
2024-04-04 21:39:27 +00:00
${htmlSource}
</div>
<script>
${jsSource}
</script>
`;
}
function showError(msg: string, root: HTMLElement) {
root.classList.add("error");
root.createEl("p", { cls: "icon", text: "⚠️" });
root.createEl("p", { text: msg });
2022-04-15 18:13:31 +00:00
}
2024-04-04 21:39:27 +00:00
export default class SwarnamPlugin extends Plugin {
async onload() {
this.registerMarkdownCodeBlockProcessor(
"swarnam",
(source, el, ctx) => {
2024-04-04 22:03:36 +00:00
const root = el.createDiv({ cls: `${PREFIX}-root` });
2024-04-04 21:39:27 +00:00
let [
htmlSource = "",
cssSource = "",
jsSource = "",
// eslint-disable-next-line prefer-const
...others
] = source.split(/^\s*---\*---\s*$/m);
if (others.length > 0) {
showError(
"Swarnam only supports HTML, CSS and JS blocks but your snippet has more than 3 blocks.",
root
);
return;
}
2022-04-15 18:13:31 +00:00
2024-04-04 21:39:27 +00:00
htmlSource = htmlSource.trim();
cssSource = cssSource.trim();
jsSource = jsSource.trim();
2022-04-15 18:13:31 +00:00
2024-04-04 21:39:27 +00:00
if (!htmlSource) {
showError(
"A Swarnam block must at least contain HTML",
root
);
return;
}
const sourceRoot = root.createDiv({
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-source-root`,
2024-04-04 21:39:27 +00:00
});
const htmlContainer = sourceRoot.createDiv({
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-source-container`,
2024-04-04 21:39:27 +00:00
});
const htmlEl = htmlContainer.createEl("pre", {
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-source ${PREFIX}-html-source`,
2024-04-04 21:39:27 +00:00
});
htmlContainer.createDiv({
text: "HTML",
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-badge ${PREFIX}-html-badge`,
2024-04-04 21:39:27 +00:00
});
htmlEl.setText(htmlSource);
if (cssSource) {
const cssContainer = sourceRoot.createDiv({
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-source-container`,
2024-04-04 21:39:27 +00:00
});
const cssEl = cssContainer.createEl("pre", {
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-source ${PREFIX}-css-source`,
2024-04-04 21:39:27 +00:00
});
cssContainer.createDiv({
text: "CSS",
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-badge ${PREFIX}-css-badge`,
2024-04-04 21:39:27 +00:00
});
cssEl.setText(cssSource);
}
if (jsSource) {
const jsContainer = sourceRoot.createDiv({
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-source-container`,
2024-04-04 21:39:27 +00:00
});
const jsEl = jsContainer.createEl("pre", {
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-source ${PREFIX}-js-source`,
2024-04-04 21:39:27 +00:00
});
jsContainer.createDiv({
text: "JS",
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-badge ${PREFIX}-js-badge`,
2024-04-04 21:39:27 +00:00
});
jsEl.setText(jsSource);
}
const iframeEl = root.createEl("iframe", {
2024-04-04 22:03:36 +00:00
cls: `${PREFIX}-preview`,
2024-04-04 21:39:27 +00:00
});
iframeEl.src = `data:text/html;base64;charset=UTF-8,${asBase64(
getIframeDoc(htmlSource, cssSource, jsSource)
)}`;
}
);
2022-04-15 18:13:31 +00:00
}
}