问题
In short - what is the JavaScript for Mac Automation equivalent of AppleScript's as «class utf8»
?
I have a unicode string that I'm trying to write to a text file using JavaScript for Mac Automation.
When writing the string to the file, any unicode characters present become question marks in the file (ASCII char 3F
).
If this was an AppleScript script instead of a JavaScript one, I could have solved this by adding the as «class utf8»
raw statement as explained on Takashi Yoshida's Blog (https://takashiyoshida.org/blog/applescript-write-text-as-utf8-string-to-file/).
The script, however, is already written in JavaScript so I'm looking for the JavaScript equivalent to this AppleScript statement. Apple's page about raw statements addresses only AppleScript (https://developer.apple.com/library/content/documentation/AppleScript/Conceptual/AppleScriptLangGuide/conceptual/ASLR_raw_data.html).
To write the file, I am using Apple's own writeTextToFile
JavaScript function example (https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/ReadandWriteFiles.html#//apple_ref/doc/uid/TP40016239-CH58-SW1). I added an as
argument to the following call, according to the StandardAdditions dictionary:
// Write the new content to the file
app.write(text, { to: openedFile, startingAt: app.getEof(openedFile), as: "utf8" })
And tried all of the following strings (as written and also in lowercase form):
- Unicode text
- Unicode
- Class utf8
- «class utf8»
- utf8
- text
- utf8 text
Apart for "text" (which resulted in the same question marks situation), using all of the above strings yielded a zero-bytes file.
I understand I might be wading into uncharted waters here, but if anyone reading this has dealt with this before and is willing to provide some pointers, I will be quite grateful 😋
回答1:
If you want to ensure your file gets written with UTF8 encoding, use NSString's writeToFile:atomically:encoding:error
function, like so:
fileStr = $.NSString.alloc.initWithUTF8String( 'your string here' )
fileStr.writeToFileAtomicallyEncodingError( filePath, true, $.NSUTF8StringEncoding, $() )
You would think that writing an NSString object initialized from a UTF8 string would get written out as UTF8 but I've found from experience that writeToFile:atomically
does not honor the encoding of the string being written out. writeToFile:atomically:encoding:error
explicitly specifies which encoding to use. On top of that, writeToFile:atomically
has been deprecated by Apple since OS X 10.4.
回答2:
@PatrickWayne has the correct solution.
I already had this function in my lib, so I thought I'd share it. It uses the same key commands.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function writeFile(pPathStr, pOutputStr) { // @File @Write @ObjC
/* VER: 2.0 2017-03-18
---------------------------------------------------------------
PARAMETERS:
pPathStr | string | Path of file to write. May use tilde (~)
pOutputStr | string | String to be output to file.
*/
//--- CONVERT TO NS STRING ---
var nsStr = $.NSString.alloc.initWithUTF8String(pOutputStr)
//--- EXPAND TILDE AND CONVERT TO NS PATH ---
var nsPath = $(pPathStr).stringByStandardizingPath
//--- WRITE TO FILE ---
// Returns true IF successful, ELSE false
var successBool = nsStr.writeToFileAtomicallyEncodingError(nsPath, false, $.NSUTF8StringEncoding, null)
if (!successBool) {
throw new Error("function writeFile ERROR:\nWrite to File FAILED for:\n" + pPathStr)
}
return successBool
};
回答3:
While I was unable to find a way to do it with JavaScript only, I ended up utilizing the Objective-C Bridge to accomplish UTF-8 file write-out.
Here is the code that I used. This is JavaScript code that invokes the Objective-C NSString class, and it replaces the writeTextToFile
function that I mentioned above altogether:
objCText = $.NSString.alloc.initWithUTF8String(text);
objCText.writeToFileAtomically(filePathString, true);
回答4:
JXA can't do symbol types (type and enumerator names) right, and it can't do raw four-char codes at all. Either stick to AppleScript, which is the only officially supported option that speaks Apple events right, or use the Cocoa bridge to write a NSString to file in NSUTF8StringEncoding, c.f. Patrick's solution.
来源:https://stackoverflow.com/questions/44268436/how-can-i-write-utf-8-files-using-javascript-for-mac-automation