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