Is there any function that will return the path to where the current TB file is located within the file system (sort of like pwd)?
Not offhand, I think! Do you need it, or will something like “./”+$FileName suffice?
Not sure, would $FileName contain the fully qualified path of the TB file?. I want to store images and other artifacts externally to the current TB file in the Mac file system. For example, if the TB file is located in say
~Documents/Tinderbox/Daily Journal, I want to be able to store those artifacts within
Daily Journal in a directory (say
Attachments — which is given by a user attribute like
TbxAttachmentsPath) that is a peer to the TB file. Assuming there were a function
getCWD, then the path to the
Attachments directory would be
getCWD() + '/' + $TbxAttachmentsPath.
Why not use runCommand. Calling
pwd gives you home folder with is the _app’s
pwd. But afind
command might work. The problem searching from home directory scope itfind
wants to search~/Library
thowing permission errors. But, whilst~/Documents` used to be a got starting but, things like Dropbox or other Cloud-sync folder are peers of Document as and so out of such scope.
I got this stamp to work:
$MyDoc = eval(^docTitle^) + ".tbx"; $MyRoot = runCommand('pwd').replace("\r",""); $Text = "This file is at:\n" + runCommand("find "+ $MyRoot + $MyFolder + " -name " + $MyDoc );
Action code can’t access the doc’s name but export code can. You do need the
eval() or the subsequent concatenation fails as Tinderbox things you’re trying to pass a parameter to the export code.
The result of
pwd returns with a trailing carriage return character (i.e. as seen in Terminal output) so that needs removing before building the path. The default shell working director for theTinderbox app is always your home (
/users/[yourname]) folder. Note that the shell
find command cannot interprest the
~ shortcut for the home folder so don’t use it!
In the code above I’m starting in the
If you’d prefer the resulting path shorter, e.g. so more readable in Displayed Attributes, then this works:
$MyDoc = eval(^docTitle^) + ".tbx"; $MyRoot = runCommand('pwd').replace("\r",""); $Text = "This file is at:\n" + runCommand("find "+ $MyRoot + $MyFolder + " -name " + $MyDoc ); $Text = $Text.replace($MyRoot,"~");
We can go further and derive the TBX parent folder’s parth:
$MyDoc = eval(^docTitle^) + ".tbx"; $MyRoot = runCommand('pwd').replace("\r",""); $MyPath = runCommand("find "+ $MyRoot + $MyFolder + " -name " + $MyDoc ); $Text = "This file is at:\n" + $MyPath + "\nor\n" + $MyPath.replace($MyRoot,"~") + "\nThe TBX's parent folder is:\n" + $MyPath.replace($MyRoot,"~").replace($MyDoc,"");
For real use, I’d convert the attributes used to action code variables. For the ‘MyFolder’ part likely you can hard-code that or you will need an attribute to set the variable. The use of $Text here is mainly to make the result easier to see. You could put the eventual path(s) into attribute(s) if you so choose.
The stamp approach makes sense as it can be re-used in different TBXs.
Here is a demo file (look at its Stamps menu and Stamps Inspector!): pwd.tbx (77.6 KB)
Honestly it did not occur to me to use
runCommand (it should have). Thanks for taking the time to work all this out! I’ll give it a try.
pwd prints the current working directory, not the home directory unless the home directory happens to be the current working directory (cwd) (which is likely is in a call to runCommand). But if your shell is configured to charge the cwd before the code in your runCommand is executed, then the cwd may not be your home directory. However, all is not list. The environment variable HOME always contains the path to the home directory of the current user. So to guarantee that you get the home directory regardless of what the cwd happens to be, use the following:
I’m puzzled about the replacement about the carriage return in your example. MacOS does not emit a carriage return at the end of lines, only a newline (this is true on all operating systems that are certified as UNIX or POSIX compliant). You can see this in the following obtained by piping the output of
hexdump (try this on your own Mac). Note that the last character at the end of the hex is
0a, which is a newline; it would be
0d if it were a carriage return:
$ pwd | hexdump -C 00000000 2f 55 73 65 72 73 2f 72 6f 67 65 61 6c 65 78 0a |/Users/rogealex.| 00000010
Could it be that
runCommand() is itself adding the carriage return??
Did you try the demo file? If you use the stamp to get the cwd do you get something different? Also see this on the Command Line and Tinderbox. I can add some clarification to that article if needs be. I do think it fair though that if the user has gone to the lengths of setting a non-default
HOME on their system they will know enough to adjust the documentation available.
Argh, the article on runCommand() is confusing as I didn’t fully document this change in v6.0.1:
The runCommand() command has been extended to accept an optional third argument specifying the intended working directory.
creates a shell and runs the designated command. The input, if any, is passed to the command’s standard input. If directory is specified, it sets the working directory. Otherwise, the working directory is the user’s folder ~. (831)
That is what is behind the cryptic reference to a ‘directory’ option at the end of my runCommand article, which I’ll update IDC.
So, further to my demo file, if you need your command to run from a location other than
HOME you can do so via that third optional input for runCommand.
As to the line return, I’m not sure. It wasn’t until I got problems concatenating the home folder to the rest of the search path that I realised there was a line break. In resolving that, I discovered the gremlin was a carriage return
\r and not, as I’d initially guessed, a line break
\n. The latter matters when trying to remove that character!
Glad as I am that I can find where my doc is, I think it would be so much easier for the general user is action code had a property
docPath that returned the full POSIX path of the current TBX, and
docName as the names of the TBX file (plus extension). From that string it’s easy to construct alternative path, get the doc name (sans extension), etc.
Aha; runCommand is doing this in the services of a text engine we haven’t used in eons. I expect to change this in Tinderbox 9.
HOME is set by the shell, and remains set unless the user explicitly changes it (I’ve never seen that done though I am sure there are use cases for do so). But is is not uncommon to have the shell switch to a different directory before turning control over to the user, and determining if this is the case is not predictable without opening one of the run control files (E.g., zsh.rc) and looking to see if that has been done. The real point is that you cannot in runCommand count on
pwd returning the user’s home directory. Instead use the code that I suggested, which is guaranteed:
Note that the double quotes around
$HOME are necessary (if you use single quotes instead,
echo would emit
$HOME as its result; zsh — now the default shell in MacOS — treats double and single quotes differently, as do most shells).
As for your first query, yes I get the same behavior as you. What spired my response what that in your post you stated that
pwd returns the user’s home directory, which is technically not what it does. My objective was to add clarity to the conversation (the professor in me).
Finally, while you and I are comfortable with using
runCommand and perhaps the shell in general, my sense is that most users of Tinderbox are not (and would rather not be). Having Tinderbox provide a function to return the path to the currently open file would be authoritative and not require inference (or hope) that one has made the right decisions. I realize that each request that @MarkB acquiesces to comes at the expense of some other feature.
Amen. In another channel I’ve suggested action code properties docPath() and docTitle() with optional boolean POSIX-escaped options which might route around some of these issues. My demo above took more effort and thought than expected ‘just’ to get a path. I’m conscious that’s off-putting for a string people might need. Not necessarily often, but when in need…!