AppleScript: what do you want to see in the Scrivener Suite?

I have to admit, this is something that I haven’t given a lot of thought, having had it in the back of my head that it would be a remote possibility in the distant future. :slight_smile: At the same time, providing what is essentially an API to a complex application is pretty significant task. You want to strike a balance between abstraction and detail.

Take a look at OmniOutliner Pro’s dictionary. That is a classy (though a bit exhaustive!) example of how AppleScript should be supported. Not everything is directly translateable, but there are some good ideas in it, I think. Afterall, this is the dictionary that allowed Ethan to take an ordinary outliner and turn it into an automated cross-referenced to-do list with iCal synchronisation.

Some obvious things would be full access to the Binder. Allow the creation, movement, and deletion of items within it. This would probably be most easily accomplished by allowing the scripter to assign item objects to variables, and a battery of methods which allow a full range of horizontal and vertical movement, adding, and trashing. This would probably be best done by providing the ability to assign binder objects to variables, and using them as targets in the move commands, basically what the Move To menu currently allows. I wonder if relative up/down/left/right movement would be handy for some people, too?

Addressing objects in the Binder is something that would need a little thought. Since items can have identical names, access to the underlying reference number would be important. Fixed items such as the Draft should probably be accessible by name.

Another area that could be addressed is aspects and settings of the project itself. You probably would not want to go too far into that–but I can see how the setting of some things would be nice to add. For example, the ability to hold label/status in an array. Editing them would probably be unnecessary, more important is allowing the script to “know” what meta-data exists in the document, for the purposes of assigning them to binder objects. Of course there is the project notes, references and scratchpad. The contents of these should definitely be accessible, perhaps not the functions of them. For example, there is little reason to script Scratch Pad’s handy data movement feature, since a script can just as easily do that itself.

In the Document object. One would definitely want access to the two rich text areas: Main edit and Notes (see next paragraph for details). Synopsis, Title, and other meta-data. A good question would be how to address label/status, since each project can supply its own nomenclature. The simple answer would be simply to call them label/status, but that is merely the default nomenclature. Perhaps referring to them as their Corkboard appearance refers to them: pins and stamps? Keywords are pretty straight-forward. That is just an array. References are a little more interesting, but a reference object with a name and URL would be pretty easy to interface with, I think, but a better question would be whether or not there would be much third-party need to mess with reference lists. I suppose it could be handy if you have a list of URLs and wanted to turn them into references.

In the text itself; have a look at OmniOutliner’s dictionary in the Extended Text Suite section; lots of useful methods in there. Footnote/annotation toggle on ranges, and the ability to linkTo binderItem, and unlink on a range of text. Scripted link manipulation could be very useful. Annotation and footnote access would be more important in the import/export type scripts. This could potentially expand Scrivener’s ability to interface with odd applications. For example, getting Page’s comments and annotating them correctly, or vice versa. Access to highlights would let a person go through the entire project, highlighting a certain phrase they know from experience they tend to abuse.

Splits would need to be addressed. There needs to be a keyword to operate on the focussed split, as well as the unfocussed split. The ability to test if the editor is currently split or not. Either that or ‘smart’ handling: set edit_me to rich text from selected split Would just get text from the editor if no splits are open, as would from unselected split.

Maria, your suggestions are more along the lines of implementation than syntax and access: Here are some possible methods and their requirements.

This should be a fairly easy script to write if you have access to the rich text and rudimentary Binder manipulation. You wouldn’t need access to the cut command per say, as you can find spots in a text string, split the string, and create a new document with string2. The ability to create a new document with a rich text block in place–would that bypass Scrivener’s auto-Synopsis?

This would need the ability to grab the binder items currently represented in the E.S. session; and it would also require access to the focussed split, as well as the export settings (which may be overkill for round 1).

I’m not sure what you mean with this one. Do you mean the ability to create named snapshots? That is actually an interesting idea. You could create ‘machine friendly’ titles that saved the meta-data. It is prone to failure though, unless you are pretty careful about keeping labels/status around even after nothing current is using them. What is the length limitation on snapshot titles? Making snapshots in general is probably not a bad idea, actually. It would make running a script much safer if you knew it would back up the current text before slicing and dicing.

Anyway. I am not a super-experienced AppleScript coder. I know enough to create some simple automation or edit things that others have done. This will all benefit me in the end though, through the OSA. This all would put Scrivener out on (yet another) platform of its own. There are very few authoring programs with good AppleScript support.

OK, I thought you would extract what has to be exposed via AppleScript from requests like this and dictionaries already present for other applications.

