From: zzang@whale.uucp (Zhuo Zang[~{j0WA~}])
Subject: hzfmt for hz files
Organization: University of Florida
Distribution: usa
Date: Tue, 1 Sep 92 14:27:56 GMT

Hello, 
this is a text formatter for the HZ coded file.
it will format the HZ coded file into text
with line length 70. see notes in the header
message of the source file.
hzfmt has many features as fmt, and also have
some better features than the fmt in Unix.
I try to incorporate as many good features in fmt
as possible. however, due to the time and laziness.
some features are not included in this version,
and will be included in later version. depending
on the users' interests, and the times allow me to do.
hzfmt can't be the same as the fmt, due to the
special codes in the HZ files.
here are some major differences come into my mind:
1. fmt is a line interpreter, hzfmter is not.
   this can be done soon.
2. fmt will strip the trailing blanks in the output.
   hzfmt keeps all the blanks in the original file.
   many minor features like the treatment of the
   punctions in the English text (certainly, this
   is not the problem with the Chinese texts).
   these will be expected in the later version.
3. verbose line feature of hzfmt, see the e.g. in
   the head of source file. I will also incorporate
   the fmt like verbose feature later.
4. paragraph folding, almost the same as the fmt
   except the trailing blanks stuff in 2.

Enjoy !

Please send bug reports or suggestions to

zzang@stat.ufl.edu .

I will try to incorporate as many features as possible.
and also I need keep this program in small size and efficient.

--zhuo
------- test.fmt--- CUT HERE----------
/* hzfmt test file 
.  IMPORTANT: DONT change the lines following the comments
.  otherwise, you WONT see the results 
.  I don't include the hz test file here. you may try yourself. */
/* the following is testing keeping blank lines
.  that is, lines may contain white spaces */ 
                              
                   

                                                            


/* test of paragraph wrapping */
       asdf ghjk lzxc vbnmqwertyu iopasdf ghjkl zxcvbnmq werty uiopasd  fghjk lzxc
vbnmq wertyu iopa sdfghjk lzxc vbn mqwer tyui oas dfg hjkl zxcvb nmq werty uiopp

/* test of no leading blanks */
jk~{ this is test of blank skip at the end                            ~}     noleadingblanks
/* the following test keeping the blank line, including the blanks */
                                    
