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

Hi Keith,
Three suggestions, if this is still on your mind:

  • a property-rich “insertion point” and/or “selection” object, to access and modify the current selection. Including properties like: parent document, start offset, end offset, rich text. Contained by editor, window, document, application; containing: paragraphs, words, characters, attribute runs, etc (the standard text classes).
  • a “select”-command as companion, enabling instructions like “select paragraphs 4 tru 6 of current editor”, or “select insertion point after selection”
  • an “editor” class providing access to the currently displayed text in one of the editors, be it in an edit scrivenings session or not. The editor class would be contained by application, and it would contain documents, selection/insertion point (a class referring to the the currently selected text), and have properties such as: isCurrent, position (upper/lower), scrivening mode (boolean), current document (the one displayed), …

These may not be easy to implement on the basis of Apple’s text engine. Not even the otherwise highly scriptable DevonThink does the current-selection thing properly. But having spent a ridiculous amount of hours on developing inter-application workflows in Applescript, I feel that these are often what makes the difference (Pages 09 is not bad in this regard, but InDesign is still the reference).

Still hoping for AppleScript in 2.1 :slight_smile:

Martin

Thanks for the suggestions!

AppleScript is marked as the main feature for 2.1, don’t worry…

All the best,
Keith

In Scrivener 2.0 We have a great opportunity to write notes Can I make these notes to all Projects? Your notes for the entire project is a good idea, but it do not say when they were made? Day and time is very important. In my opinion it should automatically put the date and time as in the magazine … Can you add this feature?
And your spelling not working as it works in version 1.54. Why?

Is this an AppleScript request? If so that is slated for 2.1 or 2.2. As for spelling, it works exactly the same as in 1.54. Check the Spelling and Grammar settings to ensure they aren’t set to “Automatic by Language”. If this isn’t an AppleScript request, then please start a separate thread for tech support.
Thanks,
Keith

Hi Keith and crew,

Altering created/modified dates?

Don’t know if this has already been suggested - and don’t know for sure if it’s not already in Scrivener 2 - but if not, I’d love to be able to use applescript to change the created/modified dates on selected documents within a project.

Why? I’ve just switched to Snow Leopard, am going to upgrade to Scrivener 2 next week, and am finally going to give up on Mori for my catch-all notes manager (Oh, Jesse, why did you bring apokalypse down upon us?). I’ve got thousands of notes to export from Mori and import into Scrivener. The only ways I can think of to preserve creation dates for these notes is to either change my system’s date/time to match a group of notes’ creation date when I export them to rtf files in the Finder, or to modify the creation dates after importing them to Scrivener via applescript. (Of course, if anyone knows of a better way to do this, I’d be extremely grateful).

Thanks. Looking forward to Scrivener 2. Congrats on all the growth and success.

I’d love to be able to add a prefix and a suffix to a selection of text, as you can in TextWrangler or BBEdit.

Especially since I already wrote the applescript for TextWrangler, I’d just have to change the application name, set a keyboard shortcut, and be done with that pesky inserting of html comment tags :smiley:

Duncan

Is the following possible with Applescript:

  1. Save the project
  2. Make back up to local backup drive (external)
  3. Sync with Dropbox
  4. Close the project.

This would be a great script to execute when I’m done writing on my iMac, leave, and maybe work on it later on my MacBook. If this is not possible, I’d like torequest that :smiley:

Yes, this is possible. Scrivener already produces an automatic backup copy in the ~/Library/Application Support/Scrivener/Backups folder—though that can be changed in preferences. Thus, you can set up a script and attach it to this folder. It would be trivial to disperse copies of any incoming zip files to multiple locations. In fact some people like to skip one stage of that and just change their automatic backup folder to a place on Dropbox. That way whenever Scrivener creates one, it automatically gets uploaded as well as being stored on the local drive. You’d still need a script to copy it to the external drive though; so might as well keep the locations to three, since one of them rotates out older ones.

Something to clear out all the blank lines at the end of every document in the binder would be nice.

:slight_smile:

That’s more the type of thing that one would use AppleScript to do. AppleScript isn’t so much a suite of extra features—it’s a bunch of hooks into the interface and data models that let you make your own features—like this. So for something like what you describe, you would need the ability to trawl through the binder item by item; access to those items text data and the ability to write rich text modifications. All basic stuff in other words.

While it turned out to be eminently doable, my recent query about flagging text in a document that would not be included in the document’s word count got me thinking about what kinds of AppleScript functions and properties might be useful. The pseudo-code below illustrates strawman approaches to:

  • referring to a Scrivener project in different ways
  • referring to documents in a project in different ways
  • retrieving properties from a project
  • retrieving and processing text in a document
  • and extending the Outliner with a column named “AppleScript Results” that could contain the results of AppleScripts.

(The task itself is not the point.) Hope this is useful.

[code]-- strawman AppleScript pseudo-code that proposes ways of selecting documents, getting properties of a project, and processing text in documents,
– and proposes a custom column in the outliner that is dedicated to displaying the results of an AppleScript.

– the example task is counting the number of “manuscript words” in selected documents of a Scrivener project
– (“manuscript words”: the total number of words in the selected documents, less the total number of words that are in inline annotations).

– it’s just food for thought.

tell application “Scrivener”
– ==============================
– get a reference to a project. this could be done in a number of ways, such as:
– refer to the frontmost project:
set p to frontmost project

-- could also refer to a project by index:
set p to project 1

-- could also refer to a project by name, assuming that it is open:
set p to "My Great Novel"

-- could also refer to a project by path:
set p to "~/Library/Documents/My Great Novel/My Great Novel.scriv"

-- could also call up a Scrivener AppleScript dialog box to find and select a project (like calling "choose file" from standard additions):
set p to choose project "Select a project:"

-- ==============================
-- get the attributes that are used in the project to show inline annotations.
-- this is an example definition that uses color, background color, font, typeface (i.e., bold, etc.), and font size.
set attrs to {color, bgcolor, font, typeface, size} of inline annotations of p

-- an alternate way to get these attributes:
set attrs to attributes of inline annotations of p

-- ==============================
-- look in each of the selected documents in the target project,
-- and find the number of words that are formatted with the inline annotation's attributes. also, tally up the total number of words in the selected documents as we go.
-- refer to all of the currently selected documents:
set theSelection to selection of p

-- could also refer to them by their names:
set theSelection to {"Document 1", "Document 26", "Another document"} of manuscript folder of p

-- allow an arbitrary set of documents too, by using a parent/child structure of documents within folders.
-- ("manuscript folder" is a constant that can be used to refer to the manuscript folder, no matter what it is named):
set theSelection to {"Document 1", "Opening scene", "Another document"} of manuscript folder of p
set theSelection to theSelection & {"Some doc", "Theory of everything"} of folder "Notes" of project p

-- use collections, too, and allow selecting documents by index as well:
set theSelection to theSelection & document 2 of collection "My collection" of project p
-- or, could select all of the documents in a collection, folder, etc.
set theSelection to all of the documents in collection “My Collection”
set theSelection to all of the documents in folder “Folder 5”

-- a project browser would be useful, too -- this would call up a browser and
-- return a list of all of the documents selected by the user:
set theSelection to select documents of project p

-- count the manuscript words in each document.
set results to {}
repeat with ctr from 1 to count of documents in theSelection
	set doc to document ctr of theSelection
	set foundInDoc to 0
	-- note that "words" would have to be returned from Scrivener, so that a script doesn't calculate
	-- word count in some different way.
	repeat with w from 1 to words in doc
		set match to matchAttributes (attributes of w, attrs)
		if match = true then
			-- found a word in an inline annotation.
			set foundIndoc to foundInDoc + 1
		end if
	end repeat
	-- save the document name & counts.
	set results to results & {name:name of doc, totalWords: count of words in doc, inlineWords: foundIndoc}
	
	-- prepare the report.		
	set str to "Document: " & name of item ctr of results & return & ¬
		tab & "Total words: " & (totalwords of item ctr of results as string)" & return & ¬
		tab & "Inline annotated words: " & (inlineWOrds of item ctr of results as string) & return & ¬
		tab & "Manuscript words: " & (totalwords of item ctr of results - inlineWords of item ctr of results as string) & return & return
	set totalManuscriptWords to totalManuscriptWords + (totalwords of item ctr of results - inlineWords of item ctr of results)
end repeat

-- report the results.
display dialog str & return & return & "Grand total of manuscript words in " & name of p & ": " & manuscriptWords as string

-- if the outliner is being viewed, put the counts in the "AppleScript Results" column for all of the documents processed.
-- "outline" is a constant.
if current view = outline then
	-- "AppleScript Results" is a constant
	set name of column AppleScript Results of outline of project p to "Manuscript words"
	repeat with ctr from 1 to count of items in results
		repeat with outlineCtr from 1 to number of items in outline of project p
			if name of item ctr of theSelection = name of item outlineCtr of outline of project p then
				set text of column "Manuscript words" of outline of p to (totalwords of item ctr of results - inlineWords of item ctr of results as string)
			else
				set text of column "Manuscript words" to "(Not calculated)"
			end if
		end repeat
	end repeat
end if

end tell

– ==============================
on matchAttributes (w, attrs)
– return true if the attributes of the passed word match the attributes contained in attr,
– return false if they do not match.
– this is just an example way of doing this. this function could also be a Scrivener function.

if color of w = color of attrs and bgcolor of w = bgcolor of attrs and font of w = font of attrs and typeface of w = typeface of attrs size of w = size of attrs then
	set res to true
else
	set res to false
end if

return res

end matchAttributes

[/code]

Heh. For you maybe … :smiley:

So this thread is really about what bits of Scriv should hook into the Applescript engine. My goof, I completely misunderstood.

Sounds like I need a decent Applescript book.

Binder object returned from some sort of search criteria (so I can filter out documents from images and PDFs, and stuff in the draft folder that is included in the compilation. That could be a really big list of stuff).

Navigate through the text in the binder document would be good. Some kind or regex search and replace could be handy I suppose, so I could just search for all the new lines characters that occur at the end of the document and delete them.

Okay, apparently I don’t need a regex search because I can call something like SED from the operating system.

Right, I’m out of my depth right now but it all does sound doable.

I meant basic from the implementation standpoint. :slight_smile: OS X already provides a lot of those access methods, like the ability to read and manipulate rich text in an application window, which is what you’d need to strip out blank space. So that particular thing would not require any custom work to get operating. It’s the stuff like exposing binder items as objects that will need more work—but that’s going to be such a fundamental want that it would be any spec to begin with.

I’m not sure of this, but I know Apple finally added regex to Cocoa recently, so it might be something AppleScript has access to natively. Sure would be nice.

Not sure if there is regex support direct from AppleScript, but there is a third party extension that would probably fit the bill:

http://www.satimage.fr/software/en/downloads/downloads_companion_osaxen.html

Okay, how about this:

Hooks that would enable you to run AppleScript on the document generated from a compilation before it is written to word/PDF/plain text/whatever.

Could be used to strip those blank lines I’m obsessing about, or implement rudimentary styling. If you embed codes in the document then you could use a script to replace them with something else in the compiled output (leaving the original binder text unaffected).

Just curious – is scripting support being actively developed or considered for the new future?

My interest in scripting support in Scrivener shot up 400% when I found out that MacRuby is now a painless and lovely alternative for the scripting language.

It’s not being actively developed yet, no - it keeps getting delayed by other things. It will be one big effort for an update at some point (and then just adding to it based on suggestions after that). It’s non-trivial and involves a lot of planning, thought, coding and work. I’m hoping to get to work on it finally in the new year.
All the best,
Keith

@Sophie: Indeed the knowledge that we’ll be able to use MacRuby to interface to the Applescript instead of the infernal syntax of applescript itself – delicious!!!

I realize I’m a bit late to this particular thread, but here’s what I’d like to see:

  1. Full access to the binder, with documents as objects (with each one having a ‘name’ property, to make them easier to work with), and relative movement (using words like ‘left’, ‘down’, ‘right’, ‘up’), as well as the ability to move an object “into” or “out of” another one; i.e., “Move documentOne into documentTwo” or “Move thisDocument out of thisFolder”)

  2. Full access to the current editor window (and of course the ability to switch between editors and to make objects in the Binder active), with a few general text editing commands, and the ability to adjust the properties of text objects and selections.

  3. At least partial access to the Compile window, and the ability to use AppleScript to set formatting options for a Project, and especially to create and adjust properties of objects in the Formatting pane, and the ability to select compile formats and presets.

  4. Commands for file import and export commands, to possibly use in conjunction with Binder objects.

Other than of course making Scrivener fully open to GUI scripting through AppleScript (which is usually regarded as the ‘hard’ way to make AppleScript do stuff), this is about all I can think of.

—A.H.

Not so much Apple Script but related: enable the user to run applescripts/ scripts from either an application menu or an icon on a customised toolbar. See OmniOutliner for example.

Simon