home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / usg-fmt < prev    next >
Internet Message Format  |  1991-08-07  |  7KB

  1. From: bgray@marque.mu.edu (Bill Gray)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i102: fmt: a simple text formatter
  4. Message-ID: <8804201443.AA29460@marque.mu.edu>
  5. Date: 20 Apr 88 20:43:49 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. comp.sources.misc: Volume 2, Issue 102
  9. Submitted-By: "Bill Gray" <bgray@marque.mu.edu>
  10. Archive-Name: usg-fmt
  11.  
  12. [The Makefile is distinctly System-V-ish.  However, I'm somewhat uncertain as
  13. to whether this came from the BSD "fmt" or not....  ++bsa]
  14.  
  15. -------------------------------------------------------------
  16.  
  17. echo x - fmt.1 1>&2
  18. sed 's/^X//' >fmt.1 <<'----enD-oF-fmt.1----'
  19. X.TH FMT 1 LOCAL
  20. X.SH NAME
  21. Xfmt \- a simple text formatter
  22. X.SH SYNOPSIS
  23. X.B fmt
  24. X[
  25. X.B \-i
  26. X] [
  27. X.B \-j
  28. X] [
  29. X.B \-l n
  30. X] [
  31. X.B \-p n
  32. X] [
  33. X.B \-t n
  34. X] [ filenames ]
  35. X.SH DESCRIPTION
  36. X.I Fmt
  37. Xis a simple text formatter.  With no options present, the default
  38. Xbehavior of
  39. X.I fmt
  40. Xis to copy its input (from specified files or from stdin, if no files
  41. Xare specified) to its output but with input reformatted into lines no
  42. Xlonger than 72 characters long.  A blank line is taken to indicate the
  43. Xbeginning of a new paragraph.  Lines that begin with a period are
  44. Xpreserved.
  45. X.PP
  46. XThe following options modify this behavior:
  47. X.TP
  48. X.B \-i
  49. XThis option will cause
  50. X.I fmt 
  51. Xto preserve indentations.  Blanks or tabs at the beginning of a line
  52. Xwill be considered the beginning of a new paragraph.
  53. X.TP
  54. X.B \-j
  55. XJustify output lines.  (The default behavior of
  56. X.I fmt
  57. Xis to output lines with a ragged right margin).
  58. X.TP
  59. X.B \-l n
  60. XThis option can be used to change the line length from the default of 72
  61. Xcharacters.
  62. X.TP
  63. X.B \-p n
  64. XChange the page offset.  This option will cause the output lines to be
  65. Xoffset the indicated number of columns from the left.
  66. X.TP
  67. X.B \-t n
  68. XSet tab size.  This option is useful only with the
  69. X.B \-i 
  70. Xoption since tabs are preserved only at the beginning of lines and are
  71. Xthrown away by default.
  72. X.SH TIPS
  73. XIn
  74. X.IR vi ,
  75. Xyou can define a macro that will reformat paragraphs by typing
  76. X.I ":map V {!}fmt^M" 
  77. Xor by putting the line
  78. X.ti +7n
  79. X.I "map V {!}fmt^M"
  80. X.br
  81. Xin your
  82. X.I .exrc
  83. Xfile.  After defining this macro, pressing
  84. X.I V 
  85. Xwill cause the paragraph under the cursor to be reformatted.  (Use the
  86. X.I u
  87. Xkey to
  88. X.I undo
  89. Xif necessary.
  90. X.SH "SEE ALSO"
  91. Xnroff(1), vi(1)
  92. ----enD-oF-fmt.1----
  93. echo x - fmt.c 1>&2
  94. sed 's/^X//' >fmt.c <<'----enD-oF-fmt.c----'
  95. X/* 
  96. Xfile: fmt.c   
  97. X04/88  bgray
  98. X*/
  99. X
  100. X/* a simple text formatter */
  101. X
  102. X
  103. X#include <stdio.h>
  104. X#include <ctype.h>
  105. X#include <string.h>
  106. X
  107. X
  108. X#define TRUE 1
  109. X#define FALSE 0
  110. X
  111. Xint iflag = FALSE;
  112. Xint jflag = FALSE;
  113. Xint maxlen = 72;
  114. Xint tabsize = 8;
  115. Xint offset = 0;
  116. Xint spaces = 0;
  117. X
  118. Xchar *progname = NULL;
  119. Xchar *delimiters = " \t\n\r\f";
  120. Xchar *usage = "usage: %s [-ij] [-l n] [-p n] [-t n] [file ...]\n";
  121. X
  122. Xint dir = FALSE;
  123. Xint holecnt = 0;
  124. Xchar *holeptr[256];  /* holeptr[0] is unused */
  125. X
  126. Xchar iline[2048] = "\0";
  127. Xchar *ilp = iline;
  128. Xchar oline[2048] = "\0";
  129. Xchar *olp = oline;
  130. X
  131. Xextern char *optarg;
  132. Xextern int optind;
  133. X
  134. Xint max();
  135. Xvoid exit();
  136. Xchar *basename(), *strtok();
  137. X
  138. X
  139. Xmain(argc, argv)
  140. Xint argc;
  141. Xchar *argv[];
  142. X{
  143. X    int c;
  144. X
  145. X    progname = basename(argv[0]);
  146. X    while ((c = getopt(argc, argv, "ijl:p:t:")) != EOF)
  147. X        switch(c) {
  148. X            case 'i' : iflag = TRUE; break;
  149. X            case 'j' : jflag = TRUE; break;
  150. X            case 'l' : maxlen = max(0, atoi(optarg)); break;
  151. X            case 'p' : offset = max(0, atoi(optarg)); break;
  152. X            case 't' : tabsize = max(1, atoi(optarg)); break;
  153. X            default : fprintf(stderr, usage, progname); exit(1); break;
  154. X        }
  155. X    
  156. X    if (optind >= argc)
  157. X        format();
  158. X    else for ( ;  (optind < argc);  optind++) {
  159. X        if (freopen(argv[optind], "r", stdin) != NULL)
  160. X            format();
  161. X        else {
  162. X            fprintf(stderr, "Couldn't open file: %s", argv[optind]);
  163. X            exit(1);
  164. X        }
  165. X    }
  166. X    return(0);
  167. X}  /* main */
  168. X
  169. X
  170. X
  171. Xformat()
  172. X{
  173. X    char *p;
  174. X    
  175. X    while (ilp = gets(iline)) 
  176. X        if (*ilp == '\0')
  177. X            skipline(1);
  178. X        else if (*ilp == '.') {
  179. X            putline();
  180. X            while (*olp++ = *ilp++);
  181. X            putline();
  182. X        }
  183. X        else {
  184. X            if ((iflag) && (isspace(*ilp))) {
  185. X                putline();
  186. X                copyindent();
  187. X            }
  188. X            p = strtok(ilp, delimiters);
  189. X            while (*p) {
  190. X                putword(p);
  191. X                p = strtok(NULL, delimiters);
  192. X            }
  193. X        }
  194. X    putline();
  195. X}  /* format */
  196. X
  197. X
  198. X
  199. Xcopyindent()
  200. X{
  201. X    int col = 1;
  202. X    
  203. X    for (  ;  (isspace(*ilp));  col++) {
  204. X        if (*ilp++ == '\t')
  205. X            for (  ;  (col % tabsize);  col++) 
  206. X                *olp++ = ' ';
  207. X        *olp++ = ' ';
  208. X    }
  209. X}  /* copyindent */
  210. X
  211. X
  212. X
  213. Xputword(p)
  214. Xchar *p;
  215. X{
  216. X    int plen;
  217. X
  218. X    plen = strlen(p);
  219. X    if ((olp - oline) + spaces + plen > maxlen) {
  220. X        if ((jflag) && (holecnt))
  221. X            justifyline();
  222. X        putline();
  223. X    }
  224. X    if (spaces) {
  225. X        holeptr[++holecnt] = olp;
  226. X        for (  ;  (spaces > 0);  spaces--)
  227. X            *olp++ = ' ';
  228. X    }
  229. X    spaces = 1 + endofsentence(p, plen);
  230. X    while (*p)
  231. X        *olp++ = *p++;
  232. X}  /* putword */
  233. X
  234. X
  235. X
  236. Xjustifyline()
  237. X{
  238. X    int n;
  239. X    char *fp;
  240. X    char *tp;
  241. X    
  242. X    dir = (! (dir));
  243. X    fp = olp - 1;
  244. X    olp = &oline[maxlen];
  245. X    tp = olp - 1;
  246. X    while (tp > fp) {
  247. X        while (fp >= holeptr[holecnt])
  248. X            *tp-- = *fp--;
  249. X        if (dir)
  250. X            n = ((tp - fp) - 1) / holecnt + 1;
  251. X        else
  252. X            n = (tp - fp) / holecnt;
  253. X        while (n--) 
  254. X            *tp-- = ' ';
  255. X        holecnt--;
  256. X    }
  257. X}  /* justifyline */
  258. X
  259. X
  260. X
  261. Xputline()
  262. X{
  263. X    *olp = '\0';
  264. X    if (*oline)
  265. X        printf("%*s\n", offset + strlen(oline), oline);
  266. X    *oline = '\0';
  267. X    olp = oline;
  268. X    spaces = 0;
  269. X    holecnt = 0;
  270. X}  /* putline */
  271. X
  272. X
  273. X
  274. Xskipline(n)
  275. Xint n;
  276. X{
  277. X    putline();
  278. X    for (  ;  (n > 0);  n--)
  279. X        printf("\n");
  280. X}  /* skipline */
  281. X
  282. X
  283. X
  284. Xint endofsentence(p, plen)
  285. Xchar *p;
  286. Xint plen;
  287. X{
  288. X    if (plen < 3)
  289. X        return(FALSE);
  290. X    if (!strchr(".:?!", *(p + plen - 1)))
  291. X        return(FALSE);
  292. X    if (abbr(p))
  293. X        return(FALSE);
  294. X    return(TRUE);
  295. X}  /* endofsentence */
  296. X
  297. X
  298. X
  299. Xint abbr(s)
  300. Xchar *s;
  301. X{
  302. X    char *p, *q, *r;
  303. X
  304. X    while (*s == '(') s++;
  305. X    q = ".i.e.g.dr.mr.mrs.st.";
  306. X    for (  ;  (*q);  q++) {
  307. X        p = q;
  308. X        r = s;
  309. X        while ((*r) && (*p++ == (*r++ | 0x20))) ;
  310. X        if (!*r)
  311. X            return(TRUE);
  312. X    }
  313. X    return(FALSE);
  314. X}  /* abbr */
  315. X
  316. X
  317. X
  318. Xchar *basename(s)
  319. Xchar *s;
  320. X{
  321. X    char *p;
  322. X
  323. X    if (p = strrchr(s, '/'))
  324. X        return(++p);
  325. X    else
  326. X        return(s);
  327. X}  /* basename */
  328. X
  329. X
  330. X
  331. Xint max(a, b)
  332. Xint a, b;
  333. X{
  334. X    return((a > b) ? a : b);
  335. X}  /* max */
  336. X
  337. ----enD-oF-fmt.c----
  338. echo x - Makefile 1>&2
  339. sed 's/^X//' >Makefile <<'----enD-oF-Makefile----'
  340. X# file: fmt/Makefile
  341. X# 04/88  bgray
  342. X
  343. X
  344. XBINDIR = /usr/lbin
  345. XMANDIR = /usr/man/u_man/man1
  346. XCATMAN = /usr/catman/u_man/man1
  347. X
  348. XLIBS =
  349. XCFLAGS = -O
  350. XLDFLAGS = -s
  351. XCC = /bin/cc
  352. XRM = /bin/rm -f
  353. XMV = /bin/mv -f
  354. XCP = /bin/cp
  355. X
  356. XFORMATTER = nroff
  357. X
  358. XOBJS =
  359. X
  360. X
  361. Xall: fmt fmt.doc
  362. X
  363. Xfmt: fmt.c
  364. X    $(CC) $(LDFLAGS) -o fmt fmt.c
  365. X
  366. Xfmt.doc: fmt.1
  367. X    ${FORMATTER} -man fmt.1 > fmt.doc 
  368. X
  369. Xinstall: all
  370. X    $(CP) fmt $(BINDIR)
  371. X    chown bin $(BINDIR)/fmt
  372. X    chgrp bin $(BINDIR)/fmt
  373. X    chmod 755 $(BINDIR)/fmt
  374. X    $(CP) fmt.doc $(CATMAN)/fmt.1
  375. X    chown bin $(CATMAN)/fmt.1
  376. X    chgrp bin $(CATMAN)/fmt.1
  377. X    chmod 644 $(CATMAN)/fmt.1
  378. X
  379. ----enD-oF-Makefile----
  380. exit
  381.  
  382. Bill Gray
  383. --
  384. bgray@marque.mu.edu    { uunet | uwvax }!marque.mu.edu!bgray
  385.