aboutsummaryrefslogtreecommitdiff
path: root/pkg/system/help/lroff/textout.x
blob: 663bccc878b09c565ea9e9d0f72c63ee9484cc15 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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