Date   

Re: TextEdit won't open a plain text file after writing to it with write cmd

Shane Stanley
 

On 16 Jun 2018, at 3:40 pm, Ilya Shebalin <iljashebalin2@gmail.com> wrote:

Here's my script (copy pasted as plain text) and another following that one.
I'm no longer sure what your question is. Neither use the suggested code. And the second one is problematic if the file already exists and is longer than the text you're writing.

--
Shane Stanley <sstanley@myriad-com.com.au>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


Re: TextEdit won't open a plain text file after writing to it with write cmd

Ilya Shebalin
 

Here's my script (copy pasted as plain text) and another following that one.
==============================================


property theText : ""
property theFile : missing value
property theSubject : ""
tell application "Mail"


set TheNotes to (get selection)
repeat with aNote in TheNotes
set {theText, theSubject} to {content of aNote, subject of aNote}
end repeat
end tell
tell application "Finder"
set theName to theSubject & ".txt"
set FullFilePath to ((path to desktop as text) & theName)
if not (file FullFilePath exists) then
set theDoc to make new document file with properties {name:theName, displayed name:theName} at folder "Desktop" of home
tell application "TextEdit"
activate
set MyDoc to make new document with properties {text:theText, name:theName} at end of documents


end tell
else
set theFile to (FullFilePath as alias)
set theText to theText
display dialog "The file already exists." & return & return & "Do you want to update it?" buttons {"Cancel", "Update"} default button  1 cancel button 2
if button rif button returned of result is "Cancel" then
error number -128
else
try
my writeToFile(theText, theFile)
on error number -49
close access theFile
end try
my writeToFile(theText, theFile)
end if
end if
end tell

on writeToFile(theText, theFile)
set FileID to open for access theFile with write permission
set eof FileID to 0
write theText to FileID
close access FileID
end writeToFile

===========================================

I wrote another test script. Interestingly enough it let's me open with TextEdit just fine. Here it is:


property theText : ""
property theFile : missing value
tell application "Finder"


set theName to "102"
set theExtension to "txt"
set FullFilePath to (((path to desktop) as text) & theName & "." & theExtension)
if not (file FullFilePath exists) then
set theText to "This is test of writing text to a file and closing it."
set theDoc to make new document file with properties {name:theName & "." & theExtension, displayed name:theName} at folder "Desktop" of home
tell application "TextEdit"
activate


set myDoc to make new document with properties {text:theText, name:theName & "." & theExtension} at end of documents
#save myDoc in file FullFilePath
close myDoc saving in (FullFilePath as alias)


end tell
else
set theFile to FullFilePath as alias
set theText to "This is another text"


set theDialog to display dialog "The document already exists. " & return & "Write another text to it?" buttons {"No", "Yes"} default answer "" default button 2 cancel button 1
if button returned of result is "No" then
error number -128
else
set theText to text returned of theDialog
my writeUTF16(theText, theFile)
end if
end if
end tell

on writeUTF16(theText, theFile)
set FileID to open for access theFile with write permission
set theEnd to get eof FileID
write theText to FileID as Unicode text starting at theEnd
close access FileID
end writeUTF16






16.06.2018, в 4:24, Shane Stanley написал(а):

On 16 Jun 2018, at 11:12 am, Ilya Shebalin <iljashebalin2@...> wrote:

Ooops...Through your question I think I'm onto smth. Yes I enclose it in quotes - just as given in the AppleScript guide I'm reading.

The « and » characters are quotes in some languages, but they have a special meaning in AppleScript. You have to enter them exactly.

It would help trouble-shoot if you copied and pasted your code here directly.

--
Shane Stanley <sstanley@...>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>







Re: TextEdit won't open a plain text file after writing to it with write cmd

Shane Stanley
 

On 16 Jun 2018, at 2:23 pm, Alastair Leith <qc.student.au@gmail.com> wrote:

Is it possible to maintain the rich text formatting in the text file same as email?
No.

--
Shane Stanley <sstanley@myriad-com.com.au>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


Re: TextEdit won't open a plain text file after writing to it with write cmd

Shane Stanley
 

On 16 Jun 2018, at 11:12 am, Ilya Shebalin <iljashebalin2@gmail.com> wrote:

Ooops...Through your question I think I'm onto smth. Yes I enclose it in quotes - just as given in the AppleScript guide I'm reading.
The « and » characters are quotes in some languages, but they have a special meaning in AppleScript. You have to enter them exactly.

It would help trouble-shoot if you copied and pasted your code here directly.

--
Shane Stanley <sstanley@myriad-com.com.au>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


Re: TextEdit won't open a plain text file after writing to it with write cmd

Ilya Shebalin
 

