source: trunk/third/texinfo/makeinfo/xml.c @ 18945

Revision 18945, 39.8 KB checked in by amb, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18944, which included commits to RCS files with non-trunk default branches.
Line 
1/* xml.c -- xml output.
2   $Id: xml.c,v 1.1.1.2 2003-02-28 17:44:51 amb Exp $
3
4   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20   Originally written by Philippe Martin <feloy@free.fr>.  */
21
22#include "system.h"
23#include "makeinfo.h"
24#include "insertion.h"
25#include "macro.h"
26#include "cmds.h"
27#include "lang.h"
28
29#include "xml.h"
30
31/* Options */
32int xml_index_divisions = 1;
33
34
35void xml_close_sections (/* int level */);
36
37typedef struct _element
38{
39  char name[32];
40  int contains_para;
41  int contained_in_para;
42} element;
43
44element texinfoml_element_list [] = {
45  { "texinfo",             1, 0 },
46  { "setfilename",         0, 0 },
47  { "titlefont",           0, 0 },
48  { "settitle",            0, 0 },
49
50  { "node",                1, 0 },
51  { "nodenext",            0, 0 },
52  { "nodeprev",            0, 0 },
53  { "nodeup",              0, 0 },
54
55  { "chapter",             1, 0 },
56  { "section",             1, 0 },
57  { "subsection",          1, 0 },
58  { "subsubsection",       1, 0 },
59
60  { "top",                 1, 0 },
61  { "unnumbered",          1, 0 },
62  { "unnumberedsec",       1, 0 },
63  { "unnumberedsubsec",    1, 0 },
64  { "unnumberedsubsubsec", 1, 0 },
65
66  { "appendix",            1, 0 },
67  { "appendixsec",         1, 0 },
68  { "appendixsubsec",      1, 0 },
69  { "appendixsubsubsec",   1, 0 },
70
71  { "majorheading",        1, 0 },
72  { "chapheading",         1, 0 },
73  { "heading",             1, 0 },
74  { "subheading",          1, 0 },
75  { "subsubheading",       1, 0 },
76
77  { "menu",                1, 0 },
78  { "menuentry",           1, 0 },
79  { "menutitle",           0, 0 },
80  { "menucomment",         1, 0 },
81  { "menunode",            0, 0 },
82  { "nodename",            0, 0 },
83
84  { "acronym",             0, 1 },
85  { "tt",                  0, 1 },
86  { "code",                0, 1 },
87  { "kbd",                 0, 1 },
88  { "url",                 0, 1 },
89  { "key",                 0, 1 },
90  { "var",                 0, 1 },
91  { "sc",                  0, 1 },
92  { "dfn",                 0, 1 },
93  { "emph",                0, 1 },
94  { "strong",              0, 1 },
95  { "cite",                0, 1 },
96  { "notfixedwidth",       0, 1 },
97  { "i",                   0, 1 },
98  { "b",                   0, 1 },
99  { "r",                   0, 1 },
100
101  { "title",               0, 0 },
102  { "ifinfo",              1, 0 },
103  { "sp",                  0, 0 },
104  { "center",              1, 0 },
105  { "dircategory",         0, 0 },
106  { "quotation",           0, 0 },
107  { "example",             0, 0 },
108  { "smallexample",        0, 0 },
109  { "lisp",                0, 0 },
110  { "smalllisp",           0, 0 },
111  { "cartouche",           1, 0 },
112  { "copying",             1, 0 },
113  { "format",              0, 0 },
114  { "smallformat",         0, 0 },
115  { "display",             0, 0 },
116  { "smalldisplay",        0, 0 },
117  { "footnote",            0, 1 },
118
119  { "itemize",             0, 0 },
120  { "itemfunction",        0, 0 },
121  { "item",                1, 0 },
122  { "enumerate",           0, 0 },
123  { "table",               0, 0 },
124  { "tableitem",           0, 0 }, /* not used */ /* TABLEITEM */
125  { "tableterm",           0, 0 }, /* not used */ /* TABLETERM */
126
127  { "indexterm",           0, 1 },
128
129  { "xref",                0, 1 },
130  { "xrefnodename",        0, 1 },
131  { "xrefinfoname",        0, 1 },
132  { "xrefprinteddesc",     0, 1 },
133  { "xrefinfofile",        0, 1 },
134  { "xrefprintedname",     0, 1 },
135
136  { "inforef",             0, 1 },
137  { "inforefnodename",     0, 1 },
138  { "inforefrefname",      0, 1 },
139  { "inforefinfoname",     0, 1 },
140
141  { "uref",                0, 1 },
142  { "urefurl",             0, 1 },
143  { "urefdesc",            0, 1 },
144  { "urefreplacement",     0, 1 },
145
146  { "email",               0, 1 },
147  { "emailaddress",        0, 1 },
148  { "emailname",           0, 1 },
149
150  { "group",               0, 0 },
151
152  { "printindex",          0, 0 },
153  { "anchor",              0, 1 },
154  { "image",               0, 1 },
155  { "",                    0, 1 }, /* PRIMARY (docbook) */
156  { "",                    0, 1 }, /* SECONDARY (docbook) */
157  { "",                    0, 0 }, /* INFORMALFIGURE (docbook) */
158  { "",                    0, 0 }, /* MEDIAOBJECT (docbook) */
159  { "",                    0, 0 }, /* IMAGEOBJECT (docbook) */
160  { "",                    0, 0 }, /* IMAGEDATA (docbook) */
161  { "",                    0, 0 }, /* TEXTOBJECT (docbook) */
162  { "",                    0, 0 }, /* INDEXENTRY (docbook) */
163  { "",                    0, 0 }, /* PRIMARYIE (docbook) */
164  { "",                    0, 0 }, /* SECONDARYIE (docbook) */
165  { "",                    0, 0 }, /* INDEXDIV (docbook) */
166  { "multitable",          0, 0 },
167  { "",                    0, 0 }, /* TGROUP (docbook) */
168  { "columnfraction",      0, 0 },
169  { "",                    0, 0 }, /* TBODY (docbook) */
170  { "entry",               0, 0 }, /* ENTRY (docbook) */
171  { "row",                 0, 0 }, /* ROW (docbook) */
172  { "",                    0, 0 }, /* BOOKINFO (docbook) */
173  { "",                    0, 0 }, /* ABSTRACT (docbook) */
174  { "",                    0, 0 }, /* REPLACEABLE (docbook) */
175  { "",                    0, 0 }, /* ENVAR (docbook) */
176  { "",                    0, 0 }, /* COMMENT (docbook) */
177  { "",                    0, 0 }, /* FUNCTION (docbook) */
178  { "",                    0, 0 }, /* LEGALNOTICE (docbook) */
179
180  { "para",                0, 0 } /* Must be last */
181  /* name / contains para / contained in para */
182};
183
184element docbook_element_list [] = {
185  { "book",                0, 0 }, /* TEXINFO */
186  { "",                    0, 0 }, /* SETFILENAME */
187  { "",                    0, 0 }, /* TITLEINFO */
188  { "title",               0, 0 }, /* SETTITLE */
189
190  { "",                    1, 0 }, /* NODE */
191  { "",                    0, 0 }, /* NODENEXT */
192  { "",                    0, 0 }, /* NODEPREV */
193  { "",                    0, 0 }, /* NODEUP */
194
195  { "chapter",             1, 0 },
196  { "sect1",               1, 0 }, /* SECTION */
197  { "sect2",               1, 0 }, /* SUBSECTION */
198  { "sect3",               1, 0 }, /* SUBSUBSECTION */
199
200  { "chapter",             1, 0 }, /* TOP */
201  { "chapter",             1, 0 }, /* UNNUMBERED */
202  { "sect1",               1, 0 }, /* UNNUMBEREDSEC */
203  { "sect2",               1, 0 }, /* UNNUMBEREDSUBSEC */
204  { "sect3",               1, 0 }, /* UNNUMBEREDSUBSUBSEC */
205
206  { "appendix",            1, 0 },
207  { "sect1",               1, 0 }, /* APPENDIXSEC */
208  { "sect2",               1, 0 }, /* APPENDIXSUBSEC */
209  { "sect3",               1, 0 }, /* APPENDIXSUBSUBSEC */
210
211  { "chapter",             1, 0 }, /* MAJORHEADING */
212  { "chapter",             1, 0 }, /* CHAPHEADING */
213  { "sect1",               1, 0 }, /* HEADING */
214  { "sect2",               1, 0 }, /* SUBHEADING */
215  { "simplesect",               1, 0 }, /* SUBSUBHEADING */
216
217  { "",                    1, 0 }, /* MENU */
218  { "",                    1, 0 }, /* MENUENTRY */
219  { "",                    0, 0 }, /* MENUTITLE */
220  { "",                    1, 0 }, /* MENUCOMMENT */
221  { "",                    0, 0 }, /* MENUNODE */
222  { "anchor",              0, 0 }, /* NODENAME */
223
224  { "acronym",             0, 1 },
225  { "wordasword",          0, 1 }, /* TT */
226  { "command",             0, 1 }, /* CODE */
227  { "userinput",           0, 1 }, /* KBD */
228  { "wordasword",          0, 1 }, /* URL */
229  { "keycap",              0, 1 }, /* KEY */
230  { "varname",             0, 1 }, /* VAR */
231  { "",                    0, 1 }, /* SC */
232  { "firstterm",           0, 1 }, /* DFN */
233  { "emphasis",            0, 1 }, /* EMPH */
234  { "emphasis",            0, 1 }, /* STRONG */
235  { "citation",            0, 1 }, /* CITE */
236  { "",                    0, 1 },  /* NOTFIXEDWIDTH */
237  { "wordasword",          0, 1 }, /* I */
238  { "wordasword",          0, 1 }, /* B */
239  { "",                    0, 1 }, /* R */
240
241  { "title",               0, 0 },
242  { "",                    1, 0 }, /* IFINFO */
243  { "",                    0, 0 }, /* SP */
244  { "",                    1, 0 }, /* CENTER */
245  { "",                    0, 0 }, /* DIRCATEGORY */
246  { "blockquote",          1, 0 }, /* QUOTATION */
247  { "screen",              0, 1 },
248  { "screen",              0, 1 }, /* SMALLEXAMPLE */
249  { "screen",              0, 1 }, /* LISP */
250  { "screen",              0, 1 }, /* SMALLLISP */
251  { "",                    1, 0 }, /* CARTOUCHE */
252  { "",                    1, 0 }, /* COPYING */
253  { "screen",              0, 1 }, /* FORMAT */
254  { "screen",              0, 1 }, /* SMALLFORMAT */
255  { "screen",              0, 1 }, /* DISPLAY */
256  { "screen",              0, 1 }, /* SMALLDISPLAY */
257  { "footnote",            0, 1 },
258
259  { "itemizedlist",        0, 0 }, /* ITEMIZE */
260  { "",                    0, 0 }, /* ITEMFUNCTION */
261  { "listitem",            1, 0 }, /* ITEM */
262  { "orderedlist",         0, 0 }, /* ENUMERATE */
263  { "variablelist",        0, 0 }, /* TABLE */
264  { "varlistentry",        0, 0 }, /* TABLEITEM */
265  { "term",                0, 0 }, /* TABLETERM */
266
267  { "indexterm",           0, 1 }, /* INDEXTERM */
268
269  { "xref",                0, 1 }, /* XREF */
270  { "link",                0, 1 }, /* XREFNODENAME */
271  { "",                    0, 1 }, /* XREFINFONAME */
272  { "",                    0, 1 }, /* XREFPRINTEDDESC */
273  { "",                    0, 1 }, /* XREFINFOFILE */
274  { "",                    0, 1 }, /* XREFPRINTEDNAME */
275
276  { "",                    0, 1 }, /* INFOREF */
277  { "",                    0, 1 }, /* INFOREFNODENAME */
278  { "",                    0, 1 }, /* INFOREFREFNAME */
279  { "",                    0, 1 }, /* INFOREFINFONAME */
280
281  { "",                    0, 1 }, /* UREF */
282  { "",                    0, 1 }, /* UREFURL */
283  { "",                    0, 1 }, /* UREFDESC */
284  { "",                    0, 1 }, /* UREFREPLACEMENT */
285
286  { "ulink",               0, 1 }, /* EMAIL */
287  { "",                    0, 1 }, /* EMAILADDRESS */
288  { "",                    0, 1 }, /* EMAILNAME */
289
290  { "",                    0, 0 }, /* GROUP */
291
292  { "index",               0, 1 }, /* PRINTINDEX */
293  { "",                    0, 1 }, /* ANCHOR */
294  { "",                    0, 1 }, /* IMAGE */
295  { "primary",             0, 1 }, /* PRIMARY */
296  { "secondary",           0, 1 },
297  { "informalfigure",      0, 0 },
298  { "mediaobject",         0, 0 },
299  { "imageobject",         0, 0 },
300  { "imagedata",           0, 0 },
301  { "textobject",          0, 0 },
302  { "indexentry",          0, 0 },
303  { "primaryie",           0, 0 },
304  { "secondaryie",         0, 0 },
305  { "indexdiv",            0, 0 },
306  { "informaltable",       0, 0 },
307  { "tgroup",              0, 0 },
308  { "colspec",             0, 0 },
309  { "tbody",               0, 0 },
310  { "entry",               0, 0 },
311  { "row",                 0, 0 },
312  { "bookinfo",            0, 0 },
313  { "abstract",            1, 0 },
314  { "replaceable",         0, 0 },
315  { "envar",               0, 1 },
316  { "comment",             0, 0 },
317  { "function",            0, 1 },
318  { "legalnotice",         1, 0 },
319 
320  { "para",                0, 0 } /* Must be last */
321  /* name / contains para / contained in para */
322};
323
324element *xml_element_list = NULL;
325
326
327typedef struct _replace_element
328{
329  int element_to_replace;
330  int element_containing;
331  int element_replacing;
332} replace_element;
333
334/* Elements to replace - Docbook only
335   -------------------
336   if `element_to_replace' have to be inserted
337   as a child of `element_containing,'
338   use `element_replacing' instead.
339
340   A value of `-1' for element_replacing means `do not use any element.'
341*/
342
343replace_element replace_elements [] = {
344  { I, TABLETERM, EMPH },
345  { B, TABLETERM, EMPH },
346  { TT, CODE, -1 },
347  { EXAMPLE, DISPLAY, -1 },
348  { CODE, DFN, -1 },
349  { CODE, VAR, -1 },
350  { EMPH, CODE, REPLACEABLE },
351  { VAR, VAR, -1},
352  { VAR, B, EMPH},
353  { B, CODE, ENVAR},
354  { CODE, I, EMPH},
355  { FORMAT, BOOKINFO, ABSTRACT },
356  { QUOTATION, ABSTRACT, -1},
357  /* Add your elements to replace here */
358  {-1, 0, 0}
359};
360
361int xml_in_menu_entry = 0;
362int xml_in_menu_entry_comment = 0;
363int xml_node_open = 0;
364int xml_node_level = -1;
365int xml_in_para = 0;
366int xml_just_after_element = 0;
367
368int xml_no_para = 0;
369char *xml_node_id = NULL;
370int xml_sort_index = 0;
371
372int xml_in_xref_token = 0;
373int xml_in_bookinfo = 0;
374int xml_in_book_title = 0;
375int xml_in_abstract = 0;
376
377static int xml_after_table_term = 0;
378static int book_started = 0;
379static int first_section_opened = 0;
380
381static int xml_in_item[256];
382static int xml_table_level = 0;
383
384static int in_table_title = 0;
385
386static int in_indexentry = 0;
387static int in_secondary = 0;
388static int in_indexterm = 0;
389
390static int xml_current_element ();
391
392void
393#if defined (VA_FPRINTF) && __STDC__
394xml_insert_element_with_attribute (int elt, int arg, char *format, ...);
395#else
396xml_insert_element_with_attribute ();
397#endif
398
399char *
400xml_id (id)
401    char *id;
402{
403  char *tem = xmalloc (strlen (id) + 1);
404  char *p = tem;
405  strcpy (tem, id);
406  while (*p)
407    {
408      if (strchr ("~ &/+^;?()%<>\"'$¿", *p))
409        *p = '-';
410      p++;
411    }
412  p = tem;
413  if (*p == '-')
414    *p = 'i';
415  return tem;
416}
417
418int
419xml_element (name)
420    char *name;
421{
422  int i;
423  for (i=0; i<=PARA; i++)
424    {
425      if (strcasecmp (name, texinfoml_element_list[i].name) == 0)
426        return i;
427    }
428  printf ("Error xml_element\n");
429  return -1;
430}
431
432void
433xml_begin_document (output_filename)
434    char *output_filename;
435{
436  if (book_started)
437    return;
438
439  book_started = 1;
440  if (docbook)
441    {
442      insert_string ("<!DOCTYPE Book PUBLIC \"-//OASIS//DTD DocBook V3.1//EN\">");
443      xml_element_list = docbook_element_list;
444    }
445  else
446    {
447      insert_string ("<!DOCTYPE texinfo SYSTEM \"texinfo.dtd\">");
448      xml_element_list = texinfoml_element_list;
449    }
450  if (docbook)
451    {
452      if (language_code != last_language_code)
453        xml_insert_element_with_attribute (TEXINFO, START, "lang=\"%s\"", language_table[language_code].abbrev);
454    }
455  else
456    xml_insert_element (TEXINFO, START);
457  if (!docbook)
458    {
459      xml_insert_element (SETFILENAME, START);
460      insert_string (output_filename);
461      xml_insert_element (SETFILENAME, END);
462    }
463}
464
465/* */
466static int element_stack[256];
467static int element_stack_index = 0;
468
469static void
470xml_push_current_element (elt)
471    int elt;
472{
473  element_stack[element_stack_index++] = elt;
474  if (element_stack_index > 200)
475    printf ("*** stack overflow (%d - %s) ***\n",
476            element_stack_index,
477            xml_element_list[elt].name);
478}
479
480void
481xml_pop_current_element ()
482{
483  element_stack_index--;
484  if (element_stack_index < 0)
485    printf ("*** stack underflow (%d - %d) ***\n",
486            element_stack_index,
487            xml_current_element());
488}
489
490static int
491xml_current_element ()
492{
493  return element_stack[element_stack_index-1];
494}
495
496static void
497xml_indent ()
498{
499  int i;
500  insert ('\n');
501  for (i = 0; i < element_stack_index; i++)
502    insert (' ');
503}
504
505static void
506xml_indent_end_para ()
507{
508  int i;
509  for (i = 0; i < element_stack_index; i++)
510    insert (' ');
511}
512
513void
514xml_end_document ()
515{
516  if (xml_node_open)
517    {
518      if (xml_node_level != -1)
519        {
520          xml_close_sections (xml_node_level);
521          xml_node_level = -1;
522        }
523      xml_insert_element (NODE, END);
524    }
525  else
526    xml_close_sections (xml_node_level);
527
528  xml_insert_element (TEXINFO, END);
529  insert_string ("\n");
530  insert_string ("<!-- Keep this comment at the end of the file\n\
531Local variables:\n\
532mode: sgml\n\
533sgml-indent-step:1\n\
534sgml-indent-data:nil\n\
535End:\n\
536-->\n");
537  if (element_stack_index != 0)
538    error ("Element stack index : %d\n", element_stack_index);
539}
540
541/* MUST be 0 or 1, not true or false values */
542static int start_element_inserted = 1;
543
544/* NOTE: We use `elt' rather than `element' in the argument list of
545   the next function, since otherwise the Solaris SUNWspro compiler
546   barfs because `element' is a typedef declared near the beginning of
547   this file.  */
548void
549#if defined (VA_FPRINTF) && __STDC__
550xml_insert_element_with_attribute (int elt, int arg, char *format, ...)
551#else
552xml_insert_element_with_attribute (elt, arg, format, va_alist)
553     int elt;
554     int arg;
555     char *format;
556     va_dcl
557#endif
558{
559  /* Look at the replace_elements table to see if we have to change the element */
560  if (xml_sort_index)
561      return;
562  if (docbook)
563    {
564      replace_element *element_list = replace_elements;
565      while (element_list->element_to_replace >= 0)
566        {
567          if ( ( (arg == START) &&
568                 (element_list->element_containing == xml_current_element ()) &&
569                 (element_list->element_to_replace == elt) ) ||
570               ( (arg == END) &&
571                 (element_list->element_containing == element_stack[element_stack_index-1-start_element_inserted]) &&
572                 (element_list->element_to_replace == elt) ) )
573            {
574              elt = element_list->element_replacing;
575              break;
576            }
577          element_list ++;
578        }
579
580      /* Forget the element */
581      if (elt < 0)
582        {
583          if (arg == START)
584            start_element_inserted = 0;
585          else
586            /* Replace the default value, for the next time */
587            start_element_inserted = 1;
588          return;
589        }
590    }
591
592  if (!book_started)
593      return;
594
595  if (xml_after_table_term && elt != TABLETERM)
596    {
597      xml_after_table_term = 0;
598      xml_insert_element (ITEM, START);
599    }
600
601  if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
602    return;
603   
604  if (!xml_element_list[elt].name || !strlen (xml_element_list[elt].name))
605    {
606      /*printf ("Warning: Inserting empty element %d\n", elt);*/
607      return;
608    }
609
610  if (arg == START && !xml_in_para && !xml_no_para
611      && xml_element_list[elt].contained_in_para
612      && xml_element_list[xml_current_element()].contains_para )
613    {
614      xml_indent ();
615      insert_string ("<para>");
616      xml_in_para = 1;
617    }
618
619
620  if (arg == START && xml_in_para && !xml_element_list[elt].contained_in_para)
621    {
622      xml_indent_end_para ();
623      insert_string ("</para>");
624      xml_in_para = 0;
625    }
626
627  if (arg == END && xml_in_para && !xml_element_list[elt].contained_in_para)
628    {
629      xml_indent_end_para ();
630      insert_string ("</para>");
631      xml_in_para = 0;
632    }
633
634  if (arg == START && !xml_in_para && !xml_element_list[elt].contained_in_para)
635    xml_indent ();
636
637  if (docbook && xml_table_level && !xml_in_item[xml_table_level] && !in_table_title
638      && arg == START && elt != TABLEITEM && elt != TABLETERM
639      && !in_indexterm && xml_current_element() == TABLE)
640    {
641      in_table_title = 1;
642      xml_insert_element (TITLE, START);
643    }
644
645
646  if (arg == START)
647    xml_push_current_element (elt);
648  else
649    xml_pop_current_element ();
650
651  insert ('<');
652  if (arg == END)
653    insert ('/');
654  insert_string (xml_element_list[elt].name);
655
656  /*  printf ("%s ", xml_element_list[elt].name);*/
657
658  if (format)
659    {
660      char temp_string[2000]; /* xx no fixed limits */
661#ifdef VA_SPRINTF
662      va_list ap;
663#endif
664
665      VA_START (ap, format);
666#ifdef VA_SPRINTF
667      VA_SPRINTF (temp_string, format, ap);
668#else
669      sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8);
670#endif
671      insert (' ');
672      insert_string (temp_string);
673      va_end (ap);
674    }
675
676  if (arg == START && xml_node_id && elt != NODENAME)
677    {
678      insert_string (" id=\"");
679      insert_string (xml_node_id);
680      insert_string ("\"");
681      free (xml_node_id);
682      xml_node_id = NULL;
683    }
684
685  insert ('>');
686
687  xml_just_after_element = 1;
688}
689
690/* See the NOTE before xml_insert_element_with_attribute, for why we
691   use `elt' rather than `element' here.  */
692void
693xml_insert_element (int elt, int arg)
694{
695  xml_insert_element_with_attribute (elt, arg, NULL);
696}
697
698void
699xml_insert_entity (char *entity_name)
700{
701  int saved_escape_html = escape_html;
702
703  if (!book_started)
704    return;
705  if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
706    return;
707
708  if (!xml_in_para && !xml_no_para && !only_macro_expansion
709      && xml_element_list[xml_current_element ()].contains_para
710      && !in_fixed_width_font)
711    {
712      insert_string ("<para>");
713      xml_in_para = 1;
714    }
715  escape_html = 0;
716  insert ('&');
717  escape_html = saved_escape_html;
718  insert_string (entity_name);
719  insert (';');
720}
721
722typedef struct _xml_section xml_section;
723struct _xml_section {
724  int level;
725  char *name;
726  xml_section *prev;
727};
728
729xml_section *last_section = NULL;
730
731void
732xml_begin_node ()
733{
734  first_section_opened = 1;
735  if (xml_in_abstract)
736    {
737      xml_insert_element (ABSTRACT, END);
738      xml_in_abstract = 0;
739    }
740  if (xml_in_bookinfo)
741    {
742      xml_insert_element (BOOKINFO, END);
743      xml_in_bookinfo = 0;
744    }
745  if (xml_node_open && ! docbook)
746    {
747      if (xml_node_level != -1)
748        {
749          xml_close_sections (xml_node_level);
750          xml_node_level = -1;
751        }
752      xml_insert_element (NODE, END);
753    }
754  xml_insert_element (NODE, START);
755  xml_node_open = 1;
756}
757
758void
759xml_close_sections (level)
760    int level;
761{
762  if (!first_section_opened)
763    {
764      if (xml_in_abstract)
765        {
766          xml_insert_element (ABSTRACT, END);
767          xml_in_abstract = 0;
768        }
769      if (xml_in_bookinfo)
770        {
771          xml_insert_element (BOOKINFO, END);
772          xml_in_bookinfo = 0;
773        }
774      first_section_opened = 1;
775    }
776
777  while (last_section && last_section->level >= level)
778    {
779      xml_section *temp = last_section;
780      xml_insert_element (xml_element(last_section->name), END);
781      temp = last_section;
782      last_section = last_section->prev;
783      free (temp->name);
784      free (temp);
785    }
786}
787
788void
789xml_open_section (level, name)
790    int level;
791    char *name;
792{
793  xml_section *sect = (xml_section *) xmalloc (sizeof (xml_section));
794
795  sect->level = level;
796  sect->name = xmalloc (1 + strlen (name));
797  strcpy (sect->name, name);
798  sect->prev = last_section;
799  last_section = sect;
800
801  if (xml_node_open && xml_node_level == -1)
802    xml_node_level = level;
803}
804
805void
806xml_start_menu_entry (tem)
807    char *tem;
808{
809  char *string;
810  discard_until ("* ");
811
812  /* The line number was already incremented in reader_loop when we
813     saw the newline, and discard_until has now incremented again.  */
814  line_number--;
815
816  if (xml_in_menu_entry)
817    {
818      if (xml_in_menu_entry_comment)
819        {
820          xml_insert_element (MENUCOMMENT, END);
821          xml_in_menu_entry_comment=0;
822        }
823      xml_insert_element (MENUENTRY, END);
824      xml_in_menu_entry=0;
825    }
826  xml_insert_element (MENUENTRY, START);
827  xml_in_menu_entry=1;
828
829  xml_insert_element (MENUNODE, START);
830  string = expansion (tem, 0);
831  add_word (string);
832  xml_insert_element (MENUNODE, END);
833  free (string);
834
835  /* The menu item may use macros, so expand them now.  */
836  xml_insert_element (MENUTITLE, START);
837  only_macro_expansion++;
838  get_until_in_line (1, ":", &string);
839  only_macro_expansion--;
840  execute_string ("%s", string); /* get escaping done */
841  xml_insert_element (MENUTITLE, END);
842  free (string);
843
844  if (looking_at ("::"))
845    discard_until (":");
846  else
847    { /* discard the node name */
848      get_until_in_line (0, ".", &string);
849      free (string);
850    }
851  input_text_offset++;  /* discard the second colon or the period */
852  xml_insert_element (MENUCOMMENT, START);
853  xml_in_menu_entry_comment ++;
854}
855
856void
857xml_end_menu ()
858{
859  if (xml_in_menu_entry)
860    {
861      if (xml_in_menu_entry_comment)
862        {
863          xml_insert_element (MENUCOMMENT, END);
864          xml_in_menu_entry_comment --;
865        }
866      xml_insert_element (MENUENTRY, END);
867      xml_in_menu_entry--;
868    }
869  xml_insert_element (MENU, END);
870}
871
872static int xml_last_character;
873
874void
875xml_add_char (character)
876    int character;
877{
878  if (!book_started)
879      return;
880  if (docbook && !only_macro_expansion && (in_menu || in_detailmenu))
881    return;
882 
883  if (docbook && xml_table_level && !xml_in_item[xml_table_level] && !in_table_title
884      && !cr_or_whitespace (character) && !in_indexterm)
885    {
886      in_table_title = 1;
887      xml_insert_element (TITLE, START);
888    }
889
890  if (!first_section_opened && !xml_in_abstract && !xml_in_book_title
891      && !xml_no_para && character != '\r' && character != '\n' && character != ' ')
892    {
893      if (!xml_in_bookinfo)
894        {
895          xml_insert_element (BOOKINFO, START);
896          xml_in_bookinfo = 1;
897        }
898      xml_insert_element (ABSTRACT, START);
899      xml_in_abstract = 1;
900    }
901
902  if (xml_after_table_term && !xml_sort_index && !xml_in_xref_token)
903    {
904      xml_after_table_term = 0;
905      xml_insert_element (ITEM, START);
906    }
907
908  if (xml_just_after_element && !xml_in_para && !inhibit_paragraph_indentation)
909    {
910      if (character == '\r' || character == '\n' || character == '\t' || character == ' ')
911        return;
912      xml_just_after_element = 0;
913    }
914
915  if (xml_element_list[xml_current_element()].contains_para
916      && !xml_in_para && !only_macro_expansion && !xml_no_para
917      && !cr_or_whitespace (character) && !in_fixed_width_font)
918    {
919      xml_indent ();
920      insert_string ("<para>\n");
921      xml_in_para = 1;
922    }
923
924  if (xml_in_para)
925    {
926      if (character == '\n')
927        {
928          if (xml_last_character == '\n' && !only_macro_expansion && !xml_no_para
929              && xml_element_list[xml_current_element()].contains_para )
930            {
931              xml_indent_end_para ();
932              insert_string ("</para>");
933              xml_in_para = 0;
934              xml_just_after_element = 1;
935              if (xml_in_menu_entry_comment)
936                {
937                  xml_insert_element (MENUCOMMENT, END);
938                  xml_in_menu_entry_comment = 0;
939                  xml_insert_element (MENUENTRY, END);
940                  xml_in_menu_entry = 0;
941                }
942            }
943        }
944    }
945
946  if (character == '\n' && !xml_in_para && !inhibit_paragraph_indentation)
947    return;
948
949  xml_last_character = character;
950
951  if (character == '&' && escape_html)
952      insert_string ("&amp;");
953  else if (character == '<' && escape_html)
954      insert_string ("&lt;");
955  else
956    insert (character);
957
958  return;
959}
960
961void
962xml_insert_footnote (note)
963    char *note;
964{
965  xml_insert_element (FOOTNOTE, START);
966  insert_string ("<para>");
967  execute_string ("%s", note);
968  insert_string ("</para>");
969  xml_insert_element (FOOTNOTE, END);
970}
971
972
973/*
974 * Lists and Tables
975 */
976void
977xml_begin_table (type, item_function)
978    enum insertion_type type;
979    char *item_function;
980{
981  switch (type)
982    {
983    case ftable:
984    case vtable:
985    case table:
986      /*if (docbook)*/ /* 05-08 */
987        {
988          xml_insert_element (TABLE, START);
989          xml_table_level ++;
990          xml_in_item[xml_table_level] = 0;
991        }
992      break;
993    case itemize:
994      if (!docbook)
995        {
996          xml_insert_element (ITEMIZE, START);
997          xml_table_level ++;
998          xml_in_item[xml_table_level] = 0;
999          xml_insert_element (ITEMFUNCTION, START);
1000          if (*item_function == COMMAND_PREFIX
1001              && item_function[strlen (item_function) - 1] != '}'
1002              && command_needs_braces (item_function + 1))
1003            execute_string ("%s{}", item_function);
1004          else
1005            execute_string ("%s", item_function);
1006          xml_insert_element (ITEMFUNCTION, END);
1007        }
1008      else
1009        {
1010          xml_insert_element_with_attribute (ITEMIZE, START,
1011                                             "mark=\"%s\"",
1012                                             (*item_function == COMMAND_PREFIX) ?
1013                                             &item_function[1] : item_function);
1014          xml_table_level ++;
1015          xml_in_item[xml_table_level] = 0;
1016        }
1017      break;
1018    }
1019}
1020
1021void
1022xml_end_table (type)
1023    enum insertion_type type;
1024{
1025  switch (type)
1026    {
1027    case ftable:
1028    case vtable:
1029    case table:
1030      /*      if (docbook)*/ /* 05-08 */
1031        {
1032          if (xml_in_item[xml_table_level])
1033            {
1034              xml_insert_element (ITEM, END);
1035              xml_insert_element (TABLEITEM, END);
1036              xml_in_item[xml_table_level] = 0;
1037            }
1038          xml_insert_element (TABLE, END);
1039          xml_table_level --;
1040        }
1041      break;
1042    case itemize:
1043      if (xml_in_item[xml_table_level])
1044        {
1045          xml_insert_element (ITEM, END);
1046          xml_in_item[xml_table_level] = 0;
1047        }
1048      /* gnat-style manual contains an itemized list without items! */
1049      if (in_table_title)
1050        {
1051          xml_insert_element (TITLE, END);
1052          in_table_title = 0;
1053        }
1054      xml_insert_element (ITEMIZE, END);
1055      xml_table_level --;
1056      break;
1057    }
1058}
1059
1060void
1061xml_begin_item ()
1062{
1063  if (xml_in_item[xml_table_level])
1064    xml_insert_element (ITEM, END);
1065
1066  xml_insert_element (ITEM, START);
1067  xml_in_item[xml_table_level] = 1;
1068}
1069
1070void
1071xml_begin_table_item ()
1072{
1073  if (!xml_after_table_term)
1074    {
1075      if (xml_in_item[xml_table_level])
1076        {
1077          xml_insert_element (ITEM, END);
1078          xml_insert_element (TABLEITEM, END);
1079        }
1080      if (in_table_title)
1081        {
1082          in_table_title = 0;
1083          xml_insert_element (TITLE, END);
1084        }
1085      xml_insert_element (TABLEITEM, START);
1086    }
1087  xml_insert_element (TABLETERM, START);
1088  xml_in_item[xml_table_level] = 1;
1089  xml_after_table_term = 0;
1090}
1091
1092void
1093xml_continue_table_item ()
1094{
1095  xml_insert_element (TABLETERM, END);
1096  xml_after_table_term = 1;
1097}
1098
1099void
1100xml_begin_enumerate (enum_arg)
1101    char *enum_arg;
1102{
1103  if (!docbook)
1104    xml_insert_element_with_attribute (ENUMERATE, START, "first=\"%s\"", enum_arg);
1105  else
1106    {
1107      if (isdigit (*enum_arg))
1108      {
1109        if (enum_arg[0] == '1')
1110          xml_insert_element_with_attribute (ENUMERATE, START,
1111                                             "numeration=\"arabic\"", NULL);
1112        else
1113          xml_insert_element_with_attribute (ENUMERATE, START,
1114                                             "continuation=\"continues\" numeration=\"arabic\"", NULL);
1115      }
1116      else if (isupper (*enum_arg))
1117        {
1118        if (enum_arg[0] == 'A')
1119          xml_insert_element_with_attribute (ENUMERATE, START,
1120                                             "numeration=\"upperalpha\"", NULL);
1121        else
1122          xml_insert_element_with_attribute (ENUMERATE, START,
1123                                             "continuation=\"continues\" numeration=\"upperalpha\"", NULL);
1124      }
1125      else
1126        {
1127          if (enum_arg[0] == 'a')
1128          xml_insert_element_with_attribute (ENUMERATE, START,
1129                                             "numeration=\"loweralpha\"", NULL);
1130        else
1131          xml_insert_element_with_attribute (ENUMERATE, START,
1132                                             "continuation=\"continues\" numeration=\"loweralpha\"", NULL);
1133        }
1134    }
1135  xml_table_level ++;
1136  xml_in_item[xml_table_level] = 0;
1137}
1138
1139void
1140xml_end_enumerate ()
1141{
1142  if (xml_in_item[xml_table_level])
1143    {
1144      xml_insert_element (ITEM, END);
1145      xml_in_item[xml_table_level] = 0;
1146    }
1147  xml_insert_element (ENUMERATE, END);
1148  xml_table_level --;
1149}
1150
1151static void
1152xml_insert_text_file (name_arg)
1153    char *name_arg;
1154{
1155  char *fullname = xmalloc (strlen (name_arg) + 4 + 1);
1156  FILE *image_file;
1157  strcpy (fullname, name_arg);
1158  strcat (fullname, ".txt");
1159  image_file = fopen (fullname, "r");
1160  if (image_file)
1161    {
1162      int ch;
1163      int save_inhibit_indentation = inhibit_paragraph_indentation;
1164      int save_filling_enabled = filling_enabled;
1165
1166      xml_insert_element (TEXTOBJECT, START);
1167      xml_insert_element (DISPLAY, START);
1168
1169      inhibit_paragraph_indentation = 1;
1170      filling_enabled = 0;
1171      last_char_was_newline = 0;
1172
1173      /* Maybe we need to remove the final newline if the image
1174         file is only one line to allow in-line images.  On the
1175         other hand, they could just make the file without a
1176         final newline.  */
1177      while ((ch = getc (image_file)) != EOF)
1178        add_char (ch);
1179
1180      inhibit_paragraph_indentation = save_inhibit_indentation;
1181      filling_enabled = save_filling_enabled;
1182
1183      xml_insert_element (DISPLAY, END);
1184      xml_insert_element (TEXTOBJECT, END);
1185
1186      if (fclose (image_file) != 0)
1187        perror (fullname);
1188    }
1189  else
1190    warning (_("@image file `%s' unreadable: %s"), fullname,
1191             strerror (errno));
1192
1193  free (fullname);
1194}
1195
1196void
1197xml_insert_docbook_image (name_arg)
1198    char *name_arg;
1199{
1200  xml_insert_element (INFORMALFIGURE, START);
1201  xml_insert_element (MEDIAOBJECT, START);
1202
1203  xml_insert_element (IMAGEOBJECT, START);
1204  xml_insert_element_with_attribute (IMAGEDATA, START, "fileref=\"%s.eps\" format=\"eps\"", name_arg);
1205  xml_pop_current_element ();
1206  xml_insert_element (IMAGEOBJECT, END);
1207
1208  xml_insert_element (IMAGEOBJECT, START);
1209  xml_insert_element_with_attribute (IMAGEDATA, START, "fileref=\"%s.jpg\" format=\"jpg\"", name_arg);
1210  xml_pop_current_element ();
1211  xml_insert_element (IMAGEOBJECT, END);
1212
1213  xml_insert_text_file (name_arg);
1214
1215  xml_insert_element (MEDIAOBJECT, END);
1216  xml_insert_element (INFORMALFIGURE, END);
1217}
1218
1219void
1220xml_asterisk ()
1221{
1222}
1223
1224
1225/*
1226 *     INDEX
1227 */
1228/* Used to separate primary and secondary entries in an index -- we need
1229   to have real multilivel indexing support, not just string analysis.  */
1230#define INDEX_SEP "@this string will never appear@" /* was , */
1231
1232xml_insert_indexterm (indexterm, index)
1233    char *indexterm;
1234    char *index;
1235{
1236  if (!docbook)
1237    {
1238      xml_insert_element_with_attribute (INDEXTERM, START, "index=\"%s\"", index);
1239      in_indexterm = 1;
1240      execute_string ("%s", indexterm);
1241      xml_insert_element (INDEXTERM, END);
1242      in_indexterm = 0;
1243    }
1244  else
1245    {
1246      char *primary = NULL, *secondary;
1247      if (strstr (indexterm+1, INDEX_SEP))
1248        {
1249          primary = xmalloc (strlen (indexterm) + 1);
1250          strcpy (primary, indexterm);
1251          secondary = strstr (primary+1, INDEX_SEP);
1252          *secondary = '\0';
1253          secondary += strlen (INDEX_SEP);
1254        }
1255      xml_insert_element_with_attribute (INDEXTERM, START, "role=\"%s\"", index);
1256      in_indexterm = 1;
1257      xml_insert_element (PRIMARY, START);
1258      if (primary)
1259        execute_string (primary);
1260      else
1261        execute_string (indexterm);
1262      xml_insert_element (PRIMARY, END);
1263      if (primary)
1264        {
1265          xml_insert_element (SECONDARY, START);
1266          execute_string (secondary);
1267          xml_insert_element (SECONDARY, END);
1268        }
1269      xml_insert_element (INDEXTERM, END);
1270      in_indexterm = 0;
1271    }
1272}
1273
1274
1275int xml_last_section_output_position = 0;
1276static char last_division_letter = ' ';
1277static char index_primary[2000]; /** xx no fixed limit */
1278static int indexdivempty = 0;
1279
1280static void
1281xml_close_indexentry ()
1282{
1283  if (!in_indexentry)
1284    return;
1285  if (in_secondary)
1286    xml_insert_element (SECONDARYIE, END);
1287  xml_insert_element (INDEXENTRY, END);
1288  in_secondary = 0;
1289  in_indexentry = 0;
1290}
1291
1292void
1293xml_begin_index ()
1294{
1295  /*
1296     We assume that we just opened a section, and so that the last output is
1297     <SECTION ID="node-name"><TITLE>Title</TITLE>
1298     where SECTION can be CHAPTER, ...
1299   */
1300
1301  xml_section *temp = last_section;
1302
1303  int l = output_paragraph_offset-xml_last_section_output_position;
1304  char *tmp = xmalloc (l+1);
1305  char *p = tmp;
1306  strncpy (tmp, output_paragraph, l);
1307
1308  /* We remove <SECTION */
1309  tmp[l] = '\0';
1310  while (*p != '<')
1311    p++;
1312  while (*p != ' ')
1313    p++;
1314
1315  output_paragraph_offset = xml_last_section_output_position;
1316  xml_last_section_output_position = 0;
1317
1318  xml_pop_current_element (); /* remove section element from elements stack */
1319
1320  if (last_section)
1321    last_section = last_section->prev; /* remove section from sections stack */
1322  if (temp)
1323    {
1324      free (temp->name);
1325      free (temp);
1326    }
1327
1328  /* We put <INDEX> */
1329  xml_insert_element (PRINTINDEX, START);
1330  /* Remove the final > */
1331  output_paragraph_offset--;
1332
1333  /* and put  ID="node-name"><TITLE>Title</TITLE> */
1334  insert_string (p);
1335
1336  if (xml_index_divisions)
1337    {
1338      xml_insert_element (INDEXDIV, START);
1339      indexdivempty = 1;
1340    }
1341}
1342
1343void
1344xml_end_index ()
1345{
1346  xml_close_indexentry ();
1347  if (xml_index_divisions)
1348    xml_insert_element (INDEXDIV, END);
1349  xml_insert_element (PRINTINDEX, END);
1350}
1351
1352void
1353xml_index_divide (entry)
1354    char *entry;
1355{
1356  char c;
1357  if (strlen (entry) > (strlen (xml_element_list[CODE].name) + 2) &&
1358      strncmp (entry+1, xml_element_list[CODE].name, strlen (xml_element_list[CODE].name)) == 0)
1359    c = entry[strlen (xml_element_list[CODE].name)+2];
1360  else
1361    c = entry[0];
1362  if (tolower (c) != last_division_letter && isalpha (c))
1363    {
1364      last_division_letter = tolower (c);
1365      xml_close_indexentry ();
1366      if (!indexdivempty)
1367        {
1368          xml_insert_element (INDEXDIV, END);
1369          xml_insert_element (INDEXDIV, START);
1370        }
1371      xml_insert_element (TITLE, START);
1372      insert (toupper (c));
1373      xml_insert_element (TITLE, END);
1374    }
1375}
1376
1377void
1378xml_insert_indexentry (entry, node)
1379    char *entry;
1380    char *node;
1381{
1382  char *primary = NULL, *secondary;
1383  if (xml_index_divisions)
1384    xml_index_divide (entry);
1385
1386  indexdivempty = 0;
1387  if (strstr (entry+1, INDEX_SEP))
1388    {
1389      primary = xmalloc (strlen (entry) + 1);
1390      strcpy (primary, entry);
1391      secondary = strstr (primary+1, INDEX_SEP);
1392      *secondary = '\0';
1393      secondary += strlen (INDEX_SEP);
1394
1395      if (in_secondary && strcmp (primary, index_primary) == 0)
1396        {
1397          xml_insert_element (SECONDARYIE, END);
1398          xml_insert_element (SECONDARYIE, START);
1399          execute_string (secondary);
1400        }
1401      else
1402        {
1403          xml_close_indexentry ();
1404          xml_insert_element (INDEXENTRY, START);
1405          in_indexentry = 1;
1406          xml_insert_element (PRIMARYIE, START);
1407          execute_string (primary);
1408          xml_insert_element (PRIMARYIE, END);
1409          xml_insert_element (SECONDARYIE, START);
1410          execute_string (secondary);
1411          in_secondary = 1;
1412        }
1413    }
1414  else
1415    {
1416      xml_close_indexentry ();
1417      xml_insert_element (INDEXENTRY, START);
1418      in_indexentry = 1;
1419      xml_insert_element (PRIMARYIE, START);
1420      execute_string (entry);
1421    }
1422  add_word_args (", %s", _("see "));
1423  xml_insert_element_with_attribute (XREF, START, "linkend=\"%s\"", xml_id (node));
1424  xml_pop_current_element ();
1425
1426  if (primary)
1427    {
1428      strcpy (index_primary, primary);
1429      /*      xml_insert_element (SECONDARYIE, END);*/
1430      /*     *(secondary-1) = ',';*/ /* necessary ? */
1431      free (primary);
1432    }
1433  else
1434    xml_insert_element (PRIMARYIE, END);
1435
1436  /*  xml_insert_element (INDEXENTRY, END); */
1437}
1438
1439/*
1440 * MULTITABLE
1441 */
1442void
1443xml_begin_multitable (ncolumns, column_widths)
1444    int ncolumns;
1445    int *column_widths;
1446{
1447  int i;
1448  if (docbook)
1449    {
1450      xml_insert_element (MULTITABLE, START);
1451      xml_insert_element_with_attribute (TGROUP, START, "cols=\"%d\"", ncolumns);
1452      for (i=0; i<ncolumns; i++)
1453        {
1454          xml_insert_element_with_attribute (COLSPEC, START, "colwidth=\"%d*\"", column_widths[i]);
1455          xml_pop_current_element ();
1456        }
1457      xml_insert_element (TBODY, START);
1458      xml_no_para = 1;
1459    }
1460  else
1461    {
1462      xml_insert_element (MULTITABLE, START);
1463      for (i=0; i<ncolumns; i++)
1464        {
1465          xml_insert_element (COLSPEC, START);
1466          add_word_args ("%d", column_widths[i]);
1467          xml_insert_element (COLSPEC, END);
1468        }
1469      xml_no_para = 1;
1470    }
1471}
1472
1473void
1474xml_end_multitable_row (first_row)
1475    int first_row;
1476{
1477  if (!first_row)
1478    {
1479      xml_insert_element (ENTRY, END);
1480      xml_insert_element (ROW, END);
1481    }
1482  xml_insert_element (ROW, START);
1483  xml_insert_element (ENTRY, START);
1484}
1485
1486void
1487xml_end_multitable_column ()
1488{
1489  xml_insert_element (ENTRY, END);
1490  xml_insert_element (ENTRY, START);
1491}
1492
1493void
1494xml_end_multitable ()
1495{
1496  if (docbook)
1497    {
1498      xml_insert_element (ENTRY, END);
1499      xml_insert_element (ROW, END);
1500      xml_insert_element (TBODY, END);
1501      xml_insert_element (TGROUP, END);
1502      xml_insert_element (MULTITABLE, END);
1503      xml_no_para = 0;
1504    }
1505  else
1506    {
1507      xml_insert_element (ENTRY, END);
1508      xml_insert_element (ROW, END);
1509      xml_insert_element (MULTITABLE, END);
1510      xml_no_para = 0;
1511    }
1512}
Note: See TracBrowser for help on using the repository browser.