Zettelkasten Forum

Insert a List of Backlinks Into All Your Notes

Insert a List of Backlinks Into All Your Notes

Use this script to add a list of backlinks to all of your notes, and update it in place to always have up-to-date results.

Read the full story here



  • edited January 2020

    This is interesting. I'll look forward to a "less precise search since the script is open source" as now I format my links [[201910011532]] Computational thinking.

    Don't forget to down load 'yarn' as part of the install.
    brew install yarn

    Will Simpson
    My peak cognition is behind me. One day I will read my last book, write my last note, eat my last meal, and kiss my sweetie for the last time.

  • Also, if you download the source and build it locally, the result is in dist/index.js, so you can execute it via

    node ./dist/index.js  path/to/testarchive

    Author at Zettelkasten.de • https://christiantietze.de/

  • Cool. I too will looking forward to a less precise search as I use Computational thinking [[201910012532]]

  • Backlinks.

    Conceptually I see @Sascha's point about when using The Archive's search (Omni Bar) the Note List provides the 'backlinks' to the search which makes this project redundant. It also updates in realtime. As new links are created their backlinks are available to be shown in the note list.

    I guess I need more training on this. By training I mean I want to practice and become familiar with the nuances, to create some mental muscle memory.

    Adding backlinks to notes seems like a productive thing, maybe I'm fooling myself and I'm doing busywork to embellish a note and to get some endorphin tickle. A visible backlink in the note feels saver and comforting for some reason.

    Will Simpson
    My peak cognition is behind me. One day I will read my last book, write my last note, eat my last meal, and kiss my sweetie for the last time.

  • I think the primary difference is that this script tries to mimic Roam's "Contextual Backlinks" - So instead of just having a list of files that reference your current note (which would be using The Archives note list), you get the line of text where the link is held.


    ## Backlinks
    * [[Something that links here]]
        * The block of text in the referencing note which contains the link to [[Sample note]].
        * Another block in that same note which links to [[Sample note]].
    * [[A different note that links here]]
        * This is a paragraph from another note which links to [[Sample note]].

    So for some use cases, having that text and not just a link to the page would be much more useful.

  • @Eiff thanks for the clarification. As you point out, there is a difference between The Archive's note list and this script. CONTEXT!
    Just like we need more cowbell in our music, we need more context in our Zettlekasten!

    You've renewed my curiosity. Thanks.

    Will Simpson
    My peak cognition is behind me. One day I will read my last book, write my last note, eat my last meal, and kiss my sweetie for the last time.

  • edited February 2020

    I wrote a few command line utilities to help with note-link-janitor.

    note-link-janitor requires that the filename be the first header line in the file itself, e.g.
    I have a note named '20180903101400 Drew 2015 Visual influences on sensorimotor EEG responses' so the first line in that note must be:
    # 20180903101400 Drew 2015 Visual influences on sensorimotor EEG responses

    There's a command to insert # filename into each file.

    Also, as others have noted, the links created are the full filename, rather than just the ID.
    There are a couple of sed commands that will make the links use the ID, with the rest of the title left trailing, or make them ID + text again.

    As always, caveat emptor. The code could harm your files, so try it on a backup.

    code on gist

  • I've noticed a lot of different conventions when it comes to the first line of the file vs the filename. Some do as you have, with the # for a H1 header, and others do just the filename (nvAlt and similar), and you can do a divider below it to make that a H1 header as well. Some don't bother keeping filename/first line in sync at all...

    I may have to play with these scripts for my particular way of doing notes as well, see how they work there (and possibly hack something similar into the nvPy I've come to love making do new things...).

  • That all sounds very interesting. Has someone a good workflow when you need to get things done. I mean really done. When you have physical zettel you can grab them out of your kasten, place it on your desk and read them "all at once" like you have 10 or more screens. So the real problem for me is not the linking/ backlinking. It is to find all important zettel with the linked zettel and the next linked zettel and e.g. export it to a PDF.
    Has someone a solution/ workflow for this problem?

  • This is old, and specific to how Christian used to use his outlines and names, but it seems to be what you want: Create a combination note from the ID's of a set of them to work on later.


  • edited February 2020

    Made some changes:

    • it doesn't matter now if you have # header with note title
    • you can use [[202002282236 Full note title]] as well as [[202002282236]], both will be added to backlinks section

    "works for me", but as always, do backups

  • That's great work, @piotr! I experimented with a totally different approach that ultimately led nowhere, so I wonder why yours ended up being so simple :grimace: Really cool!

    Author at Zettelkasten.de • https://christiantietze.de/

  • edited February 2020

    Thanks :) I wanted to make this as unintrusive to original code as possible in case Andy will improve the project in the future, maybe that goal helped to find this solution :)

    btw. KM macro to regenerate them automatically when app goes out of focus or when shortcut is pressed: Regenerate backlinks.kmmacros

    Post edited by piotr on
  • @piotr (or indeed anyone else) - would you mind walking me through what I need to do install this please? I'm not computer illiterate as such (despite my recent idiocy with converting txts to mds!) but I'm not that familiar with the Mac environment and therefore can't quite see what I need to do.

  • I pasted my response two times before, hopefully third time will be successful :)

    Sure, @JKF , are you familiar with terminals? Terminal.app is the default on Mac.
    First of all you need to install node. Download '13.9.0 Current' from https://nodejs.org/ and double click to open installer and click on "yes" etc. couple of times until it ends. You can check in your terminal if node --version gives the correct output.
    Next thing is yarn https://classic.yarnpkg.com/en/docs/install#mac-stable . If brew install yarn command doesn't work in your terminal, try with curl -o- -L https://yarnpkg.com/install.sh | bash. After that see if yarn --version command gives you version and no errors.
    Next download and unpack https://github.com/panpiotrs/note-link-janitor/archive/master.zip
    You will need to go to that unpacked directory in your terminal, by default it's most likely in Downloads, so cd /Users/YOURUSERNAME/Downloads/note-link-janitor-master should work.
    When you're in there use yarn install to trigger installation of required libraries, and after that yarn build.
    Now you can use this project with this command: dist/index.js /path/to/folder/containing/md/files each time you want to generate the backlinks. You can automate it with macro I posted before or some other way, for example to run it every couple of minutes or hours, but I can't help you on that route, never did that.

  • @piotr said:
    I pasted my response two times before, hopefully third time will be successful :)

    Fab, thank you so much. I'll give this a try when I get home after a few days away.

  • You're awesome @piotr! Great tweaks to the original. Works great. Thanks for all you do. 🙏

  • You're welcome :)

  • I pushed new change to github, to master branch, because I don't see any broken backlinks in my archive.
    The change is for extending context, inspired by how it works in Roam, you can now do stuff like:

    • Lorem ipsum [[202003021607]] dolor sit amet
      • indented context
        • this one even more
      • another one

    and everything will be available in the backlinks section (indented, of course). Before only Lorem ipsum [[202003021607]] dolor sit amet would be listed.

  • edited March 2020

    @piotr said:
    I pushed new change to github, to master branch, because I don't see any broken backlinks in my archive.

    Great update - Thanks!

    Now that I got you here @piotr - I know that I can't add anything to the backlinks section itself or afterwards unless I make a new section with # or <!--- -----> etc.

    Wouldn't it make sense, if the script added that by itself? I seem to forget sometimes to add a new section and then lose my newly added text.

    Thanks again :smile:

  • I'm getting this error and no results - what am I missing, please?

    (node:18951) UnhandledPromiseRejectionWarning: Error: /Users/jennyfaulkner/Dropbox/Archiv/Aristotle/202001210750 Aristotle: audience.md has no title
    at readNote (/Users/jennyfaulkner/Downloads/note-link-janitor-master/dist/lib/readAllNotes.js:18:15)
    at async /Users/jennyfaulkner/Downloads/note-link-janitor-master/dist/lib/readAllNotes.js:35:88
    at async Promise.all (index 2)
    at async Object.readAllNotes [as default] (/Users/jennyfaulkner/Downloads/note-link-janitor-master/dist/lib/readAllNotes.js:35:25)
    at async /Users/jennyfaulkner/Downloads/note-link-janitor-master/dist/index.js:16:19
    (node:18951) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
    (node:18951) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

  • Looks like you have original code, not my fork, I removed and modified the part that is throwing error with the message "... has no title".

  • @piotr said:
    Looks like you have original code, not my fork, I removed and modified the part that is throwing error with the message "... has no title".

    Doh!! You're totally correct, I didn't have my thinking hat on. Thank you so much, that's working now :)

  • Great :)

    @frandsoh that make sense. There are some other things that annoys me too (e.g. if the note has no content other than the title, it attaches the ## Backlinks to the title line), I'll look into both things in the future when I'll have more free time to work with that.

  • When adding the ## Backlinks section, it just appends to the bottom of the document. Most of mine did not have an extra blank line at the bottom of the document (if any), and put it right up against the last text line already present. This made a subsequent run of the script re-add another ## Backlinks section, which duplicated things in many notes.

    Markdown does like it's extra blank lines between sections. I wrote a quick & dirty bash script to test & add the extra blank line as needed for my purposes, but figured I would also mention it here.

  • @piotr thank you so much for this. I've now got it fully working and I've tested it. I'm coming up with the same issue where I have no blank line at the bottom of a document as others, but the rest of it is great.

  • In the interest of sharing and helping, here's the one-liner I came up with to add blank lines to the documents that needed it:

    find . -name '*.md' -print0 | while IFS= read -rd '' f; do [[ -n $(tail -n1 "$f") ]] && echo >> "$f"; done

    I think that should work the same on Osx as it did for me in Linux (via WSL on Windows), but it may need some tweaking. As always, test on a copy of your notes first, please.

  • Yes, I see that and it annoys me too, but it's how the original code works, so until I have more time to work on this, it unfortunately needs to be that way :(

  • ok, both changes pushed to github - remember to create backup of your notes

    • backlinks now ends with ## ... to let you know where it ends and allow to write below it without worry that your notes will be removed (## ... can be changed to any other header level and text)
    • before inserting backlinks it will add couple of empty lines if note doesn't end with empty line
  • edited March 2020

    Oh man! These changes: 🔥 Thanks again.

    @piotr - Including nested content in the backlinks is amazing and it makes me wonder how you format your notes. Would you mind sharing? Are your notes standard markdown or do you make a type of plain text outline?

    Post edited by Eiff on
Sign In or Register to comment.