diff options
Diffstat (limited to 'pkg/system/help/lroff/textout.x')
-rw-r--r-- | pkg/system/help/lroff/textout.x | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/pkg/system/help/lroff/textout.x b/pkg/system/help/lroff/textout.x new file mode 100644 index 00000000..663bccc8 --- /dev/null +++ b/pkg/system/help/lroff/textout.x @@ -0,0 +1,140 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <chars.h> +include "lroff.h" + +# TEXTOUT -- Process a line of text. Move words from the text buffer into +# the word buffer WBUF, maintaining an array of pointers to the words, until +# an output line has been filled. Leading whitespace is part of the word, +# if it is the first word on a line (thus we get paragraph indents). +# Thereafter only trailing whitespace is included in the word. The last word +# on a line gets one trailing space, unless the last char is a period, in which +# case it gets two. Otherwise whitespace at the end of the input text line is +# stripped. BREAKLINE is subsequently called to reassemble the words to form +# an output line. +# +# WBUF is the word buffer (a set of strings separated by EOS markers). WP is +# a pointer to the next available char in WBUF. NWORDS is the number of words +# in the buffer. WORDS is a pointer to the array of word pointers. We do not +# check for word buffer overflow because the word buffer is allocated large +# enough to accommodate the worst case (the buffer is flushed when an output +# line is filled, which always happens before the buffer overflows). WCOLS is +# the number of printable characters in the word buffer. The word buffer +# variables are all stored in the "words" common for use by TEXTOUT and +# BREAKLINE. Set_wordbuf() must be called upon startup and shutdown to +# allocate/deallocate the word buffer. + +procedure set_wordbuf (max_words) + +int max_words #I output word buffer size + +int word_buffer_size +errchk malloc + +include "lroff.com" +include "words.com" + +begin + word_buffer_size = (max_words * 2) + SZ_LINE # worst case + if (max_words <= 0 && words != NULL) { + call mfree (wbuf, TY_CHAR) + call mfree (words, TY_POINTER) + } else { + call malloc (wbuf, word_buffer_size, TY_CHAR) + call malloc (words, max_words, TY_POINTER) + wp = wbuf + nwords = 0 + wcols = 0 + } +end + + +# TEXTOUT -- Output a newline delimited line of text. + +procedure textout (out, text) + +extern out() +char text[1] + +char ch +int ip_save, wcols_save, ip +errchk breakline +include "lroff.com" +include "words.com" + +begin + if (wbuf == NULL || words == NULL) + call error (1, "No Lroff word buffer allocated") + + for (ip=1; text[ip] != EOS; ) { + # Set up descriptors of new word. Save the input pointer in case + # the output line fills and we have to "put the word back". + + Memi[words+nwords] = wp # word pointer + ip_save = ip + wcols_save = wcols + + # The following is a nop except at the beginning of a line. + for (; text[ip] == BLANK; ip=ip+1) { + Memc[wp] = BLANK + wp = wp + 1 + wcols = wcols + 1 + } + + # Copy the word itself. + for (ch=text[ip]; ch != BLANK && ch != EOS; ch=text[ip]) { + Memc[wp] = ch + wp = wp + 1 + if (!INVISIBLE (ch)) + wcols = wcols + 1 + ip = ip + 1 + } + + # And then any trailing whitespace. + for (; text[ip] == BLANK; ip=ip+1) { + Memc[wp] = BLANK + wp = wp + 1 + wcols = wcols + 1 + } + + # End of word string. + Memc[wp] = EOS + wp = wp + 1 + + # If line has been filled, call breakline to format output line + # and send it out. Put word which caused break back for next line. + # Do not put word back if it is the first word, or we will have + # an infinite loop. + if (wcols > (right_margin - left_margin + 1) && nwords > 0) { + ip = ip_save + wcols = wcols_save + wp = Memi[words+nwords] + call breakline (out, JU) + } else + nwords = nwords + 1 + } + + # Strip trailing whitespace at the end of an input line. If input + # line ends with a period, assume it is a sentence and add a blank. + # Otherwise add a blank to separate words when output line is filled. + # If a sentence ends within a line, the user is responsible for placing + # two spaces after the period. + + if (nwords > 0) { + for (wp=wp-2; Memc[wp] == BLANK && wp > wbuf; wp=wp-1) + wcols = wcols - 1 + if (Memc[wp] == '.') { + wp = wp + 1 + Memc[wp] = BLANK + wcols = wcols + 1 + } + wp = wp + 1 # point to next avail + + Memc[wp] = BLANK # need at least one + wp = wp + 1 + wcols = wcols + 1 + + Memc[wp] = EOS + wp = wp + 1 + } +end |