Obtain the real path from the opened notebook itself

I want to obtain the real path from the opened notebook itself. See the following information:

NotebookInformation[][[1]];
%
"FileName" -> 
 FrontEnd`FileName[{$RootDirectory, "home", "werner", 
   "git-mathematica"}, "Matrix-quantum-mechanics.nb", 
  CharacterEncoding -> "UTF-8"]

As you can see, the realpath is as follows:

$ realpath Matrix-quantum-mechanics.nb 
/home/werner/git-mathematica/Matrix-quantum-mechanics.nb

But how can I construct this path based on the output of NotebookInformation?

Regards,
HZ

Have you tried NotebookDirectory[]?

NotebookDirectory[] can only give the result as follows:

/home/werner/git-mathematica

But I want to generate the full path name including the notebook’s name without inputting it manually.

NotebookFileName

Thank you for your tip. It does the trick. BTW, I also tried the following, but still can’t tweak out the result I want:

In[38]:= StringRiffle[{NotebookInformation[][[1]][[2]][[1]], 
      NotebookInformation[][[1]][[2]][[2]] }, "/"]
Out[38]= "{/, home, werner}/Untitled-1.nb"

You may try FileNameJoin.

But this method still needs to manually provide “File-BaseName”:

FileNameJoin[{NotebookDirectory[], "File-BaseName"}]

Hongyi,

Easier to do it using Pattern and ReplaceAll, rather than Part.

"FileName" /. NotebookInformation[] /. _[{path__}, fileName_, __] :> FileNameJoin@{path, fileName}

@Rohit Namjoshi

Really, it does the trick. I’m new in Wolfram language. Would you please give me some explanations on the working logic of the above code snippet?

Hi Hongyi

Take a look at

NotebookInformation[] // InputForm

it is a List of Rule. We are interested in the “FileName” Rule so extract it (similar to how one would extract a solution from Solve)

"FileName" /. NotebookInformation[]
(* FrontEnd`FileName[{$RootDirectory, "Users", "rohit", "Documents", 
  "Mathematica"}, "test.nb", CharacterEncoding -> "UTF-8"] *)

We are interested in the first argument, the List passed to FrontEnd`FileName which are components of the path, and the second argument which is the file name. We can extract them using the pattern

_[{path__}, fileName_, __]

The first _ matches any head, in this case FrontEnd`FileName. The {path__} matches the first argument as a list of something and binds it to path. The fileName_ matches the second argument and binds it to fileName, the __ matches the rest of the arguments which we don’t care about so it is not bound to anything. We now have the pieces we need

"FileName" /. NotebookInformation[] /. _[{path__}, fileName_, __] :> {path, fileName}
(* {"/", "Users", "rohit", "Documents", "Mathematica", "test.nb"} *)

So we pass it to FileNameJoin to add the right directory delimiters for the OS

"FileName" /. NotebookInformation[] /. _[{path__}, fileName_, __] :> FileNameJoin@{path, fileName}
(* "/Users/rohit/Documents/Mathematica/test.nb" *)

One thing to be aware of is that path is a Sequence not a List so there is no need to Append fileName to it before passing to FileNameJoin.

"FileName" /. NotebookInformation[] /. _[{path__}, fileName_, __] :> path
(* Sequence["/", "Users", "rohit", "Documents", "Mathematica"] *)

Hope you enjoy your Wolfram Language journey. 千里之行,始于足下

Dear Rohit Namjoshi,

Thank you for your in depth, systematic, detailed and insightful analysis and interpretation. But I still have some additional confusion as described below:

[{path_}, fileName_, __]

I tried the following methods, and they all gave the same results:

_[{path__}, fileName_, _]
_[{path__}, fileName_, __]
_[{path__}, fileName_, ___]

One thing to be aware of is that path is a Sequence not a List so there is no need to Append fileName to it before passing to FileNameJoin.

  1. What’s the difference between a Sequence and a List?

  2. In my humble opinion, Wolfram language in nature is a type (dialect) of lisp, as described here. If so, all things in Wolfram language should be List. Is there anything wrong with my understanding?

  3. As per you said above, how can I check the data type of specific object? For example, in this case, if I don’t run the following command, how can I know the Sequence data type of the result?

    "FileName" /. NotebookInformation[] /. _[{path__}, fileName_, __] :> path
    

Actually there is NotebookFileName for obtaining the full path to an opened Notebook:

NotebookFileName[EvaluationNotebook[]]

According to the document, it seems that no formal parameters seem to be required for the question discussed here:

NotebookFileName[]
gives the file name of the current evaluation notebook. 

NotebookFileName[nb]
gives the file name for the notebook specified by nb.