1 /*
2 * Copyright (c) 2003, 2004 Sasha Vasko <sasha@aftercode.net>
3 *
4 * This module is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20 /*#define DO_CLOCKING */
21 #define LOCAL_DEBUG
22 #define EVENT_TRACE
23
24 #include "../../configure.h"
25 #include "../../libAfterStep/asapp.h"
26 #include <unistd.h>
27 #include "../../libAfterStep/screen.h"
28 #include "../../libAfterStep/module.h"
29 #include "../../libAfterStep/aswindata.h"
30 #include "../../libAfterStep/event.h"
31 #include "../../libAfterStep/wmprops.h"
32 #include "../../libAfterStep/parser.h"
33 #include "../../libAfterConf/afterconf.h"
34
35 #include "ASDocGen.h"
36 #include "xmlproc.h"
37 #include "docfile.h"
38 #include "datadoc.h"
39
40 /* <li><b><A href="graphics.php?inc=icons/normal/index">normal</A></b></li> */
41
42 typedef struct ASData2xmlState
43 {
44 ASFlagType flags ;
45
46 xml_elem_t* doc ;
47 xml_elem_t* curr_section ;
48
49 }ASData2xmlState;
50
51
52
53 xml_elem_t*
add_tag(xml_elem_t * owner,const char * tag_str,int tag_id)54 add_tag( xml_elem_t* owner, const char *tag_str, int tag_id )
55 {
56 xml_elem_t* t = xml_elem_new() ;
57 t->tag = mystrdup( tag_str );
58 t->tag_id = tag_id ;
59 LOCAL_DEBUG_OUT( "tag = \"%s\", tag_id = %d", t->tag, t->tag_id );
60 if( owner != NULL )
61 xml_insert(owner, t);
62 LOCAL_DEBUG_OUT( "added to owner = %p", owner );
63 return t;
64 }
65
66 #define ADD_TAG(o,t) add_tag( o, #t, DOCBOOK_##t##_ID)
67
68 xml_elem_t*
add_data_section_header2xml(ASData2xmlState * xml_state,const char * id)69 add_data_section_header2xml( ASData2xmlState *xml_state, const char *id )
70 {
71 xml_elem_t* sect = NULL;
72 xml_elem_t* title = NULL ;
73
74 LOCAL_DEBUG_OUT("id = \"%s\", owner = %p, owner->child = %p", id, xml_state->doc, xml_state->doc->child );
75
76 sect = ADD_TAG(xml_state->doc,section);
77
78 LOCAL_DEBUG_OUT("section=%p", sect );
79
80 sect->parm = safemalloc( 4+strlen(id)+32+1 );
81 sprintf(sect->parm, "id=\"%s\"", id );
82
83 LOCAL_DEBUG_OUT("parm = \"%s\"", sect->parm?sect->parm:"(NULL)" );
84
85 xml_state->curr_section = sect ;
86
87 if( strlen(id) > 0 )
88 {
89 title = ADD_TAG(sect,title);
90 append_CDATA_line( title, id, strlen(id) );
91 LOCAL_DEBUG_OUT("title = %p", title );
92 }
93
94 return sect;
95 }
96
97 xml_elem_t*
add_file_info_li(xml_elem_t * varlist,const char * term)98 add_file_info_li( xml_elem_t* varlist, const char *term)
99 {
100 xml_elem_t* entry ;
101 xml_elem_t* entry_term ;
102 xml_elem_t* entry_li ;
103
104 entry = ADD_TAG(varlist,varlistentry);
105 entry_term = ADD_TAG(entry,term);
106 append_CDATA_line( entry_term, term, strlen(term) );
107 entry_li = ADD_TAG(entry,listitem);
108 return entry_li;
109 }
110
111 void
add_file_info_item(xml_elem_t * varlist,const char * term,const char * info)112 add_file_info_item( xml_elem_t* varlist, const char *term, const char *info )
113 {
114 xml_elem_t* entry_li = add_file_info_li( varlist, term);
115 xml_elem_t* entry_p ;
116
117 entry_p = ADD_TAG(entry_li,para);
118 append_CDATA_line( entry_p, info, strlen(info) );
119 }
120
121 void
make_data_file_info(ASImageListEntry * df,ASXMLInterpreterState * parent_state,Bool preview_saved)122 make_data_file_info( ASImageListEntry *df, ASXMLInterpreterState *parent_state, Bool preview_saved )
123 {
124 #if 1
125 ASXMLInterpreterState state;
126 ASData2xmlState xml_state ;
127
128 xml_elem_t* varlist ;
129 xml_elem_t* ptr ;
130
131 static char *img_type_names[ASIT_Unknown+1] =
132 {
133 "Xpm",
134 "ZCompressedXpm",
135 "GZCompressedXpm",
136 "Png",
137 "Jpeg",
138 "Xcf",
139 "Ppm",
140 "Pnm",
141 "Bmp",
142 "Ico",
143 "Cur",
144 "Gif",
145 "Tiff",
146 "XML",
147 "Xbm",
148 "Targa",
149 "Pcx",
150 "Unknown"
151 };
152
153 if( !start_doc_file( parent_state->dest_dir, df->name, NULL, parent_state->doc_type, df->name, df->name, df->fullfilename, &state, DOC_CLASS_None, DocClass_Overview ) )
154 return ;
155
156 memset( &xml_state, 0x00, sizeof(xml_state));
157 xml_state.doc = xml_elem_new();
158 xml_state.doc->tag = mystrdup(XML_CONTAINER_STR) ;
159 xml_state.doc->tag_id = XML_CONTAINER_ID ;
160
161 LOCAL_DEBUG_OUT( "doc = %p, doc->child = %p", xml_state.doc, xml_state.doc->child );
162
163 /* generate file contents : */
164 add_data_section_header2xml( &xml_state, "Details" );
165 varlist = ADD_TAG(xml_state.curr_section,variablelist);
166
167 if( df->preview )
168 {
169 char tmp[64];
170 sprintf( &tmp[0], "%dx%d", df->preview->width, df->preview->height );
171 add_file_info_item( varlist, "Size : ", &tmp[0] );
172 }
173 add_file_info_item( varlist, "Full path : ", df->fullfilename );
174 if( df->type < ASIT_Unknown)
175 add_file_info_item( varlist, "Type : ", img_type_names[df->type]);
176
177
178 if( preview_saved )
179 {
180 xml_elem_t* entry_li = add_file_info_li( varlist, "Preview : ");
181 xml_elem_t* medobj = ADD_TAG(entry_li,mediaobject);
182 xml_elem_t* imgobj = ADD_TAG(medobj,imageobject);
183 xml_elem_t* imgdat = ADD_TAG(imgobj,imagedata);
184
185 imgdat->parm = safemalloc( 28+strlen(df->name)+32);
186 sprintf( imgdat->parm, "fileref=\"%s.png\"", df->name );
187 }
188
189 if( df->type == ASIT_XMLScript || !preview_saved )
190 {
191 char *doc_str = load_file(df->fullfilename);
192 if( doc_str )
193 {
194 xml_elem_t* credits_section;
195 xml_elem_t* litlayout;
196
197 if( df->type == ASIT_XMLScript )
198 {
199 credits_section = add_data_section_header2xml( &xml_state,
200 (strstr( doc_str,"<body>")!=NULL)?"HTML document : ":"XML text : ");
201 }else
202 credits_section = add_data_section_header2xml( &xml_state, "ASCII text: ");
203
204 litlayout = ADD_TAG(credits_section,literallayout);
205 append_CDATA_line( litlayout, doc_str, strlen(doc_str) );
206 free( doc_str );
207 }
208 }
209
210 /* now lets write it out into file : */
211 for (ptr = xml_state.doc->child ; ptr ; ptr = ptr->next)
212 convert_xml_tag( ptr, NULL, &state );
213
214 end_doc_file( &state );
215 LOCAL_DEBUG_OUT( "xml_elem_delete for doc %p", xml_state.doc );
216 xml_elem_delete(NULL, xml_state.doc);
217 #endif
218 }
219
220 int
data_fname_filter(const char * d_name)221 data_fname_filter (const char *d_name)
222 {
223 int name_len = strlen( d_name );
224 if( d_name[0] == '.' ||
225 (name_len >= 7 && strcmp(d_name+name_len-7, ".tar.gz") == 0) ||
226 (name_len >= 5 && strcmp(d_name+name_len-5, ".mini") == 0) ||
227 (name_len >= 5 && strcmp(d_name+name_len-5, ".html") == 0))
228 return False;
229 printf( "\b%c", d_name[0] );
230 fflush( stdout );
231 return True;
232 }
233
234
235
236 void
convert_data_file(const char * source_dir,const char * dst_dir,ASXMLInterpreterState * state,ASData2xmlState * xml_state)237 convert_data_file( const char *source_dir, const char *dst_dir, ASXMLInterpreterState *state, ASData2xmlState *xml_state)
238 {
239 unsigned int count = 0;
240 Bool files_sect_added = False ;
241 ASImageListEntry *curr ;
242 ASImageListEntry *im_list = get_asimage_list( Scr.asv, source_dir, LOAD_PREVIEW,
243 SCREEN_GAMMA, 0, 0,
244 0, &count, data_fname_filter );
245
246 LOCAL_DEBUG_OUT( "im_list = %p, count = %d", im_list, count );
247
248 printf( "\b" );
249 fflush( stdout );
250
251 curr = im_list ;
252 while( curr )
253 {
254 LOCAL_DEBUG_OUT( "curr = %p", curr );
255 LOCAL_DEBUG_OUT( "curr->name = \"%s\"", curr->name );
256
257 if( mystrcasecmp(curr->name, "CREDITS") != 0 )
258 {
259 int name_len = strlen( curr->name );
260 int odir_name_len = dst_dir?strlen( dst_dir )+1:0;
261 char *preview_name = safemalloc( odir_name_len + name_len + 1 + 3 + 1 );
262 char *ext_name = safemalloc(odir_name_len + name_len + 1 + 4 + 1 );
263 Bool preview_saved = False ;
264
265 xml_elem_t* link = NULL ;
266
267 /* printf( "[%s]", curr->name );
268 fflush(stdout);
269 */
270 if( !files_sect_added )
271 {
272 add_data_section_header2xml( xml_state, "Files" );
273 files_sect_added = True ;
274 }
275
276 LOCAL_DEBUG_OUT( "curr->name = \"%s\", curr->preview = %p", curr->name, curr->preview );
277 if( odir_name_len > 0 )
278 {
279 sprintf( preview_name, "%s/%s.png", dst_dir, curr->name );
280 sprintf( ext_name, "%s/%s", dst_dir, curr->name );
281 }else
282 {
283 strcpy( preview_name, curr->name );
284 strcpy( ext_name, curr->name );
285 strcpy( &(preview_name[name_len]), ".png" );
286 }
287 if( curr->preview )
288 {
289 ASImageExportParams params ;
290 if( curr->type != ASIT_Jpeg &&
291 get_flags( get_asimage_chanmask(curr->preview), SCL_DO_ALPHA) &&
292 curr->preview->width < 200 && curr->preview->height < 200 )
293 {
294 params.png.flags = EXPORT_ALPHA ;
295 params.png.compression = 6 ;
296 params.png.type = ASIT_Png ;
297 preview_saved = ASImage2file( curr->preview, NULL, preview_name,ASIT_Png, ¶ms );
298 }else
299 {
300 params.jpeg.flags = EXPORT_ALPHA ;
301 params.jpeg.quality = 100 ;
302 params.jpeg.type = ASIT_Jpeg ;
303 preview_saved = ASImage2file( curr->preview, NULL, preview_name,ASIT_Jpeg, ¶ms );
304 }
305
306 if( !preview_saved )
307 show_warning( "failed to save \"%s\" as png preview - skipping", curr->name );
308 }
309 if( preview_saved )
310 {
311 link = ADD_TAG(xml_state->curr_section,ulink);
312
313 if( link )
314 {
315 xml_elem_t* medobj = ADD_TAG(link,mediaobject);
316 xml_elem_t* imgobj = ADD_TAG(medobj,imageobject);
317 xml_elem_t* imgdat = ADD_TAG(imgobj,imagedata);
318
319 imgdat->parm = safemalloc( 28+name_len+32);
320 sprintf( imgdat->parm, "fileref=\"%s.png\"", curr->name );
321 }
322 }else
323 {
324 xml_elem_t* p = ADD_TAG(xml_state->curr_section,para);
325 link = ADD_TAG(p,ulink);
326 append_CDATA_line( link, curr->name,name_len );
327 }
328 if( link )
329 {
330 link->parm = safemalloc( 6+name_len+32);
331 sprintf( link->parm, "url=\"%s\"", curr->name );
332 LOCAL_DEBUG_OUT( "%s", link->parm );
333 }
334
335 make_data_file_info( curr, state, preview_saved );
336
337 printf( "." );
338 fflush(stdout);
339
340 }
341 curr = curr->next ;
342 }
343 curr = im_list ;
344 while( curr )
345 {
346 if( mystrcasecmp(curr->name, "CREDITS") == 0)
347 {
348 char *doc_str = load_file(curr->fullfilename);
349 if( doc_str )
350 {
351 xml_elem_t* credits_section = add_data_section_header2xml( xml_state, "CREDITS" );
352 xml_elem_t* litlayout = ADD_TAG(credits_section,literallayout);
353
354 append_CDATA_line( litlayout, doc_str, strlen(doc_str) );
355 free( doc_str );
356 }
357 break;
358 }
359 curr = curr->next ;
360 }
361 destroy_asimage_list( &im_list );
362 }
363
364
365 void
gen_data_doc(const char * source_dir,const char * dest_dir,const char * display_name,const char * display_purpose,ASDocType doc_type)366 gen_data_doc( const char *source_dir, const char *dest_dir,
367 const char *display_name,
368 const char *display_purpose,
369 ASDocType doc_type )
370 {
371 ASXMLInterpreterState state;
372 ASData2xmlState xml_state ;
373 char *slash ;
374 char *short_fname ;
375 struct direntry **list = NULL;
376 int list_len, i ;
377 xml_elem_t* dir_header_section = NULL ;
378 xml_elem_t* dir_header_varlist = NULL ;
379 xml_elem_t* ptr ;
380
381
382 if( (slash = strrchr( source_dir, '/' )) != NULL )
383 short_fname = mystrdup( slash+1 );
384 else
385 short_fname = mystrdup( source_dir );
386
387 memset( &xml_state, 0x00, sizeof(xml_state) );
388 if( !start_doc_file( dest_dir, "index", NULL, doc_type, short_fname, display_name, display_purpose, &state, DOC_CLASS_None, DocClass_Overview ) )
389 return ;
390
391 xml_state.doc = xml_elem_new();
392 xml_state.doc->tag = mystrdup(XML_CONTAINER_STR) ;
393 xml_state.doc->tag_id = XML_CONTAINER_ID ;
394
395 LOCAL_DEBUG_OUT( "doc = %p, doc->child = %p", xml_state.doc, xml_state.doc->child );
396 list_len = my_scandir ((char*)source_dir, &list, ignore_dots, direntry_compar_alpha);
397 for (i = 0; i < list_len; i++)
398 {
399 if (S_ISDIR (list[i]->d_mode) && strcasecmp(list[i]->d_name, "doc") != 0 )
400 {
401 char *subdir = make_file_name( source_dir, list[i]->d_name );
402 char *dest_subdir = dest_dir?make_file_name( dest_dir, list[i]->d_name ):mystrdup(list[i]->d_name);
403 char *subdir_display_name = make_file_name( display_name, list[i]->d_name );
404 xml_elem_t* entry ;
405 xml_elem_t* entry_term ;
406 xml_elem_t* entry_link ;
407
408 if( dir_header_section == NULL )
409 {
410 dir_header_section = add_data_section_header2xml( &xml_state, "Subdirectories" );
411 dir_header_varlist = ADD_TAG(dir_header_section,variablelist);
412 }
413
414 entry = ADD_TAG(dir_header_varlist,varlistentry);
415 entry_term = ADD_TAG(entry,term);
416 entry_link = ADD_TAG(entry_term,ulink);
417 entry_link->parm = safemalloc( 12+strlen(list[i]->d_name)+32 );
418 sprintf( entry_link->parm,"url=\"%s/index\"", list[i]->d_name );
419 append_CDATA_line( entry_link, list[i]->d_name, strlen(list[i]->d_name) );
420
421 gen_data_doc( subdir, dest_subdir,
422 subdir_display_name, subdir, doc_type );
423
424 free( subdir );
425 free( dest_subdir );
426 free( subdir_display_name );
427 }
428 free(list[i]);
429 }
430 if( list )
431 free( list );
432 printf( "\nCataloguing %s ", source_dir );
433 fflush( stdout );
434
435 convert_data_file( source_dir, dest_dir, &state, &xml_state );
436
437 /*xml_print(xml_state.doc); */
438
439 for (ptr = xml_state.doc->child ; ptr ; ptr = ptr->next)
440 convert_xml_tag( ptr, NULL, &state );
441 end_doc_file( &state );
442
443 LOCAL_DEBUG_OUT( "xml_elem_delete for doc %p", xml_state.doc );
444 xml_elem_delete(NULL, xml_state.doc);
445 free( short_fname );
446 }
447
448
449