Skip to main content
Inspiring
December 21, 2016
Answered

Custom Ruling & Shading via ExtendScript

  • December 21, 2016
  • 2 replies
  • 714 views

Hi,

I've taken up learning ExtendScript to tackle some common problems in my workflow.

My current project is to write a scrip that applies white rules to the columns in table heading rows.

So far my script can select the top (heading) row of the appropriate tables. But I can't figure out what the commands are for applying ruling. I've searched through every piece of documentation I could get my hands on, but there doesn't seem to be extensive material written with the beginner in mind.

Here's the script so far (Note: the counter and the alerts are just there so I know everything is working as I go along):

//target the active document

var doc = app.ActiveDoc;

//target the "first" table

var table = doc.FirstTblInDoc;

//number of tables to edit

var numberOfTables = 0;

if(table.ObjectValid() == true)

{

    while(table.ObjectValid() == true)

    {

        if(table.TblTag == "WithHeading")

        {

            numberOfTables++;

            alert("The table '" + table.TblTag.toString() + "' will be edited.");

           

            //select the top row of the table

            table.MakeTblSelection(0, 0, 0, table.TblNumRows - 1);

            table = table.NextTblInDoc;

        }

        else

        {

            alert("The table '" + table.TblTag.toString() + "' will not be edited.");

            table = table.NextTblInDoc;

        }

    }

}

else

{

    alert("No more tables.");

}

alert(numberOfTables + " tables will be edited.");

This topic has been closed for replies.
Correct answer frameexpert

Once I get my code working on a single table, then I expand it to work on the entire document. Notice my liberal use of functions to keep things modular. Modular code is easier to test, troubleshoot and reuse. Please let me know if you have any questions or comments.

#target framemaker

main ();

function main () {

  

    var doc = app.ActiveDoc;

    if (doc.ObjectValid () === 1) {

        processDoc (doc);

    }

    else {

        alert ("There is no active document.");

    }  

}

function processDoc (doc) {

  

    var tbl, rulingFmt;

  

    // Get the required ruling format.

    rulingFmt = getRulingFmt ("1ptWhite", doc);

  

    // Process all of the tables in the document.

    tbl = doc.FirstTblInDoc;

    while (tbl.ObjectValid () === 1) {

        // Test for the correct table format.

        if (tbl.TblTag === "WithHeading") {

            processTbl (tbl, rulingFmt);

        }

        tbl = tbl.NextTblInDoc;

    }

    // Refresh the document display.

    doc.Redisplay ();

}

function processTbl (tbl, rulingFmt) {

  

    var row, cell;

  

    // Get the first row of the table and the first cell in the row.

    row = tbl.FirstRowInTbl;

    cell = row.FirstCellInRow;

  

    // Loop through the cells.

    while (cell.ObjectValid () === 1) {

        // Process all of the cells in the row, except the last cell.

        if (cell.NextCellInRow.ObjectValid () === 1) {

            // Apply the ruling format to the right side of the cell.

            cell.CellOverrideRightRuling = rulingFmt;

            cell.CellUseOverrideRRuling = 1;

        }

        cell = cell.NextCellInRow;

    }

}

function getRulingFmt (name, doc) {

  

    var rulingFmt;

  

    // Get the ruling format.

    rulingFmt = doc.GetNamedRulingFmt (name);

    if (rulingFmt.ObjectValid () === 0) {

        // If it doesn't exist, create it.

        rulingFmt = doc.NewNamedRulingFmt (name);

        rulingFmt.Pen = Constants.FV_FILL_WHITE;

        rulingFmt.RulingPenWidth = 1 * 65536; // 65536 = 1 point

        rulingFmt.RulingLines = 1;

    }

  

    return rulingFmt;

}

2 replies

frameexpert
Community Expert
Community Expert
December 22, 2016

Here is working code with some comments:

#target framemaker 

 

var doc = app.ActiveDoc; 

 

// The table containing your text cursor. 

var tbl = doc.SelectedTbl; 

 

// The first row of the table. 

var row = tbl.FirstRowInTbl; 

// The first cell in the row. 

var cell = row.FirstCellInRow; 

// The ruling format to apply to the row's columns.

var rulingFmt = getRulingFmt ("1ptWhite", doc);

// Loop through the cells. 

