Here's one of my working tools.
(vl-load-com)
(defun c:MoveFromLine ( / ss pl i en ed et pc pt pp an fn tmp)
(or *mtl-ds*
(setq *mtl-ds* 0.))
(if (and (setq ss (ssget '((0 . "LINE,LWPOLYLINE,ARC,CIRCLE,RAY,*TEXT,INSERT"))))
(progn
(while (not (progn
(initget "Copy")
(setq tmp (getdist (strcat "\nDistance from line [Copy] <" (rtos *mtl-ds* 2 2) ">: ")))
(cond ((not tmp))
((= tmp "Copy")
(setq fn entmake)
nil)
((setq *mtl-ds* tmp))))))
*mtl-ds*)
(or (and (setq pl (acet-ss-ssget-filter ss '((0 . "LINE,LWPOLYLINE,ARC,CIRCLE,RAY"))))
(setq pl (ssname pl 0)))
(and (setq pl (car (entsel "\nSelect a poline: ")))
(or (wcmatch (cdr (assoc 0 (entget pl))) "LINE,LWPOLYLINE,ARC,CIRCLE,RAY")
(prompt "\nError: Wrong selection. Must be LINE,LWPOLYLINE,ARC,CIRCLE or RAY"))))
(setq ss (acet-ss-ssget-filter ss '((0 . "*TEXT,INSERT"))))
)
(repeat (setq i (sslength ss))
(if (setq en (ssname ss (setq i (1- i)))
ed (entget en)
et (cdr (assoc 0 ed))
pc (if (and (= "TEXT" et)
(/= 0 (cdr (assoc 72 ed)) (cdr (assoc 73 ed))))
11
10)
pt (cdr (assoc pc ed))
pp (vlax-curve-getClosestPointTo pl pt)
an (angle '(0 0 0) (vlax-curve-getFirstDeriv pl (vlax-curve-getParamAtPoint pl pp))))
((cond (fn) (entmod))
(append ed
(list (cons pc (polar pp (+ an (/ pi 2)) *mtl-ds*))
(cons 50 (setq an (if (= et "MTEXT")
(- an (angle '(0 0 0) (getvar 'UCSXDIR)))
an)
an (if (< an 0)
(+ an (* 2 pi))
an)
an (if (and (<= (if (= et "MTEXT")
an
(angle (trans '(0 0 0) 0 1) (trans (polar '(0 0 0) an 1) 0 1))) ; readable text mtext ucs
(* 1.5 pi))
(> (if (= et "MTEXT")
an
(angle (trans '(0 0 0) 0 1) (trans (polar '(0 0 0) an 1) 0 1)))
(* 0.5 pi)))
(+ an pi)
an)))))))))
(princ)
)