Copy link to clipboard
Copied
I am putting together a script to align numbers in a table by decimal/assumed decimals. (I think all of the parts I’ve found here on the forum – what a great resource!)
FrameMaker aligns like this:
We'd like it to align like this:
My script adds “.0” and changes the character style to white. (I got help with that part last week but the post got lost in the Adobe forum conversion.) That part works, but I can’t get it to do more than one cell. We can't run it on all tables in the document, or even a whole table. It will need to be by column. Right now, I'm thinking to put the cursor in the top cell of the column, then run the script. Here’s what I have.
#target framemaker
var doc, pgf, cell, regex;
//given the cell containing the insertion point
doc = app.ActiveDoc;
pgf = doc.TextSelection.beg.obj;
cell = pgf.InTextObj;
regex = /\./; // this finds a decimal
// ...navigate down the column.
while (cell.ObjectValid () === 1) { //I think this is where it breaks down
processDec (pgf, doc, regex);
cell = cell.CellBelowInCol;
}
// From here down it works great, on one cell.
function processDec (pgf, doc, regex) { //by FrameExpert
var end = Constants.FV_OBJ_END_OFFSET - 1, begin = 0, textRange;
var textList = pgf.GetText (Constants.FTI_CharPropsChange);
for (var i = textList.length - 1; i >= 0; i -= 1) {
begin = textList[i].offset;
if (begin !== end) {
textRange = new TextRange (new TextLoc (pgf, begin), new TextLoc (pgf, end));
if (regex.test (getText (textRange, doc)) === false) { // if there is a decimal, nothing happens
addDecimal ();
}
end = begin;
}
}
if (end > 0) {
textRange = new TextRange (new TextLoc (pgf,0), new TextLoc (pgf,end));
if (regex.test (getText (textRange, doc)) === false) { // if there is a decimal, nothing happens
addDecimal ();
}
}
}
function getText (textObj, doc) { //by FrameExpert
var text = "", textItems, i;
if (textObj.constructor.name !== "TextRange") {
textItems = textObj.GetText(Constants.FTI_String);
} else {
textItems = doc.GetTextForRange(textObj, Constants.FTI_String);
}
for (i = 0; i < textItems.len; i += 1) {
text += (textItems[i].sdata);
}
return text;
}
function addDecimal () {
var textRange = new TextRange;
textRange.beg.obj = textRange.end.obj = pgf;
textRange.beg.offset = 0;
textRange.end.offset = Constants.FV_OBJ_END_OFFSET - 1;
doc.TextSelection = textRange;
textRange = doc.TextSelection;
doc.AddText(textRange.end, ".0");
addWhite (); //calls function to apply the White character format to the .0
}
function addWhite () {
var textRange = new TextRange;
textRange.beg.obj = textRange.end.obj = pgf;
textRange.beg.offset = Constants.FV_OBJ_END_OFFSET - 3;
textRange.end.offset = Constants.FV_OBJ_END_OFFSET - 1;
applyCharFmt (textRange, "White", doc);
}
function applyCharFmt (textRange, name, doc) {
var charFmt = 0;
charFmt = doc.GetNamedCharFmt (name);
if (charFmt.ObjectValid()) {
doc.SetTextProps (textRange, charFmt.GetProps());
}
}
If it's possible, I'd like it if we could run it on multiple selected columns. Can anyone help me fix this?
Thank you.
Hi,
You have gone a long time without a reply. Maybe you figured it out already. I think the lack of response is related to the big changes with these forums. I'm sorry that you did not get any help yet.
I think your problem is very simple and exactly where you identified it. The problem is that you are iterating through multiple cells, but never resetting the paragraph for processing to the new cells. I think you just need to add one line as shown below:
// ...navigate down the column.
while (ce
Copy link to clipboard
Copied
I would suggest contacting someone like Rick Quatro. His TableCleanerES script already does formatting changes for columns on a mass basis, and I expect the parts of it that move from cell to cell or apply column formats could be adapted to what you want to do. Be aware that his scripting is part of how he makes a living, so he may charge for this. I can vouch that his scripts are excellent aids and that his charges are quite reasonable.
Copy link to clipboard
Copied
Hi,
You have gone a long time without a reply. Maybe you figured it out already. I think the lack of response is related to the big changes with these forums. I'm sorry that you did not get any help yet.
I think your problem is very simple and exactly where you identified it. The problem is that you are iterating through multiple cells, but never resetting the paragraph for processing to the new cells. I think you just need to add one line as shown below:
// ...navigate down the column.
while (cell.ObjectValid () === 1) { //I think this is where it breaks down
var pgf = cell.FirstPgf;
processDec (pgf, doc, regex);
cell = cell.CellBelowInCol;
}
For multiple selected columns, you need to first be able to find out which cells are selected. Here is an uncommented function I use for that. You will need to interpolate the results into the desired columns. For example, for each selected cell returned, you would need to iterate up to find the top of the column, then run your column modifier routine. And you would want to remember the columns you processed (by remembering the top cell) so you don't process columns multiple times. I hope this helps.
Russ
function tbl_GetSelectedCells(oDoc, oTable)
{
var cells = new Array();
if(!oDoc.ObjectValid())
return cells;
if(!oTable.ObjectValid())
oTable = doc.SelectedTbl;
if(!oTable.ObjectValid())
return cells;
var oRow = oTable.TopRowSelection;
var bottomRowSelected = oTable.BottomRowSelection;
var leftColSelected = oTable.LeftColNum;
var rightColSelected = oTable.RightColNum;
while(oRow.ObjectValid())
{
var i = 0;
oCell = oRow.FirstCellInRow;
while(oCell.ObjectValid())
{
if(i >= leftColSelected && i <= rightColSelected)
cells.push(oCell);
i++;
oCell = oCell.NextCellInRow;
}
if(oRow.id == bottomRowSelected.id)
oRow = oDoc.GetNamedColor ("InvalidateThisObject");
else oRow = oRow.NextRowInTbl;
}
return cells;
}
Copy link to clipboard
Copied
Hi Russ,
Thank you for your reply. No, I hadn't received an answer yet. I figured the new format was why.
I used the line you added in my initial code and it does move down the column now. But something is still wrong. I put the cursor in the first cell of each column and ran it. It does this:
(I used "bold" instead of "white" so I could see what it was doing.) The code says to use the addDecimal function if there is no decimal, but on some of the cells it is ignoring that. Is there something wrong with my textRange?
Thanks,
Julie
Copy link to clipboard
Copied
Hi Julie, I think I can help. But I need you to help me first... Can you explain the basic logic of the processDec() function? It basically looks like a simple end goal... check if there is a decimal in the cell. If there is one, do nothing. If there is none, add ".0" to the end of the text.
If that is the goal, I can't follow your various loops. I don't know why you are retrieving FTI_CharPropsChange text items and I don't follow the second conditional - if(end > 0)...
If all you care about is checking for a decimal; that is, a period, it seems that it could be much simpler. I would do something like this (untested):
var pgf = cell.FirstPgf;
var text = getText(pgf, doc);
if(text.indexOf(".") > -1)
{
//Do the decimal add...
}
You might even want to test an index >0 instead of -1, just to be sure there actually is a digit before the decimal. But that probably doesn't really matter.
So let me know if there is more to the story. The complexity of your code suggests that there is something else going on and I don't have the time to decipher it all 🙂 And apparently the history of this thread is not available now.
Russ
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Russ,
Here is my original post (it got lost in the forum transition):
I am looking for/trying to write a script to align decimals (and assumed decimals) in a table. FrameMaker does not align a column of numbers in a table to the decimal/assumed decimal. Instead, numbers without the decimal are shifted to the right a little.
To get around this, we have to add a decimal after the whole number and color it white, so that it looks like this:
I am trying to write a script to do this for us. The ultimate goal is for us to select the column or columns and then run the script on them. The script will read through the columns and when if finds a whole number, it will add “.0” and tag it “White,” then move on to the next whole number. I’ve been searching the forum for scripts others have shared, and I’m trying to build from the bottom up. So far, I can add the decimal in single cell.
I can also apply the character format; however, it only works if the cursor is before the decimal. If the cursor is after the decimal, it jumps to the next cell, but it doesn’t do anything. How do I make it apply the character format regardless of where the cursor is? [I got this part to work with help from people on the forum.]
I was trying to build from the bottom up, like FrameExpert always says to do. So I started with the most basic step -- adding the decimal. Did I make it more complicated that I needed to?
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Yes, the questions was for you. I'll give what you suggested a try.
By "build from the bottom up" I just meant making it work one step at at time. First, seeing if it was a decimal; next, add a decimal; next, make it white, etc. I was trying to adapt code that I already had, which is probably why it was so complicated.
By the way, do you get notifications? I keep changing my settings to get them, but whenever I log back in, it's reset.
Copy link to clipboard
Copied
It works!
var pgf = cell.FirstPgf;
var text = getText(pgf, doc);
if(text.indexOf(".") === -1)
{
addDecimal ();
}
Thank you for your help, Russ!
Julie
Copy link to clipboard
Copied
Copy link to clipboard
Copied
I changed it to <0 and also added "&& isNaN(text) == false" because sometimes we may have a dash or NA or some other non-number in the field. Thank you again for your help!
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Where do you do that now? I don't see that option anywhere.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Maybe it's Report, but that's usually is a bad thing. I was a little scared to try it. 🙂
---
Nope, it's not Report.
I'm not a fan of this new forum design.
Copy link to clipboard
Copied
Apparently only an Adobe staff member or moderator can mark a post as corrrect.