I've been trying to get this simple script to work, it's supposed to search for a string, replace it while applying some styling, e.g. setting the text bold and red.
Here's what I have so far:
tell application "Finder"
set fl to files of folder POSIX file "/Users/Sc/Desktop/app/" as alias list
end tell
repeat with f in fl
tell application "TextEdit"
open f
set text of front document to replace_chars(text of front document, "a", "0000") of me
end tell
end repeat
on replace_chars(this_text, search_string, replacement_string)
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set the size of replacement_string to 14
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 ""
return this_text
end replace_chars
However this produces an error, I understand why, but not sure how to go about styling it before replacement, any help would be appreciated.
TextEdit uses Cocoa Scripting's standard Text Suite implementation, which is pretty naff at the best of times. If you're doing whole-word replacement, the following should work:
tell application "TextEdit"
set aRef to a reference to (every word of document 1 where it is "OLDWORD")
set aRef's color to {65535, 0, 0}
set aRef's contents to "NEWWORD"
end tell
The same approach should also work for single-character or whole-paragraph replacement; just modify the every word of... query appropriately. In each case though, you must match exactly one word/character/paragraph and replace it with exactly one word/character/paragraph, otherwise you'll get hilarious off-by-N errors throughout subsequent matches[1] due to Cocoa Scripting being made of dumb and incompetent[2] (e.g. try changing a recurring word to two new words, e.g. "foo" -> "boo boo" to see what I mean).
Also, unlike Text Suite implementations found in better written apps, Cocoa Scripting's Text Suite provides no way to describe to text ranges (e.g. text (character i) thru (character j) of.../text i thru j of...), so it's impossible to tell TextEdit to match, say, "oo" in "baboon", "fool", "spitoon", etc. If you need to match arbitrary character ranges, you'll have to get the text into AppleScript and calculate the start and end of each match yourself.
[1] When making multiple replacements, CS's Text Suite first calculates the positions of all of the text ranges that need changed, and then performs each substitution starting at the first match and finishing at the last. Thus, any differences in the length of the new vs old text mean all of the remaining match indexes it already calculated are no longer correct because the characters previously at that position have now shifted to the left or right. To do the job right, CS should've calculated all the positions from first to last, and then replaced them starting at the last and working backwards to the first.
[2] (CocoaScripting.framework was originally designed by Cocoa developers who didn't understand how AppleScript works, and since then has been maintained by AppleScript developers who don't understand either. So it goes.)
TextEdit is not the best tool to search and replace styled text, for example the free TextWrangler has more powerful skills to do that.
Anyway, try this, it affects only one opened document in TextEdit
The "algorithm" is to calculate the offset of the search string, replace it with the replace string and keeps the location in a repeat loop. At the end reassign the changed text to the text object of TextEdit and change the style at the stored locations to {font: Helvetica Bold, size: 24 and color: red}.
property searchString : "a"
property replaceString : "0000"
tell application "TextEdit"
set completed to false
set ranges to {}
set theText to text of front document
set theSize to size of text of front document
repeat while completed is false
tell current application to set o to offset of searchString in theText
if o is 0 then
set completed to true
else
tell theText to set newText to text 1 thru (o - 1) & replaceString & text (o + (length of searchString)) thru -1
set end of ranges to o
copy newText to theText
end if
end repeat
set text of front document to theText
set size of text of front document to theSize
repeat with aRange in ranges
tell characters aRange thru (aRange + (length of replaceString) - 1) of front document
set size to 24
set its color to {65535, 0, 0}
set font to "Helvetica Bold"
end tell
end repeat
end tell
Since the other posters both noted how poorly suited TextEdit is for this task, allow me to make an "out of the box" suggestion: Use MS Word
The Find and Replace tool in Word can easily handle this task, and much more complicated replacements.
If you have a lot of source documents in RTF format, you could open them in Word, make the changes, and save back to the same (or different) RTF file. It would be very easy to create a Word VBA macro to do this.
You could then either write an AppleScript to open each RTF file in Word and run the macro, or you could do all of the processing using a master Word VBA. You could do it in either way, but I would choose the all VBA route since, IMO, it is a much better language for processing MS documents than AppleScript.
Of course, this requires that you have MS Word installed. I'm still running MS Office 2011 on all of my Macs, and don't plan to upgrade to Office 2016 for a while. Word 2011 works very well.
Good luck.
Related
I'm pretty newbie at Applescript and I can't work out how to remove a word from a variable if the word contains a “#” in it.
My script gets this error -> "Can’t make word into type integer." number -1700 from word to integer
Here's my script so far:
activate application "Grids"
delay 2
tell application "System Events"
keystroke "a" using command down
delay 0.25
keystroke "c" using command down
delay 0.25
set Description to the clipboard
if any word in Description contains "#" then delete that word
return Description
end tell
Any pointers?
Cheers,
Chris
To get text out of the clipboard, use (clipboard as text). The clipboard can contain almost anything, even multiple objects, in multiple formats, so as text gives you a string to work with.
And watch out: 'Description' appears to be part of some existing appleScript 'terminology', at least on the Mac I have right here, so I am changing your identifier to desc here:
activate application "Grids"
delay 2
tell application "System Events"
keystroke "a" using command down
delay 0.25
keystroke "c" using command down
delay 0.25
set desc to the clipboard as text
end tell
set out to {}
set tids to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
repeat with anItem in (text items of desc)
set str to (anItem as string)
if (str does not contain "#") then
set end of out to str
end if
end repeat
set outStr to out as string
set AppleScript's text item delimiters to tids
return outStr
This code just returns the text you are looking for. It does not re-insert the groomed string, or do anything else interesting.
I assume you're going to tell System Events to paste it via cmd-v. (Remember to set the clipboard to outStr before you paste!)
AppleScript's text item delimiters allows the string to be split and reassembled using a space (or any other token you wish). For code hygiene reasons, it's wise practice to store it before changing it, then reset it to its original value afterwards, as shown here, otherwise odd things might happen in scripts which expect it to have the default value.
How can I insert text from Chinese characters using AppleScript? All my attempts end with "aaaa aaaaaa aaaaaaa", I tried to find some information about using Unicode, but I failed.
I also tried to change the system language. This relatively helped, AppleScript actually started inserting hieroglyphs, but in the final result it didn't help, because only 1 hieroglyph was printed due to auto-correction and help in typing.
I'm making some guesses about what you're trying to do but this should allow for inserting text into a document (or the clipboard). I use TextEdit but it should work with any app that allows you to work similarly with text. In my example, I simply use your text as is, but you could get that text from the clipboard or another document (as provided for in the comments).
set srcIdeo to "你好,朋友!你好嗎?测试消息。" -- text taken from screen shot
--set srcIdeo to the clipboard
tell application "TextEdit"
-- list all Chinese characters to begin with
-- set srcIdeo to every character of document "sourceIdeo.txt"
set allChar to every character of srcIdeo
-- list unicode id of allChar
set chList to {}
repeat with i in allChar
copy id of i to end of chList
end repeat
end tell
-- list all Chinese characters to insert into text (doesn't work inside TextEdit tell block)
set chTx to ""
repeat with ch in chList
character id ch
set chTx to chTx & character id ch
end repeat
-- set the clipboard to chTx
-- insert into text
tell application "TextEdit" to set last paragraph of front document to chTx
--tell application "TextEdit" to set last paragraph of front document to the clipboard
(*
Example
allChar {"你", "好", ",", "朋", "友", "!", "你", "好", "嗎", "?", "测", "试", "消", "息", "。"}
chList {20320, 22909, 65292, 26379, 21451, 65281, 20320, 22909, 21966, 65311, 27979, 35797, 28040, 24687, 12290}
chTx "你好,朋友!你好嗎?测试消息。"
*)
Essentially, applescript uses a 16-bit dec (base10) code to represent the unicode 4-digit hex code. So for the first character '你', which the character viewer describes as below, the code U+4F60 translates to '20320' — which turns out to be a straight conversion from the hex to decimal. As an aside, it handles RGB colour codes in a similar manner.
CJK UNIFIED IDEOGRAPH-4F60
Unicode: U+4F60, UTF-8: E4 BD A0
In applescript…
id of "你"
character id 20320
From the AppleScript Language Guide, 124
Class Reference > text > Properties of text objects
https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_classes.html
Short answer, we can input non-ASCII characters with the clipboard:
tell application "System Events"
set textBuffer to "你好吗,朋友!"
repeat with i from 1 to count characters of textBuffer
set the clipboard to (character i of textBuffer)
delay 0.05
keystroke "v" using command down
end repeat
end tell
I need to remove the last character in a text string AppleScript. It's proving to the much more difficult problem than I thought.
can someone explain how this would be done?
Try this
set t to "this is a string"
text 1 thru -2 of t
Output:
"this is a strin"
Sympathies. It ought to be a trivial task (in most languages it's just a matter of calling a built-in "trim" function) but AppleScript has absolutely miserable library support and the community has done nothing to plug these gaps itself, so you have to roll your own ad-hoc handlers for even basic everyday stuff like this. For example:
on trimLastChar(theText)
if length of theText = 0 then
error "Can't trim empty text." number -1728
else if length of theText = 1 then
return ""
else
return text 1 thru -2 of theText
end if
end trimLastChar
You might consider investing in an AppleScript book (note: I co-wrote the Apress one), which tend to cover common text and list processing tasks much better than AppleScript's own documentation.
Another option is to call through to Cocoa via the AppleScript-ObjC bridge, giving you free access to a huge amount of ready-to-use functionality. It's a bit more work, but for more advanced text processing tasks it's often the simplest, safest, and most efficient solution. I recommend getting a copy of Shane Stanley's Everyday AppleScript-ObjC if/when you go that way.
tell application "Safari"
open location "https://www.youtube.com/watch?v=IxnD5AViu6k#t=152.07430805"
delay 1
end tell
delay 1
tell application "Safari"
set theURL to URL of front document as text
end tell
if theURL contains "#" then
repeat until theURL does not contain "#"
set theURL to text 1 thru -2 of theURL
end repeat
end if
I find this to be interesting http://applehelpwriter.com/2016/09/06/applescript-remove-characters-from-a-string/
Essentially, you can import Foundation to help you
use scripting additions
use framework "Foundation"
property NSString : a reference to current application's NSString
Here is how I remove the last path component
on myRemoveLastPath(myPath)
set myString to NSString's stringWithString:myPath
set removedLastPathString to myString's stringByDeletingLastPathComponent
removedLastPathString as text
end myRemoveLastPath
I am writing some text in to word file i want to change the color of that text any one can help on that one plz.
I want to print the 'message' from following script in red color.
Here is the Script:
set message to "mostly these windows are popup in application"
on ResultCreationFuction(message)
try
set text_to_save to message as text
tell application "System Events"
tell application "Finder"
set sortedList to sort (get files of folder "SofTestAutomationResult" of desktop) by modification date
set FileCount to get count of sortedList
set theFile to (item FileCount of sortedList) as alias
end tell
set file_ref to open for access theFile with write permission
write (text_to_save & return) to the file_ref starting at eof
close access file_ref
delay 2
end tell
end try
end ResultCreationFuction
Some Details:
The file is word which is all ready present on above location having name "10.012.2014_17_4_20.doc" (the name of .doc file is not fix)
What you are attempting is the wrong way to do it.
To manipulate content like that, including formatted text (not plain
text), you need to work within, ideally, a well-scriptable app, like
Pages (or Word, perhaps, but I don't have that on the machine I'm
writing this from).
Don't use System Events if you don't need to. Use the apps with the appropriate AppleEvents/dictionary, etc. If you don't know what I'm talking about, you need to take advantage of the infinite resource known as the web.
"Fuction" is just bad form.
I would suggest doing a lot more reading up on how AppleScript works (or scripting in general), but to start you out, here is a script I just wrote in pages which sets the color of a specific word of the open document after putting text in there:
tell application "Pages"
set body text of document 1 to "hello there mister fancy pants"
set color of word 3 of body text of page 1 of document 1 to {64614, 0, 111}
end tell
If you have Pages, try this by starting with a blank page and running this script. Obviously, you could get rid of "word 3 of" in the 2nd line, and the whole body text will be red.
I hope this makes sense and is of help.
[edit]
I should mention that even TextEdit is scriptable and can open Word documents. Here's an example using TextEdit:
tell application "TextEdit"
set text of document 1 to "hello mister fancy pants"
set color of words 2 thru 3 of text of document 1 to {65535, 0, 0}
end tell
There is a little danger of non-Word apps losing formatting of Word files. But it just seems you are attempting something very simple, and I'm not sure if Word is really necessary here.
You can't add color using the write to eof. You should open the document in Word and then insert the line and add the color. Here's a script that should demonstrate how:
set text_to_add to "mostly these windows are popup in application"
set theFile to ((path to desktop folder) & "10.012.2014_17_4_20.doc") as string
tell application "Microsoft Word"
set theFile to theFile as string -- assuming theFile is an alias or :: path
open file theFile
tell active document
set endOfDoc to end of content of text object -- insert the text to end of document
set theRange to create range start (endOfDoc - 1) end endOfDoc
insert text text_to_add at theRange
set myRange to create range start endOfDoc end (endOfDoc + (length of text_to_add))
set color index of font object of myRange to red
save
end tell
end tell
I just purchased Alfred App for my Mac and I want to use this script I found online:
---------------------------------------------------
--Modified by: Pontus Sundén, http://psu.se
--Icon from: http://findicons.com/pack/1362/private_eye_act_1
---------------------------------------------------
on alfred_script(strQuery)
--Get the parameters passed to the script - this is the search query
set strSearchCriteria to SpaceList(strQuery)
--Try to populated an existing window with the search query
tell application "Evernote"
try
set query string of window 1 to strSearchCriteria
on error
--No existing window, open an new one
open collection window with query string strSearchCriteria
end try
end tell
tell application "System Events" to set frontmost of process "Evernote" to true
end alfred_script
--Take a list of text items and retrun them as a string with a space between each item
on SpaceList(astrItems)
--Store what the current list delimiter is
set tmpDelimiters to AppleScript's text item delimiters
--Set the list delimiter to a space and build the string we want to pass back
set AppleScript's text item delimiters to " "
set strReturn to astrItems as string
--Set the list delimiter back to what it was previously
set AppleScript's text item delimiters to tmpDelimiters
--Return the string we built
return strReturn
end SpaceList
which should open up evernote and search for something. It works fine, but instead of searching for, say the word boat, it will search for "boat" with the double quotes and obviously this yields no matches.
Your script is perfectly correct – the spurious quoting of search terms passed via AppleScript is a known Evernote bug in version 3 of the client (well, “known” as in “I opened a support ticket for it a while ago, and Evernote acknowledged it”; I’d add a link to the ticket, but these are private to the user who opened it … will update on progress, though).
Until they get around to fix it, you will have to either use the suggested GUI Scripting solution as a workaround, or correct the search strings manually.
You can use UI scripting to populate the search field like this:
set xxx to "boat"
activate application "Evernote"
tell application "System Events" to tell process "Evernote"
set value of text field 1 of group 4 of tool bar 1 of window 1 to xxx
end tell