/*---------------------------------------------------------------------- TemplateFindHead looks for the xt:head element and creates it if it doesn't exist. ----------------------------------------------------------------------*/ Element TemplateFindHead (Document doc) { #ifdef TEMPLATES ElementType headType, elType; Element head, root; headType.ElSSchema = TtaGetSSchema ("Template", doc); if (headType.ElSSchema == NULL) return NULL; root = TtaGetMainRoot (doc); elType = TtaGetElementType (root); headType.ElTypeNum = Template_EL_head; if (elType.ElSSchema == headType.ElSSchema) head = root; else head = TtaSearchTypedElement (headType, SearchInTree, root); if (head == NULL) { // create the template head head = TtaNewElement (doc, headType); if (!IsNotHTMLorHTML5 (TtaGetSSchemaName (elType.ElSSchema))) { elType.ElTypeNum = HTML_EL_HEAD; root = TtaSearchTypedElement (elType, SearchInTree, root); } TtaInsertFirstChild (&head, root, doc); SetAttributeStringValue (head, Template_ATTR_version, Template_Current_Version); SetAttributeStringValue (head, Template_ATTR_templateVersion, "1.0"); } return head; #else /* TEMPLATES */ return NULL; #endif /* TEMPLATES */ }
/*---------------------------------------------------------------------- SetStyleOfLog applies style rules to a log document ----------------------------------------------------------------------*/ void SetStyleOfLog (Document doc) { #ifdef _WX PRule newPRule; Element root; root = TtaGetMainRoot (doc); if (root) { newPRule = TtaNewPRuleForView (PRSize, 1, doc); TtaAttachPRule (root, newPRule, doc); TtaSetPRuleValue (root, newPRule, 11, doc); } #endif /* _WX */ }
/*---------------------------------------------------------------------- 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 */ }
/*----------------------------------------------------------------------- LINK_AddLinkToSource Adds to a source document, an annotation link pointing to the annotation. Returns TRUE if the annotation could be attached and FALSE if the annotation became orphan. -----------------------------------------------------------------------*/ ThotBool LINK_AddLinkToSource (Document source_doc, AnnotMeta *annot) { ElementType elType, firstElType; Element el, first, anchor, child_el; AttributeType attrType; Attribute attr; SSchema XLinkSchema; char *docSchemaName, *CharNum; int c1, cN, Char, line, length; int length_el, line_el, count_child; ThotBool check_mode; /*annot_user = GetAnnotUser ();*/ if (DocumentTypes[source_doc] != docText) { if (annot->xptr) { XPointerContextPtr ctx; nodeInfo *node; ctx = XPointer_parse (source_doc, annot->xptr); node = XPointer_nodeStart (ctx); first = XPointer_el (node); c1 = XPointer_startC (node); cN = XPointer_endC (node); XPointer_free (ctx); } else { first = TtaSearchElementByLabel(annot->labf, TtaGetRootElement (source_doc)); c1 = annot->c1; cN = annot->cl; } } else { first = SearchTextattribute (source_doc, annot->xptr); line = TtaGetElementLineNumber (first); CharNum = strstr (annot->xptr, "="); CharNum = &CharNum[1]; Char = atoi (CharNum); c1 = CharNum_IN_Line (source_doc, Char); if(c1 == -1) c1 = 0; cN = c1 - 1; length = TtaGetElementVolume (first); el = TtaGetMainRoot (source_doc); elType = TtaGetElementType (el); elType.ElTypeNum = TextFile_EL_Line_; el = TtaSearchTypedElement (elType, SearchForward, el); for (line_el=1; line_el < line; line_el++) TtaNextSibling (&el); child_el = TtaGetFirstChild(el); length_el = TtaGetElementVolume(child_el); count_child = 1; while(child_el != first) { if(count_child % 3 != 2) { c1 -= length_el; cN = c1 - 1; } count_child++; TtaNextSibling(&child_el); length_el = TtaGetElementVolume(child_el); } } if (first) /* we found it */ annot->is_orphan = FALSE; else { /* it's an orphan annotation */ first = TtaGetRootElement (source_doc); annot->is_orphan = TRUE; } #ifdef ANNOT_ON_ANNOT /* don't add the Xlink element for replies */ if (annot->inReplyTo) return (!(annot->is_orphan)); #endif /* ANNOT_ON_ANNOT */ /* Verify that the annotates property really does point to this document and discard if not (or if there is no annotates property). */ if (!Annot_isSameURL (annot->source_url, DocumentURLs[source_doc])) return TRUE; /* treat this as not orphanned */ /* create the anotation element */ XLinkSchema = GetXLinkSSchema (source_doc); elType.ElSSchema = XLinkSchema; elType.ElTypeNum = XLink_EL_XLink; anchor = TtaNewTree (source_doc, elType, ""); /* ** insert the anchor in the document tree */ firstElType = TtaGetElementType (first); docSchemaName = TtaGetSSchemaName (firstElType.ElSSchema); check_mode = TtaGetStructureChecking (source_doc); TtaSetStructureChecking (FALSE, source_doc); /* @@ JK: this doesn't seem useful anymore */ /* is the user trying to annotate an annotation? */ el = TtaGetTypedAncestor (first, elType); if (el) { /* yes, so we will add the anchor one element before in the struct tree */ TtaInsertSibling (anchor, el, TRUE, source_doc); } else if (!strcmp (docSchemaName, "MathML")) { /* An annotation on a MathMl structure. We backtrace the tree until we find the Math root element and then add the annotation as its first child. */ el = first; while (el) { elType = TtaGetElementType (el); if (elType.ElTypeNum == MathML_EL_MathML) break; el = TtaGetParent (el); } TtaInsertFirstChild (&anchor, el, source_doc); } else if (!strcmp (docSchemaName, "SVG")) { /* An annotation on an SVG structure. We backtrace the tree until we find the SVG root element and then add the annotation as its first child. */ el = first; while (el) { elType = TtaGetElementType (el); if (elType.ElTypeNum == SVG_EL_SVG) break; el = TtaGetParent (el); } TtaInsertFirstChild (&anchor, el, source_doc); } else if (!strcmp (docSchemaName, "HTML") || !strcmp (docSchemaName, "HTML5")) { /* it's an HTML document */ el = first; elType = TtaGetElementType (el); if (elType.ElTypeNum == HTML_EL_HTML || elType.ElTypeNum == HTML_EL_HEAD || elType.ElTypeNum == HTML_EL_TITLE || elType.ElTypeNum == HTML_EL_BASE || elType.ElTypeNum == HTML_EL_META || elType.ElTypeNum == HTML_EL_SCRIPT_ || elType.ElTypeNum == HTML_EL_STYLE_ || elType.ElTypeNum == HTML_EL_BODY) { /* we can't put the annotation icon here, so let's find the first child of body and add it to it */ el = TtaGetRootElement (source_doc); elType.ElTypeNum = HTML_EL_BODY; el = TtaSearchTypedElement (elType, SearchForward, el); if (el) /* add it to the beginning */ TtaInsertFirstChild (&anchor, el, source_doc); else /* we add it where it was declared, although we may not see it at all */ TtaInsertSibling (anchor, first, TRUE, source_doc); } else if (elType.ElTypeNum == HTML_EL_Unnumbered_List || elType.ElTypeNum == HTML_EL_Numbered_List || elType.ElTypeNum == HTML_EL_List_Item || elType.ElTypeNum == HTML_EL_Definition) { /* for lists, we attach the A-element to the first pseudo paragraph. The .S forbids doing so elsewhere */ elType.ElTypeNum = HTML_EL_Pseudo_paragraph; el = TtaSearchTypedElement (elType, SearchForward, el); if (el) /* add it to the beginning */ TtaInsertFirstChild (&anchor, el, source_doc); else /* we add it where it was declared, although we may not see it at all */ TtaInsertSibling (anchor, first, TRUE, source_doc); } else if (elType.ElTypeNum == HTML_EL_PICTURE_UNIT) { /* add it before the image */ TtaInsertSibling (anchor, first, TRUE, source_doc); } else if (elType.ElTypeNum == HTML_EL_Table_ || elType.ElTypeNum == HTML_EL_thead || elType.ElTypeNum == HTML_EL_tbody || elType.ElTypeNum == HTML_EL_tfoot ) { /* add the A-element before the table */ el = first; elType = TtaGetElementType (el); while (elType.ElTypeNum != HTML_EL_Table_) { el = TtaGetParent (el); elType = TtaGetElementType (el); } /* add it before the image */ TtaInsertSibling (anchor, el, TRUE, source_doc); } else if (elType.ElTypeNum == HTML_EL_Table_row) { /* add the A-element to the first cell */ el = first; while ((el = TtaGetFirstChild (el))) { elType = TtaGetElementType (el); /* the elements where we can add the A-element */ if (elType.ElTypeNum == HTML_EL_Table_cell || elType.ElTypeNum == HTML_EL_Data_cell || elType.ElTypeNum == HTML_EL_Heading_cell) break; } TtaInsertFirstChild (&anchor, el, source_doc); } else { if (c1 == 0) { /* add it as the first child of the element */ TtaInsertFirstChild (&anchor, el, source_doc); } else if (c1 == 1) { /* add it to the beginning of the element */ TtaInsertSibling (anchor, first, TRUE, source_doc); } else if (c1 > 1) { /* split the text */ int len; len = TtaGetTextLength (first); if (cN > len && c1 == cN) /* add it to the end (a caret) */ TtaInsertSibling (anchor, first, FALSE, source_doc); else { /* add it in the middle */ TtaSplitText (first, c1, source_doc); TtaNextSibling (&first); TtaInsertSibling (anchor, first, TRUE, source_doc); } } } } else if (DocumentTypes[source_doc] == docXml) { /* An annotation on a generic XML structure. We don't do anything special. */ el = first; if (c1 == 0) { /* add it as the first child of the element */ TtaInsertFirstChild (&anchor, el, source_doc); } else if (c1 == 1) { /* add it to the beginning of the element */ TtaInsertSibling (anchor, first, TRUE, source_doc); } else if (c1 > 1) { /* split the text */ int len; len = TtaGetTextLength (first); if (cN > len && c1 == cN) /* add it to the end (a caret) */ TtaInsertSibling (anchor, first, FALSE, source_doc); else { /* add it in the middle */ TtaSplitText (first, c1, source_doc); TtaNextSibling (&first); TtaInsertSibling (anchor, first, TRUE, source_doc); } } } else if (!strcmp (docSchemaName, "TextFile")) { el = first; elType = TtaGetElementType (el); elType.ElTypeNum = TextFile_EL_Line_; el = TtaSearchTypedElement (elType, SearchForward, el); if (c1 == 0) { /* add it as the first child of the element */ TtaInsertFirstChild (&anchor, el, source_doc); } else if (c1 == 1) { /* add it to the beginning of the element */ TtaInsertSibling (anchor, first, TRUE, source_doc); } else if (c1 > 1) { int len; len = TtaGetElementVolume(first); if (c1 > len) /* add it to the end (a caret)*/ TtaInsertSibling (anchor, first, FALSE, source_doc); else { /* add it in the middle */ TtaSplitText (first, c1, source_doc); TtaNextSibling (&first); TtaSplitText (first, 2,source_doc); TtaInsertSibling (anchor, first, TRUE, source_doc); TtaSelectString(source_doc,first,1,0); } } } TtaSetStructureChecking (check_mode, source_doc); /* add the Xlink attribute */ SetXLinkTypeSimple (anchor, source_doc, FALSE); /* ** add the other attributes */ attrType.AttrSSchema = XLinkSchema; #ifdef ANNOT_ON_ANNOT /* @@ JK: Systematically hiding the thread annotations */ if (annot->inReplyTo) { attrType.AttrTypeNum = XLink_ATTR_AnnotIsHidden; attr = TtaNewAttribute (attrType); TtaAttachAttribute (anchor, attr, source_doc); } #endif /* ANNOT_ON_ANNOT */ /* add the annotation icon */ if (!annot->is_orphan) attrType.AttrTypeNum = XLink_ATTR_AnnotIcon1; else attrType.AttrTypeNum = XLink_ATTR_AnnotOrphIcon; attr = TtaNewAttribute (attrType); TtaAttachAttribute (anchor, attr, source_doc); /* add an HREF attribute pointing to the annotation */ attrType.AttrTypeNum = XLink_ATTR_href_; attr = TtaNewAttribute (attrType); TtaAttachAttribute (anchor, attr, source_doc); TtaSetAttributeText (attr, annot->body_url, anchor, source_doc); /* add a ID attribute so that the annotation doc can point back to the source of the annotation link */ attrType.AttrTypeNum = XLink_ATTR_id; attr = TtaNewAttribute (attrType); TtaAttachAttribute (anchor, attr, source_doc); /* set the ID value (anchor endpoint) */ TtaSetAttributeText (attr, annot->name, anchor, source_doc); /* add the annotation icon */ LINK_AddAnnotIcon (source_doc, anchor, annot); return (!(annot->is_orphan)); }