Jump to content

Aligning text after labels


dbarbee

Recommended Posts

Posted

On a business card, I need to left justify some phone numbers after their variable length labels. I took the direction of using tab stops, taking the length of the longest label, and then adding more tabs to the shorter labels to make them all align.

 

Paragraph Tab Stops are set every tenth of an inch, so if I calculate the difference between text widths in tenths of an inch, and add tab tags.

 

First I calculated the longest label width:

var TMO1 = new FusionProTextMeasure;
TM1.pointSize = "8.5 pt";
TM1.font = "HelveticaNeueLT Std";
TM1.useTags = false;
var TM2 = new FusionProTextMeasure;
TM2.pointSize = "8.5 pt";

Etc...


TM1.CalculateTextExtent(Field("C1Label")+":");
TM2.CalculateTextExtent(Field("C2Label")+":");
TM3.CalculateTextExtent(Field("C3Label")+":");

return Math.ceil(Math.max(TM1.textWidth, TM2.textWidth, TM3.textWidth)/720);

 

Then I subtracted the width of the label from the max label width:

 

var TM = new FusionProTextMeasure;
TM.pointSize = "8.5 pt";
TM.font = "HelveticaNeueLT Std";
TM.useTags = false;
TM.CalculateTextExtent(Field("C1Label")+":");
var TMwidth = Math.floor(TM.textWidth/720); //Width of Label (in tenths of inch)
var count = Rule("MaxLabelWidth")-TMwidth;

s = ""
for (c = 0; c < count; c++)
s += ("<t>");

return s+"<t>";

 

This works for the most part, but I'm not getting consistent results.

Posted

It's hard to figure out what all of these rules are doing outside of the context of the template. Can you collect up a sample and post it?

 

That said, instead of using tabs, it might be simpler to use a paragraph indent set to the exact width you want.

Posted

It's very similar to this thread:

http://forums.pti.com/showthread.php?p=7082

 

I would do it with a single rule in the frame, like this:

var targetFrameName = "ContactLabels";
var SpaceAfterLabelInches = 0.05;

var maxWidth = 0;
var TM1 = new FusionProTextMeasure;
TM1.pointSize = "8.5 pt";
TM1.font = "HelveticaNeueLT Std";

for (var i = 1; i <= 3; i++)
{
   TM1.CalculateTextExtent(TaggedDataField("C" + i + "Label")+":");
   if (TM1.messages)
       throw TM1.messages;
   maxWidth = Math.max(maxWidth, TM1.textWidth);
}

var FirstColumnWidth = maxWidth + SpaceAfterLabelInches * 7200;
var FrameWidth = FindTextFrame(targetFrameName).GetSettableTextWidth();
var CellMargins = { Top:0, Bottom:0, Left:0, Right:0 };

var table = new FPTable;
table.AddColumns(FirstColumnWidth, FrameWidth - FirstColumnWidth);
for (var i = 1; i <= 3; i++)
{
   var row = table.AddRow();
   row.Cells[0].Content = TaggedDataField("C" + i + "Label") + ":";
   row.Cells[0].Margins = CellMargins;
   row.Cells[1].Content = TaggedDataField("C" + i + "Number");
   row.Cells[1].Margins = CellMargins;
}
return table.MakeTags();

Posted

Actually, if you want to get a little trickier, this can be done with a single iteration, which will be a bit faster:

var targetFrameName = "ContactLabels";
var SpaceAfterLabelInches = 0.05;

var FrameWidth = FindTextFrame(targetFrameName).GetSettableTextWidth();

var maxWidth = 0;
var TM1 = new FusionProTextMeasure;
TM1.pointSize = "8.5 pt";
TM1.font = "HelveticaNeueLT Std";
var CellMargins = { Top:0, Bottom:0, Left:0, Right:0 };

var table = new FPTable;
table.AddColumns(1, 1); // dummy widths to start
for (var i = 1; i <= 3; i++)
{
   var row = table.AddRow();
   row.Cells[0].Content = TaggedDataField("C" + i + "Label") + ":";
   row.Cells[0].Margins = CellMargins;
   row.Cells[1].Content = TaggedDataField("C" + i + "Number");
   row.Cells[1].Margins = CellMargins;

   TM1.CalculateTextExtent(row.Cells[0].Content);
   if (TM1.messages)
       throw TM1.messages;
   maxWidth = Math.max(maxWidth, TM1.textWidth);
}

var FirstColumnWidth = maxWidth + SpaceAfterLabelInches * 7200;
table.Columns = []; // clear columns to set the actual widths
table.AddColumns(FirstColumnWidth, FrameWidth - FirstColumnWidth);
return table.MakeTags();

Posted

And here's an even simpler version which uses a tab instead of creating a table, but it sets the tab stop position dynamically:

var SpaceAfterLabelInches = 0.05;
var TM1 = new FusionProTextMeasure;
TM1.pointSize = "8.5 pt";
TM1.font = "HelveticaNeueLT Std";

var maxWidth = 0;
var lines = [];
for (var i = 1; i <= 3; i++)
{
   lines.push(TaggedDataField("C" + i + "Label") + ":<t>" + TaggedDataField("C" + i + "Number"));
   TM1.CalculateTextExtent(TaggedDataField("C" + i + "Label") + ":");
   if (TM1.messages)
       throw TM1.messages;
   maxWidth = Math.max(maxWidth, TM1.textWidth);
}

var tabStop = maxWidth + SpaceAfterLabelInches * 7200;
return '<p br=false tabstops="' + tabStop + '">\n' + lines.join("<br>\n");

This is actually a better solution than the table, because you don't need to supply the frame name to get its width. Also, it will compose faster.

Posted

var row = table.AddRow();
   row.Cells[0].Content = TaggedDataField("C" + i + "Label") + ":";

 

Thanks Dan,

 

I'm getting an error on the above code which reads, "line 26: TypeError: row has no properties. Any idea why?

Posted
I'm getting an error on the above code which reads, "line 26: TypeError: row has no properties. Any idea why?

Because you're using a version of FusionPro older than 7.2P1k. You should add the version you're using to your signature. You can fix it by adding this line after the call to table.AddRow():

row = table.Rows[table.Rows.length-1];

However, I recommend using the last solution above with the tab stop instead of a table.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...