And as I stated, these processes could be part of the Application as well. I understand and use AppleScript as an extension of the application.

Maria

AmberV,
you do what I thought Keith wanted to do: Collecting ideas of what could be done and then extracting the features AppleScript needs to expose.

I already like the titles of the zipped backups very much: Project name and date-time, very helpful. I thought of exposing an additional dialog (which could be done by Scrivener or AppleScript) to add a comment like “State before deleting reordering chapter 6 according to the ideas in …” or “state before moving the project to the iBook”. – Of course, all this can be done with other means as well, but we were asked for AppleScript, and I thought of usage scenarios.

As for snapshot, I think, it is sometimes good to get rid of them in the actual project but keep them easily accessible. So an export feature might be helpful.

These were just ideas before breakfast, there are exactly 4 features that I would love Scrivener to have, but they will not be implemented the way I personally like (which is absolutely OK for me), all other features are not essential to me. I was just brainstorming. Basically Scrivener is developed for my needs. I live in Scrivener when I am not working outdoor.

All the best,
Maria

A couple of things that just pop into my head when thinking about the Applescript are flags about the state of certain things, such as whether or not the program is in full screen mode. Some things I was thinking of, such as whether certain windows or palettes were visible probably falls under the Standard window object.

Also access to any statistics which aren’t easily available from querying the text objects, like those which depend on user preferences.

If I think of something else, I’ll let you know.

I’d probably use Scrivener Applescript support to grab individual documents / resources out of scrivener and stick them in an archive (e.g. EagleFiler, Yojimbo/DevonThink, etc.) or move rss and bookmarked resources to or from web apps (e.g. WebNoteHappy, Pukka, NetNewsWire, Vienna etc.)

Example 1: Document database app support

I decide that something I’ve saved in my document database app (e.g. EagleFiler, Yojimbo etc.) would be handy in a Scrivener document, and I want to import it in a fine-grained way (mapping metadata). Or, conversely, I decide that something I collected in a Scrivener document is useful enough that I want to move it to my general archive.

So I might highlight a document (or documents?) in the Scrivener binder and run an Applescript to import copies into EagleFiler/Yojimbo. I’d want Scrivener dictionary entries for:

  1. title
  2. path (POSIX)
  3. url (if any)

That should get me images, RTF documents, and weblocs/webarchives.

Bonus, I’d like the option to get:

  1. abstract (-> description)
  2. keywords (-> tags etc.)
  3. datemodified, datecreated, status, label etc… any metadata, which I can then stuff in the script if I want at added to the target application.

Conversely, I highlight a document (or documents) in EagleFiler/Yojimbo and run a script to copy it into the Scrivener Research folder as a new entry (or new entries). I want to be able to write to a new object in the binder with Title, abstract, keywords, etc. For this, it might be nice to have an addressable “text” field so that I could directly assign what the new object would contain (most of these programs don’t use a database made of RTF files, so passing a POSIX path isn’t possible).

Example 2: Bookmarking

Exactly the same, except with apps like NetNewsWire, WebnoteHappy, or Pukka. You can’t write entries to RSS readers, but you might be subscribed to feeds and want to quickly and completely copy selected entries into your Scrivener Research folder - again perhaps by passing a title, url, and optional abstract/keywords/date-information. With bookmark managers, you likewise might want to import into Scrivener - or you might decide you want to push selected Scrivener resources with URL information out to your bookmark archive or a del.icio.us feed - other than title, url, and abstract, I’d definitely want to recover keywords and write them to tags - so it would be important to get the keywords output either as an array or as a string that supported space-delimited or comma-delimited format (space-delimited is the more popular target, I believe).

Those are my thoughts - I hope they are helpful if you decide to go ahead with this. If those entries were available, I could probably write a batch of scripts connecting the apps mentioned. If highlighting multiple documents in the Scrivener Binder allowed me to loop on my export scripts, that would also be excellent.

Regarding the above discussion of parsed binder imports: a number of interesting advanced effects could be pulled off with Binder manipulation routines, however my two-cents would be to first focus on entirely implementing access to individual entries and entry collections, and create a basic way of dumping a new entry into the Binder.

My thinking on this is that scriptable Binder manipulation is a big can of worms, and you can do most things without it - for example, if you wanted to parse a large import document by headers, you can write the pieces to the bottom of the binder in parse order and then let the user drag them wherever, all without any addressable Binder manipulation terms at all. Its only in importing nested outlines that you would need to support insertion points or outliner-like commands.

