Internationalization of file names in applescript - macos

Regarding this question and this answer, this a problem I encounter often. How can I tell applescript to correctly understand the file names I’m giving it, i.e. understand all characters, not just ASCII ones.

The read and write commands still default to the "primary encoding", like MacRoman or MacJapanese. You can use UTF-8 by adding as «class utf8»:
$ printf äあ>/tmp/a
$ osascript -e 'read "/tmp/a"'
äあ
$ osascript -e 'read "/tmp/a" as «class utf8»'
äあ
as Unicode text is UTF-16.

Related

Unable to make a regex work in new Mac Big Sur terminal

I am trying to make a perl onliner work in mac Big Sur terminal. The online is this
perl -pi -e 's/REGULAR_EXPRESSION_TO_BE FOUND/REPLACEMENT/g' *.hmtl
When I try to search and replace in editor BBEDITOR it works fine, but when I try in macOS terminal it does not replace. I believe it may have to do with encoding since I am working with Spanish texts. But my texts are in UTF-8.
If your regex or replacement text are unicode, you need the utf8 pragma to tell Perl to decode the command line script as unicode. Otherwise they will be interpreted as bytes or otherwise according to your locale. Just because it looks like the right character to you on your terminal doesn't mean it really is. This is because the terminal does its own decoding of the bytes you pasted or typed or printed.
Add -Mutf8 to the command line or do use utf8. You can always use the B::perlstring function to see what Perl thinks of what you typed.
# v5.22
$ perl -e 'use B; print B::perlstring "愛"; '
"\346\204\233"
$ perl -Mutf8 -e 'use B; print B::perlstring "愛"; '
"\x{611b}"
$ perl -e 'print "\346\204\233"; '
愛
The regex and the file have to be in the same encoding for the matching to work. Because obviously "\346\204\233" != "\x{611b}". To remove the ambiguity of the terminal you might have to write a short script file to debug it. You also might need -CSD as well.
See here for more information.
perlrun
utf8 pragma
HTH

Read Double byte characters in plist from shell

I am working on Mac. I have a p-list entry containing double byte chinese characters,
ie.ProductRoot /Users/labuser/Desktop/您好.
Now i am running this command on terminal
defaults read "path to p-list" ProductRoot
and I am getting /Users/labuser/Desktop/\u60a8\u597d
........How can i fix this?
"defaults read" doesn't seem to have any way to change the format of the output. Maybe you could pipe that to another command-line tool to unescape the Unicode characters.
Failing that, it'd be very easy to write a tool in Objective-C or Swift to dump just that one value as a string.
As a side note, you claim the file has double-byte characters. If it's being created by native Mac code, it's probably more-likely to be in UTF-8 encoding. I don't know if that would matter at all, but I figured I'd add that in case it's relevant.
You could try this:
defaults read | grep ppt | perl -npe 's/\\\\U(\w\w\w\w)/chr hex $1/ge'

Copy pure text from clipboard using AppleScript

Situation
Open a Word Document.
Copy some formatted text from inside the document to the clipboard.
Paste it into an instance of CKEditor
CKEditor received smelling M$-style HTML with tons of useless html elements and styles. Even removing formatting using CKEditor's feature does not render pure text.
Desired solution
Could anybody provide an AppleScript, which removes the styled-/HTML-string and pastes the pure text part back to clipboard.
A plus would be a short hint, how to bind the AppleScript to function key.
You don't show how you're copying and pasting currently. It should be possible to use something like this, though:
tell application "Word"
set theData to (the clipboard as text)
set the clipboard to theData
end tell
That will obtain the plain text version of the clipboard data and then replace the clipboard contents (which contains HTML) with the plain text.
To bind the script to a function key, I recommend using Automator to make a service that runs your script and then use the Keyboard pane of System Preferences to assign a key. In fact, I suspect this whole task would be better as a service that receives the text as input rather than attempting to explicitly fetch it from the clipboard.
Old question, but I found that the existing answers do not completely convert the text to plain. They seem to set the font to Helvetica and the size to 12.
However, you can pipe pbpaste and pbcopy to really remove formatting.
In the Terminal:
$ pbpaste | pbcopy
As an AppleScript:
do shell script "pbpaste | pbcopy"
That's it.
set the clipboard to is defined in Standard Additions. You don't need to enclose it in a tell application "Word" ...
set the clipboard to (the clipboard as text)
echo -n doesn't work because AppleScript's do shell script command uses sh, not bash, and sh's echo is a builtin that doesn't accept options. Specify /bin/echo explicitly and it will work:
do shell script "/bin/echo -n " & quoted form of my_string & " | pbcopy"
That will put a plain text copy of my_string on the clipboard.
This worked for me:
do shell script "echo " & total_paying & " | tr -d \"\n\" | pbcopy"
NOTE: When you click compile, the \n will be converted to a literal newline. This is fine. It still works. I tried using echo -n but it was printing the -n in the output.

Converting to one line AppleScript

