1 /***************************************************************************
3 TextEditor.mcc - Textediting MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005-2014 TextEditor.mcc Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 TextEditor class Support Site: http://www.sf.net/projects/texteditor-mcc
21 ***************************************************************************/
26 #include <exec/memory.h>
27 #include <proto/exec.h>
41 HOOKPROTONO(ExportHookFunc
, STRPTR
, struct ExportMessage
*emsg
)
43 struct Buffer
*buf
= emsg
->UserData
;
44 struct InstData
*data
= emsg
->data
;
49 // create a temporary buffer if we don't have one yet
52 if((buf
= AllocVecShared(sizeof(*buf
), MEMF_CLEAR
)) != NULL
)
56 // respect our pool's threshold size
57 buf
->buffer
= AllocVecPooled(data
->mypool
, 512);
62 buf
->buffer
= AllocVecShared(1024, MEMF_CLEAR
);
69 buf
->pointer
= buf
->buffer
;
74 if(buf
!= NULL
&& buf
->buffer
!= NULL
)
76 LONG expand
= emsg
->Length
* 10;
78 if(buf
->buffer
+buf
->size
< buf
->pointer
+expand
)
80 // remember the current buffer, size and offset
81 STRPTR oldbuf
= buf
->buffer
;
82 ULONG oldsize
= buf
->size
;
83 ULONG offset
= buf
->pointer
- oldbuf
;
85 // allocate an expanded buffer
88 // respect our pool's threshold size
89 buf
->buffer
= AllocVecPooled(data
->mypool
, oldsize
+expand
+512);
90 buf
->size
= oldsize
+expand
+512;
94 buf
->buffer
= AllocVecShared(oldsize
+expand
+1024, MEMF_CLEAR
);
95 buf
->size
= oldsize
+expand
+1024;
98 if(buf
->buffer
!= NULL
)
100 buf
->pointer
= buf
->buffer
+offset
;
102 memcpy(buf
->buffer
, oldbuf
, offset
);
106 W(DBF_BLOCK
, "failed to allocate temporary buffer");
107 emsg
->failure
= TRUE
;
110 // free the old buffer
112 FreeVecPooled(data
->mypool
, oldbuf
);
117 if(emsg
->failure
== FALSE
)
120 struct LineStyle
*styles
= emsg
->Styles
;
121 struct LineColor
*colors
= emsg
->Colors
;
123 UWORD currentstyle
= 0;
124 ULONG hookType
= (IPTR
)hook
->h_Data
;
127 // if this hook is of plain type we have consider highlighting as well.
128 if(hookType
== MUIV_TextEditor_ExportHook_Plain
&& emsg
->Highlight
== TRUE
)
130 *buf
->pointer
++ = '\033';
131 *buf
->pointer
++ = 'h';
134 if(hookType
== MUIV_TextEditor_ExportHook_Plain
&& emsg
->Flow
!= buf
->flow
)
136 *buf
->pointer
++ = '\033';
140 case MUIV_TextEditor_Flow_Right
:
141 *buf
->pointer
++ = 'r';
144 case MUIV_TextEditor_Flow_Center
:
145 *buf
->pointer
++ = 'c';
148 case MUIV_TextEditor_Flow_Left
:
150 *buf
->pointer
++ = 'l';
154 buf
->flow
= emsg
->Flow
;
157 if(emsg
->Separator
!= LNSF_None
)
159 if(hookType
== MUIV_TextEditor_ExportHook_Plain
)
160 snprintf(buf
->pointer
, buf
->size
-(buf
->pointer
-buf
->buffer
), "\033[s:%d]", emsg
->Separator
);
162 strlcpy(buf
->pointer
, isFlagSet(emsg
->Separator
, LNSF_Thick
) ? "<tsb>" : "<sb>", buf
->size
-(buf
->pointer
-buf
->buffer
));
164 buf
->pointer
+= strlen(buf
->pointer
);
167 // define some start values.
168 startx
= buf
->pointer
;
169 length
= emsg
->Length
-emsg
->SkipFront
-emsg
->SkipBack
;
170 lastpos
= emsg
->SkipFront
;
172 if((styles
!= NULL
|| colors
!= NULL
) &&
173 (hookType
== MUIV_TextEditor_ExportHook_EMail
|| hookType
== MUIV_TextEditor_ExportHook_Plain
))
177 BOOL coloured
= FALSE
;
178 UWORD colour_state
= 7;
179 LONG nextStyleColumn
;
180 LONG nextColorColumn
;
183 nextStyleColumn
= EOS
;
185 nextStyleColumn
= styles
[0].column
;
188 nextColorColumn
= EOC
;
190 nextColorColumn
= colors
[0].column
;
192 while(length
> 0 && (nextStyleColumn
!= EOS
|| nextColorColumn
!= EOC
))
197 SHOWVALUE(DBF_EXPORT
, nextStyleColumn
);
198 SHOWVALUE(DBF_EXPORT
, nextColorColumn
);
200 // check whether a style change or a color change is first to be handled
201 if((coloured
== TRUE
&& nextStyleColumn
< nextColorColumn
) ||
202 (coloured
== FALSE
&& nextStyleColumn
<= nextColorColumn
))
204 pos
= styles
->column
- 1;
205 style
= styles
->style
;
206 isColorChange
= FALSE
;
207 // remember the next style change column
209 nextStyleColumn
= styles
->column
;
213 pos
= colors
->column
- 1;
214 style
= colors
->color
;
215 isColorChange
= TRUE
;
216 // remember the next style change column
218 nextColorColumn
= colors
->column
;
221 // skip styles&colors which below lastpos
225 // depending on how much we export
226 // we have to fire up the style convert routines.
227 if(pos
-lastpos
<= length
)
230 memcpy(buf
->pointer
, emsg
->Contents
+lastpos
, len
);
233 if(hookType
== MUIV_TextEditor_ExportHook_EMail
)
235 if(isColorChange
== TRUE
)
237 if((coloured
= (style
== colour_state
? TRUE
: FALSE
)))
239 *buf
->pointer
++ = '#';
250 *buf
->pointer
++ = '_';
257 *buf
->pointer
++ = '*';
264 *buf
->pointer
++ = '/';
270 else if(hookType
== MUIV_TextEditor_ExportHook_Plain
)
272 if(isColorChange
== TRUE
)
274 D(DBF_EXPORT
, "exporting color %ld of column %ld", style
, pos
+1);
275 snprintf(buf
->pointer
, buf
->size
-(buf
->pointer
-buf
->buffer
), "\033p[%d]", style
);
276 buf
->pointer
+= strlen(buf
->pointer
);
284 D(DBF_EXPORT
, "exporting bold style of column %ld", pos
+1);
285 *buf
->pointer
++ = '\033';
286 *buf
->pointer
++ = 'b';
287 setFlag(currentstyle
, BOLD
);
293 D(DBF_EXPORT
, "exporting italic style of column %ld", pos
+1);
294 *buf
->pointer
++ = '\033';
295 *buf
->pointer
++ = 'i';
296 setFlag(currentstyle
, ITALIC
);
302 D(DBF_EXPORT
, "exporting underline style of column %ld", pos
+1);
303 *buf
->pointer
++ = '\033';
304 *buf
->pointer
++ = 'u';
305 setFlag(currentstyle
, UNDERLINE
);
313 currentstyle
&= style
;
315 if(pos
+1 != styles
->column
|| styles
->style
< 0x8000)
317 D(DBF_EXPORT
, "exporting plain style of column %ld", pos
+1);
318 *buf
->pointer
++ = '\033';
319 *buf
->pointer
++ = 'n';
321 if(isFlagSet(currentstyle
, UNDERLINE
))
323 *buf
->pointer
++ = '\033';
324 *buf
->pointer
++ = 'u';
327 if(isFlagSet(currentstyle
, BOLD
))
329 *buf
->pointer
++ = '\033';
330 *buf
->pointer
++ = 'b';
333 if(isFlagSet(currentstyle
, ITALIC
))
335 *buf
->pointer
++ = '\033';
336 *buf
->pointer
++ = 'i';
348 memcpy(buf
->pointer
, emsg
->Contents
+lastpos
, len
);
363 memcpy(buf
->pointer
, emsg
->Contents
+lastpos
, length
);
364 buf
->pointer
+= length
;
367 // NUL terminate our buffer string
368 *buf
->pointer
= '\0';
370 while(emsg
->ExportWrap
!= 0 && buf
->pointer
-startx
> emsg
->ExportWrap
)
372 LONG max
= emsg
->ExportWrap
+1;
374 if(startx
[emsg
->ExportWrap
] != '\n')
376 while(--max
&& *(startx
+max
) != ' ')
382 *(startx
+= max
) = '\n';
386 while(++startx
< buf
->pointer
&& *(startx
) != ' ')
389 if(buf
->pointer
!= startx
)
397 if(emsg
->Last
== TRUE
)
399 // free the temporary struct after we processed the last line
400 result
= buf
->buffer
;
405 // return the temporary struct for the next call
406 result
= (STRPTR
)buf
;
411 W(DBF_BLOCK
, "failed to allocate temporary buffer");
412 SHOWVALUE(DBF_BLOCK
, buf
);
414 SHOWVALUE(DBF_BLOCK
, buf
->buffer
);
415 emsg
->failure
= TRUE
;
422 MakeHookWithData(ExportHookPlain
, ExportHookFunc
, MUIV_TextEditor_ExportHook_Plain
);
423 MakeHookWithData(ExportHookEMail
, ExportHookFunc
, MUIV_TextEditor_ExportHook_EMail
);
424 MakeHookWithData(ExportHookNoStyle
, ExportHookFunc
, MUIV_TextEditor_ExportHook_NoStyle
);