How to get filename without extension from Omnigraffle?


#1

I’m trying to get the filename without the extension of the current document file in Omnigraffle Professional 5.

tell application "OmniGraffle Professional 5"
    set _document to front document
    set _path to path of _document

    -- Get filename without extension
    tell application "Finder"
        set {_filename, _extension, _ishidden} to the
             {displayed_name, name_extension, extension_hidden} of the _path
    end tell
end tell

This gives me the following error: error "Can’t get displayed_name of \"/Users/ca/Downloads/Feb 8.graffle\"." number -1728 from displayed_name of "/Users/ca/Downloads/Feb 8.graffle" .

I found some related questions and pages, but I’m a bit lost and really can’t understand why it does not work.

Thanks for your help!


#2

A few things wrong here:

  1. path of document returns a POSIX path (i.e., something like /blah/blah/blahbity/blah), but the properties you are asking about belong to the Finder’s item object, not the POSIX path
  2. it’s displayed name, name extension and extension hidden without underscores
  3. don’t nest tell application blocks

try this instead:

tell application "OmniGraffle Professional 5"
	
	set _document to front document
	set _path to path of _document
	
end tell

-- Get filename without extension
tell application "Finder"
	
	set _file to (POSIX file _path) as alias
	set {_filename, _extension, _ishidden} to the {displayed name, name extension, extension hidden} of the _file
	
end tell

#3

and if you want to stay in OmniGraffle scope, rather than using Finder methods, another approach is to paste in some prefab functions:

tell application "OmniGraffle"
    set fp to path of front document
    
    {my takeDirectory(fp), my takeFileName(fp), my takeBaseName(fp), my takeExtension(fp)}
end tell

------------------- PARTS OF FILE PATHS -------------------
-- https://github.com/RobTrew/prelude-applescript


-- takeBaseName :: FilePath -> String
on takeBaseName(strPath)
    if strPath ≠ "" then
        if text -1 of strPath = "/" then
            ""
        else
            set fn to item -1 of splitOn("/", strPath)
            if fn contains "." then
                intercalate(".", items 1 thru -2 of splitOn(".", fn))
            else
                fn
            end if
        end if
    else
        ""
    end if
end takeBaseName

-- takeDirectory :: FilePath -> FilePath
on takeDirectory(strPath)
    if strPath ≠ "" then
        if character -1 of strPath = "/" then
            text 1 thru -2 of strPath
        else
            set xs to init(splitOn("/", strPath))
            if xs ≠ {} then
                intercalate("/", xs)
            else
                "."
            end if
        end if
    else
        "."
    end if
end takeDirectory

-- takeExtension :: FilePath -> String
on takeExtension(strPath)
    set xs to splitOn(".", strPath)
    if 1 < length of xs then
        "." & item -1 of xs
    else
        ""
    end if
end takeExtension

-- takeFileName :: FilePath -> FilePath
on takeFileName(strPath)
    if strPath ≠ "" and character -1 of strPath ≠ "/" then
        item -1 of splitOn("/", strPath)
    else
        ""
    end if
end takeFileName

------------------------------ GENERIC -------------------------------

-- init :: [a] -> [a]
-- init :: [String] -> [String]
on init(xs)
    set blnString to class of xs = string
    set lng to length of xs
    
    if lng > 1 then
        if blnString then
            text 1 thru -2 of xs
        else
            items 1 thru -2 of xs
        end if
    else if lng > 0 then
        if blnString then
            ""
        else
            {}
        end if
    else
        missing value
    end if
end init


-- intercalate :: String -> [String] -> String
on intercalate(delim, xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, delim}
    set str to xs as text
    set my text item delimiters to dlm
    str
end intercalate

-- splitOn :: String -> String -> [String]
on splitOn(pat, src)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, pat}
    set xs to text items of src
    set my text item delimiters to dlm
    return xs
end splitOn