AngusSanto 0 Posted May 17, 2019 Share Posted May 17, 2019 Hi, I'm looking for some help on quite a specific project. I'm new to using Script Editor on Mac, but have successfully used it to move all of my notes from Apple Notes to Evernote. However, now I would like to bulk rename all of the notes in this way: I would like to move the current title (the text on the first line of the note) to become the second line of each note, and move the second line of each note to become the title. Is this possible? I found this script to bulk rename notes but it doesn't have this level of functionality (https://gist.github.com/brandonpittman/5994734) Link to comment
Level 5* DTLow 5,735 Posted May 17, 2019 Level 5* Share Posted May 17, 2019 On 5/16/2019 at 11:15 PM, AngusSanto said: I would like to move the current title (the text on the first line of the note) to become the second line of each note, and move the second line of each note to become the title. Yes, it's possible, You retrieve the note's content using set theText to HTML content of theNote Parse the text, update Use the reverse to update the note's content The parsing is a bit awkward because you're working with html instead of plain text Setting the note title is simple set title of theNote to ....... Link to comment
Level 5* JMichaelTX 4,115 Posted May 17, 2019 Level 5* Share Posted May 17, 2019 14 hours ago, AngusSanto said: However, now I would like to bulk rename all of the notes in this way: I would like to move the current title (the text on the first line of the note) to become the second line of each note, and move the second line of each note to become the title. Is this possible? Yes, this is definitely possible using AppleScript. Options: Just Set the Note Title The easy part is extracting the second line of each Note, and setting the Note title to it. Changing the Note Body Use HTML of the Body -- Ignore Images & Attachments AppleScript allows us to read/set the HTML of a note. You will lose any images or attachments in the Note. Use Full ENML of the Body Much harder is changing the Note Body that contains images and/or attachments.. This is because Evernote AppleScript does NOT allow us to read the full ENML of the Note that includes images and attachments. I can definitely help you with Option #1, and maybe #2.1. Option 2.2 would require more time than I have available right now. So, if you'd like to get something done quickly, go with Option #1. One thing you should do now, if you have not already done so, is to tag all Notes you imported from Apple Notes that need to have the Title changes. This will allow you to immediately continue to use Evernote and add new Notes. What would you like to do? Link to comment
Level 5* DTLow 5,735 Posted May 17, 2019 Level 5* Share Posted May 17, 2019 On 5/17/2019 at 2:09 PM, JMichaelTX said: You will lose any images or attachments in the Note. We can update the enml/html content without impacting images or attachments - be careful not to adjust the code lines for media xref There's some translation for html <> enml/html, but it seems to be working well edited; Added sample code, extract note content, update, overwrite note contents tell application "Evernote" set theNote to item 1 of (get selection) set theText to HTML content of theNote <<<< Retrieve note contents set theText to theText & "Updated Note Content" <<<< Minor Update to the note contents set HTML content of theNote to theText <<<< Overwrite note contents --set title of theNote to ....... end tell Link to comment
Level 5* JMichaelTX 4,115 Posted May 18, 2019 Level 5* Share Posted May 18, 2019 2 hours ago, DTLow said: We can update the HTML content without impacting inages or attachments Please share your code if you have found a way to do this. In my testing it always dropped images, attachments, and even the Evernote checkboxes. Link to comment
Level 5* JMichaelTX 4,115 Posted May 18, 2019 Level 5* Share Posted May 18, 2019 22 hours ago, DTLow said: We can update the enml/html content without impacting inages or attachments - be careful not to adjust the code lines for media xref There's some translation for html <> enml/html, but it seems to be working well edited; Added sample code @DTLow, well done sir! 👍 I can confirm your script works, and retains everything in the Note, including: images, attachments, checkboxes, lists. NOTE: Running Evernote 6.11.1 (455059) on macOS 10.12.6. I also testing adding at the top, and that also worked: set theText to "Updated Note Content at TOP" & theText -- Insert at top of Note I will now test changing the first few lines. Link to comment
Level 5* DTLow 5,735 Posted May 18, 2019 Level 5* Share Posted May 18, 2019 22 hours ago, JMichaelTX said: I will now test changing the first few lines. fwiw The screenshot below shows the HTML content of my test note. It's one continuous string, I inserted line breaks for clarity Keeping this simple, notice that each "line" begins with <div I use AppleScript's text delimiters to parse the contents into "lines", and again to reassemble the contents edited; Added sample code, extract note content, parse, update, unparse, overwrite note contents tell application "Evernote" set theNote to item 1 of (get selection) set theText to HTML content of theNote -- retrieve the note contents set oldDelims to AppleScript's text item delimiters set AppleScript's text item delimiters to {"<div"} set noteLines to every text item of theText -- parse the content into note lines set updatedNoteLines to {} repeat with i from 1 to count of noteLines -- pass through every note line set end of updatedNoteLines to (item i of noteLines) -- copy to updated note lines, do updates end repeat (this is the place to switch lines 1 and 2) set updatedText to the updatedNoteLines as string -- unparse the updated note lines set HTML content of theNote to updatedText --- overwrite note contents --set title of theNote to ....... set AppleScript's text item delimiters to oldDelims end tell Link to comment
Level 5* JMichaelTX 4,115 Posted May 19, 2019 Level 5* Share Posted May 19, 2019 4 hours ago, DTLow said: I was thinking of using AppleScript's text delimiters to parse the contents into note lines, That would work if the HTML is always nice, neat, and orderly as you show. In my testing I have found it can vary quite a bit. So I'm using RegEx. I have three RegEx patterns currently in place, and the script tries each one until one works. After a bit more testing and cleanup, I'll post my script. @AngusSanto, are you still interested in an AppleScript solution? Please let us know. I have a solution I'm testing that will do this: Extract the first two lines of the Note body Set the Note Title to the 2nd body line Insert the original Title at top of Note Body. Would that work for you? Link to comment
AngusSanto 0 Posted May 19, 2019 Author Share Posted May 19, 2019 @JMichaelTX @DTLow Thanks so much for your responses - I would love to see your solution JMichaelTX as that sounds like exactly what I need and I haven’t had time to look at the simple option 1 solution myself yet - if you have space would love to see your script Link to comment
Level 5* DTLow 5,735 Posted May 19, 2019 Level 5* Share Posted May 19, 2019 17 hours ago, JMichaelTX said: That would work if the HTML is always nice, neat, and orderly as you show. In my testing I have found it can vary quite a bit. Agreed, the HTML code can get complex. My intention is to ignore the code as much as possible and just focus on switching lines 1 and 2. Also updating the title, which requires stripping the html code from the line Link to comment
Level 5* JMichaelTX 4,115 Posted May 20, 2019 Level 5* Share Posted May 20, 2019 On 5/17/2019 at 1:15 AM, AngusSanto said: However, now I would like to bulk rename all of the notes in this way: I would like to move the current title (the text on the first line of the note) to become the second line of each note, and move the second line of each note to become the title. Is this possible? @AngusSanto and @DTLow: I have a BETA solution you guys can test that will do this: Extract the 2nd Line of the Note body based on the Plain Text of the Note Set the Note Title to the 2nd body line Insert the original Title at top of Note Body. I'm still testing, but thought I'd let you guys get in on the fun. 😎 I started out using RegEx, and found 3 patterns that would work, but there can be just too much variation in how the first two lines are set (formatting, links, etc). So, I resorted to a simpler solution: Convert the HTML to Plain Text, and get the first two non-blank lines. DO NOT TEST ON A REAL NOTE. Just do a Duplicate (⌘D) of one of your target notes, and use the dup. Please let me know if this works for you and if you have any issues or desired changes (no promises). property ptyScriptName : "Set Evernote Note Title to 2nd Body Line Using Plain Text -- TEST" property ptyScriptVer : "BETA 2.0" property ptyScriptDate : "2019-05-19" property ptyScriptAuthor : "JMichaelTX" (* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PURPOSE: • Update Evernote Note Title and Body Using HTML • Set Note Title to 2nd Body Line • Insert Original Note Title at Top of Body RETURNS: Revised Evernote Note REQUIRED: 1. macOS 10.11.6+ 2. Mac Applications • Evernote Mac 6.11.1+ TAGS: @SW.EN @CAT.Notes @CAT.HTML @type.Example REF: The following were used in some way in the writing of this script. 1. 2019-05-17, DTLow, Evernote User Forum Bulk Rename Notes with Script Editor https://discussion.evernote.com/topic/120023-bulk-rename-notes-with-script-editor/?do=findComment&comment=537798 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *) use AppleScript version "2.5" -- El Capitan (10.11) or later use framework "Foundation" -- this may not be required use framework "AppKit" -- this may not be required use scripting additions property LF : linefeed tell application "Evernote" set oNote to item 1 of (get selection) tell oNote set noteTitle to title set noteBodyHTML to HTML content -- Retrieve note contents set noteBodyPtxt to my HTMLDecode(noteBodyHTML) set nbLines to paragraphs of noteBodyPtxt --- Extract the 2nd Line of Text --- -- (ignoring blank lines) set lineCount to 0 repeat with oLine in nbLines if ((contents of oLine) ≠ "") then set lineCount to lineCount + 1 if (lineCount ≥ 2) then set nbLine2 to contents of oLine exit repeat end if end repeat --- Replace Unusual "Â" Character with Space --- set nbLine2Clean to my regexChange("Â", " ", nbLine2) --- REPLACE INVISIBLE CHARS FOUND IN SOME HTML (like OUTLOOK 2011) WITH SPACE --- -- set nbLine2Clean to regexChange("\\x{A0}|\\x{2028}", " ", nbLine2Clean) set bodyLine2 to nbLine2Clean --- Change Note Title to 2nd Body Line --- set title to bodyLine2 --- Insert Original Title at Top of Body --- set HTML content to ("<div>" & noteTitle & "</div>") & noteBodyHTML display dialog ¬ "Note Title Has Been Revised" & LF & LF & "FROM: " & tab & noteTitle ¬ & LF & "TO: " & tab & bodyLine2 ¬ with title ptyScriptName buttons {"Cancel", "OK"} default button "OK" end tell end tell --~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ on regexChange(pFindStr, pReplaceStr, pSourceStr) -- @RegEX @Change @Replace @Strings @ASObjC --––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– (* VER: 2.0 2018-07-06 PURPOSE: Change ALL Occurances of pFindStr into pReplaceStr in pSourceStr METHOD: Uses ASObjC RegEx (which is based on ICU Regex) PARAMETERS: • pFindStr | text | RegEx Pattern to Find • pReplaceStr | text | Replace string which • May contain these RegEx MetaChars: \\n, \\r, \\t for linefeed, return, and tab $<CG>, where <CG> is Capture Group number • pSourceStr | text | Source String to be searched RETURNS: Revised String with all changes that were found. AUTHOR: JMichaelTX -- with help from NigelGarvey ## REQUIRES: use framework "Foundation" REF: 1. 2018-07-06, NigelGarvey, Late Night Software Ltd. ASObjC RegEx Change Handler http://forum.latenightsw.com/t/asobjc-regex-change-handler/1395/10 2. ICU RegEx Users Guide http://userguide.icu-project.org/strings/regexp --––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– *) set nsCurApp to current application -- Replace any backslash-n sequences in the replace string with actual character -- set nsReplaceStr to nsCurApp's NSString's stringWithString:pReplaceStr set nsReplaceStr to nsReplaceStr's stringByReplacingOccurrencesOfString:"\\n" withString:(linefeed) set nsReplaceStr to nsReplaceStr's stringByReplacingOccurrencesOfString:"\\r" withString:(return) set nsReplaceStr to nsReplaceStr's stringByReplacingOccurrencesOfString:"\\t" withString:(tab) set nsSourceStr to nsCurApp's NSString's stringWithString:pSourceStr set nsSourceStr to (nsSourceStr's stringByReplacingOccurrencesOfString:pFindStr withString:nsReplaceStr options:(nsCurApp's NSRegularExpressionSearch) range:{0, nsSourceStr's |length|()}) return nsSourceStr as text end regexChange --~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ on HTMLDecode(HTMLString) -- @HTML @Strings @Decode @Convert @Text @PlainText @ASObjC -------------------------------------------------------------------------------------- (* From: Shane Stanley <sstanley@myriad-com.com.au> Date: Thu, Jun 16, 2016 at 8:56 PM To: "ASUL (AppleScript)" <applescript-users@lists.apple.com> Subject: Re: Convert HTML Text to Plain Text -- ASObjC handler is 2.03 X as fast as Shell Handler *) -- make it an NSString set theString to current application's NSString's stringWithString:HTMLString -- get raw data set theData to theString's dataUsingEncoding:(current application's NSUTF8StringEncoding) -- convert to attributed string set attStr to current application's NSAttributedString's alloc()'s initWithHTML:theData documentAttributes:(missing value) -- extract just the text set plainText to attStr's |string|() as text --- REPLACE INVISIBLE CHARS FROM OUTLOOK WITH SPACE --- -- set plainText to regexChange("\\x{A0}|\\x{2028}", " ", plainText) return plainText end HTMLDecode Link to comment
Level 5* DTLow 5,735 Posted May 20, 2019 Level 5* Share Posted May 20, 2019 1 hour ago, JMichaelTX said: I have a BETA solution you guys can test Extract the 2nd Line of the Note body based on the Plain Text of the Note Set the Note Title to the 2nd body line Insert the original Title at top of Note Body. Reviewing the content.enml file for the note I see the original Title inserted as a first line[x] The original contents are now located in a sub div level You might want to review your "insert" process Link to comment
Level 5* JMichaelTX 4,115 Posted May 20, 2019 Level 5* Share Posted May 20, 2019 2 hours ago, DTLow said: The original contents are now located in a sub div level So? I don’t see the issue. The actual note looks fine in my testing. Do you see something in the updated note that is incorrect? Link to comment
Level 5* DTLow 5,735 Posted May 20, 2019 Level 5* Share Posted May 20, 2019 6 hours ago, JMichaelTX said: The actual note looks fine in my testing. Agreed; The actual note looks fine in the Evernote display. >>Do you see something in the updated note that is incorrect? My testing feedback included something in the updated note that is incorrect. >>So? I don’t see the issue. I don't know the impact. Link to comment
Level 5* JMichaelTX 4,115 Posted May 20, 2019 Level 5* Share Posted May 20, 2019 2 hours ago, DTLow said: My testing feedback included something in the updated note that is incorrect. Sorry, I don't see anything in the ENML or HTML that is incorrect. The "extra" <div> is perfectly legal HTML, and causes no problems. As long as the Note displays properly that is all that matters. @AngusSanto, how is the script working for you? Any issues? Link to comment
AngusSanto 0 Posted May 20, 2019 Author Share Posted May 20, 2019 @JMichaelTX Thanks so much - going to test it out today and I’ll let you know how it goes Link to comment
AngusSanto 0 Posted May 21, 2019 Author Share Posted May 21, 2019 @JMichaelTX Sorry for the delay, been a long day, just trying to work with the script now - It seems to work as I originally described but I've realised I made a mistake in the way I described what I was looking to do - rather than the second line of the body I need to make the title the first line of the body - I was getting confused and assumed that the title was already the first line. The script is a bit beyond my level so I haven't been able to figure out how to change it to apply to the first line rather than the second, could you help with this? Other than that the script works, although at the moment it only automatically applies to the last created note for me - is there a way to get it to apply to all of the notes in a specific folder or with a specific tag? Link to comment
Level 5* DTLow 5,735 Posted May 21, 2019 Level 5* Share Posted May 21, 2019 7 hours ago, AngusSanto said: could you help with this? I have a different style in providing assistance. You write/update the script; if you run into issues, I'll give advice Take it slow; don't address the entire script in one pass; just one section at a time Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime >>is there a way to get it to apply to all of the notes in a specific folder or with a specific tag? These are the lines identifying the notes being updated; item 1 of the Selected Notes To use the entire set of Selected Notes, use set selectedNotes to get selection This returns a string of notes. You use a repeat loop to extract each note repeat with oNote in selectedNotes .... end repeat I think it's safer to use Selected Notes, but using a search string is possible - example: set theNotes to find notes ("tag:aaaaaaaa") >>I need to make the title the first line of the body In the script, these are the lines identifying the line being extracted for the title It's currently line 2, change it to line 1 Short form is: set title to item 1 of nbLines Link to comment
AngusSanto 0 Posted May 25, 2019 Author Share Posted May 25, 2019 Hey guys, took me some time but I got it working this morning (I'm Australian). Here's my version of the script that swaps around the title of the note and the first line of the body, based on all the notes you have selected in Evernote. I removed the dialog box from JMichaelTX's code for my own convenience property ptyScriptName : "Set Evernote Note Title to 2nd Body Line Using Plain Text -- TEST" property ptyScriptVer : "BETA 2.0" property ptyScriptDate : "2019-05-19" property ptyScriptAuthor : "JMichaelTX" (* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PURPOSE: • Update Evernote Note Title and Body Using HTML • Set Note Title to 2nd Body Line • Insert Original Note Title at Top of Body RETURNS: Revised Evernote Note REQUIRED: 1. macOS 10.11.6+ 2. Mac Applications • Evernote Mac 6.11.1+ TAGS: @SW.EN @CAT.Notes @CAT.HTML @type.Example REF: The following were used in some way in the writing of this script. 1. 2019-05-17, DTLow, Evernote User Forum Bulk Rename Notes with Script Editor https://discussion.evernote.com/topic/120023-bulk-rename-notes-with-script-editor/?do=findComment&comment=537798 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *) use AppleScript version "2.5" -- El Capitan (10.11) or later use framework "Foundation" -- this may not be required use framework "AppKit" -- this may not be required use scripting additions property LF : linefeed tell application "Evernote" set selectedNotes to (get selection) repeat with oNote in selectedNotes tell oNote set noteTitle to title set noteBodyHTML to HTML content -- Retrieve note contents set noteBodyPtxt to my HTMLDecode(noteBodyHTML) set nbLines to paragraphs of noteBodyPtxt --- Extract the 2nd Line of Text --- -- (ignoring blank lines) set lineCount to 0 repeat with oLine in nbLines if ((contents of oLine) ≠ "") then set lineCount to lineCount + 1 if (lineCount ≥ 1) then set nbLine2 to contents of oLine exit repeat end if end repeat --- Replace Unusual "Â" Character with Space --- set nbLine2Clean to my regexChange("Â", " ", nbLine2) --- REPLACE INVISIBLE CHARS FOUND IN SOME HTML (like OUTLOOK 2011) WITH SPACE --- -- set nbLine2Clean to regexChange("\\x{A0}|\\x{2028}", " ", nbLine2Clean) set bodyLine2 to nbLine2Clean --- Change Note Title to 2nd Body Line --- set title to bodyLine2 --- Insert Original Title at Top of Body --- set HTML content to ("<div>" & noteTitle & "</div>") & noteBodyHTML end tell end repeat end tell --~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ on regexChange(pFindStr, pReplaceStr, pSourceStr) -- @RegEX @Change @Replace @Strings @ASObjC --––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– (* VER: 2.0 2018-07-06 PURPOSE: Change ALL Occurances of pFindStr into pReplaceStr in pSourceStr METHOD: Uses ASObjC RegEx (which is based on ICU Regex) PARAMETERS: • pFindStr | text | RegEx Pattern to Find • pReplaceStr | text | Replace string which • May contain these RegEx MetaChars: \\n, \\r, \\t for linefeed, return, and tab $<CG>, where <CG> is Capture Group number • pSourceStr | text | Source String to be searched RETURNS: Revised String with all changes that were found. AUTHOR: JMichaelTX -- with help from NigelGarvey ## REQUIRES: use framework "Foundation" REF: 1. 2018-07-06, NigelGarvey, Late Night Software Ltd. ASObjC RegEx Change Handler http://forum.latenightsw.com/t/asobjc-regex-change-handler/1395/10 2. ICU RegEx Users Guide http://userguide.icu-project.org/strings/regexp --––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– *) set nsCurApp to current application -- Replace any backslash-n sequences in the replace string with actual character -- set nsReplaceStr to nsCurApp's NSString's stringWithString:pReplaceStr set nsReplaceStr to nsReplaceStr's stringByReplacingOccurrencesOfString:"\\n" withString:(linefeed) set nsReplaceStr to nsReplaceStr's stringByReplacingOccurrencesOfString:"\\r" withString:(return) set nsReplaceStr to nsReplaceStr's stringByReplacingOccurrencesOfString:"\\t" withString:(tab) set nsSourceStr to nsCurApp's NSString's stringWithString:pSourceStr set nsSourceStr to (nsSourceStr's stringByReplacingOccurrencesOfString:pFindStr withString:nsReplaceStr options:(nsCurApp's NSRegularExpressionSearch) range:{0, nsSourceStr's |length|()}) return nsSourceStr as text end regexChange --~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ on HTMLDecode(HTMLString) -- @HTML @Strings @Decode @Convert @Text @PlainText @ASObjC -------------------------------------------------------------------------------------- (* From: Shane Stanley <sstanley@myriad-com.com.au> Date: Thu, Jun 16, 2016 at 8:56 PM To: "ASUL (AppleScript)" <applescript-users@lists.apple.com> Subject: Re: Convert HTML Text to Plain Text -- ASObjC handler is 2.03 X as fast as Shell Handler *) -- make it an NSString set theString to current application's NSString's stringWithString:HTMLString -- get raw data set theData to theString's dataUsingEncoding:(current application's NSUTF8StringEncoding) -- convert to attributed string set attStr to current application's NSAttributedString's alloc()'s initWithHTML:theData documentAttributes:(missing value) -- extract just the text set plainText to attStr's |string|() as text --- REPLACE INVISIBLE CHARS FROM OUTLOOK WITH SPACE --- -- set plainText to regexChange("\\x{A0}|\\x{2028}", " ", plainText) return plainText end HTMLDecode Link to comment
Level 5* DTLow 5,735 Posted May 25, 2019 Level 5* Share Posted May 25, 2019 2 hours ago, AngusSanto said: Here's my version of the script that swaps around the title of the note and the first line of the body Glad to see you got it working A point on inserting noteTitle into the HTML content. The first line specifies the en-note container I would look into inserting after this line. You extracted a line from the note contents. Should it be deleted? Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now