Note Composer: links to blocks and headers should be updated when extracting

Use case or problem

Currently, the actual extraction of a note works beautifully. And it does the job, because the placeholder link allows the user to trace a path to the new note. BUT…if I’ve been linking to “Header A” or “block A” and I extract this header section or block to a new note, I now have a bunch of links to the old note which require me to figure out and “jump through” to the new note.

Of course if you’re splitting notes as you’re making them, this is no big deal, but if you’re splitting out pre-existing notes…well, I’m looking at having to manually update a bunch of links.

Proposed solution

Ideally, the plugin would take all notes that go specifically to headers or blocks within the portion being extracted, and update them so they point to the new note instead, since these headers or blocks no longer exist within the original note.

Current workaround (optional)

As far as I’m aware, the only current option is to look through the list of backlinks to the original note, weed through them to see what went to that section, and manually update them all in their respective notes.

Related feature requests (optional)

Linked mentions in link pane sorted by section

9 Likes

thanks for adding this

1 Like

Great idea!!!

Another workaround would be to use VSCode to do a mass search and replace, searching for all occurrences of links to that heading and replacing them with a link to the new note.

There is one catch that can make this tricky, and perhaps others, so be careful and backup often if you experiment with this. If you tend to use pretty links (pipes followed by alternate text for the link to present as), it won’t find those unless you are using regular expressions to basically consider these non matches a match. 99.99…% of the time this won’t cause any issues, but to be sure it can be useful to review the matches that are being replaced. I say this because, for example, if by chance you accidentally have a link to a heading and then a pipe and text without the closing brackets, you could be replacing all the text up to and including the next set of closing brackets in that note, which would obviously be very bad.

I mention this because I know you have a lot of notes and I’d hate to lead you towards possible data loss. Overall, I wouldn’t be too concerned, as using mass search and replace in conjunction with regular expressions has been a life saver for me many times. If you aren’t already familiar with them and decide to give it a try, it is also worth utilizing capture groups in the regular expression search and replace, which can definitely save lots of time.

Good luck!

1 Like

That’s a good idea! And I wonder if the issue with alternate text could be avoided by not replacing the closing brackets? So replace:

[[Old Note#Old Note Section

with:

[[New Note

I think (I’d have to actually see it in front of me to be sure) that would leave the remainder properly intact, whether it’s merely ]] OR if it’s |alternate text]].

1 Like

Good call! I think you are right. Like you, I haven’t really tested it, but it seems to be a perfectly valid way to avoid that issue. Thanks!

I use block linking a ton, probably to a fault. This would make my life in obsidian a lot smoother.

1 Like

Not sure if this should be a feature request or bug report. But when extracting the selection Header Links and Block References don’t update. This seems inconsistent when compared to how when merging notes the links are nicely updated.

Here’s a case example

If I want to extract Heading 2 as it’s own note, note B will not update it’s links. Instead, it continues to link to the now extracted portion of the text from note A.

What would be very useful is if it auto-updated the links like so:

1 Like

@I-d-as

I use VSCode regularly for mass search and replace, but have no knowledge whatsoever with Regex. Could you tell me what expression you use to reset the links?

1 Like

@Klaas I will try to answer without too much of a diversion. If it is, I don’t mind deleting the post.

Anyways, for this specific use case @a2jc4life was doing, I was recommending VSCode for a simple search and replace across the vault providing the exact link to the heading for the search and the exact link to the new note for the replace.

I should have probably been more clear in my suggestion of using regex/capture groups with search and replace. The tactic has proved extremely helpful for me when renaming things en masse when some more complexity is required.

Although it may seem very niche, I will provide an exact example of a use case I used it for a couple months ago in the process of creating an offline version of the MAXScript documentation. First I copied and pasted each page into a new note named with the correct name. This was a good start, but all the links between the various pages were formatted as markdown links to the corresponding webpages. I obviously wanted the links to instead go to the corresponding notes inside my vault. Doing this required the use of capture groups.

