silverbulletmd / silverbullet

The knowledge hacker's notebook
https://silverbullet.md
MIT License
2.14k stars 155 forks source link

Bake results of templates and queries #719

Closed Maarrk closed 5 months ago

Maarrk commented 5 months ago

This is an implementation for (#708)

I used the "bake" verb, that's how they call calculating dynamic lights and shadows, and paths to static ones in multiple game dev and 3d graphics programs. But I'm not strongly opinionated on this, can change to "Materialize".

Works: baking any block with a button

Breaks sometimes: baking the entire page - I don't know how to do multiple replacements at once. Normally I'd do them by changing ParseTree, but I don't know how to reuse the widget() functions to be compatible with that. I also tried the approach of parsing the document after every replacement in a for loop, but I was getting the old content most of the time (with the non-baked query still).

Needs a rework: This should work on every code block, for now it's hardcoded for the two built-in plugs. Would there be a way to hook it up more globally? Perhaps by finding CodeWidgetContent on the page? Also the bakeButton function is duplicated between query and template plugs, I don't like it either.

Minor improvements:

zefhemel commented 5 months ago

Man you're on fire. I like it. I'll have closer look at this later. Regarding terminology, I'm not opposed to "bake". I used materialized before since it's a term from databases (materialize views), but bake is maybe more accessible.

Maarrk commented 5 months ago

Even if I find some hacky solution to update the widgets myself, the ranges are still broken after undo.

Not a bug, I just need to know how to parse the page again without refreshing it (that loses edit history)

zefhemel commented 5 months ago

This seems a bit convoluted. What I'd imagine my approach would be, requiring no new syscalls:

When the user clicks a bake button on the widget: find the node at the widget position, renderToText, then pass it to https://github.com/silverbulletmd/silverbullet/blob/cf010b5ef29a1dfde166241ae6e6c6dac21d89bf/plug-api/syscalls/code_widget.ts#L4

If this results in content with a markdown property: Then editor.dispatch() the resulting change. If not: error.

For the command that does this for all blocks on a page: find all fenced code blocks with a tree traversal, do the as what I described for each.

Maarrk commented 5 months ago

That is infinitely better solution, thanks @zefhemel! I was figthing the buttons not updating position, and somehow got tunnel vision.

Now that the code is simpler, I added error messages in editor and console make the problem really clear.

Error demonstration

Manually, also on `main`: - Write some simple template, eg. {{ 2 + 2 }} - Write some text immediately preceding the template, and don't enter the template with cursor - Click the edit button Notice that the cursor is moved before the template, instead of to the start, because of the old position passed to button --- With this plug it becomes much easier to run into: - Have a few pages in the space - Paste the content below into an empty page - Keep the cursor outside either Live block - Bake with the button the first template, then the second: - See error notification similar to: `Expected a "CodeText" node at 149 to bake`, check console for more details ```` ## Recent pages ```query page order by lastModified desc limit 15 render [[Library/Core/Query/Page]] ``` ```template {{3 + 3}} ``` ````


The button gets the position here, and doesn't update it until you enter it with the cursor.

https://github.com/silverbulletmd/silverbullet/blob/cf010b5ef29a1dfde166241ae6e6c6dac21d89bf/web/cm_plugins/markdown_widget.ts#L243-L250

zefhemel commented 5 months ago

Ah I've noticed this happening but could never figure out when and why. Now I think I know it’s because of the equals check in the CM widget I think. I can fix that separately.

Maarrk commented 5 months ago

I can paste the repro independent of baking into a new issue to not lose it, and finish this in a moment then

Maarrk commented 5 months ago

I think it's ready now:

zefhemel commented 5 months ago

Very nice, thanks!

Maarrk commented 5 months ago

A few closing comments: