I have a home server and I was looking for an application to take notes. As you know, Obsidian is not the ideal choice, especially since I use Docker on my home server. While discussing with ChatGPT, it suggested I use SilverBullet, which turned out to be a very suitable option, particularly with its feature of saving notes as files on the device, and its simple interface that allows writing immediately without much configuration.
However, the problem I faced when writing was Arabic, as it is written from right to left, unlike English, and similar issues occur with other languages like Persian, Urdu, and Hebrew. I tried to develop a plugin to solve this problem, but my attempts were unsuccessful due to my limited experience.
I would like an explanation or method to convert my code into a SilverBullet plugin, even though the JavaScript code works perfectly in the browser:
// RTL fix with English line detection
(function(): void {
const id: string = 'rtl-fix';
if (document.getElementById(id)) return;
const css: string = `
@import url('https://fonts.googleapis.com/css2?family=Noto+Naskh+Arabic:[email protected]&family=Readex+Pro:[email protected]&display=swap');
.cm-editor, .cm-scroller, .cm-content, .cm-line, .rendered-markdown, .page-content {
direction: rtl !important;
text-align: right !important;
font-family: "Noto Naskh Arabic", "Readex Pro", sans-serif !important;
font-optical-sizing: auto !important;
font-variation-settings: "HEXP" 0 !important;
}
.cm-line::before, .rendered-markdown p::before, .rendered-markdown li::before {
content: "\\200F"; width: 0; height: 0;
}
.cm-line.ltr-line, .rendered-markdown p.ltr-line {
direction: ltr !important; text-align: left !important;
}
.cm-line.ltr-line::before, .rendered-markdown p.ltr-line::before { content: none !important; }
pre, code, table, .cm-inline-code { direction: ltr !important; text-align: left !important; }
`;
const s: HTMLStyleElement = document.createElement('style');
s.id = id;
s.textContent = css;
document.head.appendChild(s);
document.querySelectorAll('.cm-editor, .sb-editor, .rendered-markdown, .page-content')
.forEach((el: Element) => el.setAttribute('dir', 'rtl'));
const isEng = (txt: string): boolean => {
const clean: string = txt.replace(/[\s\d\p{P}\p{S}]/gu, '');
return clean && !/[\u0600-\u06FF\u0750-\u077F]/.test(clean);
};
const detect = (): void => {
document.querySelectorAll('.cm-line, .rendered-markdown p').forEach((el: Element) => {
isEng(el.textContent || '') ? el.classList.add('ltr-line') : el.classList.remove('ltr-line');
});
};
detect();
new MutationObserver(detect).observe(document.body, { childList: true, subtree: true, characterData: true });
})();