/*---------------------------------------------------------------------- TemplateGetParentHead looks for the parent xt:head element ----------------------------------------------------------------------*/ Element TemplateGetParentHead (Element el, Document doc) { #ifdef TEMPLATES ElementType headType; SSchema schema; schema = TtaGetSSchema ("Template", doc); if (schema == TtaGetDocumentSSchema (doc)) return TtaGetMainRoot (doc); if (schema == NULL) // no template element in that document return NULL; headType.ElTypeNum = Template_EL_head; return TtaGetExactTypedAncestor (el, headType); #endif /* TEMPLATES */ }
/*---------------------------------------------------------------------- GetPExtension returns the Presentation Extension Schema associated with the document doc and the structure sSchema At the same time, this funciton updates the css context. ----------------------------------------------------------------------*/ PSchema GetPExtension (Document doc, SSchema sSchema, CSSInfoPtr css, Element link) { CSSInfoPtr oldcss; PInfoPtr pInfo, oldInfo; PISchemaPtr pIS, oldIS; PSchema pSchema, nSchema, prevS; Element prevEl, nextEl; ElementType elType, styleType, linkType, piType; AttributeType attrType; Attribute attr; char buffer[MAX_LENGTH]; char *name, pname[30]; int length; ThotBool found, before; if (css == NULL) return NULL; if (sSchema == NULL) sSchema = TtaGetDocumentSSchema (doc); pInfo = css->infos[doc]; /* generate the presentation schema name */ if (css->url) { length = strlen (css->url); if (length > 29) { strcpy (pname, "..."); strcat (pname, &css->url[length-26]); } else strcpy (pname, css->url); } else pname[0] = EOS; nextEl = NULL; found = FALSE; pIS = NULL; while (pInfo && !found) { if (pInfo->PiLink == link) { /* look for the list of document schemas */ pIS = pInfo->PiSchemas; while (pIS && !found) { if (sSchema == pIS->PiSSchema) { if (pIS->PiPSchema) /* the pschema is already known */ return (pIS->PiPSchema); } else pIS = pIS->PiSNext; } found = TRUE; } if (!found) /* next info context */ pInfo = pInfo->PiNext; } if (pInfo == NULL) { /* add the presentation info block for the current document style */ pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, link); pIS = NULL; if (pInfo == NULL) return NULL; } if (pIS == NULL) { /* add the schema info */ pIS = (PISchemaPtr) TtaGetMemory (sizeof (PISchema)); pIS->PiSNext = pInfo->PiSchemas; pInfo->PiSchemas = pIS; pIS->PiSSchema = sSchema; pIS->PiPSchema = NULL; } /* create the presentation schema for this structure */ nSchema = TtaNewPSchema (sSchema, pInfo->PiCategory == CSS_USER_STYLE); pSchema = TtaGetFirstPSchema (doc, sSchema); pIS->PiPSchema = nSchema; /* chain the presentation schema at the right position */ prevS = NULL; before = FALSE; if (pInfo->PiCategory == CSS_USER_STYLE || pSchema == NULL) { /* add in first position and last priority */ /* link the new presentation schema */ TtaAddPSchema (nSchema, pSchema, TRUE, doc, sSchema, pname); } else if (pInfo->PiCategory == CSS_DOCUMENT_STYLE || pInfo->PiCategory == CSS_EXTERNAL_STYLE) { /* check the order among its external style sheets */ if (pInfo->PiLink) { /* look for the previous link with rel="STYLESHEET" */ prevEl = pInfo->PiLink; nextEl = pInfo->PiLink; elType = TtaGetElementType (prevEl); name = TtaGetSSchemaName (elType.ElSSchema); styleType.ElSSchema = elType.ElSSchema; linkType.ElSSchema = elType.ElSSchema; piType.ElSSchema = elType.ElSSchema; attrType.AttrSSchema = elType.ElSSchema; if (!strcmp (name, "MathML")) { linkType.ElTypeNum = MathML_EL_XMLPI; styleType.ElTypeNum = MathML_EL_XMLPI; piType.ElTypeNum = MathML_EL_XMLPI; attrType.AttrTypeNum = HTML_ATTR_REL; } #ifdef _SVG /* if it's a SVG document, remove the style defined in the SVG DTD */ else if (!strcmp (name, "SVG")) { linkType.ElTypeNum = SVG_EL_XMLPI; styleType.ElTypeNum = SVG_EL_style__; piType.ElTypeNum = SVG_EL_XMLPI; attrType.AttrTypeNum = 0; } #endif /* _SVG */ else { linkType.ElTypeNum = HTML_EL_LINK; styleType.ElTypeNum = HTML_EL_STYLE_; piType.ElTypeNum = HTML_EL_XMLPI; attrType.AttrTypeNum = HTML_ATTR_REL; } /* look for a previous style item (link, style, PI) */ found = FALSE; while (!found && prevEl) { prevEl = TtaSearchElementAmong5Types (linkType, styleType, piType, linkType, styleType, SearchBackward, prevEl); if (prevEl) { if (attrType.AttrTypeNum == 0) found = TRUE; else { elType = TtaGetElementType (prevEl); if (elType.ElTypeNum == linkType.ElTypeNum) { attr = TtaGetAttribute (prevEl, attrType); if (attr) { /* get a buffer for the attribute value */ length = MAX_LENGTH; TtaGiveTextAttributeValue (attr, buffer, &length); found = (!strcasecmp (buffer, "STYLESHEET") || !strcasecmp (buffer, "STYLE")); } } else found = TRUE; } } if (found) { /* there is another linked CSS style sheet before */ oldcss = CSSList; found = FALSE; /* search that previous CSS context */ while (oldcss && !found) { oldInfo = oldcss->infos[doc]; while (oldInfo && !found) { if (oldInfo != pInfo && oldInfo->PiLink == prevEl) { oldIS = oldInfo->PiSchemas; while (oldIS && oldIS->PiSSchema != sSchema) oldIS = oldIS->PiSNext; if (oldIS && oldIS->PiPSchema) { /* link after that presentation schema */ before = FALSE; prevS = oldIS->PiPSchema; found = TRUE; } } if (!found) oldInfo = oldInfo->PiNext; } if (!found) /* it's not the the previous style sheet */ oldcss = oldcss->NextCSS; } } } /* look for a next style item (link, style, PI) */ while (!found && nextEl) { nextEl = TtaSearchElementAmong5Types (linkType, styleType, piType, linkType, styleType, SearchForward, nextEl); if (nextEl) { if (attrType.AttrTypeNum == 0) found = TRUE; else { elType = TtaGetElementType (nextEl); if (elType.ElTypeNum == linkType.ElTypeNum) { attr = TtaGetAttribute (nextEl, attrType); if (attr) { /* get a buffer for the attribute value */ length = MAX_LENGTH; TtaGiveTextAttributeValue (attr, buffer, &length); found = (!strcasecmp (buffer, "STYLESHEET") || !strcasecmp (buffer, "STYLE")); } } else found = TRUE; } } if (found) { /* there is another linked CSS style sheet before */ oldcss = CSSList; found = FALSE; /* search that previous CSS context */ while (oldcss && !found) { oldInfo = oldcss->infos[doc]; while (oldInfo && !found) { if (oldInfo != pInfo && oldInfo->PiLink == nextEl) { oldIS = oldInfo->PiSchemas; while (oldIS && oldIS->PiSSchema != sSchema) oldIS = oldIS->PiSNext; if (oldIS && oldIS->PiPSchema) { /* link after that presentation schema */ before = TRUE; prevS = oldIS->PiPSchema; found = TRUE; } } if (!found) oldInfo = oldInfo->PiNext; } if (!found) /* it's not the the previous style sheet */ oldcss = oldcss->NextCSS; } } } if (!found) { /* look for CSS_USER_STYLE */ oldcss = CSSList; while (oldcss && !found) { oldInfo = oldcss->infos[doc]; while (oldInfo && !found) { if (oldInfo != pInfo && oldInfo->PiCategory == CSS_USER_STYLE) { oldIS = oldInfo->PiSchemas; while (oldIS && oldIS->PiSSchema != sSchema) oldIS = oldIS->PiSNext; if (oldIS && oldIS->PiPSchema) { /* add after that schema with a higher priority */ prevS = oldIS->PiPSchema; before = FALSE; found = TRUE; } } if (!found) oldInfo = oldInfo->PiNext; } if (!found) /* it's not the the previous style sheet */ oldcss = oldcss->NextCSS; } } if (found) /* link the new presentation schema */ TtaAddPSchema (nSchema, prevS, before, doc, sSchema, pname); else TtaAddPSchema (nSchema, pSchema, TRUE, doc, sSchema, pname); } else { /* link the new presentation schema */ TtaAddPSchema (nSchema, pSchema, TRUE, doc, sSchema, pname); } } return (nSchema); }