Thanks @mentaloid for sticking with this. If Logseq would provide a PortableApp I wouldn’t have to do stuff like this (it’s quie annoying to do this every update - i have updated 0.9.17 to 0.9.17 on this ocasion ).
The good:
I now see the “kits ok” message at Logseq startup;
It is not replaced with the time but rather functions the old way (same as :time "<%time%>" macro would), by updating this time every time i refresh (click on it to see the “{{time}}” text)
definition isn’t applied somehow, maybe the expandmacro function in expandmacro.md is not reached/applied… (is there a js command I can add to this function to show something on screen or whatever just so I can see if it’s actually run? - I tried with adding console.log("Expanding macro: " + macroName); to the function but I get nothing at the Logseq Dev Tools Console…)
The weird thing is that I have the markdown file under /pages (tried even copy/pasting it into the /logseq folder and I get a warning that I already have a page with that name so Logseq clearly finds/sees it). It contains your updated function:
Hmm… copied that function inside custom.js and all works ok
It somehow finds the /pages/expandmacro.md because, if I remove that file, I get a different first error message: instead of ran 0 codeblock(s) I get page not found:
ok, I created the expandmacro.md outside Logseq and had the dash for the block missing. I opened the page from Logseq and it added the dash (created the block containing the function) but I am sill having the same error.
This is what I get after I open the expandmacro page in logseq and I switch to the scratchpad page where I run my tests:
This is exactly what I was thinking, to have macros that are not dynamic but static -replacing themselves at runtime is something Logseq Maros shoudl have as a parameter or something. I wonder why nobody has posted any use cases …
Man, it’s no easy task to get uploads less than 4MB in here. I wanted for a quite some long time to showcase my need for macros that replace themselves, so here is my use case:
Logseq Dynamic Variables are available in Templates, Queries and Macros. They are not available to Custom Commands nor they are available to Journal Blocks/Pages. I wanted to make them available to daily usage in Blocks as well as in Block Templates created with Custom Commands;
Macros are the obvious solution to be able to insert Dynamic Variables in Blocks. But there is one fat problem. Macros are Dynamic themselves and they update every time the page is loaded. So I was stuck until this solution -luckily- became available; @Mentaloid
Now I can have Macros that “replace themselves with their result”. Awesome. So I created a few Macros that access Dynamic Variables:
:macros {
;; make Dynamic Variables accessible by running [custom macros that replace themselves with their value on first run](https://discuss.logseq.com/t/make-custom-macros-that-replace-themselves-with-their-value-on-first-run/20967/1)
:current-page "<div class='kit' data-kit='expandmacro'><% current page %></div>"
:time "<div class='kit' data-kit='expandmacro'><%time%></div>"
:today "<div class='kit' data-kit='expandmacro'><%today%></div>"
}
Finally, I added the folowing Macro to be able to access the natural language syntax for dates, ex: <%next Tuesday%>:
and it gets replaced with the appropriate date just as I would do by using the /date Command and then selecting, with mouse, the day I am interested in.
Here is a screen recording showcasing it (you might want to right click > “open image in new Tab” for larger viewpoint)…
Now, to be able to pre-fill some properties in Block Templates (yes, these are Templates for a single Block that I can easily access by typing “<template_name” instead of going the route → “/templ”{ENTER} + Template_Name{Enter}, which would ruin my Quick Capture experience):
I use a lot of Single-Block-“Templates” for every input i do in Logseq. I rarely do multi-block templates (the daily journal template is one of those, for example). I totally dislike to have to use /template {Enter}, then template name {Enter} and would rather do <template-name{Enter}. I also design my “single-block-teplates” (actually Custom Commands) to leave the cursor exactly where I feel it’s the most logical for quick capture of data (something Templates can’t do). And, because Custom Commands can’t use Dynamic Variables, I had to somehow make them work via Macros. But Normal Macros won’t do, as they are dynamic and change their result at every refresh. So @mentaloid 's solution is gold to my specific use case.
I’ve been looking for this since literally today and found today. This seems like it should become an official feature of Logseq. Thanks for the discussion here, very clear.
My usage is just writing complex templated, long winded latex equations for category theory. You can use the Katex macros but it requires custom.js. Going this far I found this post, which only required a little more and made the argument clear how it could be done. I just did this.
@mentaloid Is there a way to circumvent macros not being parsed inside Named Links?
If I do Ctrl+L I get “[]()” and the cursor is placed inside the square brackets, where I write my name for the link, then I go in between the round brackets and I call my macro “{{var next monday}}”. When I exit the Edit Mode for the Block I get nothing, the “{{…}}” is not parsed.
PS: I would extensively use this when writing days of week in my language: [Luni]([[Monday, 01.04.2024]]) but it’s impossible atm. I was wondering if you can see a solution for that by using Macros (it can be done by doing [Luni]( /date) and picking a date from the popup )…
I understand that and like the concept very mch. I was simply asking if configuring Synthesis would render expandmacro superseeded and I should use further evalonce instead of it, as it does the same thing and more.
Regarding Synthesis, can we maybe have a new thread under Synthesis - Logseq to gather practical usecases so it’s easier to grasp for people like me (non-programmers)?
I understand that one can use/call any program Logseq supports to do something and then define a “natural” language so that that specific “something” can be achieved using whatever form of natural language is covered in the corresponding definition patterns …
With existing info I can grasp the usefulness for evalonce (as per my previous question, to render a macro inside another macro - ex: [Luni]( {{macro-name var1 var2 etc }} ) so I guess one would write it something like this: {{evalonce [Luni]({{var this monday}})}}?
I can also see the potential to have a macro to create an empty Xcolumns x Yrows Markdown Table where Cells can be edited without going to block edit mode, in a “live” manner. I have no idea yet how that could possibly be triggered ({{evalonce table, 4x3, zeroed}} ??)… Another idea: importing a CSV into a table ??
I am also curious how can this be used to:
make a natural language querying environment, where complex queries are created behind the scenes from the natural language provided to the macro… ;
creating multi-block “templates” just like we can now call the (single)block templates;
call templates from an evalonce so the daily template would just contain an evalonce call that calls Weekday template if it’s a week day, Weekend template if it’s weekend, etc … (?)
I can’t wrap my head around how the above would work and even if my assumptions are correct so I am eagerly waiting for any discussions/examples/videos that anybody would post so we better understand how this works and what is possible.
Ideally when I write Luni during writing a text the system would have already made it into a markdown link just as we can do with text expanders :Luni goes straight to link but even without having to think about it.
Other automation I can think of is automatically populating some properties of my blocks. I use a dozen block templates to capture anything from Logs to Info to Video to Book to whatnot and I have a certain number of properties that go with each input data and I would like to define somewhere in Logseq:
if the block is of type “Info” and any word inside the Header of the block contains something that resembles a namespace, put that as the namespace property, otherwise look for some page-name inside my graph and, if it resembles that page-name, put that as “related-to::” property. If nothing is found in the header, move to the block body… and so on. Automatically filling some of the properties would drastically cut my time setting up each block. Ideally an AI-type thing that learns from previous such cases and helps with this meta-data “guessing” would be the thing to have;
Each user has his/her own set of automating needs and they will still have to learn to implement them if they are niche…
I wanted a scheduled task to automatically appear on my journal page each day reminding me to take some vitamins.
I use Logseq on both mobile and desktop
So I wrote a macro {{schedule-date-today} }that replaces itsself with SCHEDULED: <todays date> when and only when it is evaluated on a journal page. Otherwise it just behaves as a normal macro.
Environment
I use :default-templates { :journals } to load a template to the daily journal.