How to prevent the "Modify Attributes" dialog when splitting an element?

From AdeptersWiki

Jump to: navigation, search

Answered by: Brent Hartwig Last Updated: 2006-09-22


More beautiful code from Brent Hartwig


Question by N.N.

I am using EditSplit to split one tag. This tag contains required attributes. When I choose Edit > Split, a Modify Attributes dialog pops up and list all the attributes. How can I assign attribute into the second split tag programmatically? I want to prevent Modify Attributes dialog from popping up. I tried to set context=off. But the Modify Attributes dialog still popup.


Brent Hartwig answers

This may not be the exactly what you need, but I've been wanting to share this with the group for a while. It's a recursive split that will set attributes if you so desire -- user is never prompted.

I created this for an Interchange import routine. Please read all comments, dramatic as they may be. If you use this and are not calling from within the postimporthook, you should not have to enable the workaround, which would be best given there is a drawback. Also, given my use of this and that it is oid-based, I never tested with selections. This was created and tested under Epic 4.4K. All dependencies were consolidated into this one package. The main function is recursiveSplit(), at the bottom.

package split;

# Boolean to workaround Epic split command bug -- hangs during post import hook.
# ATI30960. As of 20041213, Arbortext suggested using "<?Pub Caret?>" vs.
# "<?Pub Caret1?>" within XML import templates. This worked for 1 file but not
# another. Leaving "<?Pub Caret?>" in templates but turning workaround on.
global WORKAROUND_ATI30960 = 1;

#
# Determine if given document id is valid.
#
function isDocValid( doc )
{
   return ( doc_valid( doc ) && doc > 0 );
}

#
# This function's only reason for existence is to provide an alternative to
# Epic's split command -- WHICH HANGS EPIC WHEN EXECUTED WITHIN THE POST
# IMPORT HOOK! The preceding is true at least with Epic 4.4K (ATI30960). This
# function isolates the workaround. The function behaves similar to Epic's
# split command in the respect the caret must be in the correct spot in the
# current doc. Compare $main::status to know if a call to this function was
# successful.
#
# THIS WORKAROUND HAS A DRAWBACK: The oids of elements that end up being cut
# and pasted elsewhere are no longer valid.
#
function split( workaroundATI30960 = split::WORKAROUND_ATI30960 )
{
   if ( workaroundATI30960 )
   {
      local name = oid_name( oid_caret() );

      # Cut residual element content into paste buffer
      clear_mark all;
      mark -noinvert begin;
      goto_oid( oid_caret(), -1 );
      mark end;
      delete_mark bufSplitCmd;
      if ( main::status != 0 ) { return };

      # Move past end tag
      forward_char( 1 );
      if ( main::status != 0 ) { return };

      # Create new element
      insert_tag $name;
      if ( main::status != 0 ) { return };

      # Paste content
      paste bufSplitCmd;
      if ( main::status != 0 ) { return };

      # Place caret at beginning of new tag
      goto_oid( oid_caret() );
   }
   else
   {
      split;
   }
}

#
# Utility to perform a recursive split starting at the caret's location, of the
# given document, up through the specified element name. By default, attributes
# of the split element are copied over.
#
# Example: If caret is within //item/para/style/style, $tagname is "para" and
#          $copyAttrs is 1, then this function will split style, style and
#          para.
# Before:
#     <item>
#        <para>
#           TEXT
#           <style styles="bold">
#              <style styles="italic">TEXT<?Pub Caret1?>TEXT</style>
#           </style>
#           TEXT
#        </para>
#     </item>
# After:
#     <item>
#        <para>
#           TEXT
#           <style styles="bold">
#              <style styles="italic">TEXT</style>
#           </style>
#        </para>
#        <para><?Pub Caret1?>
#           <style styles="bold">
#              <style styles="italic">TEXT</style>
#           </style>
#           TEXT
#        </para>
#     </item>
#
# The caret is left after the last split element's start tag (see above).
#
# Parameters:
#  tagname - The element name to split up through.
#  doc - ID of document to perform split within.
#  copyAttrs - If non-zero, attributes of split elements are copied over.
#  workaroundATI30960 - Boolean passed onto split().
#
# Limitations:
#  1. Does not account for the 'addrequiredtags' option.
#  2. Does not account for the 'autotaginserts' option.
#  3. Does not account for the 'promptattrs' option.
#
# Returns:
#  -1: Error encountered. Edits to the document may or may not have occurred.
#   0: No error encountered yet no nodes were split.
#  >0: No error encountered. Number of nodes split.
#
function recursiveSplit( tagname, doc = current_doc(), copyAttrs = 1, \
   workaroundATI30960 = split::WORKAROUND_ATI30960 )
{
   local cnt = 0;                   # count of split nodes.
   local continue = 1;              # boolean
   local savedDoc = current_doc();  # current doc ID
   local savedRequireAttrs;         # current requireattrs option value.
   local o;                         # single OID
   local attrs[];                   # array of attribute names & values.
   local i;                         # loop index

   # Doc must be valid and caret must be within given tagname.
   if ( isDocValid( doc ) && inside_tag( tagname ) )
   {
      # Set doc focus, if needed.
      if ( savedDoc != doc )
      {
         current_doc( doc );
      }

      # Retain require attributes setting and change if necessary.
      savedRequireAttrs = option( "requireattrs" );
      if ( savedRequireAttrs != "off" )
      { 
         set requireattrs=off;
      }

      # While $continue is true, continue splitting.
      while( continue && ( cnt >= 0 ) )
      {
         o = oid_caret();

         # If current node's name is $tagname, this is the last split.
         if ( oid_name( o ) == tagname ) { continue = 0 };

         # Retain current nodes attributes
         oid_attr_list( o, attrs );

         # Perform single-node split.
         split( workaroundATI30960 ); # Do NOT directly call Epic's split command.
         if ( main::status != 0 )
         {
            cnt = -1;  # error encountered
            break;     # get out of while loop
         }

         # Copy attributes
         if ( copyAttrs && count( attrs ) )
         {
            for( i in attrs )
            {
               if ( !oid_modify_attr( oid_caret(), i, attrs[ i ] ) )
               {
                  cnt = -1;  # error encountered
                  break;     # get out of for loop
               }
            }
         }

         # Reposition for next split, providing there is to be an additional
         # split and an error was not encountered while setting the attributes.
         if ( continue && ( cnt >= 0 ) )
         {
            # Move in front of start tag.
            forward_char( -1 );
            if ( main::status != 0 )
            {
               cnt = -1;  # error encountered
               break;     # get out of while loop
            }
         }

         # Split was successful; increment counter.
         cnt++;
      } 

      # Restore prompt attrs setting, if needed
      if ( savedRequireAttrs != option( "requireattrs" ) )
      {
         set requireattrs=$savedRequireAttrs;
      }

      # Restore doc focus, if needed
      if ( savedDoc != current_doc() )
      {
         current_doc( savedDoc );
      }
   }

   return cnt;
}


Download a copy here: File:Code-acl00001.txt

Personal tools