@alex0 Apologies for the delay in replying. The approach I’m suggesting is drawn from R Markdown and more fully described here.
The original Markdown spec used indentation with at least four spaces or a tab to delineate a block that should be typeset in a fixed width, typewriter style font. This was common for code snippets, so syntax was designated as a “code block”. As an alternative to indentations, code could be “fenced” using ``` or, in some (most?) interpreters, ~~~.
That was fine, but it meant that all programming languages were shown in the same manner. Programmers, on the other hand, are used to syntax highlighting editors and IDEs, which pick out and emphasise syntactic features of the language features such as keyword. Thus the ``` notation was further extended with a parameter list, bounded by braces { … }, further instructing the markdown interpreter how to display the fenced code.
The first element in the parameter list is a language designator. Thus ```{clojure} means pretty print/ syntax highlight the remainder of the block as Clojure code. There is now a long list f supported languages!
If the parameter list has only one element – the language name – the { } can be dropped, hence ```clojure and ```{clojure} are syntactically identical.
If the parameter list has more than one element, the remaining elements are passed to the whatever formatter the interpreter calls. Typically these arguments control the HTML output (see, for example, Python Markdown). I don’t think there is any standardisation of this.
R Markdown was designed as a tool for creating high quality, data rich documents and reports. It treats an otherwise standard markdown file (with a YAML header block) as a sequence of “chunks”, interpreting standard markdown in the normal way but, but executing rather than formatting ``` fenced code blocks (at lest those in R and some other languages – Python and bash for certain). If you want to show the code rather than execute it, you simply use indentation or (I think, because t’s been a while) ~~~ fencing.
R Markdown’s process is two stage. First fenced (R) code blocks are executed in the context of the interpreter, meaning that they have access to data that has already been loaded and to any YAML data. The means that an initial code chunk can, for example, load data from a file, database or website, later chunks process it and still later chunks display the results of that processing; I’ve done this for some reports that involved Monte-Carlo modelling.
The output (if any) of each code chunk must be valid markdown; typically, as raw HTML is itself valid markdown, the output is an HTML div
. These, plus any raw markdown in the file, are then passed to a process called knitr
, which “knits” them into a unified markdown file. This process is typically controlled by values passed through the code block’s parameter list, so you frequently see knitr
directives that control the captioning, size and positioning of the div
created which a code block is executed.
Finally, the second stage markdown/ HTML is passed through pandoc to render it as HTML pages, PDF, LaTex, Word or whatever.
Now, R Markdown (and an extension called Bookdown, which is designed for long form technical documentation, writing theses etc.) have very different objectives from Logseq; they are publishing, not knowledge management, tools. Nevertheless, the ability to dynamically execute code within a markdown document (a block in Logseq) is hugely powerful. Given that Logseq is coded in Clojure and that R and Clojure share an ability to dynamically load and execute code chunks (using the eval
function, but I think there may be better ways involving pre-compilation to JVM byte-code and dynamic loading) taking a leaf from R Markdown’s book is something that I feel is well worth investigating.
What would particularly interest me is if such code could have the ability to walk the page/ block graph, extract text and properties for processing, set property values, create links etc. (perhaps calling Logseq’s own functions to do so). Other PKM applications, notably Tinderbox, can do this, but Tinderbox uses it’s own language (Action Script) and a “semi-proprietary” file format (everything is stored in as XML) so it’s pretty much a walled garden. Clojure, on the other hand, opens the door to just about anything written in Java.
Sorry for the long explanation, I hope it was useful.