I wanted to search for the literal [ so I had to start by escaping it with a \ which made the beginning of my expression \[ and this is required because brackets serve a different purpose in regex.

I then wanted to capture the name of the page within the brackets so that I could use it in my replace expression. To do this, I added an opening parentheses, which I would have to soon close, but not yet. At this point the expression is \[(

Inside the parentheses, I added .* which will basically take the characters you give it until it finds the next search character after the closing parentheses. At this point the expression is \[(.*)

You may want to look into the use of the ? as well because it can be useful. There are plenty of guides. Anyways, now I had to add the closing bracket, again escaping it. The expression is now \[(.*)\]

Since these were markdown links to webpages, I also wanted to search for the opening parentheses, the website url text, and the closing parentheses. With the same methods just described, I use the .* within the parentheses. But since I want literal parentheses, not a capture group I escape the opening and closing parentheses. The expression is now [(.*)\]\(.*\)

When doing this, my plan was initially to simply use the replace expression of [[$1]] thus creating wiki links for all the links across the vault based on the page name, which matched the names for my notes, as the $1 replaces whatever is contained within the first capture group parentheses. Unfortunately, I remembered that while I was copy pasting the documentation pages there were many pages which had colons in their names, which I couldn’t use because they are illegal characters in Obsidian note names. I had decided to instead use double hyphens in place of the colon. This was helpful since there were not any other occurrences of double hyphens in note names for the various pages.

So, I adapted my search expression I explained above into the following \[(.*):(.*)\]\(.*\)

Now, since I had split the part of the page name on the left side of the colon into a separate capture group from what is on the right side of the colon, I had to adapt my replace expression into [[$1--$2]]

At this point I finally made sure to check the .* icon next to the search field for the replace in all files. This turns on regex for the search and replace. Of course I had VSCode set with the correct folder within my vault folder as open. I ran the search [(.*):(.*)\]\(.*\) replacing with [[$1--$2]]

This took care of the note names with colons and correctly renamed them all based on my adopted convention. Then, I finally used the first expression to search for just [(.*)\]\(.*\) and replace it with just [[$1]] which took care of what was remaining, the pages without colons in their names.

As a side note, if I wanted, I could have put the url in a separate capture group and replace with that in addition to the wiki link, thus also having the web link. I should also add that I kind of simplified what I did here for the sake of clarity. For example, in actuality, within my search I included the beginning part of the url that was consistently used. This way, I knew I wasn’t breaking links to other external websites within the documentation. All kinds of surprises can pop up when you are dealing with the unknown so I recommend being very careful. I also fairly closely reviewed the list of occurrences before committing; and there were many occurrences of many thousands of links. Again, obviously I made backups, and opted to do this in a dedicated vault.

In the end, this and other tactics saved me so much time and was so effective that I also created offline documentation vaults for 3ds Max, tyFLOW, Zbrush, Arnold, V-Ray, etc. I surely couldn’t have done it otherwise. And when issues arise, it feels like there is usually a way to make things work. For example, occasionally a while back when using the Local Images plugin, I ended up with funky broken links and I was able fix them all in one swoop.

Sorry for the lengthy description. When I type things out on my phone they usually go long. The expressions should be correct as far as I can remember. Even though you were asking about a different scenario, it sounded like you might be interested in something like this. Hopefully this is of some use.

Good luck!

I’d love it if links to blocks and headings were updated when they change in general (for example, if I reword a heading).

2 Likes

@CawlinTeffid Currently on the Obsidian roadmap on Trello, at the top of the Short-term list is:

  • Preserve links after renaming headings and blocks

There is also the Working On list with the following:

  • Export to standard Markdown
  • Sync: collaborate with shared vaults
  • Publish: publish-specific themes

Of course those lists don’t include many of the sweet features that are regularly released. I just know I have also been excitedly looking forward to the preservation of links after the renaming of headings and blocks. That is going to be a game changer, for sure.


Edit: Unfortunately I was mistaken:

4 Likes

That’s unlikely to happen: https://forum.obsidian.md/t/automatic-inline-update-of-links-to-headers-when-they-are-modified-no-extra-dialog-window/25412/10

Let’s keep this FR on-topic.

Sorry, I thought this was a subset of the general case, but I see now that it’s different.

Thanks for the link.

2 Likes

@I-d-as many thanks for that detailed explanation. Couple of remarks:

  • in para 8 you said: “The expression is now \[(.*)\]”, and in para 9 you said “The expression is now [(.*)\]\(.*\)”, so it seems you forgot the very 1st escape sign

  • Regex is extremely powerful, but seems quite difficult to learn, I’ll give it another try, even though

  • Regex in VSCode is slightly different from regex in Obsidian, as I seem to recall.

1 Like

@Klaas You are right. I fixed the mistake. I am definitely a novice with regex and really only use it in VSCode to accomplish things like I explained, learning as I go. In terms of the differences and/or basics Obsidian regex, I couldn’t find an exact description, although I admittedly didn’t spend too much time searching. However, that is definitely something that I would be interested in if anyone knows the “flavor” that Obsidian uses. If I am not mistaken, VSCode uses JavaScript flavor. I may be probably am wrong.

Anyways, Thanks! And good luck on your journey!

@I-d-as No, you are obviously not a novice, you just made a typo, happens to the best of experts :wink:

1 Like

It is exciting to see that a similar request will be implemented soon, here:

Perhaps if everything goes well with that, we might have a reason to be hopeful about this request. Regardless, I appreciate that this request appears to have gotten the ball rolling.

Thanks again, @a2jc4life! Nice job.

1 Like

Use case or problem

A possible use case of heading reference is to link with precision to slightly different concepts (e.g. how a bacterium reacts to particular antibiotics) without having to divide such concepts in different truly atomic notes.

This has the benefit of grouping the backlinks under the same note, instead of dispersing them across a bigger group of little notes, thus enhancing the ability to spot and create connections.

Currently, the issue with it is that, if one of those initially small slightly different concepts grows to the point it needs to become a note on its own (as we learn about the topic etc.) or to be moved under a different note (because of organization purpouses), all the links to that heading will not be automatic updated to the new location.

Proposed solution

The “extract this heading” command should trigger auto-update of:

  1. the links to the header, and
  2. the links to every hierarchically inferior sub-heading currently under the heading we are running the command on,

as the “rename this heading” feature already does.


Example

Note A has the heading # 1, and heading ## 1.1 under it
Note B has the link [[A#1]]
Note C has the link[[A#1.1]]

If heading 1 is extracted to a new note D

Note A is now empty
Note B has the link [[D#1]]
Note C has the link [[D#1.1]]
Note D has the heading # 1 and heading ## 1.1

Current workaround (optional)

I’m aware of no workaround but to manually fix every link to each heading and sub-heading.

Related feature requests (optional)

13 Likes

This Feature I find so extremely important and it is hard to believe that there seem to be so little people who have this concern.

Automatically updating backlinks to headers, after extracting them to new notes seems absolutely essential.

Otherwise the extraction Function is so dangerous to use as it can fuck up your whole link structure (which is THE Core Feature of obsidian after all).

5 Likes

Currently struggeling with the same problem. Would highly appreciate this feature!
Thanks for bringing it up!

2 Likes