示例#1
0
文件: ANNOTlink.c 项目: ezura/Amaya
/*-----------------------------------------------------------------------
  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));
}
示例#2
0
文件: css.c 项目: ArcScofield/Amaya
/*----------------------------------------------------------------------
  GetStyleContents returns a buffer that contains the whole text of the
  style element el. It returns NULL if the element is empty.
  The buffer should be freed by the caller.
  ----------------------------------------------------------------------*/
char *GetStyleContents (Element el)
{
  ElementType         elType;
  Element             text;
  Attribute           attr;
  AttributeType       attrType;
  CSSmedia            media = CSS_ALL;
  Language            lang;
  char               *buffer, *name;
  int                 length, i, j;
  ThotBool            loadcss;

  buffer = NULL;

  /* check if we have to load CSS */
  TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
  if (loadcss && el)
    {
      /* check the media type of the element */
      elType = TtaGetElementType (el);
      attrType.AttrSSchema = elType.ElSSchema;
      name = TtaGetSSchemaName (attrType.AttrSSchema);
      if (!strcmp (name, "HTML"))
        attrType.AttrTypeNum = HTML_ATTR_media;
#ifdef _SVG
      else if (!strcmp (name, "HTML"))
        attrType.AttrTypeNum = SVG_ATTR_media;
#endif /* _SVG */
      else
        attrType.AttrTypeNum = 0;
      if (attrType.AttrTypeNum)
        {
          attr = TtaGetAttribute (el, attrType);
          if (attr)
            {
              length = TtaGetTextAttributeLength (attr);
              name = (char *)TtaGetMemory (length + 1);
              TtaGiveTextAttributeValue (attr, name, &length);
              media = CheckMediaCSS (name);
              TtaFreeMemory (name);
            }
        }
      /* get enough space to store UTF-8 characters */
      length = TtaGetElementVolume (el) * 6 + 1;
      if ((media == CSS_ALL || media == CSS_SCREEN) && length > 1)
        {
          /* get the length of the included text */
          buffer = (char *)TtaGetMemory (length);
          /* fill the buffer */
          elType.ElTypeNum = 1 /* 1 = TEXT_UNIT element */;
          text = TtaSearchTypedElementInTree (elType, SearchForward, el, el);
          i = 0;
          while (text != NULL)
            {
              j = length - i;
              TtaGiveTextContent (text, (unsigned char *)&buffer[i], &j, &lang);
              i += TtaGetTextLength (text);
              text = TtaSearchTypedElementInTree (elType, SearchForward, el, text);
            }
          buffer[i] = EOS;
        }
    }
  return (buffer);
}