Ooops...Through your question I think I'm onto smth. Yes I enclose it in quotes - just as given in the AppleScript guide I'm reading.


On Sat, Jun 16, 2018 at 4:08 AM Shane Stanley <sstanley@...> wrote:
On 16 Jun 2018, at 11:05 am, Ilya Shebalin <iljashebalin2@...> wrote:
>
> When I use "class utf8" I get an error.

Are you enclosing it in « and » characters?

--
Shane Stanley <sstanley@...>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>






Re: TextEdit won't open a plain text file after writing to it with write cmd

Shane Stanley
 

On 16 Jun 2018, at 11:05 am, Ilya Shebalin <iljashebalin2@gmail.com> wrote:

When I use "class utf8" I get an error.
Are you enclosing it in « and » characters?

--
Shane Stanley <sstanley@myriad-com.com.au>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


Re: TextEdit won't open a plain text file after writing to it with write cmd

Ilya Shebalin
 

Hi, Shane
I did that too, I tried every encoding that write cmd provide as a value of its as parameter. When I use "class utf8" I get an error. 

On Sat, Jun 16, 2018 at 2:25 AM Shane Stanley <sstanley@...> wrote:
On 16 Jun 2018, at 4:30 am, Ilya Shebalin <iljashebalin2@...> wrote:
>
> IIf the file exists and all the statements beyond "else" clause are executed then TextEdit gives a warning of a wrong encoding ("The document "theFile.txt" could not be opened. Text encoding Unicode (UTF-8) isn’t applicable.") and refuses to open the file.

You need to save the file as UTF-8 -- at the moment you're saving it in MacRoman. Change this:

> write theText to  FileID

to:

write theText to FileID as «class utf8»


--
Shane Stanley <sstanley@...>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>






Re: TextEdit won't open a plain text file after writing to it with write cmd

Shane Stanley
 

On 16 Jun 2018, at 4:30 am, Ilya Shebalin <iljashebalin2@gmail.com> wrote:

IIf the file exists and all the statements beyond "else" clause are executed then TextEdit gives a warning of a wrong encoding ("The document "theFile.txt" could not be opened. Text encoding Unicode (UTF-8) isn’t applicable.") and refuses to open the file.
You need to save the file as UTF-8 -- at the moment you're saving it in MacRoman. Change this:

write theText to FileID
to:

write theText to FileID as «class utf8»


--
Shane Stanley <sstanley@myriad-com.com.au>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


TextEdit won't open a plain text file after writing to it with write cmd

Ilya Shebalin
 

Hello,
I wrote a script that would act as an Automator service plug-in in Mail.app when placed to "Run AppleScript" action. It basically would extract the contents of a selected message along with its subject and create a plain text file with the subject as its name and the msg contents becoming the file's contents. IIf the file exists and all the statements beyond "else" clause are executed then TextEdit gives a warning of a wrong encoding ("The document "theFile.txt" could not be opened. Text encoding Unicode (UTF-8) isn’t applicable.") and refuses to open the file. The script is as follows:


property theText: ""
property theSubject:""
property theFile: missing value

tell application "Mail"
set theMessages to (get selection)
set theSubject to ""

repeat with aMessage in theMessages
set {theSubject, theText} to {subject of aMessage, content of aMessage}
end repeat
end tell

tell application "Finder"
set theName to theSubject & ".txt"
set FullFilePath to (((path to desktop) as text) & theName)
if not (file  FullFilePath exists) then
set theDoc to make new document file with properties {name:theName, displayed name: theSubject } at folder "Desktop" of home
tell application "TextEdit"
activate
set myDoc to make new document with properties {text:theText, name:theName} at end of documents
close myDoc saving in file  FullFilePath 
quit
end tell
else
display dialog "The file already exists." & return & return & "Do you want to update it?" buttons {"Cancel", "Update"} default button  1 cancel button 2
if button returned of result is "Cancel" then
error number -128
else
set theFile to  (FullFilePath as alias)
try
my writeToFile(theText, theFile)
on error number -49
close access theFile
my  writeToFile(theText, theFile)
end try
end if
end if
end tell

on   writeToFile(theText, theFile)
set FileID to open for access theFile with write permission
set eof FileID to 0
write theText to  FileID
close access FileID
end 

.Is this an issue when you cannot open a file in an app that wasn't the one you created said file in?
OS X Lion 10.7.5


Re: drafting/prototyping code ?

Jean-Christophe Helary <jean.christophe.helary@...>
 

Thank you Jim.

I'm not really sure what I assume. I guess writing things down on paper would help too.

JC

On Apr 10, 2018, at 10:51, JMichaelTX <JMichael@...> wrote:

