PageRenderTime 232ms CodeModel.GetById 99ms app.highlight 104ms RepoModel.GetById 15ms app.codeStats 1ms

/amaya/fetchXMLname.c

https://github.com/pffy/Amaya-Editor
C | 809 lines | 598 code | 68 blank | 143 comment | 314 complexity | 7c08c4f75e708ff313b9837f9c392667 MD5 | raw file
  1/*
  2 *
  3 *  (c) COPYRIGHT INRIA and W3C, 1996-2008
  4 *  Please first read the full copyright statement in file COPYRIGHT.
  5 *
  6 */
  7 
  8/*
  9 *
 10 * fetchXMLname
 11 *
 12 * Authors: I. Vatton
 13 *          L. Carcone
 14 *
 15 */
 16
 17#define THOT_EXPORT extern
 18#include "amaya.h"
 19#include "parser.h"
 20#include "HTMLnames.h"
 21#include "MathMLnames.h"
 22#include "SVGnames.h"
 23#include "XLinknames.h"
 24#include "Templatename.h"
 25
 26/* define some pointers to let other parser functions access the local table */
 27int               HTML_ENTRIES = (sizeof(XHTMLElemMappingTable) / sizeof(ElemMapping));
 28ElemMapping      *pHTMLGIMapping = XHTMLElemMappingTable;
 29AttributeMapping *pHTMLAttributeMapping = XHTMLAttributeMappingTable;
 30
 31XmlEntity        *pXhtmlEntityTable = XhtmlEntityTable;
 32XmlEntity        *pMathEntityTable = MathEntityTable;
 33
 34#include "fetchXMLname_f.h"
 35#ifdef TEMPLATES
 36#include "templates.h"
 37#include "templates_f.h"
 38#endif /* TEMPLATES */
 39
 40/* Global variables used by the entity mapping */
 41static int        XHTMLSup = 0;
 42static int        MathSup = 0;
 43
 44/*----------------------------------------------------------------------
 45  GetXHTMLSSchema returns the XHTML Thot schema for document doc.
 46  ----------------------------------------------------------------------*/
 47SSchema GetXHTMLSSchema (Document doc)
 48{
 49  SSchema	XHTMLSSchema;
 50
 51  XHTMLSSchema = TtaGetSSchema ("HTML", doc);
 52  if (XHTMLSSchema == NULL)
 53    XHTMLSSchema = TtaNewNature(doc, TtaGetDocumentSSchema(doc), NULL,
 54                                "HTML", "HTMLP");
 55  return (XHTMLSSchema);
 56}
 57
 58/*----------------------------------------------------------------------
 59  GetMathMLSSchema returns the MathML Thot schema for document doc.
 60  ----------------------------------------------------------------------*/
 61SSchema GetMathMLSSchema (Document doc)
 62{
 63  SSchema	MathMLSSchema;
 64
 65  MathMLSSchema = TtaGetSSchema ("MathML", doc);
 66  if (MathMLSSchema == NULL)
 67    MathMLSSchema = TtaNewNature(doc, 
 68                                 TtaGetDocumentSSchema(doc), NULL,
 69                                 "MathML", "MathMLP");
 70  return (MathMLSSchema);
 71}
 72
 73/*----------------------------------------------------------------------
 74  GetSVGSSchema returns the SVG Thot schema for document doc.
 75  ----------------------------------------------------------------------*/
 76SSchema GetSVGSSchema (Document doc)
 77{
 78  SSchema	SVGSSchema;
 79
 80  SVGSSchema = TtaGetSSchema ("SVG", doc);
 81  if (SVGSSchema == NULL)
 82    SVGSSchema = TtaNewNature(doc, TtaGetDocumentSSchema(doc), NULL,
 83                              "SVG", "SVGP");
 84  return (SVGSSchema);
 85}
 86
 87/*----------------------------------------------------------------------
 88  GetXLinkSSchema returns the XLink Thot schema for document doc.
 89  ----------------------------------------------------------------------*/
 90SSchema GetXLinkSSchema (Document doc)
 91{
 92  SSchema	XLinkSSchema;
 93
 94  XLinkSSchema = TtaGetSSchema ("XLink", doc);
 95  if (XLinkSSchema == NULL)
 96    XLinkSSchema = TtaNewNature(doc, TtaGetDocumentSSchema(doc), NULL,
 97                                    "XLink", "XLinkP");
 98  return (XLinkSSchema);
 99}
