General XMetaL Discussion
pooh2583 October 16, 2013 at 10:16 am
Inserting ElementOctober 16, 2013 at 10:16 amParticipants 4Replies 5Last Activity 9 years, 3 months ago
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 it can be inserted i my code is,
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 it can be inserted i have written
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,Derek Read October 16, 2013 at 7:57 pm
Reply to: Inserting ElementOctober 16, 2013 at 7:57 pm
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
if(rng.ContainerName == “.DOCUMENT”) break;
do the insertion
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.pooh2583 October 24, 2013 at 10:07 am
Reply to: Inserting ElementOctober 24, 2013 at 10:07 am
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.
(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.
RegardsDerek Read October 24, 2013 at 8:14 pm
Reply to: Inserting ElementOctober 24, 2013 at 8:14 pm
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.pooh2583 October 25, 2013 at 10:50 am
Reply to: Inserting ElementOctober 25, 2013 at 10:50 am
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
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?
RegardsDerek Read October 25, 2013 at 5:26 pm
Reply to: Inserting ElementOctober 25, 2013 at 5:26 pm
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.
- You must be logged in to reply to this topic.