2
/******************************************************************************
3
* MODULE : concat_text.cpp
4
* DESCRIPTION: Typesetting textual markup
5
* COPYRIGHT : (C) 1999 Joris van der Hoeven
6
*******************************************************************************
7
* This software falls under the GNU general public license and comes WITHOUT
8
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
9
* If you don't have this file, write to the Free Software Foundation, Inc.,
10
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
11
******************************************************************************/
13
#include "concater.hpp"
14
#include "formatter.hpp"
16
lazy make_lazy_vstream (edit_env env, tree t, path ip, tree channel);
18
/******************************************************************************
20
******************************************************************************/
23
concater_rep::typeset_substring (string s, path ip, int pos) {
24
box b= text_box (ip, pos, s, env->fn, env->col);
25
a << line_item (STRING_ITEM, b, HYPH_INVALID, env->lan);
28
#define PRINT_SPACE(spc_type) \
39
print (space (spc->min>>2, spc->def>>2, spc->max>>2)); \
42
print (space (spc->min>>1, spc->def>>1, spc->max)); \
49
#define PRINT_CONDENSED_SPACE(spc_type) \
60
print (space (spc->min>>4, spc->def>>4, spc->max>>4)); \
63
print (space (spc->min>>3, spc->def>>3, spc->max>>2)); \
66
print (space (spc->min>>2, spc->def>>2, spc->max>>2)); \
71
concater_rep::typeset_string (string s, path ip) {
73
space spc= env->fn->spc;
74
space extra= env->fn->extra;
75
bool condensed= env->math_condensed;
79
text_property tp= env->lan->advance (s, pos);
80
if ((pos>start) && (s[start]==' ')) { // spaces
81
if (start==0) typeset_substring ("", ip, 0);
82
penalty_min (tp->pen_after);
83
PRINT_SPACE (tp->spc_before);
84
PRINT_SPACE (tp->spc_after);
85
if ((pos==N(s)) || (s[pos]==' '))
86
typeset_substring ("", ip, pos);
89
penalty_max (tp->pen_before);
90
if (condensed) PRINT_CONDENSED_SPACE (tp->spc_before)
91
else PRINT_SPACE (tp->spc_before)
92
typeset_substring (s (start, pos), ip, start);
93
penalty_min (tp->pen_after);
94
if (tp->limits != LIMITS_NONE) with_limits (tp->limits);
95
if (condensed) PRINT_CONDENSED_SPACE (tp->spc_after)
96
else PRINT_SPACE (tp->spc_after)
101
/******************************************************************************
102
* Typesetting errors, documents and concatenations
103
******************************************************************************/
106
concater_rep::typeset_uninit (tree t, path ip) {
109
marker (descend (ip, 0));
110
ghost ("?", decorate_right (ip), env->dis->red);
111
marker (descend (ip, 1));
116
concater_rep::typeset_error (tree t, path ip) {
117
typeset_unknown ("error", t, ip);
121
concater_rep::typeset_paragraph (tree t, path ip) {
122
print (STD_ITEM, ::typeset_as_paragraph (env, t[0], descend (ip, 0)));
126
concater_rep::typeset_document (tree t, path ip) {
127
print (STD_ITEM, ::typeset_as_stack (env, t, ip));
131
concater_rep::typeset_surround (tree t, path ip) {
132
marker (descend (ip, 0));
133
typeset (t[0], descend (ip, 0));
134
array<line_item> b= ::typeset_concat (env, t[1], descend (ip, 1));
135
typeset (t[2], descend (ip, 2));
137
marker (descend (ip, 1));
141
concater_rep::typeset_concat (tree t, path ip) {
144
typeset (t[i], descend (ip, i));
147
/******************************************************************************
149
******************************************************************************/
152
concater_rep::typeset_hspace (tree t, path ip) {
154
string s= as_string (t[0]);
155
print (space (env->decode_length (s * "-"),
156
env->decode_length (s),
157
env->decode_length (s * "+")));
159
else print (space (env->decode_length (t[0]),
160
env->decode_length (t[1]),
161
env->decode_length (t[2])));
166
concater_rep::typeset_space (tree t, path ip) {
167
SI w = env->decode_length (t[0]);
171
y1= env->decode_length (t[1]);
172
y2= env->decode_length (t[2]);
174
print (STD_ITEM, empty_box (ip, 0, y1, w, y2));
177
/******************************************************************************
178
* Moving and resizing
179
******************************************************************************/
182
concater_rep::typeset_move (tree t, path ip) {
183
// IDEA: set left, right, bottom, top environment variables
184
// and allow doing computations with them
185
box b= typeset_as_concat (env, t[0], descend (ip, 0));
186
SI x= env->decode_length (t[1]);
187
SI y= env->decode_length (t[2]);
188
print (STD_ITEM, move_box (ip, b, x, y, true));
192
resize (edit_env env, SI old, SI minimum, SI maximum, tree new_size) {
193
if (!is_atomic (new_size)) return old;
194
string s= new_size->label;
195
if (N(s)<2) return old;
196
if (s[0] == '@') s= s (1, N(s));
208
offset= (minimum + maximum) >> 1;
221
SI arg= env->decode_length (s (2, N(s)));
223
case '+': return offset + arg;
224
case '-': return offset - arg;
225
case '[': return min (offset, arg);
226
case ']': return max (offset, arg);
227
default : return arg;
230
else return env->decode_length (s);
234
concater_rep::typeset_resize (tree t, path ip) {
235
// IDEA: set left, right, bottom, top environment variables
236
// and allow doing computations with them
237
box b = typeset_as_concat (env, t[0], descend (ip, 0));
238
SI x1= resize (env, b->x1, b->x1, b->x2, t[1]);
239
SI y1= resize (env, b->y1, b->y1, b->y2, t[2]);
240
SI x2= resize (env, b->x2, b->x1, b->x2, t[3]);
241
SI y2= resize (env, b->y2, b->y2, b->y2, t[4]);
242
bool fl= is_atomic (t[1]) && (N(t[1]->label)!=0) && (t[1]->label[0]=='@');
243
print (STD_ITEM, resize_box (ip, b, x1, y1, x2, y2, true, !fl));
246
/******************************************************************************
248
******************************************************************************/
251
concater_rep::typeset_float (tree t, path ip) {
252
tree t1= env->exec (t[0]);
253
tree t2= env->exec (t[1]);
254
tree ch= tuple (t1, t2);
255
lazy lz= make_lazy_vstream (env, t[2], descend (ip, 2), ch);
256
marker (descend (ip, 0));
257
print (FLOAT_ITEM, control_box (decorate_middle (ip), lz, env->fn));
258
marker (descend (ip, 1));
261
/******************************************************************************
262
* Repetition of boxes inside other boxes
263
******************************************************************************/
266
concater_rep::typeset_repeat (tree t, path ip) {
267
box b1 = typeset_as_concat (env, t[0], descend (ip, 0));
268
box b2 = typeset_as_concat (env, t[1], descend (ip, 1));
269
SI xoff= env->get_length (XOFF_DECORATIONS);
270
print (STD_ITEM, repeat_box (ip, b1, b2, xoff));
273
/******************************************************************************
274
* Formatting information and decorations
275
******************************************************************************/
278
concater_rep::typeset_formatting (tree t, path ip, string v) {
280
tree new_format= join (env->read (v), t (0, n-1));
281
tree old_format= env->local_begin (v, new_format);
282
if (v != CELL_FORMAT) {
283
marker (descend (ip, 0));
284
control (t (0, N(t)-1), decorate (ip));
286
typeset (t[n-1], descend (ip, n-1));
287
if (v != CELL_FORMAT) {
288
control (tree (L(t)), decorate (ip));
289
marker (descend (ip, 1));
291
env->local_end (v, old_format);
295
concater_rep::typeset_decorated_box (tree t, path ip) {
297
int n= N (env->decorated_boxes);
298
if ((n > 0) && (!nil (env->decorated_boxes [n-1]))) {
299
print (STD_ITEM, env->decorated_boxes [n-1]);
300
env->decorated_boxes [n-1]= box ();