Jump to content

Subtract a file name from a path name?


be_bo

Recommended Posts

I'm printing CAD to PDF using LSP.

Here is the code for a full file name path:

 

(setq pdf_name (getfiled "Specify file name to plot *.pdf" (getvar "SAVENAME") "pdf" 5))

 

i.e. - i:\cadd\project\Plan.pdf

 

What would be the code to capture the folder path only, in other words, how can I subtract a file name from this expression, and get only a folder name?

 

i.e. - i:\cadd\project\

 

Thank you!

Link to comment
Share on other sites

  • Replies 22
  • Created
  • Last Reply

Top Posters In This Topic

  • be_bo

    7

  • Lee Mac

    5

  • pBe

    5

  • irneb

    4

Top Posters In This Topic

That would get the path to the folder with DWG file.

I'm saving the PDF file into the different folder.

My lisp would invoke a dialog box and a user can browse and save the PDF inito the folder of his choice.

I need to get the path to this folder, so I can open this folder.

So, I need to subtract a file name from this expression, and get only the folder name.

Link to comment
Share on other sites

(vl-load-com)
(setq path "i:\\cadd\\project\\Plan.pdf")
(setq file (VL-FILENAME-BASE path))
(setq dir (VL-FILENAME-DIRECTORY path))
(setq ext (VL-FILENAME-EXTENSION path))

Link to comment
Share on other sites

there are more than one way to retrieve folder path...

 

but since you already have the variable pdf_name

 

(substr pdf_name 1 (- (strlen pdf_name)(strlen (getvar "dwgname"))))

 

:)

 

VVA you beat me to it

Edited by pBe
typo
Link to comment
Share on other sites

That was something I had to play with, but I made it to work!

Thank you!

спасибо, земляк!!

Edited by be_bo
typo
Link to comment
Share on other sites

there are more than one way to retrieve folder path...

 

but since you already have the variable pdf_name

 

(substr pdf_name 1 (- (strlen pdf_name)(strlen (getvar "dwgname"))))

 

Bear in mind that is not generic in that it assumes the filename is of the same length as the current drawing filename... *just making you aware*

 

Anyway, some have already been posted, but here are a few more:

 

(car (fnsplitl <filename>)) 

(vl-filename-directory <filename>)

(substr <filename> 1 (vl-string-position 92 <filename> 0 t)) ;; assumes "\\" used

(substr <filename> 1 (vl-string-position 92 (vl-string-translate "/" "\\" <filename>) 0 t))

Link to comment
Share on other sites

Bear in mind that is not generic in that it assumes the filename is of the same length as the current drawing filename...

 

by george you're right :shock:

 

(substr <filename> 1 (vl-string-position 92 <filename> 0 t)) ;;;;; Lee Mac 2010

 

This ones cool 8)

Link to comment
Share on other sites

Thank you LeeMac for code and for making me aware, too!

You explained me why when PDF file name length was set differently from DWG file name, it didn't give the proper folder name, while I was using

(substr pdf_name 1 (- (strlen pdf_name)(strlen (getvar "dwgname"))))

Link to comment
Share on other sites

Thank you LeeMac for code and for making me aware, too!

You explained me why when PDF file name length was set differently from DWG file name, it didn't give the proper folder name, while I was using

(substr pdf_name 1 (- (strlen pdf_name)(strlen (getvar "dwgname"))))

 

I apologize for that be_bo.. i assume too much, ....... Lesson learned

 

"pBe Go to your room!!!!! " :oops:

Link to comment
Share on other sites

Just as another problem, filenames (and even folder names) may have more than just one dot. They may also not have any extension at all.

(vl-load-com)
(defun splitpath (path / sLst item ext name folder stage)
 (setq sLst (reverse (vl-string->list path)) stage 0)
 (foreach item sLst
   (cond
     ((= stage 2) (setq folder (cons item folder)))
     ((and (= item 46) (= stage 0)) ;Last dot
      (setq ext (vl-list->string folder)
            folder nil
            stage 1
      )
     )
     ((and (or (= item 47) (= item 92)) ;Path delimeter / or \
           (< stage 2) ;Only last one
      )
      (setq name (vl-list->string folder)
            folder nil
            stage 2
      )
     )
     (t (setq folder (cons item folder)))
   )
 )
 (if (= name "") (setq name nil))
 (setq folder (vl-list->string folder))
 (list folder name ext)
)

Try it with these:

 

  • (splitpath "c:\\testpath/subfolder\\file.name.ext")
  • (splitpath "c:\\testpath/sub.folder\\")
  • (splitpath "c:\\testpath/sub.folder\\filename")

Link to comment
Share on other sites

what about this
Again, that assumes the path you're trying to extract from is in the same folder as the drawing. It's a similar problem as per the DWGNAME variable.
Link to comment
Share on other sites

Just as another problem, filenames (and even folder names) may have more than just one dot. They may also not have any extension at all

 

Irneb,

 

The standard functions (as I listed previously) should deal with these cases correctly - do they not on your system?

Link to comment
Share on other sites

Your function sparked an interest Irneb, perhaps another way to write it would be:

 

(defun LM:fnsplitl ( fn / sub )

 (defun _sub ( s l / p )
   (if (and l (setq p (vl-string-position (car l) s nil t)))
     (cons (substr s 1 p) (_sub (substr s (+ 2 p)) (cdr l)))
     (list s)
   )
 )

 (_sub (vl-string-translate "/" "\\" fn) '(92 46))
)

 

Or an iterative version:

 

(defun LM:fnsplitl_iter ( fn )
 (
   (lambda ( f p )
     (mapcar
       (function
         (lambda ( d )
           (if (setq p (vl-string-position d (setq f (substr f (+ 2 p))) nil t))
             (substr f 1 p)
             f
           )
         )
       )
       '(92 46 46)
     )
   )
   (vl-string-translate "/" "\\" fn) -1
 )
)

Link to comment
Share on other sites

yeah i know.... I should have stayed in my room :(

 

Bummer, i should restrain myself from giving answers and stick with just asking questions. :oops:

No, you learn much quicker when you try to do something. The "nice" thing about yours is you're trying to make it as simple and efficient as possible. Unfortunately it doesn't work for all scenarios.

 

Irneb,

 

The standard functions (as I listed previously) should deal with these cases correctly - do they not on your system?

I know, just for those who don't want the vla stuff, but still want it to work on all possibilities. :wink:

Edit: my code also uses the vl stuff, but that can be changed ...

 

Or an iterative version:

...

I'd advise an iterative version over recursion in nearly all cases. While recursion could make for short-n-sweet coding, it's not the most efficient if not done exactly correct.

 

See this post: http://devlicio.us/blogs/christopher_bennage/archive/2010/09/14/what-is-functional-programming-part-3-recursion.aspx

 

Note the discussion about Tail Call optimization. If your function doesn't do this the Lisp interpreter's going to make huge amounts of CPU calls and RAM addressing just to step through the calls to the same function. And I'm not sure if AutoLisp optimizes these calls as more modern lisp compilers / interpreters do.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...