Copy link to clipboard
Copied
var doc = app.activeDocument;
var textFrames = doc.textFrames;
var numTextFrames = textFrames.length; for (var i = 0; i < numTextFrames; i++) { var tf = textFrames[i]; if (tf.kind == TextType.AREATEXT && tf.textPath.contents.length > 0 && tf.textPath.overflows) { alert("Overset text detected in text frame " + (i+1)); } }
can anyone here help me on this!
This returns error
or any other way to alert
Try this
var doc = app.activeDocument;
var textFrames = doc.textFrames;
var numTextFrames = textFrames.length;
for (var i = 0; i < numTextFrames; i++) {
var tf = textFrames[i];
if (tf.kind == TextType.AREATEXT &&
tf.contents.length > 0 &&
overflows(tf)) {
alert("Overset text detected in text frame " + (i + 1));
// tf.selected = true;
}
}
function overflows(tf) {
var lastLine = tf.lines[tf.lines.length - 1];
var textRange1 = lastLine.con
...
Copy link to clipboard
Copied
Hi @thirukumarans77083, I've put together a function to do this, which I found in another area on this forum. See code for link. - Mark
var doc = app.activeDocument;
var textFrames = doc.textFrames;
var numTextFrames = textFrames.length;
for (var i = 0; i < numTextFrames; i++) {
var tf = textFrames[i];
if (textFrameIsOverset(tf)) {
alert("Overset text detected in text frame " + (i + 1) + ' ' + tf.name);
}
}
/**
* Returns true if an Illustrator Area Text Frame is overset.
* @author based on code by moluapple
* @url https://community.adobe.com/t5/illustrator-discussions/illustrator-javascript-for-quot-identify-overset-text-in-a-text-frame-and-reduce-the-font-size-quot/td-p/9273739
* @param {TextFrame} tf - an Illustrator text frame.
* @returns {Boolean}
*/
function textFrameIsOverset(tf) {
var isOverset = !tf.hasOwnProperty('kind') || tf.kind != TextType.AREATEXT;
var dup = tf.duplicate();
dup.name = 'temp';
dup.convertAreaObjectToPointObject();
dup = tf.parent.textFrames['temp'];
isOverset = dup.contents.replace(/[\x03\r]/g, '') !== tf.contents.replace(/[\x03\r]/g, '')
dup.remove();
return isOverset;
};
Copy link to clipboard
Copied
An alternative function (not rigorously tested).
var doc = app.activeDocument;
var textFrames = doc.textFrames;
var numTextFrames = textFrames.length;
for (var i = 0; i < numTextFrames; i++) {
var tf = textFrames[i];
if (tf.kind == TextType.AREATEXT &&
tf.contents.length > 0 &&
overflows(tf)) {
alert("Overset text detected in text frame " + (i + 1));
}
}
function overflows(tf) {
var lastLine = tf.lines[tf.lines.length - 1];
var textRange1 = lastLine.contents;
var textRange2 = "";
for (var i = tf.characters.length - 1;
i > (tf.characters.length - lastLine.contents.length) - 1;
i--) {
textRange2 = tf.characters[i].contents + textRange2;
}
return textRange1 != textRange2;
}
Copy link to clipboard
Copied
Hey @femkeblanco, I really like your method—much cleaner. Nice one! - Mark
Copy link to clipboard
Copied
@m1b @femkeblanco
Thankyou both
I am trying and testing both
@m1b
One thing with the first method is the layers should be unlocked, also the sublayers, sub groups.
sometimes with multiple elements, it returns an error, but I am analysing it.
@femkeblanco
With your method as @m1b said is clear but i tried in multiple documents with multiple elements, it also alerts for multiple frames which does n't have any overset warning.
Copy link to clipboard
Copied
Hi @thirukumarans77083, thanks for testing.
Could you please post an Illustrator file with example textframe(s) that fail for @femkeblanco's function? You can attach it here if you save it as a .pdf with Illustrator editing capabilities.
It is possible to fix the problem you noticed with the script I posted, but @femkeblanco's is nicer, so I would like to fix that if possible.
- Mark
Copy link to clipboard
Copied
Hello, @m1b Here with the file this one should not be overset.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Thanks! Can you try this, please:
var doc = app.activeDocument;
var textFrames = doc.textFrames;
var numTextFrames = textFrames.length;
for (var i = 0; i < numTextFrames; i++) {
var tf = textFrames[i];
if (tf.kind == TextType.AREATEXT &&
tf.contents.length > 0 &&
overflows(tf)) {
alert("Overset text detected in text frame " + (i + 1));
}
}
function overflows(tf) {
var lastLine = tf.lines[tf.lines.length - 1];
var textRange1 = lastLine.contents;
var textRange2 = "";
var linefeeds = /[\n\r]/g;
for (var i = tf.characters.length - 2;
i > (tf.characters.length - lastLine.contents.length) - 2;
i--) {
textRange2 = tf.characters[i].contents + textRange2;
}
return textRange1.replace(linefeeds,'') != textRange2.replace(linefeeds,'');
}
Copy link to clipboard
Copied
@m1b
The updated one works for the shared document only but if we tested in other documents. not working as it shows multiple frame as overset.
Please find the example file
Copy link to clipboard
Copied
Right, well I couldn't get @femkeblanco's version to work with the variety of cases, so I've gone back to @moluapple's technique. ( @moluapple feel free to let us know if you have improved upon it after your original post.) Here is the script. It shows (a) a technique for getting the overset text frames even if the layers are locked or hidden, and (b) an example usage of selecting the overset text frames (after unhiding and unlocking their layer). I hope that will give you enough info to adapt for your own needs.
- Mark
/**
* Collect the overset text frames in active document.
*/
var oversetTextFrames = getOversetTextFrames(app.activeDocument);
if (oversetTextFrames != undefined) {
// example usage: select overset text frames
app.selection = [];
for (var i = 0; i < oversetTextFrames.length; i++) {
oversetTextFrames[i].layer.hidden = false;
oversetTextFrames[i].layer.locked = false;
oversetTextFrames[i].selected = true;
}
}
/**
* Returns any overset
* textFrames in document.
* @param {Document} doc - an Illustrator Document.
* @returns {Array<TextFrame>}
*/
function getOversetTextFrames(doc) {
var oversetTextFrames = [],
textFrames = doc.textFrames,
tempLayer = doc.layers.add();
for (var i = 0; i < textFrames.length; i++) {
var tf = textFrames[i];
if (textFrameIsOverset(tf, tempLayer))
oversetTextFrames.push(tf);
}
tempLayer.remove();
return oversetTextFrames;
}
/**
* Returns true if an Illustrator Area Text Frame is overset.
* @author based on code by moluapple
* @url https://community.adobe.com/t5/illustrator-discussions/illustrator-javascript-for-quot-identify-overset-text-in-a-text-frame-and-reduce-the-font-size-quot/td-p/9273739
* @param {TextFrame} tf - an Illustrator text frame.
* @param {Layer} tempLayer - where to place the temporary duplicate.
* @returns {Boolean}
*/
function textFrameIsOverset(tf, tempLayer) {
if (
!tf.hasOwnProperty('kind')
|| tf.kind != TextType.AREATEXT
)
return false;
var dup = tf.duplicate(tempLayer);
dup.convertAreaObjectToPointObject();
dup = tempLayer.textFrames[0];
isOverset = dup.contents.replace(/[\x03\r]/g, '') !== tf.contents.replace(/[\x03\r]/g, '')
dup.remove();
return isOverset;
};
Copy link to clipboard
Copied
@thirukumarans77083 Unfortunately, I can't open your file properly, because I use CS6, so I can't take this further forward.
Copy link to clipboard
Copied
Sorry, @femkeblanco, here is sample file.
Copy link to clipboard
Copied
Thanks, @m1b. I'll have a look, probably tomorrow, and post if I get anywhere.
Copy link to clipboard
Copied
Thank you!
Copy link to clipboard
Copied
@m1b The only error I get with the file you kindly attached is because of a carriage return at the end of a text frame. I realised after making the fix below that that is what you've already done above. So this will presuambly not fix the OP's errors. (Also, it's unclear if the OP is happy with your adaptation of moluapple's script, in which case we can move on.)
var doc = app.activeDocument;
var textFrames = doc.textFrames;
var numTextFrames = textFrames.length;
for (var i = 0; i < numTextFrames; i++) {
var tf = textFrames[i];
if (tf.kind == TextType.AREATEXT &&
tf.contents.length > 0 &&
overflows(tf)) {
alert("Overset text detected in text frame " + (i + 1));
}
}
function overflows(tf) {
var lastLine = tf.lines[tf.lines.length - 1];
var textRange1 = lastLine.contents;
var textRange2 = "";
var i = tf.characters.length - 1;
var difference = (tf.characters.length - lastLine.contents.length) - 1;
var lastChar = tf.characters[tf.characters.length - 1].contents;
if (lastChar == "\r") i--, difference--;
for (i; i > difference; i--) {
textRange2 = tf.characters[i].contents + textRange2;
}
return textRange1 != textRange2;
}
Copy link to clipboard
Copied
Hi @femkeblanco, I tried your updated version and it worked perfectly on the sample file. As far as I can tell, you solved the problem, and when I tried I don't think I really even understood the issue of the extra linefeed correctly, so thank you for showing the way!
@thirukumarans77083 You may replace my version with this one if you like. Personally I prefer @femkeblanco's version because it does no DOM manipulation (mine makes a temp layer and duplicate textframe), but in practice they are probably indistinguishable to the user. Bear in mind that you will need to deal with the locked or hidden layers/items problem by setting those to false (see example in my script above).
- Mark
Copy link to clipboard
Copied
@m1b @femkeblanco Thank you very much, I have tested it working well on the documents shared, but some of the tested files still show the display alert of the textbox which doesn't have the overset warning.
Copy link to clipboard
Copied
So, we are getting somewhere! If you have an example with text frame(s) where the script doesn't work, please post as pdf again for us to test. When you save-as the sample file, please save as .ai file version CS6, and then change the file extension from ".ai" to ".pdf" and then post that .pdf file here.
Copy link to clipboard
Copied
@m1b sure I will share once I am ready with the converted files.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Try this
var doc = app.activeDocument;
var textFrames = doc.textFrames;
var numTextFrames = textFrames.length;
for (var i = 0; i < numTextFrames; i++) {
var tf = textFrames[i];
if (tf.kind == TextType.AREATEXT &&
tf.contents.length > 0 &&
overflows(tf)) {
alert("Overset text detected in text frame " + (i + 1));
// tf.selected = true;
}
}
function overflows(tf) {
var lastLine = tf.lines[tf.lines.length - 1];
var textRange1 = lastLine.contents;
var textRange2 = "";
var i = tf.characters.length - 1;
var difference = (tf.characters.length - lastLine.contents.length) - 1;
var lastChar = tf.characters[tf.characters.length - 1].contents;
for (var j = 0; j < 32; j++) {
if (lastChar == String.fromCharCode(j) && lastChar != "\t") {
i--, difference--;
break;
}
}
for (i; i > difference; i--) {
textRange2 = tf.characters[i].contents + textRange2;
}
return textRange1 != textRange2;
}
Copy link to clipboard
Copied
Hello, @femkeblanco @m1b Thankyou both as the last update from @femkeblanco works fine.
Copy link to clipboard
Copied
Awesome! 🙂
Copy link to clipboard
Copied
Your code is good but fails if only one line is overflown and last two lines are the same.
You can approach it more simpler. count the characters of all viewable lines and compare it with the length of all characters in the text area. But you should consider the fact that between any two lines there is a new line character.
function is_text_overflow(text){
var char_num_lines = 0;
for(var i = 0; i < text.lines.length; i++)
char_num_lines += text.lines[i].contents.length;
return text.characters.length != (char_num_lines + text.lines.length - 1);
}