home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / lang / perl / 7952 < prev    next >
Encoding:
Text File  |  1993-01-23  |  9.5 KB  |  392 lines

  1. Newsgroups: comp.lang.perl
  2. Path: sparky!uunet!mcsun!sunic!uts!id.dth.dk!ej
  3. From: ej@id.dth.dk (Erik Johansen (none#None))
  4. Subject: Re: editor scripts.
  5. Message-ID: <ej.727733830@id.dth.dk>
  6. Keywords: editor editing scripts perl subroutine text
  7. Organization: Department of Computer Science
  8. References: <1314@alsys1.aecom.yu.edu>
  9. Date: Fri, 22 Jan 1993 20:17:10 GMT
  10. Lines: 380
  11.  
  12. manaster@yu1.yu.edu (Chaim Manaster) writes:
  13.  
  14. >The following is a repost in the hope that more people will respond
  15. >this time. I have had many inquiries asking for the results of my
  16. >posting, so I know there is a good deal of interest in the matter.
  17. >This is quite logical as it is a very common need. Please respond
  18. >if you can. Here it is once again.
  19. >________________________________________________________________
  20.  
  21. >Does anybody out there in netland have any perl scripts that do
  22. >simple full-screen editing on either ascii or wordprocessor format
  23. >files that they wouldn't mind sharing? They don't have to be
  24. >anything fancy, just plain vanilla editors (in fact they could be
  25. >line oriented although full-screen would be preferred).
  26. >Preferably, they would be in the form of a subroutine, but if they
  27. >are not, I imagine that it is a minor modification for me to make.
  28. >(I am obviously no pro at this stuff yet).
  29.  
  30. Well, well, I made up a require file for the times when you need to
  31. edit a small text (Actual: Array of texts).
  32.  
  33. The idea is to pass an array to an &Edit call allowing the user
  34. to do the desired changes to the text before continuing.
  35. As this was a quick written up procedure, I am sure that a better
  36. version will be available at some time.
  37.  
  38. Not so much talk, here it is:
  39.  
  40. ------snap snap---- edit.pl -----------snap snap--------
  41. #
  42. # Edit module.
  43. #
  44. # Example of calling:
  45. #
  46. #   require "edit.pl";
  47. #
  48. #   @user_text = split(/\n/, <<TEST);
  49. #   This is a test
  50. #   of the editor module.
  51. #   TEST
  52. #
  53. #   &Edit( *user_text );
  54. #
  55. #   print "Your text now:\n", @user_text;
  56. #
  57. #
  58. # Works on UNIX, some changes will be needed to run on PC
  59. # The lines in @user_test should not contain "\n".
  60. #
  61.  
  62. $version = "1.0";
  63.  
  64. sub Edit
  65.  {
  66.   local( *buf ) = @_;
  67.  
  68.   &Definitions unless defined %esctab;
  69.  
  70.   local($x_max, $y_max, $x, $y, $x_off, $editing) =  (80, 24, 0,0,0, 1);
  71.  
  72.   &Repaint;
  73.  
  74.   &stty_cbreak_noecho;
  75.   while ( $editing )
  76.    {
  77.     $key = &GetKey;
  78.     $key = $esctab{ $key } if defined $esctab{ $key };
  79.     if ( length($key) == 1 &&  $key ge " " )
  80.      {
  81.       push(@buf, "") while ! defined $buf[$y];
  82.       $buf[$y] .= " " x ($x - length($buf[$y])) if $x > length($buf[$y]);
  83.       substr( $buf[$y], $x++, $overstrike ) = $key;
  84.       print $key;
  85.      }
  86.     elsif ( length($key) > 1 && $key !~ /^\033/  )
  87.      {
  88.       eval $key;
  89.       print $@ if $@;
  90.      }
  91.     else
  92.      {
  93.       print "\007"; # Ring bell
  94.      }
  95.    }
  96.   &stty_nocbreak_echo;
  97.   print $CLS;  # Clear screen (remove if you don't like this)
  98.  }
  99.  
  100. sub ShowCursor
  101.  {
  102.   local( $repaint ) = 0;
  103.  
  104.   # Make full wraparound
  105.  
  106.   $y++, $x=0 if $x > length($buf[$y])+1;
  107.   --$y, $x=length($buf[$y])+1 if $x < 0;
  108.   $y = $#buf-$y   if $y < 0;  # If further up than first line we start at end
  109.   $y = $y-$#buf-1 if $y > $#buf+1; # efter end we get back to start
  110.  
  111.   $y_off = $y, $repaint++ if $y < $y_off; 
  112.   $y_off = $y-$y_max+1, $repaint++ if $y > $y_off + $y_max;
  113.  
  114.   print $CSI, "23;70H ($y, $x)  "; # DEBUG -remove if you don't like this
  115.  
  116.   print $CSI, $y-$y_off+1, ";", $x+1, "H" unless $repaint; # Position cursor
  117.  
  118.   $repaint;  # Return true if repaint is needed
  119.  }
  120.  
  121. sub Repaint
  122.  {
  123.   &ShowCursor; # First make sure that offset etc. are right
  124.   print $CLS;
  125.   local( $ry, $count ) = ($y_off, $y_max);
  126.   print substr( $buf[$ry++], 0, $x_max ), "\n" 
  127.      while --$count && defined $buf[$ry];
  128.   &ShowCursor;
  129.  }
  130.  
  131.  
  132. sub GetKeyPart
  133. {
  134.  local( $buf ) = "";
  135.  read(STDIN, $buf, 1);
  136.  $buf;
  137. }
  138.  
  139. sub GetKey
  140.  {
  141.   local( $buf ) = &GetKeyPart;
  142.   if ( $buf eq "\033" )
  143.    {
  144.     $buf .= &GetKeyPart;
  145.     $buf = "\033[" if $buf eq "\233";
  146.     if ( $buf eq "\033[" )
  147.      {
  148.       $buf .= &GetKeyPart;
  149.       $buf .= &GetKeyPart  while $buf =~ /[0-9;,]$/;
  150.      }
  151.    }
  152.   $buf;
  153.  }
  154.  
  155. #-----------------------------------------------------------------------------
  156. # Interactive Keyboard functions
  157. #-----------------------------------------------------------------------------
  158. sub Help
  159.  {
  160.   print $CLS; # Clear scroll region and screen
  161.  
  162.   local( %help, $txt );
  163.   foreach $val ( values %esctab )
  164.    {
  165.     next unless $val =~ /\#\s*(.+)\s*\-\s*/;
  166.     $help{ $1 } = $';
  167.    }
  168.  
  169.   format HELP_TOP =
  170. Edit Version @<<<<<<<<<<<<<<<<<<<<<<<                          By Erik Johansen
  171.              $version
  172.                          HELP INFORMATION                            Page @|||
  173.                                                                           $%
  174.  
  175.      Function key            Description
  176. ------------------------+------------------------------------------------------
  177. .
  178.  
  179.   format HELP =
  180.      @<<<<<<<<<<<<<<<<     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  181.      $key,                 $help{$key}
  182. ~~                         ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  183.                            $help{$key}
  184. .
  185.   $^ = HELP_TOP; # Set name of header format
  186.   $~ = HELP; # Set name of format
  187.   $= = $y_max - 2;    # Number of lines on page (minus trailer)
  188.   $% = 0;
  189.   $- = 0; # Page 0 line 0
  190.   foreach $key ( sort keys %help )
  191.    {
  192.     write;
  193.     next if $- > 1; # unless end of page
  194.     print <<SEP;
  195. ------------------------+------------------------------------------------------
  196. SEP
  197.     print 'Press any key to continue:';
  198.     &GetKey;
  199.     print $CLS;
  200.    }
  201.   print <<SEP;
  202. ------------------------+------------------------------------------------------
  203. SEP
  204.   print "\n";
  205.   &Repaint;
  206.  }
  207.  
  208. sub Up
  209.  {
  210.   $y--;
  211.   $x=length($buf[$y])+1 if $x>length($buf[$y])+1;
  212.   &ShowCursor && &Repaint;
  213.  }
  214.  
  215. sub Down
  216.  {
  217.   $y++;
  218.   $x=length($buf[$y])+1 if $x>length($buf[$y])+1;
  219.   &ShowCursor && &Repaint;
  220.  }
  221.  
  222. sub Left
  223.  {
  224.   $x--;
  225.   &ShowCursor && &Repaint;
  226.  }
  227.  
  228. sub Right
  229.  {
  230.   $x++;
  231.   &ShowCursor && &Repaint;
  232.  }
  233.  
  234.  
  235. sub Return
  236.  {
  237.   splice( @buf, $y, 1, substr($buf[$y],0,$x), substr($buf[$y],$x));
  238.   $y++; $x=0;
  239.   &Repaint;
  240.  }
  241.  
  242. sub Key_Remove
  243.  {
  244.   $PasteBuffer = $buf[ $y ];
  245.   undef $buf[ $y ];
  246.   &Repaint;
  247.  }
  248.  
  249. sub Insert_Here
  250.  {
  251.   if ( defined($PasteBuffer) )
  252.    {
  253.     $buf[ $y ] = ""  unless defined $buf[ $y ];
  254.     substr( $buf[ $y ], $x, $overstrike ) = $PasteBuffer;
  255.     $y += length($PasteBuffer);
  256.     &Repaint;
  257.    }
  258.   else { print "\007"; } # Ring bell
  259.  }
  260.  
  261.  
  262. sub CtrlE
  263.  {
  264.   $x = (defined $buf[ $y ]) ? length($buf[ $y ]) : 0;
  265.   &ShowCursor && &Repaint;
  266.  }
  267.  
  268. sub Home
  269.  {
  270.   $x = 0;
  271.   &ShowCursor && &Repaint;
  272.  }
  273.  
  274. sub CtrlU   # Control-U - Erase to start of line
  275.  {
  276.   if ( $x > 0 && defined $buf[ $y ])   
  277.    {
  278.     $PasteBuffer = substr( $buf[ $y ], 0, $x);
  279.     substr( $buf[ $y ], 0, $x) = "";
  280.     &Home;
  281.     &Repaint;
  282.    }
  283.   else { print "\007"; } # Ring bell
  284.  }
  285.  
  286. sub BackSpace
  287.  {
  288.   if ( $x > 0 && defined $buf[ $y ] )
  289.    {
  290.     substr( $buf[ $y ], --$x, 1 ) = "";
  291.     &Repaint;
  292.    }
  293.   else { print "\007"; } # Ring bell
  294.  }
  295.  
  296. sub PrevScreen
  297.  {
  298.   $y -= 12;
  299.   &Repaint;
  300.  }
  301.  
  302. sub NextScreen
  303.  {
  304.   $y += 12;
  305.   &Repaint;
  306.  }
  307.  
  308. sub DO
  309.  {
  310.   print "Add something here";
  311.   &Repaint;
  312.  }
  313.  
  314. sub Definitions
  315.  {
  316. #  $SIG{'INT'} = 'IGNORE';
  317.  
  318.   $CSI    = "\033[";
  319.   $CLS    = "\033[2J" . "\033[1;1H";
  320.   $Attr   = "\033[0;7m";
  321.   $NoAttr = "\033[0m";
  322.  
  323.   #
  324.   # table of keyboard functions
  325.   #
  326.   %esctab =
  327.    (
  328.     "\033[A",   '&Up;            # UP - Moves up',
  329.     "\033[B",   '&Down;            # DOWN - Moves down',
  330.     "\033[C",   '&Right;        # RIGHT - Moves right.',
  331.     "\033[D",   '&Left;            # LEFT - Moves left.',
  332.     "\033[1~",  '&FindFile;        # FIND - Find file ??',
  333.     "\033[2~",  '&Insert_Here;        # INSERT HERE - Insert contents of paste buffer here.',         
  334.     "\033[3~",  '&Key_Remove;        # REMOVE - Cuts field to paste buffer.',
  335.     "\033[4~",  '&Mark',        # SELECT - Mark position',
  336.     "\033[5~",  '&PrevScreen;        # PREV SCREEN - 12 lines up',
  337.     "\033[6~",  '&NextScreen;        # NEXT SCREEN - 12 lines down',
  338.     "\033[17~", 'undef @buf;$editing=0;    # F6 - Quit.',
  339.     "\033[21~", '$editing=0;        # F10 - Exit',
  340.     "\033[24~", '&SaveTo;',        # F12 - Save file as.
  341.     "\033[25~", '&Include;',        # F13 - Include file from.
  342.     "\033[26~", '$overstrike = 1 - $overstrike;    # F14 - Shift between insert/overwrite',
  343.     "\033[28~", '&Help;            # HELP - Gives this Help screen.',
  344.     "\033[29~", '&DO;            # DO - Do something',
  345.     "\001",     '&Home;            # Ctrl-A - Move to start of line.',
  346.     "\003",     'print "Control-C\n";exit;    # Ctrl-C - Quit program (no questions).',
  347.     "\004",     '$editing=0;        # Ctrl-D - Exit program.',
  348.     "\005",     '&CtrlE;        # Ctrl-E - Move to end of line.',
  349.     "\010",     '&Home;            # Ctrl-H - Move to start of line.',
  350.     "\012",     '&Return;         # <CR> - End currrent line',
  351.     "\014",     '&Repaint;',            # Ctrl-L - Repaints screen.',
  352.     "\015",     ';            # <LF> - Ignore.',
  353.     "\025",     '&CtrlU;        # Ctrl-U - Delete to start of line.',
  354.     "\177",     '&BackSpace;        # BACKSPACE - Remove one character.',
  355.   );
  356.  }
  357.  
  358. sub stty_nocbreak_noecho
  359.  {
  360.   system "/bin/stty -cbreak -echo pass8 </dev/tty >/dev/tty";
  361.  }
  362.  
  363. sub stty_cbreak_noecho
  364.  {
  365.   system "/bin/stty cbreak -echo pass8 </dev/tty >/dev/tty";
  366.  }
  367.  
  368. sub stty_nocbreak_echo
  369.  {
  370.   system "/bin/stty -cbreak echo pass8 </dev/tty >/dev/tty";
  371.  }
  372.  
  373. "End of require - do not remove";    # My way of returning true
  374.  
  375. ------snap here-------------------end of edit.pl-------------------------------
  376.  
  377.  
  378.  
  379.  
  380.   Hope this helps
  381.   Erik Johansen
  382.  
  383. ---
  384.     $txt=" ltrterhnuc--sor eep-\nkJ.a "; srand(53747414);
  385.     for (1..26) { print substr($txt,rand 27,1); }  ### Is this a random write ?
  386. ---
  387. Erik Johansen / Institute for Computer Science / Danish Technical University
  388. ej@id.dth.dk
  389. -- 
  390. Erik Johansen / Institute for Computer Science / Danish Technical University
  391. ej@id.dth.dk
  392.