100
101/* --------------------------------------------------------------------
102   GetTemplateSSchema returns the Template Thot schema for document doc.
103   --------------------------------------------------------------------*/
104SSchema GetTemplateSSchema (Document doc)
105{
106  SSchema       TemplateSSchema = NULL;
107  
108#ifdef TEMPLATES
109  TemplateSSchema = TtaGetSSchema ("Template", doc);
110  if (TemplateSSchema == NULL)
111    {
112      if (IsTemplateInstanceDocument(doc))
113        TemplateSSchema = TtaNewNature (doc, TtaGetDocumentSSchema(doc), NULL,
114                                    "Template", "TemplatePI");
115      else
116        TemplateSSchema = TtaNewNature (doc, TtaGetDocumentSSchema(doc), NULL,
117                                        "Template", "TemplateP");
118    }
119#endif /* TEMPLATES */
120  return (TemplateSSchema);
121}
122    
123
124
125/*----------------------------------------------------------------------
126  GetTextSSchema returns the TextFile Thot schema for document doc.
127  (this is not XML, but its useful to have this function here).
128  ----------------------------------------------------------------------*/
129SSchema GetTextSSchema (Document doc)
130{
131  SSchema	XLinkSSchema;
132
133  XLinkSSchema = TtaGetSSchema ("TextFile", doc);
134  if (XLinkSSchema == NULL)
135    XLinkSSchema = TtaNewNature(doc, TtaGetDocumentSSchema(doc), NULL,
136                                "TextFile", "TextFileP");
137  return (XLinkSSchema);
138}
139
140/*----------------------------------------------------------------------
141  GetGenericXMLSSchema
142  Returns the XML Thot schema of name schemaName for the document doc.
143  ----------------------------------------------------------------------*/
144SSchema GetGenericXMLSSchema (const char *schemaName, Document doc)
145{
146  SSchema	XMLSSchema;
147
148  XMLSSchema = TtaGetSSchema (schemaName, doc);
149  if (XMLSSchema == NULL)
150    XMLSSchema = TtaNewNature(doc, TtaGetDocumentSSchema(doc), NULL,
151                              "XML", "XMLP");
152  return (XMLSSchema);
153}
154
155/*----------------------------------------------------------------------
156  GetGenericXMLSSchemaByUri
157  Returns the XML Thot schema for the document doc.
158  ----------------------------------------------------------------------*/
159SSchema GetGenericXMLSSchemaByUri (const char *uriName, Document doc, ThotBool *isnew)
160{
161  SSchema	XMLSSchema;
162
163  if (uriName == NULL)
164    XMLSSchema = TtaGetSSchemaByUri ("Default_Uri", doc);
165  else
166    XMLSSchema = TtaGetSSchemaByUri (uriName, doc);
167  if (XMLSSchema == NULL)
168    {
169      XMLSSchema = TtaNewNature(doc, TtaGetDocumentSSchema(doc), uriName,
170                                "XML", "XMLP");
171      *isnew = TRUE;
172    }
173  return (XMLSSchema);
174}
175
176
177/*----------------------------------------------------------------------
178  GetXMLSSchema returns the XML Thot schema for document doc.
179  ----------------------------------------------------------------------*/
180SSchema GetXMLSSchema (int XMLtype, Document doc)
181{
182  if (XMLtype == XHTML_TYPE)
183    return GetXHTMLSSchema (doc);
184  else if (XMLtype == MATH_TYPE)
185    return GetMathMLSSchema (doc);
186  else if (XMLtype == SVG_TYPE)
187    return GetSVGSSchema (doc);
188  else if (XMLtype == XLINK_TYPE)
189    return GetXLinkSSchema (doc);
190  else if (XMLtype == Template_TYPE)
191    return GetTemplateSSchema (doc);
192  else
193    return NULL;
194}
195
196/*--------------------------------------------------------------------------
197  HasNatures
198  Check if there are MathML and/or SVG natures
199  --------------------------------------------------------------------------*/
200void HasNatures (Document document, ThotBool *useMathML, ThotBool *useSVG)
201{
202  SSchema         nature;
203  char           *ptr;
204
205  /* look for a MathML or SVG nature within the document */
206  nature = NULL;
207  *useMathML = FALSE;
208  *useSVG = FALSE;
209  if (DocumentMeta[document] && DocumentMeta[document]->compound)
210    do
211      {
212        TtaNextNature (document, &nature);
213        if (nature)
214          {
215            ptr = TtaGetSSchemaName (nature);
216            if (!strcmp (ptr, "MathML"))
217              *useMathML = TRUE;
218            if (!strcmp (ptr, "SVG"))
219              *useSVG = TRUE;
220          }
221      }
222    while (nature);
223}
224
225/*----------------------------------------------------------------------
226  MapXMLElementType
227  Generic function which searchs in the Element Mapping table, selected
228  by the parameter XMLtype, the entry XMLname and returns the corresponding
229  Thot element type.
230  If SSchema is specified (not NULL)in elType, only it is searched.
231  Returns:
232  - ElTypeNum and ElSSchema into elType  ElTypeNum = 0 if not found.
233  - content information about this entry
234  - checkProfile TRUE if the entry is valid for the current Doc profile.
235  ----------------------------------------------------------------------*/
236void MapXMLElementType (int XMLtype, const char *XMLname, ElementType *elType,
237                        char **mappedName, char *content,
238                        ThotBool *checkProfile, Document doc)
239{
240  ElemMapping        *ptr;
241  char                c;
242  int                 i, profile;
243  ThotBool            xmlformat;
244
245  /* Initialize variables */
246  *mappedName = NULL;
247  *checkProfile = TRUE;
248  elType->ElTypeNum = 0;
249  profile = TtaGetDocumentProfile (doc);
250  if (profile == L_Annot)
251    profile = L_Other;
252  /* case sensitive comparison for xml documents */
253  xmlformat = (DocumentMeta[doc] && DocumentMeta[doc]->xmlformat);
254
255  /* Select the right table */
256  if (XMLtype == XHTML_TYPE)
257    {
258      ptr = XHTMLElemMappingTable;
259      /* no case sensitive whent there is an explicit "text/html" content_type */
260      if (xmlformat && DocumentMeta[doc] && DocumentMeta[doc]->content_type &&
261          !strcmp (DocumentMeta[doc]->content_type, "text/html"))
262        xmlformat = FALSE;
263    }
264  else if (XMLtype == MATH_TYPE)
265    {
266      if (profile == L_Basic && DocumentTypes[doc] == docHTML)
267        {
268          /* Maths are not allowed in this document */
269          ptr = NULL;
270          *checkProfile = FALSE;
271        }
272      else
273        ptr = MathMLElemMappingTable;
274    }
275  else if (XMLtype == SVG_TYPE)
276    {
277      if (profile == L_Basic && DocumentTypes[doc] == docHTML)
278        {
279          /* Graphics are not allowed in this document */
280          ptr = NULL;
281          *checkProfile = FALSE;
282        }
283      else
284        ptr = SVGElemMappingTable;
285    }
286#ifdef TEMPLATES
287  else if (XMLtype == Template_TYPE)
288    {
289      if (profile == L_Basic && DocumentTypes[doc] == docHTML)
290        {
291          /* Graphics are not allowed in this document */
292          ptr = NULL;
293          *checkProfile = FALSE;
294        }
295      else
296        ptr = TemplateElemMappingTable;
297    }
298#endif /* TEMPLATES */
299  else
300    ptr = NULL;
301   
302  if (ptr)
303    {
304      /* search in the ElemMappingTable */
305      i = 0;
306      /* case insensitive for HTML */
307      if (!xmlformat && ptr == XHTMLElemMappingTable)
308        c = tolower (XMLname[0]);
309      else
310        c = XMLname[0];
311      /* look for the first concerned entry in the table */
312      while (ptr[i].XMLname[0] < c && ptr[i].XMLname[0] != EOS)
313        i++;     
314      /* look at all entries starting with the right character */
315      do
316        if (!xmlformat && ptr == XHTMLElemMappingTable &&
317            strcasecmp (ptr[i].XMLname, XMLname))
318          /* it's not the tag */
319          i++;
320        else if ((xmlformat || ptr != XHTMLElemMappingTable) &&
321                 strcmp (ptr[i].XMLname, XMLname))
322          /* it's not the tag */
323          i++;
324        else if (XMLtype == XHTML_TYPE && profile != L_Other && !(ptr[i].Level & profile))
325          {
326            /* this tag is not valid in the document profile */
327            *checkProfile = FALSE;
328            i++;
329          }
330        else
331          {
332            elType->ElTypeNum = ptr[i].ThotType;
333            if (elType->ElSSchema == NULL)
334              {
335                if (XMLtype == Template_TYPE)
336                  elType->ElSSchema = GetTemplateSSchema(doc);
337                else
338                  elType->ElSSchema = GetXMLSSchema (XMLtype, doc);
339              }
340            *mappedName = ptr[i].XMLname;
341            *content = ptr[i].XMLcontents;
342          }
343      while (elType->ElTypeNum <= 0 && ptr[i].XMLname[0] == c);
344    }
345}
346
347
348/*----------------------------------------------------------------------
349  GetXMLElementName
350  Generic function which searchs in the mapping tables the XML name for
351  a given Thot type.
352  ----------------------------------------------------------------------*/
353const char *GetXMLElementName (ElementType elType, Document doc)
354{
355  ElemMapping  *ptr;
356  char         *name;
357  int           i, profile;
358  ThotBool      invalid = FALSE;
359
360  if (elType.ElTypeNum > 0)
361    {
362      i = 0;
363      /* Select the table which matches with the element schema */
364      name = TtaGetSSchemaName (elType.ElSSchema);
365      if (strcmp ("MathML", name) == 0)
366        ptr = MathMLElemMappingTable;
367      else if (strcmp ("SVG", name) == 0)
368        ptr = SVGElemMappingTable;
369      else if (strcmp ("HTML", name) == 0)
370        ptr = XHTMLElemMappingTable;
371#ifdef TEMPLATES
372      else if (strcmp ("Template", name) == 0)
373        ptr = TemplateElemMappingTable;
374#endif /* TEMPLATES */
375      else
376        ptr = NULL;
377
378      profile = TtaGetDocumentProfile (doc);
379      if (profile == L_Annot)
380        profile = L_Other;
381
382      if (ptr)
383        do
384          {
385            if (ptr[i].ThotType == elType.ElTypeNum)
386              {
387                if (doc == 0 || 
388                    profile == L_Other || (ptr[i].Level & profile))
389                  return ptr[i].XMLname;
390                else
391                  invalid = TRUE;
392              }
393            i++;
394          }
395        while (ptr[i].XMLname[0] != EOS);	  
396    }
397  if (invalid)
398    return "";
399  else
400    return "???";
401}
402
403
404/*----------------------------------------------------------------------
405  IsXMLElementInline
406  Generic function which searchs in the mapping tables if a given
407  Thot type is an inline character or not
408  ----------------------------------------------------------------------*/
409ThotBool IsXMLElementInline (ElementType elType, Document doc)
410{
411  int            i;
412  ThotBool       ret = FALSE;
413  char          *name;
414  ElemMapping   *ptr;
415
416  if (elType.ElTypeNum > 0)
417    {
418      i = 0;
419      /* Select the table which matches with the element schema */
420      name = TtaGetSSchemaName (elType.ElSSchema);
421      if (strcmp ("MathML", name) == 0)
422        ptr = MathMLElemMappingTable;
423      else if (strcmp ("SVG", name) == 0)
424        ptr = SVGElemMappingTable;
425      else if (strcmp ("HTML", name) == 0)
426        ptr = XHTMLElemMappingTable;
427#ifdef TEMPLATES
428      else if (strcmp ("Template", name) == 0)
429        return FALSE;
430#endif /* TEMPLATES */
431      else
432        ptr = NULL;
433      
434      if (ptr)
435        {
436          while (ptr[i].XMLname[0] != EOS &&
437                 ptr[i].ThotType != elType.ElTypeNum)
438            i++;
439          if (ptr[i].ThotType == elType.ElTypeNum)
440            ret = ptr[i].InlineElem;
441        }
442    }
443  return ret;
444}
445
446/*----------------------------------------------------------------------
447  MapXMLAttributeValue
448  Search in the Attribute Value Mapping Table the entry for the attribute
449  ThotAtt and its value attVal. Returns the corresponding Thot value.
450  ----------------------------------------------------------------------*/
451void MapXMLAttributeValue (int XMLtype, char *attVal, const AttributeType *attrType,
452                           int *value)
453{
454  AttrValueMapping   *ptr;
455  int                 i;
456
457  /* Select the right table */
458  if (XMLtype == XHTML_TYPE)
459    ptr = XhtmlAttrValueMappingTable;
460  else if (XMLtype == MATH_TYPE)
461    ptr = MathMLAttrValueMappingTable;
462  else if (XMLtype == SVG_TYPE)
463    ptr = SVGAttrValueMappingTable;
464#ifdef TEMPLATES
465  else if (XMLtype == Template_TYPE)
466    ptr = TemplateAttrValueMappingTable;
467#endif /* TEMPLATES */
468  else
469    ptr = NULL;
470  
471  *value = 0;
472  i = 0;
473  if (ptr == NULL)
474    return;
475  while (ptr[i].ThotAttr != attrType->AttrTypeNum && ptr[i].ThotAttr != 0)
476    i++;
477  if (ptr[i].ThotAttr == attrType->AttrTypeNum)
478    do
479      if (!strcmp (ptr[i].XMLattrValue, attVal))
480        *value = ptr[i].ThotAttrValue;
481      else
482        i++;
483    while (*value == 0 && ptr[i].ThotAttr == attrType->AttrTypeNum);
484}
485
486
487/*----------------------------------------------------------------------
488  MapXMLAttribute
489  Generic function which searchs in the Attribute Mapping Table (table)
490  the entry attrName associated to the element elementName.
491  Returns the corresponding entry or -1.
492  ----------------------------------------------------------------------*/
493int MapXMLAttribute (int XMLtype, const char *attrName, const char *elementName,
494                     ThotBool *checkProfile, Document doc, int *thotType)
495{
496  AttributeMapping   *ptr;
497  char                c;
498  int                 i, profile, extraprofile;
499  ThotBool            xmlformat;
500
501  /* Initialization */
502  *checkProfile = TRUE;
503  i = 1;
504  *thotType = 0;
505  /* case sensitive comparison for xml documents */
506  xmlformat = (DocumentMeta[doc] && DocumentMeta[doc]->xmlformat);
507  
508  /* Select the right table */
509  if (XMLtype == XHTML_TYPE)
510    {
511      ptr = XHTMLAttributeMappingTable;
512      /* no case sensitive whent there is an explicit "text/html" content_type */
513      if (xmlformat && DocumentMeta[doc] && DocumentMeta[doc]->content_type &&
514          !strcmp (DocumentMeta[doc]->content_type, "text/html"))
515        xmlformat = FALSE;
516    }
517  else if (XMLtype == MATH_TYPE)
518    ptr = MathMLAttributeMappingTable;
519  else if (XMLtype == SVG_TYPE)
520    ptr = SVGAttributeMappingTable;
521#ifdef TEMPLATES
522  else if (XMLtype == Template_TYPE)
523    ptr = TemplateAttributeMappingTable;
524#endif /* TEMPLATES */
525  else if (XMLtype == XLINK_TYPE)
526    ptr = XLinkAttributeMappingTable;
527
528  else
529    ptr = NULL;
530  if (ptr == NULL)
531    return -1;
532  if (strcmp (attrName, "unknown_attr") == 0)
533    {
534      *thotType = ptr[0].ThotAttribute;
535      return 0;
536    }
537
538  /* case insensitive for HTML */
539  if (!xmlformat && ptr == XHTMLAttributeMappingTable)
540    c = tolower (attrName[0]);
541  else
542    c = attrName[0];
543
544  profile = TtaGetDocumentProfile (doc);
545  extraprofile = TtaGetDocumentExtraProfile (doc);
546
547  if (profile == L_Annot)
548    profile = L_Other;
549  /* look for the first concerned entry in the table */
550  while (ptr[i].XMLattribute[0] < c &&  ptr[i].XMLattribute[0] != EOS)
551    i++;
552  while (ptr[i].XMLattribute[0] == c)
553    {
554      if (!xmlformat && ptr == XHTMLAttributeMappingTable &&
555          (strcasecmp (ptr[i].XMLattribute, attrName) ||
556           (ptr[i].XMLelement[0] != EOS && elementName &&
557            strcasecmp (ptr[i].XMLelement, elementName))))
558        i++;
559      else if ((xmlformat || ptr != XHTMLAttributeMappingTable) &&
560               (strcmp (ptr[i].XMLattribute, attrName) ||
561                (ptr[i].XMLelement[0] != EOS && elementName &&
562                 strcmp (ptr[i].XMLelement, elementName))))
563        i++;
564      else if (profile != L_Other && extraprofile == 0 && !(ptr[i].Level & profile))
565        {
566          *checkProfile = FALSE;
567          i++;
568        }
569      else if ((ptr[i].Level == L_RDFaValue) && (extraprofile != L_RDFa))
570        {
571          *checkProfile = FALSE;
572          i++;
573        }
574      else
575        {
576          /* Special case for the 'name' attribute for elements 'a' and 'map' in xhtml1.1 profile */
577          if ((profile == L_Xhtml11) &&
578              !strcmp (attrName, "name") && elementName &&
579              (!strcmp (elementName, "a") || !strcmp (elementName, "map")))
580            *checkProfile = FALSE;
581          /* Special case for the attributes 'rel' and 'rev' for elements 'a' and 'link' */
582          else if ((!strcmp (attrName, "rel") || !strcmp (attrName, "rev")) &&
583		   elementName && 
584                   (strcmp (elementName, "a") && strcmp (elementName, "link")) &&
585		   (extraprofile != L_RDFa))
586	    *checkProfile = FALSE;
587	  else
588            *thotType = ptr[i].ThotAttribute;
589          return (i);
590        }
591    }
592  return (-1);
593}
594
595
596/*----------------------------------------------------------------------
597  GetXMLAttributeName
598  Generic function which searchs in the mapping tables the XML name for
599  a given Thot type.
600  ----------------------------------------------------------------------*/
601const char *GetXMLAttributeName (AttributeType attrType, ElementType elType,
602                           Document doc)
603{
604  AttributeMapping   *ptr;
605  char               *name;
606  const char         *tag;
607  int                 i, profile, extraprofile;
608  ThotBool            invalid = FALSE;
609
610  if (attrType.AttrTypeNum > 0)
611    {
612      /* get the specific element tag */
613      if (elType.ElTypeNum > 0)
614        tag = GetXMLElementName (elType, doc);
615      else
616        tag = "";
617
618      i = 0;
619      /* Select the table which matches with the element schema */
620      name = TtaGetSSchemaName (attrType.AttrSSchema);
621      if (strcmp ("MathML", name) == 0)
622        ptr = MathMLAttributeMappingTable;
623#ifdef _SVG
624      else if (strcmp ("SVG", name) == 0)
625        ptr = SVGAttributeMappingTable;
626#endif /* _SVG */
627      else if (strcmp ("XLink", name) == 0)
628        ptr = XLinkAttributeMappingTable;
629#ifdef TEMPLATES
630      else if (strcmp ("Template",name) == 0)
631        ptr = TemplateAttributeMappingTable;
632#endif /* TEMPLATES */
633      else
634        ptr = XHTMLAttributeMappingTable;
635      
636      profile = TtaGetDocumentProfile (doc);
637      extraprofile = TtaGetDocumentExtraProfile (doc);
638      if (profile == L_Annot)
639        profile = L_Other;
640
641      if (ptr)
642        do
643          {
644            if (ptr[i].ThotAttribute == attrType.AttrTypeNum &&
645                (ptr[i].XMLelement[0] == EOS || !strcmp (ptr[i].XMLelement, tag)))
646              {
647                if (doc != 0 && profile != L_Other && extraprofile == L_NoExtraProfile && !(ptr[i].Level & profile))
648                  invalid = TRUE;
649                else if (doc != 0 && ptr[i].Level == L_RDFaValue && extraprofile != L_RDFa)
650                  invalid = TRUE;
651		else if ((attrType.AttrTypeNum == HTML_ATTR_REL ||
652			  attrType.AttrTypeNum == HTML_ATTR_REV) &&
653		 	  elType.ElTypeNum != HTML_EL_Anchor &&
654			  elType.ElTypeNum != HTML_EL_LINK &&
655			  extraprofile != L_RDFa)
656                  invalid = TRUE;
657		else
658                  return ptr[i].XMLattribute;
659              }
660            i++;
661          }
662        while (ptr[i].XMLattribute[0] != EOS);	  
663    }
664  if (invalid)
665    return "";
666  else
667    return "???";
668}
669
670/*----------------------------------------------------------------------
671  HasADoctype returns TRUE if the document includes a DocType
672  ----------------------------------------------------------------------*/
673void HasADoctype (Document doc, ThotBool *found, ThotBool *useMath)
674{
675  Element         el_doc, el_doctype;
676  ElementType     elType;
677  char           *s;
678  ThotBool        useSVG;
679
680  /* Look for a doctype */
681  el_doc = TtaGetMainRoot (doc);
682  elType = TtaGetElementType (el_doc);
683  /* Search the doctype declaration according to the main schema */
684  s = TtaGetSSchemaName (elType.ElSSchema);
685  if (strcmp (s, "HTML") == 0)
686    elType.ElTypeNum = HTML_EL_DOCTYPE;
687  else if (strcmp (s, "SVG") == 0)
688    elType.ElTypeNum = SVG_EL_DOCTYPE;
689  else if (strcmp (s, "MathML") == 0)
690    elType.ElTypeNum = MathML_EL_DOCTYPE;
691  else
692    elType.ElTypeNum = XML_EL_doctype;
693  el_doctype = TtaSearchTypedElement (elType, SearchInTree, el_doc);
694  *found = (el_doctype != NULL);
695  HasNatures (doc, useMath, &useSVG);
696}
697
698
699/*----------------------------------------------------------------------
700  MapXMLEntity
701  Generic function which searchs in the Entity Mapping Table (table)
702  the entry entityName and give the corresponding decimal value.
703  Returns FALSE if entityName is not found.
704  ----------------------------------------------------------------------*/
705ThotBool MapXMLEntity (int XMLtype, char *entityName, int *entityValue)
706{
707  XmlEntity  *ptr;
708  ThotBool    found;
709  int         inf, sup, med, rescomp;
710
711  /* Initialization */
712  found = FALSE;
713  sup = 0;
714
715  /* Select the right table */
716  if (XMLtype == XHTML_TYPE || XMLtype == Template_TYPE)
717    {
718      ptr = XhtmlEntityTable;
719      if (XHTMLSup == 0)
720        for (XHTMLSup = 0; ptr[XHTMLSup].charCode > 0; XHTMLSup++);
721      sup = XHTMLSup;
722    }
723  else if (XMLtype == MATH_TYPE)
724    {
725      ptr = MathEntityTable;
726      if (MathSup == 0)
727        for (MathSup = 0; ptr[MathSup].charCode > 0; MathSup++);
728      sup = MathSup;
729    }
730  else
731    ptr = NULL;
732  
733  if (ptr)
734    {
735      inf = 0;
736      while (sup >= inf && !found)
737        /* Dichotomic research */
738        {
739          med = (sup + inf) / 2;
740          rescomp = strcmp (ptr[med].charName, entityName);
741          if (rescomp == 0)
742            {
743              /* entity found */
744              *entityValue = ptr[med].charCode;
745              found = TRUE;
746            }
747          else
748            {
749              if (rescomp > 0)
750                sup = med - 1;
751              else
752                inf = med + 1;
753            }
754        }
755    }
756  if (!found && ptr == XhtmlEntityTable)
757    // check MathML entities
758    return MapXMLEntity (MATH_TYPE, entityName, entityValue);
759  return found;
760}
761
762/*----------------------------------------------------------------------
763  MapEntityByCode
764  Generic function which searchs in the Entity Mapping Table (table)
765  the entry with code entityValue and give the corresponding name.
766  withMath is TRUE when MathML entities are accepted.
767  Returns FALSE if entityValue is not found.
768  ----------------------------------------------------------------------*/
769void MapEntityByCode (int entityValue, Document doc, ThotBool withMath,
770                      char **entityName)
771{
772  XmlEntity  *ptr;
773  ThotBool    found;
774  int         i;
775
776  /* Select the right table */
777  if (withMath)
778    /* look for in the Math entities table */
779    ptr = MathEntityTable;
780  else
781    ptr = XhtmlEntityTable;
782  if (ptr)
783    {
784      /* look for in the HTML entities table */
785      found = FALSE;
786      while (ptr && !found)
787        {
788          for (i = 0; ptr[i].charCode != 0 && !found; i++)
789            found = (ptr[i].charCode == entityValue);
790  
791          if (found)
792            {
793              /* entity value found */
794              i--;
795              *entityName = (char *) (ptr[i].charName);
796            }
797          else if (withMath && ptr != XhtmlEntityTable)
798            /* look for in the Math entities table */
799            ptr = XhtmlEntityTable;
800          else
801            {
802              *entityName = NULL;
803              ptr = NULL;
804            }
805        }
806    }
807  else
808    *entityName = NULL;
809}