On Mon, Apr 9, 2018 at 06:12 pm, Jean-Christophe Helary wrote:
I want to draft or prototype with real text mixed with code and maybe graphs to get a better idea of the flow.
Assuming you meant "rich text", I think we need a bit more info about your requirements/specification.
Are you looking for one tool that will support everything:  rich text, code blocks, diagramming, graphing, etc?
Or, will you accept multiple tools for each of the sub-tasks, and one tool to provide the documentation?

Some ideas for now . . .

If it is the latter, this forum offers a nice rich-text editor that can handle images, and it also offers a wiki that can do the same.
Unfortunately, I just remembered that when using the rich-text editor, it does not provide a tool for code blocks with syntax highlighting.
So, I would imagine that rules this forum out.

Evernote does offer a nice rich-text editor that supports rich-text, images, inline attachments, and code blocks that would retain syntax highlights if the source provided it.  You can then, if you so choose, make an individual Evernote Note public so anyone can read it with the Note link.  You can also share entire Evernote Notebooks, if that is of any interest.

Of course you can do almost anything with a web site, provided you know how to code HTML and JavaScript, OR, maybe there is a WordPress theme that would do the job for you.

Undoubtedly there are some commercial apps that will do all or most of what you want, provided you are willing to pay the price.  
😉

Jean-Christophe Helary
-----------------------------------------------
http://mac4translators.blogspot.com @brandelune



Re: drafting/prototyping code ?

 

On Mon, Apr 9, 2018 at 06:12 pm, Jean-Christophe Helary wrote:
I want to draft or prototype with real text mixed with code and maybe graphs to get a better idea of the flow.
Assuming you meant "rich text", I think we need a bit more info about your requirements/specification.
Are you looking for one tool that will support everything:  rich text, code blocks, diagramming, graphing, etc?
Or, will you accept multiple tools for each of the sub-tasks, and one tool to provide the documentation?

Some ideas for now . . .

If it is the latter, this forum offers a nice rich-text editor that can handle images, and it also offers a wiki that can do the same.
Unfortunately, I just remembered that when using the rich-text editor, it does not provide a tool for code blocks with syntax highlighting.
So, I would imagine that rules this forum out.

Evernote does offer a nice rich-text editor that supports rich-text, images, inline attachments, and code blocks that would retain syntax highlights if the source provided it.  You can then, if you so choose, make an individual Evernote Note public so anyone can read it with the Note link.  You can also share entire Evernote Notebooks, if that is of any interest.

Of course you can do almost anything with a web site, provided you know how to code HTML and JavaScript, OR, maybe there is a WordPress theme that would do the job for you.

Undoubtedly there are some commercial apps that will do all or most of what you want, provided you are willing to pay the price.  
😉


drafting/prototyping code ?

Jean-Christophe Helary <jean.christophe.helary@...>
 

I already have a number of scripts that I'd like to "merge" but before that I want to draft or prototype with real text mixed with code and maybe graphs to get a better idea of the flow.

What would be an adequate tool for that ?


Jean-Christophe Helary
-----------------------------------------------
http://mac4translators.blogspot.com @brandelune


Auto mount .dmg in High Sierra? Possible??

Brian Christmas
 

G’day Scripters

You’ve been most fortunate. I’ve been laid up in hospital for 4 months quite ill, and have not had access to my iMac in that time.

However, I’m quite well now, and ready to annoy you all once more (grin)!

So, a new sort of question…..

I’ve upgraded to High Sierra, and hugely modified the two versions of my App; re-named to Art Archiver, and a lite version, Art Archiver Secretary. However, I’m newly having problems in the distribution of them. In the past, ‘blessing’ a pre-compressed disk image resulted in the image, when downloaded, expanding and then auto mounting, showing the .dmg folder, ah la Carbon Copy Cloner.

This procedure either no longer works, or I’m leaving some step(s) out.

My .dmg.zip decompresses, but does no mount under Sierra or High Sierra, which is a pain.

I invested in Toast 16, but it’s own distribution only follows the latter procedure, and while it can include a picture background, it’s distribution is a square default window, and the icon is in the default top left, and quite small. It remains un-compressed in the downloads folder, and the purchaser has to ‘guess’ where it is, and what to do with the .dmg.

Is anyone able to guide me on how to create compressed .dmg, and have it auto mount after de-compression, please??

Regards

Santa

PS. It’s great fun being back in the land of the living, and no longer suffering the long term effects of 28 months of severe sleep deprivation.


[ANN] Script Debugger 7 released

Shane Stanley
 

Late Night Software has released Script Debugger 7, the latest version of its award-winning AppleScript development software. The upgrade introduces Script Debugger Lite, several new features and a raft of other tweaks and improvements.

For further details:

<https://latenightsw.com>

--
Shane Stanley <sstanley@myriad-com.com.au>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


