Advertisement
Cronos

Illustrator Join Text Script

Nov 11th, 2013
582
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #target Illustrator
  2.  
  3. //  script.name = joinText.jsx;
  4. //  script.description = joins broken text pieces (usually from PDF's created with other applications) back into words and or sentences
  5. //  script.requirements = an open document with some POINT text to join
  6. //  script.parent = carlos canto // 11/10/13;
  7. //  script.elegant = false;
  8.  
  9. // Usage: The script targets all text in a document by default, when run, it will read the position of all frames and determine if 2 adjacent frames
  10. //               are close enough to be joined into a word, far enough to be considered another word of the same sentece or way too far to be a separate frame.
  11. //
  12. //               press and hold Ctrl/Cmd before running the script to process Selected text frames only (text inside groups are NOT targeted)
  13. //               press and hold Shift before running the script to change space detection settings
  14.  
  15.  
  16. function main () {
  17.     try {var idoc = app.activeDocument;}
  18.     catch (e) {alert ('open a document and try again'); return };
  19.    
  20.     var tfObj=idoc.textFrames;
  21.    
  22.     var letterSensitivity = 4;
  23.     var wordSensitivity = 2;
  24.     var sensitivity = [letterSensitivity, wordSensitivity];
  25.    
  26.     if(ScriptUI.environment.keyboardState.shiftKey) {
  27.         var msg = '(4,2) should work for most font types & sizes...,';
  28.         msg = msg+'\r- decrease 1st number (3,2) to detect wider letter spacing';
  29.         msg = msg+'\r- decrease 2nd number (4,1) to detect wider word spacing';
  30.         msg = msg+'\r- increase 2nd number (4,4) to make two separate frames';
  31.         strRes = prompt (msg, sensitivity.join (','), 'Letter/Word/Frame Spacing Sensitivity Options');
  32.        
  33.         if (strRes!=null) {// quit if pressed Cancel
  34.             sensitivity = strRes.split (',');
  35.         }
  36.         else {alert ('cancelled by user'); return};
  37.     }
  38.     if(ScriptUI.environment.keyboardState.ctrlKey || ScriptUI.environment.keyboardState.metaKey) { // metaKey = cmd key on a mac
  39.         //alert('ctrl key');
  40.         var sel = idoc.selection;
  41.         tfObj = null;
  42.         tfObj = [];
  43.         for (t=0; t<sel.length; t++) {
  44.             var itext = sel[t];
  45.             if(itext.typename=="TextFrame" && itext.kind=="TextType.POINTTEXT")
  46.                 tfObj.push(itext);
  47.         }
  48.  
  49.     }
  50.  
  51.     // check version and switch order accordingly
  52.     var ver = Number((app.version).substr (0, 2));
  53.     var x = -1; // CS5
  54.     if (ver<15)
  55.         x = 1;  // CS4
  56.  
  57.    
  58.  
  59.     var objectProperties = []; // array to hold top, left, and each frame
  60.  
  61.     // get each text frame properties
  62.     for (var i=0; i<tfObj.length; i++){
  63.         var tf = tfObj[i];
  64.         var tfTop = Math.round(tf.position[1]);
  65.         var tfLeft = Math.round(tf.position[0]);
  66.  
  67.         objectProperties.push([tfTop, tfLeft, tf]);
  68.     }
  69.  
  70.     var objCount = objectProperties.length;
  71.     var pBar = new ProgressBar('joinText Script');
  72.     pBar.reset('Processing...sorting text frames', objCount);
  73.    
  74.     // sort by top then by left
  75.     var sortedArr = objectProperties.sort(mysortfunction);
  76.  
  77.     pBar.close();
  78.    
  79.     // get rid of top and left, so final array has only text frames
  80.     var tFrames = [];
  81.     for (var j=0; j<sortedArr.length; j++){
  82.         tFrames.unshift (sortedArr[j][2]);
  83.     }
  84.  
  85.     joinFrames (tFrames, sensitivity);
  86.    
  87.     // Sort function by dcp @ stackoverflow.com
  88.     function mysortfunction(a, b) {
  89.         pBar.hit();
  90.  
  91.       var o1 = a[0]; // sort by first Field (top)
  92.       var o2 = b[0];
  93.  
  94.       var p1 = a[1]; // then sort by second Field (left)
  95.       var p2 = b[1];
  96.  
  97.       if (o1 != o2) {
  98.         if (o1 < o2) return x; // for CS4 we need to use 1, and -1 for CS5
  99.         if (o1 > o2) return -x;
  100.         return 0;
  101.       }
  102.       if (p1 < p2) return -1;
  103.       if (p1 > p2) return 1;
  104.       return 0;
  105.     } // end sort function
  106.  
  107. } // end main function
  108. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  109.  
  110. function joinFrames (tFrames /*array of textFrames*/, sensitivity /*array [4,2] */) {
  111.    
  112.     var letterSensitivity = sensitivity[0];
  113.     var wordSensitivity = sensitivity[1];
  114.    
  115.     var removeFrames = [];
  116.    
  117.     var frameCount = tFrames.length;
  118.     var pBar = new ProgressBar('joinText Script');
  119.     pBar.reset('Processing...joining frames', frameCount);
  120.        
  121.     for (k = 1 ; k<frameCount ; k++, pBar.hit(k) ) { //loop thru textFrames
  122.  
  123.         var rtFrame = tFrames[k-1];
  124.         var ypos = Math.round (rtFrame.position[1]); // get y
  125.         var rtbounds = rtFrame.geometricBounds;
  126.  
  127.         var ltFrame = tFrames[k];
  128.         if (Math.round(ltFrame.position[1]) == ypos) {
  129.             var ltbounds = ltFrame.geometricBounds;
  130.             var letterSpacing = rtFrame.textRange.characterAttributes.size/letterSensitivity;
  131.             var wordSpacing = rtFrame.textRange.characterAttributes.size/wordSensitivity;
  132.  
  133.             if (ltbounds[2]+letterSpacing >= rtbounds[0]) {
  134.               ltFrame.contents = ltFrame.contents+rtFrame.contents;
  135.               removeFrames.push(rtFrame);
  136.            }
  137.             else {
  138.                 if (ltbounds[2]+wordSpacing >= rtbounds[0]) {
  139.                   ltFrame.contents = ltFrame.contents+" "+rtFrame.contents;
  140.                   removeFrames.push(rtFrame);
  141.                }
  142.            }
  143.        }
  144.     }
  145.  
  146.     var removedCount = removeFrames.length;
  147.     pBar.reset('Processing...deleting incomplete frames', removedCount);
  148.    
  149.     for (e=0; e<removedCount; e++, pBar.hit(e) )
  150.         removeFrames[e].remove();
  151.    
  152.     pBar.close();
  153.    
  154.     var helpmsg = '\r\rHelp: \rScript works on all text by default, press & hold \rCtrl/Cmd before launching the script \rto join selected text frames only.';
  155.     var settingsmsg = '\r\rDefault Settings should work for most scenarios, \rif you ever need to fine tune spacing detection, \r(i.e. for Justified paragraphs) hold Shift before \rlaunching the script to bring up Settings Dialog.';
  156.     alert('Initial frame count: ' + frameCount + ' \rFinal frame count: ' + (frameCount-removedCount)+ helpmsg + settingsmsg);
  157. }
  158.  
  159.  
  160. // progress bar by Marc Autret
  161. function ProgressBar(/*str*/title)
  162. {
  163.      var w = new Window('palette', ' '+title, {x:0, y:0, width:340, height:60}),
  164.           pb = w.add('progressbar', {x:20, y:12, width:300, height:12}, 0, 100),
  165.           st = w.add('statictext', {x:10, y:36, width:320, height:20}, '');
  166.      st.justify = 'center';
  167.      w.center();
  168.      this.reset = function(msg,maxValue)
  169.           {
  170.           st.text = msg;
  171.           pb.value = 0;
  172.           pb.maxvalue = maxValue||0;
  173.           pb.visible = !!maxValue;
  174.           w.show();
  175.           };
  176.      this.hit = function(value) {/*st.text = '\tProcessing... ' + value; */++pb.value;};
  177.      this.hide = function() {w.hide();};
  178.      this.close = function() {w.close();};
  179. };
  180.  
  181. main ();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement