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

sh
shortguy
Posts: 28
Joined: Thu Jun 10, 2010 3:59 pm

Thu Nov 10, 2011 10:51 pm Post

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: Select all

-- 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


User avatar
Rayz
Posts: 506
Joined: Fri Sep 22, 2006 4:43 pm
Platform: Mac

Fri Nov 11, 2011 8:58 am Post

AmberV wrote: All basic stuff in other words.


Heh. For you maybe ... :D

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.
As if I didn't talk enough: Dom on Writing

User avatar
AmberV
Posts: 20612
Joined: Sun Jun 18, 2006 4:30 am
Platform: Mac + Linux
Location: Santiago de Compostela, Galiza
Contact:

Fri Nov 11, 2011 9:02 pm Post

I meant basic from the implementation standpoint. :) 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.
.:.
Ioa Petra'ka
“Whole sight, or all the rest is desolation.” —John Fowles

User avatar
Rayz
Posts: 506
Joined: Fri Sep 22, 2006 4:43 pm
Platform: Mac

Sat Nov 12, 2011 5:41 am Post

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
As if I didn't talk enough: Dom on Writing

User avatar
Rayz
Posts: 506
Joined: Fri Sep 22, 2006 4:43 pm
Platform: Mac

Sat Nov 12, 2011 5:51 am Post

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).
As if I didn't talk enough: Dom on Writing

So
Sophie
Posts: 216
Joined: Thu Aug 21, 2008 12:45 am

Sat Nov 19, 2011 10:33 pm Post

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.
I'm sure someone will shortly explain what I am missing :-) ... Sophie

User avatar
KB
Site Admin
Posts: 19190
Joined: Tue Jun 13, 2006 11:23 pm
Platform: Mac
Location: Truro, Cornwall
Contact:

Sun Nov 20, 2011 10:07 am Post

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
"You can't waltz in here, use my toaster, and start spouting universal truths without qualification."

User avatar
nontroppo
Posts: 752
Joined: Mon Mar 05, 2007 5:22 pm
Platform: Mac
Location: Airstrip One

Fri Dec 16, 2011 11:55 am Post

@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!!!

User avatar
subgeniuszero
Posts: 240
Joined: Fri Oct 28, 2011 11:34 am
Platform: Mac
Location: New Albany, IN
Contact:

Tue Feb 21, 2012 7:37 pm Post

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.
"We are star-stuff. We are the universe, made manifest, trying to figure itself out." — Delenn

Si
Simon Knight
Posts: 48
Joined: Tue Nov 06, 2007 9:26 pm

Thu Apr 26, 2012 12:33 pm Post

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

ta
taja47
Posts: 10
Joined: Fri Aug 03, 2012 3:12 pm
Platform: Mac

Wed Aug 08, 2012 4:22 pm Post

I'm also a bit late to this thread, and worse, don't know anything about scripting. But I do use Bookends, and it seems the developer has recently improved its Applescript capabilities:
https://www.sonnysoftware.com/phpBB3/vi ... f=6&t=3161
https://www.sonnysoftware.com/phpBB3/vi ... f=6&t=3122

So if there's any easy and useful way to get Scrivener to tap into Bookends that'd be great...

User avatar
KB
Site Admin
Posts: 19190
Joined: Tue Jun 13, 2006 11:23 pm
Platform: Mac
Location: Truro, Cornwall
Contact:

Thu Aug 09, 2012 9:53 pm Post

I was in touch with Jon at Sonny about this recently, in fact. I'm not sure it will add an awful lot to Scrivener's integration with Bookends seeing as it's probably better to scan documents once they have been exported to RTF, but it's on my list for further investigation.
"You can't waltz in here, use my toaster, and start spouting universal truths without qualification."

User avatar
nontroppo
Posts: 752
Joined: Mon Mar 05, 2007 5:22 pm
Platform: Mac
Location: Airstrip One

Sat Jan 19, 2013 2:08 pm Post

One thing I wanted to be able to do and hope an Applescript dictionary would enable: I want to export my Scrivener research folder into a standard filesystem hierarchy with documents (mostly PDFs) renamed to the names they have in Scrivener. So I suppose a script would need the ability to read the binder structure and binder names at the very least, even better would be to also enable export of document notes as a txt file with the same name as the document.

User avatar
KB
Site Admin
Posts: 19190
Joined: Tue Jun 13, 2006 11:23 pm
Platform: Mac
Location: Truro, Cornwall
Contact:

Sat Jan 19, 2013 2:46 pm Post

The same way Export Files works now?
"You can't waltz in here, use my toaster, and start spouting universal truths without qualification."

User avatar
nontroppo
Posts: 752
Joined: Mon Mar 05, 2007 5:22 pm
Platform: Mac
Location: Airstrip One

Sun Jan 20, 2013 7:51 pm Post

How did you sneek that feature in there without me realising!? Is there some sort of nefarious backdoor in Scrivener that allows you to keep adding features I need just to make me look an nincompoop on a public forum? :?

I'm sure you'll tell me that has been in Scrivener (gold) since V0.0005, are you playing with my memory too? :shock:

Fine. :oops:

(many thanks, that is exactly what I wanted!!!!) :D