while (cell.ObjectValid () === 1) { 

    // Process all of the cells in the row, except the last cell.

    if (cell.NextCellInRow.ObjectValid () === 1) {

        // Apply the ruling format to the right side of the cell.

        cell.CellOverrideRightRuling = rulingFmt;

        cell.CellUseOverrideRRuling = 1;

    }

    cell = cell.NextCellInRow; 

// Refresh the document display.

doc.Redisplay ();

function getRulingFmt (name, doc) {

   

    var rulingFmt;

   

    // Get the ruling format.

    rulingFmt = doc.GetNamedRulingFmt (name);

    if (rulingFmt.ObjectValid () === 0) {

        // If it doesn't exist, create it.

        rulingFmt = doc.NewNamedRulingFmt (name);

        rulingFmt.Pen = Constants.FV_FILL_WHITE;

        rulingFmt.RulingPenWidth = 1 * 65536; // 65536 = 1 point

        rulingFmt.RulingLines = 1;

    }

   

    return rulingFmt;

}

www.frameexpert.com
frameexpert
Community Expert
frameexpertCommunity ExpertCorrect answer
Community Expert
December 22, 2016

Once I get my code working on a single table, then I expand it to work on the entire document. Notice my liberal use of functions to keep things modular. Modular code is easier to test, troubleshoot and reuse. Please let me know if you have any questions or comments.

#target framemaker

main ();

function main () {

  

    var doc = app.ActiveDoc;

    if (doc.ObjectValid () === 1) {

        processDoc (doc);

    }

    else {

        alert ("There is no active document.");

    }  

}

function processDoc (doc) {

  

    var tbl, rulingFmt;

  

    // Get the required ruling format.

    rulingFmt = getRulingFmt ("1ptWhite", doc);

  

    // Process all of the tables in the document.

    tbl = doc.FirstTblInDoc;

    while (tbl.ObjectValid () === 1) {

        // Test for the correct table format.

        if (tbl.TblTag === "WithHeading") {

            processTbl (tbl, rulingFmt);

        }

        tbl = tbl.NextTblInDoc;

    }

    // Refresh the document display.

    doc.Redisplay ();

}

function processTbl (tbl, rulingFmt) {

  

    var row, cell;

  

    // Get the first row of the table and the first cell in the row.

    row = tbl.FirstRowInTbl;

    cell = row.FirstCellInRow;

  

    // Loop through the cells.

    while (cell.ObjectValid () === 1) {

        // Process all of the cells in the row, except the last cell.

        if (cell.NextCellInRow.ObjectValid () === 1) {

            // Apply the ruling format to the right side of the cell.

            cell.CellOverrideRightRuling = rulingFmt;

            cell.CellUseOverrideRRuling = 1;

        }

        cell = cell.NextCellInRow;

    }

}

function getRulingFmt (name, doc) {

  

    var rulingFmt;

  

    // Get the ruling format.

    rulingFmt = doc.GetNamedRulingFmt (name);

    if (rulingFmt.ObjectValid () === 0) {

        // If it doesn't exist, create it.

        rulingFmt = doc.NewNamedRulingFmt (name);

        rulingFmt.Pen = Constants.FV_FILL_WHITE;

        rulingFmt.RulingPenWidth = 1 * 65536; // 65536 = 1 point

        rulingFmt.RulingLines = 1;

    }

  

    return rulingFmt;

}

www.frameexpert.com
TMLTurbyAuthor
Inspiring
December 23, 2016

First of all, I'd like to thank you for the unexpectedly-detailed reply : )

I'll spend some time processing this and am sure I'll have some questions.

But for now, happy holidays!

frameexpert
Community Expert
Community Expert
December 21, 2016

I am a little pressed for time but I am going to try to answer this today. First of all, one of the fundamentals: you want to get your code working on a single table before looping through all of the tables in the document. So we will start with this (make sure your cursor is in a single table):

#target framemaker

var doc = app.ActiveDoc;

// The table containing your text cursor.

var tbl = doc.SelectedTbl;

// The first row of the table.

var row = tbl.FirstRowInTbl;

// The first cell in the row.

var cell = row.FirstCellInRow;

// Loop through the cells.

while (cell.ObjectValid () === 1) {

    // We will do something here.

    cell = cell.NextCellInRow;

}

The code that you need to apply the white rules will go at line 15. Note that when you use scripting, there is no need to select the row, you just need to loop through the cells. I will try to post the rest of the code shortly.

-Rick

www.frameexpert.com