Rob, thanks for posting this JXA script. I always learn a lot from your scripts.
When I was testing it and trying to understand how it worked, I ran across this bug:
Your test for valid strClip
fails if only an image is on the clipboard.
Here's a small snippet from your script:
var a = Application.currentApplication(),
sa = (a.includeStandardAdditions = true, a),
strClip = sa.theClipboard();
if (strClip)
The (strClip)
returns true
if there is only an object (and no text) on the clipboard.
Here's a test script you can run to verify this:
'use strict';
var app = Application.currentApplication()
app.includeStandardAdditions = true
//--- COPY ONLY AN IMAGE TO CLIPBOARD ---
// Then run this script
var clipStr = app.theClipboard();
//--- This is NOT a valid test for the variable containing text ---
// It also returns true if the variable is an object, like an
// image on the clipboard.
if (clipStr) {
console.log ("'clipStr IS TRUE'")
console.log(typeof clipStr)
}
//---RESULTS---
/* 'clipStr IS TRUE' */
/* object */
Here is a revised script that fixes this issue, as well as adds some comments to help those like me who are still learning JXA.
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SAVE TEXT ON CLIPBOARD TO FILE
------------------------------
Ver: 2.0 2016-05-11
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DATE: May 11, 2016
AUTHOR: Ver 1: Rob Trew (@ComplexPoint)
Ver 2: JMichaelTX
CHANGE LOG:
• Ver 2 2016-05-11 17:49 CT JMichaelTX
• Fixed issue where image only on clipboard caused script to fail.
• Added return if no text was found, to indicate error.
• Added clarity to code by decompressing some statements, and adding comments
REF:
• Copy to New TXT File? - general - Keyboard Maestro Discourse
• https://forum.keyboardmaestro.com/t/copy-to-new-txt-file/3689/2
REQUIREMENTS:
• Use first line as file name
• Save as TEXT file.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
function run() {
var app = Application.currentApplication()
app.includeStandardAdditions = true
//--- READ CLIPBOARD ---
var clipStr = app.theClipboard();
//--- IF TEXT WAS FOUND ON CLIPBOARD, THEN PROCESS ---
if (typeof clipStr === "string") {
//--- SPLIT TEXT BY LINE INTO ARRAY ---
var clipArray = clipStr.split(/[\n\r]/)
var numLines = clipArray.length
//--- GET FIRST LINE TO USE AS FILE NAME ---
var fileNameStr = numLines > 1 ? clipArray[0] : undefined
//--- JOIN REMAINDER OF ELEMENTS INTO STRING FOR FILE CONTENTS ---
var fileContentsStr = fileNameStr ? clipArray.slice(1).join('\n') : undefined;
//--- ASK USER FOR FILE NAME/PATH ---
if (fileContentsStr) {
//--- ACTIVE CURRENT APP TO DISPLAY DIALOG ---
app.activate
var outputFilePathStr = (app.chooseFileName({
withPrompt: 'Save As',
defaultName: fileNameStr + '.txt'
})
).toString();
//--- OUTPUT TO SELECTED FILE ---
writeFile(outputFilePathStr, fileContentsStr);
return (outputFilePathStr);
}
} // END if (clipStr)
else {
return ("ERROR - No text was found on clipboard")
}
//~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function writeFile(pOutputFilePathStr, pFileContentsStr) {
// writeFile :: FilePath -> String -> IO ()
$.NSString.alloc.initWithUTF8String(pFileContentsStr)
.writeToFileAtomicallyEncodingError(
pOutputFilePathStr, true,
$.NSUTF8StringEncoding, null
);
} // END function writeFile()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // END function run()