I’m not against rich addressable binder manipulation via applescript - I’d just suggest that you make that the Scrivener Applescript Dictionary 2.0 rather than 1.0 goal, and start by putting out the basics so people can test it for you with scripts.

Thanks - this is very helpful. Yes, for a start I definitely just want to go with the most useful basics. I don’t want to open up a whole host of potential new problems just yet, and I don’t want to dedicate too much development to this at this stage, either - I just want to add the basics that will enable some useful scripting for inter-app support. A lot of your suggestions make sense, Jeremy, and I will look into them. Amber - I am looking at OO Pro’s AppleScript support and it is impressive, though obviously Scrivener won’t be able to offer that sort of extensive support at this stage, as you note yourself.

Thanks!
Keith

I am a modern Major General and I made a little list;

convert - text to pdf
convert or format - to multimarkdown
convert - all caps
convert - lower case
convert - plain quotes
convert - smart quotes
image - duplicate
image - flip
image - rotate
delete - trash folder
move - to pre-trash folder
insert - current date and time
create - vertical split
create - horizontal split
speak - text
url - Scrivener forum
append - note
create - index
create - note from selection
import - image
import - Screenwriter script
import - Final Draft Pro script
import - Montage script
insert - date and time

Just idea starters.
:confused:

Importing of Mail.

Yes, to be able to import emails into Scrivener would be really great.

I think if I could import attachments directly from Mail into Scrivener, that would be a reason to switch back from GyazMail to Apple Mail … unless of course it was possible to set up an Applescript that worked with GyazMail.

:slight_smile:

Mark

I work with Entourage, but that process is fairly simple: (1) select the attachment and drag to Desktop, (2) select the file and drag to Scrivener. A script might make that quicker, but how would it know where to place the file? I guess I’m wary of automation that cuts into thought and decision.

Hi,

Sorry, maybe I wasn’t very clear in my original post - I guess if you have never written an Apple Script then the first post didn’t make my question very clear.

I don’t want any suggestions for actual Apple Scripts here. Things like an import for MMS or Final Draft, or a direct Mail attachment import and suchlike could possibly be supported via Apple Script, but that is not my concern at all - that sort of thing will fall to users who want to create Apple Scripts for Scrivener. I won’t be creating any myself (I am not an Apple Scripter as already mentioned).

No, I am really asking the people who use Apple Script what sort of commands, elements and suchlike they would like to have access to in order to create such extra functionality.

To reiterate, I would like ideas for the contents of the Apple Script dictionary itself, and not suggestions for actual Apple Scripts that could add functionality to Scrivener, as that is up to others.

Thanks!
Keith

One of the fastest ways to add automation functions to Scrivener might be to add some Automator actions. I use Automator to to move email messages into a FileMaker database, for instance. I also use it to move any desired selected text from a webpage into the appropriate FM database. In all, I probably use about a dozen Automator scripts. Some Automator actions work on their own, while others complete specified steps, then trigger Applescripts created by using FileMaker’s built-in Applescript creation tool: ScriptMaker.

With FileMaker the user can open ScriptMaker and select “steps” from the large menu of commands offered. The script then runs through each of the selected steps until the entire script has been run. This makes it fairly fast and easy to use. If a user knows how to write his own Applesctipts, they can be added to the ScriptMaker script where they will then run as an additional step within the FM script.

—m.

Yes, but the point is that in order for an app to work with Automator, it first needs to be AppleScriptable - I most certainly will not be providing any Automator actions, that will be left to users for now. Which brings me back to the original question: what sort of AppleScript commands and elements should be available? I sort of feel as though I am talking in circles here. :slight_smile:

So, to keep this on-topic: please post only suggestions for what should go into a Scrivener AppleScript Suite. If you do not know what an AppleScript Suite is, please do not post in this thread (but feel free to post any such suggestions elsewhere on the forum, of course). The main reason I ask this is not to be rude, but because I don’t really understand AppleScript myself, so I’m kind of asking for help here. Browsing through the documentation I can find, it is starting to look a lot more complicated than I had anticipated, and this may well get left until 1.5 or 2.0 now.

If you do understand AppleScript, please do post ideas for the Suite, and any advice you can give me on getting to grips with this would be much appreciated.

Thanks!
Keith

Don’t lose heart. The ability to create entries at the bottom of the binder with defined terms for title and contents (optionally, abstract) would be a great first step - metadata options can wait, and import is probably more important to most people than export, so you could also just put export off until later.

I don’t know enough about the inner workings of Scrivener to understand how you would support non-textual importing, but I’m assuming you would use a create/import which accepts either a POSIX path or URL in order to import images, pdfs, webarchives, weblocs etc.

