How to avoid "element not allowed in context" errors when inserting tag templates?

Answered by: Tung Fu (PTC) Last Updated: 2006-09-20

=Question by N.N.=

Is there a way to do a "smart" insert of tag templates? that is, to prevent "element not allowed in context" errors.

=Tung Fu answers=

This can be done by customizing:

EPICPATH/packages/tools/tagtmpls.acl. The function to modify is insert_template.

If each template has only one root element, you can use in_context to determine if the cursor position is valid for a template. If some templates have two or more root elements, you probably have to use oid_paste_valid, which takes a paste buffer. This means you need to copy the content of the template to a paste buffer before calling the oid_paste_valid.

Here I assume each template has only one root element. In insert_template, you can get the root element name of a template as follows:

local tmpldoc = doc_open(tmplfile); local roottag = oid_name(oid_root(tmpldoc)); doc_close(tmpldoc);

You then should check if the current cursor position is valid for the template:

local valid = in_context(roottag, doc);

If the current position is valid, great; otherwise, you need to move the cursor around to find a valid point. To do so, you need to save the current cursor position, so you can go back to it if needed. These two functions can help you do so:

save_point; restore_point;

The following is how I move the cursor around, but you can use another way if it fits your application better. First, move the cursor forward:

local RANGE = 5; # any preset number local i; for (i = 0; i < RANGE; i++) { if (in_context('text', doc)) { goto_oid(oid_caret, -1); }   forward_char(1, doc); if (in_context(roottag, doc)) { # found the point break; } }

If you cannot find a point for the template, move the cursor to the original position and then move the cursor backward:

restore_point; for (i = 0; i < RANGE; i++) { if (in_context('text', doc)) { goto_oid(oid_caret, 0); }   forward_char(-1, doc); if (in_context(roottag, doc)) { # found the point break; } }

If you still cannot find a point for the template, you probably have to give up and display an error message, but be sure to move the cursor back to the original position first.

If you find a point, execute the undo and read commands as shown in the insert_template.

The new tagtmpls.acl can be stored in your custom directory CUSTOM/scripts, so whenever Epic loads tagtmpls.acl, it will load your version instead of the one in the Epic install tree.