Re: Generic XML generation with AppleScriptObjectiveC (introduction)

Jean-Christophe Helary <jean.christophe.helary@...>
 

Thank you for the comments. I eventually posted the thing here after a number of modifications:

https://mac4translators.blogspot.jp/2018/02/this-article-is-attempt-at-putting.html

Jean-Christophe Helary
-----------------------------------------------
http://mac4translators.blogspot.com @brandelune


Generic XML generation with AppleScriptObjectiveC (introduction)

Jean-Christophe Helary <jean.christophe.helary@...>
 

-- This document is intended for my blog, but I thought that I'd share it here first, just in case there are comments/suggestions/questions, etc. Including the code, it is 3000 words. It's trivial for most of you, but it took me quite some time to put everything together and then to document everything. Everything is still not super clear, so go ahead and tear it apart. :)


(*
This code is an attempt at putting together a practical introduction to using AppleScriptObjectiveC from all the information I gathered when creating a stand-alone application that required XML generation.

The application itself, a script that converts Excel contents to TMX is trivial as far as AppleScript itself is concerned. The problem that needed a solution was generic simple XML generation.

There are a number of solutions in AppleScript to create XML but nothing out of the box to generate generic data. System Events cannot create generic XML, it can only modify existing files. The only format it can natively produce is the "property list" format, used to store application preferences, etc. There are solutions that involve concatenating strings and doing a lot of checks on the data to make sure the output is valid (in XML a number of characters are forbidden, so all strings that are concatenated need to be thoroughly checked for those) but they are neither elegant nor robust. There are libraries available, but they do a lot more than what casual users need.

I thought that offering a simple solution for a simple problem that would provide the reader with a step-by-step introduction to reading the Foundation documentation and understanding how to use it with vanilla AppleScript was a better approach, at least for me, since short of having scriptable applications that do what you want, the only way to do really complex things in AppleScript is to use Foundation.

My problem, which is common to all amateur AppleScript users, is a problem of discoverability and of fluency. AppleScript is not a trivial language, a systematic description of its features is non-existent, and when you want to go beyond the "tell Finder to sort the mess on my Desktop" you end up needing to check a lot of references that either consider that you know a lot, or that you don't know much. There is no middle ground and no easy way to find what you need without actually asking. In fact, I still wonder how I could have written this code without the help of people who just seem to "know". There is no clear discoverability path to the information I gathered here.


AppleScriptObjC is not described in the AppleScript Language Guide issued by Apple. The 3rd edition of "Learn AppleScript" by Hamish Sanderson and Hanaan Rosenthal from Apress (2010) discusses some aspects of AppleScriptObjC but the document that best describes it is "Everyday AppleScriptObjC" by Shane Stanley (2015). The Foundation framework, along with other frameworks that can be accessed by AppleScriptObjC are described in the developer documentation (either in Xcode or online) with Objective-C use in mind (syntax, etc.) so we'll thus use the 3 references to go through the code.

Becoming fluent in a language is a problem both for the linguist and for the programmer. Fluency only comes with regular practice based on sound references, and regular contact with "natives". As far as AppleScript (and AppleScriptObjC) is concerned, "natives" can be found in a number of very interesting places on the internet. The first is the official AppleScript User List (ASUL) hosted by Apple. Apple has been a bad host in recent years so fear of losing this resource has motivated some of its users to create an independent list, hosted on groups.io. There also is the Macsripter web forum. I'm not super fond of web forums. Their user interface is clumsy more often than not and this one is no exception. But it's been around for ever and a number of world-class experts are there to comment on code and generally manage the community. Then, there is the ScriptDebugger's user forum. Conversations there generally revolve around higher level topics, the web forum is a modern one and the user experience is of extremely high quality. Considering that the next version of ScriptDebugger (7, in Beta at the time of this writing) will offer a Lite version à la BBEdit once the trial period expires, you really have no reason to prefer Apple's Script Edit over ScriptDebugger.

Ok, so, you're all set, no more chatting, let's check the code.
*)

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

