Mathematical expressions

Hello, Zef!
I have tried many note-taking apps.
Yours is most close to Logseq.
I’m impressed by how you decided The Problem of Sync: if it needs to look note from a smart kettle, so use app that is on every kettle - browser.
So I’m now really interested in moving my flow to here.
Part of my notes made by the lectures of technical subjects and include math in KaTeX expressions ($ A = B + C $)

My question is “Can I use math rendering in SilverBullet?”

Yes you can!

3 Likes

This is great! I’m coming from logseq too (or strongly considering it). Is there any way to do this kind of math/katex rendering inline? I’d be willing to work on it. Maybe using MathJax?

Are you asking for this?

Technically it would be possible to do this, but it would requiring the SilverBullet parser itself. It cannot be done from a plug. If anybody wants to attempt this, that’d be great. I have little current interest this myself, because I don’t use any type of formula in my daily life :wink:

Yes, that’s exactly my use case. I see the concerns regarding plain $ ... $; it’s an issue with other similar tools as well. Parsers are hard! :slight_smile:

Hi all

I’d like to come back to this topic since now SB v2 is here and the plugin ‘silverbullet-katex’ has been developed for v1:

I wonder how this can easily(?) be made available for v2?

Kind regards, Pascal

Should be really easy. I can make a quick PR later, it‘s just the settings part that changed

2 Likes

Have you tested it? I just saw there is a polyfill for the old api, so it should still work fine

Hi,

no I didn’t test it, I do not know how that should be done. There is no Plugs: add command anymore and the settings for the plugin should go to ‘SETTINGS’ in yaml format, but this file also is deprecated.

You can see how plugs are installed now here. You just have to do a system reload and run the plug update command afterwards.

1 Like

Created a PR

1 Like

Thanks a lot, it worked. Thanks for your support :folded_hands:

I am a physics student, and the fact that SilverBullet does not support in-line math does not trouble me much because my solution is to simply write my note in LaTeX and put the LaTeX project folder into my SilverBullet space.

Within this setup I can easily link to (via wiki-link) or embed (via ![]() syntax) my notes. Many LaTeX packages aren’t supported by browser-based renderers anyway (e.g. the physics package that I use extremely frequently)!

I wrote a very simple Lua function that gives me the path to PDF files. In my SB space there is a folder tex-notes where each project note is developed inside SB-space/tex-notes/note. Given this structure, the following function

function pdfPath(pdfName)
  pathLink = "[[tex-notes/"..pdfName.."/"..pdfName..".pdf]]"
  return pathLink
end

maps the title of my note pdfName to the wiki-link to the file, i.e. ${pdfPath(name)} produces a wiki-link to the desired note SB-space/tex-notes/name/name.pdf.

For example, you can check out second quantization.

I also think this is a quite universal work-around, e.g. if you have a Jupyter notebook or Pluto notebook or Quarto-flavoured markdown, instead of requiring SilverBullet to be able to render all of these, all one has to do is to link to the PDF version of these formats, which can be done very easily.

1 Like

Ok this is pretty insane. I have to say I have written most of the code in the katex plug, so I know how the library works and all, but still … It took me 10 minutes to write this (and this includes two slash commands for easier use) very tiny space lua and look what’s possible.

Space Lua
latex = {
  header = [[<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css">]],
  katex = js.import("https://cdn.jsdelivr.net/npm/[email protected]/+esm")
}

function latex.inline(expression)  
  local html = latex.katex.renderToString(expression, {
    trust = true,
    throwOnError = false,
    displayMode = false
  })
  
  return widget.new {
    html = "<span>" + latex.header + html + "</span>"
  }
end

function latex.block(expression)
  local html = latex.katex.renderToString(expression, {
    trust = true,
    throwOnError = false,
    displayMode = true
  })
  
  return widget.new {
    html = "<span>" + latex.header + html + "</span>"
  }
end 

slashcommand.define {
  name = "math",
  run = function()
    editor.insertAtCursor("${latex.inline[[]]}", false, true)
    editor.moveCursor(editor.getCursor() - 3)
  end
}

slashcommand.define {
  name = "equation",
  run = function()
    editor.insertAtCursor("${latex.block[[]]}", false, true)
    editor.moveCursor(editor.getCursor() - 3)
  end
}
Space Style
.sb-lua-directive-inline:has(.katex-html) {
  border: none !important;
}

Code for the image
If ${latex.inline[[S]]} is a set, ${latex.inline[[\circ]]} is a binary operation on ${latex.inline[[S]]}, and ${latex.inline[[e \in S]]}, then ${latex.inline[[G = (S, e, \circ)]]} is called a *group* if

1. ${latex.inline[[\forall a, b \in G, \quad a \circ \ b \in G]]} (completeness);
2. ${latex.inline[[(ab)c = a(bc), \quad \forall a,b,c \in S]]} (associativity);
3. ${latex.inline[[\exists e \in S]]} such that ${latex.inline[[ae=a=ea, \quad \forall a \in S]]} (identity);
4. ${latex.inline[[\forall a \in S, \quad \exists b \in S]]} such that ${latex.inline[[ab=e=ba]]} (inverse).

The Fourier transform of a complex-valued (Lebesgue) integrable function ${latex.inline[[f(x)]]} on the real line, is the complex valued function ${latex.inline[[\hat {f}(\xi )]]}, defined by the integral
${latex.block[[\widehat{f}(\xi) = \int_{-\infty}^{\infty} f(x)\ e^{-i 2\pi \xi x}\,dx, \quad \forall \xi \in \mathbb{R}.]]}

It’s actually insane what’s possible. Only thing that bugs me here is that it (afaik) won’t work offline because the cdn resources aren’t cached. Open to ideas on this one, dependencies always have kind of been a struggle with SB.

(This really makes the katex plug obsolete @zef)

4 Likes

Loving it @MrMugame

Shouldn’t it be possible to place the files to includes somewhere within the space directory and link to it?
However, the caching argument would most probably be true, also…