I have a series of AppleScript commands I need to implement into a single line of AppleScript. The code is below.
delay 2
tell application "System Events" to keystroke "foo"
tell application "System Events" to keystroke return
You can combine the two keystroke commands into a single one by concatenating your strings together:
tell app "System Events" to keystroke "foo" & return
But that still leaves you with one command and a statement (delay and tell … to …).
Effectively, AppleScript’s statement separator is a line break. In modern AppleScript the line breaks can be either CR, LF, or CRLF (respectively: old-Mac-, Unix-, or DOS-style). There is no convenient way write a multi-statement line (like foo; bar; baz; in C, Perl, Ruby, et cetera).
For your specific request, you can combine the two in a really ugly way by using delay as a part of an expression.
tell application "System Events" to keystroke "" & (delay 2) & "foo" & return
This is ugly because delay technically returns no value, but we are able to concatenate it with an empty string without causing an error.
The problem is that such a construction is not very “general purpose”. You may not always be able to turn any command into an expression in the same way (and you can not use statements like tell as a part of an expression1). For a bit more brevity (and obfuscation), you can write the last bit as "foo" & return & (delay 2). It still runs in the same order (delay first) because each part of the concatenation expression must be evaluated before it can be built into a single value for the keystroke command.
1 Short of putting them in a string given to run script that is. Even then, some statements (loops, try/catch, etc.) are always multi-line; though you can get around that by using escaped line breaks or concatenation and one of the line break constants (as follows).
You could use run script with a string argument and use the backslash2 escapes to represent the line breaks.
run script "delay 0.1\ntell app \"System Events\" to keystroke \"foo\" & return"
AppleScript Editor may translate the escape notation into a literal unless you have “Escape tabs and line break in string” enabled in its Editing preferences (available in 10.5 and later). You could always use the return constant and concatenation instead of the in-string-literal/escape-notation.
run script "delay 0.1" & return & "tell app \"System Events\" to keystroke \"foo\" & return"
2 If you are going to represent such strings inside an Objective C string literal (as one of your comments might imply), then you will have to escape the backslashes and double quotes for Objective C, also (…& \"tell app \\\"System…).
Or, if you are ultimately trying to run the code with osascript, then you can use the fact that each instance of -e will become a separate line to put it all on a single shell command line.
osascript -e 'delay 2' -e 'tell app "System Events" to keystroke "foo" & return'
osascript with several -e 'line1' -e 'line2' -e 'line3' ...
The manpage for osascript suggests to use several -e to build up a multi-line script.
-e statement
Enter one line of a script. If -e is given, osascript will not look for a filename in the argument list.
Multiple -e options may be given to build up a multi-line script.
Because most scripts use characters
that are special to many shell programs (for example, AppleScript uses single and double quote marks, “(”,
“)”, and “*”), the statement will have to be correctly quoted and escaped to get it past the shell intact.
Answer already given by Chris Johnsen, but is contained in a longer answer and therefore can be overlooked.

Getting RTF data out of Mac OS X pasteboard (clipboard)

According to the man page for pbpaste,
-Prefer {txt | rtf | ps}
tells pbpaste what type of data to look for in the pasteboard
first. As stated above, pbpaste normally looks first for plain
text data; however, by specifying -Prefer ps you can tell
pbpaste to look first for Encapsulated PostScript. If you spec-
ify -Prefer rtf, pbpaste looks first for Rich Text format. In
any case, pbpaste looks for the other formats if the preferred
one is not found. The txt option replaces the deprecated ascii
option, which continues to function as before. Both indicate a
preference for plain text.
However (in my experience with 10.6 Snow Leopard at least), pbpaste -Prefer rtf never, ever gives up the RTF data even when it exists on the pasteboard. Is there any other simple way to get the RTF text of whatever’s ready to be pasted?
I tried AppleScript, but osascript -e 'the clipboard as «class RTF »' gives the response «data RTF 7Bton of Hex encoded crap7D». Can AppleScript convert this hexdata into text I can play with?
I can't see any way to do it from inside AppleScript, but since you're working in the shell anyway, I'd just post-process it: the "hex-encoded crap" is the RTF data you want. The simplest script I can think of is
perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'
An explanation: substr($_,11,-3) strips off the «data RTF and »\n bits (each of the guillemets is two bytes); pack("H*", ...) packs hex-encoded data into a bytestream; unpack("C*", ...) unpacks a bytestream into an array of character values; print chr foreach ... converts each integer in the array to its corresponding character and prints it; and the -ne options evaluate the script given for each line, with that line implicitly stored in $_. (If you want that script in its own file, just make sure the shebang line is #!/usr/bin/perl -ne.) Then, running
osascript -e 'the clipboard as «class RTF »' | \
perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'
will give you raw RTF output.
I think that at least on OS X 10.8 this would work if you copied HTML content from Chrome:
osascript -e 'the clipboard as "HTML"'|perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'
In my experience it's impossible to get RTF data out of pbpaste, even if the man page says otherwise.
The simplest solution is to use pbv instead, which was developed exactly to work around the limitations of pbpaste.
An example: after copying the following rich text string into your clipboard:
"Hi, I'm rich text"
pbv is able to give you back proper RTF data:
$ pbv public.rtf | textutil -stdin -info
File: stdin
Type: rich text format (RTF)
Length: 19 characters
Contents: "Hi, I'm rich text"
Whereas pbpaste will always output plain text even when instructed to prefer RTF:
$ pbpaste -Prefer rtf | textutil -stdin -info
File: stdin
Type: plain text
Length: 19 characters
Contents: "Hi, I'm rich text"
Found via this similar question.
i found a conversation about this with a quick google search
It is very easy via AppleScript (tested in 10.11 El Capitan):
set the clipboard to (the clipboard as «class RTF »)
You can create a Service via Automator:
open Automator
make new service ("Dienst" in German)
add "execute a AppleScript"
input: nothing; output; replaces Selection
The Script:
-- name: convert to RTF
on run {input, parameters}
set the clipboard to (the clipboard as «class RTF »)
return the clipboard
end run
Done. Now save the new Service and to try it out: Select a text, then go to the Application Menu and choose "Services" > "convert to RTF"

Resources