[comp.sources.misc] v06i047: meunshar, a MicroEmacs macro to split shar files

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (03/05/89)

Posting-number: Volume 6, Issue 47
Submitted-by: saj@chinet.chi.il.us.UUCP (Stephen Jacobs)
Archive-name: unshar.uemacs

This submission is a macro to split up shell archives (shar files) using
Daniel Lawrence's MicroEMACS.  It will be useful on systems which do not
have UNIX's features of here-documents (ie: take the rest of this file as
stdin until you match the thing after '<<') and flexible file naming.  I
developed it on an Atari ST under the Mark Williams shell 'msh'; it should
also be useful under MS-DOS.  It works on archives which use sed to remove
a pad character at the start of each line; it does not work on archives 
which use cat to split them without such manipulations.  The names of the
files created must be unique in the first 12 characters.

To use this macro, enter the shar file into MicroEMACS, then type Meta-X
(this is usually escape key followed by unshifted x): this will give a
command line.  Type 'execute-file' followed by a space: this will cause
the program to prompt for a file to execute.  Type the name the following
macro is stored under, followed by <return>.  If all goes well, this will
split the archive into sections, each in its own buffer named with the 
first 12 characters of its intended filename.  Much of the non-file matter
in the archive will be in a buffer named 'head%mattr' and the lines that 
were used as item separaters will be in a buffer named 'sep%markers'.  The
user must cycle through the buffers, saving to file names or not as (s)he
sees fit.

Some old or hand-made archives may not be unpacked properly by this macro.
Versions of MicroEMACS earlier than 3.9 may not handle this macro properly
(I haven't tried).

Atari and ST are trademarks of Atari Corp.,  UNIX is a trademark of AT&T
and MS-DOS is a trademark of Microsoft Corp.  The macro begins AFTER 
(not including) the 'cut here' line.  I believe it would be contrary to
the spirit of this posting to package it as a shell archive.

[Given the nature of the posting, it makes the most sense to load it directly
into your copy of microEmacs anyway....  ++bsa]

x---------------------------------cut here----------------------------------x
beginning-of-file
add-mode "magic"
add-mode "exact"
set %original $cbufname
*sect%loop
	search-forward "^sed"
	search-forward "<<"
	kill-to-end-of-line
	select-buffer "sep%markers"
	yank
	beginning-of-line
	set-mark
	!while &equal &ascii #sep%markers 32	;Loop strips leading blanks
		previous-line
		delete-next-character
	!endwhile
	exchange-point-and-mark
	!if &equal &ascii #sep%markers 34	;remove enclosing quotes
		previous-line
		delete-next-character
		end-of-line
		delete-previous-character
	!else
		previous-line
		!if &equal &ascii #sep%markers 39	;remove enclosing
			previous-line			;apostrophes
			delete-next-character
			end-of-line
			delete-previous-character
		!endif
	!endif
	beginning-of-line
	set-mark		; Next 5 lines escape risky MAGIC special chars
	replace-string "\" "\\"
	exchange-point-and-mark
	set-mark
	replace-string "*" "\*"
	exchange-point-and-mark
	select-buffer %original
	delete-previous-character
	delete-previous-character
	backward-character			;This and following loop 
	!while &equal &ascii #$cbufname 32	;strip trailing blanks
		backward-character		;from destination buffer
		delete-previous-character	;name--they'd be used 
		backward-character		;otherwise, causing trouble
	!endwhile
	search-reverse ">"
	delete-next-character
	set-mark
	!while &equal &ascii #%original 32	;Loop strips leading blanks
		exchange-point-and-mark		;same as trailing blanks
		delete-next-character
		set-mark
	!endwhile
	exchange-point-and-mark
	set %destbuf &left #$cbufname 12	;Long buffer names troublesome
	previous-line
	set-mark
	beginning-of-file
	kill-region
	select-buffer head%mattr
	yank
	select-buffer %original
	search-forward "s/"
	kill-region
	search-forward "/"
	backward-character
	kill-to-end-of-line
	beginning-of-line
	set-mark
	set $search &cat "^" #sep%markers
	hunt-forward
	beginning-of-line
	kill-region
	select-buffer %destbuf
	add-mode "magic"
	yank
	beginning-of-file
	set-mark
	set $search #$cbufname		;Note that this advances cursor 1 line
	kill-region
	replace-string $search ""
	select-buffer %original
!goto sect%loop