home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1824 < prev    next >
Internet Message Format  |  1990-12-28  |  24KB

  1. From: smidt@fy.chalmers.se (Peter Smidt)
  2. Newsgroups: alt.sources
  3. Subject: mfold - Maaniker's fold and column making
  4. Message-ID: <1990Sep15.100447.5593@fy.chalmers.se>
  5. Date: 15 Sep 90 10:04:47 GMT
  6.  
  7. Submitted-by: smidt@sponsz.cd.chalmers.se
  8. Archive-name: mfold.shar/part01
  9.  
  10. Mfold have previously been published in alt.sources.
  11. A bug have been fixed and a better documentation have
  12. been created. There have been some small changes to
  13. the man pages and the makefile.
  14.  
  15. ---- Cut Here and feed the following to sh ----
  16. #!/bin/sh
  17. # This is mfold.shar, a shell archive (produced by shar 3.49)
  18. # To extract the files from this archive, save it to a file, remove
  19. # everything above the "!/bin/sh" line above, and type "sh file_name".
  20. #
  21. # made 09/15/1990 08:55 UTC by smidt@sponsz
  22. # Source directory /nfs/alcazar/u/smidt/src/mfold/exp
  23. #
  24. # existing files will NOT be overwritten unless -c is specified
  25. # This format requires very little intelligence at unshar time.
  26. # "if test", "echo", "true", and "sed" may be needed.
  27. #
  28. # This shar contains:
  29. # length  mode       name
  30. # ------ ---------- ------------------------------------------
  31. #     87 -rw-r--r-- makefile
  32. #   3626 -rw-r--r-- mfold.1
  33. #  13693 -rw-r--r-- mfold.c
  34. #   2613 -rw-r--r-- mfold_doc
  35. #    499 -rw-r--r-- README
  36. #
  37. # ============= makefile ==============
  38. if test -f 'makefile' -a X"$1" != X"-c"; then
  39.     echo 'x - skipping makefile (File already exists)'
  40. else
  41. echo 'x - extracting makefile (Text)'
  42. sed 's/^X//' << 'SHAR_EOF' > 'makefile' &&
  43. Xmfold: mfold.o
  44. X    cc mfold.o -o mfold
  45. X    rm -f mfold.o
  46. X
  47. Xmfold.o: mfold.c
  48. X    cc -c mfold.c -O
  49. SHAR_EOF
  50. true || echo 'restore of makefile failed'
  51. fi
  52. # ============= mfold.1 ==============
  53. if test -f 'mfold.1' -a X"$1" != X"-c"; then
  54.     echo 'x - skipping mfold.1 (File already exists)'
  55. else
  56. echo 'x - extracting mfold.1 (Text)'
  57. sed 's/^X//' << 'SHAR_EOF' > 'mfold.1' &&
  58. X.\" Public Domain 1990 of Chalmers Computer Society.
  59. X.\"
  60. X.\"    @(#)mfold.1    (G|teborg) 1990-09-11
  61. X.\"
  62. X.TH MFOLD 1 "September 11, 1990"
  63. X.UC
  64. X.SH NAME
  65. Xmfold \- Maaniker's fold and column making
  66. X.SH SYNOPSIS
  67. X.B mfold
  68. X[
  69. X.B \-sn -ln -en -wn -f -d
  70. X.B -rn
  71. X.B -tn -cn -pn -n -L -Bn
  72. X.B -D '<text>' -i '<text>'
  73. X]
  74. X.SH DESCRIPTION
  75. X.I Mfold
  76. Xreads text files from standard input and writes to standard
  77. Xoutput.
  78. X.I Mfold
  79. Xconcatenates and folds the text in one or more columns
  80. Xwithout breaking in the middle of a word. Tabs and newlines are
  81. Xconverted to blank space. Multiple blank space is substituted with
  82. Xone single blank space. Some flags don't do anything if they aren't
  83. Xused together with either '-c' or '-d'.
  84. X.PP
  85. XThere is a limited amount of options:
  86. X.TP
  87. X.B \-sn
  88. XStart line for
  89. X.I mfold,
  90. Xwhere n is the line number. The preceding text
  91. Xis passed through
  92. X.I mfold
  93. Xwithout being changed. If an end-of-file character is encountered
  94. Xbefore line n,
  95. X.I mfold
  96. Xwill end the execution.
  97. X.TP
  98. X.B \-i
  99. XInsert text at the beginning of every line, or with '\-c', at every
  100. Xcolumn. This option as the last flag doesn't need any argument if
  101. Xa null argument is wanted. A space is required between the flag
  102. Xand the argument. Tabs may be present in the insert text. Default
  103. Xinsert text is a tab.
  104. X.TP
  105. X.B \-ln
  106. XLenght for output lines, excluding any insert text and excluding
  107. Xany delimiter text. Where n is the number of characters. Default
  108. Xlength is 76.
  109. X.TP
  110. X.B \-en
  111. X.I Mfold
  112. Xwill end the folding at input line n. Text coming after this
  113. Xline is not being changed by
  114. X.I mfold.
  115. X.TP
  116. X.B \-wn
  117. XSpecify the width n, of the not folded lines to avoid overrunning the
  118. Xinternal reverse buffer when using the '-d' flag. '-w' is not always
  119. Xprovided. Run
  120. X.I mfold,
  121. Xlook at the result and decide if you want to specify the full
  122. Xwidth. Default is 80 characters.
  123. X.TP
  124. X.B \-f
  125. XFill each line with blank space to its full line length.
  126. X.TP
  127. X.B \-rn
  128. XFills the lines with extra blank space up to an amount of
  129. Xn blank spaces, to get an even right margin. The words will get
  130. Xa little random placement on the lines.
  131. X.TP
  132. X.B \-d
  133. XReverse the text for dyslexics.
  134. X.TP
  135. X.B \-tn
  136. XExpanding the tabs to spaces. Where n is the number of
  137. Xspaces. Default is four spaces. Use only with '-d'.
  138. X.TP
  139. X.B \-cn
  140. XSpecifies columns where n is the number of columns. Text is inserted at
  141. Xevery column.
  142. X.TP
  143. X.B \-pn
  144. XSpecifies page length n, meaningfull when used with the '-c'
  145. Xflag. Default are 40 lines per page.
  146. X.TP
  147. X.B \-n
  148. XMany newlines in a row is not substituted with one single 
  149. Xblank space, which is otherwise the default. Instead they are
  150. Xleft without change, but may be put in a separate column.
  151. X.TP
  152. X.B \-L
  153. XWrite a ^L (newpage) at the end of each page. Use with '-c'.
  154. X.TP
  155. X.B \-Bn
  156. XWrite n newlines at the bottom (end) of the page. Default is
  157. Xone newline. Use when the number of columns are greater then one.
  158. X.TP
  159. X.B \-D
  160. XSpecify column delimiter. Default is three blank spaces. Tabs may be
  161. Xpresent in the delimiter. This option as the last flag doesn't need
  162. Xany argument if a null argument is wanted.
  163. X.SH ERRORS
  164. XYou will notice them, when you give bad flags.
  165. X.SH AUTHOR
  166. XPeter Smidt, Chalmers Computer Society.
  167. X.SH SEE ALSO
  168. Xawk(1), sed(1), lex(1), nroff(1), fmt(1), fold(1), rev(1)
  169. X.SH BUGS
  170. XIf underlining is present it will get messed up with the
  171. Xtext. The '-c' and the '-d' flags
  172. X.I may
  173. Xproduce some extra
  174. Xunnecessary blank space at the end of the lines. When
  175. Xa word is longer than the line length, the word may be
  176. Xcut at an inappropriate place. Everything except blank space,
  177. Xnewline and tab counts as parts of words.
  178. X.SH BUG REPORTS TO
  179. XPeter Smidt  smidt@cd.chalmers.se    or
  180. X.br
  181. XPeter Smidt  smidt@fy.chalmers.se
  182. SHAR_EOF
  183. true || echo 'restore of mfold.1 failed'
  184. fi
  185. # ============= mfold.c ==============
  186. if test -f 'mfold.c' -a X"$1" != X"-c"; then
  187.     echo 'x - skipping mfold.c (File already exists)'
  188. else
  189. echo 'x - extracting mfold.c (Text)'
  190. sed 's/^X//' << 'SHAR_EOF' > 'mfold.c' &&
  191. X#include <stdio.h>
  192. X#include <curses.h>
  193. X#include <strings.h>
  194. X
  195. X#define DEF_LINE_LEN    76
  196. X#define DEF_WORD_LEN    40
  197. X#define DEF_TAB_LEN        4
  198. X#define FULL_WIDTH        80
  199. X#define PAGE_LEN        40
  200. X#define POS1            1
  201. X#define DO_ALL1 \
  202. X    col_pos = POS1;\
  203. X    for ( doo = 0; doo < ins_len; doo++ ) {\
  204. X        putcolu(insert[doo]);\
  205. X    }
  206. X#define BOT_LINES        1
  207. X#define STR                15
  208. X#define TEST_STR        25
  209. X#define GET_NUM_STR        25
  210. X
  211. Xint colu_chars, colu_lines;
  212. Xint page_len = PAGE_LEN, columns = 1, lin = 0, bot_lines = BOT_LINES;
  213. Xint got_newpage = FALSE, got_dyslexi = FALSE, full_line = FULL_WIDTH;
  214. Xint tab_len = DEF_TAB_LEN, ins_tabs = 0, del_len, got_fill = FALSE;
  215. Xint got_mrandom = FALSE, got_bot = FALSE, ins_len, mrandom = 1;
  216. Xchar **cur_page, *malloc(), *delim = "   ", **glob_argv;
  217. X
  218. Xmain(argc, argv)
  219. Xchar *argv[];
  220. Xint argc;
  221. X{
  222. X    int col_pos = 1, j = 0, k, in, doo, line_len = DEF_LINE_LEN, row_count = 1;
  223. X    int cnt_nwl = 0, new_wo_le, dummy = TRUE, end = 2;
  224. X    int width = FULL_WIDTH, err = FALSE, in_2 = 0, in_3 = 0, tmp_chars = 0;
  225. X    char *cur_word, *insert = "\t", *s = "Bad option '  '";
  226. X    int index, start = 1, word_len = DEF_WORD_LEN;
  227. X    int got_start = FALSE, got_line_len = FALSE, got_insert = FALSE;
  228. X    int got_tab_len = FALSE, got_end = FALSE, got_width = FALSE;
  229. X    int got_columns = FALSE, got_page_len = FALSE;
  230. X    int got_newlines = FALSE, got_delim = FALSE;
  231. X    int index_start = 0, index_insert = 0, index_line_len = 0;
  232. X    int index_tab_len = 0, index_end = 0, index_width = 0;
  233. X    int index_columns = 0, index_page_len = 0, index_delim = 0;
  234. X    int index_bot = 0, index_mrandom = 0;
  235. X    glob_argv = argv;
  236. X    for ( index = 1; index < argc; index++) {
  237. X        if ( argv[index][0] != '-' ) {
  238. X            if ( index != 1 ) {
  239. X                if ( argv[index - 1][0] == '-' ) {
  240. X                    if ( argv[index - 1][1] == 'i' ) {
  241. X                        index_insert = index;
  242. X                    } else if ( argv[index - 1][1] == 'D' ) {
  243. X                        index_delim = index;
  244. X                    } else {
  245. X                        err = TRUE;
  246. X                    }
  247. X                } else {
  248. X                    err = TRUE;
  249. X                }
  250. X            } else {
  251. X                err = TRUE;
  252. X            }
  253. X            if ( err ) {
  254. X                fprintf(stderr, "Flag '%s' not allowed.\n", argv[index]);
  255. X                usage(11);
  256. X            }
  257. X        }
  258. X        doo = index_insert != index && index_delim != index;
  259. X        switch ( argv[index][1] ) {
  260. X            case 'i':
  261. X                check_it(&got_insert, "-i", 8, doo, &index_insert, index + 1);
  262. X                break;
  263. X            case 's':
  264. X                check_it(&got_start, "-s", 9, doo, &index_start, index);
  265. X                break;
  266. X            case 'l':
  267. X                check_it(&got_line_len, "-l", 10, doo, &index_line_len, index);
  268. X                break;
  269. X            case 'e':
  270. X                check_it(&got_end, "-e", 10, doo, &index_end, index);
  271. X                break;
  272. X            case 'w':
  273. X                check_it(&got_width, "-w", 10, doo, &index_width, index);
  274. X                break;
  275. X            case 'r':
  276. X                check_it(&got_mrandom, "-r", 37, doo, &index_mrandom, index);
  277. X                break;
  278. X            case 'd':
  279. X                check_it(&got_dyslexi, "-d", 11, doo, &dummy, index);
  280. X                break;
  281. X            case 't':
  282. X                check_it(&got_tab_len, "-t", 13, doo, &index_tab_len, index);
  283. X                break;
  284. X            case 'c':
  285. X                check_it(&got_columns, "-c", 15, doo, &index_columns, index);
  286. X                break;
  287. X            case 'p':
  288. X                check_it(&got_page_len, "-p", 16, doo, &index_page_len, index);
  289. X                break;
  290. X            case 'B':
  291. X                check_it(&got_bot, "-B", 17, doo, &index_bot, index);
  292. X                break;
  293. X            case 'f':
  294. X                check_it(&got_fill, "-f", 33, doo, &dummy, index);
  295. X                break;
  296. X            case 'n':
  297. X                check_it(&got_newlines, "-n", 18, doo, &dummy, index);
  298. X                break;
  299. X            case 'L':
  300. X                check_it(&got_newpage, "-L", 19, doo, &dummy, index);
  301. X                break;
  302. X            case 'D':
  303. X                check_it(&got_delim, "-D", 36, doo, &index_delim, index + 1);
  304. X                break;
  305. X            case '\0':
  306. X                write_err(doo, "Empty flag '-'", 31);
  307. X                break;
  308. X            default:
  309. X                s[12] = argv[index][0];
  310. X                s[13] = argv[index][1];
  311. X                write_err(doo, s, 20);
  312. X                break;
  313. X        }
  314. X    }
  315. X    ext_num(got_start, &start, argv[index_start],
  316. X    "Line zero, for start, not allowed", 21);
  317. X    ext_num(got_page_len, &page_len, argv[index_page_len],
  318. X    "Page length zero, not allowed", 24);
  319. X    ext_num(got_tab_len, &tab_len, argv[index_tab_len],
  320. X    "Tab length zero, not allowed", 27);
  321. X    ext_num(got_line_len, &line_len, argv[index_line_len],
  322. X    "Line length zero, not allowed", 25);
  323. X    write_err(line_len < 2, "Too short line length, not allowed", 32);
  324. X    ext_num(got_end, &end, argv[index_end],
  325. X    "End length zero, not allowed", 25);
  326. X    write_err(got_end && end <= start,
  327. X    "End not greater than start line, not allowed", 33);
  328. X    ext_num(got_width, &width, argv[index_width],
  329. X    "Line length zero, not allowed", 25);
  330. X    ext_num(got_mrandom, &mrandom, argv[index_mrandom],
  331. X    "Zero fill length, not allowed", 36);
  332. X    if ( got_bot ) get_num(&bot_lines, argv[index_bot]);
  333. X    if ( got_insert ) {
  334. X        if ( index_insert < argc ) {
  335. X            insert = argv[index_insert];
  336. X        } else {
  337. X            insert = "";
  338. X        }
  339. X    }
  340. X    if ( got_delim ) {
  341. X        if ( index_delim < argc ) {
  342. X            delim = argv[index_delim];
  343. X        } else {
  344. X            delim = "";
  345. X        }
  346. X    }
  347. X    del_len = strlen(delim);
  348. X    if ( got_columns ) {
  349. X        get_num(&columns, argv[index_columns]);
  350. X        write_err(columns == 0, "columns count zero, not allowed", 26);
  351. X        write_err(line_len % columns,
  352. X        "Lines not an even multiple of columns length", 27);
  353. X    }
  354. X/* colu_chars is the chars on one column. colu_lines is the total number of
  355. Xlines in all the columns in one page. page_len is the number of lines in one
  356. Xpage. */
  357. X    ins_len = strlen(insert);
  358. X    colu_chars = line_len / columns + ins_len;
  359. X    colu_lines = page_len * columns;
  360. X    write_err( !(cur_page = (char**) malloc(colu_lines * sizeof(char*))),
  361. X    "Can not malloc that page length", 39);
  362. X    for ( in = 0; in < colu_lines; in++ ) {
  363. X        if ( !(cur_page[in] = malloc(colu_chars * sizeof(char))) ) {
  364. X            write_err(TRUE, "Can not malloc that page length", 40);
  365. X        }
  366. X    }
  367. X    for ( doo = 0; doo < ins_len; doo++ ) {
  368. X        if ( insert[doo] == '\t' ) {
  369. X            ins_tabs++;
  370. X        }
  371. X    }
  372. X    full_line = line_len + ins_len * columns + del_len * ( columns - 1);
  373. X    full_line += ( tab_len - 1 ) * columns * ins_tabs;
  374. X    line_len = line_len / columns;
  375. X    word_len = line_len;
  376. X    write_err( !(cur_word = malloc(word_len * sizeof(char))),
  377. X    "Can not malloc that word (line?) length", 41);
  378. X    if ( width > full_line ) initrev(width);
  379. X    else initrev(full_line);
  380. X    while ( row_count < start ) {
  381. X        in = getchar();
  382. X        if ( in == EOF ) exit(0);
  383. X        if ( in == '\n' ) {
  384. X            if ( got_dyslexi ) {
  385. X                flushrev();
  386. X            }
  387. X            putchar('\n');
  388. X            row_count++;
  389. X        } else if ( got_dyslexi ) {
  390. X            putrev(in);
  391. X        } else {
  392. X            putchar(in);
  393. X        }
  394. X    }
  395. X    if ( !got_end ) end = row_count + 1;
  396. X    lin = ( ( start - 1 ) % page_len ) * columns;
  397. X    new_wo_le = word_len - 1;
  398. X/* ******************** The fold follows ******************** */
  399. X    DO_ALL1
  400. X    while ( 1 ) {
  401. X        if ( row_count > end ) {
  402. X            in = EOF;
  403. X        } else if ( j == new_wo_le && tmp_chars == 0 ) {
  404. X            in_2 = getchar();
  405. X            if ( in_2 == ' ' || in_2 == '\n' || in_2 == '\t' ) {
  406. X                in = in_2;
  407. X            } else {
  408. X                in_3 = getchar();
  409. X                if ( in_3 == ' ' || in_3 == '\n' || in_3 == '\t' ) {
  410. X                    in = in_2;
  411. X                    tmp_chars = 1;
  412. X                } else {
  413. X                    in = '-';
  414. X                    tmp_chars = 2;
  415. X                }
  416. X            }
  417. X        } else if ( j == word_len ) { 
  418. X            in = ' ';
  419. X        } else if ( tmp_chars > 0 ) {
  420. X            if ( tmp_chars == 1 && j == 0 ) {
  421. X                in = in_3;
  422. X                tmp_chars = 0;
  423. X            } else if ( tmp_chars == 1 && j == 1 ) {
  424. X                in_2 = in_3;
  425. X                tmp_chars = 0;
  426. X                if ( line_len != 2 || in_2 == ' ' || in_2 == '\n'
  427. X                || in_2 == '\t' ) {
  428. X                    in = in_2;
  429. X                } else {
  430. X                    in_3 = getchar();
  431. X                    if ( in_3 == ' ' || in_3 == '\n' || in_3 == '\t' ) {
  432. X                        in = in_2;
  433. X                        tmp_chars = 1;
  434. X                    } else {
  435. X                        in = '-';
  436. X                        tmp_chars = 2;
  437. X                    }
  438. X                }
  439. X            } else {
  440. X                in = in_2;
  441. X                tmp_chars = 1;
  442. X            }
  443. X        } else { 
  444. X            in = getchar();
  445. X        }
  446. X        if ( cnt_nwl > 1 && got_newlines && in != '\n' ) {
  447. X            putcolu('\n');
  448. X            while ( --cnt_nwl ) {
  449. X                putcolu(' ');
  450. X                putcolu('\n');
  451. X            }
  452. X            DO_ALL1
  453. X        }
  454. X        if ( in != '\n' ) cnt_nwl = 0;
  455. X        if ( in == '\n' || in == '\t' ) {
  456. X            if ( in == '\n' ) {
  457. X                if ( got_end ) row_count++;
  458. X                if ( got_newlines ) cnt_nwl++;
  459. X            }
  460. X            in = ' ';
  461. X        }
  462. X        if ( in == EOF ) {
  463. X            putcolu('\n');
  464. X            flushpage(columns);
  465. X            if ( !got_end ) exit(0);
  466. X            else break;
  467. X        }
  468. X        if ( in != ' ' ) {
  469. X            write_err( j >= word_len || j < 0 ,
  470. X            "Internal error or to long text word", 3);
  471. X            cur_word[j++] = in;
  472. X        } else {
  473. X            if ( col_pos != POS1 && (col_pos + j) <= line_len &&
  474. X            j != 0 ) {
  475. X                putcolu(' ');
  476. X                col_pos++;
  477. X            } else if ( (col_pos + j) > line_len && col_pos != POS1 ) {
  478. X                putcolu('\n');
  479. X                DO_ALL1
  480. X            }
  481. X            for ( k = 0; k < j; k++ ) {
  482. X                putcolu(cur_word[k]);
  483. X            }
  484. X            col_pos += j;
  485. X            j = 0;
  486. X        }
  487. X    }
  488. X/* ************** End of the fold ****************** */
  489. X    if ( cnt_nwl > 1 && got_newlines ) {
  490. X        while ( cnt_nwl-- ) putcolu('\n');
  491. X    }
  492. X    while ( 1 ) {
  493. X        in = getchar();
  494. X        if ( in == EOF ) exit(0);
  495. X        if ( in == '\n' ) {
  496. X            if ( got_dyslexi ) {
  497. X                flushrev();
  498. X            }
  499. X            putchar('\n');
  500. X        } else if ( got_dyslexi ) {
  501. X            putrev(in);
  502. X        } else {
  503. X            putchar(in);
  504. X        }
  505. X    }
  506. X}
  507. X
  508. Xchar *buff;
  509. Xint gl_i = 0, len;
  510. X/* lin is the line index in the one long column before it is pasted out onto the
  511. Xpage. len is the lenght of each line in the one long column. */
  512. X
  513. Xputrev(c)
  514. X{
  515. X    int i;
  516. X
  517. X    if ( gl_i >= 0 && gl_i < len ) {
  518. X        if ( c != '\t' ) {
  519. X            buff[gl_i++] = c;
  520. X        } else {
  521. X            int k = tab_len - gl_i % tab_len;
  522. X            for ( i = 0; i < k; i++ ) {
  523. X                putrev(' ');
  524. X            }
  525. X        }
  526. X    } else {
  527. X        write_err(TRUE,
  528. X        "Internal error in reverse buffer. Specify bigger buffer", 4);
  529. X    }
  530. X}
  531. X
  532. Xflushrev() {
  533. X    int i;
  534. X
  535. X    for ( i = len - 1; i > 0; i--) {
  536. X        if ( buff[i] != '\0' ) {
  537. X            putchar(buff[i]);
  538. X            buff[i] = '\0';
  539. X        } else {
  540. X            putchar(' ');
  541. X        }
  542. X    }
  543. X    if ( buff[0] != ' ' ) {
  544. X        putchar(buff[0]);
  545. X    }
  546. X    gl_i = 0;
  547. X}
  548. X
  549. Xinitrev(l)
  550. Xint l;
  551. X{
  552. X    int i;
  553. X
  554. X    len = l;
  555. X    write_err( !(buff = malloc(len * sizeof(char))),
  556. X    "Can not malloc that internal reverse buffer length", 42);
  557. X    for ( i = 0; i < len; i++ ) {
  558. X        buff[i] = '\0';
  559. X    }
  560. X}
  561. X
  562. Xcheck_it(got_flag, s, err, boole, index_flag, index)
  563. Xint *got_flag, *index_flag;
  564. Xchar *s;
  565. X{
  566. X    test(*got_flag, s, err);
  567. X    test_two(boole, index_flag, index, got_flag);
  568. X}
  569. X
  570. Xtest(flag, s1, err)
  571. Xchar *s1;
  572. X{
  573. X    char *s2 = "Multiple '  ' not allowed";
  574. X
  575. X    s2[10] = s1[0];
  576. X    s2[11] = s1[1];
  577. X    write_err(flag, s2, err);
  578. X}
  579. X
  580. Xtest_two(boole, index_flag, index, got_flag)
  581. Xint *index_flag, *got_flag;
  582. X{
  583. X    if ( boole ) {
  584. X        if ( *index_flag && glob_argv[index][2] != '\0' ) {
  585. X            fprintf(stderr, "Flag '%c%c' doesn't want any argument.\n",
  586. X            glob_argv[index][0], glob_argv[index][1]);
  587. X            usage(35);
  588. X        }
  589. X        *index_flag = index;
  590. X        *got_flag = TRUE;
  591. X    }
  592. X}
  593. X
  594. Xwrite_err(flag, s, err)
  595. Xchar *s;
  596. X{
  597. X    if ( flag ) {
  598. X        fprintf(stderr, "%s.\n", s);
  599. X        usage(err);
  600. X    }
  601. X}
  602. X
  603. Xext_num(bulle, tal, arg, s, err)
  604. Xint *tal;
  605. Xchar *arg, *s;
  606. X{
  607. X    if ( bulle ) {
  608. X        get_num(tal, arg);
  609. X        write_err(*tal == 0, s, err);
  610. X    }
  611. X}
  612. X
  613. Xget_num(number, argv) 
  614. Xint *number;
  615. Xchar argv[];
  616. X{
  617. X    int k, in, tmp;
  618. X    char *s = "Not a number in flag '  '";
  619. X
  620. X    s[22] = argv[0];
  621. X    s[23] = argv[1];
  622. X    *number = 0;
  623. X    k = strlen(argv);
  624. X    write_err(k == 1, s, 9);
  625. X    for( in = 2; in < k; in++) {
  626. X        tmp = argv[in] - '0';
  627. X        write_err(tmp < 0 || tmp > 9, "Bad flag, N-A-P-N", 5);
  628. X        *number = tmp + *number * 10;
  629. X    }
  630. X}
  631. X
  632. Xusage(t) {
  633. X    fprintf(stderr, "[ %d ]  Usage: mfold [ -sn -ln -en -wn -f -d -rn -tn -cn -pn -n -L -Bn\n-D '<text>' -i '<text>' ]\n", t);
  634. X    exit(t);
  635. X}
  636. X
  637. Xint col = 0;
  638. X
  639. Xputcolu(c)
  640. Xchar c;
  641. X{
  642. X    if ( c == '\n' || col == colu_chars ) {
  643. X        advance_line();
  644. X        return;
  645. X    }
  646. X    cur_page[lin][col++] = c;
  647. X}
  648. X
  649. Xadvance_line() {
  650. X        col = 0;
  651. X        if ( ++lin == colu_lines ) {
  652. X            flushpage(columns);
  653. X            end_page();
  654. X        }
  655. X}
  656. X
  657. Xend_page() {
  658. X    int i;
  659. X
  660. X    if ( columns > 1 || got_bot ) {
  661. X        for ( i = 0; i < bot_lines; i++ ) {
  662. X            putchar('\n');
  663. X        }
  664. X    }
  665. X    if ( got_newpage ) putchar(12);        /* 12 == ^L  (ascii) */
  666. X}
  667. X
  668. Xflushpage(columns) {
  669. X    int line_sta = 0, cs, tmpl, lin_diff, lin_end;
  670. X    int end_col = columns - 1, lin_sto = colu_lines, end_char = colu_chars - 1;
  671. X
  672. X    for ( lin = 0; lin < colu_lines; lin++ ) {
  673. X        if ( cur_page[lin][0] != '\0' ) {
  674. X            line_sta = lin;
  675. X            break;
  676. X        }
  677. X    }
  678. X    for ( lin = line_sta; lin < colu_lines; lin += columns ) {
  679. X        if ( cur_page[lin][0] == '\0' ) {
  680. X            lin_sto =  lin;
  681. X            break;
  682. X        }
  683. X    }
  684. X    lin_diff = (lin_sto - line_sta) / columns;
  685. X    lin_end = line_sta + lin_diff;
  686. X    for ( lin = line_sta; lin < lin_end; lin++) {
  687. X        if ( cur_page[lin][0] == ' ' && cur_page[lin][1] == '\0'
  688. X        && columns == 1 ) {
  689. X            putchar('\n');
  690. X        } else {
  691. X            for ( cs = 0; cs < columns; cs++ ) {
  692. X                tmpl = lin + lin_diff * cs;
  693. X                if ( cur_page[tmpl][end_char] == '\0' && got_mrandom ) {
  694. X                    fill_sp(tmpl, end_char);
  695. X                }
  696. X                for ( col = 0; col < colu_chars; col++ ) {
  697. X                    if ( cur_page[tmpl][col] == '\0' ) {
  698. X                        if ( cs == end_col && !got_fill ) break;
  699. X                        if ( got_dyslexi ) putrev(' ');
  700. X                        else putchar(' ');
  701. X                    } else {
  702. X                        if ( got_dyslexi ) putrev(cur_page[tmpl][col]);
  703. X                        else putchar(cur_page[tmpl][col]);
  704. X                        cur_page[tmpl][col] = '\0';
  705. X                    }
  706. X                }
  707. X                if ( cs < end_col ) {
  708. X                    for ( col = 0; col < del_len; col++ ) {
  709. X                        if ( got_dyslexi ) putrev(delim[col]);
  710. X                        else putchar(delim[col]);
  711. X                    }
  712. X                }
  713. X            }
  714. X        }
  715. X        if ( got_dyslexi ) flushrev();
  716. X        putchar('\n');
  717. X    }
  718. X    lin = col = 0;
  719. X}
  720. X
  721. Xfill_sp(line, end_char) {
  722. X    int pass = 0, last, nulls = end_char, words = 0, i, found_sp = FALSE;
  723. X    int found_word = FALSE, moves, new_end, old_end;
  724. X
  725. X    while ( cur_page[line][--nulls] == '\0' && nulls != 1 );
  726. X    nulls = end_char - nulls;
  727. X    last = end_char - nulls;
  728. X    for ( i = ins_len; i <= last; i++) {
  729. X        if ( cur_page[line][i] != ' ' ) {
  730. X            if ( !found_word ) {
  731. X                words++;
  732. X                found_word = TRUE;
  733. X            }
  734. X        } else {
  735. X            found_word = FALSE;
  736. X        }
  737. X    }
  738. X    if ( words < 2 ) return;
  739. X    old_end = last;
  740. X    while ( ++pass < mrandom ) {
  741. X        if ( words > nulls ) moves = nulls;
  742. X        else moves = words - 1;
  743. X        i = moves;
  744. X        new_end = moves + old_end;
  745. X        last = new_end;
  746. X        while( 1 ) {
  747. X            cur_page[line][new_end--] = cur_page[line][old_end--];
  748. X            if ( old_end < 0 ) break;
  749. X            if ( cur_page[line][old_end] == ' ' ) {
  750. X                if ( !found_sp ) {
  751. X                    if ( moves-- > 0 ) cur_page[line][new_end--] = ' ' ;
  752. X                }
  753. X                found_sp = TRUE;
  754. X            } else {
  755. X                found_sp = FALSE;
  756. X            }
  757. X        }
  758. X        if ( cur_page[line][end_char] != '\0' ) return;
  759. X        nulls = nulls - i;
  760. X        old_end = last;
  761. X    }
  762. X}
  763. SHAR_EOF
  764. true || echo 'restore of mfold.c failed'
  765. fi
  766. # ============= mfold_doc ==============
  767. if test -f 'mfold_doc' -a X"$1" != X"-c"; then
  768.     echo 'x - skipping mfold_doc (File already exists)'
  769. else
  770. echo 'x - extracting mfold_doc (Text)'
  771. sed 's/^X//' << 'SHAR_EOF' > 'mfold_doc' &&
  772. XThe documentation follows:
  773. X
  774. XThe program have some large main parts:
  775. X
  776. X    1) One part scans the options and their arguments from the command line.
  777. X
  778. X    2) One part reads text input which not should be changed and
  779. X    writes the text to standard output.
  780. X
  781. X    3) One part does the actual folding and inserts text from
  782. X    the '-i' flag. This part does also cut the words if they are too
  783. X    long and puts a '-' at the end of the cut word.
  784. X
  785. X    4) One part reads input text which not should be changed after
  786. X    the folding, writes to standard output.
  787. X
  788. XVariables with names 'got_blabla' and 'index_blabla' refers to
  789. Xthe different flags the programs can receive. The program don't
  790. Xuse getopts(3) and have therefore a more rigid option format
  791. Xin the shell. But it's easier to handle errors this way.
  792. X
  793. XThe '-i' and '-D' options are handled as special cases by mfold.
  794. XRemaining options are handled in one separate switch construction.
  795. X
  796. XThe text which is to be folded is read into an internal 'page' buffer.
  797. XThis buffer has the width of one column and the length of all the
  798. Xlines in ALL columns on one page. The buffer is named 'cur_page' and
  799. Xis a global variable.
  800. X
  801. XThe folding is done in a 'while ( 1 )' loop. The first thing done
  802. Xin this loop is a large 'if' statment, about 44 lines long. This
  803. X'if' stament looks if a word is larger than the line length and then
  804. Xcuts the word, saves some charcters in som temporary variables,
  805. X'in_2' and 'in_3'. This construction can handle 2 (two) character
  806. Xlong lines. Then some newline handeling is done, see the '-n'
  807. Xoption in the manual to understand the source easier. A 'if'
  808. Xstatement look if the next charcter is a blank space or not a
  809. Xblank space. If it is a space, the word in 'cur_word' is written to
  810. Xthe output, and if it's not, the character is put into 'cur_word'.
  811. XWhen encountering an EOF, mfold exits the 'while ( 1 )' loop.
  812. X
  813. XThe output is not sent to standard output directly. Instead a
  814. Xfuntion 'putcolu' is used. 'putcolu' writes to the internal
  815. Xpage buffer 'cur_page'. When 'cur_page' is full, the function
  816. X'flush_page' writes 'cur_page to the output. But if the '-d'
  817. Xflag is used the output is written to 'putrev' instead, where
  818. Xthe function 'flushrev' flushes the internal reverse script
  819. Xbuffer, one line. When the '-r' flag is set, the function
  820. X'fill_sp' fills blank space until every line is right justified.
  821. X
  822. XThere is some more help functions, but they are very simple
  823. Xand should be understand without explanation... :-) ?
  824. X
  825. X
  826. XBug reports, ideas, or patches could be sent to;
  827. XPeter Smidt   smidt@cd.chalmers.se    or
  828. XPeter Smidt   smidt@fy.chalmers.se
  829. X
  830. X/Maaniker
  831. SHAR_EOF
  832. true || echo 'restore of mfold_doc failed'
  833. fi
  834. # ============= README ==============
  835. if test -f 'README' -a X"$1" != X"-c"; then
  836.     echo 'x - skipping README (File already exists)'
  837. else
  838. echo 'x - extracting README (Text)'
  839. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  840. XThe program mfold is a simpel folding and column making program.
  841. Xunpack the files from the shar file put them in a empty
  842. Xdirectory, type 'make' and you'll get the executable. A manual
  843. Xis included in the shar file.
  844. X
  845. XA bug have been removed and some optimization have been done since the first
  846. Xposting to alt.sources.
  847. X
  848. XA more exact documentation is in mfold_doc.
  849. X
  850. X
  851. XBug reports, ideas, or patches could be sent to;
  852. XPeter Smidt   smidt@cd.chalmers.se    or
  853. XPeter Smidt   smidt@fy.chalmers.se
  854. X
  855. X/Maaniker
  856. SHAR_EOF
  857. true || echo 'restore of README failed'
  858. fi
  859. exit 0
  860. -- 
  861. +=======================================+
  862. "The whole valley is like a smorgasbord."
  863.                     -- TREMORS
  864.