Jump to content

Auto-create internal links?


Recommended Posts

I stumbled across a feature in another piece of software I would love to try and recreate for Evernote and thought it might be doable in Evernote Mac with AppleScript. However, I know nothing about how to create AppleScripts with Evernote

I would love to add a keyword phrase within brackets (or manually highlight the string) and have AppleScript search for a note with this title and set a link to it.

Any help or guidance on if and how this is possible with AppleScript (or other software) would be greatly appreciated!

Link to comment
  • Level 5*
6 hours ago, Nick Lane said:

I would love to add a keyword phrase within brackets (or manually highlight the string) and have AppleScript search for a note with this title and set a link to it.

To search for a note with this title, the search argument is   intitle:"this title"
I wrote this script      searchtitle.scpt
                                    set searchQuery to "intitle:\"this title\""
                                     
tell application "Evernote" to find notes searchQuery
Code refinement is required for setting the value of variable searchQuery

>>add a keyword phrase within brackets (or manually highlight the string)
This is do-able but do you really want to type a note title?
What if there's multiple notes matching this title?  
What if there's no match?

>>set a link to it
This is do-able
It requires formatting the proper html code and inserting into the original note

>>Any help or guidance on if and how this is possible with AppleScript (or other software) would be greatly appreciated!

I'm willing to walk you through the coding elements for this.   
It sounds like an interesting script

Link to comment

Thanks @DTLow for the reply! To answer your questions, I was thinking the same. Here’s where I currently stood on those...

  1. I don’t mind typing a note title, it was meant to be a reference to the note I’d be typing it for. Hopefully I’m interpreting your question on this correctly.
  2. if multiple match, and I know that to be true scenario for me, it would be INCREDIBLE to get a drop down to choose from, that shows a list of possible matches with title/created date. However, coming back down from the cloud in the sky, I would gladly default to most recent. I know it’s not fool-proof, but for my purposes it would still serve well 99% of the time.
  3. No match? No link.

i’m not familiar with proper HTML formatting for Evernote. I am familiar with HTML in general. I have no prior experience with AppleScript, but I guess we’ve got to start somewhere :)

Greatly appreciate any assistance! 🙏🏻

Link to comment
  • Level 5*

>>2. if multiple match, and I know that to be true scenario for me, it would be INCREDIBLE to get a drop down to choose from, that shows a list of possible matches with title/created date.

This is do-able

>> 3. No match? No link.

I'd like to give the option to create a new note

 

To get you started on scripting

  1. Download the script file searchtitle.scpt601862308_ScreenShot2020-05-25at6_29_30AM.png.6214e484443adc162ee240970b5bf54d.png
    Just store it on your desktop; we'll work on the proper location later
     
  2. Right Click the file on your desktop and select Open
    This launches the Script Editor app installed on your Mac

    You'll see your script commands for editing
    and icons for Run and Compile
     
  3. Script Editor > File > Open Dictionary > Evernote51432595_ScreenShot2020-05-25at6_36_01AM.png.b86cb44e63f2cc8060a07358514ba9d1.png
    will show all the Evernote scriptable information

 

Let me know when you're ready to proceed
I'm thinking we could work on    
- refining the "this title" search criteria   
- Script Menu and the proper location for the script file

Link to comment

Thanks! So far, I've ran the script from the editor and it's returning the correct result in a data array.

Had a thought, it might be beneficial if we kept it to this array of possible results, in a way we could choose one to apply as a link, so we wouldn't have to target the exact title. That may work better (which I think alludes to your original question).

Link to comment
  • Level 5*

>>if we kept it to this array of possible results, in a way we could choose one to apply as a link, so we wouldn't have to target the exact title.

Agreed, in fact we'll keep the title, date, link in an array (actually called a list)

 

But first, let's look at Script Menu because it's such a cool feature1918715026_ScreenShot2020-05-25at1_01_34PM.png.1c66b9f5decfcb96068c0f9378efd92f.png
Turn on the feature in Script Editor > Preferences

This adds the Script Editor to the upper Mac Menu
It gives us an easy way to launch scripts and a folder to store scripts
- to launch a script, click on a menu entry
- to edit a script, option-click on a menu entry

 

In the screenshot, I moved the searchtitle.scpt file from the desktop and you can see it listed at the bottom of the screenshot
2024116201_ScreenShot2020-05-25at1_00_42PM.png.b195f454a4decf24cbb789c9220f1247.png

Link to comment
  • Level 5*

>>add a keyword phrase within brackets (or manually highlight the string)

I'm working on using the selected text as the keyword phrase
The only way I know to do this is through the clipboard

We can capture the selected text using Command C
This can be coded in the script, but we'll leave that for later; for now, just use Command C manually
My focus is on using the selected text

I modified the search query as follows
          set selectedText to the clipboard
          set searchQuery to "intitle:\"" & selectedText & "\""
          tell application "Evernote" to find notes searchQuery

Let me know when you're ready for the next step
My intention is to start capturing the data from the search

Link to comment

Cool feature! I wasn't aware. I'll check it out!

