Question From a First Timer About Copying Source

Hi! I am new here and did some Googling but was still pretty confused so sorry for the newbie question.

My entire goal is to figure out a way to copy a chunk of text as well as information about the source - (if the text is from a website, then I'd like to copy the text, URL and Title, and if its from an internal document, I'd like to copy the text, file id/path, and file name.) then I'd like to send the text and the citation to be appended to a document in OmniOutliner, and copied to a new document in DEVONthink.

I think I am getting there slowly, but for the life of me I can't figure out how to get the file name of whatever document I'm copying text from. I see how to get the URL if I'm copying from the Internet, but don't see how to get the file name if I'm copying something from my internal files. When I try to use the "set file" or "get file attribute" options, they seem to require a static document. but htis variable would change every time I copied text. any help would be much appreciated!

Hey @jdr,

That's not too surprising, since it can't be done if the given application doesn't have AppleScript support.

Unless of course you know the magic spell.

See this:

Finding the File Path for the Front Document in the Front Application

If you can't figure it out from there then holler at me.

@peternlewis – this comes up with some frequency – would it be possible to add a token for the path to the front document in the front application?

-Chris

Wow thank you sooooo much for the quick response! this is helpful.

Would this only work for text documents like Microsoft Word? What about if I'm working in an Obsidian document?

Thanks again!

I can't speak about Obsidian, because I've never used it.

It depends upon whether the developers have properly implemented accessibility in their app.

You'll just have to try it and find out for yourself.

-Chris

Possibly. I'm not sure how reliable it is, probably reliable enough I suppose.

It can be done as a Plug In action, and indeed I use a similar plug in action for getting the path of the front Preview window, but since it actually supports AppleScript, its easier with:

tell application "Preview"
   path of document 1 of window 1
end tell

And that is the problem with implementing it as a token - then when it doesn't work its considered a bug in Keyboard Maestro rather than poorly behaved applications. This does not always stop me, but it does make me hesitant.

1 Like

It also depends on, for example:

  • Whether or not any documents are actually open in the front application,
  • and whether the front document, if it exists, is saved.

A token is best used as a simple function that yields a predictable and intelligible value.

This kind of thing depends on contingencies that really need to be handled by a script, and even JS code like the function below will always yield false negatives if an Electron app like Visual Studio Code is at the front:

// frontDocPath :: Application Name -> Either String FilePath
const frontDocPath = appName => {
    const ds = Application(appName).documents;

    return 0 < ds.length ? (() => {
        const
            doc = ds.at(0),
            path = doc.file();

        return null !== path ? (
            path.toString()
        ) : `Document not saved: ${doc.name()}`;
    })() : `No documents open in ${appName}`;
};

If it doesn't find a viable path then you could return PATH NOT FOUND.

That would make error handling pretty straightforward for the user.

-Chris

My time tested System Events code actually does work with Visual Studio Code.

tell application "System Events"
   tell application process "Code"
      tell front window
         set frontDoc to value of attribute "AXDocument"
      end tell
   end tell
end tell

return frontDoc

So it will likely work with other Electron apps as well.

-Chris

1 Like

I agree – that's much the best approach and should work with Document-based Electron apps. Looking at uses of it in my JS library, I notice that it's wrapped in things to cope with:

  • spaces in the file path (which will need to be uri-decoded, as in file:///Users/houthakker/Desktop/sample%20test.applescript)
  • the file:// prefix

and, of course, more marginally:

  • cases where no window is open in the application,
  • cases where there is a front document but it isn't saved,
  • and optionally, rewriting the path to the user $HOME as ~

Yes. My full hander does a bit more than the rough example above.

I don't quote or escape spaces in the resulting POSIX Path, because I use them in too many contexts where that might or might not be problematic.

-Chris

--------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2021/11/27 22:18
# dMod: 2021/11/27 22:22
# Appl: System Events
# Task: Return the POSIX Path of the Front Document in the Frontmost Application (If Available).
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @ASObjC, @System_Events, @Return, @POSIX_Path, @Front, @Document
--------------------------------------------------------
use AppleScript version "2.4" -- Yosemite and later
use framework "Foundation"
use scripting additions
--------------------------------------------------------
property LF : linefeed
--------------------------------------------------------

set fullPosixPath to pathToFrontmostDocument({tildeAbbreviation:false})
set tildePath to pathToFrontmostDocument({tildeAbbreviation:true})

--------------------------------------------------------
--» HANDLERS
--------------------------------------------------------
on pathToFrontmostDocument(parametersRecord)
   
   tell application (path to frontmost application as text) to set processName to its name
   
   tell application "System Events" to tell application process processName
      
      if exists of (first window whose subrole is "AXStandardWindow") then
         
         tell its (first window whose subrole is "AXStandardWindow") to ¬
            set frontDocFileURL to value of attribute "AXDocument"
         
      else
         error "The front document seems to be missing!"
      end if
      
   end tell
   
   if frontDocFileURL is not missing value then
      
      set posixPathOfFrontDocument to (current application's class "NSURL"'s ¬
         URLWithString:frontDocFileURL)'s |path|() as text
      
      if tildeAbbreviation of parametersRecord = true then
         set posixPathOfFrontDocument to ((current application's NSString's ¬
            stringWithString:posixPathOfFrontDocument)'s stringByAbbreviatingWithTildeInPath) as text
      end if
      
      return posixPathOfFrontDocument
      
   else
      error "No File-URL was returned for the front document!" & LF & ¬
         LF & ¬
         "It would appear to be Unsaved..."
   end if
   
end pathToFrontmostDocument
--------------------------------------------------------
1 Like