My extremely unscientific guess is that creating title/contents and importing POSIX paths or URLs is 90% of your use cases - some people (like me) will also be extremely excited about preserving particular metadata (mailtags-keywords, file datestamps, labels etc.) or about exporting, but that is probably your last 10%, and can wait.

I’m not entirely clear on what an application has to include in its suite as opposed to things (if any) that are just part of OS X, but here are a few thoughts:

selected text
selected binder document
convert (binder document into folder)
insert (as in inserting a file on your computer into the Binder)
create (create a new blank document in the Binder)
merge (merge two documents in the Binder)
split (split a document into two at the insertion point)
move to trash
empty trash

Also have a window class (id, position, bounds, etc).

Just noticed this thread, and yes I have some ideas :slight_smile:

To get a general feel what an Applescript Suite should support, run the Script Editor and open the dictionary for DevonThink. You’ll notice two types of exports: data types (i.e. objects with properties) and actions (routines called to get objects or interact with the app).

If I were adding Applescript for Scrivener, I’d add at least the following data types:

Application (has Active Wndow contains DocumentWindow, Current Project, Recent Projects, etc)
DocumentWindow (has Selected Text and such)
Project (has name, notes, contains Binder)
Binder (contains BinderItems, has Root Group which contains Drafts/Trash/etc)
BinderItem (has name, path, synopsis, notes, references, type, label, status, keywords, etc)

…and so forth.

I’d support the following actions like the following:

open project (closes current project)
create binder item at path
delete (to trash) binder item at path
move binder item at path to path
get binder item at path
take snapshot
backup project to file_path
export project to file_path
import file at file_path to path

Applescript is used for two things: automation and interacting with other applications (could be considered the same thing actually).

This means that there needs to be direct access to the raw data in Scrivener (text, keywords, labels, status, references, and notes) via data types, and access to commonly-automated tasks (opening, saving, exporting, importing) via actions.

In an application like Scrivener, exposing the data types (which are all native to OS X and will play well with Applescript) is more important that providing routines. Consider the likely use cases, and how the scripts for them would be written:

  • List unfinished items: iterate over documents, printing all with TODO status. Same applies for listing document keywords, references, etc.
  • Add metadata to a document: find document, modify notes/ref/keyword/status/synopsis
  • Apply text changes: find document, modify RTF directly
  • Add file to project: invoke import routine
  • Export data from project: compile export settings and list of object IDs to export, then invoke export routine
  • Send selected text to application : get selected text, tell application

I don’t see much value in adding applescript support for the kind of stuff that generally requires human interaction/judgement, e.g. merging and splitting documents/empty trash, or for the stuff that applescripts can easily do themselves, e.g. convert case/insert date/etc.

So the heart of the applescript suite would be the BinderItem data type:

BinderItem
Name (string)
Location (string: path from Binder root)
Path (string: path inside project dir)
Type (r/o)
Title (string)
Label (integer)
Status (integer)
Synopsis (string)
Create Date (r/o)
Mod Date (r/o)
Include in Export (boolean)
Page Break Before (boolean)
Preserve Formatting (boolean)
Notes (string)
Keywords (list of Keyword objects)
References (list of Reference objects)
Target (?)
Progress (?)
Children (list of BinderItem objects)

Note word count and char count are unneccessary for BinderItem as they are inherent properties of applescript strings, though per-project counts should be included.

Based on this, the rest of the data types become obvious (Reference, Keyword, Binder containing BinderItems, Window containing Binder, Application containing Window), and the routines simply become ways to either to access (create/find/delete) the types, or to perform operations that aren’t related to modifying data stored in types.

Thanks edf - they are great ideas and that looks like a very good start for an AppleScript suite. Shame that implementing the Cocoa side of it looks a lot more difficult (and obliquely documented) than I had hoped…

You mean it’s not as simple as setting NSAppleScriptEnabled to True in the plist? :wink:

Yeah, scoping out the Cocoa Scripting Guide doc, it looks a bit involved, and the writing is rather obtuse. Reads like agile programming books.

This guy has a decent (but possibly outdated) play-by-play of adding applescript to an app, if it helps:

http://www.stone.com/The_Cocoa_Files/Adding_Applescript.html

Some complaints and workarounds are given here:

http://earthlingsoft.net/ssp/blog/2004/07/cocoa_and_applescript

All this Cocoa discussion makes me glad I’m off doing backend stuff these days.

Good luck! I’m looking forward to scripting Scrivener