How can I write UTF-8 files using JavaScript for Mac Automation?

故事扮演 提交于 2019-12-08 03:58:00

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!