Annotation of Amaya/amaya/templateInstantiate.c, revision 1.54
1.19 vatton 1: /*
2: *
3: * COPYRIGHT INRIA and W3C, 2006-2007
4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
7:
1.1 vatton 8: #include "templates.h"
9:
10: #define THOT_EXPORT extern
11: #include "templateDeclarations.h"
12:
1.8 kia 13: #include "Elemlist.h"
14:
1.41 vatton 15: #include "AHTURLTools_f.h"
1.1 vatton 16: #include "EDITimage_f.h"
17: #include "HTMLactions_f.h"
18: #include "HTMLsave_f.h"
1.34 vatton 19: #include "HTMLtable_f.h"
1.49 vatton 20: #include "html2thot_f.h"
1.1 vatton 21: #include "init_f.h"
22: #include "templates_f.h"
23: #include "templateDeclarations_f.h"
24: #include "templateInstantiate_f.h"
25: #include "Templatebuilder_f.h"
26: #include "templateUtils_f.h"
27: #include "fetchHTMLname_f.h"
28: #include "Template.h"
29:
30: #ifdef TEMPLATES
31: #define TEMPLATE_SCHEMA_NAME "Template"
32:
33: typedef struct _InstantiateCtxt
34: {
1.47 kia 35: char *templatePath;
36: char *instancePath;
37: char *schemaName;
1.41 vatton 38: Document doc;
1.47 kia 39: DocumentType docType;
40: ThotBool dontReplace;
1.1 vatton 41: } InstantiateCtxt;
42: #endif /* TEMPLATES */
43:
44:
1.49 vatton 45:
46: /*----------------------------------------------------------------------
47: Template_InsertRepeatChildAfter
48: Insert a child to a xt:repeat
49: The decl parameter must be valid and will not be verified. It must be a
50: direct child element or the "use in the use" for union elements.
51: @param el element (xt:repeat) in which insert a new element
52: @param decl Template declaration of the element to insert
53: @param elPrev Element (xt:use) after which insert the new elem, NULL if first.
54: @return The inserted element
55: ----------------------------------------------------------------------*/
56: Element Template_InsertRepeatChildAfter (Document doc, Element el,
57: Declaration decl, Element elPrev)
58: {
59: #ifdef TEMPLATES
60: Element useFirst; /* First xt:use of the repeat.*/
61: Element use; /* xt:use to insert.*/
62: ElementType useType; /* type of xt:use.*/
63:
64: if (!TtaGetDocumentAccessMode (doc))
65: return NULL;
66:
67: /* Copy xt:use with xt:types param */
68: useFirst = TtaGetFirstChild (el);
69: useType = TtaGetElementType (useFirst);
70: use = TtaCopyElement (useFirst, doc, doc, el);
71:
1.51 kia 72: TtaChangeElementType(use, Template_EL_useSimple);
73:
1.49 vatton 74: /* insert it */
75: if (elPrev)
76: TtaInsertSibling(use, elPrev, FALSE, doc);
77: else
78: TtaInsertSibling(use, useFirst, TRUE, doc);
79: Template_InsertUseChildren(doc, use, decl);
80:
81: TtaRegisterElementCreate (use, doc);
82: return use;
83: #else /* TEMPLATES */
84: return NULL;
85: #endif /* TEMPLATES */
86: }
87:
88: /*----------------------------------------------------------------------
89: Template_InsertRepeatChild
90: Insert a child to a xt:repeat
91: The decl parameter must be valid and will not be verified. It must be a
92: direct child element or the "use in the use" for union elements.
93: @param el element (repeat) in which insert a new element
94: @param decl Template declaration of the element to insert
95: @param pos Position of insertion (0 before all, 1 after first ... -1 after all)
96: @return The inserted element
97: ----------------------------------------------------------------------*/
98: Element Template_InsertRepeatChild (Document doc, Element el, Declaration decl, int pos)
99: {
100: #ifdef TEMPLATES
101: if (!TtaGetDocumentAccessMode(doc) || !decl)
102: return NULL;
103:
104: if (pos == 0)
105: return Template_InsertRepeatChildAfter (doc, el, decl, NULL);
106: else if (pos == -1)
107: return Template_InsertRepeatChildAfter (doc, el, decl, TtaGetLastChild(el));
108: else
109: {
110: Element elem = TtaGetFirstChild(el);
111: pos--;
112: while (pos > 0)
113: {
114: TtaNextSibling(&elem);
115: pos--;
116: }
117: return Template_InsertRepeatChildAfter (doc, el, decl, elem);
118: }
119: #else /* TEMPLATES */
120: return NULL;
121: #endif /* TEMPLATES */
122: }
123:
124:
125: /*----------------------------------------------------------------------
126: Template_InsertBagChild
127: Insert a child to a xt:bag at the current insertion point.
128: The decl parameter must be valid and will not be verified.
129: @param el element (xt:bag) in which insert a new element
130: @param decl Template declaration of the element to insert
131: @return The inserted element
132: ----------------------------------------------------------------------*/
1.53 kia 133: Element Template_InsertBagChild (Document doc, Element el, Declaration decl, ThotBool before)
1.49 vatton 134: {
135: #ifdef TEMPLATES
136: Element sel;
137: ElementType newElType, selType;
138: int start, end;
139:
140: if (!TtaGetDocumentAccessMode (doc) || !decl)
141: return NULL;
142:
143: TtaGiveFirstSelectedElement (doc, &sel, &start, &end);
144: if (TtaIsAncestor (sel, el))
145: {
146: newElType.ElSSchema = TtaGetSSchema ("Template", doc);
147: if (decl->nature == UnionNat)
148: newElType.ElTypeNum = Template_EL_useEl;
149: else
150: newElType.ElTypeNum = Template_EL_useSimple;
151:
152: selType = TtaGetElementType (sel);
153: if (decl->blockLevel &&
154: (TtaIsLeaf (selType) || !IsTemplateElement (sel)))
155: {
156: // force the insertion of a block level element at the right position
157: while (sel && IsCharacterLevelElement (sel))
158: sel = TtaGetParent (sel);
159: if (sel)
160: TtaSelectElement (doc, sel);
1.53 kia 161: TtaInsertAnyElement (doc, before);
1.49 vatton 162: }
163: TtaInsertElement (newElType, doc);
164: TtaGiveFirstSelectedElement (doc, &sel, &start, &end);
165: if (sel)
166: {
167: selType = TtaGetElementType (sel);
168: TtaUnselect (doc);
169:
170: if (selType.ElSSchema == newElType.ElSSchema &&
171: selType.ElTypeNum == Template_EL_useSimple)
172: {
173: SetAttributeStringValueWithUndo (sel, Template_ATTR_types, decl->name);
174: SetAttributeStringValueWithUndo (sel, Template_ATTR_title, decl->name);
175: Template_InsertUseChildren (doc, sel, decl);
176: }
177: return sel;
178: }
179: }
180: #endif /* TEMPLATES */
181: return NULL;
182: }
183:
1.1 vatton 184: /*----------------------------------------------------------------------
185: CreateInstance
1.41 vatton 186: basedoc is the displayed doc that launchs the creation of instance
1.3 vatton 187: ----------------------------------------------------------------------*/
1.41 vatton 188: void CreateInstance(char *templatePath, char *instancePath, int basedoc)
1.3 vatton 189: {
1.1 vatton 190: #ifdef TEMPLATES
1.41 vatton 191: Document doc = 0, newdoc = 0;
192: DocumentType docType;
193: ElementType elType;
194: Element root, title, text;
1.54 ! vatton 195: CHARSET charset;
! 196: char *localFile, *s, *charsetname;
1.1 vatton 197:
1.35 kia 198: XTigerTemplate t = GetXTigerTemplate(templatePath);
1.1 vatton 199: if (t == NULL)
1.29 vatton 200: {
201: // the template cannot be loaded
202: InitConfirm (doc, 1, TtaGetMessage (AMAYA, AM_BAD_TEMPLATE));
203: return;
204: }
1.41 vatton 205: // the template document
1.5 vatton 206: doc = GetTemplateDocument (t);
1.41 vatton 207: // localize the new created document
208: if (DontReplaceOldDoc)
209: newdoc = TtaGetNextDocumentIndex ();
210: else
211: newdoc = basedoc;
1.54 ! vatton 212:
1.41 vatton 213: localFile = GetLocalPath (newdoc, instancePath);
1.1 vatton 214: if (!TtaPrepareUndo (doc))
215: {
216: TtaOpenUndoSequence (doc, NULL, NULL, 0, 0);
1.14 vatton 217: root = TtaGetRootElement(doc);
218: elType = TtaGetElementType (root);
219: // get the target document type
220: s = TtaGetSSchemaName (elType.ElSSchema);
221: if (strcmp (s, "HTML") == 0)
222: docType = docHTML;
223: else if (strcmp (s, "SVG") == 0)
224: docType = docSVG;
225: else if (strcmp (s, "MathML") == 0)
226: docType = docMath;
227: else
228: docType = docXml;
1.30 vatton 229: // update all links
1.33 vatton 230: SetRelativeURLs (doc, instancePath, "", FALSE, FALSE, FALSE);
1.41 vatton 231:
232: // prepare the new document view
233: TtaExtractName (instancePath, DirectoryName, DocumentName);
234: // save in the local path
1.1 vatton 235: switch (docType)
236: {
1.14 vatton 237: case docSVG:
1.41 vatton 238: TtaExportDocumentWithNewLineNumbers (doc, localFile, "SVGT");
1.1 vatton 239: break;
1.14 vatton 240: case docMath:
1.41 vatton 241: TtaExportDocumentWithNewLineNumbers (doc, localFile, "MathMLT");
1.1 vatton 242: break;
1.14 vatton 243: case docHTML:
244: // Initialize the document title
245: elType.ElTypeNum = HTML_EL_TITLE;
246: title = TtaSearchTypedElement (elType, SearchInTree, root);
247: text = TtaGetFirstChild (title);
248: while (text)
249: {
250: elType = TtaGetElementType (text);
251: if (elType.ElTypeNum == HTML_EL_TEXT_UNIT && Answer_text[0] != EOS)
252: {
253: TtaSetTextContent (text, (unsigned char*)Answer_text,
254: TtaGetDefaultLanguage (), doc);
255: text = NULL;
256: }
257: else if ((elType.ElTypeNum == Template_EL_useEl ||
258: elType.ElTypeNum == Template_EL_useSimple) &&
259: !strcmp (TtaGetSSchemaName (elType.ElSSchema), "Template"))
260: // Ignore the template use element
261: text = TtaGetFirstChild (text);
262: else
263: // Look for the first text child
264: TtaNextSibling (&text);
265: }
1.54 ! vatton 266:
! 267: // update the charset if needed
! 268: charsetname = TtaGetEnvString ("DOCUMENT_CHARSET");
! 269: charset = TtaGetCharset (charsetname);
! 270: if (charset != UNDEFINED_CHARSET && strcmp (charsetname, DocumentMeta[doc]->charset))
! 271: {
! 272: TtaSetDocumentCharset (doc, charset, FALSE);
! 273: DocumentMeta[doc]->charset = TtaStrdup (charsetname);
! 274: SetNamespacesAndDTD (doc);
! 275: }
! 276:
! 277: // export the document
1.41 vatton 278: if (TtaGetDocumentProfile(doc) == L_Xhtml11 ||
279: TtaGetDocumentProfile(doc) == L_Basic)
280: TtaExportDocumentWithNewLineNumbers (doc, localFile, "HTMLT11");
1.1 vatton 281: else
1.41 vatton 282: TtaExportDocumentWithNewLineNumbers (doc, localFile, "HTMLTX");
1.1 vatton 283: break;
1.14 vatton 284: default:
1.41 vatton 285: TtaExportDocumentWithNewLineNumbers (doc, localFile, NULL);
1.1 vatton 286: break;
287: }
1.47 kia 288:
1.1 vatton 289: TtaCloseUndoSequence (doc);
290: TtaUndoNoRedo (doc);
291: TtaClearUndoHistory (doc);
1.41 vatton 292: RemoveParsingErrors (doc);
293: GetAmayaDoc (instancePath, NULL, basedoc, basedoc, CE_INSTANCE,
294: !DontReplaceOldDoc, NULL, NULL);
295: TtaSetDocumentModified (newdoc);
1.1 vatton 296: }
1.41 vatton 297: TtaFreeMemory (localFile);
1.1 vatton 298: #endif /* TEMPLATES */
299: }
300:
301: /*----------------------------------------------------------------------
1.3 vatton 302: ----------------------------------------------------------------------*/
1.41 vatton 303: void InstantiateTemplate_callback (int newdoc, int status, char *urlName,
304: char *outputfile,
305: char *proxyName, AHTHeaders *http_headers,
306: void * context)
1.1 vatton 307: {
308: #ifdef TEMPLATES
1.47 kia 309: InstantiateCtxt *ctx = (InstantiateCtxt*)context;
1.1 vatton 310:
1.47 kia 311: DoInstanceTemplate (ctx->templatePath);
1.41 vatton 312: CreateInstance (ctx->templatePath, ctx->instancePath, ctx->doc);
1.1 vatton 313: TtaFreeMemory (ctx->templatePath);
314: TtaFreeMemory (ctx->instancePath);
315: TtaFreeMemory (ctx);
316: #endif /* TEMPLATES */
317: }
318:
319: /*----------------------------------------------------------------------
1.3 vatton 320: ----------------------------------------------------------------------*/
1.1 vatton 321: void InstantiateTemplate (Document doc, char *templatename, char *docname,
322: DocumentType docType, ThotBool loaded)
323: {
324: #ifdef TEMPLATES
1.47 kia 325: if (!loaded)
1.3 vatton 326: {
327: // Create the callback context
328: InstantiateCtxt *ctx = (InstantiateCtxt *)TtaGetMemory (sizeof (InstantiateCtxt));
329: ctx->templatePath = TtaStrdup (templatename);
330: ctx->instancePath = TtaStrdup (docname);
331: ctx->schemaName = GetSchemaFromDocType(docType);
1.41 vatton 332: ctx->doc = doc;
1.3 vatton 333: ctx->docType = docType;
1.47 kia 334:
1.3 vatton 335: GetAmayaDoc (templatename, NULL, doc, doc, CE_MAKEBOOK, FALSE,
1.41 vatton 336: (void (*)(int, int, char*, char*, char*,
337: const AHTHeaders*, void*)) InstantiateTemplate_callback,
1.3 vatton 338: (void *) ctx);
339: }
1.47 kia 340: else
1.1 vatton 341: {
342: DoInstanceTemplate (templatename);
1.41 vatton 343: CreateInstance (templatename, docname, doc);
1.3 vatton 344: }
1.1 vatton 345: #endif /* TEMPLATES */
346: }
347:
348: /*----------------------------------------------------------------------
349: InstantiateAttribute
1.3 vatton 350: ----------------------------------------------------------------------*/
1.1 vatton 351: static void InstantiateAttribute (XTigerTemplate t, Element el, Document doc)
352: {
353: #ifdef TEMPLATES
354: AttributeType useType, nameType, defaultType, attrType;
355: Attribute useAttr, nameAttr, defAttr, attr;
356: ElementType elType;
357: Element parent;
358: char *text, *elementName;
359: ThotBool level;
360: NotifyAttribute event;
1.48 kia 361: int val;
1.1 vatton 362:
363: parent = TtaGetParent (el);
364: if (!parent)
365: return;
366: // if attribute "use" has value "optional", don't do anything
367: useType.AttrSSchema = TtaGetSSchema (TEMPLATE_SCHEMA_NAME, doc);
368: useType.AttrTypeNum = Template_ATTR_useAt;
369: useAttr = TtaGetAttribute (el, useType);
370: if (useAttr)
371: // there is a "use" attribute. Check its value
372: {
1.48 kia 373: val = TtaGetAttributeValue(useAttr);
374: if (val == Template_ATTR_useAt_VAL_optional)
1.18 kia 375: {
376: return;
377: }
1.1 vatton 378: }
1.18 kia 379:
1.1 vatton 380: // get the "name" and "default" attributes
381: nameType.AttrSSchema = defaultType.AttrSSchema = TtaGetSSchema (TEMPLATE_SCHEMA_NAME, doc);
1.9 vatton 382: nameType.AttrTypeNum = Template_ATTR_ref_name;
1.1 vatton 383: defaultType.AttrTypeNum = Template_ATTR_defaultAt;
384: nameAttr = TtaGetAttribute (el, nameType);
385: defAttr = TtaGetAttribute (el, defaultType);
386: if (nameAttr)
387: {
1.10 kia 388: text = GetAttributeStringValue (el, nameAttr, NULL);
1.1 vatton 389: if (text)
390: {
391: elType = TtaGetElementType (parent);
392: elementName = TtaGetElementTypeName (elType);
393: level = TRUE;
394: MapHTMLAttribute (text, &attrType, elementName, &level, doc);
395: TtaFreeMemory(text);
396: attr = TtaNewAttribute (attrType);
397: if (attr)
398: {
399: TtaAttachAttribute (parent, attr, doc);
400: if (defAttr)
401: {
1.10 kia 402: text = GetAttributeStringValue (el, defAttr, NULL);
1.25 vatton 403: if (text)
1.18 kia 404: TtaSetAttributeText(attr, text, parent, doc);
1.1 vatton 405: TtaFreeMemory(text);
406: // if it's a src arttribute for an image, load the image
407: if (!strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") &&
408: elType.ElTypeNum == HTML_EL_IMG)
409: if (attrType.AttrTypeNum == HTML_ATTR_SRC &&
410: attrType.AttrSSchema == elType.ElSSchema)
411: {
412: event.document = doc;
413: event.element = parent;
414: event.attribute = attr;
415: SRCattrModified (&event);
416: }
417: }
418: }
419: }
420: }
421: #endif /* TEMPLATES */
422: }
423:
424: #ifdef TEMPLATES
425: /*----------------------------------------------------------------------
426: ProcessAttr
1.9 vatton 427: Look for all "attribute" elements in the subtree and instantiate them
1.3 vatton 428: ----------------------------------------------------------------------*/
1.1 vatton 429: static void ProcessAttr (XTigerTemplate t, Element el, Document doc)
430: {
431: Element child;
432: ElementType elType;
433:
434: for (child = TtaGetFirstChild (el); child; TtaNextSibling(&child))
435: {
436: elType = TtaGetElementType (child);
437: if (elType.ElTypeNum == Template_EL_attribute &&
438: !strcmp (TtaGetSSchemaName (elType.ElSSchema), TEMPLATE_SCHEMA_NAME))
439: InstantiateAttribute (t, child, doc);
440: else
441: ProcessAttr (t, child, doc);
442: }
443: }
444: #endif /* TEMPLATES */
445:
1.12 kia 446:
447: /*----------------------------------------------------------------------
448: Template_GetNewSimpleTypeInstance
449: Create an new instance of xt:use/SimpleType
450: The decl attribute must embed SimpleType declaration (no validation).
451: @param decl Declaration of new element
452: @param parent Future parent element
453: @param doc Document
454: @return The new element
455: ----------------------------------------------------------------------*/
456: Element Template_GetNewSimpleTypeInstance(Document doc, Element parent, Declaration decl)
457: {
458: Element newEl = NULL;
459: #ifdef TEMPLATES
460: ElementType elType;
461: char *empty = " ";
1.24 vatton 462:
1.38 vatton 463: elType.ElSSchema = TtaGetSSchema("Template", doc);
1.12 kia 464: elType.ElTypeNum = Template_EL_TEXT_UNIT;
465: newEl = TtaNewElement (doc, elType);
466: TtaSetTextContent (newEl, (unsigned char*) empty, 0, doc);
1.24 vatton 467: #endif /* TEMPLATES */
1.12 kia 468: return newEl;
469: }
470:
471: /*----------------------------------------------------------------------
472: Template_GetNewXmlElementInstance
473: Create an new instance of xt:use/XmlElement
474: The decl attribute must embed XmlElement declaration (no validation).
475: @param decl Declaration of new element
476: @param parent Future parent element
477: @param doc Document
478: @return The new element
479: ----------------------------------------------------------------------*/
480: Element Template_GetNewXmlElementInstance(Document doc, Element parent, Declaration decl)
481: {
482: Element newEl = NULL;
483: #ifdef TEMPLATES
484: ElementType elType;
485:
1.24 vatton 486: GIType (decl->name, &elType, doc);
487: if (elType.ElTypeNum != 0)
1.12 kia 488: {
1.23 kia 489: newEl = TtaNewTree (doc, elType, "");
1.12 kia 490: }
491: #endif /* TEMPLATES */
492: return newEl;
493: }
494:
1.34 vatton 495:
496: /*----------------------------------------------------------------------
497: InsertWithNotify applies pre and post functions when inserting the new
498: element el after child (if not NULL) or as first child of parent.
499: ----------------------------------------------------------------------*/
500: Element InsertWithNotify (Element el, Element child, Element parent, Document doc)
501: {
502: ElementType elType;
503: NotifyElement event;
504: char *name;
505: ThotBool isRow = FALSE, isCell = FALSE;
1.50 vatton 506: ThotBool isImage = FALSE;
507: ThotBool oldStructureChecking;
508:
509: // avoid to check attributes now
510: oldStructureChecking = TtaGetStructureChecking (doc);
511: TtaSetStructureChecking (FALSE, doc);
1.34 vatton 512:
513: elType = TtaGetElementType (el);
514: name = TtaGetSSchemaName (elType.ElSSchema);
515: isCell = ((!strcmp (name,"HTML") &&
516: elType.ElTypeNum == HTML_EL_Data_cell ||
517: elType.ElTypeNum == HTML_EL_Heading_cell) ||
518: (!strcmp (name,"MathML") && elType.ElTypeNum == MathML_EL_MTD));
519: isRow = ((!strcmp (name,"HTML") && elType.ElTypeNum == HTML_EL_Table_row) ||
520: (!strcmp (name,"MathML") &&
521: (elType.ElTypeNum == MathML_EL_MTR ||
522: elType.ElTypeNum == MathML_EL_MLABELEDTR)));
1.50 vatton 523: isImage = (!strcmp (name,"HTML") &&
524: (elType.ElTypeNum == HTML_EL_IMG || elType.ElTypeNum == HTML_EL_Object));
1.34 vatton 525: if (child)
526: TtaInsertSibling (el, child, FALSE, doc);
527: else
528: TtaInsertFirstChild (&el, parent, doc);
1.50 vatton 529: TtaSetStructureChecking (oldStructureChecking, doc);
1.34 vatton 530:
1.50 vatton 531: if (isImage)
532: InsertImageOrObject (el, doc);
533: else if (isCell)
1.34 vatton 534: {
535: // a cell is created
1.39 quint 536: NewCell (el, doc, TRUE, TRUE, TRUE);
1.34 vatton 537: }
538: else if (isRow)
539: {
540: // a row is created
541: event.element = el;
542: event.document = doc;
543: RowPasted (&event);
544: }
1.50 vatton 545:
546: if (!strcmp (name,"HTML"))
547: {
548: elType.ElTypeNum = HTML_EL_IMG;
549: child = TtaSearchTypedElement (elType, SearchInTree, el);
550: while (child)
551: {
552: InsertImageOrObject (child, doc);
553: child = TtaSearchTypedElementInTree (elType, SearchForward, el, child);
554: }
555: elType.ElTypeNum = HTML_EL_Object;
556: child = TtaSearchTypedElement (elType, SearchInTree, el);
557: while (child)
558: {
559: InsertImageOrObject (child, doc);
560: child = TtaSearchTypedElementInTree (elType, SearchForward, el, child);
561: }
562: }
1.34 vatton 563: return el;
564: }
565:
566:
1.12 kia 567: /*----------------------------------------------------------------------
1.16 kia 568: Template_InsertUseChildren
569: Insert children to a xt:use
570: The dec parameter must be valid and will not be verified. It must be a
571: direct child element (for union elements).
572: @param el element (xt:use) in which insert a new element
573: @param dec Template declaration of the element to insert
574: @return The inserted element (the xt:use element if insertion is multiple as component)
575: ----------------------------------------------------------------------*/
576: Element Template_InsertUseChildren(Document doc, Element el, Declaration dec)
577: {
1.34 vatton 578: Element newEl = NULL;
1.16 kia 579: #ifdef TEMPLATES
1.19 vatton 580: Element current = NULL;
1.34 vatton 581: Element child = NULL;
1.19 vatton 582: //char *attrCurrentTypeValue;
583: //ElementType elType;
1.17 kia 584:
1.25 vatton 585: if (TtaGetDocumentAccessMode(doc))
1.16 kia 586: {
1.23 kia 587: switch (dec->nature)
588: {
589: case SimpleTypeNat:
590: newEl = Template_GetNewSimpleTypeInstance(doc, el, dec);
1.34 vatton 591: newEl = InsertWithNotify (newEl, NULL, el, doc);
1.23 kia 592: break;
593: case XmlElementNat:
594: newEl = Template_GetNewXmlElementInstance(doc, el, dec);
1.34 vatton 595: newEl = InsertWithNotify (newEl, NULL, el, doc);
1.23 kia 596: break;
597: case ComponentNat:
598: newEl = TtaCopyTree(dec->componentType.content, doc, doc, el);
1.35 kia 599: ProcessAttr (dec->usedIn, newEl, doc);
1.23 kia 600: /* Copy elements from new use to existing use. */
1.34 vatton 601: while ((child = TtaGetFirstChild(newEl)))
1.23 kia 602: {
603: TtaRemoveTree (child, doc);
1.34 vatton 604: child = InsertWithNotify (child, current, el, doc);
1.23 kia 605: current = child;
606: }
607:
608: /* Copy currentType attribute. */
609: //attrCurrentTypeValue = GetAttributeStringValue (el, Template_ATTR_currentType, NULL);
610: //SetAttributeStringValue (el, Template_ATTR_currentType, attrCurrentTypeValue);
611: TtaDeleteTree(newEl, doc);
612: newEl = el;
613: break;
614: case UnionNat :
615: /* Nothing to do.*/
616: // elType.ElTypeNum = Template_EL_useEl;
617: // cont = TtaNewElement (doc, elType);
618: // if (cont)
619: // {
620: // TtaSetAccessRight (cont, ReadWrite, doc);
621: // at = TtaNewAttribute (att);
622: // if (at)
623: // {
624: // TtaAttachAttribute (cont, at, doc);
625: // TtaSetAttributeText(at, types, cont, doc);
626: // }
627: // }
628: /* @@@@@ */
629: break;
630: default :
631: //Impossible
632: break;
633: }
1.44 kia 634: Template_FixAccessRight (dec->usedIn, el, doc);
635: TtaUpdateAccessRightInViews (doc, el);
1.23 kia 636: }
1.16 kia 637: #endif /* TEMPLATES */
638: return newEl;
639: }
640:
1.40 kia 641:
642: /*----------------------------------------------------------------------
643: Fix access rights.
644: ----------------------------------------------------------------------*/
1.41 vatton 645: void Template_FixAccessRight (XTigerTemplate t, Element el, Document doc)
1.40 kia 646: {
647: #ifdef TEMPLATES
648: ElementType elType;
649: Element child;
650: char currentType[MAX_LENGTH];
651: Declaration decl;
652:
653: if (t && el && doc)
654: {
655: elType = TtaGetElementType(el);
1.41 vatton 656: if (elType.ElSSchema == TtaGetSSchema ("Template", doc))
1.40 kia 657: {
1.41 vatton 658: switch (elType.ElTypeNum)
1.40 kia 659: {
660: case Template_EL_TEXT_UNIT:
1.41 vatton 661: //TtaSetAccessRight( el, ReadWrite, doc);
662: return;
1.40 kia 663: case Template_EL_useEl:
664: case Template_EL_useSimple:
665: GiveAttributeStringValueFromNum(el, Template_ATTR_currentType,
666: (char*)currentType, NULL);
667: decl = Template_GetDeclaration(t, currentType);
668: if (decl)
669: {
670: switch (decl->nature)
671: {
672: case SimpleTypeNat:
673: case XmlElementNat:
1.41 vatton 674: TtaSetAccessRight (el, ReadWrite, doc);
675: return;
1.40 kia 676: default:
1.41 vatton 677: TtaSetAccessRight (el, ReadOnly, doc);
678: break;
1.40 kia 679: }
680: }
681: break;
682: case Template_EL_bag:
1.45 vatton 683: case Template_EL_repeat:
1.40 kia 684: TtaSetAccessRight(el, ReadWrite, doc);
685: break;
686: default:
687: TtaSetAccessRight(el, ReadOnly, doc);
688: break;
689: }
690: }
691:
1.41 vatton 692: child = TtaGetFirstChild (el);
693: // fix access right to children
694: while (child)
1.40 kia 695: {
1.41 vatton 696: Template_FixAccessRight (t, child, doc);
697: TtaNextSibling (&child);
1.40 kia 698: }
699: }
700: #endif /* TEMPLATES */
701: }
702:
1.16 kia 703: /*----------------------------------------------------------------------
1.46 vatton 704: AddPromptIndicator
705: ----------------------------------------------------------------------*/
706: void AddPromptIndicator (Element el, Document doc)
707: {
708: #ifdef TEMPLATES
709: ElementType elType;
710: AttributeType attrType;
711: Attribute att;
712:
713: elType = TtaGetElementType (el);
714: attrType.AttrSSchema = elType.ElSSchema;
715: attrType.AttrTypeNum = Template_ATTR_prompt;
716: att = TtaNewAttribute (attrType);
717: TtaAttachAttribute (el, att, doc);
718: #endif /* TEMPLATES */
719: }
720:
721: /*----------------------------------------------------------------------
1.1 vatton 722: InstantiateUse
1.3 vatton 723: ----------------------------------------------------------------------*/
1.1 vatton 724: Element InstantiateUse (XTigerTemplate t, Element el, Document doc,
1.27 kia 725: ThotBool registerUndo)
1.1 vatton 726: {
727: #ifdef TEMPLATES
1.47 kia 728: Element cont = NULL;
1.1 vatton 729: ElementType elType;
730: Declaration dec;
1.28 kia 731: int size, nbitems, i;
1.1 vatton 732: struct menuType *items;
1.33 vatton 733: char *types, *text = NULL;
1.1 vatton 734: ThotBool oldStructureChecking;
735:
1.25 vatton 736: if (!t)
1.23 kia 737: return NULL;
738:
1.1 vatton 739: /* get the value of the "types" attribute */
740: cont = NULL;
1.12 kia 741: elType = TtaGetElementType (el);
1.46 vatton 742: AddPromptIndicator (el, doc);
1.32 vatton 743: types = GetAttributeStringValueFromNum (el, Template_ATTR_types, &size);
1.36 vatton 744: if (!types || types[0] == EOS)
745: {
746: TtaFreeMemory (types);
747: return NULL;
748: }
1.1 vatton 749: giveItems (types, size, &items, &nbitems);
750: // No structure checking
751: oldStructureChecking = TtaGetStructureChecking (doc);
752: TtaSetStructureChecking (FALSE, doc);
1.10 kia 753:
1.1 vatton 754: if (nbitems == 1)
755: /* only one type in the "types" attribute */
756: {
1.17 kia 757: dec = Template_GetDeclaration (t, items[0].label);
1.1 vatton 758: if (dec)
1.27 kia 759: {
1.46 vatton 760: cont = Template_InsertUseChildren (doc, el, dec);
1.32 vatton 761: if (cont)
1.27 kia 762: {
763: TtaChangeTypeOfElement (el, doc, Template_EL_useSimple);
1.32 vatton 764: if (registerUndo)
765: TtaRegisterElementTypeChange (el, Template_EL_useEl, doc);
1.27 kia 766: }
767: }
1.1 vatton 768: }
1.33 vatton 769: TtaFreeMemory (text);
1.32 vatton 770: TtaFreeMemory (types);
1.28 kia 771:
1.32 vatton 772: for (i = 0; i < nbitems; i++)
1.28 kia 773: TtaFreeMemory(items[i].label);
1.18 kia 774: TtaFreeMemory(items);
1.1 vatton 775: TtaSetStructureChecking (oldStructureChecking, doc);
1.40 kia 776:
1.44 kia 777: Template_FixAccessRight (t, el, doc);
778: TtaUpdateAccessRightInViews (doc, el);
779:
1.1 vatton 780: return cont;
1.23 kia 781: #else /* TEMPLATES */
782: return NULL;
1.1 vatton 783: #endif /* TEMPLATES */
784: }
785:
786: /*----------------------------------------------------------------------
1.22 kia 787: InstantiateRepeat
788: Check for min and max param and validate xt:repeat element content.
789: @param registerUndo True to register undo creation sequences.
1.3 vatton 790: ----------------------------------------------------------------------*/
1.46 vatton 791: void InstantiateRepeat (XTigerTemplate t, Element el, Document doc,
792: ThotBool registerUndo)
1.1 vatton 793: {
794: #ifdef TEMPLATES
1.32 vatton 795: Element child, newChild;
1.52 vatton 796: ElementType newElType;
797: Attribute minAtt, maxAtt;
798: AttributeType minType, maxType;
799: char *text, *types = NULL, *title = NULL;
800: int curVal, minVal, maxVal;
1.32 vatton 801: int childrenCount;
802:
1.1 vatton 803:
1.25 vatton 804: if (!t)
1.23 kia 805: return;
806:
1.1 vatton 807: //Preparing types
1.52 vatton 808: minType.AttrSSchema = TtaGetSSchema (TEMPLATE_SCHEMA_NAME, doc);
1.1 vatton 809: minType.AttrTypeNum = Template_ATTR_minOccurs;
1.52 vatton 810: maxType.AttrSSchema = minType.AttrSSchema;
1.1 vatton 811: maxType.AttrTypeNum = Template_ATTR_maxOccurs;
1.52 vatton 812: newElType.ElSSchema = minType.AttrSSchema;
813: //Get minOccurs and maxOccurs attributes
1.1 vatton 814: minAtt = TtaGetAttribute (el, minType);
815: maxAtt = TtaGetAttribute (el, maxType);
816: //Get the values
817: if (minAtt)
818: {
1.10 kia 819: text = GetAttributeStringValue(el, minAtt, NULL);
1.1 vatton 820: if (text)
821: {
822: minVal = atoi(text);
823: TtaFreeMemory(text);
1.52 vatton 824: curVal = minVal;
1.1 vatton 825: }
826: else
827: //Error : Attribute with no value
828: return;
829: }
830: else
1.52 vatton 831: {
832: minVal = 0;
833: curVal = 1;
834: }
1.1 vatton 835:
836: if (maxAtt)
837: {
1.10 kia 838: text = GetAttributeStringValue (el, maxAtt, NULL);
1.1 vatton 839: if (text)
840: {
841: if (!strcmp (text, "*"))
842: maxVal = INT_MAX;
843: else
844: maxVal = atoi (text);
845: TtaFreeMemory (text);
846: }
847: else
848: //Error : Attribute with no value
849: return;
850: }
851: else
852: maxVal = INT_MAX;
853:
854: text = (char*)TtaGetMemory(MAX_LENGTH);
1.52 vatton 855: //Create non existing min max attributes
856: if (minAtt == NULL)
1.1 vatton 857: {
1.32 vatton 858: minAtt = TtaNewAttribute (minType);
859: sprintf (text, "%d", minVal);
860: TtaAttachAttribute (el, minAtt, doc);
861: TtaSetAttributeText (minAtt, text, el, doc);
1.25 vatton 862: if (registerUndo)
1.32 vatton 863: TtaRegisterAttributeCreate (minAtt, el, doc);
1.1 vatton 864: }
865:
1.52 vatton 866: if (maxAtt == NULL)
1.1 vatton 867: {
1.32 vatton 868: maxAtt = TtaNewAttribute (maxType);
869: if (maxVal < INT_MAX)
870: sprintf(text, "%d", maxVal);
1.1 vatton 871: else
1.32 vatton 872: sprintf (text, "*");
873: TtaAttachAttribute (el, maxAtt, doc);
874: TtaSetAttributeText (maxAtt, text, el, doc);
1.25 vatton 875: if (registerUndo)
1.32 vatton 876: TtaRegisterAttributeCreate (maxAtt, el, doc);
1.1 vatton 877: }
1.52 vatton 878: TtaFreeMemory(text);
1.1 vatton 879:
1.52 vatton 880: //We must have minOccurs children
1.1 vatton 881: child = TtaGetFirstChild(el);
882: if (!child)
883: //Error : a repeat must have at least one child which will be the model
884: return;
885:
886: for(childrenCount = 0; child; TtaNextSibling(&child))
887: {
888: //TODO : Check that every child is valid
889: childrenCount ++;
890: }
891:
892: if (childrenCount > maxVal)
893: //Error : too many children!
894: return;
895:
896: child = TtaGetLastChild(el);
1.32 vatton 897: types = GetAttributeStringValueFromNum (child, Template_ATTR_types, NULL);
898: title = GetAttributeStringValueFromNum (child, Template_ATTR_title, NULL);
1.52 vatton 899: newElType.ElTypeNum = Template_EL_useEl;
1.32 vatton 900: while (childrenCount < curVal)
1.1 vatton 901: {
1.32 vatton 902: newChild = TtaNewElement (doc, newElType);
1.27 kia 903: // Insert it
1.32 vatton 904: TtaInsertSibling (newChild, child, FALSE, doc);
905: SetAttributeStringValueWithUndo (newChild, Template_ATTR_types, types);
906: SetAttributeStringValueWithUndo (newChild, Template_ATTR_title, title);
1.34 vatton 907: InstantiateUse (t, newChild, doc, TRUE);
1.27 kia 908:
1.25 vatton 909: if (registerUndo)
1.34 vatton 910: TtaRegisterElementCreate (newChild, doc);
1.1 vatton 911: child = newChild;
912: childrenCount++;
913: }
1.27 kia 914:
1.44 kia 915: Template_FixAccessRight (t, el, doc);
916: TtaUpdateAccessRightInViews (doc, el);
1.32 vatton 917: TtaFreeMemory (types);
918: TtaFreeMemory (title);
1.1 vatton 919: #endif /* TEMPLATES */
920: }
921:
922: /*----------------------------------------------------------------------
923: ParseTemplate
1.3 vatton 924: ----------------------------------------------------------------------*/
1.1 vatton 925: static void ParseTemplate (XTigerTemplate t, Element el, Document doc,
926: ThotBool loading)
927: {
928: #ifdef TEMPLATES
1.47 kia 929: AttributeType attType;
930: Attribute att;
931: Element aux, child; //Needed when deleting trees
932: char *name;
933: ElementType elType = TtaGetElementType (el);
934:
1.37 kia 935: if (!t || !el)
1.23 kia 936: return;
937:
1.5 vatton 938: name = TtaGetSSchemaName (elType.ElSSchema);
1.47 kia 939: if (!strcmp (name, "Template"))
1.1 vatton 940: {
1.5 vatton 941: switch(elType.ElTypeNum)
1.1 vatton 942: {
943: case Template_EL_head :
944: //Remove it and all of its children
945: TtaDeleteTree(el, doc);
946: //We must stop searching into this tree
947: return;
948: break;
949: case Template_EL_component :
1.25 vatton 950: // remove the name attribute
1.5 vatton 951: attType.AttrSSchema = elType.ElSSchema;
1.1 vatton 952: attType.AttrTypeNum = Template_ATTR_name;
1.18 kia 953: name = GetAttributeStringValueFromNum (el, Template_ATTR_name, NULL);
1.5 vatton 954: TtaRemoveAttribute (el, TtaGetAttribute (el, attType), doc);
1.25 vatton 955: // replace the component by a use
1.1 vatton 956: if (NeedAMenu (el, doc))
1.5 vatton 957: TtaChangeElementType (el, Template_EL_useEl);
1.1 vatton 958: else
1.5 vatton 959: TtaChangeElementType (el, Template_EL_useSimple);
1.25 vatton 960: // generate the types attribute
1.1 vatton 961: attType.AttrTypeNum = Template_ATTR_types;
1.5 vatton 962: att = TtaNewAttribute (attType);
963: TtaAttachAttribute (el, att, doc);
1.25 vatton 964: if (name)
1.18 kia 965: TtaSetAttributeText (att, name, el, doc);
1.25 vatton 966: // generate the title attribute
967: attType.AttrTypeNum = Template_ATTR_title;
968: att = TtaNewAttribute (attType);
969: TtaAttachAttribute (el, att, doc);
970: if (name)
971: TtaSetAttributeText (att, name, el, doc);
972: // generate the currentType attribute
1.1 vatton 973: attType.AttrTypeNum = Template_ATTR_currentType;
1.5 vatton 974: att = TtaNewAttribute (attType);
1.18 kia 975: TtaAttachAttribute (el, att, doc);
1.25 vatton 976: if (name)
1.18 kia 977: TtaSetAttributeText (att, name, el, doc);
1.28 kia 978: TtaFreeMemory(name);
1.1 vatton 979: break;
980: case Template_EL_option :
981: aux = NULL;
982: break;
983: case Template_EL_bag :
984: //Link to types
985: //Allow editing the content
986: break;
987: case Template_EL_useEl :
988: case Template_EL_useSimple :
989: /* if this use element is not empty, don't do anything: it is
990: supposed to contain a valid instance. This should be
991: checked, though */
1.46 vatton 992: if (DocumentMeta[doc] && DocumentMeta[doc]->isTemplate)
993: // add the initial indicator
994: AddPromptIndicator (el, doc);
995:
1.1 vatton 996: if (!TtaGetFirstChild (el))
1.27 kia 997: InstantiateUse (t, el, doc, FALSE);
1.1 vatton 998: break;
999: case Template_EL_attribute :
1000: if (!loading)
1001: InstantiateAttribute (t, el, doc);
1002: break;
1003: case Template_EL_repeat :
1.22 kia 1004: InstantiateRepeat (t, el, doc, FALSE);
1.1 vatton 1005: break;
1006: default :
1007: break;
1008: }
1009: }
1.47 kia 1010:
1011: child = TtaGetFirstChild (el);
1012: while (child)
1.1 vatton 1013: {
1014: aux = child;
1.5 vatton 1015: TtaNextSibling (&aux);
1016: ParseTemplate (t, child, doc, loading);
1.1 vatton 1017: child = aux;
1018: }
1019: #endif /* TEMPLATES */
1020: }
1021:
1022: /*----------------------------------------------------------------------
1.3 vatton 1023: ----------------------------------------------------------------------*/
1.1 vatton 1024: void DoInstanceTemplate (char *templatename)
1025: {
1026: #ifdef TEMPLATES
1.47 kia 1027: XTigerTemplate t;
1028: ElementType elType;
1029: Element root, piElem, doctype, elFound, text;
1.54 ! vatton 1030: Document doc;
1.47 kia 1031: char *s, *charsetname = NULL, buffer[MAX_LENGTH];
1.1 vatton 1032: int pi_type;
1033:
1.47 kia 1034: //Instantiate all elements
1035: t = GetXTigerTemplate(templatename);
1.25 vatton 1036: if (!t)
1.23 kia 1037: return;
1.47 kia 1038:
1.1 vatton 1039: doc = GetTemplateDocument (t);
1.47 kia 1040: root = TtaGetMainRoot (doc);
1041: ParseTemplate (t, root, doc, FALSE);
1.1 vatton 1042:
1043: //Look for PIs
1044: /* check if the document has a DOCTYPE declaration */
1045: #ifdef ANNOTATIONS
1046: if (DocumentTypes[doc] == docAnnot)
1047: elType = TtaGetElementType (root);
1048: else
1049: #endif /* ANNOTATIONS */
1050: elType = TtaGetElementType (root);
1051: s = TtaGetSSchemaName (elType.ElSSchema);
1052: if (strcmp (s, "HTML") == 0)
1053: {
1054: elType.ElTypeNum = HTML_EL_DOCTYPE;
1055: pi_type = HTML_EL_XMLPI;
1056: }
1057: #ifdef _SVG
1058: else if (strcmp (s, "SVG") == 0)
1059: {
1060: elType.ElTypeNum = SVG_EL_DOCTYPE;
1061: pi_type = SVG_EL_XMLPI;
1062: }
1063: #endif /* _SVG */
1064: else if (strcmp (s, "MathML") == 0)
1065: {
1066: elType.ElTypeNum = MathML_EL_DOCTYPE;
1067: pi_type = MathML_EL_XMLPI;
1068: }
1069: else
1070: {
1071: elType.ElTypeNum = XML_EL_doctype;
1072: pi_type = XML_EL_xmlpi;
1073: }
1.54 ! vatton 1074:
1.1 vatton 1075: doctype = TtaSearchTypedElement (elType, SearchInTree, root);
1076: if (!doctype)
1077: {
1078: /* generate the XML declaration */
1079: /* Check the Thot abstract tree against the structure schema. */
1080: TtaSetStructureChecking (FALSE, doc);
1081: elType.ElTypeNum = pi_type;
1082: doctype = TtaNewTree (doc, elType, "");
1083: TtaInsertFirstChild (&doctype, root, doc);
1084: elFound = TtaGetFirstChild (doctype);
1085: text = TtaGetFirstChild (elFound);
1086: strcpy (buffer, "xml version=\"1.0\" encoding=\"");
1087: charsetname = UpdateDocumentCharset (doc);
1088: strcat (buffer, charsetname);
1089: strcat (buffer, "\"");
1090: TtaSetTextContent (text, (unsigned char*)buffer, Latin_Script, doc);
1091: TtaSetStructureChecking (TRUE, doc);
1.28 kia 1092: TtaFreeMemory(charsetname);
1.1 vatton 1093: }
1094:
1095: /* generate the XTiger PI */
1096: /* Check the Thot abstract tree against the structure schema. */
1097: TtaSetStructureChecking (FALSE, doc);
1098: elType.ElTypeNum = pi_type;
1099: piElem = TtaNewTree (doc, elType, "");
1.34 vatton 1100: TtaInsertSibling (piElem, doctype, FALSE, doc);
1.1 vatton 1101: elFound = TtaGetFirstChild (piElem);
1102: text = TtaGetFirstChild (elFound);
1103: strcpy (buffer, "xtiger template=\"");
1104: strcat (buffer, templatename);
1.17 kia 1105: strcat (buffer, "\" version=\"");
1.20 vatton 1106: if (t->version)
1107: strcat (buffer, t->version);
1108: else
1109: strcat (buffer, "0.8");
1.1 vatton 1110: strcat (buffer, "\"");
1.25 vatton 1111: if (t->templateVersion)
1.20 vatton 1112: {
1113: strcat (buffer, " templateVersion=\"");
1114: strcat (buffer, t->templateVersion);
1115: strcat (buffer, "\"");
1116: }
1.1 vatton 1117: TtaSetTextContent (text, (unsigned char*)buffer, Latin_Script, doc);
1118: TtaSetStructureChecking (TRUE, doc);
1.5 vatton 1119:
1120: // update the document title
1.47 kia 1121: if (!strcmp (s, "HTML"))
1.5 vatton 1122: {
1123: elType.ElTypeNum = HTML_EL_TITLE;
1124: elFound = TtaSearchTypedElement (elType, SearchInTree, root);
1125: if (elFound)
1126: {
1127: elFound = TtaGetFirstChild (elFound);
1128: TtaSetTextContent (elFound, (unsigned char *)Answer_text,
1129: TtaGetDefaultLanguage (), doc);
1130: }
1131: }
1.1 vatton 1132: #endif /* TEMPLATES */
1133: }
1134:
1135: /*----------------------------------------------------------------------
1.46 vatton 1136: Template_PreInstantiateComponents: Instantiates all components in
1137: order to improve editing.
1.3 vatton 1138: ----------------------------------------------------------------------*/
1.35 kia 1139: void Template_PreInstantiateComponents (XTigerTemplate t)
1.1 vatton 1140: {
1141: #ifdef TEMPLATES
1.25 vatton 1142: if (!t)
1.23 kia 1143: return;
1144:
1.35 kia 1145: HashMap components = GetComponents(t);
1146: ForwardIterator iter = HashMap_GetForwardIterator(components);
1147: Declaration comp;
1148: HashMapNode node;
1.47 kia 1149:
1.35 kia 1150: ITERATOR_FOREACH(iter, HashMapNode, node)
1.1 vatton 1151: {
1.35 kia 1152: comp = (Declaration) node->elem;
1.1 vatton 1153: ParseTemplate(t, GetComponentContent(comp), GetTemplateDocument(t), TRUE);
1154: }
1.35 kia 1155: TtaFreeMemory(iter);
1.1 vatton 1156: #endif /* TEMPLATES */
1157: }
Webmaster