2 * xsltproc.c: user program for the XSL Transformation 1.0 engine
4 * See Copyright for the status of this software.
9 //#include <libxslt/libxslt.h>
10 //#include <libexslt/exslt.h>
12 #ifdef HAVE_SYS_STAT_H
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>
29 #ifdef LIBXML_XINCLUDE_ENABLED
30 #include <libxml/xinclude.h>
32 #ifdef LIBXML_CATALOG_ENABLED
33 #include <libxml/catalog.h>
35 #include <libxml/parserInternals.h>
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>
43 #include <libexslt/exsltconfig.h>
48 /* MS C library seems to define stat and _stat. The definition
49 * is identical. Still, mapping them to each other causes a warning. */
51 # define stat(x,y) _stat(x,y)
57 xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
59 xmlParserCtxtPtr ctxt);
62 static int novalid = 0;
65 #ifdef LIBXML_DOCB_ENABLED
66 static int docbook = 0;
68 #ifdef LIBXML_HTML_ENABLED
71 #ifdef LIBXML_XINCLUDE_ENABLED
72 static int xinclude = 0;
74 static int profile = 0;
76 static const char *params[16 + 1];
77 static int nbparams = 0;
78 static const char *output = NULL;
81 * The LaTeX translation table. Translate unicodes to LaTeX escape sequences.
89 unsigned char *sequence;
98 { '\\', "$\\backslash$" },
103 { '~', "\\verb+~+" },
113 { 169, "\\copyright" },
120 { 176, "$^{\\circ}$" },
132 { 188, "$\\frac{1}{4}$" },
133 { 189, "$\\frac{1}{2}$" },
134 { 190, "$\\frac{3}{4}$" },
159 { 215, "$\\times$" },
207 { 915, "$\\Gamma$" },
208 { 916, "$\\Delta$" },
212 { 920, "$\\Theta$" },
215 { 923, "$\\Lambda$" },
222 { 931, "$\\Sigma$" },
224 { 933, "$\\Upsilon$" },
228 { 937, "$\\Omega$" },
229 { 945, "$\\alpha$" },
231 { 947, "$\\gamma$" },
232 { 948, "$\\delta$" },
233 { 949, "$\\epsilon$" },
236 { 952, "$\\theta$" },
238 { 954, "$\\kappa$" },
239 { 955, "$\\lambda$" },
246 { 962, "$\\varsigma$" },
247 { 963, "$\\sigma$" },
249 { 965, "$\\upsilon$" },
253 { 969, "$\\omega$" },
256 { 8226, "$\\bullet$" },
257 { 8230, "$\\ldots$" },
258 { 8242, "$\\prime$" },
259 { 8243, "$\\prime\\prime$" },
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$" },
286 { 8719, "$\\prod$" },
290 { 8730, "$\\surd$" },
291 { 8733, "$\\propto$" },
292 { 8734, "$\\infty$" },
293 { 8736, "$\\angle$" },
294 { 8743, "$\\wedge$" },
299 { 8756, "$\\leadsto$" },
301 { 8773, "$\\cong$" },
302 { 8776, "$\\approx$" },
304 { 8801, "$\\equiv$" },
307 { 8834, "$\\subset$" },
308 { 8835, "$\\supset$" },
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$" },
329 unsigned char *latex_translate(int code)
336 for (i = 0; translation == 0 && textab[i].unicode <= code
337 && i < sizeof(textab) / sizeof(textab[0]); i++)
339 if (textab[i].unicode == code)
341 translation = textab[i].sequence;
343 fprintf(stderr, "\n*** translation for 0x%04x is %s\n", code, translation);
351 xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
354 #ifdef LIBXML_XINCLUDE_ENABLED
356 xmlXIncludeProcess(doc);
359 if (output == NULL) {
361 res = xsltProfileStylesheet(cur, doc, params, stderr);
363 res = xsltApplyStylesheet(cur, doc, params);
367 fprintf(stderr, "no result for %s\n", filename);
374 #ifdef LIBXML_DEBUG_ENABLED
376 xmlDebugDumpDocument(stdout, res);
379 if (cur->methodURI == NULL) {
380 xsltSaveResultToFile(stdout, res, cur);
383 (cur->method, (const xmlChar *) "xhtml")) {
384 fprintf(stderr, "non standard output xhtml\n");
385 xsltSaveResultToFile(stdout, res, cur);
388 "Unsupported non standard output %s\n",
390 xsltSaveResultToFile(stdout, res, cur);
393 #ifdef LIBXML_DEBUG_ENABLED
399 xsltRunStylesheet(cur, doc, params, output, NULL, NULL);
405 void LatexEscape(xmlNodePtr node)
411 unsigned char *translation, *replacement;
415 if (xmlNodeIsText(node))
418 fprintf(stderr, "\n-------- Text node (%d bytes):\n%s",
419 strlen(node->content), node->content);
422 textlen = strlen(node->content);
427 replacement = malloc(textlen);
430 for (byte = node->content; *byte != '\0'; byte++)
432 /* transform from utf-8 to unicode */
434 if ((*byte & 0x80) == 0)
438 else if ((*byte & 0xe0) == 0xc0)
441 fprintf(stderr, "2-byte unicode: 0x%02x, 0x%02x\n",byte[0], byte[1]);
443 unicode = (*byte & 0x1f) << 6;
445 unicode |= *byte & 0x3f;
447 fprintf(stderr, "Unicode = 0x%04x\n", unicode);
450 else if ((*byte & 0xf0) == 0xe0)
454 unicode = (*byte & 0x0f) << 12;
456 unicode |= (*byte & 0x3f) << 6;
458 unicode |= *byte & 0x3f;
462 fprintf(stderr, "More than 3 bytes utf-8 is not supported.\n");
465 translation = latex_translate(unicode);
467 /* Append the original byte or the translation to the replacment text */
469 if (translation == 0)
471 if (i + 1 >= textlen)
474 replacement = realloc(replacement, textlen);
476 replacement[i++] = *byte;
482 if (i + strlen(translation) + 1 >= textlen)
485 replacement = realloc(replacement, textlen);
487 for (j = 0; translation[j]; j++)
489 replacement[i++] = translation[j];
493 replacement[i] = '\0';
494 xmlNodeSetContent(node, replacement);
496 fprintf(stderr, "\n-------- Replacement text:\n%s", replacement);
502 for (child = node->children; child != 0; child = child->next)
504 if (strcmp(child->name, "verbatim") != 0)
512 static void usage(const char *name)
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");
527 #ifdef LIBXML_DOCB_ENABLED
528 printf("\t--docbook: the input document is SGML docbook\n");
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");
538 #ifdef LIBXML_XINCLUDE_ENABLED
539 printf("\t--xinclude : do XInclude processing on document intput\n");
541 printf("\t--profile or --norman : dump profiling informations \n");
545 main(int argc, char **argv)
548 xsltStylesheetPtr cur = NULL;
549 xmlDocPtr doc, style;
560 xmlLineNumbersDefault(1);
563 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
565 xmlLoadExtDtdDefaultValue = 0;
566 for (i = 1; i < argc; i++) {
567 if (!strcmp(argv[i], "-"))
570 if (argv[i][0] != '-')
572 #ifdef LIBXML_DEBUG_ENABLED
573 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) {
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"))) {
586 } else if ((!strcmp(argv[i], "-V")) ||
587 (!strcmp(argv[i], "-version")) ||
588 (!strcmp(argv[i], "--version")))
591 } else if ((!strcmp(argv[i], "-novalid")) ||
592 (!strcmp(argv[i], "--novalid"))) {
594 } else if ((!strcmp(argv[i], "-latex")) ||
595 (!strcmp(argv[i], "--latex"))) {
597 } else if ((!strcmp(argv[i], "-noout")) ||
598 (!strcmp(argv[i], "--noout"))) {
600 #ifdef LIBXML_DOCB_ENABLED
601 } else if ((!strcmp(argv[i], "-docbook")) ||
602 (!strcmp(argv[i], "--docbook"))) {
605 #ifdef LIBXML_HTML_ENABLED
606 } else if ((!strcmp(argv[i], "-html")) ||
607 (!strcmp(argv[i], "--html"))) {
610 } else if ((!strcmp(argv[i], "-profile")) ||
611 (!strcmp(argv[i], "--profile"))) {
613 } else if ((!strcmp(argv[i], "-norman")) ||
614 (!strcmp(argv[i], "--norman"))) {
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;
624 catalogs = getenv("SGML_CATALOG_FILES");
625 if (catalogs == NULL) {
626 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
628 xmlLoadCatalogs(catalogs);
631 #ifdef LIBXML_XINCLUDE_ENABLED
632 } else if ((!strcmp(argv[i], "-xinclude")) ||
633 (!strcmp(argv[i], "--xinclude"))) {
635 xsltSetXIncludeDefault(1);
637 } else if ((!strcmp(argv[i], "-param")) ||
638 (!strcmp(argv[i], "--param"))) {
640 params[nbparams++] = argv[i++];
641 params[nbparams++] = argv[i];
642 if (nbparams >= 16) {
643 fprintf(stderr, "too many params\n");
646 } else if ((!strcmp(argv[i], "-maxdepth")) ||
647 (!strcmp(argv[i], "--maxdepth"))) {
651 if (sscanf(argv[i], "%d", &value) == 1) {
653 xsltMaxDepth = value;
656 fprintf(stderr, "Unknown option %s\n", argv[i]);
661 params[nbparams] = NULL;
664 * Replace entities with their content.
666 xmlSubstituteEntitiesDefault(1);
669 * Register the EXSLT extensions and the test module
672 //xsltRegisterTestModule();
674 for (i = 1; i < argc; i++) {
675 if ((!strcmp(argv[i], "-maxdepth")) ||
676 (!strcmp(argv[i], "--maxdepth"))) {
679 } else if ((!strcmp(argv[i], "-o")) ||
680 (!strcmp(argv[i], "-output")) ||
681 (!strcmp(argv[i], "--output"))) {
685 if ((!strcmp(argv[i], "-param")) || (!strcmp(argv[i], "--param"))) {
689 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
690 style = xmlParseFile((const char *) argv[i]);
692 fprintf(stderr, "cannot parse %s\n", argv[i]);
695 cur = xsltLoadStylesheetPI(style);
697 /* it is an embedded stylesheet */
698 xsltProcess(style, cur, argv[i]);
699 xsltFreeStylesheet(cur);
702 cur = xsltParseStylesheetDoc(style);
704 if (cur->indent == 1)
705 xmlIndentTreeOutput = 1;
707 xmlIndentTreeOutput = 0;
720 * disable CDATA from being built in the document tree
722 xmlDefaultSAXHandlerInit();
723 xmlDefaultSAXHandler.cdataBlock = NULL;
725 if ((cur != NULL) && (cur->errors == 0)) {
726 for (; i < argc; i++) {
728 #ifdef LIBXML_HTML_ENABLED
730 doc = htmlParseFile(argv[i], NULL);
733 #ifdef LIBXML_DOCB_ENABLED
735 doc = docbParseFile(argv[i], NULL);
738 doc = xmlParseFile(argv[i]);
740 fprintf(stderr, "unable to parse %s\n", argv[i]);
745 LatexEscape(xmlDocGetRootElement(doc));
747 xsltProcess(doc, cur, argv[i]);
751 xsltFreeStylesheet(cur);
753 //xsltCleanupGlobals();