I was trying to add it as a right-click "Services" menu item, but wasn't getting anywhere. I thought that might be cool to highlight the word and quickly right-click. A keyboard shortcut might be a good idea as well. I do have TextExpander installed and thought I might be able to come up with something for it.

In the script editor, I was experimenting with something similar! I was stuck on how to pass that selectedText to the tell statement. 

tell application "System Events" to keystroke "c" using {command down}
delay 1
set selectedText to the clipboard

 

Link to comment

I have the scripts available now in my toolbar, thanks! I've saved what I had so far to this file. Testing directly in the scripts editor gets the correct result. If I highlight text in the Evernote note, and then select the script from the toolbar, nothing is happening yet.

tell application "System Events" to keystroke "c" using {command down}
delay 1
set selectedText to the clipboard
set searchQuery to "intitle:\"" & selectedText & "\""
tell application "Evernote" to find notes searchQuery

 

Link to comment
  • Level 5*
12 minutes ago, Nick Lane said:

 


tell application "System Events" to keystroke "c" using {command down}
delay 1
set selectedText to the clipboard

 

This is the method I use to capture selected text to the clipboard
There is a flaw; Command C functions in the active window

The text is selected in the Evernote window
If you're working in a Script Editor window - this has now become the active window

 

I'm still working on capturing the data from the search; I'll get back shortly

  • Like 1
Link to comment
  • Level 5*
14 minutes ago, Nick Lane said:

A keyboard shortcut might be a good idea as well.

I use keyboard shortcuts to run my scripts

This can be set in the Automator > Service Feature
Also third party products Fastscripts and Keyboard Maestro

We can get back to this later

Link to comment
  • Level 5*

>>working on capturing the data from the search

I'm using a handler (procedure) called CollectnoteData to process the notes and return a list called noteData
I used display dialog statements to provide some feedback on the process

 

     set selectedText to the clipboard
     
set searchQuery to "intitle:\"" & selectedText & "\""
     
display dialog searchQuery                              << Troubleshooting

     set noteData to CollectnoteData(searchQuery)

 

     on CollectnoteData(searchQuery)             << Applescript Handler (procedure)

          set noteData to {}
          
tell application "Evernote"
               
set theNotes to find notes searchQuery

               repeat with theNote in theNotes
                    
set theTitle to title of theNote
                    
set theDate to creation date of theNote
                    
set theLink to note link of theNote
                   
display dialog theTitle & " " & theDate & theLink      << Troubleshooting
                   set end of noteData to {theTitle & " " & theDate, theLink}
               end repeat        

         end tell

         return noteData

     end CollectnoteData

Link to comment
  • Level 5*

>>get a drop down to choose from (Part 1)

At this point, we have the raw noteData containing the title/date and link
I'm converting this to a drop down list noteInfo
and displaying it using choose from list

     set selectedText to the clipboard
     set searchQuery to "intitle:\"" & selectedText & "\""

     set noteData to CollectnoteData(searchQuery)

     set noteList to {}
     set
i to 0
     repeat with
noteInfo in noteData
          
set i to i + 1
          
set end of noteList to i & " " & item 1 of noteInfo as string
     end repeat

    set theSelectedNotes to (choose from list noteList with prompt "Select Note")795853357_ScreenShot2020-05-25at3_42_36PM.png.3abf0e2af76d34f148562ebdc5b1f7f0.png

  • Like 1
Link to comment
  • Level 5*
12 minutes ago, Nick Lane said:

So CollectnoteData is a custom function you're creating?

Right
My purpose is to segregate the code from the primary flow

  • Like 1
Link to comment
  • Level 5*

>>>>get a drop down to choose from (Part 2)

Notes
- segregated the ObtainNoteLink code to a handler
- added a bypass if no notes found matching the search query
- added an index # to the drop down list because Evernote fails to identify the exact selection   
- added the search criterIa to the drop down header 

set selectedText to the clipboard

set searchQuery to "intitle:\"" & selectedText & "\""   
set theLink to ObtainNoteLink(searchQuery)            

 

on ObtainNoteLink(searchQuery)        << segregated the ObtainNoteLink code to a handler
     set theLink to ""
     
set noteData to CollectNoteData(searchQuery)

     if noteData is not {} then                        << added bypass if no notes found matching the search query          
          
set noteList to {}
          
set i to 0
          
repeat with noteInfo in noteData
               
set i to i + 1
               
set end of noteList to i & " " & item 1 of noteInfo as string    <<added an index # to the drop down list
          end repeat

          set i to (words 1 thru 1 of item 1 of (choose from list noteList with prompt "Select Note from " & searchQuery)) as integer
          
set theNote to item i of noteData
          
set theLink to item 2 of theNote
    
end if

     return theLink

end ObtainNoteLink

Next on the list is to update the original note with the link

Link to comment
  • Level 5*

>>manually select the string set a link to it

Notes
- capture the Orignal Note so it can be modified
- obtain the link (previously developed handlers)
- retrieve the HTML Code for the Original Note
  modify the HTML Code (uses a Replace_Text handler I borrowed from another user)
  replace the HTML Code

     tell application "Evernote" to set theOriginalNote to item 1 of (get selection)     <<capture the Orignal Note
     
