Added links to related projects
[xmldoc.git] / xp.c
1 /*
2  * xsltproc.c: user program for the XSL Transformation 1.0 engine
3  *
4  * See Copyright for the status of this software.
5  *
6  * daniel@veillard.com
7  */
8
9 //#include <libxslt/libxslt.h>
10 //#include <libexslt/exslt.h>
11 #include <string.h>
12 #ifdef HAVE_SYS_STAT_H
13 #include <sys/stat.h>
14 #endif
15 #ifdef HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
18 #include <stdlib.h>
19 #ifdef HAVE_STDARG_H
20 #include <stdarg.h>
21 #endif
22 #include <libxml/xmlmemory.h>
23 #include <libxml/debugXML.h>
24 #include <libxml/HTMLtree.h>
25 #include <libxml/xmlIO.h>
26 #ifdef LIBXML_DOCB_ENABLED
27 #include <libxml/DOCBparser.h>
28 #endif
29 #ifdef LIBXML_XINCLUDE_ENABLED
30 #include <libxml/xinclude.h>
31 #endif
32 #ifdef LIBXML_CATALOG_ENABLED
33 #include <libxml/catalog.h>
34 #endif
35 #include <libxml/parserInternals.h>
36
37 #include <libxslt/xslt.h>
38 #include <libxslt/xsltInternals.h>
39 #include <libxslt/transform.h>
40 #include <libxslt/xsltutils.h>
41 #include <libxslt/extensions.h>
42
43 #include <libexslt/exsltconfig.h>
44
45
46 #ifndef HAVE_STAT
47 #  ifdef HAVE__STAT
48      /* MS C library seems to define stat and _stat. The definition
49       *         is identical. Still, mapping them to each other causes a warning. */
50 #    ifndef _MSC_VER
51 #      define stat(x,y) _stat(x,y)
52 #    endif
53 #    define HAVE_STAT
54 #  endif
55 #endif
56
57 xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
58                                                const char *ID,
59                                                xmlParserCtxtPtr ctxt);
60
61 static int debug = 0;
62 static int novalid = 0;
63 static int noout = 0;
64 static int latex = 0;
65 #ifdef LIBXML_DOCB_ENABLED
66 static int docbook = 0;
67 #endif
68 #ifdef LIBXML_HTML_ENABLED
69 static int html = 0;
70 #endif
71 #ifdef LIBXML_XINCLUDE_ENABLED
72 static int xinclude = 0;
73 #endif
74 static int profile = 0;
75
76 static const char *params[16 + 1];
77 static int nbparams = 0;
78 static const char *output = NULL;
79
80 /*
81  *  The LaTeX translation table. Translate unicodes to LaTeX escape sequences.
82  */
83
84 //#define DEBUG
85
86 struct
87 {
88    int           unicode;
89    unsigned char *sequence;
90 } textab[] =
91 {
92    {  '#',     "\\#"              },
93    {  '$',     "\\$"              },
94    {  '%',     "\\%"              },
95    {  '&',     "\\&"              },
96    {  '<',     "\\verb+<+"        },
97    {  '>',     "\\verb+>+"        },
98    {  '\\',    "$\\backslash$"    },
99    {  '^',     "\\verb+^+"        },
100    {  '_',     "\\_"              },
101    {  '{',     "\\{"              },
102    {  '}',     "\\}"              },
103    {  '~',     "\\verb+~+"        },
104    {  160,     "~"                },
105    {  161,     "!`"               },
106    {  162,     "..."              },
107    {  163,     "\\pounds"         },
108    {  164,     "..."              },
109    {  165,     "..."              },
110    {  166,     "..."              },
111    {  167,     "\\S"              },
112    {  168,     "\\\"{ }"          },
113    {  169,     "\\copyright"      },
114    {  170,     "..."              },
115    {  171,     "..."              },
116    {  172,     "$\\neg$"          },
117    {  173,     "..."              },
118    {  174,     "..."              },
119    {  175,     "\\={ }"           },
120    {  176,     "$^{\\circ}$"      },
121    {  177,     "$\\pm$"           },
122    {  178,     "$^{2}$"           },
123    {  179,     "$^{3}$"           },
124    {  180,     "\\'{ }"           },
125    {  181,     "$\\mu$"           },
126    {  182,     "\\P"              },
127    {  183,     "$\\cdot$"         },
128    {  184,     "\\c{ }"           },
129    {  185,     "$^{1}$"           },
130    {  186,     "..."              },
131    {  187,     "..."              },
132    {  188,     "$\\frac{1}{4}$"   },
133    {  189,     "$\\frac{1}{2}$"   },
134    {  190,     "$\\frac{3}{4}$"   },
135    {  191,     "?`"               },
136    {  192,     "\\`{A}"           },
137    {  193,     "\\'{A}"           },
138    {  194,     "\\^{A}"           },
139    {  195,     "\\~{A}"           },
140    {  196,     "\\\"{A}"          },
141    {  197,     "\\AA"             },
142    {  198,     "\\AE"             },
143    {  199,     "\\c{C}"           },
144    {  200,     "\\`{E}"           },
145    {  201,     "\\'{E}"           },
146    {  202,     "\\^{E}"           },
147    {  203,     "\\\"{E}"          },
148    {  204,     "\\`{I}"           },
149    {  205,     "\\'{I}"           },
150    {  206,     "\\^{I}"           },
151    {  207,     "\\\"{I}"          },
152    {  208,     "..."              },
153    {  209,     "\\~{N}"           },
154    {  210,     "\\`{O}"           },
155    {  211,     "\\'{O}"           },
156    {  212,     "\\^{O}"           },
157    {  213,     "\\~{O}"           },
158    {  214,     "\\\"{O}"          },
159    {  215,     "$\\times$"        },
160    {  216,     "\\O"              },
161    {  217,     "\\`{U}"           },
162    {  218,     "\\'{U}"           },
163    {  219,     "\\^{U}"           },
164    {  220,     "\\\"{U}"          },
165    {  221,     "\\'{Y}"           },
166    {  222,     "..."              },
167    {  223,     "\\ss"             },
168    {  224,     "\\`{a}"           },
169    {  225,     "\\'{a}"           },
170    {  226,     "\\^{a}"           },
171    {  227,     "\\~{a}"           },
172    {  228,     "\\\"{a}"          },
173    {  229,     "\\aa"             },
174    {  230,     "\\ae"             },
175    {  231,     "\\c{c}"           },
176    {  232,     "\\`{e}"           },
177    {  233,     "\\'{e}"           },
178    {  234,     "\\^{e}"           },
179    {  235,     "\\\"{e}"          },
180    {  236,     "\\`{i}"           },
181    {  237,     "\\'{i}"           },
182    {  238,     "\\^{i}"           },
183    {  239,     "\\\"{i}"          },
184    {  240,     "..."              },
185    {  241,     "\\~{n}"           },
186    {  242,     "\\`{o}"           },
187    {  243,     "\\'{o}"           },
188    {  244,     "\\^{o}"           },
189    {  245,     "\\~{o}"           },
190    {  246,     "\\\"{o}"          },
191    {  247,     "$\\div$"          },
192    {  248,     "\\o"              },
193    {  249,     "\\`{u}"           },
194    {  250,     "\\'{u}"           },
195    {  251,     "\\^{u}"           },
196    {  252,     "\\\"{u}"          },
197    {  253,     "\\'{y}"           },
198    {  254,     "..."              },
199    {  255,     "\\\"{y}"          },
200    {  338,     "\\OE"             },
201    {  339,     "\\oe"             },
202    {  352,     "\\u{S}"           },
203    {  353,     "\\u{s}"           },
204    {  376,     "\\\"{Y}"          },
205    {  913,     "A"                },
206    {  914,     "B"                },
207    {  915,     "$\\Gamma$"        },
208    {  916,     "$\\Delta$"        },
209    {  917,     "E"                },
210    {  918,     "Z"                },
211    {  919,     "H"                },
212    {  920,     "$\\Theta$"        },
213    {  921,     "I"                },
214    {  922,     "K"                },
215    {  923,     "$\\Lambda$"       },
216    {  924,     "M"                },
217    {  925,     "N"                },
218    {  926,     "$\\Xi$"           },
219    {  927,     "O"                },
220    {  928,     "$\\Pi$"           },
221    {  929,     "P"                },
222    {  931,     "$\\Sigma$"        },
223    {  932,     "T"                },
224    {  933,     "$\\Upsilon$"      },
225    {  934,     "$\\Phi$"          },
226    {  935,     "X"                },
227    {  936,     "$\\Psi$"          },
228    {  937,     "$\\Omega$"        },
229    {  945,     "$\\alpha$"        },
230    {  946,     "$\\beta$"         },
231    {  947,     "$\\gamma$"        },
232    {  948,     "$\\delta$"        },
233    {  949,     "$\\epsilon$"      },
234    {  950,     "$\\zeta$"         },
235    {  951,     "$\\eta$"          },
236    {  952,     "$\\theta$"        },
237    {  953,     "$\\iota$"         },
238    {  954,     "$\\kappa$"        },
239    {  955,     "$\\lambda$"       },
240    {  956,     "$\\mu$"           },
241    {  957,     "$\\nu$"           },
242    {  958,     "$\\xi$"           },
243    {  959,     "o"                },
244    {  960,     "$\\pi$"           },
245    {  961,     "$\\rho$"          },
246    {  962,     "$\\varsigma$"     },
247    {  963,     "$\\sigma$"        },
248    {  964,     "$\\tau$"          },
249    {  965,     "$\\upsilon$"      },
250    {  966,     "$\\phi$"          },
251    {  967,     "$\\chi$"          },
252    {  968,     "$\\psi$"          },
253    {  969,     "$\\omega$"        },
254    { 8224,     "\\dag"            },
255    { 8225,     "\\ddag"           },
256    { 8226,     "$\\bullet$"       },
257    { 8230,     "$\\ldots$"        },
258    { 8242,     "$\\prime$"        },
259    { 8243,     "$\\prime\\prime$" },
260    { 8254,     "\\={ }"           },
261    { 8364,     "\\EUR"            },
262    { 8465,     "$\\Im$"           },
263    { 8472,     "$\\wp$"           },
264    { 8476,     "$\\Re$"           },
265    { 8482,     "$^{TM}$"          },
266    { 8501,     "$\\aleph$"        },
267    { 8592,     "$\\leftarrow$"    },
268    { 8593,     "$\\uparrow$"      },
269    { 8594,     "$\\rightarrow$"   },
270    { 8595,     "$\\downarrow$"    },
271    { 8596,     "$\\leftrightarrow$" },
272    { 8629,     "$\\hookleftarrow$"},
273    { 8656,     "$\\Leftarrow$"    },
274    { 8657,     "$\\Uparrow$"      },
275    { 8658,     "$\\Rightarrow$"   },
276    { 8659,     "$\\Downarrow$"    },
277    { 8660,     "$\\Leftrightarrow$" },
278    { 8704,     "$\\forall$"       },
279    { 8706,     "$\\partial$"      },
280    { 8707,     "$\\exists$"       },
281    { 8709,     "$\\emptyset$"     },
282    { 8711,     "$\\nabla$"        },
283    { 8712,     "$\\in$"           },
284    { 8713,     "..."              },
285    { 8715,     "$\\ni$"           },
286    { 8719,     "$\\prod$"         },
287    { 8721,     "$\\sum$"          },
288    { 8722,     "$-$"              },
289    { 8727,     "$\\ast$"          },
290    { 8730,     "$\\surd$"         },
291    { 8733,     "$\\propto$"       },
292    { 8734,     "$\\infty$"        },
293    { 8736,     "$\\angle$"        },
294    { 8743,     "$\\wedge$"        },
295    { 8744,     "$\\vee$"          },
296    { 8745,     "$\\cap$"          },
297    { 8746,     "$\\cup$"          },
298    { 8747,     "$\\int$"          },
299    { 8756,     "$\\leadsto$"      },
300    { 8764,     "$\\sim$"          },
301    { 8773,     "$\\cong$"         },
302    { 8776,     "$\\approx$"       },
303    { 8800,     "$\\neq$"          },
304    { 8801,     "$\\equiv$"        },
305    { 8804,     "$\\leq$"          },
306    { 8805,     "$\\geq$"          },
307    { 8834,     "$\\subset$"       },
308    { 8835,     "$\\supset$"       },
309    { 8836,     "..."              },
310    { 8838,     "$\\subseteq$"     },
311    { 8839,     "$\\supseteq$"     },
312    { 8853,     "$\\oplus$"        },
313    { 8855,     "$\\otimes$"       },
314    { 8869,     "$\\perp$"         },
315    { 8901,     "$\\cdot$"         },
316    { 8968,     "$\\lceil$"        },
317    { 8969,     "$\\rceil$"        },
318    { 8970,     "$\\lfloor$"       },
319    { 8971,     "$\\rfloor$"       },
320    { 9001,     "$\\langle$"       },
321    { 9002,     "$\\rangle$"       },
322    { 9674,     "$\\Diamond$"      },
323    { 9824,     "$\\spadesuit$"    },
324    { 9827,     "$\\clubsuit$"     },
325    { 9829,     "$\\heartsuit$"    },
326    { 9830,     "$\\diamondsuit$"  },
327 };
328
329 unsigned char *latex_translate(int code)
330 {
331    char   *translation;
332    int    i;
333
334    translation = 0;
335
336    for (i = 0; translation == 0 && textab[i].unicode <= code
337                && i < sizeof(textab) / sizeof(textab[0]); i++)
338    {
339       if (textab[i].unicode == code)
340       {
341          translation = textab[i].sequence;
342 #ifdef DEBUG
343          fprintf(stderr, "\n*** translation for 0x%04x is %s\n", code, translation);
344 #endif
345       }
346    }
347    return  translation;
348 }
349
350 static void
351 xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
352     xmlDocPtr res;
353
354 #ifdef LIBXML_XINCLUDE_ENABLED
355     if (xinclude) {
356         xmlXIncludeProcess(doc);
357     }
358 #endif
359     if (output == NULL) {
360         if (profile) {
361             res = xsltProfileStylesheet(cur, doc, params, stderr);
362         } else {
363             res = xsltApplyStylesheet(cur, doc, params);
364         }
365         xmlFreeDoc(doc);
366         if (res == NULL) {
367             fprintf(stderr, "no result for %s\n", filename);
368             return;
369         }
370         if (noout) {
371             xmlFreeDoc(res);
372             return;
373         }
374 #ifdef LIBXML_DEBUG_ENABLED
375         if (debug)
376             xmlDebugDumpDocument(stdout, res);
377         else {
378 #endif
379             if (cur->methodURI == NULL) {
380                 xsltSaveResultToFile(stdout, res, cur);
381             } else {
382                 if (xmlStrEqual
383                     (cur->method, (const xmlChar *) "xhtml")) {
384                     fprintf(stderr, "non standard output xhtml\n");
385                     xsltSaveResultToFile(stdout, res, cur);
386                 } else {
387                     fprintf(stderr,
388                             "Unsupported non standard output %s\n",
389                             cur->method);
390                     xsltSaveResultToFile(stdout, res, cur);
391                 }
392             }
393 #ifdef LIBXML_DEBUG_ENABLED
394         }
395 #endif
396
397         xmlFreeDoc(res);
398     } else {
399         xsltRunStylesheet(cur, doc, params, output, NULL, NULL);
400         xmlFreeDoc(doc);
401     }
402 }
403
404
405 void LatexEscape(xmlNodePtr node)
406 {
407    xmlNodePtr  child;
408    xmlChar     *byte;
409    int         unicode;
410
411    unsigned char  *translation, *replacement;
412    int            textlen;
413    int            i;
414
415    if (xmlNodeIsText(node))
416    {
417 #ifdef DEBUG
418       fprintf(stderr, "\n-------- Text node (%d bytes):\n%s",
419                       strlen(node->content), node->content);
420 #endif
421
422       textlen = strlen(node->content);
423       if (textlen < 100)
424       {
425          textlen = 100;
426       }
427       replacement = malloc(textlen);
428       i           = 0;
429       
430       for (byte = node->content; *byte != '\0'; byte++)
431       {
432          /* transform from utf-8 to unicode */
433
434          if ((*byte & 0x80) == 0)
435          {
436             unicode = *byte;
437          }
438          else if ((*byte & 0xe0) == 0xc0)
439          {
440 #ifdef DEBUG
441             fprintf(stderr, "2-byte unicode: 0x%02x, 0x%02x\n",byte[0], byte[1]);
442 #endif
443             unicode = (*byte & 0x1f) << 6;
444             byte++;
445             unicode |= *byte & 0x3f;
446 #ifdef DEBUG
447             fprintf(stderr, "Unicode = 0x%04x\n", unicode);
448 #endif
449          }
450          else if ((*byte & 0xf0) == 0xe0)
451          {
452              /*  3-byte unicode */
453
454             unicode = (*byte & 0x0f) << 12;
455             byte++;
456             unicode |= (*byte & 0x3f) << 6;
457             byte++;
458             unicode |= *byte & 0x3f;
459          }
460          else
461          {
462             fprintf(stderr, "More than 3 bytes utf-8 is not supported.\n");
463          }
464
465          translation = latex_translate(unicode);
466
467          /*  Append the original byte or the translation to the replacment text */
468
469          if (translation == 0)
470          {
471             if (i + 1 >= textlen)
472             {
473                textlen += 100;
474                replacement = realloc(replacement, textlen);
475             }
476             replacement[i++] = *byte;
477          }
478          else
479          {
480             int   j;
481
482             if (i + strlen(translation) + 1 >= textlen)
483             {
484                textlen += 100;
485                replacement = realloc(replacement, textlen);
486             }
487             for (j = 0; translation[j]; j++)
488             {
489                replacement[i++] = translation[j];
490             } 
491          }
492       }
493       replacement[i] = '\0';
494       xmlNodeSetContent(node, replacement);
495 #ifdef DEBUG
496       fprintf(stderr, "\n-------- Replacement text:\n%s", replacement);
497 #endif
498       free(replacement);
499    }
500    else
501    {
502       for (child = node->children; child != 0; child = child->next)
503       {
504          if (strcmp(child->name, "verbatim") != 0)
505          {
506             LatexEscape(child);
507          }
508       }
509    }
510 }
511
512 static void usage(const char *name)
513 {
514     printf("Usage: %s [options] stylesheet file [file ...]\n", name);
515     printf("   Options:\n");
516     printf("\t--version or -V: show the version of libxml and libxslt used\n");
517     printf("\t--verbose or -v: show logs of what's happening\n");
518     printf("\t--output file or -o file: save to a given file\n");
519     printf("\t--debug: dump the tree of the result instead\n");
520     printf("\t--latex: transform special characters for latex\n");
521     printf("\t--novalid: skip the Dtd loading phase\n");
522     printf("\t--noout: do not dump the result\n");
523     printf("\t--maxdepth val : increase the maximum depth\n");
524 #ifdef LIBXML_HTML_ENABLED
525     printf("\t--html: the input document is(are) an HTML file(s)\n");
526 #endif
527 #ifdef LIBXML_DOCB_ENABLED
528     printf("\t--docbook: the input document is SGML docbook\n");
529 #endif
530     printf("\t--param name value : pass a (parameter,value) pair\n");
531     printf("\t      string values must be quoted like \"'string'\"\n");
532     printf("\t--nonet refuse to fetch DTDs or entities over network\n");
533 #ifdef LIBXML_CATALOG_ENABLED
534     printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
535     printf("\t             otherwise XML Catalogs starting from \n");
536     printf("\t         file:///etc/xml/catalog are activated by default\n");
537 #endif
538 #ifdef LIBXML_XINCLUDE_ENABLED
539     printf("\t--xinclude : do XInclude processing on document intput\n");
540 #endif
541     printf("\t--profile or --norman : dump profiling informations \n");
542 }
543
544 int
545 main(int argc, char **argv)
546 {
547     int i;
548     xsltStylesheetPtr cur = NULL;
549     xmlDocPtr doc, style;
550
551     if (argc <= 1) {
552         usage(argv[0]);
553         return (1);
554     }
555
556     xmlInitMemory();
557
558     LIBXML_TEST_VERSION
559
560     xmlLineNumbersDefault(1);
561
562     if (novalid == 0)
563         xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
564     else
565         xmlLoadExtDtdDefaultValue = 0;
566     for (i = 1; i < argc; i++) {
567         if (!strcmp(argv[i], "-"))
568             break;
569
570         if (argv[i][0] != '-')
571             continue;
572 #ifdef LIBXML_DEBUG_ENABLED
573         if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) {
574             debug++;
575         } else
576 #endif
577         if ((!strcmp(argv[i], "-v")) ||
578                 (!strcmp(argv[i], "-verbose")) ||
579                 (!strcmp(argv[i], "--verbose"))) {
580             xsltSetGenericDebugFunc(stderr, NULL);
581         } else if ((!strcmp(argv[i], "-o")) ||
582                    (!strcmp(argv[i], "-output")) ||
583                    (!strcmp(argv[i], "--output"))) {
584             i++;
585             output = argv[i++];
586         } else if ((!strcmp(argv[i], "-V")) ||
587                    (!strcmp(argv[i], "-version")) ||
588                    (!strcmp(argv[i], "--version")))
589         {
590
591         } else if ((!strcmp(argv[i], "-novalid")) ||
592                    (!strcmp(argv[i], "--novalid"))) {
593             novalid++;
594         } else if ((!strcmp(argv[i], "-latex")) ||
595                    (!strcmp(argv[i], "--latex"))) {
596             latex++;
597         } else if ((!strcmp(argv[i], "-noout")) ||
598                    (!strcmp(argv[i], "--noout"))) {
599             noout++;
600 #ifdef LIBXML_DOCB_ENABLED
601         } else if ((!strcmp(argv[i], "-docbook")) ||
602                    (!strcmp(argv[i], "--docbook"))) {
603             docbook++;
604 #endif
605 #ifdef LIBXML_HTML_ENABLED
606         } else if ((!strcmp(argv[i], "-html")) ||
607                    (!strcmp(argv[i], "--html"))) {
608             html++;
609 #endif
610         } else if ((!strcmp(argv[i], "-profile")) ||
611                    (!strcmp(argv[i], "--profile"))) {
612             profile++;
613         } else if ((!strcmp(argv[i], "-norman")) ||
614                    (!strcmp(argv[i], "--norman"))) {
615             profile++;
616         } else if ((!strcmp(argv[i], "-nonet")) ||
617                    (!strcmp(argv[i], "--nonet"))) {
618             xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
619 #ifdef LIBXML_CATALOG_ENABLED
620         } else if ((!strcmp(argv[i], "-catalogs")) ||
621                    (!strcmp(argv[i], "--catalogs"))) {
622             const char *catalogs;
623
624             catalogs = getenv("SGML_CATALOG_FILES");
625             if (catalogs == NULL) {
626                 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
627             } else {
628                 xmlLoadCatalogs(catalogs);
629             }
630 #endif
631 #ifdef LIBXML_XINCLUDE_ENABLED
632         } else if ((!strcmp(argv[i], "-xinclude")) ||
633                    (!strcmp(argv[i], "--xinclude"))) {
634             xinclude++;
635             xsltSetXIncludeDefault(1);
636 #endif
637         } else if ((!strcmp(argv[i], "-param")) ||
638                    (!strcmp(argv[i], "--param"))) {
639             i++;
640             params[nbparams++] = argv[i++];
641             params[nbparams++] = argv[i];
642             if (nbparams >= 16) {
643                 fprintf(stderr, "too many params\n");
644                 return (1);
645             }
646         } else if ((!strcmp(argv[i], "-maxdepth")) ||
647                    (!strcmp(argv[i], "--maxdepth"))) {
648             int value;
649
650             i++;
651             if (sscanf(argv[i], "%d", &value) == 1) {
652                 if (value > 0)
653                     xsltMaxDepth = value;
654             }
655         } else {
656             fprintf(stderr, "Unknown option %s\n", argv[i]);
657             usage(argv[0]);
658             return (1);
659         }
660     }
661     params[nbparams] = NULL;
662
663     /*
664      * Replace entities with their content.
665      */
666     xmlSubstituteEntitiesDefault(1);
667
668     /*
669      * Register the EXSLT extensions and the test module
670      */
671     exsltRegisterAll();
672     //xsltRegisterTestModule();
673
674     for (i = 1; i < argc; i++) {
675         if ((!strcmp(argv[i], "-maxdepth")) ||
676             (!strcmp(argv[i], "--maxdepth"))) {
677             i++;
678             continue;
679         } else if ((!strcmp(argv[i], "-o")) ||
680                    (!strcmp(argv[i], "-output")) ||
681                    (!strcmp(argv[i], "--output"))) {
682             i++;
683             continue;
684         }
685         if ((!strcmp(argv[i], "-param")) || (!strcmp(argv[i], "--param"))) {
686             i += 2;
687             continue;
688         }
689         if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
690             style = xmlParseFile((const char *) argv[i]);
691             if (style == NULL) {
692                 fprintf(stderr,  "cannot parse %s\n", argv[i]);
693                 cur = NULL;
694             } else {
695                 cur = xsltLoadStylesheetPI(style);
696                 if (cur != NULL) {
697                     /* it is an embedded stylesheet */
698                     xsltProcess(style, cur, argv[i]);
699                     xsltFreeStylesheet(cur);
700                     goto done;
701                 }
702                 cur = xsltParseStylesheetDoc(style);
703                 if (cur != NULL) {
704                     if (cur->indent == 1)
705                         xmlIndentTreeOutput = 1;
706                     else
707                         xmlIndentTreeOutput = 0;
708                     i++;
709                 } else {
710                     xmlFreeDoc(style);
711                     goto done;
712                 }
713             }
714             break;
715
716         }
717     }
718
719     /*
720      * disable CDATA from being built in the document tree
721      */
722     xmlDefaultSAXHandlerInit();
723     xmlDefaultSAXHandler.cdataBlock = NULL;
724
725     if ((cur != NULL) && (cur->errors == 0)) {
726         for (; i < argc; i++) {
727             doc = NULL;
728 #ifdef LIBXML_HTML_ENABLED
729             if (html)
730                 doc = htmlParseFile(argv[i], NULL);
731             else
732 #endif
733 #ifdef LIBXML_DOCB_ENABLED
734             if (docbook)
735                 doc = docbParseFile(argv[i], NULL);
736             else
737 #endif
738                 doc = xmlParseFile(argv[i]);
739             if (doc == NULL) {
740                 fprintf(stderr, "unable to parse %s\n", argv[i]);
741                 continue;
742             }
743             if (latex)
744             {
745                LatexEscape(xmlDocGetRootElement(doc));
746             }
747             xsltProcess(doc, cur, argv[i]);
748         }
749     }
750     if (cur != NULL)
751         xsltFreeStylesheet(cur);
752 done:
753     //xsltCleanupGlobals();
754     xmlCleanupParser();
755     xmlMemoryDump();
756     return (0);
757 }
758