Subject: v06i016: halign - line up columns (halign) Newsgroups: mod.sources Approved: rs@mirror.UUCP Submitted by: talcott!mcgill-vision!garfield!mouse (der Mouse) Mod.sources: Volume 6, Issue 16 Archive-name: halign Here is a handy little program I wrote...it produces nicely lined-up columns from messy out-of-alignment columns. For example, it can turn 3 9 9 81 81 6561 6561 43046721 43046721 (overflow) into 3 9 9 81 81 6561 6561 43046721 43046721 (overflow) Read the man page for a full description. --------------------------------cut here-------------------------------- #! /bin/sh # # Shar: Shell Archiver # # This archive created Wed Jun 11 04:53:03 1986 # Run this through sh to create: # halign.1 # halign.c echo x - halign.1 \(2051 characters\) sed 's/^X//' > halign.1 << \SHAR_EOF X.TH HALIGN 1 "11 June 1986" X.UC 4 X.SH NAME Xhalign - produce lined-up columns X.SH SYNOPSIS X.nf X.ft B Xhalign [lrc][\fIn\fP] ... X.PP X.fi X.SH DESCRIPTION X\fIHalign\fP is a program to produce nicely lined-up columns from almost any Xsort of columnized input. For example, if you have a program which prints Xlines with two numbers on each line, halign can adjust things so they line up Xnicely. For example, let us suppose you have a program (here called `foo') Xwhich produces the following output: X.PP X.in +8 X.nf X% foo X3 9 X9 81 X81 6561 X6561 43046721 X43046721 (overflow) X.PP X.fi XNow, to get things lined up and right-justified: X.PP X.in +8 X.nf X% foo | halign r r X 3 9 X 9 81 X 81 6561 X 6561 43046721 X43046721 (overflow) X.PP X.fi XEach argument to halign must be a letter followed by an optional number. The Xletter specifies how the column is to be aligned; \fIl\fP specifies that the Xcolumn is to be set flush left, \fIr\fP indicates flush right, and \fIc\fP Xspecifies centering. Of course, centering cannot always be exact; if unable Xto center an entry exactly, halign will put the extra space on the right. If Xthe number is given, it is a minimum width for the column; normally, a column Xis only as wide as necessary to contain the widest entry in that column. For Xexample, \fIl10\fP specifies a column at least 10 characters wide (though it Xwill be wider if there is an entry wider than 10 characters), with the entry Xset at the left and padded on the right (if necessary). X.SH NOTES XHalign must of course read all of its input before printing anything; the Xinput is stored in files on /tmp (one file per column). Because these files Xare all kept open at once, halign will break if more than NFILE-3 (currently X17 on most UNIX systems) columns are specified. X.SH BUGS XHalign thinks control characters, such as backspace and escape, are normal Xprinting characters, so the columns may not line up if the entries contain Xsuch characters. X.SH AUTHOR Xder Mouse (Mike Parker, mcgill-vision!mouse), September, 1985. SHAR_EOF if test 2051 -ne "`wc -c halign.1`" then echo shar: error transmitting halign.1 \(should have been 2051 characters\) fi echo x - halign.c \(6462 characters\) sed 's/^X//' > halign.c << \SHAR_EOF X/* X * halign - program to produce lined-up columns X * X * Halign reads input in the form of columns of data separated by whitespace; X * the output is similar except that all the columns line up. This was X * inspired by the common uses of the \halign command in TeX; knowing how X * TeX's \halign command works will make this program almost self-evident. X * X * Usage is X * X * halign [clr][n] ... X * X * where each argument corresponds to one column in the input. X * X * The letter indicates how the column is to be justified; r indicates X * flush-right, l indicates flush-left, and c indicates centered. Of X * course, centering cannot be perfect without half-character resolution; if X * an item cannot be centered exactly the extra space will go on the right. X * X * The number n, if given, indicates a minimum width for the column. The X * default is to make the column just wide enough to contain the widest X * entry; if this entry is narrower than n the column will be n characters X * wide anyway. X * X * Halign always puts one space between columns on output. X * X * All adjusting is done with spaces; if tabs are desired pipe the output X * through /usr/ucb/unexpand -a. X * X * Examples: X * X * % cat x X * root 0 10 / /bin/csh X * mailer 0 10 / /bin/csh X * daemon 1 666 / X * uucp 66 1 /usr/spool/uucppublic /usr/lib/uucp/uucico X * wnj 8 10 /u1/guest/wnj /bin/csh X * mckusick 9 10 /u1/guest/mckusick /bin/csh X * % halign l l l l l < x X * root 0 10 / /bin/csh X * mailer 0 10 / /bin/csh X * daemon 1 666 / X * uucp 66 1 /usr/spool/uucppublic /usr/lib/uucp/uucico X * wnj 8 10 /u1/guest/wnj /bin/csh X * mckusick 9 10 /u1/guest/mckusick /bin/csh X * % halign l r5 r5 c c < x X * root 0 10 / /bin/csh X * mailer 0 10 / /bin/csh X * daemon 1 666 / X * uucp 66 1 /usr/spool/uucppublic /usr/lib/uucp/uucico X * wnj 8 10 /u1/guest/wnj /bin/csh X * mckusick 9 10 /u1/guest/mckusick /bin/csh X * X * Halign must of course read to the end of its input before generating any X * output, so that it knows how wide the columns must be. The input column X * entries are copied into temporary files (on /tmp). X * X * The current incarnation cannot deal with more than about 17 columns; this X * is because a separate temporary file is used for each column, so not more X * than NFILE-3 (3 for stdin/stdout/stderr) columns will work. X * X * Copyright 1985 by Mike Parker. Permission is granted for redistribution X * of this code, or modified versions of it, for any purpose as long as this X * notice remains intact and that no additional restrictions are placed on X * further redistribution. I have tried to make sure that this program X * functions as the above description indicates, but I make no guarantees X * that this code does anything useful, or even that it does not do anything X * harmful. X * X * If you find any bugs I would appreciate hearing, especially if you also X * fix them. Write to X * {ihnp4,decvax,akgua,utzoo,etc}!utcsri!mcgill-vision!mouse X */ X X#include X#include X#include X Xchar *malloc(); Xchar *realloc(); X#define NEW(type) ((type *) malloc(sizeof(type))) X#define OLD(x) free((char *) x) X Xchar **argvec; X Xtypedef struct _spec { X char spec; X int tfd; X FILE *tf; X char *buf; X int maxwidth; } SPEC; X Xint errs; Xint ncols; Xint nlines; XSPEC *spec; Xchar tfilename[80]; X Xmain(ac,av) Xint ac; Xchar **av; X{ X int i; X int j; X int k; X char *cp; X char *dp; X char c; X int inspace; X int colwidth; X X argvec = av; X errs = 0; X ncols = ac - 1; X if (ncols <= 0) X { fprintf(stderr,"Usage: %s [clr][n] [clr][n] ...\n",argvec[0]); X exit(1); X } X spec = (SPEC *) malloc(ncols*sizeof(SPEC)); X sprintf(tfilename,"/tmp/halign.%d",getpid()); X av ++; X for (i=0;i= 0) X { spec[i].tf = fdopen(spec[i].tfd,"r+"); X if (! spec[i].tf) X { fprintf(stderr,"%s: cannot fdopen, serious failure: ",argvec[0]); X perror(0); X errs ++; X } X } X } X if (errs) X { exit(1); X } X nlines = 0; X i = 0; X inspace = 1; X colwidth = 0; X while (1) X { c = getchar(); X if (feof(stdin)) X { if ((i > 0) || (colwidth > 0)) X { c = '\n'; X } X else X { break; X } X } X else if (isspace(c)) X { if (! inspace) X { inspace = 1; X if (colwidth > spec[i].maxwidth) X { spec[i].maxwidth = colwidth; X } X if (i < ncols-1) X { putc('\n',spec[i].tf); X i ++; X } X colwidth = 0; X } X if (c == '\n') X { for (;i0;nlines--) X { for (i=0;i 0) X { spec[i].buf[--j] = '\0'; X } X k = spec[i].maxwidth - j; X cp = spec[i].buf; X cp[spec[i].maxwidth] = '\0'; X spacefill(cp+j,k); X switch (spec[i].spec) X { case 'l': X break; X case 'c': X k /= 2; X /* fall through */ X case 'r': X cp += j; X dp = cp + k; X for (;j>0;j--) X { *--dp = *--cp; X } X for (;k>0;k--) X { *--dp = ' '; X } X break; X } X if (i) X { putchar(' '); X } X fputs(spec[i].buf,stdout); X } X putchar('\n'); X } X} X Xspacefill(ptr,nb) Xregister char *ptr; Xregister int nb; X{ X for (;nb>0;nb--) X { *ptr++ = ' '; X } X} SHAR_EOF if test 6462 -ne "`wc -c halign.c`" then echo shar: error transmitting halign.c \(should have been 6462 characters\) fi exit 0 # end of shell archive