tell application "System Events" to keystroke "c" using {command down}               and selected text
     
delay 1
     set selectedText to the clipboard
     
set searchQuery to "intitle:\"" & selectedText & "\""

     set theLink to ObtainNoteLink(searchQuery)                        <<obtain the link

     if theLink is not "" then
          
set theLinkHTML to "<a href=\"" & theLink & "\">" & selectedText & "</a>"
          
tell application "Evernote"
               
set theHTMLCode to HTML content of theOriginalNote            <<HTML Code for the Original Note
               set theHTMLCode to my Replace_Text(theHTMLCode, selectedText, theLinkHTML)|
               
set HTML content of theOriginalNote to theHTMLCode
          
end tell
     
end if

 

     on Replace_Text(this_text, search_string, replacement_string)
          
set prevTIDs to AppleScript's text item delimiters
          
set AppleScript's text item delimiters to the search_string
          
set the item_list to every text item of this_text
          
set AppleScript's text item delimiters to the replacement_string
          
set this_text to the item_list as string
          
set AppleScript's text item delimiters to prevTIDs
          
return this_text
    
end Replace_Text


This is the final step    
There can be some code refinements; let me know if you need assistance

 

Link to comment

This is fantastic! Thank you so much @DTLow for making this a reality! I really appreciate it and plan to dig into it further to learn each aspect of this code. I hope you find it just as useful.

Below is the full source I'm running at the moment. A few comments I had, I'm not sure what options you'd recommend.

1. In the note selector that pops up, the date overpowers the title. Might recommend minimizing date format and/or perhaps add some type of delimiter.

2. My pop-up window starts at 1 line only; even if there's more than one option to choose from. Is there a way to increase its height or make height dynamic? See screenshot attached.

3. If it doesn't find a match, should we display a dialog that indicates this?

tell application "Evernote" to set theOriginalNote to item 1 of (get selection)
tell application "System Events" to keystroke "c" using {command down}
delay 1
set selectedText to the clipboard
set searchQuery to "intitle:\"" & selectedText & "\""

set theLink to ObtainNoteLink(searchQuery)

if theLink is not "" then
	set theLinkHTML to "<a href=\"" & theLink & "\">" & selectedText & "</a>"
	tell application "Evernote"
		set theHTMLCode to HTML content of theOriginalNote
		set theHTMLCode to my Replace_Text(theHTMLCode, selectedText, theLinkHTML)
		set HTML content of theOriginalNote to theHTMLCode
	end tell
end if

on Replace_Text(this_text, search_string, replacement_string)
	set prevTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to the search_string
	set the item_list to every text item of this_text
	set AppleScript's text item delimiters to the replacement_string
	set this_text to the item_list as string
	set AppleScript's text item delimiters to prevTIDs
	return this_text
end Replace_Text

on CollectnoteData(searchQuery)
	
	set noteData to {}
	tell application "Evernote"
		set theNotes to find notes searchQuery
		
		repeat with theNote in theNotes
			set theTitle to title of theNote
			set theDate to creation date of theNote
			set theLink to note link of theNote
			display dialog theTitle & " " & theDate & theLink
			set end of noteData to {theTitle & " " & theDate, theLink}
		end repeat
		
	end tell
	
	return noteData
	
end CollectnoteData

on ObtainNoteLink(searchQuery)
	set theLink to ""
	set noteData to CollectnoteData(searchQuery)
	
	if noteData is not {} then
		set noteList to {}
		set i to 0
		repeat with noteInfo in noteData
			set i to i + 1
			set end of noteList to i & " " & item 1 of noteInfo as string
		end repeat
		
		set i to (words 1 thru 1 of item 1 of (choose from list noteList with prompt "Select Note from " & searchQuery)) as integer
		set theNote to item i of noteData
		set theLink to item 2 of theNote
	end if
	
	return theLink
	
end ObtainNoteLink

 

pop-up-sample-with-multiple-options.png

Link to comment
  • Level 5*
21 hours ago, Nick Lane said:

1. In the note selector that pops up, the date overpowers the title. Might recommend minimizing date format and/or perhaps add some type of delimiter.

This is do-able - I format the date to yyyy/mm/dd
Here's an example of code I use   set {year:yyyy, month:mmm, day:d, weekday:dddd} to theJournalDate
                                                            
set dd to (text -2 thru -1 of ("0" & d as text))
                                                             
set m to mmm as integer
                                                              
set mm to (text -2 thru -1 of ("0" & m as text))

>>2. My pop-up window starts at 1 line only; even if there's more than one option to choose from. Is there a way to increase its height or make height dynamic? See screenshot attached.

Sorry, I don't have an answer.  My drop down list is larger, and allows scrollin

>>3. If it doesn't find a match, should we display a dialog that indicates this?

Sure      Display Dialog "..."

My idea is to ask if a new note should be created
- the script can create a new note and generate a link   
               tell application "Evernote" to create note title selectedText

 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...