/* you wont see ~~{ after fmt */
                                            this is another p~{    ~} ~{

/* another test of paragraph wrapping */
         asdf ghjk lzxc vbnmqwertyu iopasdf ghjkl zxcvbnmq werty uiopasd fghjk lzxc
vbnmq wertyu iopa sdfghjk lzxc vbn mqwer tyui oas dfg hjkl zxcvb nmq werty uiopp
         asdf ghjk lzxc vbnmqwertyu iopasdf ghjkl zxcvbnmq werty uiopasd fghjk lzxc
vbnmq wertyu iopa sdfghjk lzxc vbn mqwer tyui oas dfg hjkl zxcvb nmq werty uiopp
      asdf ghjk lzxc vbnmqwertyu iopasdf ghjkl zxcvbnmq werty uiopasd fghjk lzxc
vbnmq wertyu iopa sdfghjk lzxc vbn mqwer tyui oas dfg hjkl zxcvb nmq werty uiopp


     /* finally, the verbose feature
     .  can be seen from all the previous comments.
     .  and this final note */

  
--------end of test.fmt------CUT HERE-------------
---------hzfmt.c-----------CUT HERE ---------------
/*	@(#)hzfmt.c	Version 1.1	8/27/92		*/
/* 
   Copyright (C) Auguest 27, 1992  by   Zhuo ZANG[~{j0WA~}]
   All Rights Reserved                  email: zzang@stat.ufl.edu

   Chinese text fmt for hz coded files.
   line will be of size 70 chars or 35 Chinese chars.

   Usage:
   hzfmt < file1 > file2
   Features:
   1.	fast, very small as you can see,
	no limit on line length or file length.
   2.	unlike fmt, hzfmt will not fold lines with same blank
	margin as the start line of the para, this is useful
	for lists and tables.
	e.g.:
	1.
		Hzfmt wont fold this para
		While fmt will, this feature can be
		useful in verbose, you may put a dot like the following
		.	at the beginning of a line
		.	to set table, list and that is it.

	2.
		However, hzfmt will fold this para
	as the fmt do in unix, this can be very useful,
	this is one of the hzfmt's magic features.
	    This will also starts a new para as in fmt,
	this is very useful, isn't it ?
	3.
		I don't put any Chinese char here.
	However, if this line starts with Chinese, hzfmt
	wont fold the line. hzfmt wont fold line when the
	line starts with mode change.

   Method:
   the hz Chinese codes are enclosed by ~{ and ~},
   each Chinese word is represented by two bytes,
   so must be read/write in twos.
   Note:
   the output line length may exceed 70,
   if the end is a word (English or Chinese).

 */
#include <stdio.h>

#ifndef OLEN
#define	OLEN	(70)	/* output line length */
#endif

#ifndef MAXBL
#define MAXBL	(70)	/* max # of leading blanks of paragraph */
#endif

#define NL	'\n'

int get_char(void);

#define getnext(cur, next) \
{\
   putchar(cur);\
   count++;\
   cur = next;\
   next = get_char();\
}
#define is_space(c) ((c=='\t'||c==' '))
#define is_alnum(c) ((c>='0'&&c<='9')||(c>='A'&&c<='Z')||(c>='a'&&c<='z'))
/* 
   hzmode flag
   0: cur is in ascii, 1: cur is in hz,
   2: cur is ~, next is {, begin of hz
   3: cur is ~, next is }, end of hz
 */
int  hzmode = 0;

int main ()
{
   char	cur, next;
   int	count = 0;

   cur = get_char();
   next = get_char();
   while (cur!=EOF) {
      count = 0;
      while (count<OLEN && cur!=NL && cur!=EOF) {
/* end hz mode */
	 if (hzmode && cur=='~' && next=='}') hzmode = 3;
/* begin hz mode */
	 if (!hzmode && cur=='~' && next=='{') hzmode = 2;
	 if (count==0 && hzmode==2) count-=2;
	 if (count==(OLEN-2) && (hzmode == 2)) {
	    count += 2;
	    cur = get_char();
	    next = get_char();
	    goto _nextc;
	 }
	 if (!hzmode && count==(OLEN-1) && is_space(cur)) {
	    count++;
	    cur = next;
	    next = get_char();
	    goto _nextc;
	 }
	 getnext(cur, next)

	 if (!hzmode || hzmode==3) 
	    while (is_alnum(cur)) getnext(cur, next)
	 _nextc:;

      }

      if (cur=='~' && next=='}') {
	 printf("%c%c", cur, next);
	 hzmode = 3;
	 cur = get_char();
	 next = get_char();
      }
      if (cur=='~' && next=='{') {
	 hzmode = 2;
	 cur = get_char();
	 next = get_char();
      }

      if (!hzmode)
	 while (is_space(cur)) {
		cur=next;
		next=get_char();
	 } 

      if (cur==NL) {
	 getnext(cur, next)
	 hzmode = 0; }
      else {
	 putchar(NL);
	 if (hzmode==1 && cur!='~') printf("~{");
      }

   }
   return 0;

}


char	c, *bp, leadbuf[MAXBL];	/* buf to hold the leading blanks of a para */
int	leadblanks = 0,		/* leading blanks of a para, \t counts 8 */
	preblanks = 0,		/* # of leading blanks in pre line */
	first = 1,		/* 1st line, no \n on 1st */
	newline = 1,		/* begin a new line */
	verbose = 0,		/* fmt like verbose lines */
	newpara = 1;		/* new para */

#define	TABSIZE  (8)

/* get char from stdin or leadbuf if it's not empty
   it will fold the para into a long line */
int get_char ()
{
   int	lineblanks = 0,	/* # of leading blanks in a line */
	is_blanks = 0,	/* 1 if is blank line */
	indent = 0;	/* 1 if preblanks<lineblanks */
start:
   if (newline) {
      bp = leadbuf;
      *bp = '\0';
      is_blanks = 0;
      lineblanks = 0;
      c = getchar();
      while (is_space(c)) { 
	 *(bp++) = c;
	 lineblanks += (c=='\t') ? TABSIZE : 1;
	 c = getchar();
      }

      if (c==NL) {
	 is_blanks = 1;
	 lineblanks = 0;
      }

/* check indention */
      if (preblanks < lineblanks) indent = 1;
/* new paragraph */
      if (is_blanks || indent || hzmode==2 
	 || (hzmode==3 && c!='~') || (hzmode==1 && c!='~') 
	 || (hzmode==0 && c=='~') 
	 || (lineblanks >= leadblanks)) {
	 *bp++ = c;
	 *bp = '\0';
	 leadblanks = lineblanks;
	 newpara = 1; }
      else {	/* fold line, leave one blank in leadbuf */
	 if (hzmode==1 && c=='~') {
	    c = getchar();
	    leadbuf[0] = '\0'; }
	 else if (c==EOF || hzmode==3 || hzmode==2) {
	    leadbuf[0] = c;
	    leadbuf[1] = '\0'; }
	 else {
	    leadbuf[0] = ' ';
	    leadbuf[1] = c;
	    leadbuf[2] = '\0';
	 }
      }
      
      preblanks = lineblanks;
      newline = 0;
      bp = leadbuf;
   }

/* if new para */
   if (!first && newpara) {
      c = '\n';
      newpara = 0;
      return c;
   }
   if (first) {
      first = 0;
      newpara = 0;
   }

/* if leadbuf not empty, get from it */
   if (*bp) return *bp++;
   else {
      c = getchar();
      if (c == NL) {
	 newline = 1;
	 goto start;
      }
      if (hzmode==3 && c!='~') hzmode=0;
      if (hzmode==2) hzmode=1;
      return c;
   }

}
--------end of hzfmt.c-----------------
-- 
Zhuo Zang[~{j0WA~}]
Department of Statistics
University of Florida            Email: zzang@stat.ufl.edu