General XMetaL Discussion

  • pooh2583

    Inserting Element

    Participants 4
    Replies 5
    Last Activity 8 years, 11 months ago

    Hello,

    I am writting a program where my requirements are I have to insert an element into the container node, if element can not be inserted at the current node it has to travarse till its parent node untill that elemnt can be inserted.

    I am writing a code where it wil check whether elemnt can be inserted or not

    if(Selection.CanInsert(“element”))
    if it can be inserted i my code is,
    Selection.InsertElement(“element”);
    if not it will navigate to the parent node
    and select content of the parent node  using Selection.SelectContenNode(parentnode); so that selection point moves to the parent.

    and this is in the loops which again checks

    if(Selection.CanInsert(“element”))
    if it can be inserted i have written
    Selection.InsertElement(“element”);

    even though if(Selection.CanInsert(“element”)) is true i.e. element can be inserted into the selected node,actually the element node is not being inserted in the xml document

    could you please help me with how to select parent node pointer so that it can check if(Selection.CanInsert(“element”)) and subsequently insert element node.

    Regards,

    Reply

    Derek Read

    Reply to: Inserting Element

    I think I understand what you are trying to do, but I'm guessing a little bit as your description isn't really clear. I'm assuming you do not have a hard requirement for using the APIs you suggest and that it is more important to actually accomplish the task.

    The following is written for the Journalist demo to do what I'm guessing you want it to do. Either run it in the context of the Journalist demo or adjust the elementName value and run it in the context of your own customization.

    My basic logic is as follows:

    1. Create a range object (named rng).
    2. As long as the rng is not in a position that allows the element to be inserted move the rng into its parent element. This is done by selecting the parent (the current container) and then collapsing the selection to the start (you might prefer to collapse it to the end).
    3. Insert the element. We still want to check if it is allowed because there might just not be a place to insert it in the current document, or given the starting position of the selection.

    There will be many ways to do the same thing but I think this is probably the easiest to understand.

    [code=example]//XMetaL Script Language JScript:
    var elementName = “Graphic”;
    var rng = ActiveDocument.Range;
    /*————————————————–
      move rng to a postion that should allow insertion
      keep trying until we hit the document root, and
      if we do then bail
    ————————————————–*/
    while(!rng.CanInsert(elementName)) {
    rng.SelectElement();
    rng.Collapse(sqCollapseStart);
    Application.Alert(rng.ContainerName);
    if(rng.ContainerName == “.DOCUMENT”) break;
    }
    /*————————————————–
      do the insertion
    ————————————————–*/
    if(rng.CanInsert(elementName)) {
    rng.InsertElement(elementName);
    }[/code]

    The Alert() is in there just to help you understand where the Range has ended up moving to after each iteration of the loop. You would obviously remove it in any final version of the code you end up using.

    Reply

    pooh2583

    Reply to: Inserting Element

    Hello,

    Above solution is working if and only if the element can be inserted into the current insertion point , i.e
    If my DTD has structure
    !ELEMENT para (top, middle , bottom) > and suppose i have to insert element bottom and my current insertion point is  betwwn top and middle i.e.test1
    (this is my current range)
    .
    then according to canInsert api it throws false because as per the DTD bottom element can not be inserted at the current location
    but my requirement is I have to check in entire para element whether  element bottom can
    be inserted or not and if DTD allows bottom element to be inserted into para it should move to the
    valid insertion point into para and insert there into the para element.

    Could you please help me in determining how shall I go with it, finding whether particulr element can be inserted anywhere into the selected current node that element or not instead of that particular point.

    Regards

    Reply

    Derek Read

    Reply to: Inserting Element

    I would suggest that your need is very different then.
    Taking a guess, but maybe your logic could be something like this:

    1. Create a range after selecting the entire contents of the current element.
    2. Duplicate that range. So you now have rng1 and rng2.
    3. Collapse rng1 to the start and rng2 to the end.
    4. In a loop…
        – try to insert your element at rng1
        – if that fails then move rng1 to the next element
        – exit the loop if an insertion occurs or if rng1 is equal to or greater than rng2

    You could also probably try creating a node walker to do this but that code would probably be harder to understand and write. It might end up with less predictable results for the user, or they might not care. For inspiration see the Programmers Guide topic “Node example: A simple tree-walker”. If it were me I think I'd stick with something like what I've outlined above.

    Reply

    pooh2583

    Reply to: Inserting Element

    Hello,

    Thanks for your reply.

    I have tried to achieve above mntioned functionality i.e. using following logic

    1.have selected two ranges range1 and range2 where range1 points at start pont of the node and range2 points at the end pont at the node.
    2. If elemnt can not be inserted at the selected pont I keep moving the range1 to next insertion
    point inh the node by using following code

    var nextNode =child.nextSibling;
    //select insertion point before the node
    rng1.SelectBeforeNode(nextNode);
    child = nextNode;
    this logic is working, but I would like to know if is there any API present in Xmetal to move range to the next insertion point in the current node

    also could you please let me know how two ranges can be checked for equality?

    Regards

    Reply

    Derek Read

    Reply to: Inserting Element

    Search the Programmers Guide for GotoNext, IsEqual, IsGreaterThan, and IsLessThan, and compare to MoveToElement.

    You might also want to look at the list of all APIs available on the Selection object. The names are quite indicative of their function and that topic provides a brief description for each, usually with further details provided in the topic for the API itself.

    Reply

  • You must be logged in to reply to this topic.

Lost Your Password?

Products
Downloads
Support