PageRenderTime 84ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/amaya/Xml2thot.c

https://github.com/pffy/Amaya-Editor
C | 6164 lines | 4635 code | 463 blank | 1066 comment | 1209 complexity | 9aeb6c61af3f76763d5692ef2d9acfff MD5 | raw file
  1. /*
  2. *
  3. * (c) COPYRIGHT INRIA and W3C, 1996-2009
  4. * Please first read the full copyright statement in file COPYRIGHT.
  5. *
  6. */
  7. /*
  8. * Xml2thot.c
  9. *
  10. * Initializes and launches Expat parser and processes all the events it sent
  11. * Builds the Thot abstract tree corresponding to the XML document.
  12. *
  13. * Authors: L. Carcone
  14. * V. Quint
  15. */
  16. #undef THOT_EXPORT
  17. #define THOT_EXPORT extern
  18. #include "amaya.h"
  19. #include "css.h"
  20. #include "parser.h"
  21. #include "zlib.h"
  22. #include "MathML.h"
  23. #include "fetchHTMLname.h"
  24. #include "document.h"
  25. #include "AHTURLTools_f.h"
  26. #include "EDITstyle_f.h"
  27. #include "HTMLactions_f.h"
  28. #include "HTMLedit_f.h"
  29. #include "HTMLimage_f.h"
  30. #include "HTMLtable_f.h"
  31. #include "HTMLimage_f.h"
  32. #include "HTMLbook_f.h"
  33. #include "css_f.h"
  34. #include "UIcss_f.h"
  35. #include "fetchHTMLname_f.h"
  36. #include "fetchXMLname_f.h"
  37. #include "html2thot_f.h"
  38. #include "Xml2thot_f.h"
  39. #include "init_f.h"
  40. #include "styleparser_f.h"
  41. #include "XHTMLbuilder_f.h"
  42. #include "MathMLbuilder_f.h"
  43. #include "SVGbuilder_f.h"
  44. #ifdef XML_GENERIC
  45. #include "Xmlbuilder_f.h"
  46. #endif /* XML_GENERIC */
  47. #include "Elemlist.h"
  48. #ifdef TEMPLATES
  49. #include "MENUconf.h"
  50. #include "templates.h"
  51. #include "Elemlist.h"
  52. #include "Templatebuilder_f.h"
  53. #include "templates_f.h"
  54. #endif /* TEMPLATES */
  55. #include "XLinkbuilder_f.h"
  56. #ifdef ANNOTATIONS
  57. #include "annotlib.h"
  58. #include "ANNOTtools_f.h"
  59. #endif /* ANNOTATIONS */
  60. #include "expat.h"
  61. #define NS_SEP '|'
  62. #define NS_COLON ':'
  63. /* ---------------------- static variables ---------------------- */
  64. /* Expat parser identifier */
  65. static XML_Parser Parser = NULL;
  66. /* global data used by the HTML parser */
  67. static ParserData XMLcontext = {0, UTF_8, 0, NULL, 0,
  68. FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
  69. /* a parser context. It describes the specific actions to be executed
  70. when parsing an XML document fragment according to a given DTD */
  71. typedef struct _XMLparserContext *PtrParserCtxt;
  72. typedef struct _XMLparserContext
  73. {
  74. char *UriName; /* URI of namespaces for that DTD */
  75. PtrParserCtxt NextParserCtxt; /* next parser context */
  76. char *SSchemaName; /* name of Thot structure schema */
  77. SSchema XMLSSchema; /* the Thot structure schema */
  78. int XMLtype; /* indentifier used by fetchname */
  79. Proc MapAttribute; /* returns the Thot attribute corresp.
  80. to an XML attribute name */
  81. Proc MapAttributeValue; /* returns the Thot value corresp. to
  82. the name of an XML attribute value */
  83. Proc CheckContext; /* action to be called to verify if an
  84. element is allowed in the current
  85. structural context */
  86. Proc CheckInsert; /* action to be called to insert an
  87. element in the abstract tree */
  88. Proc ElementCreated; /* action to be called when an element
  89. has been created and inserted */
  90. Proc ElementComplete; /* action to be called when an element
  91. has been generated completely */
  92. Proc AttributeComplete; /* action to be called when an
  93. attribute has been generated */
  94. Proc GetDTDName; /* returns the name of the DTD to be
  95. used for parsing the contents of an
  96. element that uses a different DTD */
  97. Proc UnknownNameSpace; /* action to be called if an element
  98. belongs to a not-suported namespace */
  99. ThotBool DefaultLineBreak; /* default treatment for white-space */
  100. ThotBool DefaultLeadingSpace;
  101. ThotBool DefaultTrailingSpace;
  102. ThotBool DefaultContiguousSpace;
  103. /* preserve treatment for white-space */
  104. ThotBool PreserveLineBreak;
  105. ThotBool PreserveLeadingSpace;
  106. ThotBool PreserveTrailingSpace;
  107. ThotBool PreserveContiguousSpace;
  108. }
  109. XMLparserContext;
  110. /* information about XML languages */
  111. /* All parser contexts describing known XML DTDs constitute a chain */
  112. /* first context in the chain*/
  113. static PtrParserCtxt FirstParserCtxt = NULL;
  114. /* current context */
  115. static PtrParserCtxt CurrentParserCtxt = NULL;
  116. /* XHTML context */
  117. static PtrParserCtxt XhtmlParserCtxt = NULL;
  118. /* Generic XML context */
  119. static PtrParserCtxt GenericXmlParserCtxt = NULL;
  120. /* Namespaces table */
  121. #define MAX_NS_TABLE 50
  122. /* NameSpace prefix (if defined) */
  123. static char *Ns_Prefix[MAX_NS_TABLE];
  124. /* NameSpace URI */
  125. static char *Ns_Uri[MAX_NS_TABLE];
  126. /* first free element on the table */
  127. static int Ns_Level = 0;
  128. /* Current namespaces table */
  129. static char *CurNs_Prefix[MAX_NS_TABLE];
  130. static char *CurNs_Uri[MAX_NS_TABLE];
  131. static int CurNs_Level = 0;
  132. /* XML Style Sheets table */
  133. static char *XML_CSS_Href[MAX_NS_TABLE];
  134. static Document XML_CSS_Doc[MAX_NS_TABLE];
  135. static Element XML_CSS_El[MAX_NS_TABLE];
  136. static CSSmedia XML_CSS_Media[MAX_NS_TABLE];
  137. static int XML_CSS_Level = 0;
  138. /* Parser Stack */
  139. /* maximum stack height */
  140. #define MAX_STACK_HEIGHT 100
  141. /* XML element name */
  142. static char *nameElementStack[MAX_STACK_HEIGHT];
  143. /* element in the Thot abstract tree */
  144. static Element elementStack[MAX_STACK_HEIGHT];
  145. /* element language */
  146. static Language languageStack[MAX_STACK_HEIGHT];
  147. /* is space preserved for that element */
  148. static char spacePreservedStack[MAX_STACK_HEIGHT];
  149. /* context of the element */
  150. static PtrParserCtxt parserCtxtStack[MAX_STACK_HEIGHT];
  151. /* first free element on the stack */
  152. static int stackLevel = 1;
  153. static gzFile stream = 0;
  154. /* path or URL of the document */
  155. static char *docURL = NULL;
  156. /* save the docURL for some cases of parsing errors */
  157. static char *docURL2 = NULL;
  158. /* information about the Thot document under construction */
  159. /* Document structure schema */
  160. static SSchema DocumentSSchema = NULL;
  161. /* root element of the document */
  162. static Element RootElement;
  163. /* name of the root element */
  164. static char *XMLRootName;
  165. /* root element is closed */
  166. static ThotBool XMLrootClosed = FALSE;
  167. /* the last start tag is unknown in the current NS */
  168. static ThotBool UnknownElement = FALSE;
  169. /* the last start tag belongs to a non-supported NS */
  170. static ThotBool UnknownNS = FALSE;
  171. /* last attribute created */
  172. static Attribute currentAttribute = NULL;
  173. /* last created attribute is "unknown_attr"*/
  174. static ThotBool UnknownAttr;
  175. /* element with which the last */
  176. /* attribute has been associated */
  177. static Element lastAttrElement = NULL;
  178. /* entry in the AttributeMappingTable */
  179. /* of the attribute being created */
  180. static AttributeMapping* lastMappedAttr = NULL;
  181. /* Comments and PI generated by Amaya are skipped */
  182. static ThotBool ExtraPI = FALSE;
  183. /* the document DOCTYPE is currently parsed */
  184. static ThotBool WithinDoctype = FALSE;
  185. /* the content of a buffer is being parsed */
  186. static ThotBool PARSING_BUFFER = FALSE;
  187. /* parsing errors are not reported for external resources */
  188. static ThotBool ShowParsingErrors = FALSE;;
  189. static ThotBool ParsingSubTree = FALSE;
  190. static ThotBool ImmediatelyAfterTag = FALSE;
  191. static ThotBool HTMLStyleAttribute = FALSE;
  192. static ThotBool XMLSpaceAttribute = FALSE;
  193. static ThotBool ParsingCDATA = FALSE;
  194. static char currentElementContent = ' ';
  195. static char currentElementName[100];
  196. /* Global variable to handle white-space in XML documents */
  197. static ThotBool RemoveLineBreak = FALSE;
  198. static ThotBool RemoveLeadingSpace = FALSE;
  199. static ThotBool RemoveTrailingSpace = FALSE;
  200. static ThotBool RemoveContiguousSpace = FALSE;
  201. /* "Extra" counters for the characters and the lines read */
  202. static int ExtraLineRead = 0;
  203. static int ExtraOffset = 0;
  204. static int HtmlLineRead = 0;
  205. static int HtmlCharRead = 0;
  206. /* Virtual DOCTYPE Declaration */
  207. #define DECL_DOCTYPE "<!DOCTYPE html PUBLIC \"\" \"\">\n"
  208. #define DECL_DOCTYPE_LEN 29
  209. #define DECL_XML "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
  210. #define DECL_XML_LEN 44
  211. static ThotBool VirtualDoctype = FALSE;
  212. /* maximum size of error messages */
  213. #define MaxMsgLength 200
  214. static void StartOfXmlStartElement (const char *name);
  215. static void DisableExpatParser ();
  216. static void XhtmlCheckInsert (Element *el, Element parent, Document doc,
  217. ThotBool *inserted);
  218. static void XmlCheckInsert (Element *el, Element parent, Document doc,
  219. ThotBool *inserted);
  220. static void XhtmlCheckContext (char *elName, const ElementType * elType,
  221. ThotBool *isAllowed);
  222. static void XmlCheckContext (char *elName, const ElementType *elType,
  223. ThotBool *isAllowed);
  224. static void XmlParse (FILE *infile, CHARSET charset, ThotBool *xmlDec,
  225. ThotBool *xmlDoctype);
  226. /*----------------------------------------------------------------------
  227. ChangeXmlParserContextByDTD
  228. Get the parser context correponding to a given DTD
  229. ----------------------------------------------------------------------*/
  230. static void ChangeXmlParserContextByDTD (const char *DTDname)
  231. {
  232. CurrentParserCtxt = FirstParserCtxt;
  233. while (CurrentParserCtxt != NULL &&
  234. strcmp ((char *)DTDname, CurrentParserCtxt->SSchemaName))
  235. CurrentParserCtxt = CurrentParserCtxt->NextParserCtxt;
  236. /* initialize the corresponding entry */
  237. if (CurrentParserCtxt != NULL &&
  238. CurrentParserCtxt != GenericXmlParserCtxt &&
  239. CurrentParserCtxt->XMLSSchema == NULL)
  240. {
  241. CurrentParserCtxt->XMLSSchema =
  242. GetXMLSSchema (CurrentParserCtxt->XMLtype, XMLcontext.doc);
  243. TtaSetUriSSchema (CurrentParserCtxt->XMLSSchema, CurrentParserCtxt->UriName);
  244. }
  245. }
  246. /*----------------------------------------------------------------------
  247. ChangeXmlParserContextByUri
  248. Get the parser context correponding to a given namespace uri
  249. ----------------------------------------------------------------------*/
  250. static ThotBool ChangeXmlParserContextByUri (char *uriName)
  251. {
  252. ThotBool found = FALSE;
  253. CurrentParserCtxt = FirstParserCtxt;
  254. while (!found && CurrentParserCtxt)
  255. {
  256. if (CurrentParserCtxt->UriName == NULL)
  257. found = uriName == NULL;
  258. else if (!strcmp (CurrentParserCtxt->UriName, Template_URI))
  259. {
  260. /* Templates */
  261. if (!strcmp ((char *)uriName, Template_URI) ||
  262. !strcmp ((char *)uriName, Template_URI_o) ||
  263. !strcmp ((char *)uriName, Template_URI_f))
  264. found = TRUE;
  265. }
  266. else if (!strcmp ((char *)uriName, CurrentParserCtxt->UriName))
  267. found = TRUE;
  268. if (!found)
  269. CurrentParserCtxt = CurrentParserCtxt->NextParserCtxt;
  270. }
  271. /* Initialize the corresponding Thot schema */
  272. if (CurrentParserCtxt != NULL &&
  273. CurrentParserCtxt != GenericXmlParserCtxt &&
  274. CurrentParserCtxt->XMLSSchema == NULL)
  275. {
  276. CurrentParserCtxt->XMLSSchema =
  277. GetXMLSSchema (CurrentParserCtxt->XMLtype, XMLcontext.doc);
  278. TtaSetUriSSchema (CurrentParserCtxt->XMLSSchema, CurrentParserCtxt->UriName);
  279. return TRUE;
  280. }
  281. return FALSE;
  282. }
  283. /*----------------------------------------------------------------------
  284. InitXmlParserContexts
  285. Create the chain of parser contexts decribing all recognized XML DTDs
  286. ----------------------------------------------------------------------*/
  287. static void InitXmlParserContexts (void)
  288. {
  289. PtrParserCtxt ctxt, prevCtxt;
  290. FirstParserCtxt = NULL;
  291. prevCtxt = NULL;
  292. ctxt = NULL;
  293. /* create and initialize a context for XHTML */
  294. ctxt = (XMLparserContext*)TtaGetMemory (sizeof (XMLparserContext));
  295. if (prevCtxt == NULL)
  296. FirstParserCtxt = ctxt;
  297. else
  298. prevCtxt->NextParserCtxt = ctxt;
  299. ctxt->NextParserCtxt = NULL;
  300. ctxt->SSchemaName = (char *)TtaGetMemory (NAME_LENGTH);
  301. strcpy ((char *)ctxt->SSchemaName, "HTML");
  302. ctxt->UriName = (char *)TtaGetMemory (MAX_URI_NAME_LENGTH);
  303. strcpy ((char *)ctxt->UriName, (char *)XHTML_URI);
  304. ctxt->XMLSSchema = NULL;
  305. ctxt->XMLtype = XHTML_TYPE;
  306. ctxt->MapAttribute = (Proc) MapHTMLAttribute;
  307. ctxt->MapAttributeValue = (Proc) MapHTMLAttributeValue;
  308. ctxt->CheckContext = (Proc) XhtmlCheckContext;
  309. ctxt->CheckInsert = (Proc) XhtmlCheckInsert;
  310. ctxt->ElementCreated = NULL;
  311. ctxt->ElementComplete = (Proc) XhtmlElementComplete;
  312. ctxt->AttributeComplete = NULL;
  313. ctxt->GetDTDName = NULL;
  314. ctxt->UnknownNameSpace = (Proc)UnknownXhtmlNameSpace;
  315. ctxt->DefaultLineBreak = TRUE;
  316. ctxt->DefaultLeadingSpace = TRUE;
  317. ctxt->DefaultTrailingSpace = TRUE;
  318. ctxt->DefaultContiguousSpace = TRUE;
  319. ctxt->PreserveLineBreak = FALSE;
  320. ctxt->PreserveLeadingSpace = FALSE;
  321. ctxt->PreserveTrailingSpace = FALSE;
  322. ctxt->PreserveContiguousSpace = FALSE;
  323. XhtmlParserCtxt = ctxt;
  324. prevCtxt = ctxt;
  325. /* create and initialize a context for MathML */
  326. ctxt = (XMLparserContext*)TtaGetMemory (sizeof (XMLparserContext));
  327. if (prevCtxt == NULL)
  328. FirstParserCtxt = ctxt;
  329. else
  330. prevCtxt->NextParserCtxt = ctxt;
  331. ctxt->NextParserCtxt = NULL;
  332. ctxt->SSchemaName = (char *)TtaGetMemory (NAME_LENGTH);
  333. strcpy ((char *)ctxt->SSchemaName, "MathML");
  334. ctxt->UriName = (char *)TtaGetMemory (MAX_URI_NAME_LENGTH);
  335. strcpy ((char *)ctxt->UriName, (char *)MathML_URI);
  336. ctxt->XMLSSchema = NULL;
  337. ctxt->XMLtype = MATH_TYPE;
  338. ctxt->MapAttribute = (Proc) MapMathMLAttribute;
  339. ctxt->MapAttributeValue = (Proc) MapMathMLAttributeValue;
  340. ctxt->CheckContext = (Proc) XmlCheckContext;
  341. ctxt->CheckInsert = (Proc) XmlCheckInsert;
  342. ctxt->ElementCreated = (Proc) MathMLElementCreated;
  343. ctxt->ElementComplete = (Proc) MathMLElementComplete;
  344. ctxt->AttributeComplete = (Proc) MathMLAttributeComplete;
  345. ctxt->GetDTDName = (Proc) MathMLGetDTDName;
  346. ctxt->UnknownNameSpace = (Proc)UnknownMathMLNameSpace;
  347. ctxt->DefaultLineBreak = TRUE;
  348. ctxt->DefaultLeadingSpace = TRUE;
  349. ctxt->DefaultTrailingSpace = TRUE;
  350. ctxt->DefaultContiguousSpace = TRUE;
  351. ctxt->PreserveLineBreak = FALSE;
  352. ctxt->PreserveLeadingSpace = FALSE;
  353. ctxt->PreserveTrailingSpace = FALSE;
  354. ctxt->PreserveContiguousSpace = FALSE;
  355. prevCtxt = ctxt;
  356. /* create and initialize a context for SVG */
  357. ctxt = (XMLparserContext*)TtaGetMemory (sizeof (XMLparserContext));
  358. if (prevCtxt == NULL)
  359. FirstParserCtxt = ctxt;
  360. else
  361. prevCtxt->NextParserCtxt = ctxt;
  362. ctxt->NextParserCtxt = NULL;
  363. ctxt->SSchemaName = (char *)TtaGetMemory (NAME_LENGTH);
  364. strcpy ((char *)ctxt->SSchemaName, "SVG");
  365. ctxt->UriName = (char *)TtaGetMemory (MAX_URI_NAME_LENGTH);
  366. strcpy ((char *)ctxt->UriName, (char *)SVG_URI);
  367. ctxt->XMLSSchema = NULL;
  368. ctxt->XMLtype = SVG_TYPE;
  369. ctxt->MapAttribute = (Proc) MapSVGAttribute;
  370. ctxt->MapAttributeValue = (Proc) MapSVGAttributeValue;
  371. ctxt->CheckContext = (Proc) XmlCheckContext;
  372. ctxt->CheckInsert = (Proc) SVGCheckInsert;
  373. ctxt->ElementCreated = (Proc) SVGElementCreated;
  374. ctxt->ElementComplete = (Proc) SVGElementComplete;
  375. ctxt->AttributeComplete = (Proc) SVGAttributeComplete;
  376. ctxt->GetDTDName = (Proc) SVGGetDTDName;
  377. ctxt->UnknownNameSpace = (Proc)UnknownSVGNameSpace;
  378. ctxt->DefaultLineBreak = TRUE;
  379. ctxt->DefaultLeadingSpace = TRUE;
  380. ctxt->DefaultTrailingSpace = TRUE;
  381. ctxt->DefaultContiguousSpace = TRUE;
  382. ctxt->PreserveLineBreak = TRUE;
  383. ctxt->PreserveLeadingSpace = FALSE;
  384. ctxt->PreserveTrailingSpace = FALSE;
  385. ctxt->PreserveContiguousSpace = FALSE;
  386. prevCtxt = ctxt;
  387. #ifdef TEMPLATES
  388. /* create and initialize a context for Templates */
  389. ctxt = (XMLparserContext*)TtaGetMemory (sizeof (XMLparserContext));
  390. if (prevCtxt == NULL)
  391. FirstParserCtxt = ctxt;
  392. else
  393. prevCtxt->NextParserCtxt = ctxt;
  394. ctxt->NextParserCtxt = NULL;
  395. ctxt->SSchemaName = (char *)TtaGetMemory (NAME_LENGTH);
  396. strcpy ((char *)ctxt->SSchemaName, "Template");
  397. ctxt->UriName = (char *)TtaGetMemory (MAX_URI_NAME_LENGTH);
  398. strcpy ((char *)ctxt->UriName, (char *)Template_URI);
  399. ctxt->XMLSSchema = NULL;
  400. ctxt->XMLtype = Template_TYPE;
  401. ctxt->MapAttribute = (Proc) MapTemplateAttribute;
  402. ctxt->MapAttributeValue = (Proc) MapTemplateAttributeValue;
  403. ctxt->CheckContext = (Proc) XmlCheckContext;
  404. ctxt->CheckInsert = (Proc) TemplateCheckInsert;
  405. ctxt->ElementCreated = NULL;
  406. ctxt->ElementComplete = (Proc) TemplateElementComplete;
  407. ctxt->AttributeComplete = (Proc) TemplateAttributeComplete;
  408. ctxt->GetDTDName = (Proc) TemplateGetDTDName;
  409. ctxt->UnknownNameSpace = (Proc)UnknownTemplateNameSpace;
  410. ctxt->DefaultLineBreak = TRUE;
  411. ctxt->DefaultLeadingSpace = TRUE;
  412. ctxt->DefaultTrailingSpace = TRUE;
  413. ctxt->DefaultContiguousSpace = TRUE;
  414. ctxt->PreserveLineBreak = TRUE;
  415. ctxt->PreserveLeadingSpace = FALSE;
  416. ctxt->PreserveTrailingSpace = FALSE;
  417. ctxt->PreserveContiguousSpace = FALSE;
  418. prevCtxt = ctxt;
  419. #endif /* TEMPLATES */
  420. /* create and initialize a context for XLink */
  421. ctxt = (XMLparserContext*)TtaGetMemory (sizeof (XMLparserContext));
  422. if (prevCtxt == NULL)
  423. FirstParserCtxt = ctxt;
  424. else
  425. prevCtxt->NextParserCtxt = ctxt;
  426. ctxt->NextParserCtxt = NULL; /* last context */
  427. ctxt->SSchemaName = (char *)TtaGetMemory (NAME_LENGTH);
  428. strcpy ((char *)ctxt->SSchemaName, "XLink");
  429. ctxt->UriName = (char *)TtaGetMemory (MAX_URI_NAME_LENGTH);
  430. strcpy ((char *)ctxt->UriName, (char *)XLink_URI);
  431. ctxt->XMLSSchema = NULL;
  432. ctxt->XMLtype = XLINK_TYPE;
  433. ctxt->MapAttribute = (Proc) MapXLinkAttribute;
  434. ctxt->MapAttributeValue = (Proc) MapXLinkAttributeValue;
  435. ctxt->CheckContext = (Proc) XmlCheckContext;
  436. ctxt->CheckInsert = (Proc) XmlCheckInsert;
  437. ctxt->ElementCreated = NULL;
  438. ctxt->ElementComplete = NULL;
  439. ctxt->AttributeComplete = (Proc) XLinkAttributeComplete;
  440. ctxt->GetDTDName = NULL;
  441. ctxt->UnknownNameSpace = NULL;
  442. ctxt->DefaultLineBreak = TRUE;
  443. ctxt->DefaultLeadingSpace = TRUE;
  444. ctxt->DefaultTrailingSpace = TRUE;
  445. ctxt->DefaultContiguousSpace = TRUE;
  446. ctxt->PreserveLineBreak = FALSE;
  447. ctxt->PreserveLeadingSpace = FALSE;
  448. ctxt->PreserveTrailingSpace = FALSE;
  449. ctxt->PreserveContiguousSpace = FALSE;
  450. prevCtxt = ctxt;
  451. #ifdef XML_GENERIC
  452. /* create and initialize a context for generic XML */
  453. ctxt = (XMLparserContext*)TtaGetMemory (sizeof (XMLparserContext));
  454. if (prevCtxt == NULL)
  455. FirstParserCtxt = ctxt;
  456. else
  457. prevCtxt->NextParserCtxt = ctxt;
  458. ctxt->NextParserCtxt = NULL; /* last context */
  459. ctxt->SSchemaName = (char *)TtaGetMemory (NAME_LENGTH);
  460. strcpy ((char *)ctxt->SSchemaName, "XML");
  461. ctxt->UriName = (char *)TtaGetMemory (MAX_URI_NAME_LENGTH);
  462. ctxt->UriName[0] = EOS;
  463. ctxt->XMLSSchema = NULL;
  464. ctxt->XMLtype = XML_TYPE;
  465. ctxt->MapAttribute = NULL;
  466. ctxt->MapAttributeValue = (Proc) MapXmlAttributeValue;
  467. ctxt->CheckContext = (Proc) XmlCheckContext;
  468. ctxt->CheckInsert = (Proc) XmlCheckInsert;
  469. ctxt->ElementCreated = NULL;
  470. ctxt->ElementComplete = (Proc) XmlElementComplete;
  471. ctxt->AttributeComplete = (Proc) XmlAttributeComplete;
  472. ctxt->GetDTDName = NULL;
  473. ctxt->UnknownNameSpace = NULL;
  474. ctxt->DefaultLineBreak = TRUE;
  475. ctxt->DefaultLeadingSpace = TRUE;
  476. ctxt->DefaultTrailingSpace = TRUE;
  477. ctxt->DefaultContiguousSpace = TRUE;
  478. ctxt->PreserveLineBreak = FALSE;
  479. ctxt->PreserveLeadingSpace = FALSE;
  480. ctxt->PreserveTrailingSpace = FALSE;
  481. ctxt->PreserveContiguousSpace = FALSE;
  482. prevCtxt = ctxt;
  483. GenericXmlParserCtxt = ctxt;
  484. #endif /* XML_GENERIC */
  485. CurrentParserCtxt = NULL;
  486. }
  487. /*----------------------------------------------------------------------
  488. XmlSetElemLineNumber
  489. Assigns the current line number (number given by EXPAT parser.
  490. ----------------------------------------------------------------------*/
  491. void XmlSetElemLineNumber (Element el)
  492. {
  493. int lineNumber;
  494. if (ParsingSubTree)
  495. lineNumber = 0;
  496. else
  497. lineNumber = XML_GetCurrentLineNumber (Parser) + HtmlLineRead - ExtraLineRead;
  498. TtaSetElementLineNumber (el, lineNumber);
  499. }
  500. /*----------------------------------------------------------------------
  501. XmlParseError
  502. Print the error message msg on stderr.
  503. When the line is 0 ask to expat the current line number
  504. When the variable ShowParsingErrors is set to FALSE,
  505. the message is ignored (we are parsing an external resource).
  506. ----------------------------------------------------------------------*/
  507. void XmlParseError (ErrorType type, unsigned char *msg, int line)
  508. {
  509. int pos, n;
  510. const char *c;
  511. unsigned char val;
  512. if (IgnoreErrors)
  513. return;
  514. if (!ShowParsingErrors)
  515. return;
  516. if (line == 0 && Parser == NULL)
  517. return;
  518. if (!ErrFile)
  519. if (OpenParsingErrors (XMLcontext.doc) == FALSE)
  520. return;
  521. if (docURL)
  522. {
  523. fprintf (ErrFile, "\n*** Errors/warnings in %s\n", docURL);
  524. TtaFreeMemory (docURL);
  525. docURL = NULL;
  526. }
  527. else
  528. {
  529. if (CSSErrorsFound && docURL2)
  530. {
  531. fprintf (ErrFile, "\n*** Errors/warnings in %s\n", docURL2);
  532. TtaFreeMemory (docURL2);
  533. docURL2 = NULL;
  534. }
  535. }
  536. switch (type)
  537. {
  538. case errorEncoding:
  539. fprintf (ErrFile, "@ line 1, char 0: %s\n", msg);
  540. XMLCharacterNotSupported = TRUE;
  541. break;
  542. case errorNotWellFormed:
  543. if (line == 0)
  544. {
  545. if (Parser != NULL)
  546. {
  547. line = XML_GetCurrentLineNumber (Parser) + HtmlLineRead - ExtraLineRead;
  548. /* check if expat found an invalid utf-8 character or an error
  549. in an attribute value or an invalid entity */
  550. c = XML_GetInputContext (Parser, &pos, &n);
  551. if (c)
  552. val = (unsigned char)(c[pos]);
  553. else
  554. val = EOS;
  555. if (strstr ((char *)msg, "invalid token") && val > 127)
  556. XMLInvalidToken = TRUE;
  557. else
  558. XMLNotWellFormed = TRUE;
  559. fprintf (ErrFile, "@ line %d, char %d: %s\n", line,
  560. (int)XML_GetCurrentColumnNumber (Parser), msg);
  561. }
  562. }
  563. else
  564. {
  565. fprintf (ErrFile, "@ line %d: %s\n", line, msg);
  566. XMLNotWellFormed = TRUE;
  567. }
  568. break;
  569. case errorCharacterNotSupported:
  570. if (line == 0)
  571. {
  572. if (Parser != NULL)
  573. {
  574. fprintf (ErrFile, "@ line %d, char %d: %s\n",
  575. (int)XML_GetCurrentLineNumber (Parser) + HtmlLineRead - ExtraLineRead,
  576. (int)XML_GetCurrentColumnNumber (Parser),
  577. msg);
  578. }
  579. }
  580. else
  581. fprintf (ErrFile, "@ line %d: %s\n", line, msg);
  582. XMLCharacterNotSupported = TRUE;
  583. break;
  584. case errorParsing:
  585. XMLErrorsFound = TRUE;
  586. case warningMessage:
  587. if (line == 0)
  588. {
  589. if (Parser != NULL)
  590. {
  591. fprintf (ErrFile, "@ line %d, char %d: %s\n",
  592. (int)XML_GetCurrentLineNumber (Parser) + HtmlLineRead - ExtraLineRead,
  593. (int)XML_GetCurrentColumnNumber (Parser),
  594. msg);
  595. }
  596. }
  597. else
  598. fprintf (ErrFile, "@ line %d: %s\n", line, msg);
  599. break;
  600. case errorParsingProfile:
  601. if (line == 0)
  602. {
  603. if (Parser != NULL)
  604. {
  605. fprintf (ErrFile, "@ line %d, char %d: %s\n",
  606. (int)XML_GetCurrentLineNumber (Parser) + HtmlLineRead - ExtraLineRead,
  607. (int)XML_GetCurrentColumnNumber (Parser),
  608. msg);
  609. }
  610. }
  611. else
  612. fprintf (ErrFile, "@ line %d: %s\n", line, msg);
  613. XMLErrorsFoundInProfile = TRUE;
  614. break;
  615. case undefinedEncoding:
  616. fprintf (ErrFile, "@ %s\n", msg);
  617. break;
  618. }
  619. }
  620. /*----------------------------------------------------------------------
  621. IsXmlParsingCSS
  622. Returns the value of ParsingCSS boolean.
  623. ----------------------------------------------------------------------*/
  624. ThotBool IsXmlParsingCSS ()
  625. {
  626. return XMLcontext.parsingCSS;
  627. }
  628. /*----------------------------------------------------------------------
  629. SetXmlParsingCSS
  630. Sets the value of ParsingCSS boolean.
  631. ----------------------------------------------------------------------*/
  632. void SetXmlParsingCSS (ThotBool value)
  633. {
  634. XMLcontext.parsingCSS = value;
  635. }
  636. /*----------------------------------------------------------------------
  637. SetParsingTextArea
  638. Sets the value of ParsingTextArea boolean.
  639. ----------------------------------------------------------------------*/
  640. void SetParsingTextArea (ThotBool value)
  641. {
  642. XMLcontext.parsingTextArea = value;
  643. }
  644. /*----------------------------------------------------------------------
  645. SetParsingScript
  646. Sets the value of ParsingScript boolean.
  647. ----------------------------------------------------------------------*/
  648. void SetParsingScript (ThotBool value)
  649. {
  650. XMLcontext.parsingScript = value;
  651. }
  652. /*----------------------------------------------------------------------
  653. SetLanguagInXmlStack
  654. Sets the value of the language.
  655. ----------------------------------------------------------------------*/
  656. void SetLanguagInXmlStack (Language lang)
  657. {
  658. languageStack[stackLevel - 1] = lang;
  659. }
  660. /*----------------------------------------------------------------------
  661. IsWithinXmlTable
  662. Returns the value of WithinTable integer.
  663. ----------------------------------------------------------------------*/
  664. int IsWithinXmlTable ()
  665. {
  666. return XMLcontext.withinTable;
  667. }
  668. /*----------------------------------------------------------------------
  669. SubWithinTable
  670. ----------------------------------------------------------------------*/
  671. void SubWithinTable ()
  672. {
  673. XMLcontext.withinTable--;
  674. }
  675. /*----------------------------------------------------------------------
  676. XmlWhiteSpaceHandling
  677. Is there an openend element with a xml:space attribute ?
  678. ----------------------------------------------------------------------*/
  679. static void XmlWhiteSpaceHandling ()
  680. {
  681. int i;
  682. ThotBool found;
  683. if (CurrentParserCtxt == NULL)
  684. return;
  685. found = FALSE;
  686. i = stackLevel - 1;
  687. while (i > 0 && !found)
  688. {
  689. if (spacePreservedStack[i] == ' ')
  690. i--;
  691. else
  692. {
  693. found = TRUE;
  694. if (spacePreservedStack[i] == 'D')
  695. {
  696. RemoveLineBreak = CurrentParserCtxt->DefaultLineBreak;
  697. RemoveLeadingSpace = CurrentParserCtxt->DefaultLeadingSpace;
  698. RemoveTrailingSpace = CurrentParserCtxt->DefaultTrailingSpace;
  699. RemoveContiguousSpace = CurrentParserCtxt->DefaultContiguousSpace;
  700. }
  701. else
  702. {
  703. RemoveLineBreak = CurrentParserCtxt->PreserveLineBreak;
  704. RemoveLeadingSpace = CurrentParserCtxt->PreserveLeadingSpace;
  705. RemoveTrailingSpace = CurrentParserCtxt->PreserveTrailingSpace;
  706. RemoveContiguousSpace = CurrentParserCtxt->PreserveContiguousSpace;
  707. }
  708. }
  709. }
  710. if (!found)
  711. {
  712. RemoveLineBreak = CurrentParserCtxt->DefaultLineBreak;
  713. RemoveLeadingSpace = CurrentParserCtxt->DefaultLeadingSpace;
  714. RemoveTrailingSpace = CurrentParserCtxt->DefaultTrailingSpace;
  715. RemoveContiguousSpace = CurrentParserCtxt->DefaultContiguousSpace;
  716. }
  717. }
  718. /*----------------------------------------------------------------------
  719. XmlWhiteInStack
  720. The last element in stack has a xml:space attribute
  721. (or it is a pre, style, textarea or script element in XHTML)
  722. ----------------------------------------------------------------------*/
  723. static void XmlWhiteSpaceInStack (char *attrValue)
  724. {
  725. if (attrValue == NULL)
  726. spacePreservedStack[stackLevel-1] = 'P';
  727. else
  728. {
  729. if ((strcmp ((char *)attrValue, "default") == 0))
  730. spacePreservedStack[stackLevel-1] = 'D';
  731. else
  732. spacePreservedStack[stackLevel-1] = 'P';
  733. }
  734. }
  735. /*----------------------------------------------------------------------
  736. XmlWithinStack
  737. Checks if an element of type ThotType is in the stack.
  738. ----------------------------------------------------------------------*/
  739. static ThotBool XmlWithinStack (int ThotType, SSchema ThotSSchema)
  740. {
  741. ThotBool ret;
  742. int i;
  743. ElementType elType;
  744. ret = FALSE;
  745. i = stackLevel - 1;
  746. while (i >= 0 && !ret)
  747. {
  748. if (elementStack[i] != NULL)
  749. {
  750. elType = TtaGetElementType (elementStack[i]);
  751. if (elType.ElTypeNum == ThotType &&
  752. elType.ElSSchema == ThotSSchema)
  753. ret = TRUE;
  754. }
  755. i--;
  756. }
  757. return ret;
  758. }
  759. /*----------------------------------------------------------------------
  760. InsertingSibling
  761. Return TRUE if the new element must be inserted in the Thot document
  762. as a sibling of lastElement;
  763. Return FALSE if it must be inserted as a child.
  764. ----------------------------------------------------------------------*/
  765. static ThotBool InsertingSibling ()
  766. {
  767. if (stackLevel == 0)
  768. return FALSE;
  769. else
  770. if (XMLcontext.lastElementClosed ||
  771. TtaIsLeaf (TtaGetElementType (XMLcontext.lastElement)))
  772. return TRUE;
  773. else
  774. return FALSE;
  775. }
  776. /*----------------------------------------------------------------------
  777. XmlGetFallbackCharacter
  778. Tries to find a fallback character and generates a symbol if necessary
  779. ----------------------------------------------------------------------*/
  780. static void XmlGetFallbackCharacter (wchar_t wcharRead, char *entityName,
  781. Element el)
  782. {
  783. ElementType elType;
  784. Element elLeaf, lastChild;
  785. AttributeType attrType;
  786. Attribute attr;
  787. Language lang;
  788. unsigned char fallback[5];
  789. unsigned char bufName[10];
  790. unsigned char buffer[10];
  791. unsigned char *ptr;
  792. int len, i, j;
  793. lang = XMLcontext.language;
  794. GetFallbackCharacter ((int) wcharRead, fallback, &lang);
  795. if (fallback[0] == '?')
  796. {
  797. /* Character not found in the fallback table */
  798. /* Create a symbol leaf */
  799. elType = TtaGetElementType (el);
  800. elType.ElTypeNum = 3;
  801. elLeaf = TtaNewElement (XMLcontext.doc, elType);
  802. XmlSetElemLineNumber (elLeaf);
  803. if (el == XMLcontext.lastElement)
  804. InsertXmlElement (&elLeaf);
  805. else
  806. {
  807. /* within a comment */
  808. lastChild = TtaGetLastChild (el);
  809. if (lastChild == NULL)
  810. TtaInsertFirstChild (&elLeaf, el, XMLcontext.doc);
  811. else
  812. TtaInsertSibling (elLeaf, lastChild, FALSE, XMLcontext.doc);
  813. }
  814. /* Put the symbol '?' into the new symbol leaf */
  815. TtaSetGraphicsShape (elLeaf, fallback[0], XMLcontext.doc);
  816. /* Changes the wide char code associated with that symbol */
  817. TtaSetSymbolCode (elLeaf, wcharRead, XMLcontext.doc);
  818. /* Make that leaf read-only */
  819. TtaSetAccessRight (elLeaf, ReadOnly, XMLcontext.doc);
  820. }
  821. else
  822. {
  823. /* Character found in the fallback table */
  824. /* Create a new text leaf */
  825. elType = TtaGetElementType (el);
  826. elType.ElTypeNum = 1;
  827. elLeaf = TtaNewElement (XMLcontext.doc, elType);
  828. XmlSetElemLineNumber (elLeaf);
  829. if (el == XMLcontext.lastElement)
  830. InsertXmlElement (&elLeaf);
  831. else
  832. {
  833. /* within a comment */
  834. lastChild = TtaGetLastChild (el);
  835. if (lastChild == NULL)
  836. TtaInsertFirstChild (&elLeaf, el, XMLcontext.doc);
  837. else
  838. TtaInsertSibling (elLeaf, lastChild, FALSE, XMLcontext.doc);
  839. }
  840. /* Put the fallback character into the new text leaf */
  841. TtaSetTextContent (elLeaf, (unsigned char *)fallback, lang, XMLcontext.doc);
  842. }
  843. /* Associate an attribute EntityName with the new leaf */
  844. #ifdef TEST
  845. /* Old treatment to generate an 'entityName' attribute, useless now */
  846. attrType.AttrSSchema = elType.ElSSchema;
  847. ptr = (unsigned char*)TtaGetSSchemaName (elType.ElSSchema);
  848. if (strcmp ((char *)ptr, "MathML") == 0)
  849. attrType.AttrTypeNum = MathML_ATTR_EntityName;
  850. else if (strcmp ((char *)ptr, "HTML") == 0)
  851. attrType.AttrTypeNum = HTML_ATTR_EntityName;
  852. else
  853. attrType.AttrTypeNum = HTML_ATTR_EntityName;
  854. attr = TtaNewAttribute (attrType);
  855. TtaAttachAttribute (elLeaf, attr, XMLcontext.doc);
  856. if (entityName)
  857. /* store the given entity name */
  858. TtaSetAttributeText (attr, (char *)entityName, elLeaf, XMLcontext.doc);
  859. else
  860. {
  861. /* it's a numerical entity */
  862. len = sprintf ((char *)buffer, "%d", (int) wcharRead);
  863. i = 0;
  864. bufName[i++] = START_ENTITY;
  865. bufName[i++] = '#';
  866. for (j = 0; j < len; j++)
  867. bufName[i++] = buffer[j];
  868. bufName[i++] = ';';
  869. bufName[i] = EOS;
  870. TtaSetAttributeText (attr, (char *)bufName, elLeaf, XMLcontext.doc);
  871. }
  872. #endif
  873. /* genete the 'entityName' attribute for MathML only */
  874. attrType.AttrSSchema = elType.ElSSchema;
  875. ptr = (unsigned char*)TtaGetSSchemaName (elType.ElSSchema);
  876. if (strcmp ((char *)ptr, "MathML") == 0)
  877. {
  878. attrType.AttrTypeNum = MathML_ATTR_EntityName;
  879. attr = TtaNewAttribute (attrType);
  880. TtaAttachAttribute (elLeaf, attr, XMLcontext.doc);
  881. if (entityName)
  882. /* store the given entity name */
  883. TtaSetAttributeText (attr, (char *)entityName, elLeaf, XMLcontext.doc);
  884. else
  885. {
  886. /* it's a numerical entity */
  887. len = sprintf ((char *)buffer, "%d", (int) wcharRead);
  888. i = 0;
  889. bufName[i++] = START_ENTITY;
  890. bufName[i++] = '#';
  891. for (j = 0; j < len; j++)
  892. bufName[i++] = buffer[j];
  893. bufName[i++] = ';';
  894. bufName[i] = EOS;
  895. TtaSetAttributeText (attr, (char *)bufName, elLeaf, XMLcontext.doc);
  896. }
  897. }
  898. }
  899. /*----------------------------------------------------------------------
  900. XmlCheckInsert
  901. Inserts a Pseudo_paragraph element in the abstract tree if el
  902. is a math within a XHTML element
  903. ----------------------------------------------------------------------*/
  904. static void XmlCheckInsert (Element *el, Element parent,
  905. Document doc, ThotBool *inserted)
  906. {
  907. ElementType newElType, elType, prevType;
  908. Element newEl, ancestor, prev, prevprev;
  909. if (parent == NULL)
  910. return;
  911. elType = TtaGetElementType (*el);
  912. if (elType.ElTypeNum == MathML_EL_MathML &&
  913. strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML") == 0)
  914. {
  915. ancestor = parent;
  916. elType = TtaGetElementType (ancestor);
  917. if (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML"))
  918. return;
  919. while (ancestor != NULL &&
  920. IsXMLElementInline (elType, doc))
  921. {
  922. ancestor = TtaGetParent (ancestor);
  923. elType = TtaGetElementType (ancestor);
  924. }
  925. if (ancestor != NULL)
  926. {
  927. elType = TtaGetElementType (ancestor);
  928. if (XhtmlCannotContainText (elType) &&
  929. !XmlWithinStack (HTML_EL_Option_Menu, XhtmlParserCtxt->XMLSSchema))
  930. {
  931. /* Element ancestor cannot contain math directly. Create a */
  932. /* Pseudo_paragraph element as the parent of the math element */
  933. newElType.ElSSchema = XhtmlParserCtxt->XMLSSchema;
  934. newElType.ElTypeNum = HTML_EL_Pseudo_paragraph;
  935. newEl = TtaNewElement (doc, newElType);
  936. XmlSetElemLineNumber (newEl);
  937. /* insert the new Pseudo_paragraph element */
  938. InsertXmlElement (&newEl);
  939. BlockInCharLevelElem (newEl);
  940. if (newEl != NULL)
  941. {
  942. /* insert the Text element in the tree */
  943. TtaInsertFirstChild (el, newEl, doc);
  944. *inserted = TRUE;
  945. /* if previous siblings of the new Pseudo_paragraph element
  946. are inline elements, move them within the new
  947. Pseudo_paragraph element */
  948. prev = newEl;
  949. TtaPreviousSibling (&prev);
  950. while (prev != NULL)
  951. {
  952. prevType = TtaGetElementType (prev);
  953. if (IsXMLElementInline (prevType, doc))
  954. {
  955. prevprev = prev; TtaPreviousSibling (&prevprev);
  956. TtaRemoveTree (prev, doc);
  957. TtaInsertFirstChild (&prev, newEl, doc);
  958. prev = prevprev;
  959. }
  960. else
  961. prev = NULL;
  962. }
  963. }
  964. }
  965. }
  966. }
  967. return;
  968. }
  969. /*----------------------------------------------------------------------
  970. XhtmlCheckInsert
  971. Inserts an element Pseudo_paragraph in the abstract tree of
  972. the Thot document if el is a leaf and is not allowed to be
  973. a child of element parent.
  974. If element *el is not a character level element and parent is
  975. a Pseudo_paragraph, insert *el as a sibling of element parent.
  976. Return TRUE if element *el has been inserted in the tree.
  977. ----------------------------------------------------------------------*/
  978. static void XhtmlCheckInsert (Element *el, Element parent,
  979. Document doc, ThotBool *inserted)
  980. {
  981. ElementType parentType, newElType, elType, prevType, ancestorType;
  982. Element newEl, ancestor, prev, prevprev;
  983. int profile;
  984. char msgBuffer[MaxMsgLength];
  985. char *typeName;
  986. if (parent == NULL)
  987. return;
  988. elType = TtaGetElementType (*el);
  989. typeName = TtaGetElementTypeName (elType);
  990. if (elType.ElTypeNum == HTML_EL_TEXT_UNIT ||
  991. elType.ElTypeNum == HTML_EL_BR ||
  992. elType.ElTypeNum == HTML_EL_PICTURE_UNIT ||
  993. elType.ElTypeNum == HTML_EL_Input ||
  994. elType.ElTypeNum == HTML_EL_Text_Area ||
  995. IsXMLElementInline (elType, doc))
  996. {
  997. /* the element to be inserted is a character string */
  998. /* Search the ancestor that is not a character level element */
  999. ancestor = parent;
  1000. ancestorType = TtaGetElementType (ancestor);
  1001. while (ancestor &&
  1002. !strcmp (TtaGetSSchemaName (ancestorType.ElSSchema), "Template"))
  1003. {
  1004. // skip template ancestors
  1005. ancestor = TtaGetParent (ancestor);
  1006. ancestorType = TtaGetElementType (ancestor);
  1007. }
  1008. if (strcmp (TtaGetSSchemaName (ancestorType.ElSSchema), "HTML"))
  1009. /* parent is not a HTML element */
  1010. return;
  1011. while (ancestor &&
  1012. IsXMLElementInline (ancestorType, doc))
  1013. {
  1014. ancestor = TtaGetParent (ancestor);
  1015. ancestorType = TtaGetElementType (ancestor);
  1016. }
  1017. if (ancestor != NULL)
  1018. {
  1019. elType = TtaGetElementType (ancestor);
  1020. if (XhtmlCannotContainText (elType) &&
  1021. !XmlWithinStack (HTML_EL_Option_Menu, XhtmlParserCtxt->XMLSSchema))
  1022. {
  1023. profile = TtaGetDocumentProfile (XMLcontext.doc);
  1024. if ((profile == L_Basic || profile == L_Strict) &&
  1025. !strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") &&
  1026. elType.ElTypeNum == HTML_EL_BODY)
  1027. {
  1028. snprintf ((char *)msgBuffer, MaxMsgLength,
  1029. "Element <%s> not allowed outside a block Element - <p> forced", typeName);
  1030. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  1031. newElType.ElTypeNum = HTML_EL_Paragraph;
  1032. }
  1033. else
  1034. {
  1035. newElType.ElTypeNum = HTML_EL_Pseudo_paragraph;
  1036. }
  1037. /* Element ancestor cannot contain text directly. Create a */
  1038. /* Pseudo_paragraph element as the parent of the text element */
  1039. newElType.ElSSchema = XhtmlParserCtxt->XMLSSchema;
  1040. newEl = TtaNewElement (doc, newElType);
  1041. XmlSetElemLineNumber (newEl);
  1042. /* insert the new Pseudo_paragraph element */
  1043. InsertXmlElement (&newEl);
  1044. if (newEl != NULL)
  1045. {
  1046. /* insert the Text element in the tree */
  1047. TtaInsertFirstChild (el, newEl, doc);
  1048. BlockInCharLevelElem (newEl);
  1049. *inserted = TRUE;
  1050. /* if previous siblings of the new Pseudo_paragraph element
  1051. are character level elements, move them within the new
  1052. Pseudo_paragraph element */
  1053. prev = newEl;
  1054. TtaPreviousSibling (&prev);
  1055. while (prev != NULL)
  1056. {
  1057. prevType = TtaGetElementType (prev);
  1058. if (!IsXMLElementInline (prevType, doc))
  1059. prev = NULL;
  1060. else
  1061. {
  1062. prevprev = prev;
  1063. TtaPreviousSibling (&prevprev);
  1064. TtaRemoveTree (prev, doc);
  1065. TtaInsertFirstChild (&prev, newEl, doc);
  1066. prev = prevprev;
  1067. }
  1068. }
  1069. }
  1070. }
  1071. }
  1072. }
  1073. else
  1074. if (!IsXMLElementInline (elType, doc) &&
  1075. elType.ElTypeNum != HTML_EL_Comment_ &&
  1076. elType.ElTypeNum != HTML_EL_XMLPI)
  1077. /* it is not a character level element nor a comment or a PI */
  1078. /* don't insert it as a child of a Pseudo_paragraph, but as a sibling */
  1079. {
  1080. parentType = TtaGetElementType (parent);
  1081. if (parentType.ElTypeNum == HTML_EL_Pseudo_paragraph)
  1082. {
  1083. TtaInsertSibling (*el, parent, FALSE, doc);
  1084. *inserted = TRUE;
  1085. }
  1086. }
  1087. if (!*inserted)
  1088. if (elType.ElTypeNum == HTML_EL_TEXT_UNIT ||
  1089. (elType.ElTypeNum != HTML_EL_Inserted_Text &&
  1090. IsXMLElementInline (TtaGetElementType (*el), doc)))
  1091. {
  1092. /* it is a character level element */
  1093. parentType = TtaGetElementType (parent);
  1094. if (parentType.ElTypeNum == HTML_EL_Text_Area)
  1095. {
  1096. /* A basic element cannot be a child of a Text_Area */
  1097. /* create a Inserted_Text element as a child of Text_Area */
  1098. newElType.ElSSchema = CurrentParserCtxt->XMLSSchema;
  1099. newElType.ElTypeNum = HTML_EL_Inserted_Text;
  1100. newEl = TtaNewElement (doc, newElType);
  1101. XmlSetElemLineNumber (newEl);
  1102. InsertXmlElement (&newEl);
  1103. if (newEl != NULL)
  1104. {
  1105. TtaInsertFirstChild (el, newEl, doc);
  1106. *inserted = TRUE;
  1107. }
  1108. }
  1109. }
  1110. return;
  1111. }
  1112. /*---------------------------------------------------------------------------
  1113. InsertXmlElement
  1114. Inserts an element el in the Thot abstract tree at the current position.
  1115. ---------------------------------------------------------------------------*/
  1116. void InsertXmlElement (Element *el)
  1117. {
  1118. Element parent;
  1119. ThotBool inserted = FALSE;
  1120. if (CurrentParserCtxt != NULL)
  1121. {
  1122. if (InsertingSibling ())
  1123. {
  1124. if (XMLcontext.lastElement == NULL)
  1125. parent = NULL;
  1126. else
  1127. parent = TtaGetParent (XMLcontext.lastElement);
  1128. (*((Proc4)CurrentParserCtxt->CheckInsert)) ((void *)el,
  1129. (void *)parent,
  1130. (void *)XMLcontext.doc,
  1131. (void *)&inserted);
  1132. if (!inserted)
  1133. {
  1134. if (parent != NULL)
  1135. TtaInsertSibling (*el, XMLcontext.lastElement,
  1136. FALSE, XMLcontext.doc);
  1137. else
  1138. {
  1139. TtaDeleteTree (*el, XMLcontext.doc);
  1140. *el = NULL;
  1141. }
  1142. }
  1143. }
  1144. else
  1145. {
  1146. (*((Proc4)CurrentParserCtxt->CheckInsert)) (
  1147. (void *)el,
  1148. (void *)XMLcontext.lastElement,
  1149. (void *)XMLcontext.doc,
  1150. (void *)&inserted);
  1151. if (!inserted)
  1152. TtaInsertFirstChild (el, XMLcontext.lastElement, XMLcontext.doc);
  1153. }
  1154. if (*el)
  1155. {
  1156. XMLcontext.lastElement = *el;
  1157. XMLcontext.lastElementClosed = FALSE;
  1158. }
  1159. }
  1160. }
  1161. /*----------------------------------------------------------------------
  1162. XmlLastLeafInElement
  1163. return the last leaf element in element el.
  1164. ----------------------------------------------------------------------*/
  1165. Element XmlLastLeafInElement (Element el)
  1166. {
  1167. Element child, lastLeaf;
  1168. ElementType childType;
  1169. child = el;
  1170. lastLeaf = NULL;
  1171. while (child != NULL)
  1172. {
  1173. child = TtaGetLastChild (child);
  1174. if (child != NULL)
  1175. {
  1176. childType = TtaGetElementType (child);
  1177. if (TtaHasReturnCreateNLException (childType))
  1178. child = NULL;
  1179. else
  1180. lastLeaf = child;
  1181. }
  1182. }
  1183. return lastLeaf;
  1184. }
  1185. /*----------------------------------------------------------------------
  1186. RemoveTrailingSpaces
  1187. Removes all trailing spaces at the end of the element.
  1188. ----------------------------------------------------------------------*/
  1189. static void RemoveTrailingSpaces (Element el)
  1190. {
  1191. int length;
  1192. ElementType elType;
  1193. Element lastLeaf, lastChild;
  1194. /* Search the last leaf in the element's tree */
  1195. lastLeaf = XmlLastLeafInElement (el);
  1196. if (lastLeaf)
  1197. {
  1198. elType = TtaGetElementType (lastLeaf);
  1199. if (elType.ElTypeNum == 1)
  1200. /* the last leaf is a TEXT element */
  1201. {
  1202. length = TtaGetElementVolume (lastLeaf);
  1203. if (length > 0)
  1204. TtaRemoveFinalSpaces (lastLeaf, XMLcontext.doc,
  1205. RemoveTrailingSpace);
  1206. }
  1207. }
  1208. /* create an empty text element after the math element */
  1209. if (CurrentParserCtxt &&
  1210. strcmp ((char *)CurrentParserCtxt->SSchemaName, "HTML") == 0)
  1211. {
  1212. lastChild = TtaGetLastChild (el);
  1213. if (lastChild)
  1214. {
  1215. elType = TtaGetElementType (lastChild);
  1216. if (elType.ElTypeNum == MathML_EL_MathML &&
  1217. !strcmp (TtaGetSSchemaName (elType.ElSSchema), "MathML"))
  1218. /* the last child of this HTML element is a <math> element */
  1219. {
  1220. /* create an empty text element after the math element */
  1221. elType.ElSSchema = CurrentParserCtxt->XMLSSchema;
  1222. elType.ElTypeNum = HTML_EL_TEXT_UNIT;
  1223. lastLeaf = TtaNewElement (XMLcontext.doc, elType);
  1224. TtaInsertSibling (lastLeaf, lastChild, FALSE, XMLcontext.doc);
  1225. }
  1226. }
  1227. }
  1228. }
  1229. /*----------------------------------------------------------------------
  1230. XmlCloseElement
  1231. Terminate the corresponding Thot element.
  1232. ----------------------------------------------------------------------*/
  1233. static ThotBool XmlCloseElement (char *mappedName)
  1234. {
  1235. int i, error;
  1236. Element el, parent, pseudo;
  1237. ElementType parentType, elType;
  1238. ThotBool ret, spacesDeleted;
  1239. ret = FALSE;
  1240. if (stackLevel > 0)
  1241. {
  1242. el = XMLcontext.lastElement;
  1243. if (XMLcontext.lastElementClosed)
  1244. el = TtaGetParent (el);
  1245. i = stackLevel - 1;
  1246. if (i >= 0 && mappedName == nameElementStack[i])
  1247. /* element found in the stack */
  1248. {
  1249. /* This element and its whole subtree are closed */
  1250. stackLevel = i;
  1251. XMLcontext.lastElement = elementStack[i];
  1252. XMLcontext.lastElementClosed = TRUE;
  1253. ret = TRUE;
  1254. }
  1255. else
  1256. {
  1257. /* element not found in the stack */
  1258. if (XMLcontext.lastElement != NULL)
  1259. {
  1260. /* implicit close. Check the parent of current element */
  1261. if (InsertingSibling ())
  1262. parent = TtaGetParent (XMLcontext.lastElement);
  1263. else
  1264. parent = XMLcontext.lastElement;
  1265. if (parent != NULL)
  1266. {
  1267. parentType = TtaGetElementType (parent);
  1268. if ((!strcmp (TtaGetSSchemaName (parentType.ElSSchema), "HTML")) &&
  1269. parentType.ElTypeNum == HTML_EL_Pseudo_paragraph)
  1270. {
  1271. XMLcontext.lastElement = parent;
  1272. XMLcontext.lastElementClosed = TRUE;
  1273. ret = TRUE;
  1274. }
  1275. }
  1276. }
  1277. }
  1278. if (ret)
  1279. /* successful close */
  1280. {
  1281. /* remove closed elements from the stack */
  1282. while (i > 0)
  1283. if (elementStack[i] == XMLcontext.lastElement)
  1284. {
  1285. stackLevel = i;
  1286. i = 0;
  1287. }
  1288. else
  1289. {
  1290. if (TtaIsAncestor (elementStack[i], XMLcontext.lastElement))
  1291. stackLevel = i;
  1292. i--;
  1293. }
  1294. /* complete all closed elements */
  1295. if (el != XMLcontext.lastElement)
  1296. if (!TtaIsAncestor (el, XMLcontext.lastElement))
  1297. el = NULL;
  1298. spacesDeleted = FALSE;
  1299. while (el != NULL)
  1300. {
  1301. /* If the element closed is a block-element, remove */
  1302. /* spaces contained at the end of that element */
  1303. /*
  1304. if (!spacesDeleted)
  1305. spacesDeleted = RemoveEndingSpaces (el);
  1306. */
  1307. /* Remove the trailing spaces of that element */
  1308. RemoveTrailingSpaces (el);
  1309. /* Remove the trailing spaces for included pseudo-paragraph */
  1310. elType = TtaGetElementType (el);
  1311. if (!strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML"))
  1312. {
  1313. elType.ElTypeNum = HTML_EL_Pseudo_paragraph;
  1314. pseudo = el;
  1315. do
  1316. {
  1317. pseudo = TtaSearchTypedElementInTree (elType,
  1318. SearchForward, el, pseudo);
  1319. if (pseudo)
  1320. RemoveTrailingSpaces (pseudo);
  1321. }
  1322. while (pseudo);
  1323. }
  1324. (*(Proc3)(CurrentParserCtxt->ElementComplete))(
  1325. (void *)&XMLcontext,
  1326. (void *)el,
  1327. (void *)&error);
  1328. if (el == XMLcontext.lastElement)
  1329. el = NULL;
  1330. else
  1331. el = TtaGetParent (el);
  1332. }
  1333. if (stackLevel > 1)
  1334. {
  1335. XMLcontext.language = languageStack[stackLevel - 1];
  1336. CurrentParserCtxt = parserCtxtStack[stackLevel - 1];
  1337. /* Is there a space attribute in the stack ? */
  1338. XmlWhiteSpaceHandling ();
  1339. }
  1340. }
  1341. }
  1342. return ret;
  1343. }
  1344. /*-------------------- Namespaces procedures (start) --------------*/
  1345. /*----------------------------------------------------------------------
  1346. NsDeclarationStart
  1347. Called by the namespace declaratation start handler.
  1348. Update the two namespace tables.
  1349. ----------------------------------------------------------------------*/
  1350. static void NsDeclarationStart (char *ns_prefix, char *ns_uri)
  1351. {
  1352. if (Ns_Level >= MAX_NS_TABLE)
  1353. {
  1354. XmlParseError (errorNotWellFormed,
  1355. (unsigned char *)"**FATAL** Too many namespace declarations ", 0);
  1356. DisableExpatParser ();
  1357. return;
  1358. }
  1359. if (ns_prefix && Ns_Level == 0)
  1360. {
  1361. // declare a default namespace
  1362. if (CurrentParserCtxt)
  1363. Ns_Uri[Ns_Level] = TtaStrdup (CurrentParserCtxt->UriName);
  1364. else
  1365. Ns_Uri[Ns_Level] = NULL;
  1366. Ns_Prefix[Ns_Level] = NULL;
  1367. Ns_Level ++;
  1368. CurNs_Level ++;
  1369. }
  1370. /* Filling up the table of namespaces declared for the current element */
  1371. CurNs_Prefix[CurNs_Level] = TtaStrdup (ns_prefix);
  1372. CurNs_Uri[CurNs_Level] = TtaStrdup (ns_uri);
  1373. CurNs_Level ++;
  1374. /* Filling up the table of namespaces declared for the whole document */
  1375. if (ns_uri)
  1376. Ns_Uri[Ns_Level] = TtaStrdup (ns_uri);
  1377. else
  1378. Ns_Uri[Ns_Level] = NULL;
  1379. if (ns_prefix != NULL)
  1380. Ns_Prefix[Ns_Level] = TtaStrdup (ns_prefix);
  1381. else
  1382. Ns_Prefix[Ns_Level] = NULL;
  1383. Ns_Level ++;
  1384. }
  1385. /*----------------------------------------------------------------------
  1386. NsDeclarationEnd
  1387. Called by the namespace declaratatin end handler.
  1388. Remove the last declaration.
  1389. ----------------------------------------------------------------------*/
  1390. static void NsDeclarationEnd (char *ns_prefix)
  1391. {
  1392. int i;
  1393. i = Ns_Level - 1;
  1394. if (i < 0)
  1395. return;
  1396. if (Ns_Prefix[i] != NULL)
  1397. {
  1398. TtaFreeMemory (Ns_Prefix[i]);
  1399. Ns_Prefix[i] = NULL;
  1400. }
  1401. if (Ns_Uri[i] != NULL)
  1402. {
  1403. TtaFreeMemory (Ns_Uri[i]);
  1404. Ns_Uri[i] = NULL;
  1405. }
  1406. Ns_Level --;
  1407. CurNs_Level = 0;
  1408. }
  1409. /*----------------------------------------------------------------------
  1410. NsStartProcessing
  1411. Look for namespace declarations for the current element.
  1412. If there are such declarations, update the Document informations.
  1413. Remove all current namespace declaration(s).
  1414. ----------------------------------------------------------------------*/
  1415. static void NsStartProcessing (Element newElement, ThotBool declare)
  1416. {
  1417. int i;
  1418. if (CurNs_Level == 0)
  1419. return;
  1420. /* Update the Namespace Document informations and remove the useless declarations */
  1421. for (i = 0; i < CurNs_Level; i++)
  1422. {
  1423. if (newElement && declare)
  1424. TtaSetANamespaceDeclaration (XMLcontext.doc, newElement,
  1425. CurNs_Prefix[i], CurNs_Uri[i]);
  1426. if (CurNs_Prefix[i])
  1427. {
  1428. TtaFreeMemory (CurNs_Prefix[i]);
  1429. CurNs_Prefix[i] = NULL;
  1430. }
  1431. if (CurNs_Uri[i])
  1432. {
  1433. TtaFreeMemory (CurNs_Uri[i]);
  1434. CurNs_Uri[i] = NULL;
  1435. }
  1436. }
  1437. CurNs_Level = 0;
  1438. }
  1439. /*----------------------------------------------------------------------
  1440. GetDefaultNsUri
  1441. Return the default NS uri
  1442. ----------------------------------------------------------------------*/
  1443. static char *GetDefaultNsUri (ThotBool *def_uri)
  1444. {
  1445. int i;
  1446. char *uri;
  1447. *def_uri = FALSE;
  1448. uri = NULL;
  1449. for (i = Ns_Level; i > 0; i--)
  1450. {
  1451. if (Ns_Prefix[i-1] == NULL)
  1452. {
  1453. uri = Ns_Uri[i-1];
  1454. *def_uri = TRUE;
  1455. i = 0;
  1456. }
  1457. }
  1458. return (uri);
  1459. }
  1460. /*----------------------------------------------------------------------
  1461. NsGetPrefix
  1462. Get the prefix associated with an uri
  1463. ----------------------------------------------------------------------*/
  1464. static char *NsGetPrefix (const char *ns_uri)
  1465. {
  1466. int i;
  1467. char *ns_prefix;
  1468. ns_prefix = NULL;
  1469. if (ns_uri == NULL)
  1470. return (ns_prefix);
  1471. for (i = Ns_Level - 1; i >= 0; i--)
  1472. {
  1473. if ((ns_uri != NULL) && (Ns_Uri[i] != NULL) &&
  1474. (strcmp ((char *)ns_uri, (char *)Ns_Uri[i]) == 0))
  1475. {
  1476. ns_prefix = Ns_Prefix[i];
  1477. i = 0;
  1478. }
  1479. }
  1480. return (ns_prefix);
  1481. }
  1482. /*----------------------------------------------------------------------
  1483. UnknownXmlNsElement
  1484. Create an Unknown_Namespace element according to the current context
  1485. ----------------------------------------------------------------------*/
  1486. static void UnknownXmlNsElement (char *ns_uri, char *elemName, ThotBool startElem)
  1487. {
  1488. Element newElement;
  1489. int i, lg, tmplg;
  1490. char *ns_prefix;
  1491. #define MAX_BUFFER_SIZE 1024
  1492. char elemBuffer[MAX_BUFFER_SIZE];
  1493. if (elemName == NULL)
  1494. return;
  1495. strcpy ((char *)elemBuffer, "<");
  1496. lg = 1;
  1497. if (!startElem)
  1498. {
  1499. strcat (elemBuffer, "/");
  1500. lg ++;
  1501. }
  1502. /* Is that namespace associated with a prefix ? */
  1503. ns_prefix = NsGetPrefix (ns_uri);
  1504. if (ns_prefix != NULL)
  1505. {
  1506. strcat (elemBuffer, ns_prefix);
  1507. lg += strlen ((char *)ns_prefix);
  1508. strcat (elemBuffer, ":");
  1509. lg ++;
  1510. }
  1511. strcat (elemBuffer, elemName);
  1512. lg += strlen ((char *)elemName);
  1513. /* Search all namespace declarations for this element */
  1514. if (startElem && CurNs_Level > 0)
  1515. {
  1516. for (i = 0; i < CurNs_Level; i++)
  1517. {
  1518. /* Check if we don't overflow the buffer */
  1519. tmplg = 8;
  1520. if (CurNs_Prefix[i] != NULL)
  1521. {
  1522. tmplg += strlen ((char *)CurNs_Prefix[i]);
  1523. tmplg ++;
  1524. }
  1525. if (CurNs_Uri[i] != NULL)
  1526. tmplg += strlen ((char *)CurNs_Uri[i]);
  1527. tmplg +=2;
  1528. if ((lg + tmplg) < MAX_BUFFER_SIZE)
  1529. {
  1530. /* We can add this declaration */
  1531. strcat (elemBuffer, " xmlns");
  1532. lg += 6;
  1533. if (CurNs_Prefix[i] != NULL)
  1534. {
  1535. strcat (elemBuffer, ":");
  1536. lg ++;
  1537. strcat (elemBuffer, CurNs_Prefix[i]);
  1538. lg += strlen ((char *)CurNs_Prefix[i]);
  1539. }
  1540. strcat (elemBuffer, "=\"");
  1541. lg += 2;
  1542. if (CurNs_Uri[i] != NULL)
  1543. {
  1544. strcat (elemBuffer, CurNs_Uri[i]);
  1545. lg += strlen ((char *)CurNs_Uri[i]);
  1546. }
  1547. strcat (elemBuffer, "\"");
  1548. lg ++;
  1549. }
  1550. else
  1551. i = CurNs_Level;
  1552. }
  1553. }
  1554. /* Create the Unknown element */
  1555. newElement = NULL;
  1556. (*(Proc3)(CurrentParserCtxt->UnknownNameSpace)) (
  1557. (void *)&XMLcontext,
  1558. (void *)&newElement,
  1559. (void *)elemBuffer);
  1560. /* Store the current namespace declarations for this element */
  1561. if (CurNs_Level > 0)
  1562. NsStartProcessing (newElement, FALSE);
  1563. }
  1564. /*-------------------- Namespaces procedures (end) --------------*/
  1565. /*-------------------- StartElement (start) ---------------------*/
  1566. /*----------------------------------------------------------------------
  1567. XmlCheckContext
  1568. Verifies if the element elName is allowed to occur in the current
  1569. structural context.
  1570. ----------------------------------------------------------------------*/
  1571. static void XmlCheckContext (char *elName, const ElementType * elType,
  1572. ThotBool *isAllowed)
  1573. {
  1574. *isAllowed = TRUE;
  1575. return;
  1576. }
  1577. /*----------------------------------------------------------------------
  1578. XhtmlCheckContext
  1579. Verifies if the XHTML element elName is allowed to occur
  1580. in the current structural context.
  1581. ----------------------------------------------------------------------*/
  1582. static void XhtmlCheckContext (char *elName, const ElementType * elType,
  1583. ThotBool *isAllowed)
  1584. {
  1585. if (stackLevel <= 1 || nameElementStack[stackLevel - 1] == NULL)
  1586. {
  1587. *isAllowed = TRUE;
  1588. return;
  1589. }
  1590. else
  1591. {
  1592. *isAllowed = TRUE;
  1593. /* only TH and TD elements are allowed as children of a TR element */
  1594. if (!strcmp ((char *)nameElementStack[stackLevel - 1], "tr"))
  1595. if (strcmp ((char *)elName, "th") &&
  1596. strcmp ((char *)elName, "td"))
  1597. *isAllowed = FALSE;
  1598. if (*isAllowed &&
  1599. !strcmp (nameElementStack[stackLevel - 1], "table"))
  1600. /* only CAPTION, THEAD, TFOOT, TBODY, COLGROUP, COL and TR are */
  1601. /* allowed as children of a TABLE element */
  1602. {
  1603. if (strcmp ((char *)elName, "caption") &&
  1604. strcmp ((char *)elName, "thead") &&
  1605. strcmp ((char *)elName, "tfoot") &&
  1606. strcmp ((char *)elName, "tbody") &&
  1607. strcmp ((char *)elName, "colgroup") &&
  1608. strcmp ((char *)elName, "col") &&
  1609. strcmp ((char *)elName, "tr"))
  1610. {
  1611. if (!strcmp ((char *)elName, "td") ||
  1612. !strcmp ((char *)elName, "th"))
  1613. /* Table cell within a table, without a tr. Assume tr */
  1614. {
  1615. /* simulate a <TR> tag */
  1616. StartOfXmlStartElement ("tr");
  1617. }
  1618. else
  1619. *isAllowed = FALSE;
  1620. }
  1621. }
  1622. if (*isAllowed)
  1623. /* CAPTION, THEAD, TFOOT, TBODY, COLGROUP are allowed only as
  1624. children of a TABLE element */
  1625. if (strcmp ((char *)elName, "caption") == 0 ||
  1626. strcmp ((char *)elName, "thead") == 0 ||
  1627. strcmp ((char *)elName, "tfoot") == 0 ||
  1628. strcmp ((char *)elName, "tbody") == 0 ||
  1629. strcmp ((char *)elName, "colgroup") == 0)
  1630. if (strcmp ((char *)nameElementStack[stackLevel - 1], "table") != 0)
  1631. *isAllowed = FALSE;
  1632. if (*isAllowed)
  1633. {
  1634. /* only TR is allowed as a child of a THEAD, TFOOT or TBODY element */
  1635. if (!strcmp ((char *)nameElementStack[stackLevel - 1], "thead") ||
  1636. !strcmp ((char *)nameElementStack[stackLevel - 1], "tfoot") ||
  1637. !strcmp ((char *)nameElementStack[stackLevel - 1], "tbody"))
  1638. {
  1639. if (strcmp ((char *)elName, "tr"))
  1640. {
  1641. if (!strcmp ((char *)elName, "td") ||
  1642. !strcmp ((char *)elName, "th"))
  1643. /* Table cell within a thead, tfoot or tbody without a tr. */
  1644. /* Assume tr */
  1645. {
  1646. /* simulate a <tr> tag */
  1647. StartOfXmlStartElement ("tr");
  1648. }
  1649. else
  1650. *isAllowed = FALSE;
  1651. }
  1652. }
  1653. }
  1654. if (*isAllowed)
  1655. {
  1656. /* only LI is allowed as a child of a OL or UL element */
  1657. if (!strcmp ((char *)nameElementStack[stackLevel - 1], "ol") ||
  1658. !strcmp ((char *)nameElementStack[stackLevel - 1], "ul"))
  1659. {
  1660. if (strcmp ((char *)elName, "li"))
  1661. *isAllowed = FALSE;
  1662. }
  1663. }
  1664. if (*isAllowed)
  1665. {
  1666. /* only DT/DD is allowed as a child of a DL element */
  1667. if (!strcmp ((char *)nameElementStack[stackLevel - 1], "dl"))
  1668. {
  1669. if (strcmp ((char *)elName, "dt") && strcmp ((char *)elName, "dd"))
  1670. *isAllowed = FALSE;
  1671. }
  1672. }
  1673. if (*isAllowed)
  1674. {
  1675. /* Block elements are not allowed within an anchor */
  1676. if (!strcmp ((char *)nameElementStack[stackLevel - 1], "a") &&
  1677. (!IsXMLElementInline (*elType,XMLcontext.doc )))
  1678. *isAllowed = FALSE;
  1679. }
  1680. if (*isAllowed)
  1681. {
  1682. /* No one element is allowed within the title */
  1683. if (!strcmp ((char *)nameElementStack[stackLevel - 1], "title") )
  1684. *isAllowed = FALSE;
  1685. }
  1686. if (*isAllowed &&
  1687. strcmp ((char *)elName, "body") == 0 &&
  1688. XmlWithinStack (HTML_EL_BODY, XhtmlParserCtxt->XMLSSchema))
  1689. /* refuse BODY within BODY */
  1690. *isAllowed = FALSE;
  1691. if (*isAllowed)
  1692. /* refuse HEAD within HEAD */
  1693. if (strcmp ((char *)elName, "head") == 0)
  1694. if (XmlWithinStack (HTML_EL_HEAD, XhtmlParserCtxt->XMLSSchema))
  1695. *isAllowed = FALSE;
  1696. if (*isAllowed)
  1697. /* refuse STYLE within STYLE */
  1698. if (strcmp ((char *)elName, "style") == 0)
  1699. if (XmlWithinStack (HTML_EL_STYLE_, XhtmlParserCtxt->XMLSSchema))
  1700. *isAllowed = FALSE;
  1701. return;
  1702. }
  1703. }
  1704. /*----------------------------------------------------------------------
  1705. GetXmlElType
  1706. Search in the mapping tables the entry for the element elementName and
  1707. returns the corresponding Thot element type.
  1708. ----------------------------------------------------------------------*/
  1709. static void GetXmlElType (const char *ns_uri, const char *elementName,
  1710. ElementType *elType, char **mappedName,
  1711. char *content, ThotBool *level)
  1712. {
  1713. #ifdef XML_GENERIC
  1714. ThotBool isnew;
  1715. char *s;
  1716. char *ns_name;
  1717. // ElementType parentType;
  1718. // Element parent;
  1719. #endif /* XML_GENERIC */
  1720. /* initialize all parser contexts if not done yet */
  1721. if (FirstParserCtxt == NULL)
  1722. InitXmlParserContexts ();
  1723. /* Look at the current context if there is one */
  1724. if (CurrentParserCtxt != NULL)
  1725. {
  1726. #ifdef XML_GENERIC
  1727. if (CurrentParserCtxt == GenericXmlParserCtxt)
  1728. {
  1729. /* Search the element inside a not supported DTD */
  1730. if (XMLRootName == NULL)
  1731. {
  1732. /* This is the document root */
  1733. s = TtaGetSSchemaName (DocumentSSchema);
  1734. elType->ElSSchema = GetGenericXMLSSchema (s, XMLcontext.doc);
  1735. /* Initialize the current context schema */
  1736. if (CurrentParserCtxt->XMLSSchema == NULL)
  1737. CurrentParserCtxt->XMLSSchema = elType->ElSSchema;
  1738. /* We instanciate the XML schema with the element name */
  1739. /* (except for the elements 'comment', doctype and 'pi') */
  1740. if (strcmp ((char *)elementName, "xmlcomment") &&
  1741. strcmp ((char *)elementName, "xmlcomment_line") &&
  1742. strcmp ((char *)elementName, "doctype") &&
  1743. strcmp ((char *)elementName, "doctype_line") &&
  1744. strcmp ((char *)elementName, "xmlpi") &&
  1745. strcmp ((char *)elementName, "xmlpi_line"))
  1746. {
  1747. if (strcmp ((char *)s, "XML") == 0)
  1748. {
  1749. if (ns_uri != NULL)
  1750. {
  1751. ns_name = NsGetPrefix (ns_uri);
  1752. if (ns_name != NULL)
  1753. TtaChangeGenericSchemaNames (ns_uri, ns_name, XMLcontext.doc);
  1754. else
  1755. TtaChangeGenericSchemaNames (ns_uri, elementName, XMLcontext.doc);
  1756. }
  1757. else
  1758. TtaChangeGenericSchemaNames ("Default_Uri", elementName, XMLcontext.doc);
  1759. }
  1760. }
  1761. }
  1762. else
  1763. {
  1764. // if (ns_uri != NULL)
  1765. {
  1766. isnew = FALSE;
  1767. elType->ElSSchema = GetGenericXMLSSchemaByUri (ns_uri, XMLcontext.doc, &isnew);
  1768. if (isnew)
  1769. {
  1770. ns_name = NsGetPrefix (ns_uri);
  1771. if (ns_name != NULL)
  1772. TtaChangeGenericSchemaNames (ns_uri, ns_name, XMLcontext.doc);
  1773. else
  1774. TtaChangeGenericSchemaNames (ns_uri, elementName, XMLcontext.doc);
  1775. // complete the context if needed
  1776. if (CurrentParserCtxt && CurrentParserCtxt->XMLSSchema == NULL)
  1777. CurrentParserCtxt->XMLSSchema = elType->ElSSchema;
  1778. }
  1779. }
  1780. *level = TRUE;
  1781. *content = SPACE;
  1782. }
  1783. MapGenericXmlElement (elementName, elType, mappedName, XMLcontext.doc);
  1784. }
  1785. else
  1786. {
  1787. /* Search the element inside a supported DTD */
  1788. elType->ElSSchema = CurrentParserCtxt->XMLSSchema;
  1789. MapXMLElementType (CurrentParserCtxt->XMLtype, elementName, elType,
  1790. mappedName, content, level, XMLcontext.doc);
  1791. }
  1792. #else /* XML_GENERIC */
  1793. elType->ElSSchema = CurrentParserCtxt->XMLSSchema;
  1794. MapXMLElementType (CurrentParserCtxt->XMLtype, elementName, elType,
  1795. mappedName, content, level, XMLcontext.doc);
  1796. #endif /* XML_GENERIC */
  1797. }
  1798. else
  1799. {
  1800. /* not found */
  1801. elType->ElTypeNum = 0;
  1802. elType->ElSSchema = NULL;
  1803. }
  1804. }
  1805. /*----------------------------------------------------------------------
  1806. StartOfXmlStartElement
  1807. The name of an element type has been read from a start tag.
  1808. Create the corresponding Thot element according to the mapping table.
  1809. ----------------------------------------------------------------------*/
  1810. static void StartOfXmlStartElement (const char *name)
  1811. {
  1812. ElementType elType;
  1813. Element newElement;
  1814. PtrParserCtxt savParserCtxt = NULL;
  1815. char msgBuffer[MaxMsgLength];
  1816. char schemaName[NAME_LENGTH];
  1817. char *mappedName = NULL;
  1818. char *buffer, *ptr, *elementName, *nsURI, *nsDefUri;
  1819. int profile;
  1820. ThotBool elInStack = FALSE;
  1821. ThotBool highEnoughLevel = TRUE;
  1822. ThotBool isAllowed = TRUE;
  1823. ThotBool def_uri = FALSE;
  1824. if (stackLevel == MAX_STACK_HEIGHT)
  1825. {
  1826. XmlParseError (errorNotWellFormed,
  1827. (unsigned char *)"**FATAL** Too many XML levels", 0);
  1828. UnknownElement = TRUE;
  1829. return;
  1830. }
  1831. UnknownNS = FALSE;
  1832. UnknownElement = FALSE;
  1833. elementName = NULL;
  1834. nsURI = NULL;
  1835. buffer = NULL;
  1836. buffer = TtaStrdup (name);
  1837. if (buffer == NULL)
  1838. return;
  1839. savParserCtxt = CurrentParserCtxt;
  1840. /* Is this element in the scope of a namespace declaration */
  1841. if ((ptr = strrchr (buffer, NS_SEP)) != NULL)
  1842. {
  1843. *ptr = EOS;
  1844. nsURI = (char *)TtaStrdup ((char *)buffer);
  1845. *ptr = NS_SEP;
  1846. ptr++;
  1847. /* check the document profile */
  1848. profile = TtaGetDocumentProfile (XMLcontext.doc);
  1849. if ((profile == L_Basic || profile == L_Strict) &&
  1850. strcmp (nsURI, XHTML_URI))
  1851. {
  1852. snprintf ((char *)msgBuffer, MaxMsgLength,
  1853. "The element <%s> is not allowed by the current profile", ptr);
  1854. XmlParseError (errorParsingProfile, (unsigned char *)msgBuffer, 0);
  1855. TtaFreeMemory (nsURI);
  1856. TtaFreeMemory (buffer);
  1857. UnknownElement = TRUE; /* don't generate that element */
  1858. CurrentParserCtxt = savParserCtxt;
  1859. return;
  1860. }
  1861. /* Look for the context associated with that namespace */
  1862. ChangeXmlParserContextByUri (nsURI);
  1863. // it's a compound document
  1864. if (CurrentParserCtxt && savParserCtxt != CurrentParserCtxt &&
  1865. (!strcmp (CurrentParserCtxt->SSchemaName, "SVG") ||
  1866. !strcmp (CurrentParserCtxt->SSchemaName, "MathML")) &&
  1867. DocumentMeta[XMLcontext.doc])
  1868. DocumentMeta[XMLcontext.doc]->compound = TRUE;
  1869. elementName = (char *)TtaGetMemory ((strlen ((char *)ptr) + 1));
  1870. strcpy ((char *)elementName, (char *)ptr);
  1871. }
  1872. else
  1873. {
  1874. /* No namespace declaration */
  1875. if ((ptr = strrchr (buffer, NS_COLON)) != NULL)
  1876. {
  1877. /* there is an undefined prefix */
  1878. snprintf ((char *)msgBuffer, MaxMsgLength,
  1879. "Undefined prefix for the element <%s>", (char *)name);
  1880. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  1881. CurrentParserCtxt = NULL;
  1882. }
  1883. else if (CurrentParserCtxt->UriName != NULL &&
  1884. CurrentParserCtxt->UriName[0] != EOS)
  1885. {
  1886. nsDefUri = GetDefaultNsUri (&def_uri);
  1887. if (def_uri && nsDefUri == NULL)
  1888. {
  1889. /* Default namespace without uri */
  1890. CurrentParserCtxt = NULL;
  1891. }
  1892. }
  1893. elementName = (char *)TtaStrdup ((char *)buffer);
  1894. }
  1895. if (CurrentParserCtxt == NULL)
  1896. {
  1897. #ifdef XML_GENERIC
  1898. /* create a new XML generic context */
  1899. CurrentParserCtxt = GenericXmlParserCtxt;
  1900. CurrentParserCtxt->UriName = TtaStrdup (nsURI);
  1901. TtaSetUriSSchema (CurrentParserCtxt->XMLSSchema, CurrentParserCtxt->UriName);
  1902. #else /*XML_GENERIC*/
  1903. CurrentParserCtxt = savParserCtxt;
  1904. UnknownNS = TRUE;
  1905. #endif /* XML_GENERIC */
  1906. }
  1907. /* ignore tag <P> within PRE for Xhtml elements */
  1908. if (CurrentParserCtxt != NULL &&
  1909. (strcmp ((char *)CurrentParserCtxt->SSchemaName, "HTML") == 0) &&
  1910. (XmlWithinStack (HTML_EL_Preformatted, CurrentParserCtxt->XMLSSchema)) &&
  1911. (strcasecmp (elementName, "p") == 0))
  1912. UnknownElement = TRUE;
  1913. if (CurrentParserCtxt && !UnknownElement)
  1914. {
  1915. if (UnknownNS)
  1916. {
  1917. /* The element doesn't belong to a supported namespace */
  1918. snprintf ((char *)msgBuffer, MaxMsgLength,
  1919. "The element <%s> doesn't belong to a supported namespace", name);
  1920. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  1921. /* create an Unknown_namespace element */
  1922. UnknownXmlNsElement (nsURI, elementName, TRUE);
  1923. }
  1924. else
  1925. {
  1926. /* search the XML element name in the corresponding mapping table */
  1927. elType.ElSSchema = NULL;
  1928. elType.ElTypeNum = 0;
  1929. currentElementName[0] = EOS;
  1930. GetXmlElType (nsURI, elementName, &elType, &mappedName,
  1931. &currentElementContent, &highEnoughLevel);
  1932. if (mappedName == NULL)
  1933. {
  1934. if (strcmp ((char *)CurrentParserCtxt->SSchemaName, "HTML") == 0)
  1935. strcpy ((char *)schemaName, "XHTML");
  1936. else
  1937. strcpy ((char *)schemaName, (char *)CurrentParserCtxt->SSchemaName);
  1938. if (strncmp (elementName, "SUBTREE_ROOT", 12))
  1939. {
  1940. /* it's not the pseudo root element generated by transform */
  1941. if (highEnoughLevel)
  1942. {
  1943. /* element not found in the corresponding DTD */
  1944. /* don't process that element */
  1945. snprintf ((char *)msgBuffer, MaxMsgLength,
  1946. "Invalid or unsupported %s element <%s>",
  1947. schemaName , elementName);
  1948. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  1949. UnknownElement = TRUE;
  1950. }
  1951. else
  1952. {
  1953. /* invalid element for the document profile */
  1954. /* don't process that element */
  1955. snprintf ((char *)msgBuffer, MaxMsgLength,
  1956. "Invalid %s element <%s> for the document profile",
  1957. schemaName, elementName);
  1958. XmlParseError (errorParsingProfile, (unsigned char *)msgBuffer, 0);
  1959. UnknownElement = TRUE;
  1960. }
  1961. }
  1962. }
  1963. else
  1964. {
  1965. /* Element found in the corresponding DTD */
  1966. strcpy ((char *)currentElementName, (char *)mappedName);
  1967. if (CurrentParserCtxt != NULL)
  1968. (*(Proc3)(CurrentParserCtxt->CheckContext))(
  1969. (void *)mappedName,
  1970. (void *)&elType,
  1971. (void *)&isAllowed);
  1972. if (!isAllowed)
  1973. /* Element not allowed in the current structural context */
  1974. {
  1975. snprintf ((char *)msgBuffer, MaxMsgLength,
  1976. "The XML element <%s> is not allowed here", elementName);
  1977. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  1978. UnknownElement = TRUE;
  1979. elInStack = FALSE;
  1980. }
  1981. else
  1982. {
  1983. newElement = NULL;
  1984. /* create a Thot element */
  1985. if (currentElementContent == 'E')
  1986. /* empty XML element. Create all children specified */
  1987. /* in the Thot structure schema */
  1988. newElement = TtaNewTree (XMLcontext.doc, elType, "");
  1989. else
  1990. /* the HTML element may have children. Create only */
  1991. /* the corresponding Thot element, without any child */
  1992. newElement = TtaNewElement (XMLcontext.doc, elType);
  1993. XmlSetElemLineNumber (newElement);
  1994. InsertXmlElement (&newElement);
  1995. /* Store the current namespace declarations for this element */
  1996. if (CurNs_Level > 0)
  1997. NsStartProcessing (newElement, TRUE);
  1998. if (newElement != NULL && elType.ElTypeNum == 1)
  1999. /* If an empty Text element has been created, */
  2000. /* the following character data must go to that element */
  2001. XMLcontext.mergeText = TRUE;
  2002. elementStack[stackLevel] = newElement;
  2003. nameElementStack[stackLevel] = mappedName;
  2004. elInStack = TRUE;
  2005. }
  2006. if (elInStack)
  2007. {
  2008. languageStack[stackLevel] = XMLcontext.language;
  2009. parserCtxtStack[stackLevel] = CurrentParserCtxt;
  2010. spacePreservedStack[stackLevel] = ' ';
  2011. stackLevel++;
  2012. }
  2013. }
  2014. }
  2015. }
  2016. if (buffer != NULL)
  2017. TtaFreeMemory (buffer);
  2018. if (elementName != NULL)
  2019. TtaFreeMemory (elementName);
  2020. if (nsURI != NULL)
  2021. TtaFreeMemory (nsURI);
  2022. }
  2023. /*----------------------------------------------------------------------
  2024. EndOfXmlStartElement
  2025. Function called at the end of a start tag.
  2026. ----------------------------------------------------------------------*/
  2027. static void EndOfXmlStartElement (char *name)
  2028. {
  2029. ElementType elType;
  2030. AttributeType attrType;
  2031. Attribute attr;
  2032. int length;
  2033. char *text;
  2034. if (UnknownElement || UnknownNS)
  2035. return;
  2036. if (XMLcontext.lastElement != NULL && currentElementName[0] != EOS)
  2037. {
  2038. elType = TtaGetElementType (XMLcontext.lastElement);
  2039. if (strcmp ((char *)TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0)
  2040. {
  2041. if (!strcmp ((char *)nameElementStack[stackLevel - 1], "pre") ||
  2042. !strcmp ((char *)nameElementStack[stackLevel - 1], "style") ||
  2043. !strcmp ((char *)nameElementStack[stackLevel - 1], "textarea") ||
  2044. !strcmp ((char *)nameElementStack[stackLevel - 1], "script"))
  2045. /* a <pre>, <style> <textarea> or <scriptT> tag has been read */
  2046. XmlWhiteSpaceInStack ((char *)NULL);
  2047. else
  2048. if (!strcmp ((char *)nameElementStack[stackLevel - 1], "table"))
  2049. /* <TABLE> has been read */
  2050. XMLcontext.withinTable++;
  2051. /* if it's an AREA element, computes its position and size */
  2052. ParseAreaCoords (XMLcontext.lastElement, XMLcontext.doc);
  2053. /* if it's a STYLE element in CSS notation, activate the CSS */
  2054. /* parser for parsing the element content */
  2055. if (elType.ElTypeNum == HTML_EL_STYLE_)
  2056. {
  2057. /* Search the Notation attribute */
  2058. attrType.AttrSSchema = elType.ElSSchema;
  2059. attrType.AttrTypeNum = HTML_ATTR_Notation;
  2060. attr = TtaGetAttribute (XMLcontext.lastElement, attrType);
  2061. if (attr == NULL)
  2062. /* No Notation attribute. Assume CSS by default */
  2063. XMLcontext.parsingCSS = TRUE;
  2064. else
  2065. /* the STYLE element has a Notation attribute */
  2066. /* get its value */
  2067. {
  2068. length = TtaGetTextAttributeLength (attr);
  2069. text = (char *)TtaGetMemory (length + 1);
  2070. TtaGiveTextAttributeValue (attr, text, &length);
  2071. if (!strcasecmp (text, "text/css"))
  2072. XMLcontext.parsingCSS = TRUE;
  2073. TtaFreeMemory (text);
  2074. }
  2075. }
  2076. else
  2077. if (elType.ElTypeNum == HTML_EL_Text_Area)
  2078. {
  2079. /* we have to read the content as a simple text unit */
  2080. XMLcontext.parsingTextArea = TRUE;
  2081. }
  2082. }
  2083. /* Specific treatment (concerns only MathML for the moment) */
  2084. if (CurrentParserCtxt != NULL &&
  2085. CurrentParserCtxt->ElementCreated != NULL)
  2086. (*(Proc2)(CurrentParserCtxt->ElementCreated)) (
  2087. (void *)XMLcontext.lastElement,
  2088. (void *)XMLcontext.doc);
  2089. }
  2090. XmlWhiteSpaceHandling ();
  2091. }
  2092. /*---------------------- StartElement (end) -----------------------*/
  2093. /*---------------------- EndElement (start) -----------------------*/
  2094. /*----------------------------------------------------------------------
  2095. EndOfXmlElement
  2096. Terminate all corresponding Thot elements.
  2097. ----------------------------------------------------------------------*/
  2098. static void EndOfXmlElement (char *name)
  2099. {
  2100. ElementType elType;
  2101. PtrParserCtxt savParserCtxt = NULL;
  2102. int profile;
  2103. char *nsURI, *elementName;
  2104. char *buffer;
  2105. char *ptr;
  2106. char msgBuffer[MaxMsgLength];
  2107. char *mappedName = NULL;
  2108. ThotBool highEnoughLevel = TRUE;
  2109. UnknownNS = FALSE;
  2110. UnknownElement = FALSE;
  2111. elementName = NULL;
  2112. nsURI = NULL;
  2113. if (name == NULL)
  2114. return;
  2115. buffer = (char *)TtaStrdup ((char *)name);
  2116. savParserCtxt = CurrentParserCtxt;
  2117. /* Is this element in the scope of a namespace declaration */
  2118. if ((ptr = strrchr (buffer, NS_SEP)) != NULL)
  2119. {
  2120. *ptr = EOS;
  2121. nsURI = (char *)TtaStrdup ((char *)buffer);
  2122. *ptr = NS_SEP;
  2123. ptr++;
  2124. /* Look for the context associated with that namespace */
  2125. if (nsURI && ChangeXmlParserContextByUri (nsURI))
  2126. {
  2127. /* check the document profile */
  2128. profile = TtaGetDocumentProfile (XMLcontext.doc);
  2129. if (profile == L_Basic || profile == L_Strict)
  2130. {
  2131. TtaFreeMemory (nsURI);
  2132. TtaFreeMemory (buffer);
  2133. CurrentParserCtxt = savParserCtxt;
  2134. return;
  2135. }
  2136. }
  2137. elementName = (char *)TtaGetMemory ((strlen ((char *)ptr) + 1));
  2138. strcpy ((char *)elementName, (char *)ptr);
  2139. }
  2140. else
  2141. elementName = (char *)TtaStrdup ((char *)buffer);
  2142. if (XMLcontext.parsingTextArea)
  2143. if (strcasecmp (elementName, "textarea") != 0)
  2144. /* We are parsing the contents of a textarea element. */
  2145. /* The end tag is not the one closing the current textarea, */
  2146. /* consider it as plain text */
  2147. return;
  2148. if (CurrentParserCtxt == NULL)
  2149. {
  2150. #ifdef XML_GENERIC
  2151. /* assign the generic context */
  2152. CurrentParserCtxt = GenericXmlParserCtxt;
  2153. #else /*XML_GENERIC*/
  2154. CurrentParserCtxt = savParserCtxt;
  2155. UnknownNS = TRUE;
  2156. #endif /* XML_GENERIC */
  2157. }
  2158. /* search the element name in the corresponding mapping table */
  2159. elType.ElSSchema = NULL;
  2160. elType.ElTypeNum = 0;
  2161. currentElementName[0] = EOS;
  2162. if (UnknownNS)
  2163. /* create an Unknown_namespace element */
  2164. UnknownXmlNsElement (nsURI, elementName, FALSE);
  2165. else
  2166. {
  2167. GetXmlElType (nsURI, elementName, &elType, &mappedName,
  2168. &currentElementContent, &highEnoughLevel);
  2169. if (mappedName == NULL)
  2170. /* element not found in the corresponding DTD */
  2171. UnknownElement = TRUE;
  2172. else
  2173. {
  2174. /* element found in the corresponding DTD */
  2175. if (!XmlCloseElement (mappedName))
  2176. {
  2177. /* the end tag does not close any current element */
  2178. snprintf ((char *)msgBuffer, MaxMsgLength,
  2179. "Unexpected end tag </%s>", elementName);
  2180. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  2181. }
  2182. }
  2183. }
  2184. TtaFreeMemory (buffer);
  2185. TtaFreeMemory (elementName);
  2186. TtaFreeMemory (nsURI);
  2187. }
  2188. /*--------------------- EndElement (end) --------------------------*/
  2189. /*---------------------- Data (start) -----------------------------*/
  2190. /*----------------------------------------------------------------------
  2191. IsLeadingSpaceUseless
  2192. lastEl is the previous sibling of the new Text element
  2193. doc is the current document
  2194. isXML is TRUE if parsing a generic XML
  2195. ----------------------------------------------------------------------*/
  2196. ThotBool IsLeadingSpaceUseless (Element lastEl, Document doc,
  2197. ThotBool sibling, ThotBool isXML)
  2198. {
  2199. ElementType elType, lastElType, prevType;
  2200. Element parent, last;
  2201. char *name, *s;
  2202. ThotBool removeLeadingSpaces;
  2203. if (sibling)
  2204. /* There is a previous sibling (lastEl) for the new Text element */
  2205. {
  2206. parent = TtaGetParent (lastEl);
  2207. if (parent == NULL)
  2208. parent = lastEl;
  2209. elType = TtaGetElementType (parent);
  2210. lastElType = TtaGetElementType (lastEl);
  2211. removeLeadingSpaces = TRUE;
  2212. if (isXML)
  2213. {
  2214. /* Does the parent element contains a 'Line' presentation rule ? */
  2215. /* if (TtaHasXmlInLineRule (elType, doc))*/
  2216. /* Return FALSE for XML documents */
  2217. removeLeadingSpaces = FALSE;
  2218. }
  2219. else
  2220. {
  2221. name = TtaGetSSchemaName (elType.ElSSchema);
  2222. s = TtaGetSSchemaName (lastElType.ElSSchema);
  2223. if (!strcmp (s, "MathML") &&
  2224. lastElType.ElTypeNum == MathML_EL_MathML)
  2225. // keep space after a Math element
  2226. removeLeadingSpaces = FALSE;
  2227. else if (!strcmp (name, "HTML") &&
  2228. // parent
  2229. elType.ElTypeNum != HTML_EL_HTML &&
  2230. elType.ElTypeNum != HTML_EL_HEAD &&
  2231. elType.ElTypeNum != HTML_EL_BODY &&
  2232. elType.ElTypeNum != HTML_EL_Division &&
  2233. elType.ElTypeNum != HTML_EL_Unnumbered_List &&
  2234. elType.ElTypeNum != HTML_EL_Numbered_List &&
  2235. elType.ElTypeNum != HTML_EL_Term_List &&
  2236. elType.ElTypeNum != HTML_EL_Definition_List &&
  2237. elType.ElTypeNum != HTML_EL_Table_ &&
  2238. elType.ElTypeNum != HTML_EL_Table_row &&
  2239. // element
  2240. !strcmp (s, "HTML") &&
  2241. (lastElType.ElTypeNum == HTML_EL_Comment_ ||
  2242. lastElType.ElTypeNum == HTML_EL_ASP_element ||
  2243. lastElType.ElTypeNum == HTML_EL_XMLPI))
  2244. {
  2245. /* Search the last significant sibling prior to a comment or a Pi */
  2246. /* except for a comment or a Pi within the HEAD section */
  2247. last = lastEl;
  2248. TtaPreviousSibling (&last);
  2249. while (last && removeLeadingSpaces)
  2250. {
  2251. prevType = TtaGetElementType (last);
  2252. s = TtaGetSSchemaName (prevType.ElSSchema);
  2253. if (strcmp (s, "HTML") ||
  2254. (prevType.ElTypeNum != HTML_EL_Comment_ &&
  2255. prevType.ElTypeNum != HTML_EL_ASP_element &&
  2256. prevType.ElTypeNum != HTML_EL_XMLPI &&
  2257. prevType.ElTypeNum != HTML_EL_DOCTYPE))
  2258. // there is a previous element before
  2259. removeLeadingSpaces = (prevType.ElTypeNum == HTML_EL_TEXT_UNIT);
  2260. TtaPreviousSibling (&last);
  2261. }
  2262. }
  2263. else if (!strcmp (name, "HTML") &&
  2264. IsCharacterLevelElement (lastEl))
  2265. {
  2266. if (elType.ElTypeNum != HTML_EL_Option_Menu &&
  2267. elType.ElTypeNum != HTML_EL_OptGroup)
  2268. {
  2269. removeLeadingSpaces = FALSE;
  2270. if (lastElType.ElTypeNum == HTML_EL_BR)
  2271. removeLeadingSpaces = TRUE;
  2272. }
  2273. }
  2274. #ifdef _SVG
  2275. else if (!strcmp (name, "SVG") &&
  2276. (elType.ElTypeNum == SVG_EL_text_ ||
  2277. elType.ElTypeNum == SVG_EL_tspan))
  2278. removeLeadingSpaces = FALSE;
  2279. #endif /* _SVG */
  2280. else if (!strcmp (name, "Template") &&
  2281. lastElType.ElTypeNum == HTML_EL_TEXT_UNIT)
  2282. {
  2283. removeLeadingSpaces = FALSE;
  2284. }
  2285. }
  2286. }
  2287. else
  2288. /* the new Text element should be the first child
  2289. of the latest element encountered */
  2290. {
  2291. removeLeadingSpaces = TRUE;
  2292. }
  2293. return removeLeadingSpaces;
  2294. }
  2295. /*----------------------------------------------------------------------
  2296. PutInXmlElement
  2297. ----------------------------------------------------------------------*/
  2298. void PutInXmlElement (char *data, int length)
  2299. {
  2300. ElementType elType;
  2301. Element elText, parent;
  2302. char *buffer, *bufferws;
  2303. int i = 0;
  2304. int i1, i2 = 0, i3 = 0;
  2305. ThotBool uselessSpace = FALSE;
  2306. ThotBool insSibling, ok, removeEOL = RemoveLineBreak;
  2307. i = 0;
  2308. /* Immediately after a start tag, treatment of the leading spaces */
  2309. /* If RemoveLeadingSpace = TRUE, we suppress all leading white-space */
  2310. /* characters, otherwise, we only suppress the first line break */
  2311. if (ImmediatelyAfterTag)
  2312. {
  2313. if (RemoveLeadingSpace)
  2314. {
  2315. while (data[i] == EOL || data[i] == __CR__ ||
  2316. data[i] == TAB || data[i] == SPACE)
  2317. i++;
  2318. if (data[i] != EOS)
  2319. ImmediatelyAfterTag = FALSE;
  2320. }
  2321. else
  2322. {
  2323. if (data[0] == EOL || data[0] == __CR__)
  2324. i = 1;
  2325. ImmediatelyAfterTag = FALSE;
  2326. }
  2327. }
  2328. if (CurrentParserCtxt->XMLSSchema &&
  2329. TtaIsXmlSSchema (CurrentParserCtxt->XMLSSchema) &&
  2330. length == 1 && data[0] == EOL)
  2331. {
  2332. if (XMLcontext.lastElement)
  2333. // don't generate a XML_Element just after a text unit
  2334. elType = TtaGetElementType (XMLcontext.lastElement);
  2335. else
  2336. elType.ElTypeNum = 0;
  2337. if (elType.ElTypeNum != XML_EL_TEXT_UNIT)
  2338. {
  2339. // create an empty element
  2340. elType.ElSSchema = CurrentParserCtxt->XMLSSchema;
  2341. elType.ElTypeNum = XML_EL_xmlbr;
  2342. elText = TtaNewElement (XMLcontext.doc, elType);
  2343. XmlSetElemLineNumber (elText);
  2344. InsertXmlElement (&elText);
  2345. XMLcontext.lastElementClosed = TRUE;
  2346. return;
  2347. }
  2348. else
  2349. removeEOL = TRUE;
  2350. }
  2351. else if (length == i || data[i] == EOS)
  2352. return;
  2353. length -= i;
  2354. bufferws = (char *)TtaGetMemory (length + 1);
  2355. strncpy (bufferws, &data[i], length);
  2356. bufferws[length] = EOS;
  2357. /* Convert line-break or tabs into space character */
  2358. i = 0;
  2359. if (removeEOL)
  2360. {
  2361. while (bufferws[i] != EOS)
  2362. {
  2363. if (bufferws[i] == EOL || bufferws[i] == __CR__ ||
  2364. bufferws[i] == TAB)
  2365. bufferws[i]= SPACE;
  2366. i++;
  2367. }
  2368. }
  2369. i = 0;
  2370. if (XMLcontext.lastElement)
  2371. {
  2372. /* Suppress the leading spaces in Inline elements */
  2373. insSibling = InsertingSibling ();
  2374. uselessSpace = IsLeadingSpaceUseless (XMLcontext.lastElement, XMLcontext.doc, insSibling,
  2375. TtaIsXmlSSchema (CurrentParserCtxt->XMLSSchema));
  2376. if (RemoveLeadingSpace && uselessSpace)
  2377. /* suppress leading spaces */
  2378. while (bufferws[i] == SPACE)
  2379. i++;
  2380. /* Collapse contiguous spaces */
  2381. if (bufferws[i] != EOS)
  2382. {
  2383. length = strlen ((char *)bufferws);
  2384. buffer = (char *)TtaGetMemory (length+1);
  2385. if (RemoveContiguousSpace)
  2386. {
  2387. for (i1 = i; i1 <= length; i1++)
  2388. {
  2389. if ((unsigned int)bufferws[i1] <= SPACE && bufferws[i1] != EOS)
  2390. i3++;
  2391. else
  2392. i3 = 0;
  2393. if (i3 <= 1)
  2394. buffer[i2++] = bufferws[i1];
  2395. }
  2396. }
  2397. else
  2398. strcpy ((char *)buffer, (char *)bufferws);
  2399. i1 = 0;
  2400. /* Filling of the element value */
  2401. elType = TtaGetElementType (XMLcontext.lastElement);
  2402. if (elType.ElTypeNum == 1 && XMLcontext.mergeText)
  2403. {
  2404. if ((buffer[i1] == SPACE) && RemoveContiguousSpace)
  2405. {
  2406. /* Is the last character of text element a space */
  2407. if (TtaHasFinalSpace (XMLcontext.lastElement, XMLcontext.doc))
  2408. /* Remove leading space if last content was finished by a space */
  2409. TtaAppendTextContent (XMLcontext.lastElement,
  2410. (unsigned char *)&(buffer[i1 + 1]), XMLcontext.doc);
  2411. else
  2412. TtaAppendTextContent (XMLcontext.lastElement,
  2413. (unsigned char *)&(buffer[i1]), XMLcontext.doc);
  2414. }
  2415. else
  2416. TtaAppendTextContent (XMLcontext.lastElement,
  2417. (unsigned char *)&(buffer[i1]), XMLcontext.doc);
  2418. }
  2419. else
  2420. {
  2421. if (RemoveLeadingSpace &&
  2422. CurrentParserCtxt->XMLSSchema &&
  2423. !strcmp ((char *)CurrentParserCtxt->SSchemaName, "HTML") &&
  2424. buffer[i1] == SPACE && strlen (&buffer[i1]) == 1)
  2425. {
  2426. // avoid to generate an empty pseudo paragraph
  2427. ok = FALSE;
  2428. if (InsertingSibling ())
  2429. parent = TtaGetParent (XMLcontext.lastElement);
  2430. else
  2431. parent = XMLcontext.lastElement;
  2432. if (parent)
  2433. {
  2434. elType = TtaGetElementType (parent);
  2435. if (IsCharacterLevelElement (parent) ||
  2436. !XhtmlCannotContainText (elType))
  2437. ok = TRUE; // generate the TEXT element
  2438. }
  2439. }
  2440. else
  2441. ok = TRUE;
  2442. if (ok && CurrentParserCtxt->XMLSSchema)
  2443. {
  2444. // by default insert a new text unit
  2445. insSibling = TRUE;
  2446. if (TtaIsXmlSSchema (CurrentParserCtxt->XMLSSchema) &&
  2447. XMLcontext.lastElement)
  2448. {
  2449. // replace the previous XML_Element by a text unit
  2450. elType = TtaGetElementType (XMLcontext.lastElement);
  2451. insSibling = (elType.ElTypeNum != XML_EL_xmlbr);
  2452. if (!insSibling)
  2453. {
  2454. elText = XMLcontext.lastElement;
  2455. }
  2456. }
  2457. if (insSibling)
  2458. {
  2459. elType.ElSSchema = CurrentParserCtxt->XMLSSchema;
  2460. /* create a TEXT element */
  2461. elType.ElTypeNum = HTML_EL_TEXT_UNIT;
  2462. elText = TtaNewElement (XMLcontext.doc, elType);
  2463. if (elText)
  2464. {
  2465. XmlSetElemLineNumber (elText);
  2466. InsertXmlElement (&elText);
  2467. /* put the content of the input buffer into the TEXT element */
  2468. TtaSetTextContent (elText, (unsigned char *)&(buffer[i1]),
  2469. XMLcontext.language, XMLcontext.doc);
  2470. }
  2471. }
  2472. else
  2473. {
  2474. // replace the empty element by a text unit
  2475. TtaChangeTypeOfElement (elText, XMLcontext.doc, XML_EL_TEXT_UNIT);
  2476. XmlSetElemLineNumber (elText);
  2477. XMLcontext.lastElement = elText;
  2478. XMLcontext.lastElementClosed = FALSE;
  2479. TtaSetTextContent (elText, (unsigned char *)"\n",
  2480. XMLcontext.language, XMLcontext.doc);
  2481. TtaAppendTextContent (XMLcontext.lastElement,
  2482. (unsigned char *)&(buffer[i1]), XMLcontext.doc);
  2483. }
  2484. /* associate a specific 'Line' presentation rule to the
  2485. parent element if we are parsing a generic-XML element */
  2486. XMLcontext.lastElementClosed = TRUE;
  2487. XMLcontext.mergeText = TRUE;
  2488. }
  2489. }
  2490. TtaFreeMemory (buffer);
  2491. }
  2492. TtaFreeMemory (bufferws);
  2493. }
  2494. }
  2495. /*----------------------------------------------------------------------
  2496. HandleXMLstring handles the UTF-8 character string data and generates
  2497. entities when needed.
  2498. When handling the content of an attribute value (element = NULL) the
  2499. function generates a single string where entities are translated when
  2500. it's possible.
  2501. When handling the content of a standard element (element != NULL and
  2502. stdText == TRUE) the function generates TEXT elements and SYMBOLS
  2503. itself.
  2504. When handling the content of a comment (element != NULL and
  2505. stdText == FALSE) the function stops either when the whole string is
  2506. handled or when it has generated a fallback character for an entity
  2507. Returns
  2508. - the content of the TEXT element.
  2509. - the length of the parsed original string in *length.
  2510. ----------------------------------------------------------------------*/
  2511. static unsigned char *HandleXMLstring (unsigned char *data, int *length,
  2512. Element element, ThotBool stdText)
  2513. {
  2514. unsigned char *buffer;
  2515. unsigned char *ptr;
  2516. unsigned char *entityName;
  2517. int i = 0, j = 0;
  2518. int max;
  2519. int k, l, m;
  2520. int entityValue;
  2521. ThotBool found, end;
  2522. char msgBuffer[MaxMsgLength];
  2523. max = *length;
  2524. buffer = (unsigned char *)TtaGetMemory (4 * max + 1);
  2525. while (i < max)
  2526. {
  2527. if (data[i] == START_ENTITY)
  2528. {
  2529. /* Maybe it is the beginning of an entity */
  2530. end = FALSE;
  2531. entityName = (unsigned char *)TtaGetMemory (max + 1);
  2532. l = 0;
  2533. entityName[l++] = START_ENTITY;
  2534. for (k = i + 1; k < max && !end; k++)
  2535. {
  2536. if (data[k] == '&')
  2537. {
  2538. /* An '&' inside an other '&' ?? We suppose */
  2539. /* the first one doesn't belong to an entity */
  2540. k = max;
  2541. buffer[j++] = START_ENTITY;
  2542. }
  2543. else if (data[k] == ';')
  2544. {
  2545. /* End of the entity */
  2546. end = TRUE;
  2547. entityName[l] = EOS;
  2548. found = MapXMLEntity (CurrentParserCtxt->XMLtype,
  2549. (char *)&entityName[1], &entityValue);
  2550. if (found && (entityValue < 0x3FF ||
  2551. entityValue == 0x200D ||
  2552. entityValue == 0x200E /* lrm */ ||
  2553. entityValue == 0x200F /* rlm */ ||
  2554. entityValue == 0x202A /* lre */ ||
  2555. entityValue == 0x202B /* rle */ ||
  2556. entityValue == 0x202D /* lro */ ||
  2557. entityValue == 0x202E /* rlo */ ||
  2558. entityValue == 0x202C /* pdf */))
  2559. {
  2560. /* get the UTF-8 string of the unicode character */
  2561. ptr = &buffer[j];
  2562. j += TtaWCToMBstring ((wchar_t) entityValue, &ptr);
  2563. }
  2564. else if (found && element)
  2565. {
  2566. if (stdText)
  2567. {
  2568. buffer[j] = EOS;
  2569. if (j > 0)
  2570. {
  2571. /* close the current text element */
  2572. PutInXmlElement ((char *)buffer, j);
  2573. XMLcontext.lastElementClosed = TRUE;
  2574. }
  2575. XMLcontext.mergeText = FALSE;
  2576. ImmediatelyAfterTag = FALSE;
  2577. element = XMLcontext.lastElement;
  2578. j = 0;
  2579. }
  2580. else
  2581. {
  2582. /* stop the handling of the original string */
  2583. max = i;
  2584. *length = max;
  2585. }
  2586. /* generate a fallback character */
  2587. entityName[l++] = ';';
  2588. entityName[l] = EOS;
  2589. XmlGetFallbackCharacter ((wchar_t)entityValue,
  2590. (char *)entityName, element);
  2591. if (stdText)
  2592. {
  2593. XMLcontext.lastElementClosed = TRUE;
  2594. XMLcontext.mergeText = FALSE;
  2595. }
  2596. }
  2597. else
  2598. {
  2599. /* store the entity name */
  2600. for (m = 0; entityName[m] != EOS; m++)
  2601. buffer[j++] = entityName[m];
  2602. buffer[j++] = ';';
  2603. if (!found)
  2604. {
  2605. sprintf ((char *)msgBuffer, "Unknown entity \"%s;\"",
  2606. entityName);
  2607. XmlParseError (errorParsing,
  2608. (unsigned char *)msgBuffer, 0);
  2609. }
  2610. }
  2611. }
  2612. else
  2613. entityName[l++] = data[k];
  2614. i++;
  2615. }
  2616. TtaFreeMemory (entityName);
  2617. i++;
  2618. }
  2619. else
  2620. buffer[j++] = data[i++];
  2621. }
  2622. buffer[j] = EOS;
  2623. if (stdText)
  2624. {
  2625. if (j > 0)
  2626. PutInXmlElement ((char *)buffer, j);
  2627. }
  2628. return buffer;
  2629. }
  2630. /*---------------------- Data (end) ---------------------------*/
  2631. /*-------------------- Attributes (start) ---------------------*/
  2632. /*----------------------------------------------------------------------
  2633. UnknownXmlAttribute
  2634. Creation and filling in of an "unknown_attr" attribute
  2635. ----------------------------------------------------------------------*/
  2636. static void UnknownXmlAttribute (char *xmlAttr, char *ns_uri)
  2637. {
  2638. AttributeType attrType;
  2639. Attribute attr;
  2640. char *buffer, *bufattr, *ns_prefix = NULL;
  2641. ThotBool level = TRUE;
  2642. int length, buflen;
  2643. if (CurrentParserCtxt != NULL)
  2644. {
  2645. /* If the uri associated with a prefix ? */
  2646. if (ns_uri != NULL)
  2647. ns_prefix = NsGetPrefix (ns_uri);
  2648. /* Attach an Invalid_attribute to the current element */
  2649. attrType.AttrSSchema = CurrentParserCtxt->XMLSSchema;
  2650. if (CurrentParserCtxt == XhtmlParserCtxt)
  2651. attrType.AttrTypeNum = HTML_ATTR_Unknown_attribute;
  2652. else
  2653. (*(Proc5)(CurrentParserCtxt->MapAttribute)) (
  2654. (void *)"unknown_attr",
  2655. (void *)&attrType,
  2656. (void *)currentElementName,
  2657. (void *)&level,
  2658. (void *)XMLcontext.doc);
  2659. if (attrType.AttrTypeNum > 0)
  2660. {
  2661. attr = TtaGetAttribute (XMLcontext.lastElement, attrType);
  2662. if (attr == NULL)
  2663. {
  2664. attr = TtaNewAttribute (attrType);
  2665. TtaAttachAttribute (XMLcontext.lastElement, attr, XMLcontext.doc);
  2666. length = strlen ((char *)xmlAttr);
  2667. if (ns_prefix != NULL)
  2668. {
  2669. length += strlen ((char *)ns_prefix);
  2670. buffer = (char *)TtaGetMemory (length + 3);
  2671. strcpy ((char *)buffer, " ");
  2672. strcat ((char *)buffer, (char *)ns_prefix);
  2673. strcat ((char *)buffer, ":");
  2674. strcat ((char *)buffer, (char *)xmlAttr);
  2675. }
  2676. else
  2677. {
  2678. buffer = (char *)TtaGetMemory (length + 2);
  2679. strcpy ((char *)buffer, " ");
  2680. strcat ((char *)buffer, (char *)xmlAttr);
  2681. }
  2682. TtaSetAttributeText (attr, (char *)buffer,
  2683. XMLcontext.lastElement,
  2684. XMLcontext.doc);
  2685. TtaFreeMemory (buffer);
  2686. }
  2687. else
  2688. {
  2689. /* Copy the name of the attribute as the content */
  2690. /* of the Invalid_attribute attribute. */
  2691. buflen = TtaGetTextAttributeLength (attr);
  2692. bufattr = (char *)TtaGetMemory (buflen + 1);
  2693. TtaGiveTextAttributeValue (attr, bufattr, &buflen);
  2694. length = strlen ((char *)bufattr);
  2695. length += strlen ((char *)xmlAttr);
  2696. if (ns_prefix != NULL)
  2697. {
  2698. length += strlen ((char *)ns_prefix);
  2699. buffer = (char *)TtaGetMemory (length + 3);
  2700. strcpy ((char *)buffer, (char *)bufattr);
  2701. strcat ((char *)buffer, " ");
  2702. strcat ((char *)buffer, (char *)ns_prefix);
  2703. strcat ((char *)buffer, ":");
  2704. strcat ((char *)buffer, (char *)xmlAttr);
  2705. }
  2706. else
  2707. {
  2708. buffer = (char *)TtaGetMemory (length + 2);
  2709. strcpy ((char *)buffer, (char *)bufattr);
  2710. strcat ((char *)buffer, " ");
  2711. strcat ((char *)buffer, (char *)xmlAttr);
  2712. }
  2713. TtaSetAttributeText (attr, (char *)buffer,
  2714. XMLcontext.lastElement,
  2715. XMLcontext.doc);
  2716. TtaFreeMemory (buffer);
  2717. TtaFreeMemory (bufattr);
  2718. }
  2719. currentAttribute = attr;
  2720. }
  2721. }
  2722. return;
  2723. }
  2724. /*----------------------------------------------------------------------
  2725. EndOfXhtmlAttributeName
  2726. End of an XHTML attribute
  2727. ----------------------------------------------------------------------*/
  2728. static void EndOfXhtmlAttributeName (char *attrName, Element el,
  2729. Document doc)
  2730. {
  2731. AttributeMapping *mapAttr;
  2732. AttributeType attrType;
  2733. ElementType elType;
  2734. Attribute attr;
  2735. char translation;
  2736. ThotBool highEnoughLevel = TRUE;
  2737. char msgBuffer[MaxMsgLength];
  2738. UnknownAttr = FALSE;
  2739. attrType.AttrTypeNum = 0;
  2740. mapAttr = MapHTMLAttribute (attrName, &attrType, currentElementName,
  2741. &highEnoughLevel, doc);
  2742. if (attrType.AttrTypeNum <= 0)
  2743. {
  2744. /* this attribute is not in the HTML mapping table */
  2745. if (strcasecmp (attrName, "xml:lang") == 0)
  2746. /* attribute xml:lang is not considered as invalid, but it is ignored */
  2747. lastMappedAttr = NULL;
  2748. else if (highEnoughLevel)
  2749. {
  2750. snprintf ((char *)msgBuffer, MaxMsgLength,
  2751. "Invalid XHTML attribute \"%s\"", attrName);
  2752. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  2753. }
  2754. else
  2755. {
  2756. snprintf ((char *)msgBuffer, MaxMsgLength,
  2757. "Invalid XHTML attribute \"%s\" for the document profile",
  2758. attrName);
  2759. XmlParseError (errorParsingProfile, (unsigned char *)msgBuffer, 0);
  2760. }
  2761. }
  2762. if (attrType.AttrTypeNum > 0 && el != NULL &&
  2763. (!XMLcontext.lastElementClosed ||
  2764. (XMLcontext.lastElement != RootElement)))
  2765. {
  2766. lastMappedAttr = mapAttr;
  2767. translation = lastMappedAttr->AttrOrContent;
  2768. switch (translation)
  2769. {
  2770. case 'C': /* Content */
  2771. /* Nothing to do yet: wait for attribute value */
  2772. break;
  2773. case 'A':
  2774. /* create an attribute for current element */
  2775. CreateHTMLAttribute (el, attrType, attrName, UnknownAttr,
  2776. doc, &currentAttribute, &lastAttrElement);
  2777. if (attrType.AttrTypeNum == HTML_ATTR_HREF_)
  2778. {
  2779. elType = TtaGetElementType (el);
  2780. if (elType.ElTypeNum == HTML_EL_Anchor)
  2781. /* attribute HREF for element Anchor */
  2782. /* create attribute PseudoClass = link */
  2783. {
  2784. attrType.AttrTypeNum = HTML_ATTR_PseudoClass;
  2785. attr = TtaNewAttribute (attrType);
  2786. TtaAttachAttribute (el, attr, doc);
  2787. TtaSetAttributeText (attr, (char *)"link", el, doc);
  2788. }
  2789. }
  2790. else
  2791. if (attrType.AttrTypeNum == HTML_ATTR_Checked)
  2792. {
  2793. /* create Default-Checked attribute */
  2794. attrType.AttrTypeNum = HTML_ATTR_DefaultChecked;
  2795. attr = TtaNewAttribute (attrType);
  2796. TtaAttachAttribute (el, attr, doc);
  2797. TtaSetAttributeValue (attr, HTML_ATTR_DefaultChecked_VAL_Yes_,
  2798. el, doc);
  2799. }
  2800. else
  2801. if (attrType.AttrTypeNum == HTML_ATTR_Selected)
  2802. {
  2803. /* create Default-Selected attribute */
  2804. attrType.AttrTypeNum = HTML_ATTR_DefaultSelected;
  2805. attr = TtaNewAttribute (attrType);
  2806. TtaAttachAttribute (el, attr, doc);
  2807. TtaSetAttributeValue (attr, HTML_ATTR_DefaultSelected_VAL_Yes_,
  2808. el, doc);
  2809. }
  2810. break;
  2811. case SPACE:
  2812. /* nothing to do */
  2813. break;
  2814. default:
  2815. break;
  2816. }
  2817. }
  2818. }
  2819. /*----------------------------------------------------------------------
  2820. XmlEndOfAttrName
  2821. End of a XML attribute (other than XHTML)
  2822. ----------------------------------------------------------------------*/
  2823. static void EndOfXmlAttributeName (char *attrName, char *uriName,
  2824. Element el, Document doc)
  2825. {
  2826. AttributeType attrType;
  2827. Attribute attr;
  2828. char msgBuffer[MaxMsgLength];
  2829. ThotBool level = TRUE;
  2830. char schemaName[NAME_LENGTH];
  2831. ElementType elType;
  2832. ThotBool isnew;
  2833. attrType.AttrTypeNum = 0;
  2834. #ifdef OLD
  2835. if (strlen ((char *)attrName) >= NAME_LENGTH)
  2836. {
  2837. strcpy ((char *)schemaName, (char *)CurrentParserCtxt->SSchemaName);
  2838. snprintf ((char *)msgBuffer, MaxMsgLength,
  2839. "Attribute name too long for Amaya %s", attrName);
  2840. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  2841. UnknownAttr = TRUE;
  2842. return;
  2843. }
  2844. #endif
  2845. if (CurrentParserCtxt != NULL)
  2846. {
  2847. if (CurrentParserCtxt == GenericXmlParserCtxt)
  2848. {
  2849. if (uriName != NULL)
  2850. {
  2851. isnew = FALSE;
  2852. attrType.AttrSSchema = GetGenericXMLSSchemaByUri (uriName, XMLcontext.doc, &isnew);
  2853. if (isnew)
  2854. TtaChangeGenericSchemaNames (uriName, attrName, XMLcontext.doc);
  2855. }
  2856. else
  2857. {
  2858. elType = TtaGetElementType (XMLcontext.lastElement);
  2859. attrType.AttrSSchema = elType.ElSSchema;
  2860. }
  2861. MapGenericXmlAttribute (attrName, &attrType, doc);
  2862. }
  2863. else
  2864. {
  2865. if (CurrentParserCtxt->MapAttribute)
  2866. (*(Proc5)(CurrentParserCtxt->MapAttribute)) (
  2867. (void *)attrName,
  2868. (void *)&attrType,
  2869. (void *)currentElementName,
  2870. (void *)&level,
  2871. (void *)doc);
  2872. }
  2873. }
  2874. if (attrType.AttrTypeNum <= 0)
  2875. {
  2876. /* This attribute is not in the corresponding mapping table */
  2877. strncpy ((char *)schemaName, (char *)CurrentParserCtxt->SSchemaName,NAME_LENGTH-1);
  2878. schemaName[NAME_LENGTH-1] = EOS;
  2879. // skip possible old template attributes
  2880. if (strcmp (schemaName, "Template"))
  2881. {
  2882. snprintf (msgBuffer, MaxMsgLength,
  2883. "Invalid or unsupported %s attribute \"%s\"",
  2884. schemaName, attrName);
  2885. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  2886. /* Attach an Invalid_attribute to the current element */
  2887. /* It may be a valid attribute that is not yet defined in Amaya tables */
  2888. UnknownXmlAttribute (attrName, NULL);
  2889. }
  2890. UnknownAttr = TRUE;
  2891. }
  2892. else
  2893. {
  2894. attr = TtaGetAttribute (el, attrType);
  2895. if (!attr)
  2896. {
  2897. attr = TtaNewAttribute (attrType);
  2898. TtaAttachAttribute (el, attr, doc);
  2899. }
  2900. currentAttribute = attr;
  2901. if (strcasecmp (attrName, "style") == 0)
  2902. HTMLStyleAttribute = TRUE;
  2903. }
  2904. }
  2905. /*----------------------------------------------------------------------
  2906. EndOfAttributeName
  2907. A XML attribute has been read.
  2908. Create the corresponding Thot attribute.
  2909. ----------------------------------------------------------------------*/
  2910. static void EndOfAttributeName (char *xmlName)
  2911. {
  2912. PtrParserCtxt savParserCtxt = NULL;
  2913. int profile;
  2914. char *attrName, *nsURI;
  2915. char *ptr = NULL;
  2916. unsigned char msgBuffer[MaxMsgLength];
  2917. currentAttribute = NULL;
  2918. lastMappedAttr = NULL;
  2919. UnknownAttr = FALSE;
  2920. HTMLStyleAttribute = FALSE;
  2921. XMLSpaceAttribute = FALSE;
  2922. if (UnknownElement)
  2923. /* The corresponding element doesn't belong to the current DTD */
  2924. return;
  2925. /* look for a NS_SEP in the tag name (namespaces) */
  2926. /* and ignore the prefix if there is one */
  2927. savParserCtxt = CurrentParserCtxt;
  2928. nsURI = (char *)TtaStrdup ((char *)xmlName);
  2929. if ((ptr = strrchr (nsURI, NS_SEP)) != NULL)
  2930. {
  2931. /* This attribute belongs to a specific namespace */
  2932. *ptr = EOS;
  2933. ptr++;
  2934. /* Specific treatment to get round a bug in EXPAT parser */
  2935. /* It replaces first "xml:" prefix by the namespaces URI */
  2936. if (strcmp ((char *)nsURI, (char *)NAMESPACE_URI) == 0)
  2937. {
  2938. attrName = (char *)TtaGetMemory (strlen ((char *)ptr) + 5);
  2939. strcpy ((char *)attrName, "xml:");
  2940. strcat ((char *)attrName, (char *)ptr);
  2941. if (nsURI)
  2942. {
  2943. TtaFreeMemory (nsURI);
  2944. nsURI = NULL;
  2945. }
  2946. }
  2947. else
  2948. {
  2949. attrName = (char *)TtaStrdup ((char *)ptr);
  2950. if (UnknownNS)
  2951. CurrentParserCtxt = NULL;
  2952. if (CurrentParserCtxt && CurrentParserCtxt->UriName &&
  2953. strcmp ((char *)nsURI, (char *)CurrentParserCtxt->UriName) &&
  2954. ChangeXmlParserContextByUri (nsURI))
  2955. {
  2956. /* check the document profile */
  2957. profile = TtaGetDocumentProfile (XMLcontext.doc);
  2958. if (profile == L_Basic || profile == L_Strict)
  2959. {
  2960. TtaFreeMemory (nsURI);
  2961. CurrentParserCtxt = savParserCtxt;
  2962. return;
  2963. }
  2964. }
  2965. }
  2966. }
  2967. else
  2968. {
  2969. if ((ptr = strrchr (nsURI, NS_COLON)) != NULL)
  2970. {
  2971. /* This attribute is prefixed */
  2972. *ptr = EOS;
  2973. if (strcmp (nsURI, "xml") != 0)
  2974. {
  2975. if (CurrentParserCtxt == NULL ||
  2976. CurrentParserCtxt->SSchemaName == NULL ||
  2977. strcmp (CurrentParserCtxt->SSchemaName, "SVG") ||
  2978. strcmp (nsURI, "xlink"))
  2979. {
  2980. snprintf ((char *)msgBuffer, MaxMsgLength,
  2981. "Undefined prefix for the attribute \"%s\"", (char *)xmlName);
  2982. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  2983. *ptr = NS_COLON;
  2984. if (nsURI)
  2985. {
  2986. TtaFreeMemory (nsURI);
  2987. nsURI = NULL;
  2988. }
  2989. UnknownAttr = TRUE;
  2990. return;
  2991. }
  2992. }
  2993. *ptr = NS_COLON;
  2994. }
  2995. /* This attribute belongs to the same namespace as the element */
  2996. TtaFreeMemory (nsURI);
  2997. nsURI = NULL;
  2998. attrName = (char *)TtaStrdup ((char *)xmlName);
  2999. if (UnknownNS)
  3000. /* The corresponding element doesn't belong to a supported namespace */
  3001. {
  3002. snprintf ((char *)msgBuffer, MaxMsgLength,
  3003. "Namespace not supported for the attribute \"%s\"", (char *)xmlName);
  3004. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  3005. /* Create an unknown attribute */
  3006. UnknownXmlAttribute (attrName, NULL);
  3007. UnknownAttr = TRUE;
  3008. }
  3009. }
  3010. if (CurrentParserCtxt == NULL)
  3011. {
  3012. #ifdef XML_GENERIC
  3013. /* We assign the generic XML context by default */
  3014. CurrentParserCtxt = GenericXmlParserCtxt;
  3015. #else /* XML_GENERIC */
  3016. CurrentParserCtxt = savParserCtxt;
  3017. snprintf (msgBuffer, MaxMsgLength,
  3018. "Namespace not supported for the attribute \"%s\"",
  3019. (char *)xmlName);
  3020. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  3021. /* Create an unknown attribute */
  3022. UnknownXmlAttribute (attrName, nsURI);
  3023. UnknownAttr = TRUE;
  3024. #endif /* XML_GENERIC */
  3025. }
  3026. /* Is it a xml:space attribute */
  3027. if (strncmp (attrName, "xml:space", 9) == 0)
  3028. XMLSpaceAttribute = TRUE;
  3029. /* the attribute xml:lang is replaced by the attribute "lang" */
  3030. if (strncmp (attrName, "xml:lang", 8) == 0)
  3031. strcpy ((char *)attrName, "lang");
  3032. if (CurrentParserCtxt && !UnknownAttr)
  3033. {
  3034. if (strcmp ((char *)CurrentParserCtxt->SSchemaName, "HTML") == 0)
  3035. EndOfXhtmlAttributeName (attrName,
  3036. XMLcontext.lastElement, XMLcontext.doc);
  3037. else
  3038. EndOfXmlAttributeName (attrName, nsURI, XMLcontext.lastElement,
  3039. XMLcontext.doc);
  3040. }
  3041. TtaFreeMemory (nsURI);
  3042. TtaFreeMemory (attrName);
  3043. return;
  3044. }
  3045. /*----------------------------------------------------------------------
  3046. EndOfXmlAttributeValue
  3047. An attribute value has been read for a element that
  3048. doesn't belongs to XHTML DTD
  3049. ----------------------------------------------------------------------*/
  3050. static void EndOfXmlAttributeValue (char *attrValue)
  3051. {
  3052. AttributeType attrType;
  3053. int attrKind, val;
  3054. unsigned char msgBuffer[MaxMsgLength];
  3055. int length;
  3056. char *buffer, *name;
  3057. Language lang;
  3058. TtaGiveAttributeType (currentAttribute, &attrType, &attrKind);
  3059. switch (attrKind)
  3060. {
  3061. case 0: /* enumerate */
  3062. (*(Proc3)(CurrentParserCtxt->MapAttributeValue)) (
  3063. (void *)attrValue,
  3064. (void *)&attrType,
  3065. (void *)&val);
  3066. if (val <= 0)
  3067. {
  3068. snprintf ((char *)msgBuffer, MaxMsgLength,
  3069. "Unknown attribute value \"%s\"", (char *)attrValue);
  3070. XmlParseError (errorParsing, (unsigned char *)msgBuffer, 0);
  3071. }
  3072. else
  3073. TtaSetAttributeValue (currentAttribute, val,
  3074. XMLcontext.lastElement, XMLcontext.doc);
  3075. break;
  3076. case 1: /* integer */
  3077. sscanf (attrValue, "%d", &val);
  3078. TtaSetAttributeValue (currentAttribute, val,
  3079. XMLcontext.lastElement, XMLcontext.doc);
  3080. break;
  3081. case 2: /* text */
  3082. if (UnknownAttr)
  3083. {
  3084. /* This is the content of an invalid attribute */
  3085. /* Append it to the current Invalid_attribute */
  3086. length = strlen ((char *)attrValue) + 4;
  3087. length += TtaGetTextAttributeLength (currentAttribute);
  3088. buffer = (char *)TtaGetMemory (length + 1);
  3089. TtaGiveTextAttributeValue (currentAttribute,
  3090. buffer, &length);
  3091. strcat (buffer, "=\"");
  3092. strcat (buffer, attrValue);
  3093. strcat (buffer, "\"");
  3094. TtaSetAttributeText (currentAttribute, (char *)buffer,
  3095. XMLcontext.lastElement, XMLcontext.doc);
  3096. TtaFreeMemory (buffer);
  3097. }
  3098. else
  3099. {
  3100. TtaSetAttributeText (currentAttribute, (char *)attrValue,
  3101. XMLcontext.lastElement, XMLcontext.doc);
  3102. /* It's a style attribute */
  3103. if (HTMLStyleAttribute)
  3104. ParseHTMLSpecificStyle (XMLcontext.lastElement, attrValue,
  3105. XMLcontext.doc, 1000, FALSE);
  3106. /* it's a LANG attribute value */
  3107. if (attrType.AttrTypeNum == 1)
  3108. {
  3109. lang = TtaGetLanguageIdFromName (attrValue);
  3110. if (lang < 0)
  3111. {
  3112. snprintf ((char *)msgBuffer, MaxMsgLength,
  3113. "warning - unsupported language: %s", (char *)attrValue);
  3114. XmlParseError (warningMessage, (unsigned char *)msgBuffer, 0);
  3115. }
  3116. else
  3117. {
  3118. /* change current language */
  3119. XMLcontext.language = lang;
  3120. SetLanguagInXmlStack (lang);
  3121. }
  3122. }
  3123. #ifdef XML_GENERIC
  3124. else
  3125. {
  3126. /* check xml:id attributes */
  3127. name = TtaGetSSchemaName (attrType.AttrSSchema);
  3128. if (strcmp (name, "HTML") &&
  3129. strcmp (name, "MathML") &&
  3130. strcmp (name, "SVG") &&
  3131. attrType.AttrTypeNum == XML_ATTR_xmlid)
  3132. CheckUniqueName (XMLcontext.lastElement, XMLcontext.doc,
  3133. currentAttribute, attrType);
  3134. }
  3135. #endif /* XML_GENERIC */
  3136. }
  3137. break;
  3138. case 3: /* reference */
  3139. break;
  3140. }
  3141. if (CurrentParserCtxt != NULL && !HTMLStyleAttribute)
  3142. (*(Proc3)(CurrentParserCtxt->AttributeComplete)) (
  3143. (void *)currentAttribute,
  3144. (void *)XMLcontext.lastElement,
  3145. (void *)XMLcontext.doc);
  3146. }
  3147. /*----------------------------------------------------------------------
  3148. EndOfAttributeValue
  3149. An attribute value has been read from the parsed file.
  3150. Put that value in the current Thot attribute.
  3151. ----------------------------------------------------------------------*/
  3152. static void EndOfAttributeValue (unsigned char *attrValue,
  3153. unsigned char *attrName)
  3154. {
  3155. unsigned char *buffer;
  3156. char *bufferNS;
  3157. int length;
  3158. if ((lastMappedAttr || currentAttribute) && CurrentParserCtxt)
  3159. {
  3160. length = strlen ((char *)attrValue);
  3161. buffer = HandleXMLstring ((unsigned char *)attrValue, &length, NULL, FALSE);
  3162. /* White-space attribute */
  3163. if (XMLSpaceAttribute)
  3164. XmlWhiteSpaceInStack ((char *)buffer);
  3165. if (UnknownAttr)
  3166. {
  3167. /* This is the content of an invalid attribute */
  3168. /* Append it to the current Invalid_attribute */
  3169. length = strlen ((char *)attrValue) + 4;
  3170. length += TtaGetTextAttributeLength (currentAttribute);
  3171. bufferNS = (char *)TtaGetMemory (length + 1);
  3172. TtaGiveTextAttributeValue (currentAttribute,
  3173. bufferNS, &length);
  3174. strcat ((char *)bufferNS, "=\"");
  3175. strcat ((char *)bufferNS, (char *)attrValue);
  3176. strcat ((char *)bufferNS, "\"");
  3177. TtaSetAttributeText (currentAttribute, (char *)bufferNS,
  3178. XMLcontext.lastElement, XMLcontext.doc);
  3179. TtaFreeMemory (bufferNS);
  3180. }
  3181. else
  3182. {
  3183. if (strcmp ((char *)CurrentParserCtxt->SSchemaName, "HTML") == 0)
  3184. EndOfHTMLAttributeValue ((char *)buffer, lastMappedAttr,
  3185. currentAttribute, lastAttrElement,
  3186. UnknownAttr, &XMLcontext, TRUE);
  3187. else
  3188. EndOfXmlAttributeValue ((char *)buffer);
  3189. }
  3190. TtaFreeMemory (buffer);
  3191. }
  3192. currentAttribute = NULL;
  3193. HTMLStyleAttribute = FALSE;
  3194. XMLSpaceAttribute = FALSE;
  3195. }
  3196. /*-------------------- Attributes (end) ---------------------*/
  3197. /*-------------------- Entities (start) ---------------------*/
  3198. /*----------------------------------------------------------------------
  3199. CreateXmlEntity
  3200. Search the entity in the right entity table and
  3201. put the corresponding character in the current element.
  3202. ----------------------------------------------------------------------*/
  3203. static void CreateXmlEntity (char *data, int length)
  3204. {
  3205. unsigned char *buffer;
  3206. data[0] = START_ENTITY;
  3207. buffer = (unsigned char *)HandleXMLstring ((unsigned char *)data, &length, XMLcontext.lastElement, TRUE);
  3208. TtaFreeMemory (buffer);
  3209. }
  3210. /*-------------------- Entities (end) ---------------------*/
  3211. /*-------------------- Doctype (start) ---------------------*/
  3212. /*----------------------------------------------------------------------
  3213. ParseDoctypeContent
  3214. Parse the content of a DOCTYPE declaration
  3215. -------------------------------------- -------------------------------*/
  3216. static void ParseDoctypeContent (const char *data, int length)
  3217. {
  3218. ElementType elType;
  3219. Element doctypeLine, doctypeLeaf, doctypeLineNew, lastChild;
  3220. char *mappedName;
  3221. char cont;
  3222. ThotBool level = TRUE;
  3223. unsigned char *buffer;
  3224. int i, j;
  3225. /* get the last Doctype_line element */
  3226. doctypeLine = TtaGetLastChild (XMLcontext.lastElement);
  3227. if (doctypeLine == NULL)
  3228. return;
  3229. buffer = (unsigned char *)TtaGetMemory (length + 1);
  3230. i = 0;
  3231. j = 0;
  3232. while (i < length)
  3233. {
  3234. /* Look for line breaks in the content and create */
  3235. /* as many DOCTYPE_line elements as needed */
  3236. if (data[i] != EOL && data[i] != __CR__)
  3237. {
  3238. buffer[j] = data[i];
  3239. j++;
  3240. }
  3241. else if (data[i] == __CR__ && i < length-1 && data[i+1] == EOL)
  3242. {
  3243. /* ignoring CR in a CR/LF sequence */
  3244. }
  3245. else
  3246. {
  3247. buffer[j] = EOS;
  3248. j = 0;
  3249. elType = TtaGetElementType (doctypeLine);
  3250. elType.ElTypeNum = 1;
  3251. doctypeLeaf = TtaNewElement (XMLcontext.doc, elType);
  3252. if (doctypeLeaf != NULL)
  3253. {
  3254. XmlSetElemLineNumber (doctypeLeaf);
  3255. /* get the position of the Doctype text */
  3256. lastChild = TtaGetLastChild (doctypeLine);
  3257. if (lastChild == NULL)
  3258. TtaInsertFirstChild (&doctypeLeaf, doctypeLine, XMLcontext.doc);
  3259. else
  3260. TtaInsertSibling (doctypeLeaf, lastChild,
  3261. FALSE, XMLcontext.doc);
  3262. /* We use the Latin_Script language to avoid the spell_chekcer */
  3263. /* to check this element */
  3264. TtaSetTextContent (doctypeLeaf, (unsigned char *)buffer, Latin_Script, XMLcontext.doc);
  3265. }
  3266. /* Create a new DOCTYPE_line element */
  3267. elType.ElSSchema = NULL;
  3268. elType.ElTypeNum = 0;
  3269. GetXmlElType (NULL, "doctype_line", &elType, &mappedName, &cont, &level);
  3270. doctypeLineNew = TtaNewElement (XMLcontext.doc, elType);
  3271. if (doctypeLineNew != NULL)
  3272. {
  3273. XmlSetElemLineNumber (doctypeLineNew);
  3274. TtaInsertSibling (doctypeLineNew, doctypeLine, FALSE, XMLcontext.doc);
  3275. doctypeLine = doctypeLineNew;
  3276. }
  3277. }
  3278. i++;
  3279. }
  3280. buffer [j] = EOS;
  3281. elType = TtaGetElementType (doctypeLine);
  3282. elType.ElTypeNum = 1;
  3283. doctypeLeaf = TtaNewElement (XMLcontext.doc, elType);
  3284. if (doctypeLeaf != NULL)
  3285. {
  3286. XmlSetElemLineNumber (doctypeLeaf);
  3287. /* get the position of the Doctype text */
  3288. lastChild = TtaGetLastChild (doctypeLine);
  3289. if (lastChild == NULL)
  3290. TtaInsertFirstChild (&doctypeLeaf, doctypeLine, XMLcontext.doc);
  3291. else
  3292. TtaInsertSibling (doctypeLeaf, lastChild, FALSE, XMLcontext.doc);
  3293. /* We use the Latin_Script language to avoid */
  3294. /* the spell_checker to check this element */
  3295. TtaSetTextContent (doctypeLeaf, (unsigned char *)buffer, Latin_Script, XMLcontext.doc);
  3296. }
  3297. TtaFreeMemory (buffer);
  3298. }
  3299. /*----------------------------------------------------------------------
  3300. CreateDoctypeElement
  3301. Create a Doctype element into the Thot tree.
  3302. ----------------------------------------------------------------------*/
  3303. static void CreateDoctypeElement (char *name, char *sysid, char *pubid)
  3304. {
  3305. ElementType elType, lineType;
  3306. Element doctype, doctypeLine, doctypeLeaf, doctypeLineNew, lastChild;
  3307. char *mappedName, *buffer;
  3308. char cont;
  3309. ThotBool level = TRUE;
  3310. /* Create a DOCTYPE element */
  3311. elType.ElSSchema = NULL;
  3312. elType.ElTypeNum = 0;
  3313. GetXmlElType (NULL, "doctype", &elType, &mappedName, &cont, &level);
  3314. if (elType.ElTypeNum > 0)
  3315. {
  3316. doctype = TtaNewElement (XMLcontext.doc, elType);
  3317. XmlSetElemLineNumber (doctype);
  3318. InsertXmlElement (&doctype);
  3319. /* Make the DOCTYPE element read-only */
  3320. TtaSetAccessRight (doctype, ReadOnly, XMLcontext.doc);
  3321. /* Create a DOCTYPE_line element as first child */
  3322. lineType.ElSSchema = NULL;
  3323. lineType.ElTypeNum = 0;
  3324. GetXmlElType (NULL, "doctype_line", &lineType, &mappedName, &cont, &level);
  3325. doctypeLine = TtaNewElement (XMLcontext.doc, lineType);
  3326. XmlSetElemLineNumber (doctypeLine);
  3327. TtaInsertFirstChild (&doctypeLine, doctype, XMLcontext.doc);
  3328. /* Create the DOCTYPE leaf */
  3329. elType.ElSSchema = lineType.ElSSchema;
  3330. elType.ElTypeNum = 1;
  3331. doctypeLeaf = TtaNewElement (XMLcontext.doc, elType);
  3332. if (doctypeLeaf != NULL)
  3333. {
  3334. XmlSetElemLineNumber (doctypeLeaf);
  3335. TtaInsertFirstChild (&doctypeLeaf, doctypeLine, XMLcontext.doc);
  3336. /* We use the Latin_Script language to avoid */
  3337. /* the spell_chekcer to check this element */
  3338. TtaSetTextContent (doctypeLeaf, (unsigned char *)"<!DOCTYPE ",
  3339. Latin_Script, XMLcontext.doc);
  3340. TtaCancelSelection (XMLcontext.doc); /* TtaSetTextContent added a selection */
  3341. }
  3342. if (name != NULL)
  3343. {
  3344. elType.ElSSchema = lineType.ElSSchema;
  3345. elType.ElTypeNum = 1;
  3346. doctypeLeaf = TtaNewElement (XMLcontext.doc, elType);
  3347. if (doctypeLeaf != NULL)
  3348. {
  3349. XmlSetElemLineNumber (doctypeLeaf);
  3350. lastChild = TtaGetLastChild (doctypeLine);
  3351. if (lastChild == NULL)
  3352. TtaInsertFirstChild (&doctypeLeaf, doctypeLine, XMLcontext.doc);
  3353. else
  3354. TtaInsertSibling (doctypeLeaf, lastChild,
  3355. FALSE, XMLcontext.doc);
  3356. TtaSetTextContent (doctypeLeaf, (unsigned char *)name, Latin_Script, XMLcontext.doc);
  3357. TtaCancelSelection (XMLcontext.doc); /* TtaSetTextContent added a selection */
  3358. }
  3359. }
  3360. /* Is there any external DTD ? */
  3361. if (pubid != NULL)
  3362. {
  3363. elType.ElSSchema = lineType.ElSSchema;
  3364. elType.ElTypeNum = 1;
  3365. doctypeLeaf = TtaNewElement (XMLcontext.doc, elType);
  3366. if (doctypeLeaf != NULL)
  3367. {
  3368. buffer = (char *)TtaGetMemory (strlen ((char *)pubid) + 11);
  3369. strcpy ((char *)buffer, " PUBLIC \"");
  3370. strcat ((char *)buffer, (char *)pubid);
  3371. strcat ((char *)buffer, "\"");
  3372. XmlSetElemLineNumber (doctypeLeaf);
  3373. lastChild = TtaGetLastChild (doctypeLine);
  3374. if (lastChild == NULL)
  3375. TtaInsertFirstChild (&doctypeLeaf, doctypeLine, XMLcontext.doc);
  3376. else
  3377. TtaInsertSibling (doctypeLeaf, lastChild,
  3378. FALSE, XMLcontext.doc);
  3379. TtaSetTextContent (doctypeLeaf, (unsigned char *)buffer, Latin_Script, XMLcontext.doc);
  3380. TtaCancelSelection (XMLcontext.doc); /* TtaSetTextContent added a selection */
  3381. TtaFreeMemory (buffer);
  3382. }
  3383. }
  3384. if (sysid != NULL)
  3385. {
  3386. /* Create a new DOCTYPE_line element */
  3387. if (pubid)
  3388. {
  3389. doctypeLineNew = TtaNewElement (XMLcontext.doc, lineType);
  3390. if (doctypeLineNew != NULL)
  3391. {
  3392. XmlSetElemLineNumber (doctypeLineNew);
  3393. TtaInsertSibling (doctypeLineNew, doctypeLine,
  3394. FALSE, XMLcontext.doc);
  3395. doctypeLine = doctypeLineNew;
  3396. }
  3397. }
  3398. elType.ElSSchema = lineType.ElSSchema;
  3399. elType.ElTypeNum = 1;
  3400. doctypeLeaf = TtaNewElement (XMLcontext.doc, elType);
  3401. if (doctypeLeaf != NULL)
  3402. {
  3403. XmlSetElemLineNumber (doctypeLeaf);
  3404. lastChild = TtaGetLastChild (doctypeLine);
  3405. if (lastChild == NULL)
  3406. TtaInsertFirstChild (&doctypeLeaf, doctypeLine, XMLcontext.doc);
  3407. else
  3408. TtaInsertSibling (doctypeLeaf, lastChild,
  3409. FALSE, XMLcontext.doc);
  3410. buffer = (char *)TtaGetMemory (strlen ((char *)sysid) + 11);
  3411. if (pubid)
  3412. strcpy ((char *)buffer, " \"");
  3413. else
  3414. strcpy ((char *)buffer, " SYSTEM \"");
  3415. strcat (buffer, sysid);
  3416. strcat (buffer, "\"");
  3417. TtaSetTextContent (doctypeLeaf, (unsigned char *)buffer, Latin_Script, XMLcontext.doc);
  3418. TtaCancelSelection (XMLcontext.doc); /* TtaSetTextContent added a selection */
  3419. TtaFreeMemory (buffer);
  3420. }
  3421. }
  3422. }
  3423. }
  3424. /*-------------------- Doctype (end) ------------------------------*/
  3425. /*-------------------- CDATA (start) ---------------------*/
  3426. /*----------------------------------------------------------------------
  3427. ParseCdataElement
  3428. Parse the content of a CDATA element
  3429. -------------------------------------- -------------------------------*/
  3430. static void ParseCdataElement (char *data, int length)
  3431. {
  3432. ElementType elType;
  3433. Element cdataLine, cdataLeaf, cdataLineNew, lastChild;
  3434. char *mappedName;
  3435. char cont;
  3436. ThotBool level = TRUE;
  3437. unsigned char *buffer;
  3438. int i, j;
  3439. buffer = (unsigned char *)TtaGetMemory (length + 1);
  3440. i = 0, j = 0;
  3441. /* get the last cdata_line element */
  3442. cdataLine = TtaGetLastChild (XMLcontext.lastElement);
  3443. if (cdataLine == NULL)
  3444. return;
  3445. /* Remove the leading spaces */
  3446. if (RemoveLeadingSpace)
  3447. {
  3448. while (data[i] == TAB || data[i] == SPACE)
  3449. i++;
  3450. }
  3451. while (i < length)
  3452. {
  3453. /* Look for line breaks in the content and create as many */
  3454. /* cdata_line elements as needed */
  3455. if (data[i] != EOL && data[i] != __CR__)
  3456. {
  3457. /* Collapse contiguous spaces */
  3458. if (!RemoveContiguousSpace ||
  3459. !((data[i] == TAB || data[i] == SPACE) &&
  3460. (buffer[j-1] == TAB || buffer[j-1] == SPACE)))
  3461. buffer[j] = data[i];
  3462. j++;
  3463. }
  3464. else if (data[i] == __CR__ && i < length-1 && data[i+1] == EOL)
  3465. {
  3466. /* ignoring CR in a CR/LF sequence */
  3467. }
  3468. else
  3469. {
  3470. buffer[j] = EOS;
  3471. j = 0;
  3472. if (buffer[0] != EOS)
  3473. {
  3474. elType = TtaGetElementType (cdataLine);
  3475. elType.ElTypeNum = 1;
  3476. cdataLeaf = TtaNewElement (XMLcontext.doc, elType);
  3477. if (cdataLeaf != NULL)
  3478. {
  3479. XmlSetElemLineNumber (cdataLeaf);
  3480. /* get the position of the cdata text */
  3481. lastChild = TtaGetLastChild (cdataLine);
  3482. if (lastChild == NULL)
  3483. TtaInsertFirstChild (&cdataLeaf, cdataLine, XMLcontext.doc);
  3484. else
  3485. TtaInsertSibling (cdataLeaf, lastChild,
  3486. FALSE, XMLcontext.doc);
  3487. TtaSetTextContent (cdataLeaf, (unsigned char *)buffer,
  3488. XMLcontext.language, XMLcontext.doc);
  3489. }
  3490. }
  3491. /* Create a new cdata_line element */
  3492. elType.ElSSchema = NULL;
  3493. elType.ElTypeNum = 0;
  3494. GetXmlElType (NULL, "cdata_line", &elType, &mappedName, &cont, &level);
  3495. cdataLineNew = TtaNewElement (XMLcontext.doc, elType);
  3496. if (cdataLineNew != NULL)
  3497. {
  3498. XmlSetElemLineNumber (cdataLineNew);
  3499. TtaInsertSibling (cdataLineNew, cdataLine, FALSE, XMLcontext.doc);
  3500. cdataLine = cdataLineNew;
  3501. }
  3502. }
  3503. i++;
  3504. }
  3505. if (j > 0)
  3506. {
  3507. buffer [j] = EOS;
  3508. elType = TtaGetElementType (cdataLine);
  3509. elType.ElTypeNum = 1;
  3510. cdataLeaf = TtaNewElement (XMLcontext.doc, elType);
  3511. if (cdataLeaf != NULL)
  3512. {
  3513. XmlSetElemLineNumber (cdataLeaf);
  3514. /* get the position of the cdata text */
  3515. lastChild = TtaGetLastChild (cdataLine);
  3516. if (lastChild == NULL)
  3517. TtaInsertFirstChild (&cdataLeaf, cdataLine, XMLcontext.doc);
  3518. else
  3519. TtaInsertSibling (cdataLeaf, lastChild,
  3520. FALSE, XMLcontext.doc);
  3521. TtaSetTextContent (cdataLeaf, (unsigned char *)buffer,
  3522. XMLcontext.language, XMLcontext.doc);
  3523. }
  3524. }
  3525. TtaFreeMemory (buffer);
  3526. }
  3527. /*----------------------------------------------------------------------
  3528. CreateCdataElement
  3529. Create a CDATA element into the Thot tree.
  3530. ----------------------------------------------------------------------*/
  3531. static void CreateCdataElement ()
  3532. {
  3533. ElementType elType;
  3534. Element cdataEl, cdataLineEl;
  3535. char *mappedName;
  3536. char cont;
  3537. ThotBool level = TRUE;
  3538. /* Create a CDATA element */
  3539. elType.ElSSchema = NULL;
  3540. elType.ElTypeNum = 0;
  3541. GetXmlElType (NULL, "cdata", &elType, &mappedName, &cont, &level);
  3542. if (elType.ElTypeNum > 0)
  3543. {
  3544. cdataEl = TtaNewElement (XMLcontext.doc, elType);
  3545. XmlSetElemLineNumber (cdataEl);
  3546. InsertXmlElement (&cdataEl);
  3547. /* Create a cdata_line element as first child */
  3548. elType.ElSSchema = NULL;
  3549. elType.ElTypeNum = 0;
  3550. GetXmlElType (NULL, "cdata_line", &elType, &mappedName, &cont, &level);
  3551. cdataLineEl = TtaNewElement (XMLcontext.doc, elType);
  3552. XmlSetElemLineNumber (cdataLineEl);
  3553. TtaInsertFirstChild (&cdataLineEl, cdataEl, XMLcontext.doc);
  3554. }
  3555. }
  3556. /*-------------------- CDATA (end) ------------------------------*/
  3557. /*-------------------- Comments (start) ---------------------*/
  3558. /*----------------------------------------------------------------------
  3559. CreateXmlComment
  3560. Create a comment element into the Thot tree.
  3561. ----------------------------------------------------------------------*/
  3562. static void CreateXmlComment (char *commentValue)
  3563. {
  3564. ElementType elType, elTypeLeaf;
  3565. Element commentEl, commentLineEl, commentLeaf, lastChild;
  3566. char *mappedName;
  3567. char cont;
  3568. unsigned char *buffer;
  3569. unsigned char *ptr;
  3570. int length, l;
  3571. int i, j, error;
  3572. ThotBool level = TRUE;
  3573. char *ptrComment;
  3574. /* Skip the comments automatically generated by Amaya */
  3575. ExtraPI = FALSE;
  3576. ptrComment = strstr (commentValue, "generated by Amaya");
  3577. if (ptrComment)
  3578. {
  3579. ExtraPI = TRUE;
  3580. return;
  3581. }
  3582. /* Create a Thot element for the comment */
  3583. elType.ElSSchema = NULL;
  3584. elType.ElTypeNum = 0;
  3585. GetXmlElType (CurrentParserCtxt->UriName, "xmlcomment",
  3586. &elType, &mappedName, &cont, &level);
  3587. if (elType.ElTypeNum > 0)
  3588. {
  3589. commentEl = TtaNewElement (XMLcontext.doc, elType);
  3590. XmlSetElemLineNumber (commentEl);
  3591. InsertXmlElement (&commentEl);
  3592. /* Create a XMLcomment_line element as the first child of */
  3593. /* Element XMLcomment */
  3594. elType.ElSSchema = NULL;
  3595. elType.ElTypeNum = 0;
  3596. GetXmlElType (CurrentParserCtxt->UriName, "xmlcomment_line",
  3597. &elType, &mappedName, &cont, &level);
  3598. commentLineEl = TtaNewElement (XMLcontext.doc, elType);
  3599. XmlSetElemLineNumber (commentLineEl);
  3600. TtaInsertFirstChild (&commentLineEl, commentEl, XMLcontext.doc);
  3601. length = strlen ((char *)commentValue);
  3602. i = 0;
  3603. j = 0; /* parsed length */
  3604. ptr = (unsigned char *)&commentValue[i];
  3605. while (i <= length)
  3606. {
  3607. /* Look for line break in the comment and create as many */
  3608. /* XMLcomment_line elements as needed */
  3609. if (commentValue[i] != EOL && commentValue[i] != __CR__ &&
  3610. commentValue[i] != EOS)
  3611. i++;
  3612. else
  3613. {
  3614. /* get the position of the comment text */
  3615. lastChild = TtaGetLastChild (commentLineEl);
  3616. l = i - j;
  3617. /* handles UTF-8 characters and entities in the subtree */
  3618. buffer = HandleXMLstring ((unsigned char *)ptr, &l, commentLineEl, FALSE);
  3619. /* Put the current content into a text comment line */
  3620. elTypeLeaf.ElSSchema = elType.ElSSchema;
  3621. elTypeLeaf.ElTypeNum = 1;
  3622. commentLeaf = TtaNewElement (XMLcontext.doc, elTypeLeaf);
  3623. XmlSetElemLineNumber (commentLeaf);
  3624. if (lastChild == NULL)
  3625. TtaInsertFirstChild (&commentLeaf, commentLineEl,
  3626. XMLcontext.doc);
  3627. else
  3628. TtaInsertSibling (commentLeaf, lastChild,
  3629. FALSE, XMLcontext.doc);
  3630. TtaSetTextContent (commentLeaf, (unsigned char *)buffer,
  3631. XMLcontext.language, XMLcontext.doc);
  3632. TtaFreeMemory (buffer);
  3633. j += l;
  3634. i = j;
  3635. /* check if a new line has to be generated */
  3636. if (commentValue[i] == EOL || commentValue[i] == __CR__)
  3637. {
  3638. /* Create a new XMLcomment_line element */
  3639. commentLineEl = TtaNewElement (XMLcontext.doc, elType);
  3640. XmlSetElemLineNumber (commentLineEl);
  3641. /* Inserts the new XMLcomment_line after the previous one */
  3642. TtaInsertSibling (commentLineEl, TtaGetParent (commentLeaf),
  3643. FALSE, XMLcontext.doc);
  3644. j++;
  3645. }
  3646. i++;
  3647. ptr = (unsigned char *)&commentValue[i];
  3648. }
  3649. }
  3650. (*(Proc3)(CurrentParserCtxt->ElementComplete)) (
  3651. (void *)&XMLcontext,
  3652. (void *)commentEl,
  3653. (void *)&error);
  3654. XMLcontext.lastElementClosed = TRUE;
  3655. }
  3656. }
  3657. /*-------------------- Comments (end) ------------------------------*/
  3658. /*-------------------- PI (start) ----------------------------------*/
  3659. /*----------------------------------------------------------------------
  3660. LoadXmlStyleSheet
  3661. ---------------------------------------------------------------------*/
  3662. static void LoadXmlStyleSheet (Document doc)
  3663. {
  3664. int i;
  3665. char *ptr;
  3666. ThotBool loadcss;
  3667. TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
  3668. if (!loadcss)
  3669. return;
  3670. for (i = 0; i < XML_CSS_Level; i++)
  3671. {
  3672. if (XML_CSS_Href[i] && !strncasecmp (XML_CSS_Href[i], "data:", 5))
  3673. {
  3674. ptr = &XML_CSS_Href[i][5];
  3675. if (!strncasecmp (ptr, "text/css", 8))
  3676. /* confirm that it's a CSS stylesheet (see rfc2397) */
  3677. ptr += 8;
  3678. if (*ptr == ';')
  3679. do
  3680. ptr++;
  3681. while (*ptr != ',' && *ptr != EOS);
  3682. if (*ptr == ',')
  3683. ReadCSSRules (XML_CSS_Doc[i], NULL, &ptr[9], NULL,
  3684. TtaGetElementLineNumber (XML_CSS_El[i]), FALSE,
  3685. XML_CSS_El[i]);
  3686. }
  3687. else
  3688. LoadStyleSheet (XML_CSS_Href[i], XML_CSS_Doc[i],
  3689. XML_CSS_El[i], NULL, NULL,
  3690. XML_CSS_Media[i], FALSE);
  3691. }
  3692. }
  3693. /*----------------------------------------------------------------------
  3694. XmlStyleSheetPi
  3695. ---------------------------------------------------------------------*/
  3696. void XmlStyleSheetPi (char *PiData, Element piEl)
  3697. {
  3698. int length, i, j;
  3699. char *ptr, *end;
  3700. char *buffer;
  3701. char *css_href = NULL;
  3702. char delimitor;
  3703. CSSmedia css_media;
  3704. CSSInfoPtr css_info;
  3705. ThotBool ok;
  3706. ElementType elType;
  3707. Attribute attr_css;
  3708. AttributeType attrType;
  3709. length = strlen ((char *)PiData);
  3710. buffer = (char *)TtaGetMemory (length + 1);
  3711. i = 0; j = 0;
  3712. css_media = CSS_ALL;
  3713. /* get the "type" attribute */
  3714. ok = FALSE;
  3715. end = NULL;
  3716. strcpy ((char *)buffer, (char *)PiData);
  3717. ptr = strstr (buffer, "type");
  3718. if (ptr)
  3719. {
  3720. ptr = strstr (ptr, "=");
  3721. ptr++;
  3722. while (ptr[0] != EOS && ptr[0] == ' ')
  3723. ptr++;
  3724. if (ptr[0] != EOS)
  3725. {
  3726. delimitor = ptr[0];
  3727. end = strchr (&ptr[1], delimitor);
  3728. if (end && end[0] != EOS)
  3729. {
  3730. end[0] = EOS;
  3731. if (!strcmp ((char *)&ptr[1], "text/css"))
  3732. ok = TRUE;
  3733. }
  3734. }
  3735. }
  3736. /* Warnings about PI are no longer reported */
  3737. /*
  3738. if (!ok)
  3739. {
  3740. char msgBuffer[MaxMsgLength];
  3741. sprintf (msgBuffer,
  3742. "xml-stylesheet : attribute \"type\" not defined or not supported");
  3743. XmlParseError (errorParsing, msgBuffer, 0);
  3744. }
  3745. */
  3746. if (ok)
  3747. {
  3748. /* get the "media" attribute */
  3749. end = NULL;
  3750. strcpy ((char *)buffer, (char *)PiData);
  3751. ptr = strstr (buffer, "media");
  3752. if (ptr)
  3753. {
  3754. ptr = strstr (ptr, "=");
  3755. ptr++;
  3756. /* skip spaces */
  3757. while (*ptr != EOS && *ptr == ' ')
  3758. ptr++;
  3759. if (*ptr != EOS)
  3760. {
  3761. /* locate delimitors */
  3762. delimitor = *ptr;
  3763. end = strchr (&ptr[1], delimitor);
  3764. if (end && *end != EOS)
  3765. {
  3766. *end = EOS;
  3767. css_media = CheckMediaCSS (&ptr[1]);
  3768. }
  3769. }
  3770. }
  3771. }
  3772. if (ok)
  3773. {
  3774. /* get the "href" attribute */
  3775. end = NULL;
  3776. strcpy ((char *)buffer, (char *)PiData);
  3777. ptr = strstr (buffer, "href");
  3778. if (ptr)
  3779. {
  3780. ptr = strstr (ptr, "=");
  3781. ptr++;
  3782. while (ptr[0] != EOS && ptr[0] == ' ')
  3783. ptr++;
  3784. if (ptr[0] != EOS &&
  3785. /* don't manage a document used by make book */
  3786. (DocumentMeta[XMLcontext.doc] == NULL ||
  3787. DocumentMeta[XMLcontext.doc]->method != CE_MAKEBOOK))
  3788. {
  3789. delimitor = ptr[0];
  3790. css_href = (char *)TtaGetMemory (length + 1);
  3791. end = strchr (&ptr[1], delimitor);
  3792. if (end && end[0] != EOS && css_href)
  3793. {
  3794. end[0] = EOS;
  3795. strcpy ((char *)css_href, (char *)&ptr[1]);
  3796. css_info = NULL;
  3797. /* get the CSS URI in UTF-8 */
  3798. /*css_href = ReallocUTF8String (css_href, XMLcontext.doc);*/
  3799. /* load the stylesheet file found here ! */
  3800. ptr = (char *)TtaConvertMbsToByte ((unsigned char *)css_href,
  3801. TtaGetDefaultCharset ());
  3802. if (ptr)
  3803. {
  3804. TtaFreeMemory (css_href);
  3805. css_href = ptr;
  3806. }
  3807. /* Don't apply immediately the style sheet for XML schemas */
  3808. elType = TtaGetElementType (piEl);
  3809. if (((strcmp (TtaGetSSchemaName (elType.ElSSchema), "XML") == 0) ||
  3810. TtaIsXmlSSchema (elType.ElSSchema)) &&
  3811. XML_CSS_Level < MAX_NS_TABLE)
  3812. {
  3813. XML_CSS_Href [XML_CSS_Level] = TtaStrdup (css_href);
  3814. XML_CSS_Doc [XML_CSS_Level] = XMLcontext.doc;
  3815. XML_CSS_El [XML_CSS_Level] = piEl;
  3816. XML_CSS_Media [XML_CSS_Level] = css_media;
  3817. XML_CSS_Level++;
  3818. }
  3819. else
  3820. {
  3821. LoadStyleSheet (css_href, XMLcontext.doc, piEl,
  3822. css_info, NULL, css_media, FALSE);
  3823. /* Create a specific attribute for XHTML documents */
  3824. if (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0)
  3825. {
  3826. attrType.AttrSSchema = elType.ElSSchema;
  3827. attrType.AttrTypeNum = HTML_ATTR_is_css;
  3828. attr_css = TtaGetAttribute (piEl, attrType);
  3829. if (!attr_css)
  3830. {
  3831. attr_css = TtaNewAttribute (attrType);
  3832. TtaAttachAttribute (piEl, attr_css, XMLcontext.doc);
  3833. TtaSetAttributeText (attr_css, (char *)"text/css",
  3834. piEl, XMLcontext.doc);
  3835. }
  3836. }
  3837. }
  3838. }
  3839. TtaFreeMemory (css_href);
  3840. }
  3841. }
  3842. }
  3843. TtaFreeMemory (buffer);
  3844. }
  3845. /*----------------------------------------------------------------------
  3846. CreateXmlPi
  3847. Create a Processing Instruction element into the Thot tree.
  3848. ---------------------------------------------------------------------*/
  3849. static void CreateXmlPi (char *piTarget, char *piData)
  3850. {
  3851. ElementType elType, elTypeLeaf;
  3852. Element piEl, piLineEl, piLeaf, lastChild;
  3853. char *mappedName;
  3854. char *piValue = NULL;
  3855. char cont;
  3856. unsigned char *buffer;
  3857. unsigned char *ptr;
  3858. int length, l;
  3859. int i, j, error;
  3860. ThotBool level = TRUE;
  3861. char *ptrPi;
  3862. /* Skip the xsl stylesheet automatically generated by Amaya */
  3863. ptrPi = strstr (piData, MATHML_XSLT_NAME);
  3864. if (ptrPi && ExtraPI)
  3865. {
  3866. ExtraPI = FALSE;
  3867. return;
  3868. }
  3869. /* Create a Thot element for the PI */
  3870. elType.ElSSchema = NULL;
  3871. elType.ElTypeNum = 0;
  3872. GetXmlElType (NULL, "xmlpi", &elType, &mappedName, &cont, &level);
  3873. if (elType.ElTypeNum > 0)
  3874. {
  3875. piEl = TtaNewElement (XMLcontext.doc, elType);
  3876. XmlSetElemLineNumber (piEl);
  3877. InsertXmlElement (&piEl);
  3878. /* Create a XMLPI_line element as the first child of element XMLPI */
  3879. elType.ElSSchema = NULL;
  3880. elType.ElTypeNum = 0;
  3881. GetXmlElType (NULL, "xmlpi_line", &elType, &mappedName, &cont, &level);
  3882. piLineEl = TtaNewElement (XMLcontext.doc, elType);
  3883. XmlSetElemLineNumber (piLineEl);
  3884. TtaInsertFirstChild (&piLineEl, piEl, XMLcontext.doc);
  3885. length = strlen ((char *)piTarget) + strlen ((char *)piData);
  3886. length++;
  3887. piValue = (char *)TtaGetMemory (length + 2);
  3888. strcpy ((char *)piValue, (char *)piTarget);
  3889. strcat ((char *)piValue, " ");
  3890. strcat ((char *)piValue, (char *)piData);
  3891. i = 0;
  3892. j = 0; /* parsed length */
  3893. ptr = (unsigned char *)&piValue[i];
  3894. while (i <= length)
  3895. {
  3896. /* Look for line break in the pi and create as many */
  3897. /* XMLpi_line elements as needed */
  3898. if (piValue[i] != EOL && piValue[i] != __CR__ &&
  3899. piValue[i] != EOS)
  3900. i++;
  3901. else
  3902. {
  3903. /* get the position of the text element */
  3904. lastChild = TtaGetLastChild (piLineEl);
  3905. l = i - j;
  3906. /* handles UTF-8 characters and entities in the subtree */
  3907. buffer = HandleXMLstring ((unsigned char *)ptr, &l, piLineEl, FALSE);
  3908. if (buffer[0] != EOS)
  3909. {
  3910. /* Put the current content into a text element */
  3911. elTypeLeaf.ElSSchema = elType.ElSSchema;
  3912. elTypeLeaf.ElTypeNum = 1;
  3913. piLeaf = TtaNewElement (XMLcontext.doc, elTypeLeaf);
  3914. XmlSetElemLineNumber (piLeaf);
  3915. if (lastChild == NULL)
  3916. TtaInsertFirstChild (&piLeaf, piLineEl, XMLcontext.doc);
  3917. else
  3918. TtaInsertSibling (piLeaf, lastChild,
  3919. FALSE, XMLcontext.doc);
  3920. /* We use the Latin_Script language to avoid the spell_chekcer */
  3921. /* to check this element */
  3922. TtaSetTextContent (piLeaf, (unsigned char *)buffer, Latin_Script, XMLcontext.doc);
  3923. }
  3924. TtaFreeMemory (buffer);
  3925. j += l;
  3926. i = j;
  3927. /* check if a new line has to be generated */
  3928. if (piValue[i] == EOL || piValue[i] == __CR__)
  3929. {
  3930. /* Create a new XMLpi_line element */
  3931. piLineEl = TtaNewElement (XMLcontext.doc, elType);
  3932. XmlSetElemLineNumber (piLineEl);
  3933. /* Inserts the new XMLpi_line after the previous one */
  3934. TtaInsertSibling (piLineEl, TtaGetParent (piLeaf),
  3935. FALSE, XMLcontext.doc);
  3936. j++;
  3937. }
  3938. i++;
  3939. ptr = (unsigned char *)&piValue[i];
  3940. }
  3941. }
  3942. (*(Proc3)(CurrentParserCtxt->ElementComplete)) (
  3943. (void *)&XMLcontext,
  3944. (void *)piEl,
  3945. (void *)&error);
  3946. XMLcontext.lastElementClosed = TRUE;
  3947. TtaFreeMemory (piValue);
  3948. }
  3949. /* Call the treatment associated to that PI */
  3950. /* For the moment, Amaya only supports the "xml-stylesheet" PI */
  3951. if (!strcmp ((char *)piTarget, "xml-stylesheet"))
  3952. XmlStyleSheetPi (piData, piEl);
  3953. #ifdef TEMPLATES
  3954. else if (!strcmp ((char *)piTarget, "xtiger"))
  3955. {
  3956. Element root;
  3957. // Lock the root of a template instance */
  3958. root = TtaGetMainRoot (XMLcontext.doc);
  3959. TtaSetAccessRight (root, ReadOnly, XMLcontext.doc);
  3960. }
  3961. #endif /* TEMPLATES */
  3962. /* Warnings about PI are no longer reported */
  3963. }
  3964. /*-------------------- PI (end) ---------------------------------*/
  3965. /*----------- EXPAT handlers associated with Amaya ---------------*/
  3966. /*--------------------------------------------------------------------
  3967. Hndl_CdataStart
  3968. Handlers that get called at the beginning of a CDATA section
  3969. ------------------------------------------------------------------*/
  3970. static void Hndl_CdataStart (void *userData)
  3971. {
  3972. #ifdef EXPAT_PARSER_DEBUG
  3973. printf ("Hndl_CdataStart\n");
  3974. #endif /* EXPAT_PARSER_DEBUG */
  3975. /* The content of the current element has not to be parsed */
  3976. ParsingCDATA = TRUE;
  3977. CreateCdataElement ();
  3978. }
  3979. /*----------------------------------------------------------------------
  3980. Hndl_CdataEnd
  3981. Handlers that get called at the end of a CDATA section
  3982. ----------------------------------------------------------------------*/
  3983. static void Hndl_CdataEnd (void *userData)
  3984. {
  3985. #ifdef EXPAT_PARSER_DEBUG
  3986. printf ("Hndl_CdataEnd\n");
  3987. #endif /* EXPAT_PARSER_DEBUG */
  3988. /* The content of the current element has not to be parsed */
  3989. ParsingCDATA = FALSE;
  3990. XMLcontext.lastElementClosed = TRUE;
  3991. }
  3992. /*----------------------------------------------------------------------
  3993. Hndl_CharacterData
  3994. Handler for the text
  3995. The string the handler receives is NOT zero terminated.
  3996. We have to use the length argument to deal with the end of the string.
  3997. ----------------------------------------------------------------------*/
  3998. static void Hndl_CharacterData (void *userData, const XML_Char *data,
  3999. int length)
  4000. {
  4001. unsigned char *buffer, *ptr;
  4002. #ifdef EXPAT_PARSER_DEBUG
  4003. printf ("Hndl_CharacterData - length = %d - \n", length);
  4004. #endif /* EXPAT_PARSER_DEBUG */
  4005. /* The content of the current element has not to be parsed */
  4006. if (ParsingCDATA)
  4007. ParseCdataElement ((char*) data, length);
  4008. else
  4009. {
  4010. ptr = (unsigned char *) data;
  4011. /* handles UTF-8 characters and entities in the subtree */
  4012. buffer = HandleXMLstring ((unsigned char *)ptr, &length, XMLcontext.lastElement, TRUE);
  4013. /* the whole content is now handled */
  4014. TtaFreeMemory (buffer);
  4015. }
  4016. }
  4017. /*----------------------------------------------------------------------
  4018. Hndl_Comment
  4019. Handler for comments
  4020. The data is all text inside the comment delimiters
  4021. ----------------------------------------------------------------------*/
  4022. static void Hndl_Comment (void *userData, const XML_Char *data)
  4023. {
  4024. unsigned char *buffer;
  4025. #ifdef EXPAT_PARSER_DEBUG
  4026. printf ("Hndl_Comment %s\n", data);
  4027. #endif /* EXPAT_PARSER_DEBUG */
  4028. /* This comment has not to be parsed */
  4029. if (WithinDoctype)
  4030. {
  4031. buffer = (unsigned char *) data;
  4032. ParseDoctypeContent ("<!--", 4);
  4033. ParseDoctypeContent ((char *)buffer, strlen ((char *)buffer));
  4034. ParseDoctypeContent ("-->", 3);
  4035. return;
  4036. }
  4037. CreateXmlComment ((char*) data);
  4038. }
  4039. /*----------------------------------------------------------------------
  4040. Hndl_DefaultExpand
  4041. Default handler with expansion of internal entity references
  4042. ----------------------------------------------------------------------*/
  4043. static void Hndl_DefaultExpand (void *userData,
  4044. const XML_Char *data,
  4045. int length)
  4046. {
  4047. #ifdef EXPAT_PARSER_DEBUG
  4048. int i;
  4049. printf ("Hndl_DefaultExpand - length = %d - '", length);
  4050. for (i=0; i<length; i++)
  4051. printf ("%c", data[i]);
  4052. printf ("'\n");
  4053. #endif /* EXPAT_PARSER_DEBUG */
  4054. }
  4055. /*----------------------------------------------------------------------
  4056. Hndl_DoctypeStart
  4057. Handler for the start of the DOCTYPE declaration.
  4058. It is called when the name of the DOCTYPE is encountered.
  4059. ----------------------------------------------------------------------*/
  4060. static void Hndl_DoctypeStart (void *userData,
  4061. const XML_Char *doctypeName,
  4062. const XML_Char *sysid,
  4063. const XML_Char *pubid,
  4064. int has_internal_subset)
  4065. {
  4066. #ifdef EXPAT_PARSER_DEBUG
  4067. printf ("Hndl_DoctypeStart\n");
  4068. printf (" name : %s\n", doctypeName);
  4069. printf (" sysid : %s\n", sysid);
  4070. printf (" pubid : %s\n", pubid);
  4071. printf (" int.subset : %d\n", has_internal_subset);
  4072. #endif /* EXPAT_PARSER_DEBUG */
  4073. /* The content of this doctype has not to be parsed */
  4074. if (!VirtualDoctype)
  4075. {
  4076. CreateDoctypeElement ((char*) doctypeName, (char*) sysid, (char*) pubid);
  4077. WithinDoctype = TRUE;
  4078. }
  4079. }
  4080. /*----------------------------------------------------------------------
  4081. Hndl_DoctypeEnd
  4082. Handler for the start of the DOCTYPE declaration.
  4083. It is called when the closing > is encountered,
  4084. but after processing any external subset.
  4085. ----------------------------------------------------------------------*/
  4086. static void Hndl_DoctypeEnd (void *userData)
  4087. {
  4088. #ifdef EXPAT_PARSER_DEBUG
  4089. printf ("Hndl_DoctypeEnd\n");
  4090. #endif /* EXPAT_PARSER_DEBUG */
  4091. /* The content of this doctype has not to be parsed */
  4092. if (VirtualDoctype)
  4093. VirtualDoctype = FALSE;
  4094. else
  4095. {
  4096. ParseDoctypeContent (">", 1);
  4097. XMLcontext.lastElementClosed = TRUE;
  4098. WithinDoctype = FALSE;
  4099. }
  4100. }
  4101. /*----------------------------------------------------------------------
  4102. Hndl_ElementStart
  4103. Handler for start tags
  4104. Attributes are passed as a pointer to a vector of char pointers
  4105. ----------------------------------------------------------------------*/
  4106. static void Hndl_ElementStart (void *userData,
  4107. const XML_Char *name,
  4108. const XML_Char **attlist)
  4109. {
  4110. unsigned char *attrName = NULL;
  4111. unsigned char *attrValue = NULL;
  4112. PtrParserCtxt elementParserCtxt = NULL;
  4113. #ifdef EXPAT_PARSER_DEBUG
  4114. printf ("Hndl_ElementStart <%s>\n", name);
  4115. #endif /* EXPAT_PARSER_DEBUG */
  4116. /* Treatment for the GI */
  4117. if (XMLcontext.parsingTextArea)
  4118. {
  4119. /* We are parsing the contents of a TEXTAREA element */
  4120. /* If a start tag appears, consider it as plain text */
  4121. }
  4122. else
  4123. {
  4124. /* Ignore the virtual root of an XML sub-tree */
  4125. /* we are parsing the result of a transformation */
  4126. if (strncmp ((char*) name, "SUBTREE_ROOT", 12) != 0)
  4127. {
  4128. /* Treatment called at the beginning of a start tag */
  4129. StartOfXmlStartElement ((char*) name);
  4130. /* We save the current element context */
  4131. elementParserCtxt = CurrentParserCtxt;
  4132. /*------- Treatment of the attributes -------*/
  4133. while (*attlist != NULL)
  4134. {
  4135. /* Create the corresponding Thot attribute */
  4136. attrName = (unsigned char *)TtaGetMemory ((strlen ((char *)*attlist)) + 1);
  4137. strcpy ((char *)attrName, (char *)*attlist);
  4138. #ifdef EXPAT_PARSER_DEBUG
  4139. printf (" attr %s :", attrName);
  4140. #endif /* EXPAT_PARSER_DEBUG */
  4141. EndOfAttributeName ((char *)attrName);
  4142. /* Restore the element context */
  4143. /* It occurs if the attribute name is unknown */
  4144. if (CurrentParserCtxt == NULL)
  4145. CurrentParserCtxt = elementParserCtxt;
  4146. /* Filling of the attribute value */
  4147. attlist++;
  4148. if (*attlist != NULL)
  4149. {
  4150. attrValue = (unsigned char *)TtaGetMemory ((strlen ((char *)*attlist)) + 1);
  4151. strcpy ((char *)attrValue, (char *)*attlist);
  4152. #ifdef EXPAT_PARSER_DEBUG
  4153. printf (" value=\"%s\"\n", attrValue);
  4154. #endif /* EXPAT_PARSER_DEBUG */
  4155. EndOfAttributeValue (attrValue, attrName);
  4156. }
  4157. attlist++;
  4158. if (attrName != NULL)
  4159. TtaFreeMemory (attrName);
  4160. if (attrValue != NULL)
  4161. TtaFreeMemory (attrValue);
  4162. /* Restore the context (it may have been changed */
  4163. /* by the treatment of the attribute) */
  4164. CurrentParserCtxt = elementParserCtxt;
  4165. }
  4166. /*----- Treatment called at the end of a start tag -----*/
  4167. EndOfXmlStartElement ((char*) name);
  4168. /*----- We are immediately after a start tag -----*/
  4169. ImmediatelyAfterTag = TRUE;
  4170. /* Initialize the root element */
  4171. if (XMLRootName == NULL)
  4172. {
  4173. /* This is the first parsed element */
  4174. XMLRootName = TtaStrdup ((char*) name);
  4175. }
  4176. }
  4177. }
  4178. }
  4179. /*----------------------------------------------------------------------
  4180. Hndl_ElementEnd
  4181. Handler for end tags
  4182. ----------------------------------------------------------------------*/
  4183. static void Hndl_ElementEnd (void *userData, const XML_Char *name)
  4184. {
  4185. #ifdef EXPAT_PARSER_DEBUG
  4186. printf ("Hndl_ElementEnd </%s>\n", name);
  4187. #endif /* EXPAT_PARSER_DEBUG */
  4188. ImmediatelyAfterTag = FALSE;
  4189. /* Ignore the virtual root of a XML sub-tree */
  4190. if ((strncmp ((char*) name, "SUBTREE_ROOT", 12) != 0) &&
  4191. (XMLRootName != NULL) && !XMLrootClosed)
  4192. {
  4193. EndOfXmlElement ((char*) name);
  4194. /* Is it the end tag of the root element ? */
  4195. if (!strcmp ((char *)XMLRootName, (char*) name) &&
  4196. stackLevel == 1 && !PARSING_BUFFER)
  4197. XMLrootClosed = TRUE;
  4198. }
  4199. if (!strncmp ((char*) name, "SUBTREE_ROOT", 12) && PARSING_BUFFER)
  4200. XMLrootClosed = TRUE;
  4201. }
  4202. /*----------------------------------------------------------------------
  4203. Hndl_ExternalEntityRef
  4204. Handler for external entity references.
  4205. his handler is also called for processing an external DTD subset.
  4206. ----------------------------------------------------------------------*/
  4207. static int Hndl_ExternalEntityRef(XML_Parser p,
  4208. const XML_Char *context,
  4209. const XML_Char *base,
  4210. const XML_Char *systemId,
  4211. const XML_Char *publicId)
  4212. {
  4213. #ifdef EXPAT_PARSER_DEBUG
  4214. printf ("\nHndl_ExternalEntityRef\n");
  4215. printf (" context : %s\n", context);
  4216. printf (" base : %s\n", base);
  4217. printf (" systemId : %s\n", systemId);
  4218. printf (" publicId : %s\n", publicId);
  4219. #endif /* EXPAT_PARSER_DEBUG */
  4220. return 1;
  4221. }
  4222. /*----------------------------------------------------------------------
  4223. Hndl_NameSpaceStart
  4224. Handler for the start of namespace declarations
  4225. ----------------------------------------------------------------------*/
  4226. static void Hndl_NameSpaceStart (void *userData,
  4227. const XML_Char *ns_prefix,
  4228. const XML_Char *ns_uri)
  4229. {
  4230. #ifdef EXPAT_PARSER_DEBUG
  4231. printf ("Hndl_NameSpaceStart - prefix=\"%s\" uri=\"%s\"\n", ns_prefix, ns_uri);
  4232. #endif /* EXPAT_PARSER_DEBUG */
  4233. NsDeclarationStart ((char *) ns_prefix, (char*) ns_uri);
  4234. }
  4235. /*----------------------------------------------------------------------
  4236. Hndl_NameSpaceEnd
  4237. Handler for the end of namespace declarations
  4238. ----------------------------------------------------------------------*/
  4239. static void Hndl_NameSpaceEnd (void *userData,
  4240. const XML_Char *ns_prefix)
  4241. {
  4242. #ifdef EXPAT_PARSER_DEBUG
  4243. printf ("Hndl_NameSpaceEnd - prefix=\"%s\"\n", ns_prefix);
  4244. #endif /* EXPAT_PARSER_DEBUG */
  4245. NsDeclarationEnd ((char *) ns_prefix);
  4246. }
  4247. /*----------------------------------------------------------------------
  4248. Hndl_Notation
  4249. Handler that receives notation declarations.
  4250. ----------------------------------------------------------------------*/
  4251. static void Hndl_Notation (void *userData,
  4252. const XML_Char *notationName,
  4253. const XML_Char *base,
  4254. const XML_Char *systemId,
  4255. const XML_Char *publicId)
  4256. {
  4257. #ifdef EXPAT_PARSER_DEBUG
  4258. printf ("Hndl_Notation\n");
  4259. printf (" notationName : %s\n", notationName);
  4260. printf (" base : %s\n", base);
  4261. printf (" systemId : %s\n", systemId);
  4262. printf (" publicId : %s\n", publicId);
  4263. #endif /* EXPAT_PARSER_DEBUG */
  4264. }
  4265. /*----------------------------------------------------------------------
  4266. Hndl_NotStandalone
  4267. Handler that is called if the document is not "standalone".
  4268. This happens when there is an external subset or a reference
  4269. to a parameter entity, but does not have standalone set to "yes"
  4270. in an XML declaration.
  4271. If this handler returns 0, then the parser will throw an
  4272. XML_ERROR_NOT_STANDALONE error.
  4273. ----------------------------------------------------------------------*/
  4274. static int Hndl_NotStandalone (void *userData)
  4275. {
  4276. #ifdef EXPAT_PARSER_DEBUG
  4277. printf ("Hndl_NotStandalone\n");
  4278. #endif /* EXPAT_PARSER_DEBUG */
  4279. return 1;
  4280. }
  4281. /*----------------------------------------------------------------------
  4282. Hndl_PI
  4283. Handler for processing instructions.
  4284. The target is the first word in the processing instruction.
  4285. The pidata is the rest of the characters in it after skipping
  4286. all whitespace after the initial word.
  4287. ----------------------------------------------------------------------*/
  4288. static void Hndl_PI (void *userData, const XML_Char *target,
  4289. const XML_Char *pidata)
  4290. {
  4291. unsigned char *buffer;
  4292. #ifdef EXPAT_PARSER_DEBUG
  4293. printf ("Hndl_PI\n");
  4294. printf (" target : %s\n", target);
  4295. printf (" pidata : %s\n", pidata);
  4296. #endif /* EXPAT_PARSER_DEBUG */
  4297. /* This PI has not to be parsed */
  4298. if (WithinDoctype)
  4299. {
  4300. ParseDoctypeContent ("<?", 2);
  4301. buffer = (unsigned char *) target;
  4302. ParseDoctypeContent ((char *)buffer, strlen ((char *)buffer));
  4303. ParseDoctypeContent (" ", 1);
  4304. buffer = (unsigned char *) pidata;
  4305. ParseDoctypeContent ((char *)buffer, strlen ((char *)buffer));
  4306. ParseDoctypeContent ("?>", 2);
  4307. return;
  4308. }
  4309. CreateXmlPi ((char*) target, (char*) pidata);
  4310. }
  4311. /*----------------------------------------------------------------------
  4312. Hndl_SkippedEntityHandler
  4313. This is called in two situations:
  4314. 1) An entity reference is encountered for which no declaration
  4315. has been read *and* this is not an error.
  4316. 2) An internal entity reference is read, but not expanded, because
  4317. XML_SetDefaultHandler has been called.
  4318. Note: skipped parameter entities in declarations and skipped general
  4319. entities in attribute values cannot be reported, because
  4320. the event would be out of sync with the reporting of the
  4321. declarations or attribute values
  4322. ----------------------------------------------------------------------*/
  4323. static void Hndl_SkippedEntityHandler(void *userData,
  4324. const XML_Char *entityName,
  4325. int is_parameter_entity)
  4326. {
  4327. int length;
  4328. char *buffer;
  4329. #ifdef EXPAT_PARSER_DEBUG
  4330. printf ("Hndl_SkippedEntityHandler\n");
  4331. printf (" entity name : %s\n", entityName);
  4332. printf (" parameter : %d\n", is_parameter_entity);
  4333. #endif /* EXPAT_PARSER_DEBUG */
  4334. length = strlen ((char *)entityName);
  4335. if (WithinDoctype)
  4336. ParseDoctypeContent ((char *)entityName, length);
  4337. else
  4338. {
  4339. buffer = (char *)TtaGetMemory (length + 3);
  4340. if (buffer != NULL)
  4341. {
  4342. strcpy ((char *)buffer, "&");
  4343. strcat ((char *)buffer, (char*) entityName);
  4344. strcat ((char *)buffer, ";");
  4345. CreateXmlEntity (buffer, length+2);
  4346. TtaFreeMemory (buffer);
  4347. }
  4348. }
  4349. }
  4350. /*----------------------------------------------------------------------
  4351. Hndl_UnknownEncoding
  4352. Handler to deal with encodings other than the built in
  4353. ----------------------------------------------------------------------*/
  4354. static int Hndl_UnknownEncoding (void *encodingData,
  4355. const XML_Char *name,
  4356. XML_Encoding *info)
  4357. {
  4358. #ifdef EXPAT_PARSER_DEBUG
  4359. printf ("Hndl_UnknownEncoding - name : %s\n", name);
  4360. #endif /* EXPAT_PARSER_DEBUG */
  4361. /* This PI has not to be parsed */
  4362. XMLUnknownEncoding = TRUE;
  4363. XmlParseError (errorEncoding,
  4364. (unsigned char *)TtaGetMessage (AMAYA, AM_UNKNOWN_ENCODING), -1);
  4365. return 1;
  4366. }
  4367. /*----------------------------------------------------------------------
  4368. Hndl_UnparsedEntity
  4369. Handler that receives declarations of unparsed entities.
  4370. These are entity declarations that have a notation (NDATA) field:
  4371. ----------------------------------------------------------------------*/
  4372. static void Hndl_UnparsedEntity (void *userData,
  4373. const XML_Char *entityName,
  4374. const XML_Char *base,
  4375. const XML_Char *systemId,
  4376. const XML_Char *publicId,
  4377. const XML_Char *notationName)
  4378. {
  4379. #ifdef EXPAT_PARSER_DEBUG
  4380. printf ("Hndl_UnparsedEntity\n");
  4381. printf (" entityName : %s\n", entityName);
  4382. printf (" base : %s\n", base);
  4383. printf (" systemId : %s\n", systemId);
  4384. printf (" publicId : %s\n", publicId);
  4385. printf (" notationName : %s\n", notationName);
  4386. #endif /* EXPAT_PARSER_DEBUG */
  4387. }
  4388. /*----------------------------------------------------------------------
  4389. Hndl_XML_XmlDeclHandler
  4390. The XML declaration handler is called for *both* XML declarations
  4391. and text declarations. The way to distinguish is that the version
  4392. parameter will be NULL for text declarations. The encoding
  4393. parameter may be NULL for XML declarations. The standalone
  4394. parameter will be -1, 0, or 1 indicating respectively that there
  4395. was no standalone parameter in the declaration, that it was given
  4396. as no, or that it was given as yes.
  4397. ----------------------------------------------------------------------*/
  4398. static void Hndl_XmlDeclHandler (void *userData,
  4399. const XML_Char *version,
  4400. const XML_Char *encoding,
  4401. int standalone)
  4402. {
  4403. #ifdef EXPAT_PARSER_DEBUG
  4404. printf ("Hndl_XmlDeclHandler\n");
  4405. printf (" version : %s\n", version);
  4406. printf (" encoding : %s\n", encoding);
  4407. printf (" standalone : %d\n", standalone);
  4408. #endif /* EXPAT_PARSER_DEBUG */
  4409. }
  4410. /*---------------- End of Handler definition ----------------*/
  4411. /*----------------------------------------------------------------------
  4412. FreeXmlParser
  4413. Frees all ressources associated with the XML parser.
  4414. ----------------------------------------------------------------------*/
  4415. void FreeXmlParserContexts (void)
  4416. {
  4417. PtrParserCtxt ctxt, nextCtxt;
  4418. int i;
  4419. /* Free parser contexts */
  4420. ctxt = FirstParserCtxt;
  4421. while (ctxt != NULL)
  4422. {
  4423. nextCtxt = ctxt->NextParserCtxt;
  4424. TtaFreeMemory (ctxt->SSchemaName);
  4425. TtaFreeMemory (ctxt->UriName);
  4426. TtaFreeMemory (ctxt);
  4427. ctxt = nextCtxt;
  4428. }
  4429. FirstParserCtxt = NULL;
  4430. CurrentParserCtxt = NULL;
  4431. /* Free NameSpace table */
  4432. for (i = 0; i < Ns_Level; i++)
  4433. {
  4434. if (Ns_Prefix[i])
  4435. {
  4436. TtaFreeMemory (Ns_Prefix[i]);
  4437. Ns_Prefix[i] = NULL;
  4438. }
  4439. if (Ns_Uri[i])
  4440. {
  4441. TtaFreeMemory (Ns_Uri[i]);
  4442. Ns_Uri[i] = NULL;
  4443. }
  4444. }
  4445. /* Free XML Style Sheets table */
  4446. for (i = 0; i < XML_CSS_Level; i++)
  4447. {
  4448. if (XML_CSS_Href[i])
  4449. {
  4450. TtaFreeMemory (XML_CSS_Href[i]);
  4451. XML_CSS_Href[i] = NULL;
  4452. }
  4453. }
  4454. if (XMLRootName != NULL)
  4455. {
  4456. TtaFreeMemory (XMLRootName);
  4457. XMLRootName = NULL;
  4458. }
  4459. }
  4460. /*----------------------------------------------------------------------
  4461. DisableExpatParser
  4462. Disable all handlers
  4463. ----------------------------------------------------------------------*/
  4464. static void DisableExpatParser ()
  4465. {
  4466. int paramEntityParsing;
  4467. paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
  4468. XML_SetCdataSectionHandler (Parser, NULL, NULL);
  4469. XML_SetCharacterDataHandler (Parser, NULL);
  4470. XML_SetCommentHandler (Parser, NULL);
  4471. XML_SetDefaultHandlerExpand (Parser, NULL);
  4472. XML_SetDoctypeDeclHandler (Parser, NULL, NULL);
  4473. XML_SetElementHandler (Parser, NULL, NULL);
  4474. XML_SetExternalEntityRefHandler (Parser, NULL);
  4475. XML_SetNamespaceDeclHandler (Parser, NULL, NULL);
  4476. XML_SetNotationDeclHandler (Parser, NULL);
  4477. XML_SetNotStandaloneHandler (Parser, NULL);
  4478. XML_SetParamEntityParsing (Parser, (enum XML_ParamEntityParsing)paramEntityParsing);
  4479. XML_SetProcessingInstructionHandler (Parser, NULL);
  4480. XML_SetUnknownEncodingHandler (Parser, NULL, 0);
  4481. XML_SetUnparsedEntityDeclHandler (Parser, NULL);
  4482. }
  4483. /*----------------------------------------------------------------------
  4484. FreeExpatParser
  4485. ----------------------------------------------------------------------*/
  4486. static void FreeExpatParser ()
  4487. {
  4488. DisableExpatParser ();
  4489. XML_ParserFree (Parser);
  4490. Parser = NULL;
  4491. }
  4492. /*----------------------------------------------------------------------
  4493. InitializeExpatParser
  4494. Specific initialization for expat
  4495. ----------------------------------------------------------------------*/
  4496. static void InitializeExpatParser (CHARSET charset)
  4497. {
  4498. int paramEntityParsing;
  4499. /* Enable parsing of parameter entities */
  4500. paramEntityParsing = XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE;
  4501. /* Construct a new parser with namespace processing */
  4502. /* accordingly to the document encoding */
  4503. /* If that encoding is unknown, we don''t parse the document */
  4504. if (charset == UNDEFINED_CHARSET)
  4505. {
  4506. /* Default encoding for XML documents */
  4507. Parser = XML_ParserCreateNS ("UTF-8", NS_SEP);
  4508. TtaSetDocumentCharset (XMLcontext.doc, UTF_8, TRUE);
  4509. }
  4510. else if (charset == UTF_8 || charset == UTF_16)
  4511. /* These encoding are automatically recognized by Expat */
  4512. Parser = XML_ParserCreateNS (NULL, NS_SEP);
  4513. else if (charset == US_ASCII)
  4514. /* US-ASCII may has been set for us-ascii or ascii */
  4515. Parser = XML_ParserCreateNS ("US-ASCII", NS_SEP);
  4516. else if (charset == ISO_8859_1)
  4517. /* ISO_8859_1 may has been set for a HTML document with no encoding */
  4518. /* In this case, the default encoding is ISO_8859_1, not UTF-8 */
  4519. Parser = XML_ParserCreateNS ("ISO-8859-1", NS_SEP);
  4520. else if (charset == ISO_8859_2 || charset == ISO_8859_3 ||
  4521. charset == ISO_8859_4 || charset == ISO_8859_5 ||
  4522. charset == ISO_8859_6 || charset == ISO_8859_7 ||
  4523. charset == ISO_8859_8 || charset == ISO_8859_9 ||
  4524. charset == ISO_8859_15 || charset == KOI8_R ||
  4525. charset == WINDOWS_1250 || charset == WINDOWS_1251 ||
  4526. charset == WINDOWS_1252 || charset == WINDOWS_1253 ||
  4527. charset == WINDOWS_1254 || charset == WINDOWS_1255 ||
  4528. charset == WINDOWS_1256 || charset == WINDOWS_1257 ||
  4529. charset == ISO_2022_JP || charset == EUC_JP ||
  4530. charset == SHIFT_JIS || charset == GB_2312)
  4531. /* buffers will be converted to UTF-8 by Amaya */
  4532. Parser = XML_ParserCreateNS ("UTF-8", NS_SEP);
  4533. else
  4534. {
  4535. XMLUnknownEncoding = TRUE;
  4536. Parser = XML_ParserCreateNS ("ISO-8859-1", NS_SEP);
  4537. XmlParseError (errorEncoding,
  4538. (unsigned char *)TtaGetMessage (AMAYA, AM_UNKNOWN_ENCODING), -1);
  4539. }
  4540. /* Define the user data pointer that gets passed to handlers */
  4541. /* (not use Amaya actually) */
  4542. /* XML_SetUserData (Parser, (void*) doc); */
  4543. /* Set handlers that get called at the beginning
  4544. and end of a CDATA section */
  4545. XML_SetCdataSectionHandler (Parser,
  4546. Hndl_CdataStart,
  4547. Hndl_CdataEnd);
  4548. /* Set a text handler */
  4549. XML_SetCharacterDataHandler (Parser,
  4550. Hndl_CharacterData);
  4551. /* Set a handler for comments */
  4552. XML_SetCommentHandler (Parser,
  4553. Hndl_Comment);
  4554. /* Set default handler with no expansion of internal entity references */
  4555. /*
  4556. XML_SetDefaultHandler (Parser,
  4557. Hndl_Default);
  4558. */
  4559. /* Set a default handler with expansion of internal entity references */
  4560. XML_SetDefaultHandlerExpand (Parser,
  4561. Hndl_DefaultExpand);
  4562. /* Set a handler for DOCTYPE declaration */
  4563. XML_SetDoctypeDeclHandler (Parser,
  4564. Hndl_DoctypeStart,
  4565. Hndl_DoctypeEnd);
  4566. /* Set handlers for start and end tags */
  4567. XML_SetElementHandler (Parser,
  4568. Hndl_ElementStart,
  4569. Hndl_ElementEnd);
  4570. /* Set an external entity reference handler */
  4571. XML_SetExternalEntityRefHandler (Parser,
  4572. Hndl_ExternalEntityRef);
  4573. /* Set handlers for namespace declarations */
  4574. XML_SetNamespaceDeclHandler (Parser,
  4575. Hndl_NameSpaceStart,
  4576. Hndl_NameSpaceEnd);
  4577. /* Set an handler for notation declarations */
  4578. XML_SetNotationDeclHandler (Parser,
  4579. Hndl_Notation);
  4580. /* Set an handler for no 'standalone' document */
  4581. XML_SetNotStandaloneHandler (Parser,
  4582. Hndl_NotStandalone);
  4583. /* Controls parsing of parameter entities */
  4584. XML_SetParamEntityParsing (Parser,
  4585. (enum XML_ParamEntityParsing)paramEntityParsing);
  4586. /* Set an handler for processing instructions */
  4587. XML_SetProcessingInstructionHandler (Parser,
  4588. Hndl_PI);
  4589. /* Set an handler to deal with encodings other than the built in */
  4590. XML_SetUnknownEncodingHandler (Parser,
  4591. Hndl_UnknownEncoding, 0);
  4592. /* Set an handler that receives declarations of unparsed entities */
  4593. XML_SetUnparsedEntityDeclHandler (Parser,
  4594. Hndl_UnparsedEntity);
  4595. /* Set an handler that is called for XML declarations */
  4596. XML_SetXmlDeclHandler (Parser,
  4597. Hndl_XmlDeclHandler);
  4598. /* Set a skipped entity handler */
  4599. XML_SetSkippedEntityHandler (Parser,
  4600. Hndl_SkippedEntityHandler);
  4601. }
  4602. /*----------------------------------------------------------------------
  4603. InitializeXmlParsingContext
  4604. initializes variables and stack for parsing file.
  4605. ----------------------------------------------------------------------*/
  4606. static void InitializeXmlParsingContext (Document doc,
  4607. Element lastElem,
  4608. ThotBool isClosed,
  4609. ThotBool isSubTree)
  4610. {
  4611. XMLcontext.doc = doc;
  4612. XMLcontext.lastElement = lastElem;
  4613. XMLcontext.lastElementClosed = isClosed;
  4614. ParsingSubTree = isSubTree;
  4615. /* initialize global variables */
  4616. XMLcontext.readingAnAttrValue = FALSE;
  4617. XMLcontext.parsingTextArea = FALSE;
  4618. XMLcontext.parsingCSS = FALSE;
  4619. XMLcontext.mergeText = FALSE;
  4620. XMLcontext.withinTable = 0;
  4621. currentAttribute = NULL;
  4622. lastAttrElement = NULL;
  4623. lastMappedAttr = NULL;
  4624. ImmediatelyAfterTag = FALSE;
  4625. UnknownElement = FALSE;
  4626. XMLRootName = NULL;
  4627. XMLrootClosed = FALSE;
  4628. ParsingCDATA = FALSE;
  4629. VirtualDoctype = FALSE;
  4630. ShowParsingErrors = TRUE;
  4631. PARSING_BUFFER = FALSE;
  4632. HtmlLineRead = 0;
  4633. HtmlCharRead = 0;
  4634. /* initialize the stack of opened elements */
  4635. stackLevel = 1;
  4636. Ns_Level = 0;
  4637. CurNs_Level = 0;
  4638. XML_CSS_Level = 0;
  4639. elementStack[0] = RootElement;
  4640. }
  4641. /*----------------------------------------------------------------------
  4642. MoveExternalAttribute
  4643. ----------------------------------------------------------------------*/
  4644. static void MoveExternalAttribute (Element elold, Element elnew, Document doc)
  4645. {
  4646. AttributeType attrType;
  4647. Attribute attrold, attrnew, nextattr;
  4648. int attrKind, val, length;
  4649. char *buffer;
  4650. /* Attach the attributes to the new element */
  4651. nextattr = NULL;
  4652. TtaNextAttribute (elold, &nextattr);
  4653. while (nextattr != NULL)
  4654. {
  4655. attrold = nextattr;
  4656. TtaNextAttribute (elold, &nextattr);
  4657. TtaGiveAttributeType (attrold, &attrType, &attrKind);
  4658. attrnew = TtaNewAttribute (attrType);
  4659. TtaAttachAttribute (elnew, attrnew, doc);
  4660. switch (attrKind)
  4661. {
  4662. case 0: /* enumerate */
  4663. case 1: /* integer */
  4664. val = TtaGetAttributeValue (attrold);
  4665. TtaSetAttributeValue (attrnew, val, elnew, doc);
  4666. break;
  4667. case 2: /* text */
  4668. length = TtaGetTextAttributeLength (attrold);
  4669. buffer = (char *)TtaGetMemory (length + 1);
  4670. TtaGiveTextAttributeValue (attrold, buffer, &length);
  4671. TtaSetAttributeText (attrnew, (char *)buffer, elnew, doc);
  4672. TtaFreeMemory (buffer);
  4673. break;
  4674. case 3: /* reference */
  4675. break;
  4676. }
  4677. }
  4678. }
  4679. /*-----------------------------------------------------------------------------
  4680. SetExternalElementType
  4681. Initial treatment relative to the element which is the parent of the
  4682. external sub-tree (document)
  4683. use_ref is TRUE when we are parse a reference to an external use svg element
  4684. ------------------------------------------------------------------------------*/
  4685. static Element SetExternalElementType (Element el, Document doc,
  4686. ThotBool *use_ref)
  4687. {
  4688. ElementType elType, parentType;
  4689. Element parent, elemElement, elemContent;
  4690. AttributeType attrType;
  4691. Attribute attr;
  4692. ThotBool oldStructureChecking;
  4693. elemElement = NULL;
  4694. elemContent = NULL;
  4695. elType = TtaGetElementType (el);
  4696. *use_ref = FALSE;
  4697. /* Disable structure checking */
  4698. oldStructureChecking = TtaGetStructureChecking (doc);
  4699. TtaSetStructureChecking (FALSE, doc);
  4700. if ((strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0) &&
  4701. (elType.ElTypeNum == HTML_EL_PICTURE_UNIT))
  4702. {
  4703. /* We are parsing an external picture within a HTML document */
  4704. parent = TtaGetParent (el);
  4705. parentType = TtaGetElementType (parent);
  4706. if (parentType.ElTypeNum == HTML_EL_Object)
  4707. {
  4708. /* Create an External_Object_Content element */
  4709. elType.ElTypeNum = HTML_EL_External_Object_Content;
  4710. elemContent = TtaNewElement (doc, elType);
  4711. if (elemContent != NULL)
  4712. {
  4713. attrType.AttrSSchema = elType.ElSSchema;
  4714. TtaInsertSibling (elemContent, el, FALSE, doc);
  4715. /* Remove the IntHeightPercent Thot attributes: this attribute
  4716. does not make sense for Thot. */
  4717. attrType.AttrTypeNum = HTML_ATTR_IntHeightPercent;
  4718. attr = TtaGetAttribute (el, attrType);
  4719. if (attr != NULL)
  4720. TtaRemoveAttribute (el, attr, doc);
  4721. /* Attach the attributes to that new element */
  4722. MoveExternalAttribute (el, elemContent, doc);
  4723. /* Remove the PICTURE_UNIT element form the tree */
  4724. TtaDeleteTree (el, doc);
  4725. }
  4726. }
  4727. else
  4728. {
  4729. /* create an External_Object element instead of the PICTURE element */
  4730. elType.ElTypeNum = HTML_EL_External_Object;
  4731. elemElement = TtaNewElement (doc, elType);
  4732. if (elemElement != NULL)
  4733. {
  4734. TtaInsertSibling (elemElement, el, FALSE, doc);
  4735. /* Attach the attributes to that new element */
  4736. MoveExternalAttribute (el, elemElement, doc);
  4737. /* create an External_ObjectContent element */
  4738. elType.ElTypeNum = HTML_EL_External_Object_Content;
  4739. elemContent = TtaNewElement (doc, elType);
  4740. if (elemContent != NULL)
  4741. TtaInsertFirstChild (&elemContent, elemElement, doc);
  4742. /* Remove the PICTURE_UNIT element form the tree */
  4743. TtaDeleteTree (el, doc);
  4744. }
  4745. }
  4746. }
  4747. else if ((strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0) &&
  4748. elType.ElTypeNum == HTML_EL_Embed_)
  4749. {
  4750. /* We are parsing an embed element within a HTML document*/
  4751. /* Is there an Embed_Content element? */
  4752. elType.ElTypeNum = HTML_EL_Embed_Content;
  4753. elemContent = TtaSearchTypedElement (elType, SearchInTree, el);
  4754. if (!elemContent)
  4755. /* no, create one */
  4756. {
  4757. elemContent = TtaNewElement (doc, elType);
  4758. if (elemContent != NULL)
  4759. TtaInsertFirstChild (&elemContent, el, doc);
  4760. }
  4761. }
  4762. else if ((strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0) &&
  4763. elType.ElTypeNum == HTML_EL_IFRAME)
  4764. {
  4765. /* We are parsing an iframe element within a HTML document*/
  4766. /* Is there an Iframe_Src_Content element? */
  4767. elType.ElTypeNum = HTML_EL_Iframe_Src_Content;
  4768. elemContent = TtaSearchTypedElement (elType, SearchInTree, el);
  4769. if (!elemContent)
  4770. /* no, create one */
  4771. {
  4772. elemContent = TtaNewElement (doc, elType);
  4773. if (elemContent != NULL)
  4774. TtaInsertFirstChild (&elemContent, el, doc);
  4775. }
  4776. }
  4777. else if ((strcmp (TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0) &&
  4778. elType.ElTypeNum == SVG_EL_PICTURE_UNIT)
  4779. {
  4780. /* We are parsing a SVG document */
  4781. /* Create a SVG_Image element within a SVG element */
  4782. elType.ElTypeNum = SVG_EL_SVG_Image;
  4783. elemContent = TtaNewElement (doc, elType);
  4784. if (elemContent != NULL)
  4785. {
  4786. TtaInsertSibling (elemContent, el, FALSE, doc);
  4787. /* Attach the attributes to that new element */
  4788. MoveExternalAttribute (el, elemContent, doc);
  4789. /* Remove the PICTURE_UNIT element form the tree */
  4790. TtaDeleteTree (el, doc);
  4791. }
  4792. }
  4793. else if ((strcmp (TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0) &&
  4794. (elType.ElTypeNum == SVG_EL_use_ ||
  4795. elType.ElTypeNum == SVG_EL_tref))
  4796. {
  4797. /* We are parsing an external SVG use element */
  4798. elemContent = el;
  4799. *use_ref = TRUE;
  4800. }
  4801. /* Restore the structure checking */
  4802. TtaSetStructureChecking (oldStructureChecking, doc);
  4803. return elemContent;
  4804. }
  4805. /*---------------------------------------------------------------------------
  4806. ParseExternalDocument
  4807. Parse a document called from an other document.
  4808. The new file is parsed in an external document and then pasted
  4809. into the main document
  4810. Return TRUE if the parsing of the external document doesn't detect errors.
  4811. ---------------------------------------------------------------------------*/
  4812. void ParseExternalDocument (char *fileName, char *originalName, Element el,
  4813. ThotBool isclosed, Document doc, Language lang,
  4814. const char *typeName)
  4815. {
  4816. ElementType elType;
  4817. Element parent, oldel;
  4818. Element copy = NULL;
  4819. Element idEl = NULL, extEl = NULL;
  4820. AttributeType extAttrType;
  4821. DocumentType thotType;
  4822. Document externalDoc = 0;
  4823. CHARSET charset;
  4824. NotifyElement event;
  4825. DisplayMode dispMode;
  4826. gzFile infile;
  4827. int parsingLevel, extraProfile, saveDocNet;
  4828. char charsetname[MAX_LENGTH];
  4829. char type[NAME_LENGTH];
  4830. char *extUseUri = NULL, *extUseId = NULL, *s = NULL, *htmlURL = NULL;
  4831. char *schemaName = NULL, *tempName = NULL, *ptr = NULL;
  4832. ThotBool xmlDec, docType, isXML, useMath, isKnown;
  4833. ThotBool savParsingError;
  4834. ThotBool use_ref = FALSE;
  4835. ThotBool oldStructureChecking;
  4836. if (fileName == NULL)
  4837. return;
  4838. /* Avoid too many redisplay */
  4839. dispMode = TtaGetDisplayMode (doc);
  4840. TtaSetDisplayMode (doc, NoComputedDisplay);
  4841. /* General initialization */
  4842. RootElement = NULL;
  4843. if (typeName != NULL &&
  4844. ((strcmp ((char *)typeName, "SVG") == 0) ||
  4845. (strcmp ((char *)typeName, "MathML") == 0) ||
  4846. (strcmp ((char *)typeName, "HTML") == 0)))
  4847. {
  4848. /* We are parsing an external html, svg or mathml document */
  4849. extEl = SetExternalElementType (el, doc, &use_ref);
  4850. if (extEl == NULL)
  4851. return;
  4852. /* Create a new document with no presentation schema */
  4853. /* and load the external document */
  4854. strcpy ((char *)type, (char *)typeName);
  4855. externalDoc = TtaNewDocument (type, "tmp");
  4856. if (externalDoc == 0)
  4857. return;
  4858. else
  4859. {
  4860. DocumentMeta[externalDoc] = DocumentMetaDataAlloc ();
  4861. strcat (type, "P");
  4862. TtaSetPSchema (externalDoc, type);
  4863. RootElement = TtaGetMainRoot (externalDoc);
  4864. InitializeXmlParsingContext (externalDoc, RootElement, FALSE, FALSE);
  4865. /* Set the document reference (used for local CSS)*/
  4866. /* Disable structure checking for the external document*/
  4867. TtaSetStructureChecking (FALSE, externalDoc);
  4868. /* Delete all element except the root element */
  4869. parent = TtaGetFirstChild (RootElement);
  4870. // look for the root element (HTML, SVG, etc.)
  4871. RootElement = TtaGetRootElement (externalDoc);
  4872. while (parent && parent != RootElement)
  4873. {
  4874. oldel = parent;
  4875. TtaNextSibling (&parent);
  4876. TtaDeleteTree (oldel, externalDoc);
  4877. }
  4878. }
  4879. }
  4880. else
  4881. {
  4882. if (isclosed)
  4883. {
  4884. parent = TtaGetParent (el);
  4885. elType = TtaGetElementType (parent);
  4886. }
  4887. else
  4888. elType = TtaGetElementType (el);
  4889. schemaName = TtaGetSSchemaName(elType.ElSSchema);
  4890. InitializeXmlParsingContext (doc, el, isclosed, TRUE);
  4891. }
  4892. /* specific Initialization */
  4893. XMLcontext.language = lang;
  4894. if (externalDoc != 0)
  4895. DocumentSSchema = TtaGetDocumentSSchema (externalDoc);
  4896. else
  4897. DocumentSSchema = TtaGetDocumentSSchema (doc);
  4898. /* Set document URL */
  4899. s = TtaStrdup (originalName);
  4900. if (DocumentURLs[externalDoc])
  4901. {
  4902. TtaFreeMemory (DocumentURLs[externalDoc]);
  4903. DocumentURLs[externalDoc] = NULL;
  4904. }
  4905. DocumentURLs[externalDoc] = s;
  4906. tempName = (char *)TtaGetMemory (strlen ((char *)fileName) + 1);
  4907. if (use_ref)
  4908. {
  4909. /* We are parsing an external reference for a 'use' svg element */
  4910. extUseUri = (char *)TtaGetMemory (strlen ((char *)originalName) + 1);
  4911. strcpy ((char *)extUseUri, (char *)originalName);
  4912. /* Extract the ID target */
  4913. if ((ptr = strrchr (extUseUri, '#')) != NULL)
  4914. {
  4915. *ptr = EOS;
  4916. ptr++;
  4917. extUseId = (char *)TtaGetMemory ((strlen ((char *)ptr) + 1));
  4918. strcpy ((char *)extUseId, (char *)ptr);
  4919. }
  4920. if (TtaFileExist (fileName))
  4921. strcpy ((char *)tempName, (char *)fileName);
  4922. else if (TtaFileExist (extUseUri))
  4923. strcpy ((char *)tempName, (char *)extUseUri);
  4924. else
  4925. {
  4926. TtaFreeMemory (tempName);
  4927. tempName = NULL;
  4928. }
  4929. }
  4930. else
  4931. strcpy ((char *)tempName, (char *)fileName);
  4932. // Ignore errors of imported documents
  4933. savParsingError = ShowParsingErrors;
  4934. ShowParsingErrors = FALSE;
  4935. IgnoreErrors = TRUE;
  4936. charset = TtaGetDocumentCharset (doc);
  4937. /* For XML documents, the default charset is ISO_8859_1 */
  4938. if (charset == UNDEFINED_CHARSET && !DocumentMeta[doc]->xmlformat)
  4939. charset = ISO_8859_1;
  4940. if (tempName)
  4941. {
  4942. /* Parse the file and build the external document */
  4943. infile = TtaGZOpen (tempName);
  4944. if (infile != NULL)
  4945. {
  4946. /* Check if there is an xml declaration with a charset declaration */
  4947. if (tempName != EOS)
  4948. CheckDocHeader (tempName, &xmlDec, &docType, &isXML, &useMath, &isKnown,
  4949. &parsingLevel, &charset, charsetname, &thotType, &extraProfile);
  4950. /* Parse the external file */
  4951. DocumentMeta[externalDoc]->compound = FALSE;
  4952. if (!strcmp ((char *)typeName, "HTML"))
  4953. {
  4954. // Use the html parser as the document could be invalid
  4955. DocumentMeta[externalDoc]->xmlformat = FALSE;
  4956. htmlURL = (char *)TtaGetMemory (strlen ((char *)s) + 1);
  4957. if (htmlURL != NULL)
  4958. {
  4959. strcpy ((char *)htmlURL, (char *)s);
  4960. ParseExternalHTMLDoc (externalDoc, (FILE *)infile, charset, htmlURL);
  4961. TtaFreeMemory (htmlURL);
  4962. }
  4963. }
  4964. else
  4965. {
  4966. DocumentMeta[externalDoc]->xmlformat = TRUE;
  4967. /* Initialize parser context */
  4968. if (FirstParserCtxt == NULL)
  4969. InitXmlParserContexts ();
  4970. if (schemaName != NULL)
  4971. ChangeXmlParserContextByDTD (schemaName);
  4972. else
  4973. ChangeXmlParserContextByDTD (typeName);
  4974. /* Expat initialization */
  4975. InitializeExpatParser (charset);
  4976. /* Expat parsing */
  4977. XmlParse ((FILE *)infile, charset, &xmlDec, &docType);
  4978. /* Free expat parser */
  4979. FreeXmlParserContexts ();
  4980. FreeExpatParser ();
  4981. }
  4982. TtaGZClose (infile);
  4983. }
  4984. }
  4985. if (externalDoc != 0 && externalDoc != doc)
  4986. {
  4987. /* Disable structure checking for the main document */
  4988. oldStructureChecking = TtaGetStructureChecking (doc);
  4989. TtaSetStructureChecking (FALSE, doc);
  4990. if (use_ref)
  4991. {
  4992. /* Move the target element of the external document
  4993. as a sub-tree of the element extEl in the source document */
  4994. /* Search the target element */
  4995. #ifdef _SVG
  4996. extAttrType.AttrSSchema = TtaGetSSchema ("SVG", externalDoc);
  4997. if (extAttrType.AttrSSchema)
  4998. /* This document uses the SVG schema */
  4999. {
  5000. extAttrType.AttrTypeNum = SVG_ATTR_id;
  5001. idEl = GetElemWithAttr (externalDoc, extAttrType, extUseId, NULL, NULL);
  5002. }
  5003. /* Do the actual copy */
  5004. if (idEl)
  5005. {
  5006. elType = TtaGetElementType (extEl);
  5007. if (elType.ElTypeNum == SVG_EL_tref &&
  5008. elType.ElSSchema == extAttrType.AttrSSchema)
  5009. /* it's a tref element: do a "flat" copy */
  5010. CopyTRefContent (idEl, extEl, doc);
  5011. else
  5012. {
  5013. /* Copy the external sub-tree into the main document*/
  5014. copy = TtaCopyTree (idEl, externalDoc, doc, extEl);
  5015. TtaInsertFirstChild (&copy, extEl, doc);
  5016. if (elType.ElTypeNum == SVG_EL_use_ &&
  5017. elType.ElSSchema == extAttrType.AttrSSchema)
  5018. TtaCopyGradientUse (copy);
  5019. }
  5020. }
  5021. #endif /* _SVG */
  5022. }
  5023. else
  5024. {
  5025. /* Add the corresponding nature to the main document */
  5026. elType.ElSSchema = TtaGetSSchema (typeName, doc);
  5027. if (elType.ElSSchema == NULL)
  5028. TtaNewNature (doc, TtaGetDocumentSSchema (doc), NULL, typeName,
  5029. type);
  5030. /* Paste the external document */
  5031. if (strcmp ((char *)typeName, "HTML") == 0)
  5032. {
  5033. /* XHTML documents */
  5034. /* Handle character-level elements which contain block-level elements */
  5035. CheckBlocksInCharElem (externalDoc);
  5036. /* For (X)HTML documents, we paste the BODY element */
  5037. elType.ElSSchema = TtaGetSSchema ("HTML", externalDoc);
  5038. elType.ElTypeNum = HTML_EL_HEAD;
  5039. idEl = TtaSearchTypedElement (elType, SearchForward, RootElement);
  5040. TtaDeleteTree (idEl, externalDoc);
  5041. idEl = TtaGetRootElement (externalDoc);
  5042. }
  5043. else
  5044. idEl = TtaGetRootElement (externalDoc);
  5045. /* Copy the external sub-tree into the main document*/
  5046. copy = TtaCopyTree (idEl, externalDoc, doc, extEl);
  5047. TtaInsertFirstChild (&copy, extEl, doc);
  5048. /* Update the Images and the URLs in the pasted sub-tree */
  5049. event.event = TteElemPaste;
  5050. event.document = doc;
  5051. event.element = copy;
  5052. event.elementType.ElSSchema = NULL;
  5053. event.elementType.ElTypeNum = 0; /* tell UpdateURLsInSubtree not to
  5054. change IDs through MaqueUniqueName */
  5055. event.position = externalDoc;
  5056. event.info = 0;
  5057. UpdateURLsInSubtree(&event, copy);
  5058. }
  5059. /* Move presentation-schema extensions of the external document */
  5060. /* to the sub-tree of which 'extEl' is the root */
  5061. /* This allow to enable the style sheets attached to the external doc */
  5062. if (copy)
  5063. {
  5064. TtaMoveDocumentExtensionsToElement (externalDoc, copy);
  5065. EmbedStyleSheets (externalDoc, doc);
  5066. }
  5067. /* Remove the ParsingErrors file */
  5068. RemoveParsingErrors (externalDoc);
  5069. /* Restore the structure checking for the main document*/
  5070. TtaSetStructureChecking (oldStructureChecking, doc);
  5071. }
  5072. /* Restore ParsingError indicator */
  5073. IgnoreErrors = FALSE;
  5074. ShowParsingErrors = savParsingError;
  5075. /* Delete the external document */
  5076. if (externalDoc != 0 && externalDoc != doc)
  5077. {
  5078. FreeDocumentResource (externalDoc);
  5079. TtaCloseDocument (externalDoc);
  5080. TtaFreeMemory (DocumentURLs[externalDoc]);
  5081. DocumentURLs[externalDoc] = NULL;
  5082. }
  5083. /* Restore the display mode */
  5084. if (DocumentURLs[doc])
  5085. TtaSetDisplayMode (doc, dispMode);
  5086. if (docURL)
  5087. {
  5088. TtaFreeMemory (docURL);
  5089. docURL = NULL;
  5090. }
  5091. TtaFreeMemory (tempName);
  5092. TtaFreeMemory (extUseUri);
  5093. TtaFreeMemory (extUseId);
  5094. if (extEl)
  5095. {
  5096. /* Fetch and display the recursive images */
  5097. /* modify the net status */
  5098. saveDocNet = DocNetworkStatus[doc];
  5099. DocNetworkStatus[doc] = AMAYA_NET_ACTIVE;
  5100. FetchAndDisplayImages (doc, AMAYA_LOAD_IMAGE, extEl);
  5101. DocNetworkStatus[doc] = saveDocNet;
  5102. /* Make the external element not editable */
  5103. TtaSetAccessRight (extEl, ReadOnly, doc);
  5104. }
  5105. return;
  5106. }
  5107. /*----------------------------------------------------------------------
  5108. ParseXmlBuffer
  5109. Parse a XML sub-tree given in a buffer and complete the
  5110. corresponding Thot abstract tree.
  5111. Return TRUE if the parsing of the buffer has no error.
  5112. ----------------------------------------------------------------------*/
  5113. ThotBool ParseXmlBuffer (char *xmlBuffer, Element el, ThotBool isclosed,
  5114. Document doc, Language lang, char *typeName)
  5115. {
  5116. int tmpLen = 0;
  5117. char *transBuffer = NULL;
  5118. char *schemaName = NULL;
  5119. ElementType elType;
  5120. Element parent;
  5121. CHARSET charset;
  5122. DisplayMode dispMode;
  5123. if (xmlBuffer == NULL)
  5124. return FALSE;
  5125. /* avoid too many redisplay */
  5126. dispMode = TtaGetDisplayMode (doc);
  5127. if (dispMode == DisplayImmediately)
  5128. TtaSetDisplayMode (doc, DeferredDisplay);
  5129. /* Initialize all parser contexts */
  5130. if (FirstParserCtxt == NULL)
  5131. InitXmlParserContexts ();
  5132. /* general initialization */
  5133. RootElement = NULL;
  5134. if (isclosed)
  5135. parent = TtaGetParent (el);
  5136. else
  5137. parent = el;
  5138. // skip Template elements
  5139. do
  5140. {
  5141. elType = TtaGetElementType (parent);
  5142. parent = TtaGetParent (parent);
  5143. }
  5144. while (!strcmp (TtaGetSSchemaName(elType.ElSSchema), "Template"));
  5145. schemaName = TtaGetSSchemaName(elType.ElSSchema);
  5146. InitializeXmlParsingContext (doc, el, isclosed, TRUE);
  5147. ChangeXmlParserContextByDTD (schemaName);
  5148. /* specific Initialization */
  5149. XMLcontext.language = lang;
  5150. DocumentSSchema = TtaGetDocumentSSchema (doc);
  5151. /* Expat initialization */
  5152. charset = TtaGetDocumentCharset (doc);
  5153. /* For XML documents, the default charset is ISO_8859_1 */
  5154. if (charset == UNDEFINED_CHARSET && !DocumentMeta[doc]->xmlformat)
  5155. charset = ISO_8859_1;
  5156. InitializeExpatParser (charset);
  5157. /* We are parsing the result of a transformation */
  5158. /* Parse a virtual DOCTYPE */
  5159. VirtualDoctype = TRUE;
  5160. if (!XML_Parse (Parser, DECL_DOCTYPE, DECL_DOCTYPE_LEN, 0))
  5161. XmlParseError (errorNotWellFormed,
  5162. (unsigned char *) XML_ErrorString (XML_GetErrorCode (Parser)), 0);
  5163. /* Parse the input XML buffer and complete the Thot document */
  5164. if (!XMLNotWellFormed)
  5165. {
  5166. /* We create a virtual root for the sub-tree to be parsed */
  5167. tmpLen = (strlen ((char *)xmlBuffer)) + 1;
  5168. tmpLen = tmpLen + 14 + 15 + 1;
  5169. transBuffer = (char *)TtaGetMemory (tmpLen);
  5170. strcpy ((char *)transBuffer, "<SUBTREE_ROOT>");
  5171. strcat ((char *)transBuffer, (char *)xmlBuffer);
  5172. strcat ((char *)transBuffer, "</SUBTREE_ROOT>");
  5173. tmpLen = strlen ((char *)transBuffer);
  5174. PARSING_BUFFER = TRUE;
  5175. if (!XML_Parse (Parser, transBuffer, tmpLen, 1))
  5176. {
  5177. if (!XMLrootClosed)
  5178. XmlParseError (errorNotWellFormed,
  5179. (unsigned char *) XML_ErrorString (XML_GetErrorCode (Parser)), 0);
  5180. }
  5181. PARSING_BUFFER = FALSE;
  5182. if (transBuffer != NULL)
  5183. TtaFreeMemory (transBuffer);
  5184. }
  5185. /* Free expat parser */
  5186. FreeXmlParserContexts ();
  5187. FreeExpatParser ();
  5188. /* Handle character-level elements which contain block-level elements */
  5189. if ((schemaName != NULL) &&
  5190. (strcmp ((char *)schemaName, "HTML") == 0))
  5191. {
  5192. TtaSetStructureChecking (FALSE, doc);
  5193. CheckBlocksInCharElem (doc);
  5194. TtaSetStructureChecking (TRUE, doc);
  5195. }
  5196. /* Restore the display mode */
  5197. if (dispMode == DisplayImmediately)
  5198. TtaSetDisplayMode (doc, dispMode);
  5199. return (!XMLNotWellFormed);
  5200. }
  5201. /*----------------------------------------------------------------------
  5202. ParseIncludedXml
  5203. Parse a XML sub-tree included in a HTML document and complete the
  5204. corresponding Thot abstract tree.
  5205. Xml sub-tree is given in infile or htmlBuffer, one parameter should
  5206. be null
  5207. Return TRUE if the parsing of the sub-tree has no error.
  5208. ----------------------------------------------------------------------*/
  5209. ThotBool ParseIncludedXml (FILE *infile, char **infileBuffer, int infileBufferLength,
  5210. ThotBool *infileEnd, ThotBool *infileNotToRead,
  5211. char *infilePreviousBuffer, int *infileLastChar,
  5212. char *htmlBuffer, int *index,
  5213. int *nbLineRead, int *nbCharRead,
  5214. char *typeName, Document doc,
  5215. Element *el,
  5216. ThotBool *isclosed,
  5217. Language lang)
  5218. {
  5219. int tmpLen = 0;
  5220. int offset = 0;
  5221. int i;
  5222. ElementType elType;
  5223. char *schemaName;
  5224. char *tmpBuffer = NULL;
  5225. CHARSET charset;
  5226. ThotBool endOfParsing = FALSE;
  5227. ThotBool found;
  5228. if (infile == NULL && htmlBuffer == NULL)
  5229. return TRUE;
  5230. /* general initialization */
  5231. /* If htmlBuffer isn't null, we are parging a html sub-tree */
  5232. /* including XML elements */
  5233. RootElement = NULL;
  5234. if (htmlBuffer == NULL)
  5235. InitializeXmlParsingContext (doc, *el, *isclosed, FALSE);
  5236. else
  5237. InitializeXmlParsingContext (doc, *el, *isclosed, TRUE);
  5238. /* specific Initialization */
  5239. XMLcontext.language = lang;
  5240. DocumentSSchema = TtaGetDocumentSSchema (doc);
  5241. // it's a compound document
  5242. if (DocumentMeta[doc])
  5243. DocumentMeta[doc]->compound = TRUE;
  5244. /* Initialize counters */
  5245. ExtraLineRead = 0;
  5246. ExtraOffset = 0;
  5247. HtmlLineRead = *nbLineRead;
  5248. HtmlCharRead = *nbCharRead;
  5249. /* Expat initialization */
  5250. charset = TtaGetDocumentCharset (doc);
  5251. /* For HTML documents, the default charset is ISO_8859_1 */
  5252. if (charset == UNDEFINED_CHARSET)
  5253. charset = ISO_8859_1;
  5254. InitializeExpatParser (charset);
  5255. /* initialize all parser contexts */
  5256. if (FirstParserCtxt == NULL)
  5257. InitXmlParserContexts ();
  5258. if (typeName != NULL)
  5259. ChangeXmlParserContextByDTD (typeName);
  5260. else
  5261. {
  5262. elType = TtaGetElementType (XMLcontext.lastElement);
  5263. schemaName = TtaGetSSchemaName(elType.ElSSchema);
  5264. ChangeXmlParserContextByDTD (schemaName);
  5265. }
  5266. /* Parse a virtual DOCTYPE */
  5267. VirtualDoctype = TRUE;
  5268. if (!XML_Parse (Parser, DECL_DOCTYPE, DECL_DOCTYPE_LEN, 0))
  5269. XmlParseError (errorNotWellFormed,
  5270. (unsigned char *) XML_ErrorString (XML_GetErrorCode (Parser)), 0);
  5271. else
  5272. {
  5273. ExtraLineRead = XML_GetCurrentLineNumber (Parser);
  5274. ExtraOffset = XML_GetCurrentByteIndex (Parser);
  5275. }
  5276. /* Parse the input file or HTML buffer and complete the Thot document */
  5277. /* If htmlBuffer isn't null, we are parsing a XML sub-tree */
  5278. /* included in a transformation */
  5279. if (htmlBuffer)
  5280. {
  5281. /* parse the HTML buffer */
  5282. tmpBuffer = TtaStrdup (&htmlBuffer[*index]);
  5283. tmpLen = strlen ((char *)tmpBuffer);
  5284. if (!XML_Parse (Parser, tmpBuffer, tmpLen, 1))
  5285. if (!XMLrootClosed)
  5286. XmlParseError (errorNotWellFormed,
  5287. (unsigned char *) XML_ErrorString (XML_GetErrorCode (Parser)), 0);
  5288. }
  5289. else
  5290. {
  5291. /* read and parse the HTML file sequentialy */
  5292. while (!endOfParsing && !XMLNotWellFormed)
  5293. {
  5294. if (tmpBuffer)
  5295. {
  5296. TtaFreeMemory (tmpBuffer);
  5297. tmpBuffer = NULL;
  5298. }
  5299. if (*index == 0)
  5300. {
  5301. if (*infileNotToRead)
  5302. // work on the previous buffer
  5303. *infileNotToRead = FALSE;
  5304. else
  5305. {
  5306. GetNextHTMLbuffer (infile, infileEnd, infileBuffer, infileLastChar);
  5307. if (*infileEnd)
  5308. endOfParsing = TRUE;
  5309. }
  5310. }
  5311. if (*infileNotToRead)
  5312. {
  5313. tmpLen = strlen ((char *)infilePreviousBuffer) - *index;
  5314. tmpBuffer = (char *)TtaGetMemory (tmpLen);
  5315. for (i = 0; i < tmpLen; i++)
  5316. tmpBuffer[i] = infilePreviousBuffer[*index + i];
  5317. }
  5318. else
  5319. {
  5320. if (endOfParsing)
  5321. tmpLen = *infileLastChar - *index;
  5322. else
  5323. tmpLen = strlen ((char *)(*infileBuffer)) - *index;
  5324. tmpBuffer = TtaStrdup (&(*infileBuffer)[*index]);
  5325. }
  5326. if (!XML_Parse (Parser, tmpBuffer, tmpLen, endOfParsing))
  5327. {
  5328. if (XMLrootClosed)
  5329. endOfParsing = TRUE;
  5330. else
  5331. XmlParseError (errorNotWellFormed,
  5332. (unsigned char *) XML_ErrorString (XML_GetErrorCode (Parser)), 0);
  5333. }
  5334. else
  5335. {
  5336. *index = 0;
  5337. ExtraOffset = ExtraOffset + tmpLen;
  5338. }
  5339. }
  5340. }
  5341. /* return char/lines read */
  5342. if (htmlBuffer == NULL)
  5343. {
  5344. if (XML_GetCurrentLineNumber (Parser) - ExtraLineRead <= 0)
  5345. /* We stay on the same line */
  5346. *nbCharRead += XML_GetCurrentColumnNumber (Parser);
  5347. else
  5348. {
  5349. /* We read at least one new line */
  5350. *nbLineRead = *nbLineRead + XML_GetCurrentLineNumber (Parser) - ExtraLineRead;
  5351. *nbCharRead = XML_GetCurrentColumnNumber (Parser);
  5352. }
  5353. }
  5354. /* We look for the '>' character of the XML end tag */
  5355. offset = XML_GetCurrentByteIndex (Parser) - ExtraOffset - 1;
  5356. found = FALSE;
  5357. i = offset;
  5358. while (i >= 0 && !found)
  5359. {
  5360. if (tmpBuffer[i] == '>')
  5361. found = TRUE;
  5362. else
  5363. i--;
  5364. }
  5365. if (found)
  5366. {
  5367. i++;
  5368. *index += i;
  5369. }
  5370. else
  5371. *index += offset;
  5372. *el = XMLcontext.lastElement;
  5373. *isclosed = XMLcontext.lastElementClosed;
  5374. if (tmpBuffer != NULL)
  5375. TtaFreeMemory (tmpBuffer);
  5376. /* Free expat parser */
  5377. FreeXmlParserContexts ();
  5378. FreeExpatParser ();
  5379. return (!XMLNotWellFormed);
  5380. }
  5381. /*---------------------------------------------------------------------------
  5382. XmlParse
  5383. Parses the XML file infile and builds the equivalent Thot abstract tree.
  5384. The parameter skipDec is TRUE when the declaration should be sipped.
  5385. ---------------------------------------------------------------------------*/
  5386. static void XmlParse (FILE *infile, CHARSET charset, ThotBool *xmlDec,
  5387. ThotBool *xmlDoctype)
  5388. {
  5389. #define COPY_BUFFER_SIZE 1024
  5390. char bufferRead[COPY_BUFFER_SIZE + 1];
  5391. char *buffer;
  5392. int i, j;
  5393. int res;
  5394. int tmpLineRead = 0;
  5395. ThotBool beginning;
  5396. ThotBool endOfFile = FALSE, okay;
  5397. if (infile != NULL)
  5398. endOfFile = FALSE;
  5399. else
  5400. return;
  5401. /* Initialize global counters */
  5402. ExtraLineRead = 0;
  5403. ExtraOffset = 0;
  5404. HtmlLineRead = 0;
  5405. HtmlCharRead = 0;
  5406. /* add a null character at the end of the buffer by security */
  5407. bufferRead[COPY_BUFFER_SIZE] = EOS;
  5408. beginning = TRUE;
  5409. while (!endOfFile && !XMLNotWellFormed && !XMLInvalidToken)
  5410. {
  5411. /* read the XML file */
  5412. res = gzread (infile, bufferRead, COPY_BUFFER_SIZE);
  5413. if (res < 0)
  5414. return;
  5415. if (res < COPY_BUFFER_SIZE)
  5416. {
  5417. endOfFile = TRUE;
  5418. /* add a null character at the end of the buffer by security */
  5419. bufferRead[res] = EOS;
  5420. }
  5421. i = 0;
  5422. if (beginning)
  5423. {
  5424. if ((unsigned char) bufferRead[0] == EOL)
  5425. {
  5426. /* accept a newline before the XML declaration */
  5427. i = 1;
  5428. res = res - 1;
  5429. HtmlLineRead = 1;
  5430. }
  5431. beginning = FALSE;
  5432. }
  5433. if (*xmlDec)
  5434. /* There is an XML declaration */
  5435. /* We look for the first '>' character */
  5436. {
  5437. j = i;
  5438. while ((bufferRead[i] != '>') && i < res)
  5439. i++;
  5440. if (i < res)
  5441. {
  5442. i++;
  5443. res = res - (i-j);
  5444. }
  5445. /* The declaration is skipped */
  5446. *xmlDec = FALSE;
  5447. }
  5448. if (!*xmlDoctype)
  5449. /* There is no DOCTYPE Declaration
  5450. We include a virtual DOCTYPE declaration so that EXPAT parser
  5451. doesn't stop processing when it finds an external entity */
  5452. {
  5453. /* Virtual DOCTYPE Declaration */
  5454. if (!XMLNotWellFormed)
  5455. {
  5456. VirtualDoctype = TRUE;
  5457. tmpLineRead = XML_GetCurrentLineNumber (Parser);
  5458. if (!XML_Parse (Parser, DECL_DOCTYPE, DECL_DOCTYPE_LEN, 0))
  5459. XmlParseError (errorNotWellFormed,
  5460. (unsigned char *) XML_ErrorString (XML_GetErrorCode (Parser)), 0);
  5461. /* The Doctype is now parsed */
  5462. *xmlDoctype = TRUE;
  5463. ExtraLineRead = ExtraLineRead + XML_GetCurrentLineNumber (Parser) - tmpLineRead;
  5464. }
  5465. }
  5466. /* Standard EXPAT processing */
  5467. if (!XMLNotWellFormed)
  5468. {
  5469. okay = TRUE;
  5470. if (charset == ISO_8859_2 || charset == ISO_8859_3 ||
  5471. charset == ISO_8859_4 || charset == ISO_8859_5 ||
  5472. charset == ISO_8859_6 || charset == ISO_8859_7 ||
  5473. charset == ISO_8859_8 || charset == ISO_8859_9 ||
  5474. charset == ISO_8859_15 || charset == KOI8_R ||
  5475. charset == WINDOWS_1250 || charset == WINDOWS_1251 ||
  5476. charset == WINDOWS_1252 || charset == WINDOWS_1253 ||
  5477. charset == WINDOWS_1254 || charset == WINDOWS_1255 ||
  5478. charset == WINDOWS_1256 || charset == WINDOWS_1257 ||
  5479. charset == ISO_2022_JP || charset == EUC_JP ||
  5480. charset == SHIFT_JIS || charset == GB_2312)
  5481. {
  5482. /* convert the original stream into UTF-8 */
  5483. buffer = (char *)TtaConvertByteToMbs ((unsigned char *)&bufferRead[i], charset);
  5484. if (buffer)
  5485. {
  5486. okay = (XML_Parse(Parser, buffer, strlen ((char *)buffer), endOfFile) != XML_STATUS_ERROR);
  5487. TtaFreeMemory (buffer);
  5488. }
  5489. }
  5490. else
  5491. okay = (XML_Parse(Parser, &bufferRead[i], res, endOfFile) != XML_STATUS_ERROR);
  5492. if (okay == XML_STATUS_ERROR)
  5493. XmlParseError (errorNotWellFormed,
  5494. (unsigned char *) XML_ErrorString (XML_GetErrorCode (Parser)), 0);
  5495. }
  5496. }
  5497. }
  5498. /*------------------------------------------------------------------------------
  5499. StartXmlParser
  5500. Loads the file Directory/xmlFileName for displaying the document documentName.
  5501. The parameter pathURL gives the original (local or distant) path
  5502. or URL of the xml document.
  5503. ------------------------------------------------------------------------------*/
  5504. void StartXmlParser (Document doc, char *fileName,
  5505. char *documentName, char *documentDirectory,
  5506. char *pathURL, ThotBool withDec,
  5507. ThotBool withDoctype, ThotBool useMath, ThotBool externalDoc)
  5508. {
  5509. Element el, oldel;
  5510. CHARSET charset;
  5511. DisplayMode dispMode;
  5512. char tempname[MAX_LENGTH];
  5513. char temppath[MAX_LENGTH];
  5514. char *s;
  5515. int error;
  5516. ThotBool isXHTML, xmlDec, xmlDoctype;
  5517. ThotBool isXml = FALSE, isXtiger;
  5518. #ifdef TEMPLATES
  5519. // load the referred template if it's an instance
  5520. isXtiger = IsXTiger(pathURL);
  5521. if (!isXtiger)
  5522. Template_CheckAndPrepareInstance(fileName, doc, pathURL);
  5523. #endif /* TEMPLATES */
  5524. /* General initialization */
  5525. #ifdef ANNOTATIONS
  5526. if (DocumentTypes[doc] == docAnnot)
  5527. /* we search the start of HTML Root element in the annotation struct */
  5528. RootElement = ANNOT_GetHTMLRoot (doc, FALSE);
  5529. else
  5530. #endif /* ANNOTATIONS */
  5531. RootElement = TtaGetMainRoot (doc);
  5532. xmlDec = withDec;
  5533. xmlDoctype = withDoctype;
  5534. InitializeXmlParsingContext (doc, RootElement, FALSE, FALSE);
  5535. /* Specific Initialization */
  5536. XMLcontext.language = TtaGetDefaultLanguage ();
  5537. #ifdef ANNOTATIONS
  5538. if (DocumentTypes[doc] == docAnnot)
  5539. DocumentSSchema = ANNOT_GetBodySSchema (doc);
  5540. else
  5541. #endif /* ANNOTATIONS */
  5542. DocumentSSchema = TtaGetDocumentSSchema (doc);
  5543. /* Reading of the file */
  5544. stream = TtaGZOpen (fileName);
  5545. if (stream != 0)
  5546. {
  5547. if (documentName[0] == EOS &&
  5548. !TtaCheckDirectory (documentDirectory))
  5549. {
  5550. strcpy ((char *)documentName, (char *)documentDirectory);
  5551. documentDirectory[0] = EOS;
  5552. s = TtaGetEnvString ("PWD");
  5553. /* Set path on current directory */
  5554. if (s != NULL)
  5555. strcpy ((char *)documentDirectory, (char *)s);
  5556. else
  5557. documentDirectory[0] = EOS;
  5558. }
  5559. TtaAppendDocumentPath (documentDirectory);
  5560. /* Set document URL */
  5561. if (DocumentURLs[doc])
  5562. {
  5563. docURL = (char *)TtaGetMemory (strlen ((char *)DocumentURLs[doc]) + 1);
  5564. strcpy ((char *)docURL, (char *)DocumentURLs[doc]);
  5565. }
  5566. else
  5567. {
  5568. docURL = (char *)TtaGetMemory (strlen ((char *)pathURL) + 1);
  5569. strcpy ((char *)docURL, (char *)pathURL);
  5570. }
  5571. /* Set document URL2 */
  5572. if (docURL)
  5573. {
  5574. docURL2 = (char *)TtaGetMemory (strlen ((char *)docURL) + 1);
  5575. strcpy ((char *)docURL2, (char *)docURL);
  5576. }
  5577. /* Do not check the Thot abstract tree against the structure */
  5578. /* schema while building the Thot document. */
  5579. /* Some valid XHTML documents could be considered as invalid Thot documents */
  5580. /* For example, a <tbody> as a child of a <table> would be considered */
  5581. /* invalid because the Thot SSchema requires a Table_body element in between */
  5582. TtaSetStructureChecking (FALSE, doc);
  5583. /* Set the notification mode for the new document */
  5584. TtaSetNotificationMode (doc, 1);
  5585. dispMode = TtaGetDisplayMode (doc);
  5586. TtaSetDisplayMode (doc, NoComputedDisplay);
  5587. /* Delete all element except the root element */
  5588. el = TtaGetFirstChild (RootElement);
  5589. while (el != NULL)
  5590. {
  5591. oldel = el;
  5592. TtaNextSibling (&el);
  5593. TtaDeleteTree (oldel, doc);
  5594. }
  5595. /* Save the path or URL of the document */
  5596. TtaExtractName (pathURL, temppath, tempname);
  5597. TtaSetDocumentDirectory (doc, temppath);
  5598. // change the type of the root element if needed
  5599. s = TtaGetSSchemaName (DocumentSSchema);
  5600. if (DocumentTypes[doc] == docHTML && strcmp ((char *)s, "HTML"))
  5601. TtaUpdateRootElementType (RootElement, "HTML", doc);
  5602. else if (DocumentTypes[doc] == docSVG && strcmp ((char *)s, "SVG"))
  5603. TtaUpdateRootElementType (RootElement, "SVG", doc);
  5604. else if (DocumentTypes[doc] == docMath && strcmp ((char *)s, "MathML"))
  5605. TtaUpdateRootElementType (RootElement, "MathML", doc);
  5606. else if (DocumentTypes[doc] == docTemplate && strcmp ((char *)s, "Template"))
  5607. TtaUpdateRootElementType (RootElement, "Template", doc);
  5608. /* Initialize all parser contexts if not done yet */
  5609. if (FirstParserCtxt == NULL)
  5610. InitXmlParserContexts ();
  5611. /* Select root context */
  5612. isXHTML = FALSE;
  5613. DocumentSSchema = TtaGetDocumentSSchema (doc);
  5614. s = TtaGetSSchemaName (DocumentSSchema);
  5615. if (strcmp ((char *)s, "HTML") == 0)
  5616. {
  5617. ChangeXmlParserContextByDTD ("HTML");
  5618. isXHTML = TRUE;
  5619. }
  5620. else if (strcmp ((char *)s, "SVG") == 0)
  5621. ChangeXmlParserContextByDTD ("SVG");
  5622. else if (strcmp ((char *)s, "MathML") == 0)
  5623. ChangeXmlParserContextByDTD ("MathML");
  5624. else if (strcmp ((char *)s, "Template") == 0)
  5625. ChangeXmlParserContextByDTD ("Template");
  5626. else
  5627. #ifdef XML_GENERIC
  5628. {
  5629. ChangeXmlParserContextByDTD ("XML");
  5630. isXml = TRUE;
  5631. }
  5632. #else /* XML_GENERIC */
  5633. ChangeXmlParserContextByDTD ("HTML");
  5634. #endif /* XML_GENERIC */
  5635. /* Gets the document charset */
  5636. charset = TtaGetDocumentCharset (doc);
  5637. /* Specific initialization for Expat */
  5638. InitializeExpatParser (charset);
  5639. /* load the MathML nature if it's declared plus MathML */
  5640. if (useMath)
  5641. TtaNewNature (doc, DocumentSSchema, NULL, "MathML", "MathMLP");
  5642. /* Parse the input file and build the Thot tree */
  5643. XmlParse ((FILE*)stream, charset, &xmlDec, &xmlDoctype);
  5644. if (!externalDoc)
  5645. /* Load the style sheets for xml documents */
  5646. LoadXmlStyleSheet (doc);
  5647. /* Completes all unclosed elements */
  5648. if (CurrentParserCtxt != NULL)
  5649. {
  5650. el = XMLcontext.lastElement;
  5651. while (el != NULL)
  5652. {
  5653. (*(Proc3)(CurrentParserCtxt->ElementComplete)) (
  5654. (void *)&XMLcontext,
  5655. (void *)el,
  5656. (void *)&error);
  5657. el = TtaGetParent (el);
  5658. }
  5659. }
  5660. /* Check the Thot abstract tree for XHTML documents */
  5661. if (isXHTML)
  5662. {
  5663. CheckAbstractTree (XMLcontext.doc, isXtiger);
  5664. if (MapAreas[doc])
  5665. ChangeAttrOnRoot (doc, HTML_ATTR_ShowAreas);
  5666. }
  5667. FreeExpatParser ();
  5668. FreeXmlParserContexts ();
  5669. TtaGZClose (stream);
  5670. if (docURL)
  5671. {
  5672. TtaFreeMemory (docURL);
  5673. docURL = NULL;
  5674. }
  5675. if (docURL2)
  5676. {
  5677. TtaFreeMemory (docURL2);
  5678. docURL2 = NULL;
  5679. }
  5680. /* Display the document */
  5681. if (!externalDoc)
  5682. {
  5683. /* if (DocumentTypes[doc] == docHTML) */
  5684. /* Load specific user style only for an (X)HTML document */
  5685. /* For a generic XML document, it would create new element types
  5686. in the structure schema, one for each type appearing in a
  5687. selector in the User style sheet */
  5688. LoadUserStyleSheet (doc);
  5689. TtaSetDisplayMode (doc, dispMode);
  5690. UpdateStyleList (doc, 1);
  5691. }
  5692. /* Check the Thot abstract tree against the structure schema. */
  5693. TtaSetStructureChecking (TRUE, doc);
  5694. DocumentSSchema = NULL;
  5695. }
  5696. // if some included HTML elements affected HTML variables
  5697. ClearHTMLParser ();
  5698. TtaSetDocumentUnmodified (doc);
  5699. }
  5700. /* end of module */