(*
As seen in the script headers above, we'll be using the "Foundation" framework which allows us to directly work on the XML tools that macOS offers. Without this declaration we can't access what we need.

This code will generate an XML file that will reproduce the following typical omegat.project file, with default values for the project folders, English as source language, Japanese as target language, sentence segmentation and default translations enabled, and no external command to process when creating the target files.

In XML, the order of tags as well as the white space used to present them is irrelevant, so the appearance of the data will change depending on how the code was produced. It may not be exactly like a "genuine" OmegaT file, but as far as the meaning of the data and OmegaT proper are concerned that is not relevant.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<omegat>
    <project version="1.0">
        <source_dir>__DEFAULT__</source_dir>
        <source_dir_excludes>
            <mask>**/.svn/**</mask>
            <mask>**/CVS/**</mask>
            <mask>**/.cvs/**</mask>
            <mask>**/desktop.ini</mask>
            <mask>**/Thumbs.db</mask>
            <mask>**/.DS_Store</mask>
        </source_dir_excludes>
        <target_dir>__DEFAULT__</target_dir>
        <tm_dir>__DEFAULT__</tm_dir>
        <glossary_dir>__DEFAULT__</glossary_dir>
        <glossary_file>glossary.txt</glossary_file>
        <dictionary_dir>__DEFAULT__</dictionary_dir>
        <source_lang>EN</source_lang>
        <target_lang>JA</target_lang>
        <source_tok>org.omegat.tokenizer.LuceneEnglishTokenizer</source_tok>
        <target_tok>org.omegat.tokenizer.LuceneJapaneseTokenizer</target_tok>
        <sentence_seg>true</sentence_seg>
        <support_default_translations>true</support_default_translations>
        <remove_tags>true</remove_tags>
        <external_command></external_command>
    </project>
</omegat>

The tokenizers are generally not set by the user because OmegaT would automatically select them based on the corresponding language codes.
Anything else is user settable, even the "excludes" files, even though that is an advanced setting that most users should not have to consider.

So, we're going to create a handler that takes as input the following values:

• source_dir_value: path to directory
• source_dir_excludes_masks: list of mask tags
• target_dir_value: path to directory
• tm_dir_value: path to directory
• glossary_dir_value: path to directory
• glossary_file_value:  path to text file
• dictionary_dir_value: path to directory
• source_lang_value: string language code (we do need to check the validity of the code based on the appropriate ISO standard, but we consider here that the check has been made upstream, if only to keep the XML generation code free of such external checks)
• target_lang_value: string language code (see above)
• source_tok_value: string automatically proposed by the script, based on language code (here again, the tokenizers corresponding to the source language should be a valid tokenizer but we let the upstream code select and validate it so stick to the core XML generation code)
• target_tok_value: string automatically proposed by the script, based on language code (see above)
• sentence_seg_value: boolean
• support_default_translations_value: boolean
• remove_tags_value: boolean
• external_command_value: string to be sent to exec when the target files are created, can be empty if no action is requested.

We'll make this code a handler so that we can call it without having to copy it every time we need it. This is better because it allows to logically separate portions of the code.
*)

on CreateOmegaTProjectFile(ParametersList)


(*
The first few lines below are necessary to initialize the XML tags. First comes "project_tags", a list of tags that are used in the file. There are 15 tags, of which 14 tags that only take a simple value, either a path, or a text string, etc. As we can see above, "source_dir_excludes" takes a list of "mask" tags which we'll create with "masks", which contains the patterns that describe the type of files to be ignored by OmegaT. Last, we initialize "valueindex", an index that will be used to associate the tag to its value found in the list that we feed the handler.
  Then comes the beginning of the XML structure creation.
*)


set project_tags to {"source_dir", "source_dir_excludes", "target_dir", "tm_dir", "glossary_dir", "glossary_file", "dictionary_dir", "source_lang", "target_lang", "source_tok", "target_tok", "sentence_seg", "support_default_translations", "remove_tags", "external_command"}
set masks to {"**/.svn/**", "**/CVS/**", "**/.cvs/**", "**/desktop.ini", "**/Thumbs.db", "**/.DS_Store"}
set valueindex to 0


(*
We're first going to create an XML element that we'll then use as the XML document root. We'll create the other elements once that is done.
*)


set projectRoot to current application's NSXMLNode's elementWithName:"omegat"


