Return links/Back links

Wow Bernardo. That is so cool! Thanks very much. Also, I have read about your work on Aristotle the other thread you did. Its great to see how so many people who work in such a wide variety of fields are able to bend this application to their needs. Thanks for sharing, this is great.

1 Like

This is the last version of script A.2

  • "RegexAndStuffLib" is no longer needed.
  • No need to add database UUID.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

property UseAliases : true
property theFont : "" -- Your favorite font
property MDField : "" -- Custom meta data field name

on performSmartRule(theSources)
	tell application id "DNtp"
		show progress indicator "Updating return links"
		--	set theSources to the selection
		repeat with theSource in theSources
			
			set theSearchString to my prepare_search_string(theSource)
			set theName to name of theSource
			try
				set theShortName to texts 1 through 4 of theName
			on error
				set theShortName to texts 1 through 3 of theName
			end try
			set theShortName to my replaceText(theShortName, " ", "%20")
			set theList to my get_list(theSearchString, theShortName)
			set theResult to my print_to_DT(theList, theSource)
			
			
		end repeat
		hide progress indicator
		display notification "return links updated"
		
	end tell
end performSmartRule

-- Handlers section

on replaceText(theString, old, new)
	set {TID, text item delimiters} to {text item delimiters, old}
	set theStringItems to text items of theString
	set text item delimiters to new
	set theString to theStringItems as text
	set text item delimiters to TID
	return theString
end replaceText

on trimtext(theText, theCharactersToTrim, theTrimDirection)
	set theTrimLength to length of theCharactersToTrim
	if theTrimDirection is in {"beginning", "both"} then
		repeat while theText begins with theCharactersToTrim
			try
				set theText to characters (theTrimLength + 1) thru -1 of theText as string
			on error
				-- text contains nothing but trim characters
				return ""
			end try
		end repeat
	end if
	if theTrimDirection is in {"end", "both"} then
		repeat while theText ends with theCharactersToTrim
			try
				set theText to characters 1 thru -(theTrimLength + 1) of theText as string
			on error
				-- text contains nothing but trim characters
				return ""
			end try
		end repeat
	end if
	return theText
end trimtext

on sortlist(theList)
	set theIndexList to {}
	set theSortedList to {}
	repeat (length of theList) times
		set theLowItem to ""
		repeat with a from 1 to (length of theList)
			if a is not in theIndexList then
				set theCurrentItem to item a of theList as text
				if theLowItem is "" then
					set theLowItem to theCurrentItem
					set theLowItemIndex to a
				else if theCurrentItem comes before theLowItem then
					set theLowItem to theCurrentItem
					set theLowItemIndex to a
				end if
			end if
		end repeat
		set end of theSortedList to theLowItem
		set end of theIndexList to theLowItemIndex
	end repeat
	return theSortedList
end sortlist

on prepare_search_string(theSource)
	tell application id "DNtp"
		set theName to name of theSource
		set theNameString to "(\"" & theName & "\")"
		set theDB to the name of current database
		set theAliases to ""
		if UseAliases then set theAliases to aliases of theSource
		if theAliases is not "" then
			set theAliasesString to my trimtext(theAliases, ", ", "end")
			set theAliasesString to my trimtext(theAliases, " ", "end")
			set theAliasesString to my replaceText(theAliasesString, ", ", "\") OR (\"")
			set theSearchString to theNameString & " OR " & "(\"" & theAliasesString & "\")"
		end if
		if theAliases is "" then
			set theSearchString to theNameString
		end if
		
		set theSearchString to "name!=" & theName & " content: " & theSearchString & space & "kind: markdown"
		
		return theSearchString
	end tell
end prepare_search_string

on get_list(theSearchString, theShortName)
	tell application id "DNtp"
		
		set theRecords to search theSearchString in current database
		set theNR to count theRecords
		--	log message "Found " & theNR & " return links to the record"
		
		set theList to {}
		repeat with each in theRecords
			
			set the end of theList to return & quoted form of ("<a id=" & name of each & "\" href=\"" & reference URL of each & "?search=" & theShortName & "&reveal=1" & "\">" & name of each & "</a></br>")
			
			
		end repeat
		
		considering numeric strings
			set theList to my sortlist(theList)
		end considering
		
		return theList
		
	end tell
end get_list

