quartz icon indicating copy to clipboard operation
quartz copied to clipboard

Add support for Obsidian embedded blocks

Open andrictham opened this issue 2 years ago • 17 comments

Is your feature request related to a problem? Please describe. One important feature missing from Quartz that makes it useful for publishing digital gardens is transclusion.

In Obsidian, this is implemented as custom Markdown syntax (i.e. !^dcf64c – see Obsidian docs).

As this is not generic Markdown syntax, currently, transcluded blocks appear in Obsidian, but not in Quartz. Quartz sites show malformed markup when attempting to use this syntax, making it impossible to publish richly transcluded notes.

Describe the solution you'd like Quartz sites should render transcluded blocks.

The simplest solution would be an additional compile step similar to how backlinks are generated, with transcluded content statically inserted into a note as if it was originally there.

A more complicated solution would involve transcluded content being styled differently, with a deeplink back to its original context.

andrictham avatar Jul 29 '22 06:07 andrictham

Hi @andrictham, yeah I really wish this was more possible :// Obsidian seems to acknowledge that this is not interoperable so any transcluded block info is lost as that block info is stored internally (https://help.obsidian.md/How+to/Link+to+blocks#Interoperability)

Closing this as this won't be possible until this info is exposed for usage

jackyzha0 avatar Jul 30 '22 00:07 jackyzha0

@jackyzha0 Hmm, isn't this info in the Markdown files themselves?

Since each "block" referenced will have their own IDs appended in the original file, you can find them.

From the page you linked:

You can still find referenced block by searching for the block ID, although that's a rather manual process. The connection is not lost as long as you have software that can search in a folder.

andrictham avatar Jul 30 '22 04:07 andrictham

No, the Markdown doesn't contain any additional metadata. I couldn't find any references to the blocks aside from the content/.obsidian folder, the rest of the references I think are stored in a SQLite file that is not exposed on the Quartz folder (so there is no reliable way of finding it)

jackyzha0 avatar Jul 30 '22 04:07 jackyzha0

@jackyzha0 I just tested it with two example Obsidian notes, you can see here in Obsidian, I can embed blocks:

Screen Shot 2022-07-30 at 3 57 19 pm

and here, the same Markdown files in VSCode. The Markdown file contains the id ^b7e3ea.

Screen Shot 2022-07-30 at 3 58 54 pm

Doesn’t this mean that Quartz should be able to read ^b7e3ea in one Markdown file, and references to ^b7e3ea in other files, and parse them as references?

andrictham avatar Jul 30 '22 08:07 andrictham

Ah interesting, had no idea Obsidian just included the transcluded blocks IDs as raw text. I think supporting this will include an entire additional step in the scraping process so this will be a low priority add until more people express interest.

Thanks for pointing this out!

jackyzha0 avatar Jul 30 '22 16:07 jackyzha0

+1 for having this feature! It can be super useful, specially in long documents such as courses notes.

yshalsager avatar Aug 02 '22 07:08 yshalsager

Yeah, having this feature will make quantz much more invaluable.

aadimator avatar Aug 13 '22 16:08 aadimator

Hi, the previously closed feature request #69 seems to be relevant here as well.

Please correct me if I'm wrong, but the ability to embed an entire page, or an entire section will definitely require additional work but shouldn't the generator be similar to the already existing hover tooltips that appear?

It seems to be a logical progression to the ability to embed a page, a section and then a block as I would imagine that keeping track of block references and their exact location across the entire generation pipeline would be a bit more complicated.

autolyticus avatar Aug 30 '22 14:08 autolyticus

I think that it'll require major work to support that. The hover tooltips that appear, they don't process any markdown. The current implementation just stores the whole markdown file in a string, and displays a portion of that string later on, as far as I understand. @jackyzha0 will be able to better explain that.

There's another tool, https://github.com/zoni/obsidian-export, that can be used to embed documents as well. You can see examples on my Quartz blog, where I've used that tool. I've embedded a whole page here: https://notes.aadam.dev/TrU0OxcmyepG9PBaJ3ZoH and it also supports heading-level embeds, as can be seen here: https://notes.aadam.dev/qVZePZ-GHvoY3h6CzlGTH/

It doesn't have support for block embeds yet.

I wonder if that tool can be used somewhere in the Quartz pipeline as well, instead of reinventing the wheel.

aadimator avatar Aug 30 '22 16:08 aadimator

Correct, hugo-obsidian only scrapes at a document level but there is potential to add header/paragraph/block level scraping as well. @aadimator if you have a proposal for how to integrate it into Quartz, I'd be happy to listen!

jackyzha0 avatar Aug 30 '22 18:08 jackyzha0

There's another tool, https://github.com/zoni/obsidian-export, that can be used to embed documents as well. You can see examples on my Quartz blog, where I've used that tool. I've embedded a whole page here: https://notes.aadam.dev/TrU0OxcmyepG9PBaJ3ZoH and it also supports heading-level embeds, as can be seen here: https://notes.aadam.dev/qVZePZ-GHvoY3h6CzlGTH/