(*
This is our first line of AppleScriptObjC. How do we call the Foundation items that we need to work with?


From "Everyday AppleScriptObjC":
"Class names are effectively properties of the current application (which is, in turn, the parent of AppleScript in your script)."

From "Learn Applesccript":
"AppleScriptObjC presents Cocoa classes as class elements of the current application object."

So, everything we'll call from Cocoa will be called from "current application", hence the use of "current application's NSXMLNode".

In the Xcode documentation, NSXMLNode is described as, well, an XML node.

 

As the documentation says, an XML node can be anything from: an element, an attribute, text, a processing instruction, a namespace, or a comment.

 

Here we use the "elementWithName" method to create the element. Clicking on its description in the Xcode documentation browser shows that the method is a "type method" and returns "an NSXMLElement object with a given tag identifier, or name".

 

"Type methods" apply to classes, they are generally used to create objects which are specific instances of a given class. When we'll work on the objects themselves we'll need "instance methods". In the documentation, "type methods" have a "+" prefixed to their name and "instance methods" have a "-" prefixed instead.

 

The syntax for such method calls is methodName:parameter, so here we have: elementWithName:"omegat". This syntax well be used for all the other elements that we create.

 

It is important to note that we are using a shortcut here. As Shane mentions on ASUL:
"(elementWithName is) what's known as a convenience method. You're actually making a particular subclass of NSXMLNode, an NSXMLElement.
You could have used:
set projectRoot to current application's NSXMLElement's alloc()'s initWithName:"omegat"
But convenience methods are common, if not following any particular logic of when and where they're provided. Something like "stringWithString:" instead of "alloc()'s initWithString:" is a common example."

 

To make sense of that we need to know how Objective-C/Cocoa works:


From "Everyday AppleScriptObjC":
"The equivalent (of AppleScript's make) in Cocoa is actually a two-stage process: first the object is created by allocating memory for it, and then it is initialized.  The first stage is done using the +alloc method. You will not see it listed (in the documentation) because it is a method all classes inherit from the NSObject class."


If we check the NSObject description, we see "+ alloc" which is described as "Returns a new instance of the receiving class" and later "You must use an init... method to complete the initialization process." Then we see "- init", which is described as "Implemented by subclasses to initialize a new object (the receiver) immediately after memory for it has been allocated." In the method description we also see that it only exists for Objective-C and not for Swift which only has "init()" to cover allocation and initialization in one fell swoop.


So, instead of using that longer process, we prefer to use that "convenience method" and make the code slightly shorter.


Foundation reference:
*)


set theProject to current application's NSXMLNode's documentWithRootElement:projectRoot


(*
Here again, we'll use a convenience method that does not require us to go through the alloc-init process. Now we have a XML document and its root element. We'll need a few more things to make our output look like what OmegaT needs.


Foundation reference:
*)


theProject's setCharacterEncoding:"UTF-8"


(*
"setCharacterEncoding" is not documented in the Foundation documentation. The closest thing related to an NSXMLDocument that we have is "characterEncoding" (notice the case for "Character": lower case in the documentation, upper case in the code), which is described as an "instance property", which seems to correspond since theProject is indeed an instance of NSXMLDocument.


The "set" prefix is explained in "Everyday AppleScriptObjC":
"To set a new value for a Cocoa property, assuming it is not read-only, you use the word set, followed by the property name with the  first letter in uppercase, followed by a colon or underscore and parentheses, depending on the syntax.  The single argument is then the proposed new value."


Now we understand why "set" is prefixed and why characterEncoding is changed to CharacterEncoding when prefixed with set. If we need to get the characterEncoding property of the document, let's not forget about the letter case...


Setting characterEncoding happens to be enough to create the <?xml version="1.0" encoding="UTF-8"?> line in our example *and* to actually encode the data in UTF-8.


Foundation reference:
*)


theProject's setStandalone:true


(*
setStandalone works like setCharacterEncoding and adds the standalone="yes" part to our xml declaration.


I had the following line in a previous version of this code:


theProject's setDocumentContentKind:(current application's NSXMLDocumentXMLKind)

but we can dispense with it since XML is the default kind of XML document (other kinds include HTML, XHTML and text). Still there is something in this line that we ought to remember for other occasions. "documentContentKind" is an instance property, like "standalone". To set it we must thus use "setDocumentContentKind". The possible values for a documentContentKind are documented as "enumerations", of which NSXMLDocumentXMLKind is the default value in the case of an XML document. To use NSXMLDocumentXMLKind as a value, we must do as we've done for other Cocoa items: call them from the current application, hence the (current application's NSXMLDocumentXMLKind).

Foundation reference:
*)


set project to current application's NSXMLNode's elementWithName:"project"
set projectVersion to current application's NSXMLNode's attributeWithName:"version" stringValue:"1.0"
project's addAttribute:projectVersion
projectRoot's addChild:project


(*
We're still in NSXMLNode territory here. Now we're creating the "project" element with a "version" attribute that has a "1.0" value.


To do this, we first create the element and we then separately create an attribute node by using the "attributeWithName:stringValue:" method (see the Xcode description) that actually comes in two parts: the attributeWithName: part and the stringValue: part.

Once created, the 2 nodes have no relation to each other or to what we've created so far. We need to "link" everything together now and we do that with the 2 lines that follow:
"addAttribute" is documented as an instance method, which is good because "project" is an instance of "NSXMLNode" and "adds an attribute node to the receiver", which is exactly what we're trying to do. The parameter is "projectVersion", the attribute node that we created 1 line before that.

Now we have an element what would look like <project version="1.0"></project> and we need to add it as a child of the document root element. That's what does "addChild": an instance method that "adds a child node after the last of the receiver’s existing children". The receiver is projectRoot and the child is project.


Foundation reference:
*)


