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

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