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_XINCLUDE_ENABLED
27 #include <libxml/xinclude.h>
29 #ifdef LIBXML_CATALOG_ENABLED
30 #include <libxml/catalog.h>
32 #include <libxml/parserInternals.h>
34 #include <libxslt/xslt.h>
35 #include <libxslt/xsltInternals.h>
36 #include <libxslt/transform.h>
37 #include <libxslt/xsltutils.h>
38 #include <libxslt/extensions.h>
40 #include <libexslt/exsltconfig.h>
45 /* MS C library seems to define stat and _stat. The definition
46 * is identical. Still, mapping them to each other causes a warning. */
48 # define stat(x,y) _stat(x,y)
54 xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
56 xmlParserCtxtPtr ctxt);
59 static int novalid = 0;
62 #ifdef LIBXML_DOCB_ENABLED
63 static int docbook = 0;
65 #ifdef LIBXML_HTML_ENABLED
69 static const char *params[16 + 1];
70 static int nbparams = 0;
71 static const char *output = NULL;
73 void LatexEscape(xmlNodePtr node);
76 * The LaTeX translation table. Translate unicodes to LaTeX escape sequences.
84 unsigned char *sequence;
93 { '\\', "$\\backslash$" },
108 { 169, "\\copyright" },
115 { 176, "$^{\\circ}$" },
127 { 188, "$\\frac{1}{4}$" },
128 { 189, "$\\frac{1}{2}$" },
129 { 190, "$\\frac{3}{4}$" },
154 { 215, "$\\times$" },
202 { 915, "$\\Gamma$" },
203 { 916, "$\\Delta$" },
207 { 920, "$\\Theta$" },
210 { 923, "$\\Lambda$" },
217 { 931, "$\\Sigma$" },
219 { 933, "$\\Upsilon$" },
223 { 937, "$\\Omega$" },
224 { 945, "$\\alpha$" },
226 { 947, "$\\gamma$" },
227 { 948, "$\\delta$" },
228 { 949, "$\\epsilon$" },
231 { 952, "$\\theta$" },
233 { 954, "$\\kappa$" },
234 { 955, "$\\lambda$" },
241 { 962, "$\\varsigma$" },
242 { 963, "$\\sigma$" },
244 { 965, "$\\upsilon$" },
248 { 969, "$\\omega$" },
251 { 8226, "$\\bullet$" },
252 { 8230, "$\\ldots$" },
253 { 8242, "$\\prime$" },
254 { 8243, "$\\prime\\prime$" },
261 { 8501, "$\\aleph$" },
262 { 8592, "$\\leftarrow$" },
263 { 8593, "$\\uparrow$" },
264 { 8594, "$\\rightarrow$" },
265 { 8595, "$\\downarrow$" },
266 { 8596, "$\\leftrightarrow$" },
267 { 8629, "$\\hookleftarrow$"},
268 { 8656, "$\\Leftarrow$" },
269 { 8657, "$\\Uparrow$" },
270 { 8658, "$\\Rightarrow$" },
271 { 8659, "$\\Downarrow$" },
272 { 8660, "$\\Leftrightarrow$" },
273 { 8704, "$\\forall$" },
274 { 8706, "$\\partial$" },
275 { 8707, "$\\exists$" },
276 { 8709, "$\\emptyset$" },
277 { 8711, "$\\nabla$" },
281 { 8719, "$\\prod$" },
285 { 8730, "$\\surd$" },
286 { 8733, "$\\propto$" },
287 { 8734, "$\\infty$" },
288 { 8736, "$\\angle$" },
289 { 8743, "$\\wedge$" },
294 { 8756, "$\\leadsto$" },
296 { 8773, "$\\cong$" },
297 { 8776, "$\\approx$" },
299 { 8801, "$\\equiv$" },
302 { 8834, "$\\subset$" },
303 { 8835, "$\\supset$" },
305 { 8838, "$\\subseteq$" },
306 { 8839, "$\\supseteq$" },
307 { 8853, "$\\oplus$" },
308 { 8855, "$\\otimes$" },
309 { 8869, "$\\perp$" },
310 { 8901, "$\\cdot$" },
311 { 8968, "$\\lceil$" },
312 { 8969, "$\\rceil$" },
313 { 8970, "$\\lfloor$" },
314 { 8971, "$\\rfloor$" },
315 { 9001, "$\\langle$" },
316 { 9002, "$\\rangle$" },
317 { 9674, "$\\Diamond$" },
318 { 9824, "$\\spadesuit$" },
319 { 9827, "$\\clubsuit$" },
320 { 9829, "$\\heartsuit$" },
321 { 9830, "$\\diamondsuit$" },
324 unsigned char *latex_translate(int code)
331 for (i = 0; translation == 0 && textab[i].unicode <= code
332 && i < sizeof(textab) / sizeof(textab[0]); i++)
334 if (textab[i].unicode == code)
336 translation = textab[i].sequence;
338 fprintf(stderr, "\n*** translation for 0x%04x is %s\n", code, translation);
346 xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
349 xmlXIncludeProcessFlags(doc, XSLT_PARSE_OPTIONS);
353 LatexEscape(xmlDocGetRootElement(doc));
356 if (output == NULL) {
357 res = xsltApplyStylesheet(cur, doc, params);
361 fprintf(stderr, "no result for %s\n", filename);
368 #ifdef LIBXML_DEBUG_ENABLED
370 xmlDebugDumpDocument(stdout, res);
373 if (cur->methodURI == NULL) {
374 xsltSaveResultToFile(stdout, res, cur);
377 (cur->method, (const xmlChar *) "xhtml")) {
378 fprintf(stderr, "non standard output xhtml\n");
379 xsltSaveResultToFile(stdout, res, cur);
382 "Unsupported non standard output %s\n",
384 xsltSaveResultToFile(stdout, res, cur);
387 #ifdef LIBXML_DEBUG_ENABLED
393 xsltRunStylesheet(cur, doc, params, output, NULL, NULL);
399 void LatexEscape(xmlNodePtr node)
405 unsigned char *translation, *replacement;
409 if (xmlNodeIsText(node))
412 fprintf(stderr, "\n-------- Text node at %p (%d bytes):\n%s",
413 node, strlen(node->content), node->content);
416 textlen = strlen(node->content);
421 replacement = malloc(textlen);
424 for (byte = node->content; *byte != '\0'; byte++)
426 /* transform from utf-8 to unicode */
428 if ((*byte & 0x80) == 0)
432 else if ((*byte & 0xe0) == 0xc0)
435 fprintf(stderr, "2-byte unicode: 0x%02x, 0x%02x\n",byte[0], byte[1]);
437 unicode = (*byte & 0x1f) << 6;
439 unicode |= *byte & 0x3f;
441 fprintf(stderr, "Unicode = 0x%04x\n", unicode);
444 else if ((*byte & 0xf0) == 0xe0)
448 unicode = (*byte & 0x0f) << 12;
450 unicode |= (*byte & 0x3f) << 6;
452 unicode |= *byte & 0x3f;
456 fprintf(stderr, "More than 3 bytes utf-8 is not supported.\n");
459 translation = latex_translate(unicode);
461 /* Append the original byte or the translation to the replacment text */
463 if (translation == 0)
465 if (i + 1 >= textlen)
468 replacement = realloc(replacement, textlen);
470 replacement[i++] = *byte;
476 if (i + strlen(translation) + 1 >= textlen)
479 replacement = realloc(replacement, textlen);
481 for (j = 0; translation[j]; j++)
483 replacement[i++] = translation[j];
487 replacement[i] = '\0';
488 xmlNodeSetContent(node, replacement);
490 fprintf(stderr, "\n-------- Replacement text:\n%s", replacement);
496 for (child = node->children; child != 0; child = child->next)
498 if (strcmp(child->name, "verbatim") != 0 )
506 static void usage(const char *name)
508 printf("Usage: %s [options] stylesheet file [file ...]\n", name);
509 printf(" Options:\n");
510 printf("\t--version or -V: show the version of libxml and libxslt used\n");
511 printf("\t--verbose or -v: show logs of what's happening\n");
512 printf("\t--output file or -o file: save to a given file\n");
513 printf("\t--debug: dump the tree of the result instead\n");
514 printf("\t--latex: transform special characters for latex\n");
515 printf("\t--novalid: skip the Dtd loading phase\n");
516 printf("\t--noout: do not dump the result\n");
517 printf("\t--maxdepth val : increase the maximum depth\n");
518 #ifdef LIBXML_HTML_ENABLED
519 printf("\t--html: the input document is(are) an HTML file(s)\n");
521 #ifdef LIBXML_DOCB_ENABLED
522 printf("\t--docbook: the input document is SGML docbook\n");
524 printf("\t--param name value : pass a (parameter,value) pair\n");
525 printf("\t string values must be quoted like \"'string'\"\n");
526 printf("\t--nonet refuse to fetch DTDs or entities over network\n");
527 #ifdef LIBXML_CATALOG_ENABLED
528 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
529 printf("\t otherwise XML Catalogs starting from \n");
530 printf("\t file:///etc/xml/catalog are activated by default\n");
535 main(int argc, char **argv)
538 xsltStylesheetPtr cur = NULL;
539 xmlDocPtr doc, style;
550 xmlLineNumbersDefault(1);
553 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
555 xmlLoadExtDtdDefaultValue = 0;
556 for (i = 1; i < argc; i++) {
557 if (!strcmp(argv[i], "-"))
560 if (argv[i][0] != '-')
562 #ifdef LIBXML_DEBUG_ENABLED
563 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) {
567 if ((!strcmp(argv[i], "-v")) ||
568 (!strcmp(argv[i], "-verbose")) ||
569 (!strcmp(argv[i], "--verbose"))) {
570 xsltSetGenericDebugFunc(stderr, NULL);
571 } else if ((!strcmp(argv[i], "-o")) ||
572 (!strcmp(argv[i], "-output")) ||
573 (!strcmp(argv[i], "--output"))) {
576 } else if ((!strcmp(argv[i], "-V")) ||
577 (!strcmp(argv[i], "-version")) ||
578 (!strcmp(argv[i], "--version")))
581 } else if ((!strcmp(argv[i], "-novalid")) ||
582 (!strcmp(argv[i], "--novalid"))) {
584 } else if ((!strcmp(argv[i], "-latex")) ||
585 (!strcmp(argv[i], "--latex"))) {
587 } else if ((!strcmp(argv[i], "-noout")) ||
588 (!strcmp(argv[i], "--noout"))) {
590 #ifdef LIBXML_HTML_ENABLED
591 } else if ((!strcmp(argv[i], "-html")) ||
592 (!strcmp(argv[i], "--html"))) {
595 } else if ((!strcmp(argv[i], "-nonet")) ||
596 (!strcmp(argv[i], "--nonet"))) {
597 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
598 #ifdef LIBXML_CATALOG_ENABLED
599 } else if ((!strcmp(argv[i], "-catalogs")) ||
600 (!strcmp(argv[i], "--catalogs"))) {
601 const char *catalogs;
603 catalogs = getenv("SGML_CATALOG_FILES");
604 if (catalogs == NULL) {
605 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
607 xmlLoadCatalogs(catalogs);
610 } else if ((!strcmp(argv[i], "-param")) ||
611 (!strcmp(argv[i], "--param"))) {
613 params[nbparams++] = argv[i++];
614 params[nbparams++] = argv[i];
615 if (nbparams >= 16) {
616 fprintf(stderr, "too many params\n");
619 } else if ((!strcmp(argv[i], "-maxdepth")) ||
620 (!strcmp(argv[i], "--maxdepth"))) {
624 if (sscanf(argv[i], "%d", &value) == 1) {
626 xsltMaxDepth = value;
629 fprintf(stderr, "Unknown option %s\n", argv[i]);
634 params[nbparams] = NULL;
636 xsltSetXIncludeDefault(1);
638 * Replace entities with their content.
640 xmlSubstituteEntitiesDefault(1);
643 * Register the EXSLT extensions and the test module
646 //xsltRegisterTestModule();
648 for (i = 1; i < argc; i++) {
649 if ((!strcmp(argv[i], "-maxdepth")) ||
650 (!strcmp(argv[i], "--maxdepth"))) {
653 } else if ((!strcmp(argv[i], "-o")) ||
654 (!strcmp(argv[i], "-output")) ||
655 (!strcmp(argv[i], "--output"))) {
659 if ((!strcmp(argv[i], "-param")) || (!strcmp(argv[i], "--param"))) {
663 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
664 style = xmlParseFile((const char *) argv[i]);
666 fprintf(stderr, "cannot parse %s\n", argv[i]);
669 cur = xsltLoadStylesheetPI(style);
671 /* it is an embedded stylesheet */
672 xsltProcess(style, cur, argv[i]);
673 xsltFreeStylesheet(cur);
676 cur = xsltParseStylesheetDoc(style);
678 if (cur->indent == 1)
679 xmlIndentTreeOutput = 1;
681 xmlIndentTreeOutput = 0;
694 * disable CDATA from being built in the document tree
696 xmlDefaultSAXHandlerInit();
697 xmlDefaultSAXHandler.cdataBlock = NULL;
699 if ((cur != NULL) && (cur->errors == 0)) {
700 for (; i < argc; i++) {
702 #ifdef LIBXML_HTML_ENABLED
704 doc = htmlParseFile(argv[i], NULL);
707 doc = xmlParseFile(argv[i]);
709 fprintf(stderr, "unable to parse %s\n", argv[i]);
712 xsltProcess(doc, cur, argv[i]);
716 xsltFreeStylesheet(cur);
718 //xsltCleanupGlobals();