Skip to main content
Inspiring
December 17, 2010
Answered

How to make text unconditional

  • December 17, 2010
  • 2 replies
  • 1058 views

Hi.

I am writing a program to delete condition tag.

But if any text is tagged with the tag I'm deleting,

I need to make the text unconditional.

Can some one tell me how to do this?

Best regard

erieru

    This topic has been closed for replies.
    Correct answer Russ Ward

    Hi erieru103,

    This seems like it should be a simple task, but it reality it is very complex. The problem is that (to my knowledge) there is no built-in way to do this with the FDK. All you have to work with are objects and properties. With conditional text, it is particularly difficult because conditional settings can differ from one character to the next.

    Here is a function that I use to remove a condition from a document; that is, remove any place that it is applied (the condition remains as part of the template). It works; however, it is technically incomplete because it might remove other conditions as well. Basically, it seeks out any instance of the condition and makes that text completely unconditional. Then, it steps through every table row in the document and un-conditionalizes it. It may not be exactly what you want, but perhaps it will give you some kind of lead on where you really want to achieve.

    Russ

    ////////////////////////////////////////////
    // REMOVE A CONDITION TAG FROM THE DOCUMENT
    ////////////////////////////////////////////////
    VoidT ssp_RemoveConditionFromDoc(F_ObjHandleT docId,
                                     StringT conditionName)
    {
      F_ObjHandleT flowId,
        tableId,
        rowId,
        frameId,
        pgfId;

      F_PropValT prop;

      F_PropValsT findParams;

      IntT counter = 0;

      F_IntsT tempInts;
     
      F_TextRangeT tr;


      //show all conditions.         
      F_ApiSetInt(FV_SessionId, docId, FP_ShowAll, True);


      //Set up the find parameters for the search
      findParams = F_ApiAllocatePropVals(1);
      findParams.val[0].propIdent.num = FS_FindCondTextInCondTags;
      findParams.val[0].propIdent.name = F_StrCopyString("");
      findParams.val[0].propVal.valType = FT_Strings;
      
     
      findParams.val[0].propVal.u.ssval.len = 1;
      findParams.val[0].propVal.u.ssval.val =
        (StringT *)
        F_Alloc(1*sizeof(StringT), NO_DSE);
      findParams.val[0].propVal.u.ssval.val[0] = F_StrCopyString(conditionName);

      //Step through the flows and remove the condition
      flowId = F_ApiGetId(FV_SessionId, docId, FP_FirstFlowInDoc);

      while(flowId)
      {
        //Get the first pgf in the the flow to use as a starting place for the search.
        frameId = F_ApiGetId(docId, flowId, FP_FirstTextFrameInFlow);
        if(frameId) pgfId = F_ApiGetId(docId, frameId, FP_FirstPgf);
        else pgfId = 0;

        if(pgfId)
        {

          //initialize the error flag
          FA_errno = FE_Success;

          //do an initial find, to make the next loop work right
          tr.beg.objId = pgfId;
          tr.beg.offset = 0;
          tr = F_ApiFind(docId, &tr.beg, &findParams);
     
          //while we have found text with the offending condition, let's remove it.
          while(FA_errno == FE_Success)
          {
            //Allocate a textprop structure for conditions, then clear the list
            //and reset the property to the whole range.
            prop = F_ApiGetTextPropVal(docId, &tr.beg, FP_InCond);
           
            F_ApiDeallocateInts(&prop.propVal.u.isval);
            prop.propVal.u.isval.val = (IntT *)
              F_Alloc(0*sizeof(IntT), NO_DSE);
            prop.propVal.u.isval.len = 0;

            F_ApiSetTextPropVal(docId, &tr, &prop);

            F_ApiDeallocatePropVal(&prop);

            //and keep searching
            tr = F_ApiFind(docId, &tr.beg, &findParams);

           }

          //The only error we should receive is "not found", when every instance
          //has been found.  If this is not the case, let's warn.
          if(FA_errno != FE_NotFound)
          {      

             //handle error here

          }

        }
     
        flowId = F_ApiGetId(docId, flowId, FP_NextFlowInDoc);
      }
       
      //done with this
      F_ApiDeallocatePropVals(&findParams);
      
      //now, we have to do all the table rows, because they don't get
      //found by the find.
      tempInts.val = (IntT *) F_Alloc(0*sizeof(IntT), NO_DSE);
      tempInts.len = 0;

      tableId = F_ApiGetId(FV_SessionId, docId, FP_FirstTblInDoc);
     
      //step through all the tables in the doc
      while(tableId)
      {

        rowId = F_ApiGetId(docId, tableId, FP_FirstRowInTbl);
        //step through all the rows in the current table
        while(rowId)
        {
          //remove conditions, with this structure we allocated earlier
          F_ApiSetInts(docId, rowId, FP_InCond, &tempInts);
         
          rowId = F_ApiGetId(docId, rowId, FP_NextRowInTbl);
        }
       
        tableId = F_ApiGetId(docId, tableId, FP_NextTblInDoc);

      }
     
      //hopefully that's it.
      F_ApiDeallocateInts(&tempInts);

    }

    2 replies

    Russ WardCorrect answer
    Legend
    December 17, 2010

    Hi erieru103,

    This seems like it should be a simple task, but it reality it is very complex. The problem is that (to my knowledge) there is no built-in way to do this with the FDK. All you have to work with are objects and properties. With conditional text, it is particularly difficult because conditional settings can differ from one character to the next.

    Here is a function that I use to remove a condition from a document; that is, remove any place that it is applied (the condition remains as part of the template). It works; however, it is technically incomplete because it might remove other conditions as well. Basically, it seeks out any instance of the condition and makes that text completely unconditional. Then, it steps through every table row in the document and un-conditionalizes it. It may not be exactly what you want, but perhaps it will give you some kind of lead on where you really want to achieve.

    Russ

    ////////////////////////////////////////////
    // REMOVE A CONDITION TAG FROM THE DOCUMENT
    ////////////////////////////////////////////////
    VoidT ssp_RemoveConditionFromDoc(F_ObjHandleT docId,
                                     StringT conditionName)
    {
      F_ObjHandleT flowId,
        tableId,
        rowId,
        frameId,
        pgfId;

      F_PropValT prop;

      F_PropValsT findParams;

      IntT counter = 0;

      F_IntsT tempInts;
     
      F_TextRangeT tr;


      //show all conditions.         
      F_ApiSetInt(FV_SessionId, docId, FP_ShowAll, True);


      //Set up the find parameters for the search
      findParams = F_ApiAllocatePropVals(1);
      findParams.val[0].propIdent.num = FS_FindCondTextInCondTags;
      findParams.val[0].propIdent.name = F_StrCopyString("");
      findParams.val[0].propVal.valType = FT_Strings;
      
     
      findParams.val[0].propVal.u.ssval.len = 1;
      findParams.val[0].propVal.u.ssval.val =
        (StringT *)
        F_Alloc(1*sizeof(StringT), NO_DSE);
      findParams.val[0].propVal.u.ssval.val[0] = F_StrCopyString(conditionName);

      //Step through the flows and remove the condition
      flowId = F_ApiGetId(FV_SessionId, docId, FP_FirstFlowInDoc);

      while(flowId)
      {
        //Get the first pgf in the the flow to use as a starting place for the search.
        frameId = F_ApiGetId(docId, flowId, FP_FirstTextFrameInFlow);
        if(frameId) pgfId = F_ApiGetId(docId, frameId, FP_FirstPgf);
        else pgfId = 0;

        if(pgfId)
        {

          //initialize the error flag
          FA_errno = FE_Success;

          //do an initial find, to make the next loop work right
          tr.beg.objId = pgfId;
          tr.beg.offset = 0;
          tr = F_ApiFind(docId, &tr.beg, &findParams);
     
          //while we have found text with the offending condition, let's remove it.
          while(FA_errno == FE_Success)
          {
            //Allocate a textprop structure for conditions, then clear the list
            //and reset the property to the whole range.
            prop = F_ApiGetTextPropVal(docId, &tr.beg, FP_InCond);
           
            F_ApiDeallocateInts(&prop.propVal.u.isval);
            prop.propVal.u.isval.val = (IntT *)
              F_Alloc(0*sizeof(IntT), NO_DSE);
            prop.propVal.u.isval.len = 0;

            F_ApiSetTextPropVal(docId, &tr, &prop);

            F_ApiDeallocatePropVal(&prop);

            //and keep searching
            tr = F_ApiFind(docId, &tr.beg, &findParams);

           }

          //The only error we should receive is "not found", when every instance
          //has been found.  If this is not the case, let's warn.
          if(FA_errno != FE_NotFound)
          {      

             //handle error here

          }

        }
     
        flowId = F_ApiGetId(docId, flowId, FP_NextFlowInDoc);
      }
       
      //done with this
      F_ApiDeallocatePropVals(&findParams);
      
      //now, we have to do all the table rows, because they don't get
      //found by the find.
      tempInts.val = (IntT *) F_Alloc(0*sizeof(IntT), NO_DSE);
      tempInts.len = 0;

      tableId = F_ApiGetId(FV_SessionId, docId, FP_FirstTblInDoc);
     
      //step through all the tables in the doc
      while(tableId)
      {

        rowId = F_ApiGetId(docId, tableId, FP_FirstRowInTbl);
        //step through all the rows in the current table
        while(rowId)
        {
          //remove conditions, with this structure we allocated earlier
          F_ApiSetInts(docId, rowId, FP_InCond, &tempInts);
         
          rowId = F_ApiGetId(docId, rowId, FP_NextRowInTbl);
        }
       
        tableId = F_ApiGetId(docId, tableId, FP_NextTblInDoc);

      }
     
      //hopefully that's it.
      F_ApiDeallocateInts(&tempInts);

    }

    Michael_Müller-Hillebrand
    Legend
    December 18, 2010

    Sometimes, only sometimes, if there is no other option, you might consider using the so-called F-Codes in your programming.

    The F-Code to do the same thing as the Ctrl+6 keyboard shortcut is called KbdUnCond...

    - Michael

    erieru103Author
    Inspiring
    December 24, 2010

    Hi.

    I have used F_ApiFind to make text uncoditional, and it seems work well.

    Thank you for your advices.

    Best regard.

    erieru103

    Michael_Müller-Hillebrand
    Legend
    December 17, 2010

    Erieru,

    The quickest way to do that in the UI is Ctrl+6. For the record:

    • Ctrl+4 allows you to select a certain condition (see status bar after ?:) to apply to the selected text
    • Ctrl+5 allows you to remove a certain condition (see status bar after ¿:) to apply to the selected text
    • Ctrl+6 makes the selected text unconditional (i.e. removes all conditions)

    How to do it using programming depends on the programming language.

    - Michael

    Michael314
    Inspiring
    October 23, 2014

    Michael,

    I found your interesting list of control keys to manipulate conditions while searching for the method for removing a condition from text. I could not find where in the Frame 12 UI is the feature that turns conditioned text back into plain text.  Back in Frame 6, there was a simple check box.

    Wait! I just figured it out. If I select the conditioned text, open the Conditional Tags dialog, click the checked condition box twice so it changes to a clear box, and then click on the Apply button, the text condition is removed. That seems like a lot of steps compared to the old Make text unconditional check box.

    Yours,

    Michael F

    ======