home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / p / p024 / 5.img / R11SUPP.EXE / PTEXT.LSP < prev    next >
Encoding:
Text File  |  1991-02-04  |  62.9 KB  |  1,868 lines

  1. ;;;   PText.lsp  
  2. ;;;   Copyright (C) 1990 by Autodesk, Inc.  
  3. ;;;    
  4. ;;;   Permission to use, copy, modify, and distribute this software and its
  5. ;;;   documentation for any purpose and without fee is hereby granted.  
  6. ;;;
  7. ;;;   THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 
  8. ;;;   ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF 
  9. ;;;   MERCHANTABILITY ARE HEREBY DISCLAIMED.
  10. ;;;   
  11. ;;;   by Jan S. Yoder  
  12. ;;;   with thanks to Kieran McKeogh for suggesting how to handle control  
  13. ;;;   characters.  
  14. ;;;   15 February 1990  
  15. ;;;
  16. ;;;   Version 1.11
  17. ;;;     29 January 1991 -- JSY  : More minor bug fixes.
  18. ;;;     11 January 1991 -- JSY  : Numerous minor bug fixes.
  19. ;;;     
  20. ;;;----------------------------------------------------------------------------  ;;;   
  21. ;;; DESCRIPTION
  22. ;;;   PTEXT -- Paragraph text processor.
  23. ;;;   
  24. ;;;   Text can be entered directly on the AutoCAD text screen, in one of four
  25. ;;;   modes; Left justified, Center or Right justified, or Fit between two 
  26. ;;;   line endpoints.  Word wrapping will occur based on some rudimentary 
  27. ;;;   assumptions which are necessary until and if a function can be provided
  28. ;;;   for determining the actual size of a text item at any given font and
  29. ;;;   number and size of characters.
  30. ;;;   
  31. ;;;   The actual number of characters of "slack", the number of allowable extra
  32. ;;;   characters beyond the predetermined maximum, can be set by the user.
  33. ;;;   
  34. ;;;   This processor works by reading keyboard input via (grread) and based
  35. ;;;   on this input, causing the current text entity to be regenerated.  This
  36. ;;;   routine can probably be made to operate unacceptably slowly by doing 
  37. ;;;   one or more of the following:
  38. ;;;   
  39. ;;;     Operating the routine in multiple viewports where the text entities'
  40. ;;;     layer is ON in all of them.
  41. ;;;     
  42. ;;;     Working on fairly long text strings;  say, greater than 30 characters.
  43. ;;;     
  44. ;;;     Operating on a slow processor.
  45. ;;;   
  46. ;;;   The best method is to work on a layer which is exclusively visible in
  47. ;;;   the current viewport, and on fairly short strings.
  48. ;;;
  49. ;;;   The options are:
  50. ;;;   
  51. ;;;    Command: ptext  
  52. ;;;    Center/Edit/Fit/Load-file/Right/Slack/<Start point>:   
  53. ;;;         
  54. ;;;  Left, Center, right, and Fit justified text entry types are supported   
  55. ;;;  for text entry.  The editing portion of this routine should work on  
  56. ;;;  all of the Release 11 justification options.  This has not been tested!  
  57. ;;;      
  58. ;;;  The following control characters allow a "cursor" composed of a set of  
  59. ;;;  underline control codes to move around within a set of text entities.  
  60. ;;;    
  61. ;;;       ^A -- Append a space after the current cursor position and  
  62. ;;;             move the cursor to that position.  
  63. ;;;       ^B -- Go to the beginning of the line.  
  64. ;;;       ^D -- Move the cursor down a line; maintains the current letter   
  65. ;;;             position.  This position may appear to be different due to  
  66. ;;;             character kerning within a font.  
  67. ;;;       ^E -- Go to the end of the current line.  
  68. ;;;       ^H -- Backspace key.  
  69. ;;;       ^I -- Toggle insert/overwrite mode.  
  70. ;;;       ^L -- Move the cursor to the left  -- non-destructive cursor.  
  71. ;;;   RETURN -- Return; move any characters to the right of the cursor  
  72. ;;;             down to the next line and push the remaining lines down  
  73. ;;;             one "interline spacing" amount.  
  74. ;;;       ^N -- Go to the end of the last text entity in the list.  
  75. ;;;       ^R -- Move the cursor to the right -- non-destructive cursor.  
  76. ;;;       ^T -- Go to the start of the first text entity in the list.  
  77. ;;;       ^U -- Move the cursor up a line; maintains the current letter   
  78. ;;;             position.  This position may appear to be different due to  
  79. ;;;             character kerning within a font.  
  80. ;;;       ^Z -- Exit text entry.  
  81. ;;;       -  -- Hyphen character.  
  82. ;;;          -- The delete key deletes the current character, and if there is  
  83. ;;;             no character and the cursor is at the end of a line and there  
  84. ;;;             are more lines, then the next line is pulled up onto the   
  85. ;;;             current line and any remaining lines are moved up one   
  86. ;;;             "interline spacing" amount.  
  87. ;;;     
  88. ;;;   ^U and ^X are interchanged between DOS and UNIX machines due to low  
  89. ;;;   level character swapping by the operating system, so either of these  
  90. ;;;   combinations will cause the cursor to move up a line on either   
  91. ;;;   machine type.  
  92. ;;;   
  93. ;;;   Local variables representing key code values for translation   
  94. ;;;   to other keyboard codes, if necessary, are listed at the top   
  95. ;;;   of the (ptext) defun.  
  96. ;;;  
  97. ;;;----------------------------------------------------------------------------  
  98.   
  99.   
  100. (defun ptext (/ pt_ver pt_err        pt_oe  pt_oce pt_sty pt_twf   
  101.                 char   insert grp_72 pt_spt pt_rpt str          
  102.                 line_l pt_cl  pt_str cont   sset   j      TX:LST ent          
  103.                 pt_ils cont1  ans    temp   sl     pt_rsp pt_msp pt_tsp   
  104.                 return OK2BRK max_j  diff   nchars dir    dstrct pt_obm  
  105.                 pt_te EDIT_T  pnding pt_dth  
  106.                 P_SLCK P_BEGL P_HLPD P_HLPU P_DWNL P_ENDL P_BACK   
  107.                 P_ISRT P_JUST P_LEFT P_RTRN P_ENDT P_RGHT P_BEGT   
  108.                 P_UPLD P_UPLU P_QUIT P_SPCE P_HYPH P_DDEL P_UDEL  
  109.              )  
  110.   
  111.   (setq pt_ver "1.11")                ; Reset this local if you make a change.  
  112.   
  113.   ;;  
  114.   ;; Internal error handler defined locally  
  115.   ;;  
  116.   
  117.   (defun pt_err (s)                   ; If an error (such as CTRL-C) occurs  
  118.                                       ; while this command is active...  
  119.     (if (/= s "Function cancelled")  
  120.       (if (= s "quit / exit abort")  
  121.         (princ)  
  122.         (princ (strcat "\nError: " s))  
  123.       )  
  124.     )  
  125.     (if (null pt_GEX)
  126.       (progn
  127.         (entdel (cdr(assoc -1 pt_te))) ; Delete the test text entity.
  128.         (entmod (subst (cons 1 str) (assoc 1 ent) ent))
  129.       )
  130.     )
  131.     (command "undo" "end")  
  132.     (if ll_oe                         ; If an old error routine exists  
  133.       (setq *error* pt_oe)            ; then, reset it   
  134.     )  
  135.     (setvar "blipmode" pt_obm)        ; Restore blipmode  
  136.     (setvar "cmdecho" pt_oce)         ; Reset command echoing on error  
  137.     (princ)  
  138.   )  
  139.     
  140.   (if *error*                         ; Set our new error handler  
  141.     (setq pt_oe *error* *error* pt_err)   
  142.     (setq *error* pt_err)   
  143.   )  
  144.   (setq pt_oce (getvar "cmdecho"))    ; Save current state of command echoing  
  145.   (setq pt_obm (getvar "blipmode"))   ; Save current state of blipmode  
  146.   (setvar "cmdecho" 0)                ; Turn off command echoing  
  147.   (setvar "blipmode" 0)               ; Turn off blipmode  
  148.   (command "undo" "group")  
  149.   
  150.   (if (null pt_GEX)  
  151.     (progn
  152.       (cond
  153.         ((or (= (substr (getvar "PLATFORM") 1 4) "OS/2")   
  154.              (= (substr (getvar "PLATFORM") 1 3) "DOS"))   
  155.           (if (not (setq temp (findfile "ptext.exe")))
  156.             (setq temp (findfile "./ads/ptext.exe"))
  157.           ) 
  158.         )
  159.         ((= (substr (getvar "PLATFORM") 1 7) "386 DOS")   
  160.           (if (not (setq temp (findfile "ptext.exp")))
  161.             (setq temp (findfile "./ads/ptext.exp"))
  162.           ) 
  163.         )
  164.         (T
  165.           (if (not (setq temp (findfile "ptext")))
  166.             (setq temp (findfile "./ads/ptext"))
  167.           ) 
  168.         )
  169.       )  
  170.       (if temp
  171.         (if (null (xload temp))  
  172.           (progn  
  173.             (princ "\nCouldn't load the Ptext executable. ")  
  174.             (if (and pt_sup pt_uls get_ch pt_gll pt_cll pt_psl
  175.                      is_num pt_csl pt_gpl pt_gpr pt_sjk pt_mc
  176.                      pt_bul pt_sil pt_ael pt_ail pt_ats pt_pnl
  177.                      pt_pl pt_gmp pt_waw pt_pww pt_pee pt_mne
  178.                      pt_fww pt_dal dr_txt round)
  179.               
  180.               (princ (strcat "\nRunning the AutoLisp version "  
  181.                 "for demonstration purposes only. "))  
  182.               (progn  
  183.                 (princ "\nThis version of Ptext.lsp requires it. ")  
  184.                 (exit)  
  185.               )
  186.             )
  187.           )
  188.           (princ "\n\n\nRunning the ADS version of PTEXT. ") 
  189.         )  
  190.         (if (and pt_sup pt_uls get_ch pt_gll pt_cll pt_psl
  191.                  is_num pt_csl pt_gpl pt_gpr pt_sjk pt_mc
  192.                  pt_bul pt_sil pt_ael pt_ail pt_ats pt_pnl
  193.                  pt_pl pt_gmp pt_waw pt_pww pt_pee pt_mne
  194.                  pt_fww pt_dal dr_txt round)
  195.                     
  196.           (progn  
  197.             (princ "\nCouldn't find the Ptext executable. ")  
  198.             (princ (strcat "\nRunning the AutoLisp version "  
  199.               "for demonstration purposes only. "))  
  200.           )
  201.           (progn  
  202.             (princ "\nCouldn't find the Ptext executable. ")  
  203.             (princ "\nThis version of Ptext.lsp requires it. ")  
  204.             (exit) 
  205.           )
  206.         )  
  207.       ) 
  208.     )
  209.     (princ "\n\n\nRunning the ADS version of PTEXT. ") 
  210.   )  
  211.   ;; These are the machine codes for the various cursor motion controls
  212.   ;; for both UNIX and DOS which are reported by calls to (ads_grread).  
  213.   ;; 
  214.   ;; Note that UNIX machines can redefine the low level codes and the 
  215.   ;; actions of the keys marked "DELETE" and the backspace key, as well
  216.   ;; others.  They may not operate as documented.  Check the codes returned
  217.   ;; by (grread) "key press" against the table below to determine which
  218.   ;; codes to change for your system.
  219.   ;; 
  220.   ;; They may need translation for other country keyboard codes.
  221.   ;;
  222.   ;; The codes listed here are used only if the PTEXT executable is not
  223.   ;; in use.  Change the source code for the executable if you wish to
  224.   ;; change the response of any of the keys and recompile it as described
  225.   ;; in the ADS User Guide.
  226.   
  227.   (if (null pt_GEX)  
  228.     (setq P_APPN   1                  ; ^A Append a space at current pt_rsp.  
  229.           P_BEGL   2                  ; ^B Beginning of line.  
  230.           P_DWNL   4                  ; ^D Down a line.  
  231.           P_ENDL   5                  ; ^E End of line.  
  232.           P_BACK   8                  ; ^H Backspace.  
  233.           P_ISRT   9                  ; ^I Toggle insert/overwrite mode.  
  234.           P_LEFT  12                  ; ^L Left  -- non-destructive cursor.  
  235.           P_RTRN  13                  ;    Return.  
  236.           P_ENDT  14                  ; ^N End of text.  
  237.           P_RGHT  18                  ; ^R Right -- non-destructive cursor.  
  238.           P_BEGT  20                  ; ^T Beginning of text.  
  239.           P_UPLD  21                  ; ^U Up a line (DOS).  
  240.           P_UPLU  24                  ; ^X Up a line (UNIX).  
  241.           P_QUIT  26                  ; ^Z Exit text entry.  
  242.           P_SPCE  32                  ;    Spacebar.  
  243.           P_HYPH  45                  ; -  Hyphen character.  
  244.           P_UDEL 127                  ;    Delete character (UNIX).  
  245.           P_DDEL 211                  ;    Delete character (DOS).  
  246.           P_HLPD 222                  ;^F1 Help screen on DOS  
  247.           P_HLPU  31                  ;^?  Help screen on UNIX  
  248.     )  
  249.   )         
  250.   (setq pt_sty (tblsearch "style" (getvar "textstyle"))  
  251.         pt_dth (cdr(assoc 40 pt_sty))  
  252.         pt_twf (cdr(assoc 41 pt_sty))  
  253.         pt_toa (cdr(assoc 50 pt_sty)) 
  254.         pt_stn (cdr(assoc  2 pt_sty)) 
  255.         P_SLCK 0                      ; No slack characters  
  256.         char   P_SPCE                 ; "space" character  
  257.         insert T                      ; Start in insert mode.  
  258.   )  
  259.   
  260.   ;; Make a frozen layer for determining the length of a text string.  
  261.   (if (null (setq temp (tblsearch "layer" "frozen_text")))  
  262.     (command "layer" "new" "frozen_text" "freeze" "frozen_text" "")  
  263.     (if (= (logand (cdr(assoc 70 temp)) 1) 0)  
  264.       (command "layer" "freeze" "frozen_text" "")  
  265.       (princ)  
  266.     )  
  267.   )  
  268.   (if (= (getvar "handles") 0)        ; Handles are off  
  269.     (progn  
  270.       (initget "Yes No")  
  271.       (if (= (getkword "\nTurn On handles?  <Y>: ") "No")  
  272.         (progn  
  273.           (princ   
  274.             "\nHandles must be turned ON for this routine to continue. ")  
  275.           (exit)  
  276.         )  
  277.         (command "handles" "ON")  
  278.       )  
  279.     )  
  280.   )  
  281.   (if (null pt_GEX)  
  282.     (progn  
  283.       ;; Create a dummy text entity on this layer.  
  284.       (command "text" "r" "0,0" "" "" "Ptext")  
  285.       (setq pt_te (entget(entlast))  
  286.             pt_te (subst (cons 8 "frozen_text") (assoc 8 pt_te) pt_te)  
  287.       )  
  288.       (entmod pt_te)  
  289.     )  
  290.   )  
  291.   
  292.   (princ (strcat "\nThe Paragraph Text Editor, Version "  
  293.                  pt_ver
  294.                  ", (c) 1990 by Autodesk, Inc. "))  
  295.   (pt_opt)                            ; Get options from user  
  296.   (if (null EDIT_T)  
  297.     (progn  
  298.       (pt_sth)                        ; Set text height.  
  299.       (if (/= grp_72 5)  
  300.         (pt_sra)                      ; Set rotation angle.  
  301.         (setq pt_ra (angle pt_spt pt_rpt))  
  302.       )  
  303.       (setq pt_ils (pt_sis))          ; Set the spacing between lines.  
  304.       (if (/= grp_72 5)  
  305.         (pt_sml)                      ; Set the length of the lines.  
  306.         (setq pt_mll (distance pt_spt pt_rpt))  
  307.       )  
  308.     )  
  309.   )  
  310.   (if (null str)  
  311.     (setq str T)  
  312.   )        
  313.   (grtext -2 "Ptext: Insert mode")  
  314.   (if (null pt_GEX)  
  315.     (progn  
  316.       (setq line_l 0    
  317.             pt_cl  0   
  318.             pt_str ""  
  319.       )  
  320.       (while (/= str "")  
  321.         (pt_sup)                      ; Set up  
  322.         (while (get_ch)               ; Get characters  
  323.   
  324.           ;; Maximum line length plus "slack" amount not yet reached...  
  325.           
  326.           (if (< line_l pt_mll)  
  327.             (pt_pl)                   ; Process the line  
  328.             (progn  
  329.               (setq temp (pt_waw))    ; Set up to wrap at word  
  330.               (pt_pww temp)           ; Wrap at word  
  331.             )  
  332.           )  
  333.           (setq char nil)  
  334.         )  
  335.       )  
  336.     )  
  337.     (progn  
  338.       (setq EDIT_T (if (null EDIT_T) 0 1))  
  339.       (if (null pt_rpt) (setq pt_rpt (list 0.0 0.0 0.0)))
  340.       (setq pt_sty (cdr(assoc 2 pt_sty)))
  341.       (setq err  
  342.         (pt_GEX pt_spt pt_rpt grp_72 pt_th  pt_ra   
  343.                 pt_mll pt_ils (atof pt_ver) pt_sty EDIT_T)   
  344.       )  
  345.     )  
  346.   )  
  347.   (if (null pt_GEX)  
  348.     (entdel (cdr(assoc -1 pt_te)))    ; Delete the test text entity.  
  349.   )  
  350.   (command "undo" "end")  
  351.   (setvar "blipmode" pt_obm)          ; Restore blipmode  
  352.   (setvar "cmdecho" pt_oce)           ; Restore command echoing  
  353.   (princ)  
  354. )  
  355. ;;;  
  356. ;;; Get options  
  357. ;;;  
  358. ;;; pt_opt == PText_OPTions  
  359. ;;;  
  360. (defun pt_opt (/ cont)  
  361.   (setvar "cmdecho" 0)  
  362.   (while (null cont)  
  363.       
  364.     (setq cont T)   
  365.   
  366.     (initget "Center Edit Fit Load-file Right Slack ?")  
  367.     (setq pt_spt (getpoint   
  368.       "\nCenter/Edit/Fit/Right/Slack/?/<Start point>: "))  
  369.     
  370.     (cond   
  371.       ((= pt_spt "Center")  
  372.         (setq grp_72 1)  
  373.         (initget 1)  
  374.         (setq pt_spt (getpoint "\nCenter baseline point: "))  
  375.         (setq pt_spt (trans pt_spt 1 0))  
  376.     
  377.       )  
  378.       ((= pt_spt "Edit")  
  379.         (princ (strcat   
  380.           "\nSelect the text for editing.  Start with the first line"  
  381.           "\nof the paragraph, and select the lines in order... "))  
  382.         (setq sset (ssget))  
  383.         (if sset  
  384.           (progn  
  385.             (setq j 0)  
  386.             (setq temp   (entget (ssname sset j))  
  387.                   ename1 (cdr(assoc -1 temp))  
  388.                   k      (cdr(assoc 210 temp))  
  389.                   fd     (open "ptext.hdl" "w")  
  390.             )  
  391.             (if (null fd)
  392.               (progn
  393.                 (princ 
  394.                   "\nCouldn't open handle file \"ptext.hdl\" for writing. ")
  395.                 (exit)
  396.               )
  397.             )
  398.             (if (> (sslength sset) 1)  
  399.               (setq temp   (entget (ssname sset (1+ j)))  
  400.                     ename2 (cdr(assoc -1 temp))  
  401.               )  
  402.             )  
  403.               
  404.             (repeat (sslength sset)  
  405.               (if (null pt_GEX)  
  406.                 (progn  
  407.                   (if (= (cdr(assoc 0 (entget (ssname sset j)))) "TEXT")  
  408.                     (setq TX:LST (if TX:LST   
  409.                                    (append TX:LST (list (ssname sset j)))  
  410.                                    (list (ssname sset j))  
  411.                                  )  
  412.                           j      (1+ j)  
  413.                           gottxt T
  414.                     )  
  415.                   )  
  416.                 )  
  417.                 (progn  
  418.                   (if (and  
  419.                         (= (cdr(assoc 0 (entget (ssname sset j)))) "TEXT")  
  420.                         (equal (cdr(assoc 210 (entget (ssname sset j)))) k)  
  421.                       )  
  422.                     (progn  
  423.                       (if (> j 0) (princ "\n" fd))  
  424.                       (princ (cdr(assoc 5 (entget (ssname sset j)))) fd)
  425.                       (setq gottxt T)
  426.                     )  
  427.                   )  
  428.                   (setq j      (1+ j))  
  429.                 )  
  430.               )  
  431.             )  
  432.             (if gottxt
  433.               (progn
  434.                 (if (null pt_GEX)  
  435.                   (setq ent    (entget(nth 0 TX:LST)))  
  436.                   (progn  
  437.                     (close fd)  
  438.                     (setq ent    (entget(ssname sset 0)))  
  439.                   )  
  440.                 )  
  441.                 (setq pt_spt (cdr(assoc 10 ent))  
  442.                       str    (cdr(assoc 1  ent))  
  443.                       pt_th  (cdr(assoc 40 ent))  
  444.                       pt_ra  (cdr(assoc 50 ent))  
  445.                       grp_72 (cdr(assoc 72 ent))  
  446.                 )  
  447.                 (if (= grp_72 5)          ; Fit text  
  448.                   (setq pt_rpt (cdr(assoc 11 ent))  
  449.                         pt_mll (distance pt_spt pt_rpt)  
  450.                   )  
  451.                   (setq pt_mll (pt_sml))  ; Set maximum line length  
  452.                 )  
  453.                 (setq pt_ils (pt_gis)     ; Get interline spacing.  
  454.                       EDIT_T T            ; Set a flag that we are editing.  
  455.                 )  
  456.               )
  457.               (progn
  458.                 (setq cont nil)
  459.                 (princ "\nNo text entities selected. ")
  460.               )
  461.             )
  462.           )  
  463.           (progn  
  464.             (setq cont nil)           ; Repeat the first prompt.  
  465.             (princ "\nNo text entities selected. ")  
  466.           )  
  467.         )  
  468.       )  
  469.       ((= pt_spt "Fit")  
  470.         (setq grp_72 5)  
  471.         (initget 1)  
  472.         (setq pt_spt (getpoint "\nLeft baseline point: "))  
  473.         (initget 1)  
  474.         (setq pt_rpt (getpoint pt_spt "\nRight baseline point: "))  
  475.         (setq char nil)  
  476.         (setq pt_spt (trans pt_spt 1 0))  
  477.         (setq pt_rpt (trans pt_rpt 1 0))  
  478.       )  
  479.       ((= pt_spt "Right")  
  480.         (setq grp_72 2)  
  481.         (initget 1)  
  482.         (setq pt_spt (getpoint "\nRight baseline point: "))  
  483.         (setq pt_spt (trans pt_spt 1 0))  
  484.     
  485.       )  
  486.       ((= pt_spt "Slack")  
  487.         (setq cont nil)  
  488.         (if (null P_SLCK) (setq P_SLCK 1))  
  489.         (initget 4)  
  490.         (setq pt_spt (getint (strcat  
  491.           "\nNumber of characters of slack <" (itoa P_SLCK) ">: ")))  
  492.         (if pt_spt (setq P_SLCK pt_spt))  
  493.       )  
  494.       ((= (type pt_spt) 'LIST)        ; A point was entered  
  495.         (setq grp_72 0)  
  496.         (setq pt_spt (trans pt_spt 1 0))  
  497.     
  498.       )  
  499.       ((= pt_spt "?")  
  500.         (pt_phs T)  
  501.         (setq cont nil)  
  502.       )  
  503.       (T  
  504.         (command "undo" "end")  
  505.         (exit)                        ; Null entry -- get out.  
  506.     
  507.       )  
  508.     )  
  509.   )  
  510. )  
  511. ;;;  
  512. ;;; The help screen.  
  513. ;;;  
  514. ;;; pt_phs == PText_Print_Help_Screens  
  515. ;;;  
  516. (defun pt_phs (temp)  
  517.   (if textpage (textpage) (textscr))  
  518.   (if temp  
  519.     (progn  
  520.       (princ 
  521.         "\nText may be entered in one of four modes; Left, Center, Right,")  
  522.       (princ "\nor Fit justified.  You may move the cursor to any position")  
  523.       (princ "\nwithin the text you are entering at any time while entering")  
  524.       (princ 
  525.         "\ntext, or you may edit existing lines of text by selecting the")  
  526.       (princ "\nEdit option, and picking the lines of text you wish to edit.")  
  527.       (princ "\n")  
  528.       (princ 
  529.         "\nYou must pick the text entities in the correct order that you ")  
  530.       (princ "\nwant them to be edited, as entering additional text on one")  
  531.       (princ 
  532.         "\nline may cause the line to be \"wrapped\" onto the next line ")  
  533.       (princ "\nthat you selected.")  
  534.       (princ "\n  ")  
  535.       (princ 
  536.         "\nThe following control characters allow a \"cursor\" composed ")  
  537.       (princ "\nof a set of underline and/or overline control codes to move ")  
  538.       (princ "\naround within a set of text entities.")  
  539.       (princ "\n")  
  540.       (princ "\n<more>")  
  541.       (grread)  
  542.       (princ "\r        ")  
  543.     )  
  544.   )  
  545.   (if temp  
  546.     (progn  
  547.       (princ "\n     ^F1 (DOS) or ")  
  548.       (princ "\n     ^?  (UNIX) -- This help screen. ")  
  549.     )  
  550.   )  
  551.   (princ "\n")  
  552.   (princ "\n     ^A  -- (A)ppend a space after the current cursor position ")  
  553.   (princ "\n            and move the cursor to that position.")  
  554.   (princ "\n     ^B  -- Move the cursor to the (B)eginning of the line.")  
  555.   (princ 
  556.     "\n     ^D  -- Move the cursor (D)own a line; maintains the current ")  
  557.   (princ "\n            letter position.  This position may appear to be ")  
  558.   (princ "\n            different due to character kerning within a font.")  
  559.   (princ "\n     ^E  -- Go to the (E)nd of the current line.")  
  560.   (princ "\n     ^H  -- Backspace key.")  
  561.   (princ "\n     ^I  -- Toggle (I)nsert/overwrite mode.")  
  562.   (princ "\n     ^L  -- Move the cursor to the (L)eft.")  
  563.   (if temp  
  564.     (progn  
  565.       (princ "\n RETURN  -- Return; move any characters to the right of the ")  
  566.       (princ "\n            cursor down to the next line and push the ")  
  567.       (princ "\n            remaining lines down by the \"interline space\" ")  
  568.       (princ "\n            distance.")  
  569.     )  
  570.   )  
  571.   (princ "\n     ^N  -- Move the cursor to the e(N)d of ")  
  572.   (princ "\n            the last text entity in the list.")  
  573.   (princ "\n     ^R  -- Move the cursor to the (R)ight.")  
  574.   (princ "\n     ^T  -- Move the cursor to (T)op or the start of ")  
  575.   (princ "\n            the first text entity in the list.")  
  576.   (princ "\n     ^U  -- Move the cursor (U)p a line.")  
  577.   (princ "\n     ^Z  -- Exit text entry.")  
  578.   (princ "\n")  
  579.   (if (null temp)  
  580.     (progn  
  581.       (princ "\nPress any key to return to your drawing.")  
  582.       (grread)  
  583.       (princ "\r                                          ")  
  584.       (princ "\n")  
  585.       (princ "\n")  
  586.       (princ "\nText: ")  
  587.       (princ str)  
  588.     )  
  589.   )  
  590.   (if temp  
  591.     (progn  
  592.       (princ "\n<more>")  
  593.       (grread)  
  594.       (princ "\r        ")  
  595.       (princ 
  596.         "\n DELETE  -- The delete key deletes the current character.  If")  
  597.       (princ 
  598.         "\n            the cursor is at the end of a line and there are ")  
  599.       (princ "\n            more lines in the list, then the next line is ")  
  600.       (princ 
  601.         "\n            pulled up onto the current line and any remaining ")  
  602.       (princ "\n            lines are moved up by the \"interline space\" ")  
  603.       (princ "\n            distance.")  
  604.       (princ "\n ")  
  605.       (princ 
  606.         "\nInserting a hyphen character in a word allows that word to be")  
  607.       (princ "\n\"wrapped\" at the hyphen.")  
  608.       (princ "\n")  
  609.     )  
  610.   )  
  611.   (princ)  
  612. )  
  613. ;;;  
  614. ;;; Set the height of the text entities.  
  615. ;;; Defaults to "0.2" if not preset in the style symbol table.  
  616. ;;;  
  617. ;;; pt_sth == PText_Set_Text_Height  
  618. ;;;  
  619. (defun pt_sth ()  
  620.   (initget 6)  
  621.   (if (= pt_dth 0.0) (setq pt_dth 0.2))
  622.   (setq ans (getdist (trans pt_spt 0 1) (strcat "\nText height <"   
  623.                                     (if pt_th (rtos pt_th) (rtos pt_dth))   
  624.                                     ">: ")))  
  625.   (if ans  
  626.     (setq pt_th ans)  
  627.     (if (null pt_th)   
  628.       (setq pt_th 0.2)  
  629.     )  
  630.   )  
  631. )  
  632. ;;;  
  633. ;;; Set the rotation angle for the text.  
  634. ;;; Defaults to "0" if not preset in the style symbol table.  
  635. ;;;  
  636. ;;; pt_sra == PText_Set_Rotation_Angle  
  637. ;;;  
  638. (defun pt_sra ()  
  639.   (if (= (logand (cdr(assoc 70 pt_sty)) 4) 4)   
  640.     (setq temp 270)   
  641.     (setq temp 0)  
  642.   )  
  643.   (setq ans (getorient (trans pt_spt 0 1) (strcat   
  644.     "\nRotation angle <" (if pt_ra (angtos pt_ra) (itoa temp)) ">: ")))  
  645.   (if ans  
  646.     (setq pt_ra ans)                  ; in radians  
  647.     (setq pt_ra (/ temp (/ 180 pi)))  
  648.   )  
  649. )  
  650. ;;;  
  651. ;;; Get the spacing between the "baseline" of lines of text.  
  652. ;;; Defaults to 1.5 times the text height.  
  653. ;;; "Temp" is the group code to use.  
  654. ;;;  
  655. ;;; pt_gis == PText_Get_Interline_Spacing  
  656. ;;;  
  657. (defun pt_gis (/ temp)  
  658.   (if (> (sslength sset) 1)  
  659.     (progn  
  660.       (if (or (= grp_72 0) (= grp_72 5))  
  661.         (setq temp 10)  
  662.         (setq temp 11)  
  663.       )  
  664.       (distance (cdr(assoc temp (entget ename1)))  
  665.                 (cdr(assoc temp (entget ename2)))  
  666.       )  
  667.     )  
  668.     (progn  
  669.       (setq pt_ils (pt_sis))  
  670.     )  
  671.   )  
  672. )  
  673. ;;;  
  674. ;;; Set the spacing between the "baseline" of lines of text.  
  675. ;;; Defaults to 1.5 times the text height.  
  676. ;;;  
  677. ;;; pt_sis == PText_Set_Interline_Spacing  
  678. ;;;  
  679. (defun pt_sis ()  
  680.   (setq pt_ils (* pt_th 1.5))  
  681.   (initget 6)  
  682.   (setq ans (getdist (trans pt_spt 0 1) (strcat   
  683.     "\nInter-line spacing <" (if pt_ils (rtos pt_ils) "0.3") ">: ")))  
  684.   (if ans  
  685.     (if (= (logand (cdr(assoc 70 pt_sty)) 4) 4)   
  686.       (- ans)   
  687.       ans  
  688.     )  
  689.     (if (= (logand (cdr(assoc 70 pt_sty)) 4) 4)   
  690.       (- (* 1.5 (if pt_th pt_th 0.2)))  
  691.       (* 1.5 (if pt_th pt_th 0.2))  
  692.     )  
  693.   )  
  694. )  
  695. ;;;  
  696. ;;; Set the maximum line length.  
  697. ;;; Defaults to 2 units.  
  698. ;;; Sets the global pt_mll.  
  699. ;;;  
  700. ;;; pt_sml == PText_Set_Maximum_line_Length  
  701. ;;;  
  702. (defun pt_sml ()  
  703.   (if (null pt_mll)   
  704.     (setq pt_mll (* pt_th 10.0))  
  705.   )  
  706.   (initget 6)  
  707.   (setq ans (getdist (trans pt_spt 0 1) (strcat   
  708.     "\nMaximum line length" (if pt_mll   
  709.                               (strcat " <"  (rtos pt_mll) ">: ")  
  710.                               ": ")))  
  711.   )  
  712.   (if ans  
  713.     (setq pt_mll ans)  
  714.   )  
  715.   (+ pt_mll (* 0.9 P_SLCK pt_twf pt_th))  
  716. )  
  717. ;;;  
  718. ;;; All functions defined following this line up to the final c: function  
  719. ;;; definitions at the end of the file are duplicated in ptext.c and are  
  720. ;;; included here to allow you to execute the PTEXT command without using  
  721. ;;; an ADS routine.  You may want to try this to see the difference in speed  
  722. ;;; between the command running as a pure AutoLisp application versus one  
  723. ;;; that has been ported to ADS.  
  724. ;;;   
  725. ;;; In order to run the AutoLisp version, rename the PTEXT executable, and  
  726. ;;; then run PTEXT.  If this routine cannot find an executable with the   
  727. ;;; name of PTEXT (the extension varies), then it runs only the AutoLisp  
  728. ;;; version.  Otherwise, the ADS version is loaded and run.  
  729. ;;;   
  730. ;;; If you are never going to run the AutoLisp version, then the code   
  731. ;;; following this up to the final c: definitions may be deleted.  
  732. ;;;  
  733. ;;; ------------------ Cut here ----------------------------------  
  734.   
  735. ;;;  
  736. ;;; Set up before getting keyboard input.  
  737. ;;;   
  738. ;;; The counter "pt_cl" is the number of the current line   
  739. ;;; starting at "1".  It is always one ahead of the number  
  740. ;;; required by the lisp expression (nth <n> <list>) which  
  741. ;;; starts its numbering at "0".  This counter is used througout  
  742. ;;; for accessing text entities from the list TX:LST.  
  743. ;;;  
  744. ;;; pt_sup == PText_Set_UP  
  745. ;;;  
  746. (defun pt_sup ()  
  747.   (setq pt_rsp 1   
  748.         char   P_SPCE  
  749.         pt_cl  (1+ pt_cl)   
  750.         pt_vsp 1  
  751.   )  
  752.   (setq str    (if (= (type str) 'STR) str (chr char))  
  753.         strlst (pt_psl str)           ; Parse string to list   
  754.         pt_msp (pt_cll (length strlst) T) ; Check line length  
  755.         pt_rsp (pt_cll pt_vsp nil)    ; Get character position/size  
  756.         pt_str (pt_uls str pt_rsp)    ; Underline character 1  
  757.   )  
  758.   (if ent  
  759.     (progn  
  760.       (setq ent (subst (cons 1 pt_str) (assoc 1 ent) ent))  
  761.       (entmod ent)  
  762.     )  
  763.     (progn  
  764.       (dr_txt pt_str)                 ; Draw the text string - sets ent  
  765.       (setq TX:LST (if TX:LST  
  766.                      (pt_ael (cdr(assoc -1 ent)) pt_cl TX:LST)  
  767.                      (list (cdr(assoc -1 ent)))  
  768.                    )  
  769.       )  
  770.     )  
  771.   )  
  772.   (princ "\nText: ")  
  773.   (princ str)  
  774. )  
  775. ;;;  
  776. ;;; Turn on underlining for an apparent character location (j)  
  777. ;;; in a string (s).  Return the string with underlining.  
  778. ;;;  
  779. ;;; pt_uls == PText_UnderLine_String  
  780. ;;;    
  781. (defun pt_uls (s j / temp)  
  782.   (setq temp (strlen s))  
  783.   (if (> temp 0)  
  784.     (if (and (> j 0) (<= j temp))  
  785.       (strcat (substr s 1 (pt_csl 1 j))  
  786.               (strcat "%%u" (if insert "" "%%o")  
  787.                       (nth (1- j) strlst)   
  788.                       "%%u" (if insert "" "%%o")  
  789.               )   
  790.               (substr s (1+ (pt_csl 1 (1+ j))))  
  791.       )  
  792.       (strcat (substr s 1 (pt_csl 1 j)) "%%u %%u")  
  793.     )  
  794.     "%%u %%u"  
  795.   )  
  796. )  
  797. ;;;  
  798. ;;; Get a character from the keyboard  
  799. ;;;  
  800. ;;;  
  801. (defun get_ch (/ return)  
  802.   ;; Disallow all input except the keyboard.  
  803.   (while (/= (car (setq char (grread nil))) 2) (princ))  
  804.   (setq char (cadr char))  
  805.   (cond  
  806.     ((= char P_RTRN)  
  807.       (pt_pnl)                        ; Process newline  
  808.       (setq return nil)  
  809.     )  
  810.     ((= char P_ISRT)  
  811.       (if insert                      ; Toggle insert mode...  
  812.         (progn  
  813.           (setq insert nil)  
  814.           (grtext -2 "Ptext: Overwrite mode")  
  815.         )  
  816.         (progn  
  817.           (setq insert T)  
  818.           (grtext -2 "Ptext: Insert mode")  
  819.         )  
  820.       )   
  821.       (setq return T)  
  822.     )  
  823.     ;; Backspace key -- destructive cursor  
  824.     ((= char P_BACK)  
  825.       (pt_mc "LEFT" T)                ; Move cursor  
  826.       (setq return T)  
  827.     )  
  828.     ((or (= char P_DDEL)   
  829.          (= char P_UDEL))             ; Delete key  
  830.       (pt_mc "DEL" nil)  
  831.       (setq return T)  
  832.     )  
  833.     ;; ALT - A key  -- Append a space to the current cursor position.  
  834.     ((= char P_APPN)  
  835.       (setq char P_SPCE)  
  836.       (setq pt_rsp (pt_ats char T))   ; Add character to string  
  837.       (pt_mc "RIGHT" nil)             ; Move cursor  
  838.       (setq return T)  
  839.     )  
  840.     ((= char P_BEGL)                  ; ALT - B key : Beginning of line  
  841.       (pt_mc "HOME" nil)  
  842.       (setq return T)  
  843.     )  
  844.     ((= char P_DWNL)                  ; ALT - D key : Move down a line  
  845.       (pt_mc "DOWN" nil)  
  846.       (setq return T)  
  847.     )  
  848.     ((= char P_ENDL)                  ; ALT - E key : End of the line  
  849.       (pt_mc "END" nil)  
  850.       (setq return T)  
  851.     )  
  852.     ((= char P_LEFT)                  ; ALT - L key : Move left   
  853.       (pt_mc "LEFT" nil)  
  854.       (setq return T)  
  855.     )  
  856.     ((= char P_ENDT)                  ; ALT - N key : Move to bottom of text  
  857.       (pt_mc "BOTTOM" nil)  
  858.       (setq return T)  
  859.     )  
  860.     ((= char P_RGHT)                  ; ALT - R key : Move right  
  861.       (pt_mc "RIGHT" nil)  
  862.       (setq return T)  
  863.     )  
  864.     ((= char P_BEGT)                  ; ALT - T key : Move to top of text  
  865.       (pt_mc "TOP" nil)  
  866.       (setq return T)  
  867.     )  
  868.     ((or (= char P_UPLD)   
  869.          (= char P_UPLU))             ; ALT - U key (DOS or UNIX)  
  870.       (pt_mc "UP" nil)  
  871.       (setq return T)  
  872.     )  
  873.     ((= char P_QUIT)                  ; ALT - Z key -- exit.  
  874.       (initget "Yes No")  
  875.       (if (= (getkword "\nExit from text entry? <Y>: ") "No")  
  876.         (progn  
  877.           (setq return T)  
  878.           (princ "\nText: ")  
  879.           (princ str)  
  880.         )  
  881.         (progn  
  882.           (entmod (subst (cons 1 str) (assoc 1 ent) ent))  
  883.           (setq str    ""  
  884.                 return nil  
  885.           )  
  886.         )  
  887.       )  
  888.     )  
  889.     ((= char P_DEL)                   ; Delete -- delete character at cursor  
  890.       (pt_mc "DEL" nil)  
  891.       (setq return T)  
  892.     )  
  893.     ((or (= char P_HLPD) (= char P_HLPU)) ; ^F1 or ^? -- Help screen.  
  894.       (pt_phs nil)  
  895.       (setq return T)  
  896.     )  
  897.     ((= (chr char) "%")  
  898.       (cond   
  899.         ((= pnding nil) (setq pnding 1))  
  900.         ((= pnding 1)   (setq pnding 2))  
  901.         ((= pnding 2)   (setq pnding nil))  
  902.         (T  
  903.           (exit)  
  904.         )  
  905.       )  
  906.       (setq pt_rsp (pt_ats char nil)  
  907.             pt_vsp (pt_cll pt_rsp T)  
  908.       )  
  909.       (setq return T)  
  910.     )  
  911.     ; Else return T  
  912.     (T  
  913.       (if (= char P_HYPH)   
  914.         (setq OK2BRK T)  
  915.         (setq OK2BRK nil)  
  916.       )  
  917.       (if (> pnding 1)  
  918.         (cond  
  919.           ((or (= (chr char) "o")     ; overline  
  920.               (= (chr char) "u")      ; underline  
  921.               (= (chr char) "d")      ; degrees  
  922.               (= (chr char) "p")      ; plus/minus  
  923.               (= (chr char) " ")      ; space  
  924.            )  
  925.             (setq pt_rsp (- (pt_ats char nil) 2)  
  926.                   strlst (pt_psl str) ; Parse string to list   
  927.                   pt_vsp (pt_cll pt_rsp T)  
  928.                   pnding nil  
  929.             )  
  930.           )  
  931.           ((is_num (chr char))  
  932.             (terpri)  
  933.             (if (< pnding 4)  
  934.               (setq pt_rsp (pt_ats char nil)  
  935.                     pnding (1+ pnding)  
  936.                     pt_vsp (pt_cll pt_rsp T)  
  937.               )  
  938.               (setq pt_rsp (- (pt_ats char nil) (- pnding 2))  
  939.                     strlst (pt_psl str) ; Parse string to list   
  940.                     pnding nil  
  941.                     pt_vsp (pt_cll pt_rsp T)  
  942.               )  
  943.             )  
  944.           )  
  945.           (T   
  946.             (setq pt_rsp (pt_ats char nil)  
  947.                   pt_vsp (pt_cll pt_rsp T)  
  948.                   pnding nil  
  949.             )  
  950.           )  
  951.         )  
  952.         (setq pt_rsp (pt_ats char nil)  
  953.               pt_vsp (pt_cll pt_rsp T)  
  954.         )  
  955.       )  
  956.       (setq return T) ; Return value  
  957.     )  
  958.   )  
  959.   (if (/= char P_RTRN)  
  960.     (progn  
  961.       ;; set the current string postion (pt_vsp) after allowing for   
  962.       ;; various control character codes such as %%d or %%p.  
  963.       (setq pt_rsp (pt_cll pt_vsp nil)  
  964.             ;; set the string that gets printed on-screen via (entmod).  
  965.             pt_str (pt_uls str pt_rsp)  
  966.             ;; set the maximum string postion (pt_msp) after allowing for   
  967.             ;; various control character codes such as %%d or %%p.  
  968.             pt_msp (pt_cll (length strlst) T)  
  969.             ;; set the line length up to the current adjusted string position.  
  970.             line_l (pt_gll (pt_csl 1 pt_rsp))  
  971.       )  
  972.     )  
  973.   )  
  974.   return  
  975. )  
  976. ;;;  
  977. ;;; Get the length of a text line by making a dummy text entity  
  978. ;;; on the frozen text layer.  This entity will contain the current  
  979. ;;; text string without the underline/overline cursor characters  
  980. ;;; up to the current cursor position.  
  981. ;;;  
  982. ;;; Return the distance between the right and left points of the   
  983. ;;; right justified text string.  
  984. ;;;  
  985. ;;; pt_gll == PText_Get_Line_Length  
  986. ;;;  
  987. (defun pt_gll (pt_rsp)  
  988.   (setq pt_te (subst (cons 1 (pt_sjk 1 pt_rsp)) (assoc 1 pt_te) pt_te))  
  989.   (setq pt_te (subst (cons 40 pt_th) (assoc 40 pt_te) pt_te))  
  990.   (setq pt_te (subst (cons 41 pt_twf) (assoc 41 pt_te) pt_te))  
  991.   (setq pt_te (subst (cons 51 pt_toa) (assoc 51 pt_te) pt_te))  
  992.   (setq pt_te (subst (cons 7  pt_stn) (assoc  7 pt_te) pt_te))  
  993.   (entmod pt_te)  
  994.   (setq pt_te (entget(cdr(assoc -1 pt_te))))  
  995.   (distance (cdr(assoc 10 pt_te)) (cdr(assoc 11 pt_te)))  
  996. )  
  997. ;;;  
  998. ;;; Check the string list "strlst" for control characters.  If "diff" is T,  
  999. ;;; then return the number of visible characters, else return the number of   
  1000. ;;; the item in the list which matches the current visual string position.  
  1001. ;;; N_chars is global to this routine, and specifies how many characters  
  1002. ;;; to delete if deleting a special symbol.  
  1003. ;;;  
  1004. ;;; pt_cll == PText_Check_Line_Length  
  1005. ;;;  
  1006. (defun pt_cll (max diff / temp j)  
  1007.   (setq temp   0  
  1008.         j      0  
  1009.         k      0  
  1010.         nchars 0  ; global, local to (ptext).  
  1011.   )  
  1012.   (while (and (< k max) (< j (length strlst)))  
  1013.     (cond   
  1014.       ((or (= (nth j strlst) "%%o")   ; overline  
  1015.            (= (nth j strlst) "%%u"))  ; underline  
  1016.         (if diff   
  1017.           (setq k (1+ k))  
  1018.         )  
  1019.         (setq j (1+ j))  
  1020.       )  
  1021.       (T  
  1022.         (setq temp   (1+ temp)        ; diff count  
  1023.               nchars (strlen (nth j strlst))  
  1024.               j      (1+ j)  
  1025.               k      (1+ k)  
  1026.         )  
  1027.       )  
  1028.     )  
  1029.   )  
  1030.   (if diff (if (> temp 0) temp 1) j)  
  1031. )  
  1032. ;;;  
  1033. ;;; Parse the string "str" into a list of strings, one string for each  
  1034. ;;; visual character or control character set.    
  1035. ;;; N_chars is global to this routine, and specifies how many characters  
  1036. ;;; to delete if deleting a special symbol.  
  1037. ;;;  
  1038. ;;; pt_psl == PText_Parse_String_to_List  
  1039. ;;;  
  1040. (defun pt_psl (str / max temp j k tmplst)  
  1041.   (setq max  (strlen str)  
  1042.         j    1  
  1043.         k    0  
  1044.         x    1  
  1045.         nchars 0  ; global, local to (ptext).  
  1046.   )  
  1047.   (while (<= j  (strlen str))  
  1048.     (if (= (setq temp (substr str j 1)) "%")  
  1049.       (progn  
  1050.         (if (= (substr str (setq j (1+ j)) 1) "%")  
  1051.           (progn  
  1052.             (setq j (1+ j))  
  1053.             (cond   
  1054.               ((= (substr str j 1) " ") ; space  
  1055.                 (setq tmplst (if tmplst   
  1056.                                (append tmplst (list "%" "%" " "))  
  1057.                                (list "%" "%" " ")  
  1058.                              )  
  1059.                 )  
  1060.               )  
  1061.               ((or (= (substr str j 1) "%")  ; percent  
  1062.                    (= (substr str j 1) "d")  ; degrees  
  1063.                    (= (substr str j 1) "p")  ; plus/minus  
  1064.                    (= (substr str j 1) "o")  ; overline  
  1065.                    (= (substr str j 1) "u")) ; underline  
  1066.                 (setq temp   (substr str (- j 2) 3)  
  1067.                       j      (1+ j)  
  1068.                 )  
  1069.               )  
  1070.               ((is_num (substr str j 1))  
  1071.                 (while (and (< k 3) (is_num (substr str (+ j k) 1)))  
  1072.                   (setq k      (1+ k))  
  1073.                 )  
  1074.                 (setq temp (substr str (- j 2) (+ 2 k))  
  1075.                       j    (+ j k)  
  1076.                 )  
  1077.               )  
  1078.               (T  
  1079.                 (setq j (1+ j))  
  1080.               )  
  1081.             )  
  1082.             (setq tmplst (if tmplst   
  1083.                            (append tmplst (list temp))  
  1084.                            (list temp)  
  1085.                          )  
  1086.             )  
  1087.           )  
  1088.           (progn  
  1089.             (setq tmplst (if tmplst   
  1090.                            (append tmplst (list temp))  
  1091.                            (list temp)  
  1092.                          )  
  1093.                   tmplst (append tmplst (list (substr str j 1)))  
  1094.                   j      (1+ j)  
  1095.             )  
  1096.           )  
  1097.         )  
  1098.       )  
  1099.       (progn  
  1100.         (setq tmplst (if tmplst   
  1101.                        (append tmplst (list temp))  
  1102.                        (list temp)  
  1103.                      )  
  1104.               j      (1+ j)  
  1105.         )  
  1106.       )  
  1107.     )  
  1108.   )  
  1109.   tmplst  
  1110. )  
  1111. ;;;  
  1112. ;;; Is the character (string) a number...  
  1113. ;;;  
  1114. ;;;  
  1115. (defun is_num (char)  
  1116.   (if   
  1117.     (or   
  1118.       (= char "0") (= char "1") (= char "2") (= char "3") (= char "4")  
  1119.       (= char "5") (= char "6") (= char "7") (= char "8") (= char "9")  
  1120.     )  
  1121.     T  
  1122.     nil  
  1123.   )  
  1124. )  
  1125. ;;;  
  1126. ;;; Count the number of characters in the list of strings up to the   
  1127. ;;; current string position from the starting point.  
  1128. ;;;  
  1129. ;;; pt_csl == PText_Count_String_Length  
  1130. ;;;  
  1131. (defun pt_csl (j k / temp)  
  1132.   (setq temp 0)  
  1133.   (while (and (> j 0) (< j k) (<= j (length strlst)))  
  1134.     (setq temp (+ temp (strlen (nth (1- j) strlst)))  
  1135.           j    (1+ j)  
  1136.     )  
  1137.   )  
  1138.   temp  
  1139. )  
  1140. ;;;  
  1141. ;;; Get the real string position of the next visual character to the   
  1142. ;;; left of the current cursor posistion.  
  1143. ;;;  
  1144. ;;; pt_gpl == PText_Get_next_start_Position_Left  
  1145. ;;;  
  1146. (defun pt_gpl (temp)  
  1147.   (setq j (pt_cll temp T))  
  1148.   (while (and (> temp 0) (= j (setq k (pt_cll temp T))))  
  1149.     (setq temp (1- temp))  
  1150.   )  
  1151.   k  
  1152. )  
  1153. ;;;  
  1154. ;;; Get the real string position of the next visual character to the   
  1155. ;;; right of the current cursor posistion.  
  1156. ;;;  
  1157. ;;; pt_gpr == PText_Get_next_start_Position_Right  
  1158. ;;;  
  1159. (defun pt_gpr (temp)  
  1160.   (pt_cll temp nil)  
  1161. )  
  1162. ;;;  
  1163. ;;; Strcat from the list "strlst" from "j" position to "k" position.  
  1164. ;;; Return the string or "".  
  1165. ;;;  
  1166. ;;; pt_sjk == PText_Strcat_from_J_to_K  
  1167. ;;;  
  1168. (defun pt_sjk (j k / temp)  
  1169.   (setq temp 0  
  1170.         l    0  
  1171.   )  
  1172.   (if (and (<= j (length strlst)) (<= j k))  
  1173.     (progn  
  1174.       (while (< temp (+ j l))  
  1175.         (if (or (= (nth temp strlst) "%%o")  ; overline  
  1176.                 (= (nth temp strlst) "%%u")) ; underline  
  1177.             (setq l (1+ l))  
  1178.         )  
  1179.         (setq temp (1+ temp))  
  1180.       )        
  1181.       (setq temp "")  
  1182.       (while (and (<= (+ j l) (length strlst)) (<= j k))  
  1183.         (setq temp (strcat temp (nth (1- (+ j l)) strlst)))  
  1184.         (if (or (= (nth (1- (+ j l)) strlst) "%%o")  ; overline  
  1185.                 (= (nth (1- (+ j l)) strlst) "%%u")) ; underline  
  1186.             (setq k (1+ k))  
  1187.         )  
  1188.         (setq j (1+ j))        
  1189.       )  
  1190.     )  
  1191.     (setq temp "")  
  1192.   )  
  1193.   temp  
  1194. )  
  1195.       
  1196. ;;;  
  1197. ;;; Move the cursor the direction "dir" and if the second argument is T,  
  1198. ;;; then erase the character under the new cursor location.  
  1199. ;;;  
  1200. ;;; pt_mc == PText_Move_Cursor  
  1201. ;;;  
  1202. (defun pt_mc (dir dstrct)  
  1203.   (cond  
  1204.     ((= dir "LEFT")  
  1205.       (if dstrct                      ; deleting text  
  1206.         (if (> pt_vsp 1)              ; if not at the beginning of a line  
  1207.           ;; subtract one visual character from the current position.  
  1208.           (progn  
  1209.             (setq pt_vsp (1- pt_vsp)  
  1210.                   pt_rsp (pt_cll pt_vsp nil)  
  1211.                   str    (strcat  
  1212.                            (pt_sjk 1 (- pt_vsp 1))  
  1213.                            (pt_sjk (1+ pt_vsp) pt_msp)  
  1214.                          )  
  1215.                   strlst (pt_psl str) ; Parse string to list   
  1216.             )  
  1217.             (repeat 5   
  1218.               (princ (chr P_BACK))  
  1219.               (princ (chr P_SPCE))  
  1220.               (princ (chr P_BACK))  
  1221.             )  
  1222.           )  
  1223.           (progn                      ; AT the beginning of the text line...  
  1224.             (if (> pt_cl 1)           ; if not at the first line...  
  1225.               (pt_dal T)              ; back up a line, destructive  
  1226.             )  
  1227.           )    
  1228.         )  
  1229.         (if (> pt_vsp 1)              ; NOT deleting text...  
  1230.           (setq pt_vsp (1- pt_vsp)  
  1231.                 pt_rsp (pt_gpl pt_vsp)  
  1232.           )  
  1233.           (if (> pt_cl 1)             ; if not at the first line...  
  1234.             (pt_dal nil)              ; back up a line, non-destructive  
  1235.           )  
  1236.         )  
  1237.       )  
  1238.     )  
  1239.     ((= dir "RIGHT")  
  1240.       (if dstrct                      ; overwriting text  
  1241.         (if (< pt_vsp pt_msp)         ; if not at the end of a line  
  1242.           (setq pt_vsp (1+ pt_vsp)  
  1243.                 pt_rsp (pt_gpr pt_vsp)  
  1244.                 str    (strcat  
  1245.                          (pt_sjk 1 (- pt_rsp 2))  
  1246.                          " "  
  1247.                          (pt_sjk pt_rsp pt_msp)  
  1248.                        )  
  1249.                 strlst (pt_psl str)   ; Parse string to list   
  1250.           )  
  1251.         )  
  1252.       )  
  1253.       (if (< pt_vsp pt_msp)           ; NOT deleting text and ...  
  1254.                                       ; NOT at the end of a line...  
  1255.         (setq pt_vsp (1+ pt_vsp)  
  1256.               pt_rsp (pt_gpr pt_vsp)  
  1257.         )  
  1258.         ;; else  
  1259.         (if (< pt_cl (length TX:LST)) ; AT the end of a line...  
  1260.           ;; If not at the last line in the edit list...  
  1261.           (progn  
  1262.             ;; Modify the current entity to remove the cursor.  
  1263.             (entmod (subst (cons 1 str) (assoc 1 ent) ent))  
  1264.             (setq pt_cl  (1+ pt_cl)   ; add one to current line counter  
  1265.                   ;; get the ename from TX:LST for the new current line.  
  1266.                   ent    (entget(nth (1- pt_cl) TX:LST))  
  1267.                   ;; get the string in ent  
  1268.                   str    (cdr(assoc 1 ent))
  1269.                   strlst (pt_psl str) ; Parse string to list   
  1270.                   ;; Actual under-line postion checked in (get_ch)  
  1271.                   pt_vsp 1    
  1272.             )  
  1273.           )  
  1274.           ;; Else do nothing.  
  1275.         )  
  1276.       )  
  1277.     )  
  1278.     ((= dir "HOME")  
  1279.       ;; Actual under-line postion checked in (get_ch)  
  1280.       (setq pt_vsp 1)         
  1281.     )  
  1282.     ((= dir "END")  
  1283.       ;; Actual under-line postion checked in (get_ch)  
  1284.       (setq pt_vsp pt_msp)    
  1285.     )  
  1286.     ((= dir "TOP")  
  1287.       (entmod (subst (cons 1 str) (assoc 1 ent) ent))  
  1288.       (setq pt_cl  1  
  1289.             ent    (entget(nth 0 TX:LST))  
  1290.             str    (cdr(assoc 1 ent))  
  1291.             strlst (pt_psl str)       ; Parse string to list   
  1292.             ;; Actual under-line postion checked in (get_ch)  
  1293.             pt_vsp 1          
  1294.       )  
  1295.     )  
  1296.     ((= dir "BOTTOM")  
  1297.       (entmod (subst (cons 1 str) (assoc 1 ent) ent))  
  1298.       (setq pt_cl  (length TX:LST)  
  1299.             ent    (entget(last TX:LST))  
  1300.             str    (cdr(assoc 1 ent))  
  1301.             strlst (pt_psl str)       ; Parse string to list   
  1302.             ;; Actual under-line postion checked in (get_ch)  
  1303.             pt_vsp pt_msp     
  1304.       )  
  1305.       (terpri)
  1306.     )  
  1307.     ((= dir "DEL")  
  1308.       (if (< pt_vsp pt_msp)           ; if not at the end of the line...  
  1309.         (progn  
  1310.           (setq temp (strlen str)  
  1311.                 str    (strcat  
  1312.                          (pt_sjk 1 (1- pt_rsp))  
  1313.                          (pt_sjk (1+ pt_rsp) pt_msp)  
  1314.                        )  
  1315.                 strlst (pt_psl str)                ; Parse string to list   
  1316.           )  
  1317.           (repeat (1+ (- temp (strlen str)))   
  1318.             (princ (chr P_BACK))  
  1319.             (princ (chr P_SPCE))  
  1320.             (princ (chr P_BACK))  
  1321.           )  
  1322.         )  
  1323.         ;; else, at the last character in the line...  
  1324.         (if (= (substr str pt_rsp 1) " ") ; if it is a blank...  
  1325.           (pt_bul (1+ pt_cl))         ; Bring up lines following this line.  
  1326.           ;; else, replace the current character with a space.  
  1327.           (setq str    (strcat (pt_sjk 1 (1- pt_rsp)) " ")  
  1328.                 strlst (pt_psl str)   ; Parse string to list   
  1329.                 pt_spt (polar pt_spt (+ pt_ra (/ pi 2)) pt_ils)  
  1330.           )  
  1331.         )  
  1332.       )  
  1333.     )  
  1334.     ((= dir "UP")  
  1335.       (if (and TX:LST (> pt_cl 1))    ; Never let pt_cl below 1.  
  1336.         (progn  
  1337.           (entmod (subst (cons 1 str) (assoc 1 ent) ent))  
  1338.           (setq pt_cl  (1- pt_cl)  
  1339.                 ent    (entget(nth (1- pt_cl) TX:LST))  
  1340.                 str    (cdr(assoc 1 ent))  
  1341.                 strlst (pt_psl str)   ; Parse string to list   
  1342.                 tvsp   (length strlst)
  1343.           )  
  1344.           (if (< tvsp pt_vsp) (setq pt_vsp tvsp))
  1345.           (terpri)  
  1346.         )  
  1347.       )  
  1348.     )  
  1349.     ((= dir "DOWN")  
  1350.       (if (and TX:LST (< pt_cl (length TX:LST)))  
  1351.         (progn  
  1352.           (entmod (subst (cons 1 str) (assoc 1 ent) ent))  
  1353.           (setq pt_cl  (1+ pt_cl)  
  1354.                 ent    (entget(nth (1- pt_cl) TX:LST))  
  1355.                 str    (cdr(assoc 1 ent))  
  1356.                 strlst (pt_psl str)   ; Parse string to list   
  1357.                 tvsp   (length strlst)
  1358.           )  
  1359.           (if (< tvsp pt_vsp) (setq pt_vsp tvsp))
  1360.           (terpri)  
  1361.         )  
  1362.       )  
  1363.     )  
  1364.   )  
  1365.   (princ "\rText: ")  
  1366.   (princ str)  
  1367.   pt_rsp  
  1368. )  
  1369. ;;;  
  1370. ;;; Bring up lines of text when deleting at the end of a line of text.  
  1371. ;;;  
  1372. ;;; pt_bul == PText_Bring_Up_Lines  
  1373. ;;;  
  1374. (defun pt_bul (line)  
  1375.   (if (< pt_cl (length TX:LST))  
  1376.     (progn  
  1377.       (setq str  (strcat  
  1378.                    (substr str 1 (- pt_rsp 1))  
  1379.                    (cdr(assoc 1 (entget (nth pt_cl TX:LST))))  
  1380.                  )  
  1381.             strlst (pt_psl str)       ; Parse string to list   
  1382.             sset (ssadd)  
  1383.             j    pt_cl  
  1384.       )  
  1385.       (entdel (nth pt_cl TX:LST))  
  1386.       (setq TX:LST (pt_sil line TX:LST))  
  1387.       (while (< j (length TX:LST))  
  1388.         (ssadd (nth j TX:LST) sset)  
  1389.         (setq j (1+ j))  
  1390.       )  
  1391.       (if (> (sslength sset) 0)  
  1392.         (command "move"   
  1393.                  sset   
  1394.                  ""   
  1395.                  pt_spt   
  1396.                  (polar pt_spt (+ pt_ra (/ pi 2)) pt_ils)
  1397.         )  
  1398.       )  
  1399.     )  
  1400.   )  
  1401.   ;; Else, do nothing.  
  1402. )  
  1403. ;;;  
  1404. ;;; Strip the item from the list of enames in TX:LST.  
  1405. ;;;  
  1406. ;;; pt_sil == PText_Strip_Item_from_List  
  1407. ;;;  
  1408. (defun pt_sil (temp lst / j k tmplst)  
  1409.   (setq j   0  
  1410.         k   (length lst)  
  1411.   )  
  1412.   (while (< j k)  
  1413.     (if (= j (1- temp))  
  1414.       (setq j (1+ j))                 ; Skip the entry...  
  1415.       ;; else  
  1416.       (setq tmplst (if tmplst  
  1417.                      (append tmplst (list (nth j lst)))  
  1418.                      (list (nth j lst))  
  1419.                    )  
  1420.             j      (1+ j)  
  1421.       )  
  1422.     )  
  1423.   )  
  1424.   tmplst  
  1425. )  
  1426. ;;;  
  1427. ;;; Add the entity name to the list of enames in TX:LST.  
  1428. ;;; TX:LST must have at least one member.  
  1429. ;;;  
  1430. ;;; pt_ael == PText_Add_Ename_to_List  
  1431. ;;;  
  1432. (defun pt_ael (ename temp lst / j k tmplst)  
  1433.   (setq j   0  
  1434.         k   (length lst)  
  1435.   )  
  1436.   (while (< j k)  
  1437.     (setq tmplst (if tmplst  
  1438.                    (append tmplst (list (nth j lst)))  
  1439.                    (list (nth j lst))  
  1440.                  )  
  1441.           j      (1+ j)  
  1442.     )  
  1443.     (if (= j (1- temp))  
  1444.       (setq tmplst (append tmplst (list ename)))  
  1445.     )  
  1446.   )  
  1447.   tmplst  
  1448. )  
  1449. ;;;  
  1450. ;;; Add the item (ename) to the list (lst).  
  1451. ;;;  
  1452. ;;; pt_ail == PText_Add_Item_to_List  
  1453. ;;;  
  1454. (defun pt_ail (ename temp lst / j k tmplst)  
  1455.   (setq j   0  
  1456.         k   (length lst)
  1457.   )  
  1458.   (while (< j k)  
  1459.     (if (= j temp)  
  1460.       (setq tmplst (if tmplst  
  1461.                      (append tmplst (list ename))  
  1462.                      (list ename)  
  1463.                    )  
  1464.             temp   nil  
  1465.       )  
  1466.     )  
  1467.     (setq tmplst (if tmplst  
  1468.                    (append tmplst (list (nth j lst)))
  1469.                    (list (nth j lst))  
  1470.                  )  
  1471.           j      (1+ j)  
  1472.     )  
  1473.   )  
  1474.   (if temp (setq tmplst (if tmplst  
  1475.                           (append tmplst (list ename))  
  1476.                           (list ename) 
  1477.                         ) 
  1478.            )  
  1479.   )  
  1480.   tmplst
  1481. )  
  1482. ;;;  
  1483. ;;; Add a character to a string  
  1484. ;;;  
  1485. ;;; pt_ats == PText_Add_char_To_String  
  1486. ;;;  
  1487. (defun pt_ats (char appnd)  
  1488.   ;; Add item (chr char) to list "strlst".  
  1489.   (setq strlst (pt_ail (chr char) (if appnd pt_rsp (1- pt_rsp)) strlst))  
  1490.   (if insert  
  1491.     (progn
  1492.       (if (not appnd) (setq pt_vsp (1+ pt_vsp)))
  1493.       (setq pt_msp (1+ pt_msp))
  1494.     )  
  1495.   )  
  1496.   ;; If overwriting...  
  1497.   (if (null insert)  
  1498.     ;; Subtract item "pt_rsp" from list "strlst".  
  1499.     (if (< pt_rsp pt_msp) (setq strlst (pt_sil pt_rsp strlst)))  
  1500.   )  
  1501.   (setq str    (pt_sjk 1 (length strlst)))  
  1502.   (princ "\rText: ")  
  1503.   (princ str)  
  1504.   (1+ pt_rsp)   
  1505. )  
  1506. ;;;  
  1507. ;;; Process a newline character  
  1508. ;;;  
  1509. ;;; pt_pnl == PText_Process_NewLine  
  1510. ;;;  
  1511. (defun pt_pnl (/ sset j)  
  1512.   (if ent ; There should (!) always be an entity at this point...  
  1513.     (progn  
  1514.       ;; Get the correct "start point" for the current type of text entity...  
  1515.       ;; This should correctly handle mixed text justification types.   
  1516.       (setq pt_spt (cdr(assoc (if (or (= grp_72 2) ; Right justified  
  1517.                                       (= grp_72 1) ; Left justified  
  1518.                                   ) 11 10) ent))  
  1519.             pt_spt (polar pt_spt (- pt_ra (/ pi 2)) pt_ils)  
  1520.       )  
  1521.       (if (= grp_72 5)                ; if Fit text  
  1522.         (setq pt_rpt (cdr(assoc 11 ent))  
  1523.               pt_rpt (polar pt_rpt (- pt_ra (/ pi 2)) pt_ils)  
  1524.          )  
  1525.       )  
  1526.       (setq ent (subst (cons 1 (substr str 1 (1- pt_rsp))) (assoc 1 ent) ent))  
  1527.       (if (= (cdr(assoc 1 ent)) "")  
  1528.         (setq ent (subst (cons 1 " ") (assoc 1 ent) ent))  
  1529.       )  
  1530.       (entmod ent)  
  1531.       ;; Null line at end of paragraph...  
  1532.       (if (and (= pt_cl (length tx:lst)) (= str " "))   
  1533.         (setq str "")                 ; Exit from routine.  
  1534.         ;; else  
  1535.         (progn  
  1536.           (setq str (substr str pt_rsp)   ; The balance of the string.
  1537.                 sl     (strlen str)  
  1538.                 pt_tsp (pt_cll sl nil)  
  1539.                 pt_str (pt_uls str pt_tsp)  
  1540.                 sset   (ssadd)  
  1541.                 j      pt_cl  
  1542.           )  
  1543.           (while (< j (length TX:LST))  
  1544.             (ssadd (nth j TX:LST) sset)  
  1545.             (setq j (1+ j))  
  1546.           )  
  1547.           (if (> (sslength sset) 0)  
  1548.             (command "move"   
  1549.                      sset   
  1550.                      ""   
  1551.                      pt_spt   
  1552.                      (polar pt_spt (- pt_ra (/ pi 2)) pt_ils)  
  1553.             )  
  1554.           )  
  1555.         )  
  1556.       )  
  1557.       (setq ent nil)  
  1558.       (setq sl 0)  
  1559.     )  
  1560.     (progn  
  1561.       (princ "\nError processing newline character. ")  
  1562.       (exit)  
  1563.     )  
  1564.   )  
  1565. )  
  1566. ;;;  
  1567. ;;; Process line  
  1568. ;;;  
  1569. ;;; pt_pl == PText_Process_Line  
  1570. ;;;  
  1571. (defun pt_pl ()  
  1572.   (if ent                             ; Modify the text string  
  1573.     (entmod (setq ent (subst (cons 1 pt_str) (assoc 1 ent) ent)))  
  1574.     ;; else  
  1575.     (progn  
  1576.       (dr_txt pt_str)                 ; Draw the text string  
  1577.       (setq TX:LST (if TX:LST  
  1578.                      (pt_ael (cdr(assoc -1 ent)) pt_cl TX:LST)  
  1579.                      (list (cdr(assoc -1 ent)))  
  1580.                    )  
  1581.       )  
  1582.     )  
  1583.   )  
  1584. )  
  1585. ;;;  
  1586. ;;; Get the maximum string position allowed on a line given the   
  1587. ;;; current contents of the variable "str".  Uses (pt_gll).  
  1588. ;;;  
  1589. ;;; pt_gmp == PText_Get_Maximum_string_Position  
  1590. ;;;  
  1591. (defun pt_gmp (/ temp)  
  1592.   ;; Get a temporary projected number of characters allowed on a line.  
  1593.   ;; Check this against the actual line length of the real characters,  
  1594.   ;; adding one character until either the end of the string is reached   
  1595.   ;; or the maximum line length is reached.  Then start subtracting   
  1596.   ;; characters until either a space or hypen is found, or the start of  
  1597.   ;; the string is reached.  If the start of the string is reached, then  
  1598.   ;; search forward on the string looking for the end of the word.  If  
  1599.   ;; the end of the word is not found then return 1, else return the   
  1600.   ;; wrap position on the line.  
  1601.        
  1602.   (setq temp (round (/ pt_mll (* 0.8 pt_twf pt_th))))  
  1603.   (while (and (< temp pt_rsp) (< (pt_gll temp) pt_mll))  
  1604.     (setq temp (1+ temp))  
  1605.   )  
  1606.   (while (> (pt_gll temp) pt_mll)  
  1607.     (setq temp (1- temp))  
  1608.   )  
  1609.   (while (and (> temp 1)   
  1610.               (/= (nth (1- temp) strlst) " ") ; Back up until a space  
  1611.               (/= (nth (1- temp) strlst) "-") ; or hyphen is found...  
  1612.          )  
  1613.     (setq temp (1- temp))  
  1614.   )  
  1615.   (if (= temp 1)  
  1616.     (progn  
  1617.       (setq temp (round (/ pt_mll (* 0.8 pt_twf pt_th))))  
  1618.       (while (and (< temp pt_rsp)   
  1619.                   (/= (nth (1- temp) strlst) " ") ; Back up until a space  
  1620.                   (/= (nth (1- temp) strlst) "-") ; or hyphen is found...  
  1621.              )  
  1622.         (setq temp (1+ temp))  
  1623.       )  
  1624.     )  
  1625.   )  
  1626.   (if (= temp pt_rsp)  
  1627.     1  
  1628.     temp  
  1629.   )  
  1630. )  
  1631. ;;;  
  1632. ;;; Wrap the line at the end of the previous word, if there is one.  
  1633. ;;; Otherwise, if the line is short and/or the word is long enough  
  1634. ;;; to occupy the entire line length, then extend the word.  
  1635. ;;;  
  1636. ;;; pt_waw == PText_Wrap_At_Word  
  1637. ;;;  
  1638. (defun pt_waw (/ temp)  
  1639.   (setq temp (pt_gmp))                ; Get the maximum string position.  
  1640.   
  1641.   (if (= grp_72 5)                    ; Fit text...  
  1642.     ;; Set up to test if we are within the last 1/4 of the word,  
  1643.     ;; and if so, we will cram the whole word on the line.  
  1644.     (progn  
  1645.       (setq line_l (* 0.9   
  1646.                       pt_twf   
  1647.                       pt_th   
  1648.                       (- pt_rsp (* (- pt_rsp temp) 0.25)))  
  1649.       )  
  1650.     )  
  1651.     ;; Else, set a dummy value large enough to trip the next test.  
  1652.     (setq line_l (* 2 line_l))   
  1653.   )  
  1654.   (pt_cll temp T) ; Return the visual string position.  
  1655. )  
  1656. ;;;  
  1657. ;;; Process word wrap.  
  1658. ;;;  
  1659. ;;; pt_pww == PText_Process_Word_Wrap  
  1660. ;;;  
  1661. (defun pt_pww (loc / sset j)  
  1662.   ;; Not at the start of a line and line is longer than  maximum specified...  
  1663.   (if (and (> loc 1) (> line_l pt_mll))  
  1664.     ;; Wrapping a text line...  
  1665.     (progn  
  1666.       (pt_pee) ; Process existing entity  
  1667.         
  1668.       (pt_mne) ; Make the new text line here...  
  1669.     )  
  1670.     ;; Extending a text line...  
  1671.     (progn  
  1672.          
  1673.       ;; set the string that gets printed on-screen via (entmod).  
  1674.       (setq pt_str (pt_uls str pt_rsp))  
  1675.       (setq ent (subst (cons 1 pt_str) (assoc 1 ent) ent))  
  1676.       (entmod ent)  
  1677.     )  
  1678.   )  
  1679. )  
  1680. ;;;  
  1681. ;;; Process the existing string, entmoding it to its final form.  
  1682. ;;;  
  1683. ;;; pt_pee == PText_Process_Existing_Entity  
  1684. ;;;  
  1685. (defun pt_pee ()  
  1686.   (repeat (- (pt_cll pt_msp nil) loc) (princ (chr P_BACK))  
  1687.                                       (princ (chr P_SPCE))   
  1688.                                       (princ (chr P_BACK))  
  1689.   )  
  1690.   (princ "\rText: ")  
  1691.   ;; Strip trailing space.  
  1692.   (while (= (nth (1- loc) strlst) " ") (setq loc (1- loc)))  
  1693.   (setq ent    (subst   
  1694.                  (cons 1 (princ (pt_sjk 1 loc))) ; print the string  
  1695.                  (assoc 1 ent)   
  1696.                  ent  
  1697.                )  
  1698.         pt_cl  (1+ pt_cl)  
  1699.         pt_spt (cdr(assoc (if (or (= grp_72 2)   
  1700.                                   (= grp_72 1)) 11 10) ent))  
  1701.         str    (pt_sjk (+ loc 2)  (length strlst))  
  1702.         strlst (pt_psl str)           ; Parse string to list   
  1703.         pt_msp (pt_cll (length strlst) T) ; Check line length  
  1704.         pt_vsp (pt_cll (- pt_rsp loc 1) T)  
  1705.         pt_rsp (pt_cll pt_vsp nil)    ; Get character position/size  
  1706.   )  
  1707.   (if (< pt_vsp 1) (setq pt_vsp 1))  
  1708.   (entmod ent)  
  1709. )  
  1710. ;;;  
  1711. ;;; Make a new entity after a word wrap.  
  1712. ;;;  
  1713. ;;; pt_mne == PText_Make_New_Entity  
  1714. ;;;  
  1715. (defun pt_mne ()  
  1716.   (princ "\nText: ")  
  1717.   (princ str)  
  1718.   ;; set the string that gets printed on-screen via (entmod).  
  1719.   (setq pt_str (pt_uls str pt_rsp))  
  1720.   
  1721.   (if (<= pt_cl (length TX:LST))  
  1722.     (progn  
  1723.       (setq pt_spt (cdr(assoc (if (or (= grp_72 2)   
  1724.                                       (= grp_72 1)) 11 10) ent))  
  1725.       )  
  1726.       (if (= grp_72 5)                ; if Fit text  
  1727.         (setq pt_rpt (cdr(assoc 11 ent))  
  1728.               pt_rpt (polar pt_rpt (- pt_ra (/ pi 2)) pt_ils)  
  1729.         )  
  1730.       )  
  1731.     )  
  1732.     ;; else  
  1733.     (princ)  
  1734.   )  
  1735.   
  1736.   (pt_fww)  
  1737.   
  1738.   (setq pt_spt (polar pt_spt (- pt_ra (/ pi 2)) pt_ils))
  1739.   (dr_txt pt_str)                     ; Draw the text string  
  1740.   (setq TX:LST (if TX:LST  
  1741.                  (pt_ael (cdr(assoc -1 ent)) pt_cl TX:LST)  
  1742.                  (list (cdr(assoc -1 ent)))  
  1743.                )  
  1744.   )  
  1745. )  
  1746. ;;;  
  1747. ;;; Finish up a word wrap; get ready for the next character.  
  1748. ;;; Move any entities that may follow down by one space.  
  1749. ;;;  
  1750. ;;; pt_fww == PText_Finish_Word_wrap  
  1751. ;;;  
  1752. (defun pt_fww ()  
  1753.   (setq sset   (ssadd)  
  1754.         j      (1- pt_cl)  
  1755.   )  
  1756.   (while (< j (length TX:LST))  
  1757.     (ssadd (nth j TX:LST) sset)  
  1758.     (setq j (1+ j))  
  1759.   )  
  1760.   (if (> (sslength sset) 0)  
  1761.     (command "move"   
  1762.              sset   
  1763.              ""   
  1764.              pt_spt   
  1765.              (polar pt_spt (- pt_ra (/ pi 2)) pt_ils)  
  1766.     )  
  1767.   )  
  1768. )  
  1769. ;;;  
  1770. ;;; Delete a line and back up to the previous one  
  1771. ;;;  
  1772. ;;; pt_dal == PText_Delete_A_Line  
  1773. ;;;  
  1774. (defun pt_dal (temp / )  
  1775.   ;; Remove last ename if at the maximum string position discounting  
  1776.   ;; control characters.  Both should be 1.  
  1777.   (if (= pt_vsp pt_msp)   
  1778.     (if temp   
  1779.       (progn  
  1780.         (repeat (1+ (strlen str))   
  1781.           (princ (chr P_BACK))  
  1782.           (princ (chr P_SPCE))  
  1783.           (princ (chr P_BACK))  
  1784.         )  
  1785.         (princ "*Deleted*")  
  1786.       )  
  1787.       (progn  
  1788.         (entmod (subst (cons 1 str) (assoc 1 ent) ent))  
  1789.         (setq str "")  
  1790.       )  
  1791.     )  
  1792.     (entmod (subst (cons 1 str) (assoc 1 ent) ent))  
  1793.   )  
  1794.   (terpri)
  1795.   (setq pt_cl (1- pt_cl)  
  1796.         ent   (if (and (> pt_cl 0) (> (length TX:LST) 0))  
  1797.                 (entget (nth (1- pt_cl) TX:LST))  
  1798.                 nil  
  1799.               )  
  1800.   )  
  1801.   (if ent  
  1802.     (progn  
  1803.       (if temp   
  1804.         (progn  
  1805.           (pt_bul (1+ pt_cl))        ; Bring up lines following this line.  
  1806.           (setq st     (pt_psl (cdr(assoc 1 ent)))
  1807.                 str    (strcat (cdr(assoc 1 ent)) str)
  1808.           )
  1809.         )  
  1810.         (setq str    (cdr(assoc 1 ent)))  
  1811.       )  
  1812.       (setq strlst (pt_psl str)  
  1813.             pt_vsp (1+ (pt_cll (length st) nil))  
  1814.             pt_msp (pt_cll (length strlst) T)  
  1815.             pt_spt (polar pt_spt (+ pt_ra (/ pi 2)) pt_ils)  
  1816.       )  
  1817.       (princ str)  
  1818.       (if (= grp_72 5)  
  1819.         (setq pt_rpt (polar pt_rpt (+ pt_ra (/ pi 2)) pt_ils))  
  1820.       )  
  1821.     )  
  1822.     (progn  
  1823.       (setq TX:LST nil  
  1824.             ent    nil  
  1825.       )  
  1826.     )  
  1827.   )  
  1828. )  
  1829. ;;;  
  1830. ;;; Draw each text item  
  1831. ;;;  
  1832. ;;;  
  1833. (defun dr_txt (str / j)  
  1834.   (setq j (* pt_ra (/ 180 pi)))       ; rotation angle in decimal degrees.  
  1835.   (cond  
  1836.     ((= grp_72 0) (command "text" pt_spt pt_th j str))  
  1837.     ((= grp_72 1) (command "text" "c" pt_spt pt_th j str))  
  1838.     ((= grp_72 2) (command "text" "r" pt_spt pt_th j str))  
  1839.     ((= grp_72 5) (command "text" "f" pt_spt pt_rpt pt_th str))  
  1840.   )  
  1841.   (setq ent (entget(entlast)))  
  1842.   (setq pt_spt (cdr(assoc (if (or (= grp_72 2) (= grp_72 1)) 11 10) ent)))  
  1843.   (setq pt_spt (polar pt_spt (- pt_ra (/ pi 2)) pt_ils))  
  1844.   (if (= grp_72 5)  
  1845.     (setq pt_rpt (polar pt_rpt (- pt_ra (/ pi 2)) pt_ils))  
  1846.   )  
  1847.   ent  
  1848. )  
  1849.   
  1850. ;;;  
  1851. ;;; Round a number off to the nearest integer correctly  
  1852. ;;;  
  1853. ;;;  
  1854. (defun round (num)  
  1855.   (if (>= (- num (fix num)) 0.5)  
  1856.     (fix (1+ num))  
  1857.     (fix num)  
  1858.   )  
  1859. )  
  1860. ;;; ------------------ Cut here ----------------------------------  
  1861. ;;;  
  1862. ;;; C: function definition.  
  1863. ;;;  
  1864. (defun c:pt () (vmon)(ptext))  
  1865. (defun c:ptext () (vmon)(ptext))  
  1866. (princ "\n\tC:PText loaded.  Start command with PT or PTEXT.")  
  1867. (princ)  
  1868.