fabianmoronzirfas
5/11/2012 - 2:15 PM

creates a InDesign book from jekyll .md files

creates a InDesign book from jekyll .md files

// createBook.jsx
// creates a InDesign Book from .md files

// dependencies as follow
// font
// folder called images in jekyll folder
// some find change queries
// https://github.com/fabiantheblind/MT4D-GREP
// place them under:
// /Users/[YOUR USERNAME]/Library/Preferences/Adobe InDesign/Version [NUMBER]/[LOCALIZATION de_DE]/Find-Change Queries/GREP


// Copyright (c)  2012 
// Fabian "fabiantheblind" Morón Zirfas  
// Permission is hereby granted, free of charge, to any 
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights 
// to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to  permit persons to 
// whom the Software is furnished to do so, subject to 
// the following conditions:  
// The above copyright notice and this permission notice
// shall be included in all copies or substantial portions of the Software.  
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTIO
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  

// see also http://www.opensource.org/licenses/mit-license.php

{

var DEBUG = true;

main();    


/**
 *  Main function without params
 *  evrything is in there
 *
 */
function main(){

// ------------ the GREP FC Queries names are + .xml ------------
var findChangeXMLs = new Array ();
findChangeXMLs.push("md h1");
findChangeXMLs.push("md h2");
findChangeXMLs.push("md h3");
findChangeXMLs.push("md h4");
findChangeXMLs.push("md h5");
findChangeXMLs.push("md h6");
findChangeXMLs.push("md to bold 1");
findChangeXMLs.push("md to bold 2");
findChangeXMLs.push("md to code");
findChangeXMLs.push("md to bq");
// findChangeXMLs.push("md to ul li");
findChangeXMLs.push("md code tabstops");


var findChangeIMAGEGrep = "md find images";


var meta = loadFiles();// get the files from the folder
if(meta == null){return};// if the user cancels
var allMarkdownFiles = meta.files;// allMarkdown
var theFolder = meta.folder;// the folder where to work
var imageFolder = new Folder(theFolder.fsName+"/"+ "images");
var allImages = imageFolder.getFiles("*.*");

var IDtargetFolder = new Folder(theFolder.fsName +"/"+ "IDfiles"); 
 if(!IDtargetFolder.exists){ 

 IDtargetFolder.create();
};


var allDocs = new Array();// for the book
// alert(allMarkdownFiles);


// ------------ now loop the .md files ------------
for (var i in allMarkdownFiles){

var theFile = allMarkdownFiles[i];// File.openDialog ("select your .md file","*.*",false);

// strip of the extension
var nameExtensionless = allMarkdownFiles[i].name.substring(0, allMarkdownFiles[i].name.length-3);

var doc  = createDoc(nameExtensionless);//a new doc with that name

var dp = doc.documentPreferences; // 4 better handling
var mp = doc.marginPreferences; // 4 better handling
var styles  = createStyles(doc); // create the styles 
doc.pages.item(0).appliedMaster = doc.masterSpreads.item(0);
var tf = doc.pages.item(0).textFrames.add({
        geometricBounds:[mp.top,mp.left,dp.pageHeight - mp.bottom, dp.pageWidth - mp.right]
        });// add the first textframe on page 0

var FileString = readinFile(theFile);// read in data from the file
    tf.contents = FileString; // push it into the textframe
    DumbRunPages (doc, tf.parentStory, 0);// now run the pages so ther is no overflow

// ------------ needs a basic par style ------------
    for (var l = doc.textFrames.length - 1; l >= 0; l--) {
      doc.textFrames[l].paragraphs.everyItem().applyParagraphStyle(doc.paragraphStyles.item("body"));
    }; // close l loop 
    DumbRunPages (doc, tf.parentStory, 0);// run it again if it overflows now

// ------------ Find change all markdown - this is a still a bit buggy ------------
    for(var k = 0; k< findChangeXMLs.length; k++){

      app.loadFindChangeQuery (findChangeXMLs[k], SearchModes.grepSearch); 
      app.activeDocument.changeGrep();
        //Clear the find/change grep preferences.
      app.findGrepPreferences = NothingEnum.nothing;
      app.changeGrepPreferences = NothingEnum.nothing;


    }; // close k loop
    // this seems more buggy ;)
     // markdown(doc,styles);

     // now create a file in that folder and safe the doc into it
     var theIDFile  = new File (IDtargetFolder.fsName + "/" + nameExtensionless + ".indd");

     if(theIDFile.exists){
      theIDFile.remove(); // we want to keep it clean and not overwrite
     };


      getImageNames(doc, allImages);

     doc.save(theIDFile); // save the doc

     // add that doc to a list
     allDocs.push(doc);
}; // close i loop


// now make a book
var theBookRef = new File(IDtargetFolder.fsName + "/" + "mt4dBook.indb");
     if(theBookRef.exists){

      theBookRef.remove();
     };

var theBook = app.books.add(theBookRef);

// loop the docs
for (var j in allDocs) {

    theBook.bookContents.add(allDocs[j].fullName); // add every doc to the book
    
  };

        theBook.styleSourceDocument             = allDocs[0];
        theBook.synchronizeBulletNumberingList  =true;
        theBook.synchronizeCharacterStyle       =true;
        theBook.synchronizeMasterPage           =true;
        theBook.synchronizeObjectStyle          =true;
        theBook.synchronizeParagraphStyle       =true;
        theBook.synchronizeSwatch               =true;
 

  theBook.save();

};

/**
 *  loads the markdown files and defiens the folder
 *
 */
function loadFiles(){// the function that loads the files
      var theFolder = Folder.selectDialog ("Choose the FOLDER");// user select a folder
  if(!theFolder){// if the folder is not a folder cancel the script
    return;// this cancels the whole function image_loadFiles \(\)
    }; // end foldr check
  var theFileType = "*.md";// use only jpg
  var allMarkdownFiles = null; // will hold the md files
  try{// encapsulate in a try catch 
  allMarkdownFiles = theFolder.getFiles(theFileType);// get the files by type
     }catch(e){// this is the error catcher
       alert("Error with this:\n" +e);// e is what InDesign says
       };// end catch
  if((allMarkdownFiles.length < 1)||(allMarkdownFiles == null) ){// again if check if there are images
    alert("There are no .md files");// hm something went wrong? User error
    return null;// so we cancel the function
     
     }else{


  return {"files":allMarkdownFiles,"folder":theFolder};// give back the md files. Success!

        };// end all images check
  };


/**
 *  This reads in the data from the found .md files
 *
 */
function readinFile(theFile){
        
  // var textFile = File.openDialog("Select a text file to import.", "*.*",false);
  // var path = ((new File($.fileName)).path);
// var textFile = File( path+"/world_geo_json/" + THESELECTEDFILENAME);
var textFile = File(theFile); // File.openDialog ("select your .md file","*.*",false)

      if (textFile != null) {
        var textLines = new Array();
        textFile.open("r", "TEXT", "????");
        while (!textFile.eof){
                    textLines[textLines.length] = textFile.readln();  
                    }
                 textFile.close();   
                }
            if(!textLines){
                return;
                }
             var str = textLines.join("\r");       
            // var reg = new RegExp("\n|\r","g");
            // str.replace (reg, " ");
            // alert(str);
            // var obj = eval("(" + str + ")"); // evaluate the JSON code
        return str;       
        };



/**
 *  This finds the image referenzes in the text
 *  and places the images from the folder called images
 *
 */
function getImageNames(doc, allImages){


for(var i =0; i < allImages.length;i++){
    app.findTextPreferences = NothingEnum.nothing;
    app.changeTextPreferences = NothingEnum.nothing;
    app.findTextPreferences.findWhat = allImages[i].name;
    var result = doc.findText();
  for (var k = result.length-1; k >= 0; k--){
    
    var ip = result[k].insertionPoints[0];
    var pp = ip.parentStory.parent;
    var target = pp.rectangles.add({
                  geometricBounds:[0,0,100,doc.documentPreferences.pageWidth],
                  label: allImages[i].name
                  });


      target.applyObjectStyle( doc.objectStyles.item("images"),true,false);
// we need to catch this. if there are subfolders or so
 try{ target.place(allImages[i]);}catch(e){/* if(DEBUG)alert(e +"\n" + allImages[i].name) */};

      target.fit(FitOptions.PROPORTIONALLY);
      target.fit(FitOptions.CENTER_CONTENT);


    };

  };

};


/**
 *  This creates the paragraph styles
 *  fine thing is it does that from an
 *  JSON Object
 *
 */
function createStyles(theDoc){


var obstyles = {
  "styles":[
  {
"name": "images", 
"strokeWeight":0,
"enableTextWrapAndOthers":true,
"textWrapPreferences":{
  "textWrapMode":1650552420 /*TextWrapModes.JUMP_OBJECT_TEXT_WRAP*/,
  "textWrapOffset":[5,5]
},
"transparencySettings":{
        "blendingSettings":{
               "opacity":100 
                }
         }
    }
  ]
};

theDoc.objectStyles.add(obstyles.styles[0]);

var basesize = 12;

var h456sz = goldenRatioRetMajor((basesize/3 )*2);
var h3sz = goldenRatioRetMajor((h456sz/3 )*2);
var h2sz = goldenRatioRetMajor((h3sz/3 )*2);
var h1sz = goldenRatioRetMajor((h2sz/2 )*2);



var parStyles = {
  "styles":[ 
      {
        "name":"h1" ,
        "appliedFont":app.fonts.item(50)/* Calluna black */ 
      ,  "pointSize":h1sz,
       "basedOn":theDoc.paragraphStyles.item(0),
       "alignToBaseline":true,
       "leading": goldenRatioRetMinor(h1sz), 
     },
      {"name":"h2"   ,"appliedFont":app.fonts.item(50) ,      "pointSize":h2sz,"alignToBaseline":true,"leading":h2sz },
      {"name":"h3"   ,"appliedFont":app.fonts.item(49) ,     "pointSize":h3sz ,"alignToBaseline":true,"leading":(h3sz)},
      {"name":"h4"   ,"appliedFont":app.fonts.item(49)  ,     "pointSize":h456sz,"alignToBaseline":true ,"leading":(h456sz)},
      {"name":"h5"   ,"appliedFont":app.fonts.item(48)  ,     "pointSize":h456sz,"alignToBaseline":true,"leading":(h456sz)},
      {"name":"h6"   ,"appliedFont":app.fonts.item(48)  ,     "pointSize":h456sz ,"alignToBaseline":true,"leading":(h456sz)},
      {
        "name":"body"  ,
        "appliedFont":app.fonts.item(47)  ,
        "pointSize":basesize /* ,"basedOn":theDoc.paragraphStyles.item(0) */,
        "justification":1818915700 /* left justified*/,
        "firstLineIndent": goldenRatioRetMinor(goldenRatioRetMinor(basesize)),
        "alignToBaseline":true,
        "leading":15, 
      },
      {"name":"ul"  ,"appliedFont":app.fonts.item(47),     "pointSize":11,"alignToBaseline":true},
      {"name":"ol"   ,"appliedFont":app.fonts.item(47)  ,     "pointSize":11,"alignToBaseline":true},
      
      {
        "name":"blockquote" ,
        "appliedFont":app.fonts.item(48) ,
        "pointSize":12 , "basedOn":theDoc.paragraphStyles.item(0),
        "justification":1818915700,/* left justified*/
        "leftIndent":5,
        "rightIndent":5,
        "alignToBaseline":true
         },
         {
        "name":"marginal" ,
        "appliedFont":app.fonts.item(51) ,
        "pointSize":6, /* "basedOn":theDoc.paragraphStyles.item(0) */
        "justification":1818584692, /*left align*/
        /* "gridAlignment":1247896172, */
        "gridAlignFirstLineOnly":true

         }

      ],
     };

  // ------------ CHARCTER STYLES ------------

var charStyles = {
  "styles":[ 
      {"name":"strong"  ,"appliedFont":app.fonts.item(47)},
      {"name":"em"      ,"appliedFont":app.fonts.item(47)},
      {"name":"code"    ,"appliedFont":app.fonts.item(93)}


      ],
     };

// ------------ loop the JSON objects ------------
for(var i in parStyles.styles){

try{
theDoc.paragraphStyles.add(parStyles.styles[i]);
}catch(e){ if(DEBUG)alert(e + "\n" + i +"\n"+ parStyles.styles[i].name);};

};

for(var i in charStyles.styles){

try{
theDoc.characterStyles.add(charStyles.styles[i]);
}catch(e){ if(DEBUG)alert(e + "\n" + i+"\n"+ charStyles.styles[i].name);};

};

// ------------ this is a special style with nested Grep styles ------------
var code = build_code_paragraphStyle(theDoc);


// ------------ this is the styles object that comes back ------------
var styles ={
/* Par styles*/
  "h1"    :theDoc.paragraphStyles.item("h1"),
  "h2"    :theDoc.paragraphStyles.item("h2"),
  "h3"    :theDoc.paragraphStyles.item("h3"),
  "h4"    :theDoc.paragraphStyles.item("h4"),
  "h5"    :theDoc.paragraphStyles.item("h5"),
  "h6"    :theDoc.paragraphStyles.item("h6"),
  "ol"    :theDoc.paragraphStyles.item("ol"),
  "ul"    :theDoc.paragraphStyles.item("ul"),
  "code"  :theDoc.paragraphStyles.item("code"),
  "blockquote"  :theDoc.paragraphStyles.item("blockquote"),

/* char styles*/
  "strong":theDoc.characterStyles.item("strong"),
  "em"    :theDoc.characterStyles.item("em"),
  "code"  :theDoc.characterStyles.item("code")

};



return styles;
};


/**
 *  Creates our doc with lots of specs  
 *
 */
function createDoc (theDocName) {

var ph = 250;
var pw = goldenRatioRetMinor(ph);
var gutter = 4;
var marginalwidth = goldenRatioRetMinor(55);


var doc = app.documents.add({name:theDocName, facingPages:true, documentPreferences:{pageWidth: pw, pageHeight:ph }})
    doc.gridPreferences.baselineDivision = "15pt";

    doc.viewPreferences.properties = {
    horizontalMeasurementUnits: MeasurementUnits.MILLIMETERS,
    verticalMeasurementUnits:MeasurementUnits.MILLIMETERS,
    rulerOrigin: RulerOrigin.PAGE_ORIGIN
    };
var b = goldenRatioRetMinor(42);
var t = 30;
var l = goldenRatioRetMinor(t);

var r = goldenRatioRetMinor(30);

var rhalf =r/2;
var rightnleft = (rhalf + l);


    doc.marginPreferences.properties = {
    top:t,
    left:l,
    bottom:b,
    right:r
  };

var mp = doc.marginPreferences;

    doc.documentPreferences.properties = {
    documentBleedBottomOffset : 3,
    documentBleedTopOffset : 3,
    documentBleedInsideOrLeftOffset : 3,
    documentBleedOutsideOrRightOffset : 3
    };

var ms1 = doc.masterSpreads.item(0);
var ms1p1 = ms1.pages.item(0);// edit the masterspreads
    ms1p1.marginPreferences.properties = {
      right:  mp.right,
      top:    mp.top,
      left:   mp.left,
      bottom: mp.bottom,
      columnGutter:gutter
    };

var ms1p2 = ms1.pages.item(1);//edit the other masterspred

  ms1p2.marginPreferences.properties = {
    right:  mp.right,
    top:    mp.top,
    left:   mp.left,
    bottom: mp.bottom,
    columnGutter:gutter
  };  


var ms2 = doc.masterSpreads.add();
var ms2p1 =  ms2.pages.item(0);// edit the masterspreads

ms2p1.marginPreferences.properties = {
    right:  rhalf,
    top:    mp.top,
    left:   mp.left,
    bottom: mp.bottom,
  columnGutter:gutter,
  columnsPositions:[0,
  marginalwidth, 
  marginalwidth + gutter,
   pw - rightnleft
   ]
  };  

var ms2p2 =  ms2.pages.item(1);// edit the masterspreads

ms2p2.marginPreferences.properties = {
    right:  rhalf ,
    top:    mp.top,
    left:   mp.left ,
    bottom: mp.bottom,
    columnGutter:gutter,
    columnsPositions:[0,
     pw  - ( marginalwidth + gutter + rhalf + mp.left) ,
    pw  - ( marginalwidth + rhalf + mp.left) ,
     pw - (rhalf +mp.left) ]
  };

return doc;
};


// you can use ths solo
// alert($.fileName);
// var d = app.documents.add();
// var par = build_code_paragraphStyle(d);

function build_code_paragraphStyle(d){


var colkw   = color_add (d, "keywords", ColorModel.PROCESS,   [0,0,0,100]);
var colcmnt = color_add (d, "comments", ColorModel.PROCESS,   [0,0,0, 66]);
var colop   = color_add (d, "operators", ColorModel.PROCESS,  [0,0,0,100]);
var colsep  = color_add (d, "separators", ColorModel.PROCESS, [0,0,0,100]);
var colnum  = color_add (d, "numbers", ColorModel.PROCESS,    [0,0,0,100]);
// color_add (d, "comment", ColorModel.PROCESS,               [100,0,75,0]);
var colstr  = color_add (d, "strings", ColorModel.PROCESS,    [0,0,0,100]);


var charStyles = new Array();


var keywords    = d.characterStyles.add({name:"keywords",   fillColor: colkw});
var comments    = d.characterStyles.add({name:"comments",   fillColor: colcmnt});
var operators   = d.characterStyles.add({name:"operators",  fillColor: colop});
var separators  = d.characterStyles.add({name:"separators", fillColor: colsep});
var numbers     = d.characterStyles.add({name:"numbers",    fillColor: colnum});
var comment     = d.characterStyles.add({name:"comment",    fillColor: colcmnt});
var string      = d.characterStyles.add({name:"strings",    fillColor: colstr});


var code = d.paragraphStyles.add({name:"code",appliedFont:"DejaVu Sans Mono	Book",alignToBaseline:true, "pointSize":10 });
//change language (only in this paragraphStyle) to get the right "" for the code
    code.appliedLanguage = app.languagesWithVendors.item("English: USA")
    var grp = code.nestedGrepStyles.add();
        grp.appliedCharacterStyle = keywords;
        grp.grepExpression = "abstract|boolean|break|byte|case|catch|char|class|const|continue|debugger|default|delete|\sdo\s|double|else|enum|export|extends|false|final|finally|float|for|function|goto|if|implements|import|\sin\s|instanceof|int|interface|long|native|\snew\s|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|volatile|while|with";
        
        grp = code.nestedGrepStyles.add();
        grp.appliedCharacterStyle = keywords;
        grp.grepExpression = "is|new|sizeof|typeof";
        
        grp = code.nestedGrepStyles.add();
        grp.appliedCharacterStyle = operators;
        grp.grepExpression = "[-~\\[\\]!$%&*+/:<=>?^|]+";
        
        grp = code.nestedGrepStyles.add();
        grp.appliedCharacterStyle = separators;
        grp.grepExpression = "[(){},;\\s]+";
        
        grp = code.nestedGrepStyles.add();
        grp.appliedCharacterStyle = numbers;
        grp.grepExpression = "\\<[0-9]+(\\.[0-9]+)?([eE][-+]?[0-9]+)?";
        
        grp = code.nestedGrepStyles.add();
        grp.appliedCharacterStyle = comments;
        grp.grepExpression = "/\\*+[^*]*\\*+([^/*][^*]*\\*+)*/";        
        
        
        grp = code.nestedGrepStyles.add();
        grp.appliedCharacterStyle = comment;
        grp.grepExpression = "//.*";        
        
        grp = code.nestedGrepStyles.add();
        grp.appliedCharacterStyle = string;
        grp.grepExpression = "\".*?\"";           
        
return code;        
        };


  //  _    _ _______ _____ _      _____ _______ _____ ______  _____ 
  // | |  | |__   __|_   _| |    |_   _|__   __|_   _|  ____|/ ____|
  // | |  | |  | |    | | | |      | |    | |    | | | |__  | (___  
  // | |  | |  | |    | | | |      | |    | |    | | |  __|  \___ \ 
  // | |__| |  | |   _| |_| |____ _| |_   | |   _| |_| |____ ____) |
  //  \____/   |_|  |_____|______|_____|  |_|  |_____|______|_____/ 
                                                                 
                                                                 
/**
 * calc the golden ratio  
 *
 */ 

function goldenRatioRetMinor(val){
var res = val / 1.618033989;
return res;    
    };


function goldenRatioRetMajor(val){
var res = 1.618033989 * val;
return res;    
    };


// found on http://bit.ly/h5EobK indisnip.wordpress.com ->
// how to apply:

// add CMYK color
//myColorAdd(app.activeDocument, "My Custom Color", ColorModel.PROCESS, [80,50,30,10]);

// add RGB color
//myColorAdd(app.activeDocument, "My Custom Color", ColorModel.PROCESS, [33,66,99]);

// add HEX color
//myColorAdd(app.activeDocument, "My Custom Color", ColorModel.PROCESS, "ABCDEF");

// add color directly
// add CMYK color to document
// and asign it to selected object
//app.selection[0].fillColor = myColorAdd(app.activeDocument, "My Custom Color", ColorModel.PROCESS, [80,50,30,10]);

function color_add(myDocument, myColorName, myColorModel, myColorValue){
  if(myColorValue instanceof Array == false){
    myColorValue = [(parseInt(myColorValue, 16) >> 16 ) & 0xff, (parseInt(myColorValue, 16) >> 8 ) & 0xff, parseInt(myColorValue, 16 ) & 0xff ];
    myColorSpace = ColorSpace.RGB;
  }else{
    if(myColorValue.length == 3)
    { 
      myColorSpace = ColorSpace.RGB;
    }else{  
      myColorSpace = ColorSpace.CMYK;
    };
  };
  try{
    myColor = myDocument.colors.item(myColorName);
    myName = myColor.name;
  } catch (myError){
    myColor = myDocument.colors.add();
    myColor.properties = {name:myColorName, model:myColorModel, space:myColorSpace ,colorValue:myColorValue};
  };
  return myColor;
};

/**
 * This is dumb run pages. (takes care of the overflow)
 */
// by Dave Saunders - where are you Dave?
// UPDATE 2012 05 10 Dave is back!
// http://jsid.blogspot.de/2005/12/function-snippets.html
function DumbRunPages(theDoc, theStory, mssp_id) {  
	// What makes this "dumb" is that default master pages are used.  
	var uRuler = theDoc.viewPreferences.rulerOrigin;  
	theDoc.viewPreferences.rulerOrigin = RulerOrigin.spreadOrigin;
	while (theStory.textContainers[theStory.textContainers.length-1].overflows) {  
		/* 
		// Original: Seite nach der letzten Dokumentseite einfügen 
		theDoc.documentPreferences.pagesPerDocument = theDoc.documentPreferences.pagesPerDocument + 1;  
		var backPage = theDoc.pages[-1]; 
		*/ 
		 
		//alternativ: Seite nach der letzten Textrahmenseite einfügen 
		var backPage = theDoc.pages.add();
        backPage.appliedMaster = theDoc.masterSpreads.item(0);

		app.activeWindow.activePage = backPage;  
//~ 		backPage.appliedMaster = theDoc.pages[-2].appliedMaster;  
		var myPbounds = backPage.bounds;  
		var myNewTF = backPage.textFrames.add();  
		if ((backPage.name % 2 == 1) || (!theDoc.documentPreferences.facingPages)) {  
			myNewTF.geometricBounds =   
			[myPbounds[0] + backPage.marginPreferences.top,   
			myPbounds[1] + backPage.marginPreferences.left,   
			myPbounds[2] - backPage.marginPreferences.bottom,   
			myPbounds[3] - backPage.marginPreferences.right];  
		} else {  
			myNewTF.geometricBounds =   
			[myPbounds[0] + backPage.marginPreferences.top,   
			myPbounds[1] + backPage.marginPreferences.right,   
			myPbounds[2] - backPage.marginPreferences.bottom,   
			myPbounds[3] - backPage.marginPreferences.left];  
		}  
		myNewTF.itemLayer = theStory.textContainers[theStory.textContainers.length-1].itemLayer;  
		myNewTF.previousTextFrame = theStory.textContainers[theStory.textContainers.length-1];  
        
		if (myNewTF.characters.length == 0){  
			theDoc.viewPreferences.rulerOrigin = uRuler;  
			alert("Permanently overset"); // This indicates a permanent overset condition so break out of loop  
            break;
        }  
	}  
	theDoc.viewPreferences.rulerOrigin = uRuler;  
};
   
}