Cross-references

First, thank you for the splendid SilverBullet software. I started to use it quite extensivelly and on daily basis. This topic is something I miss, so I would like to start a discussion about it.

The idea is to add HTML tag ids for cross-references for at least every Markdown block element. See for example this RFC where every section is marked with section-<hier-number> and every paragraph is further numbered within the section, like this one (hover over it). We can even imagine going further but having at least support for basic Markdown blocks would be great…

<h1 id="1">Section 1</h1><!-- just numbers following the KISS principle -->
<h2 id="1.1">Section 1.1</h2>
<p id="1.1:1">Some text</p><!-- the colon ":" divides section and sub section -->
<h2 id="1.2">Section 1.2</h2>
<p id="1.2:1">Some text referencing a <a href="#1.1:1">paragraph</a></p>

Lot of question arise, for example where exactly to place the ids. Therefor I speak in terms of the Markdown AST and not in terms of the actual HTML. The above is just an example how it could look like on the HTML level. The user in fact would
just use it intuitively.

# Section 1
## Section 1.1
Some text.
# Section 2
Some text referencing a [paragraph](#1.1:1).

Another question that I see is how to cope with indexing and updating the references. I certainly can see some obstacles in this area. Therefor the question is whether to support only sections and paragraphs (as it is in the RFC) or whether to allow for some manual user intervention with some special syntax that will cause that, e.g., empty <span id="some user's name here"/> would be inserted in the resulting HTML, something like [mark: <My mark>] to be referenced elsewhere with something like [[<#My mark>]].

What do you think about it? How other “note taking” applications cope with this? How do they cope with structural changes within document (e.g., if you are referencing few paragraphs and then you re-order them or even move to another page then references to them simply must be updated, or what if you delete a referenced paragraph, shoult that be garbage collected or the invalid reference should stay)? And, is at least some simple support doable for SilverBullet? Perhaps other mechanism than HTML ids exist?

It’s already possible to link to header (or anchor) in your notes.

What you want is automated anchor for each Markdown item? I’m not sure I see the value added versus manual anchor.

I suppose something could be done with custom attributes extractor to auto add anchor to everything. The indexing should use some form of UUID so it can remain up to date even when content is added in between blocks or moved.

With the coming feature of Lua Script to render function in line, you could have a routine to show a live rendering of the numbered reference in the links to the UUID anchor.

What you want is automated anchor for each Markdown item?

Yes. And I can imagine that the format of the anchors could be customized using templating.

I suppose something could be done with custom attributes extractor to auto add anchor to everything.

That’s pretty interesting! (I’ve barely touched this part of the documentation. Thanks.)

The indexing should use some form of UUID so it can remain up to date even when content is added in between blocks or moved.

Can I achieve this as of now or a plug must be written for such kind of an indexer?

With the coming feature of Lua Script to render function in line, you could have a routine to show a live rendering of the numbered reference in the links to the UUID anchor.

Nice too! So, in other words, what I want will be doable quite soon?

I think the custom attributes extractor can do it. However, I haven’t yet used/tested this feature so not sure how or what you can actually achieve with it.

It seems possible but will require scripting the functionality yourself.

It seems possible but will require scripting the functionality yourself.

Well, I do not programm on daily basis, just from time to time, I will see what I can achieve myself and ask for help if I (likely) fail. :wink:

I propose to wait with this for the Lua scripts for I guess it would likely be then even easier to implement, right? @zef @bent0n

Obsidian has block identifiers: Internal links - Obsidian Help as I understand (I haven’t played with it myself) it can either use automatically generated ids (not sure when and if they auto update?) or manually entered ids (which would be similar to SilverBullet’s Markdown/Anchors (just with a different syntax).

LogSeq also has block references, but I think automatically generates a block ID (a GUID I think) only when you link to it. It then puts a [id:: GUID-HERE] marker in the file itself. I think it may hide this in the UI, but it’s there. The advantage is that it’s not subject to movement, the disadvantage is that it’s kind of ugly.

In SilverBullet in many places I simply use @pos pointers as object references (e.g. for tasks) which basically point to the nth character in a page (e.g. [[index@123]]). Obviously, this potentially shifts on every update, so these are only useful in e.g. queries and templates, not to write yourself.

While we could come up with a more clever and intuitive pointer mechanism, it will always be subject to edits to the page, which may swap sections, paragraphs and then those pointers becoming invalid. Honestly I think this in an inherent trade-off in using plain text files rather than some more fancy, perhaps database-like format, where it would be easier to maintain this stuff as you edit.

As to Lua scripting: this is still a developing feature (that you can follow in Space Lua: Making Space Script safer, simpler and unifying all the things), which indeed will allow you to create inline “widgets” that can do custom things. As much as I like Lua, I doubt it will actually solve this very fundamental problem of SilverBullet using text files that support arbitrary edits :slight_smile:

AST-oriented database? :wink: I mean, any text document can be broken into some AST (depending on the format, we are talking about Markdown here but it would apply to almost any textual format). Therefor I suggest AST-based indexing together with some sort of hashing of the leaves (this is just quick idea, I haven’t though about it enough yet, just for a discussion). You can diff ASTs too, and you can even store things with the same hash only once and only refer to them etc. To point somewhere you would point to AST leaf and a position within it.

Example document:

Some *foo*!

AST

paragraph (hier: "1")
  `--- normal text     (hier: "1", data: "Some ", hash: "123456")
  `--- emphasized text (hier: "2", date: "foo",   hash: "456789")
  `--- normal text     (hier: "3", data: "!",     hash: "987654")

Then for example 1.1 would point at the beginning of “Some” and for example 1.1@3 would point to the “m” and for example some 1.1@3:2 would select “me” etc. (this last case would be “injected” into the AST virtually, because we would like to persist it and also do something with it, i.e. style it). If we have also timestamps and log for the objects we could reconstruct any document in any point in time too and show all it’s history. Also synchronization could be based on closing an AST leaf (e.g. creating new paragraph in the editor or leaving changed emphasized text etc.) I have this idea for some time, I must say, but there is no such database yet (yeah, sorry for the off topic, it’s clear that to write such a database would be great deal of work, even theoretical). :smiley: