Steven P Posted March 22, 2022 Posted March 22, 2022 Good morning, Just a very quick and easy one this morning, and I am being lazy perhaps (a quick internet search didn't give me an answer though). I have text copied to the clipboard from for example a PDF, I paste this into drawing using a LISP (to set the formatting, text sizes, and so on that ctr+V won't do), I am struggling this morning to do a string search on this text to see if it has a new line character in it or not, tried \\n and \\P but nothing worked yet.... Pretty sure I have missed something simple and you will be saying "it is this, how can you forget that" - but what did I miss? This is what I am trying: (setq newtext (vlax-invoke (vlax-get (vlax-get (vlax-create-object "htmlfile") 'ParentWindow) 'ClipBoardData) 'getData "TEXT" ) ) ;;String Search... not working (princ (vl-string-search newtext "\\n") ) ;;result is 'nil' whatever text (princ (vl-string-search newtext "\\p") ) ;;result is 'nil' whatever text ;;Eventually I want to change this next part to "Click insertion point or choose text style" with the LISP using tha above to suggest ;;the best option (initget "M D") (setq MorDor (getkword "\nMtext or Dtext (M/D): ")) ;;Do some stuff to set up font styles, text heights, layers, colours etc. ;;Make the text using the above. Thanks Quote
Tharwat Posted March 22, 2022 Posted March 22, 2022 The search pattern \\p must be in capital letter. 1 Quote
Steven P Posted March 22, 2022 Author Posted March 22, 2022 4 hours ago, Tharwat said: The search pattern \\p must be in capital letter. Thanks - that didn't work for me this afternoon, no idea why, but will figure it out this evening - thought it was something dead simple I had missed like upper / lower case Quote
Tharwat Posted March 22, 2022 Posted March 22, 2022 I don't think that you can search a string in the clipboard so after pasting the value into a text object then you can implement your procedures / tricks on it. 1 Quote
exceed Posted March 23, 2022 Posted March 23, 2022 (edited) select all copy and paste to notepad. if that text file has enough form you want. because sometimes the text copied from the pdf, is not divided into correct columns, and order is mixed so direct copy from pdf is need to be careful i think. how about to use \\r this is part of my clipboard to text object lisp I found that the new line in the clipboard (by html method) is \r, not \n or \p. (setq str (_GETCLIPBOARDTEXT)) (setq clipboardlist (LM:str->lst (vl-princ-to-string (LM:unformat str nil)) "\r ")) Edited March 23, 2022 by exceed Quote
BIGAL Posted March 23, 2022 Posted March 23, 2022 (edited) I knew I had seen something this by PBE here at cadtutor 2014, copy paste code to command line you may be surprised what you get. (setq txtstring (vlax-invoke (vlax-get (vlax-get (setq 2ClipB (vlax-create-object "htmlfile")) 'ParentWindow ) 'ClipBoardData ) 'GetData "Text" ) ) The problem is the clip data may not be text. line 1 line 2 line 3 Returns ("line 1\r\nline2\r\nline 3") Just a side note if you debug a text file you will find in hex ODOA on end of line this is carriage return & line feed which looks like it matches \r\n Edited March 23, 2022 by BIGAL 4 Quote
exceed Posted March 23, 2022 Posted March 23, 2022 (edited) 39 minutes ago, BIGAL said: line 1 line 2 line 3 Returns ("line 1\r\nline2\r\nline 3") ; GetClipText by Patrick_35 ( http://www.theswamp.org/index.php?topic=21764.msg263108#msg263108 ) ; only minor changes have been made so that it can be run as a command. (defun c:clipboardtxt ( / txtstring ) (setq txtstring (vlax-invoke (vlax-get (vlax-get (vlax-create-object "htmlfile") 'ParentWindow) 'ClipBoardData) 'GetData "Text")) (print txtstring) (princ) ) when I was wrote that code, I continued to (princ) and thought about what this blank space was. Today I finally understand why lisp has (print) thanks to you. Edited March 23, 2022 by exceed Quote
BIGAL Posted March 23, 2022 Posted March 23, 2022 Add credit to PBE for the clipboard code I just did. Quote
exceed Posted March 23, 2022 Posted March 23, 2022 (edited) I merged PBE's code with my old code. it was created by modifying existing text, but it shouldn't be difficult to create a new text. maybe ; CBPASTE - 2022.03.23 exceed ; this lisp is using the code from this link. GetClipText by Patrick_35 ( http://www.theswamp.org/index.php?topic=21764.msg263108#msg263108 ) ; Only minor modifications have been made so that it can be run as a command. ; command list ; cbread - view clipboard texts in command line ; cbpaste - paste clipboard texts to text object (vl-load-com) (defun c:cbread ( / txtstring ) (setq txtstring (vlax-invoke (vlax-get (vlax-get (vlax-create-object "htmlfile") 'ParentWindow) 'ClipBoardData) 'GetData "Text")) (print txtstring) (princ) ) (defun c:cbpaste ( / *error* txtstring txtedit1 rowcount rowlast scstack index selectedrow selectedrowlist srllen subindex selectedcell sclist ss1stacklist ss1count ss2 ss2count ss2index ss2y ss2list ss2stacklist ss2ent ss2x ss2index2 ss1textfromstacklist ss2obj ss1notusedlist ss1notusedstacklist ss1notusedlength ss1notusedindex ss1notusedtextstr ss1notusedtext ss1notusedtextstrlen ) (setvar 'cmdecho 0) (LM:startundo (LM:acdoc)) ;error control (defun *error* ( msg ) (setvar 'cmdecho 1) (LM:endundo (LM:acdoc)) (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")) (princ (strcat "\n Error: " msg)) ) (princ) ) (setq txtstring (vlax-invoke (vlax-get (vlax-get (vlax-create-object "htmlfile") 'ParentWindow) 'ClipBoardData) 'GetData "Text")) ;(princ "\n original clipboard text - \n") ;(print txtstring) (setq txtedit1 (LM:str->lst txtstring "\r\n")) ;(princ "\n line break text - \n") ;(print txtedit1) (setq rowcount (length txtedit1)) (setq rowlast (last txtedit1)) (if (= rowlast "") (setq rowcount (- rowcount 1)) (setq rowcount rowcount) ) (setq scstack '()) (setq index 0) (repeat rowcount (setq selectedrow (nth index txtedit1)) ;(princ "\n selectedrow - ") ;(print selectedrow) (setq selectedrowlist (LM:str->lst selectedrow "\t")) ;(princ "/ selectedrowlist - ") ;(print selectedrowlist) (setq srllen (length selectedrowlist)) ;(princ "/ srllen - ") ;(princ srllen) (setq subindex 0) (repeat srllen (setq selectedcell (nth subindex selectedrowlist)) (setq sclist '()) (setq sclist (list index selectedcell subindex)) (setq scstack (cons sclist scstack)) (setq subindex (+ subindex 1)) );end of repeat (setq index (+ index 1)) ) ;(princ "\n scstack - ") ;(princ scstack) (setq ss1stacklist (mysort scstack)) ;(princ "\n sorted scstack - ") ;(princ scstack) (setq ss1count (length ss1stacklist)) (princ "\n Select the object texts to be pasted \n") ;select object texts (setq ss2 (ssget '((0 . "*TEXT"))) ) (setq ss2count (sslength ss2)) (setq ss2index 0) (setq ss2y 0) (setq ss2list nil) (setq ss2stacklist nil) ;get list of object texts ( y-coordinate index ) (repeat ss2count (setq ss2ent (entget (ssname ss2 ss2index))) (setq ss2y (atoi (rtos (* (nth 2 (assoc 10 ss2ent)) -1) 2 2))) ; * -1 for reverse y coordinates (for sorting) (setq ss2x (atoi (rtos (nth 1 (assoc 10 ss2ent)) 2 2)) ) (setq ss2list (list ss2y ss2index ss2x)) (setq ss2stacklist (cons ss2list ss2stacklist)) (setq ss2index (+ ss2index 1)) ) ;(princ "\n objectlist = ") ;(princ ss2stacklist) (setq ss2stacklist (mysort ss2stacklist)) ;(princ "\n sorted objectlist = ") ;(princ ss2stacklist) ;if object list has more member than original list, add "___" at the end of original list, ;to avoid errors, this part should precede the put-text loop. (if (> ss2count ss1count) (progn (repeat (- ss2count ss1count) (setq ss1stacklist (append ss1stacklist (list (list 0 "___" 0)) )) ) ) ) ;put the value (setq ss2index2 0) (setq ss1textfromstacklist nil) (repeat ss2count (setq ss1textfromstacklist (LM:UnFormat (cadr (nth ss2index2 ss1stacklist)) nil) ) ;to Paste (if (= ss1textfromstacklist "") (setq ss1textfromstacklist "___")) (setq ss2obj (vlax-ename->vla-object (ssname ss2 (cadr (nth ss2index2 ss2stacklist)) ))) (vla-put-textstring ss2obj ss1textfromstacklist) (setq ss2index2 (+ ss2index2 1)) );end repeat ;make not used list (if original members more than object members) (setq ss1notusedlist nil) (setq ss1notusedstacklist nil) (if (< ss2count ss1count) (progn (repeat (- ss1count ss2count) (setq ss1notusedlist (nth ss2index2 ss1stacklist)) (setq ss1notusedstacklist (cons ss1notusedlist ss1notusedstacklist)) (setq ss2index2 (+ ss2index2 1)) ) ) ) ;sort not used list (setq ss1notusedstacklist (vl-sort ss1notusedstacklist (function (lambda (x1 x2)(< (car x1) (car x2))) ) ) ) ;make string for not used list (setq ss1notusedlength (length ss1notusedstacklist)) (setq ss1notusedindex 0) (setq ss1notusedtextstr "\n Not used original texts = ") (repeat ss1notusedlength (setq ss1notusedtext (LM:UnFormat (vl-princ-to-string (cadr (nth ss1notusedindex ss1notusedstacklist))) nil)) (setq ss1notusedtextstr (strcat ss1notusedtextstr ss1notusedtext ", " )) (setq ss1notusedindex (+ ss1notusedindex 1)) ) ;delete ", " end of str (setq ss1notusedtextstrlen (strlen ss1notusedtextstr)) (setq ss1notusedtextstr (substr ss1notusedtextstr 1 (- ss1notusedtextstrlen 2))) ;result message (princ (strcat "\n Original Texts : " (vl-princ-to-string ss1count) " ea / Object Texts : " (vl-princ-to-string ss2count) " ea \n")) (cond ((> ss1count ss2count) (princ (strcat "\n Copying the contents of " (vl-princ-to-string ss2count) " texts is Complete. / " (vl-princ-to-string (- ss1count ss2count)) " ea original texts are not used." ss1notusedtextstr ))) ((< ss1count ss2count) (princ (strcat "\n Copying the contents of " (vl-princ-to-string ss1count) " texts is Complete. / " (vl-princ-to-string (- ss2count ss1count)) " ea object texts are left. not enough original texts. they are replaced by ___"))) ((= ss1count ss2count) (princ (strcat "\n Copying the contents of " (vl-princ-to-string ss2count) " texts is Complete. / The number of object and original is the same."))) ) (setvar 'cmdecho 1) (LM:endundo (LM:acdoc)) (princ) ) (defun mysort ( l ) (vl-sort l '(lambda ( a b ) (if (eq (car a) (car b)) (< (caddr a) (caddr b)) (< (car a) (car b)) ;(< (vl-prin1-to-string (car a)) (vl-prin1-to-string (car b))) ) ) ) ) ;; String to List - Lee Mac ;; Separates a string using a given delimiter ;; str - [str] String to process ;; del - [str] Delimiter by which to separate the string ;; Returns: [lst] List of strings (defun LM:str->lst ( str del / pos ) (if (setq pos (vl-string-search del str)) (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del)) (list str) ) ) ;;-------------------=={ UnFormat String }==------------------;; ;; ;; ;; Returns a string with all MText formatting codes removed. ;; ;;------------------------------------------------------------;; ;; Author: Lee Mac, Copyright ⓒ 2011 - www.lee-mac.com ;; ;;------------------------------------------------------------;; ;; Arguments: ;; ;; str - String to Process ;; ;; mtx - MText Flag (T if string is for use in MText) ;; ;;------------------------------------------------------------;; ;; Returns: String with formatting codes removed ;; ;;------------------------------------------------------------;; (defun LM:UnFormat ( str mtx / _replace rx ) (defun _replace ( new old str ) (vlax-put-property rx 'pattern old) (vlax-invoke rx 'replace str new) ) (if (setq rx (vlax-get-or-create-object "VBScript.RegExp")) (progn (setq str (vl-catch-all-apply (function (lambda ( ) (vlax-put-property rx 'global actrue) (vlax-put-property rx 'multiline actrue) (vlax-put-property rx 'ignorecase acfalse) (foreach pair '( ("\032" . "\\\\\\\\") (" " . "\\\\P|\\n|\\t") ("$1" . "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]") ("$1$2/$3" . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);") ("$1$2" . "\\\\(\\\\S)|[\\\\](})|}") ("$1" . "[\\\\]({)|{") ) (setq str (_replace (car pair) (cdr pair) str)) ) (if mtx (_replace "\\\\" "\032" (_replace "\\$1$2$3" "(\\\\[ACcFfHLlOoPpQSTW])|({)|(})" str)) (_replace "\\" "\032" str) ) ) ) ) ) (vlax-release-object rx) (if (null (vl-catch-all-error-p str)) str ) ) ) ) ;; Active Document - Lee Mac ;; Returns the VLA Active Document Object (defun LM:acdoc nil (eval (list 'defun 'LM:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object)))) (LM:acdoc) ) ;; Start Undo - Lee Mac ;; Opens an Undo Group. (defun LM:startundo ( doc ) (LM:endundo doc) (vla-startundomark doc) ) ;; End Undo - Lee Mac ;; Closes an Undo Group. (defun LM:endundo ( doc ) (while (= 8 (logand 8 (getvar 'undoctl))) (vla-endundomark doc) ) ) (princ "\n CBPASTE - loading complete") CBPASTE - copy from 1 column texts in PDF - case 1 : original texts quantity = object texts quantity - case 2 : original texts quantity < object texts quantity, the remaining object texts in cad are changed to "___". - case 3 : original texts quantity > object texts quantity, prints the contents of the remaining original text to the command prompt. CBPASTE - copy from excel - similar to the case of pdf. The only difference is that empty cells are replaced with "___". This is because when I change the value of text to "" in cad the text disappears. Edited March 23, 2022 by exceed 1 Quote
Steven P Posted March 23, 2022 Author Posted March 23, 2022 8 hours ago, exceed said: select all copy and paste to notepad. if that text file has enough form you want. This is what started me off on this one, trying to avoid the copy and then paste to notepad step and make it all a little quicker. I'll look at your code today - workload permitting - thanks Quote
Steven P Posted March 23, 2022 Author Posted March 23, 2022 I think I got what I wanted working now, I added in an 'if' and vl-string-search pretty much copied from Lee Macs LM:Str-Lst with a slight change and it all worked. I think also using \r\n helped but not sure why. Used all of your help above in parts, thanks. Anyway below just for completion this is my basic clipboard to text LISP with my question answered, Command txtcbnew will ask the user for an insertion point then paste a new text there, muiltiline or dtext according to the clipboard. (defun c:txtcbnew ( / MorDor newtext font textheight InsertPoint pos) (setq font (getvar "textstyle")) (setq textheight (getvar 'TEXTSIZE)) (setq newtext (vlax-invoke (vlax-get (vlax-get (vlax-create-object "htmlfile") 'ParentWindow) 'ClipBoardData) 'getData "TEXT" ) ) (if (setq pos (vl-string-search "\r\n" newtext)) (setq MorDor "M") (setq MorDor "D") ) ;; (initget "M D") ;; (setq MorDor (getkword "\nM or D Text (M/D): ")) (setq InsertPoint (getpoint "insertion Point")) (createtext newtext InsertPoint font textheight MorDor) ;;lisp to make text (princ) ) (defun createtext ( MyText TextPoint font textheight MorD / ) (if (= MorD "D") (progn (entmake (list '(0 . "TEXT") '(100 . "AcDbEntity") '(8 . "0") '(100 . "AcDbText") (cons 10 TextPoint) (cons 40 textheight) (cons 1 MyText) '(50 . 0.0) '(41 . 1.0) '(51 . 0.0) (cons 7 font) '(71 . 0) '(72 . 0) '(11 0.0 0.0 0.0) '(210 0.0 0.0 1.0) '(100 . "AcDbText") '(73 . 0) ));end list, entmake ) ;end progn (progn ;;(defun createmtext (MyText TextPoint font textheight / ) (entmake (list (cons 0 "MTEXT") (cons 100 "AcDbEntity") (cons 100 "AcDbMText") (cons 10 TextPoint) (cons 40 textheight) (cons 1 MyText) ));end list, entmake );end progn );end if ) 1 Quote
exceed Posted March 23, 2022 Posted March 23, 2022 (edited) i'm glad to you success as like BIGAL said, ₩r₩n = enter key like typing machine move cursor(carriage) return to leftside of line = ₩r scroll paper to make new line (line feed) = ₩n os paste that automatically when i copy multiline text to clipboard, every enter so when run my c:cbread, that will show copied text with ₩r₩n in autocad mtext also apply ₩r₩n as enter we do that simply ₩n without ₩r so, your original code cannot find ₩₩n ₩₩r. because double ₩₩ is no there. not like dcl. i think Edited March 23, 2022 by exceed 1 Quote
Steven P Posted March 23, 2022 Author Posted March 23, 2022 Thanks Exceed, interesting to know and it is one of those things that we love to get frustrated about. I might borrow your cbread by the way to use as standard with all my clipboard text functions Quote
Recommended Posts
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.