@aadimator I'm interested in understanding how you've implemented this, do you have source code for your quartz? Perhaps it may be possible to integrate obsidian-export in the build script before publishing.

matthewwong525 avatar Sep 02 '22 14:09 matthewwong525

I've outlined my whole publishing workflow here: https://notes.aadam.dev/SBYNtPHqsTW9Ck1Kuoxsu/

Keep in mind that this was designed with my particular requirements, so it's not very flexible at the moment.

I have a separate notes repo which only contains the Obsidian Vault. I didn't like the Quartz default approach of making the content directory your repo. My Obsidian Vault doesn't have any particular structure to follow, in order to be used by some publishing framework, like Hugo, Zola, Gatsby, etc. I've decoupled it so that I can easily change the publishing workflow/tooling without having to modify the vault in any way.

What I'm doing is that once a change is pushed to the vault, it will trigger a GitHub Action, which will download my modified Quartz theme, use obsidian-export to process/embed the notes, and then build and deploy those notes to gh-pages branch.

I've made some small modifications to the obsidian-export tool, so it also outputs the information of the embedded documents in some div tags, which are hidden by default (I can change their visibility using CSS later on).

aadimator avatar Sep 04 '22 04:09 aadimator

Here's the GH Action configuration that I'm using: https://gist.github.com/aadimator/5125fbd8a51b1dd13ba608fe37aacfd4

Here's my Quartz template: https://github.com/aadimator/quartz. This doesn't have any major changes, just some basic styling and metadata changes.

Here's my modified obsidian-export: https://github.com/aadimator/obsidian-export. I have no experience with Rust, so the code probably is not idiomatic, and it might have several bugs, but for the time being, it's working fine for me. I might refactor it once I've learned Rust.

Here's my modified hugo-obsidian: https://github.com/aadimator/hugo-obsidian. I needed to change it because I wanted to use permanent IDs as my URLs. All of my notes have a id property in the YAML metadata. It uses that as a URL.

Let me know if you need any further information.

aadimator avatar Sep 04 '22 04:09 aadimator

Just a side comment, I really like your workflow and templates but I had a small question regarding the paths that seemed to be generated. It seems that all of the notes seem to be referred to through IDs. Since they're from the YAML metadata, do they have to follow any specific format or does any string work? If there's a specific format, do you have to use a specific Obsidian plugin to generate these IDs? I noticed you mentioned the following in your workflow document:

Rename id property to url. All of my notes have an id property in the YAML frontmatter. It is a nanoid which ensures that each note will have a unique URL-friendly string.

Specifically, if I write a note and edit it and republish it, is the ID for that specific note guaranteed to always be the same?

autolyticus avatar Sep 05 '22 19:09 autolyticus

@reisub0 The IDs could be any string, in theory. Although, in my specific case, I'm using nanoid to generate the IDs. I have nanoid installed globally on my system using npm install -g nanoid. Then in the templater plugin, I have simply defined a user function like so: image

And in my base template file, I'm using it like this: image

Now, whenever I create a new note, it will automatically have a unique string as its ID. I'm using nanoid because it provides a URL friendly string, as well as a very high probability that no two notes will have the same ID.

If I don't manually edit the id field, that note will always have this ID, no matter how many times I edit, rename, or move the file. This allows me to have more flexibility and control over my vault, as I don't have to worry about breaking URL links whenever I rename or move a note. The only way to change the URL would be if I change the ID field manually.

PS: Initially, I had to write a small script that added the nanoid into all my existing notes. It would simply crawl over the folder and select all the .md files, see if it already has an ID or not, and create a new id field if it didn't have any ID yet. But that was just one time only. Now, all my newly created notes have a unique ID by default, thanks to the Templater Plugin.

aadimator avatar Sep 06 '22 11:09 aadimator

Thank you for the careful and detailed explanation! It is so helpful :)

autolyticus avatar Sep 08 '22 15:09 autolyticus

@aadimator

I have a separate notes repo which only contains the Obsidian Vault. I didn't like the Quartz default approach of making the content directory your repo. My Obsidian Vault doesn't have any particular structure to follow, in order to be used by some publishing framework, like Hugo, Zola, Gatsby, etc. I've decoupled it so that I can easily change the publishing workflow/tooling without having to modify the vault in any way.

This is a very good point — I wish I had read this before setting everything up, hah!

ryanjamurphy avatar Sep 15 '22 15:09 ryanjamurphy

+1 Though I understand that it would be much easier if Obsidian was supporting this in a more parse-able way.

vJourneyman avatar Oct 10 '22 00:10 vJourneyman

+1

i need that, is there any development about that. Thank you so much.

Screen Shot 2023-09-12 at 02 30 31

Screen Shot 2023-09-12 at 02 32 01

kadirkatirci avatar Sep 11 '23 23:09 kadirkatirci

Closed in https://github.com/jackyzha0/quartz/pull/475

jackyzha0 avatar Sep 13 '23 18:09 jackyzha0