repeat with child in project_tags
set valueindex to valueindex + 1
if contents of child is not "source_dir_excludes" then
set child to (current application's NSXMLNode's elementWithName:child stringValue:(item valueindex of ParametersList))
(project's addChild:child)
else
set child to (current application's NSXMLNode's elementWithName:"source_dir_excludes")
(project's addChild:child)
set source_dir_excludes to (project's elementsForName:"source_dir_excludes")'s firstObject()
repeat with mask in masks
set mask to (current application's NSXMLNode's elementWithName:"mask" stringValue:mask)
(source_dir_excludes's addChild:mask)
end repeat
end if
end repeat


(*
Now that we've been through the basics of using Foundation to create a basic XML structure, the rest of the code is very straightforward. We're running a loop on the tag list that was created at the beginning of the script and for each "child" we'll set a "stringValue" that corresponds to the item at the same position in the ParametersList that has been sent to this handler.


Once the element and its string value are created, we add it as a child to the "project" element that we created just above.


The only exception to that process is when we bump into "source_dir_excludes". Here, what happens is that we do not use stringValue: to set its value since it is going to be made of a list of <mask> tags. So instead of that, we first create the tags and add them one by one as children to "source_dir_excludes". When we're done with that special content, we resume the loop and deal with the other tags.


How we identify "source_dir_excludes" within the list of existing tags is interesting. We use elementsForName: an instance method for project that returns an array of all the elements with the name given as the parameter (here "source_dir_excludes"), and since we only have one here, we specify that we want to work with that array's "firstObject". That way we create a reference to the NSXMLElement "source_dir_excludes" that we can later use to add children to it. It took me a while to figure that out. Thank you Shane :)


The creation of the list of <mask> tags is straightforward and does introduce any new concept.


Foundation reference:
*)


set theData to theProject's XMLDataWithOptions:((get current application's NSXMLNodePrettyPrint) + (get current application's NSXMLDocumentTidyXML))
theData's writeToFile:(item 16 of ParametersList) options:(current application's NSDataWritingAtomic) |error|:(missing value)


(*
We're reaching the end of this XML generation code. Now we need to output the data, in readable form. "XMLDataWithOptions" is a method that returns an NSData object and the options are listed under "NSXMLNodeOptions". The description says, "One or more options (bit-OR'd if multiple) to affect the output of the document..." where "bit-OR'd if multiple" means "added". Another thing to notice is that the second and following options (if any) seem to need a "get". Adding the "get" to the first option does not seem to be necessary.


"writeToFile:options:error:" is an instance method of NSData, which theData is, it requires a Unix absolute path and options in the same way as defined the line before. |error| is put between vertical bars to avoid naming conflicts since the AppleScript "error" is not the same as the Foundation "error" and we're calling the later here, and the description of "error" says we can use a "NULL" value, for which the AppleScript equivalent is missing value (Everyday AppleScriptObjC, p. 52 "The terms nil and its close relative NULL are used commonly in Cocoa.  They are essentially the equivalent of AppleScript’s missing value, and the scripting bridge converts between them.")


Foundation reference:
*)


end CreateOmegaTProjectFile

(*
Let's now test the code with the following values:
*)

set ProjectSettings to {"PATH_1", "MASKS", "PATH_2", "PATH_3", "PATH_4", "FILE_5", "PATH_6", "LANG_7", "LANG_8", "TOKENIZER_9", "TOKENIZER_10", "SEGMENTATION_11", "DEFAULT_TRANSLATION_12", "REMOVE_TAGS_13", "EXTERNAL_COMMAND_14", "/Users/suzume/Desktop/omegat.project"}

my CreateOmegaTProjectFile(ProjectSettings)


Jean-Christophe Helary
-----------------------------------------------
http://mac4translators.blogspot.com @brandelune



Re: Is i possible hide AppleScript "do shell script" commands from bash/bash history?

Shane Stanley
 

On 31 Dec 2017, at 2:21 pm, David Wegener laptop <davew@wegenermedia.com> wrote:

My primary interest in using AS is in conjunction with a Filemaker app, where Filemaker creates and stores the AS within a calculated FM script (which is then hidden from the user, and passes the ‘do shell script’ upon command).
In addition, I pass both the data and the key as variables (from FM fields), rather than keeping them in a static AS..

Is that any better, or just as vulnerable?
It sounds like it removes the vulnerability of stored variable values.

--
Shane Stanley <sstanley@myriad-com.com.au>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


Re: Is i possible hide AppleScript "do shell script" commands from bash/bash history?

David Wegener laptop
 

On Dec 29, 2017, at 6:02 PM, Shane Stanley <sstanley@myriad-com.com.au> wrote:

On 30 Dec 2017, at 9:46 am, Deivy Petrescu <applescript@dicas.com> wrote:

However, thisisMYP5SSW0rd! is legible in the script, meaning if you “open” the script on a text editor, it will be there for everyone to see.
There was a big discussion here and Shane managed to break all the passwords.
May be something has changed, but I don’t think so.
There is a way around that issue: stop the script from storing its properties and top-level variable values. That means doing something like changing its privileges, code-signing it, or even using a top-level ASObjC variable. Of course that assumes the script doesn't otherwise rely on property persistence.
My primary interest in using AS is in conjunction with a Filemaker app, where Filemaker creates and stores the AS within a calculated FM script (which is then hidden from the user, and passes the ‘do shell script’ upon command).
In addition, I pass both the data and the key as variables (from FM fields), rather than keeping them in a static AS..

Is that any better, or just as vulnerable?


tx



I am thinking of a way to save passwords securely on an AS, but haven’t worked on that yet!
Store it in a keychain?

--
Shane Stanley <sstanley@myriad-com.com.au>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>





Re: Is i possible hide AppleScript "do shell script" commands from bash/bash history?

twhite_L1@twdesigns.com
 

Hi All,

I recommended that davew@... post on this list.

Here is my earlier reply to his question...
https://community.filemaker.com/message/725167?commentID=725167&et=notification.mention#comment-724808
Hope that helps.

Tony White
http://www.twdesigns.com
http://FileMaker-Fanatics.com


On 12/28/17 9:48 AM, "davew@..." <davew@...> wrote:

I was recommended to come here, by some knowledgeable folks on a Filemaker Pro forum.

So, I'm using some older versions in an active filemaker solution (FMPA 13, 14, 15), and need to enhance some security features.

 
This is within a database solution that's 'in the wild', on customers' Macs around the world. We don't really want them being able to view certain encrypted data nuggets (which may need to be sent back & forth via email).  And for certain other reasons, we can't force an upgrade to a different database version (with built-in encryption)..

 

So, to accomplish this, I use Applescript to pass data from a field into an openssl shell for encryption, then put results into an encrypted data field..

 

Calculated AppleScript here:

"property targetCell: \"cp_thisismyencrypteddatafield\" ¶

set theResult to do shell script \"echo " & cp_thisismydatasourcefield & " | openssl aes-256-cbc -k thisisMYP5SSW0rd! -base64\" ¶

copy theResult to cell targetCell of current record"

 

So, this work perfectly well, in that I'm able to pass both data and a password into openssl for encryption, and pass back.

 

My concern is this: is this action visible to prying eyes?  I've been given multiple conflicting answers from multiple 'experts', but would really appreciate someone who actually **IS** an expert to confirm or deny the security of this..

 

I thought perhaps I could see the command thru ./bash_history, but it doesn't show up.. Nor does it in any console logs that I can find... nor in 'history' (as either a user or as root). Some folks have said that a 'do shell script' (being non-interactive) is shielded from bash history...

 

But all of this is moot without something definitive - I am concerned that a well-informed hacker can perform some level of 'ps aux' at some point and actually see (or log) that shell script going by... is that so?

 

1. IF it can be logged or viewed, how?  Can I replicate that action (to prove/disprove it)?

2. IF it can be viewed, is there another (better) way to do this, without any plug-ins (yeah, i'm biased against 3rd party plug-ins), which would hide it from sight/log?

3. IF it IS hidden, (but I created a variable  - theResult), is theResult visible anywhere (or could someone simply dump that variable into plaintext somehow)?  Or does that variable self-flush when I end the script?

 

Thanks for any definitive clarity on this!




Re: Accelerator keys in displayed buttons

Jean-Christophe Helary <jean.christophe.helary@...>
 

On Dec 25, 2017, at 11:11, Shane Stanley <sstanley@myriad-com.com.au> wrote:

On 25 Dec 2017, at 1:03 pm, Jean-Christophe Helary <jean.christophe.helary@gmail.com> wrote:

Maybe not all, but some buttons can be accessed by hitting Cmd+the first letter, or something like this. It used to be that a TextEdit dialog reacted to Cmd+D for Delete, but now it is "Change location to Desktop", etc.
I suspect you're thinking of "Don't Save". Alerts are hard-wired by default to map escape/command-. to Cancel, return to OK, and command-D to Don't Save:

display alert "Test" buttons {"Cancel", "Don't Save", "OK"}
I found a new one: when adding a file extension to a file, Finder asks "Add ..." and "Don't add ..." and Cmd+A triggers "Add ..."



Jean-Christophe Helary
-----------------------------------------------
@brandelune http://mac4translators.blogspot.com

61 - 80 of 275