on print_to_DT(theList, theSource)
	tell application id "DNtp"
		
		set theList to "'<font size=\"6\" color=\"#8080BB\"><font face=\"" & theFont & "\">'" & theList & "'</font></font>'"
		
		-- Convert to RTF
		set theRTF to (do shell script "echo " & theList & " | textutil -stdin -stdout -inputencoding utf-8 -format html -convert rtf | pbcopy")
		set theRTF to the clipboard
		set theRTF to «class RTF » of theRTF
		add custom meta data theRTF for MDField to theSource
		
	end tell
end print_to_DT


@rlamber3, thank your for your kind words :wink:
Jim @BLUEFROG, is there some restriction against editing older posts? I tried to edit the original post but couldn’t do it.

No restriction I’m aware of at this time.

1 Like

@Bernardo_V, I’d like to thank you for offering these scripts to us. Your generosity helps those of us unfamiliar with scripting.

I had a question regarding Version C and A2. I searched for the Regex lib, but i received a 404 error from the Mac Automation website. Then I noticed, in Version A2, you somehow you removed the need for the regex lib altogether. I’m curious, how would one update Version C in a similar manner?

I’m attempting to alter your script to append backlinks to the file. While your A2 script works flawlessly, I think having backlinks appended to a note is be a better long term solution. I have been unsuccessful in combining C and A2 into a workable script.

What do you think? Is such an edit to Version C possible? And if so, how?

Hi @biznachio, welcome

You can remove the reference to the script library without any problems in version C. I just did that and added some improvements. Here is the updated version.

Thank you very much for posting these scripts @Bernardo_V.
I am trying to leverage the new version you shared with @biznachio.

So I created two test files 1 and 2. And File 2.md links to 1.md

I selected

property AutoWiki_Links : false

… as I use wiki-links.

Based on my understanding the smart-rule script should create a backlink in file 1.md pointing back to 2.md?

But this does not seem to work for me. What do i miss?

Thank you very much for your amazing work across this forum.

hi @jooz, you’re welcome. I just fixed the script. Let me know if it works alright for you.

For the last version of the scripts posted to this thread, please see this repository:

Thank you very much.

I am leveraging Version A as a smart rule.


With Autowikilinks false

The script is stuck for me in step 2:
image
and I cannot seem to cancel this action (requires closing DT).
Logs say theText is not definied:
image

Seems to work fine here. Is this the script you are using? Have you tried adding a condition to the smart rule so that it will only target plain text files?

I am late to this thread, so have only used the latest scripts from GitHub as of today. I am seeing the same message in the log: “on performSmartRule the variable theText is not defined”

I am using version A unchanged.

Using Script Debugger, I set a breakpoint at
tell application id “DNtp”
just inside performSmartRule() but it never triggers.

I have run standalone scripts in DT3 but this is my first attempt with a script in a smart rule so I am probably not understanding something fundamental.

I have tried the smart rule only targeting plain text and or markdown files with the same result as any document.

Hope this helps shed some light on the situation.

Hello and thank you again @Bernardo_V. Your script works like a charm! I am indebted to you.

I am curious, is there a way to skip adding the backlink delimiter on notes where if the list is empty? That way, only files with backlinks get parsed and the others don’t have a Backlinks heading with no links listed beneath.

@Bernardo_V - Thanks for these scripts!

Today, I set up a small framework to debug the script following Jim’s (@BLUEFROG) suggestion: How best to debug Applescripts running inside DT3

That quickly showed me that the reason why I was getting “theText is not defined” message in the log is because one of my test files was empty. It was being linked to from another file, but there was no text inside this “target” file and that was causing the error.

1 Like

You can add this to run it as a standalone.

tell application id "DNtp" to my PerformSmartRule(selection as list)

Done :wink: Just look for version A in the git repo.


@jooz, perhaps that could be it for your case as well?

That was indeed my case! My both test files were empty. Your script works brilliantly now after adding some random test text :slight_smile:

P.S.: Thank you a ton for being such an impressive contributor to this forum (and also other forums like KM!). I learnt a ton from you.

1 Like

Is there a way of having this script show x-devonthink-item:// links as well as wiki links? I have occasion to use those so it’d be great if the back links for those were also listed.

Hi @Bernardo_V,
Your script is exactly what I need, but for some reason I can make it work.
I want to use it as a smart rule, but it behaves strangely.
If I give a file more than one alias, then it will not return any link.
What am I doing wrong?

Hi @Bernardo_V
I set up Version B of your wonderful script. I test it in a test database.
After using it, it only works on Pdf reference file; but didn’t does anything on md and rtf files.
Is there any configuration that I missed to take?
I used the last version on GitHub.



My suggestion would to test in a separate database and with more files.
See if that helps!

Thanks. I will check it with my main database.