Adobe Illustrator JavaScript - Applying a dataset to each open document in a loop - javascript

I've written a simple script to open two documents in Adobe Illustrator (File -> Scripts) and apply some commands to those documents.
The purpose of the script; with no documents open in Illustrator, the script will:
Open the required documents.
Load an XML variable library into those documents.
Display the dataset in that library (there is only one dataset).
Save the file in a given location.
Close the file.
The script:
try
{
var doc_1 = open(File("C:/file1.ai"));
var doc_2 = open(File("C:/file2.ai"));
var sourceDoc;
var targetFile;
var options = new IllustratorSaveOptions();
for (var i = 0; i < app.documents.length; i++ )
{
sourceDoc = app.documents[i];
sourceDoc.importVariables(new File("C:/variables.xml"));
sourceDoc.dataSets[0].display();
targetFile = new File("C:/output" + sourceDoc.name + '.ai');
sourceDoc.saveAs( targetFile, options );
sourceDoc.close();
}
}
catch(err)
{
alert(err);
}
This code works only for the last opened file (file2.ai). file1.ai is never touched, almost as if there is no loop.
What could be causing this?

When closing the first file in the loop you just moved app.documents[1] to app.documents[0]
You want top loop through them backwards
try your loop with
for (var i = app.documents.length; i >0 ; i-- )

Related

I need a javascript that can extract specific text from a PDF

I work as legal support in litigation. I am not that clued up on scripting, but have managed to adapt a few google searches to perform various tasks for in Adobe.
What I need is help with what I think should be a simple script to read through a PDF and extract Document IDs. They are enclosed in square brackets, so I just need to extract all text between square brackets to a text or CSV file. I have tried using the ChatGPT bot but that hasnt been very successful. This is the code it has given me
// Open the PDF file
var filePath = "/path/to/your/file.pdf";
var doc = app.open(filePath);
// Get the number of pages
var numPages = doc.numPages;
// Create an array to hold the results
var results = [];
// Loop through each page and extract text between square brackets
for (var i = 0; i < numPages; i++) {
var page = doc.getPageNthWordQuads(i);
for (var j = 0; j < page.length; j++) {
var word = page[j];
var text = word[4];
// Check if the text is between square brackets
if (text.startsWith("[") && text.endsWith("]")) {
// Remove the brackets and add the text to the results array
results.push(text.slice(1, -1));
}
}
}
// Save the results to a text file
var outputPath = "/path/to/your/output/file.txt";
var outputFile = new File(outputPath);
outputFile.open("w");
outputFile.write(results.join("\n"));
outputFile.close();
// Close the PDF file
doc.close();
I ran the script, with my file directory, not the placeholder in the script, but nothing happened. No error or anything
I am using a work PC so I cant install python or any other program, hence the need for Java or possibly powershell if that will work
Can anyone help me?
Actually I realised i could do this using the Evermap plugin. Highlight text by pattern - [(.*?)], then extract highlighted text.
This can be achieved with pdf.js library: below example shows if specific text in the first page but can be furhter extended to check the whole pdf. Hope this helps!
// Load PDF.js library
const pdfjsLib = require('pdfjs-dist');
// Load PDF file
const url = 'path/to/pdf/file.pdf';
const loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function(pdf) {
// Load the first page
pdf.getPage(1).then(function(page) {
// Get the text content of the page
page.getTextContent().then(function(textContent) {
// Iterate through each text item
for (let i = 0; i < textContent.items.length; i++) {
const item = textContent.items[i];
// Check if the text item matches your criteria
if (item.str.includes('specific text')) {
console.log(item.str);
}
}
});
});
});
You can get rid of the entire for loop and just use a regular expression with String.match():
const data = "This is the text ofa pdf file [documentid1] and [documentid2].";
const matches = data.match(/(?<=\[).*?(?=\])/gs);
console.log(matches);

Copy Image Google Apps Script

I built a script that copies the contents of document A and pastes it into a new document, document X. Document B,C,D etc are also copied into document X. All the contents copy over great and everything works wonderfully. However, I recently added an image to document A that isn't copying over correctly. The image does show up in the new document (document x), but instead of showing the actual image it just shows a gray box with a caution triangle in it. I've attached a screenshot of the before and after.
Any tips for getting the image to copy over correctly?
Here's the code:
//Now let's use an array to create a list of optional documents we want to assemble.
// We know the cover page is always first so let's add it as the first element of the array.
var listofDocs = new Array(newDoc.getId())
...
//log the array which you've built
console.log("List of docs are: "+listofDocs)
// Now take the array of documents we created, and add their elements to the newDoc one element at a time and one doc at a time.
// Open up the coverpage and tell the system to look at the body of the doc
var basedoc = DocumentApp.openById(listofDocs[0])
var body = basedoc.getBody()
//Open the specified document from listofDocs (one at a time),append each element onto the newDoc one at a time.
for (var i = 1; i < listofDocs.length; ++i){
console.log("looking for elements in: "+ DriveApp.getFileById(listofDocs[i]))
var otherBody = DocumentApp.openById(listofDocs[i]).getBody()
var totalElements = otherBody.getNumChildren()
for (var j=0; j < totalElements; ++j){
var element = otherBody.getChild(j).copy()
var type = element.getType()
console.log("Found an element. Type: "+ type +" in doc: "+ listofDocs[i])
if (type == DocumentApp.ElementType.PARAGRAPH) body.appendParagraph(element)
else if (type== DocumentApp.ElementType.TABLE) body.appendTable(element)
else if (type == DocumentApp.ElementType.LIST_ITEM) body.appendListItem(element)
The image was originally a "wrapped" image. I changed it to "inline" thinking that may help, but no luck.
I tried adding the following code, but this had no effect.
else if (type == DocumentApp.ElementType.INLINE_IMAGE) body.appendImage(element)
This how I append an image to a report
var imageFileName='GTCImg'+ selObj.pid;
var imagesFolder=DriveApp.getFolderById(getGlobal('ImagesDirectoryId'))
var images=imagesFolder.getFilesByName(imageFileName);
while(images.hasNext()){
var imgFile=images.next();
}
if(imgFile){
body.appendImage(Utilities.newBlob(Utilities.base64Decode(imgFile.getBlob().getDataAsString().split(',')[1])));
}

InDesign Export all TextFrames to JPG or PNG Individually

I'm struggling with a problem where I need to get JPGs of all the written questions in InDesign since I work at a school. To make the process faster, I decided to go the "Export Objects" way. But i couldn't find a suitable script to achieve what I need.
Basically,
Select All Text Frames in the given Layout(Alternates are present)
Export All Text frames as JPG with given DPI value and name variable.
Both actions are actually available with the Sample codes, but in a different way. For example: SelectObject script works, but when combined with Command+E, the export result is one big image that contains all the selected frames. I want them separately.
I've tried combining the scripts given as applescript or js with my little knowledge of coding but no cigar.
Select Text : Indesign CC 2018 - SelectObjects Sample Code.
Image export: Indesign CC 2018 - Export to JPG scripts are the codes I've tried mingling with.
Goal: Export all text frames individually as variable DPI, variable name and variable destination from separate alternate layouts.
Edit 1: Code that I'm trying to mingle with. I found it on reddit but even though it essentially does what i need, it does in a crooked way and unusable. IT exports ALL items and they are with the page background, I'd need only the stuff that are contained within the TextFrame.
// Set resolution options
var rp = [72,150,300];
// Set EXPORT presets
app.pngExportPreferences.exportResolution = 72;
app.pngExportPreferences.antiAlias = true;
app.pngExportPreferences.pngQuality = PNGQualityEnum.MAXIMUM;
app.pngExportPreferences.pngColorSpace = PNGColorSpaceEnum.RGB;
app.pngExportPreferences.pngExportRange = PNGExportRangeEnum.EXPORT_RANGE;
// Resolution Select Dialog
var w;
w = new Window('dialog', 'Export Presets');
w.orientation = 'row';
with (w)
{
w.sText = add('statictext', undefined, 'Select Export Resolution:');
w.dropdown = add ( 'DropDownList',undefined,undefined,{items:rp});
w.btnOK = add('button', undefined, 'OK');
};
w.dropdown.selection=0;
w.show();
// Set resolution
var x = 0;
x = x + w.dropdown.selection;
app.pngExportPreferences.exportResolution = rp[x];
// SElECT Folder locations
var myFileAmount = 0;
var myFileLocation = Folder.selectDialog("Please select path of InDesign Files");
myFolder = new Folder ([myFileLocation]);
myFolderContents = myFolder.getFiles("*.indd"); // array
myFileAmount = (myFolderContents.length - 1);
// CHECK IF FILES IN FOLDER
if (myFileAmount < 0){alert("No Files in selected folder");}
else
{
var mySaveLocation = Folder.selectDialog("Please select path to Save PNG");
mySaveFolder = new Folder ([mySaveLocation]);
// OPEN FILES One at a time
for (i = myFileAmount; i >= 0; i--)
{
app.open(File (myFolderContents[i]));
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
// SET Active Document
var myDoc = app.activeDocument;
// EXPORT
//One Page at a time
for (var p=0; p < myDoc.pages.length; p++)
{//page loop
var pname = myDoc.pages.item(p).name;
//set all items in file hiden
for (var itemnum=0;itemnum < myDoc.pages.item(p).pageItems.length; itemnum++)
{
myDoc.pages.item(p).pageItems.item(itemnum).visible = false;
}
// set page to export
app.pngExportPreferences.pageString = pname;
//add a 0 in from on less than 10
if (p<9){var pnm=0;}else{var pnm=""}
//LOOP Through items Set Visibility, export a PNG, Set Visibility
for (var itemexport=0;itemexport < myDoc.pages.item(p).pageItems.length; itemexport++)
{
var itm = itemexport+1;//items start at 1 not 0
myDoc.pages.item(p).pageItems.item(itemexport).visible = true;
//ACTUALLY EXPORTING
app.activeDocument.exportFile(
ExportFormat.PNG_FORMAT,
File(mySaveFolder.fsName + "/" + app.activeDocument.name.split(".indd")[0] + "_"+ pnm + pname + "_" + itm +".png"),
false,
);
//SET VISIBILITY
myDoc.pages.item(p).pageItems.item(itemexport).visible = false;
}
}
app.activeDocument.close(SaveOptions.no);
}
}

javascript: how to pass an array argument from an in-html script to an external JS function

I'm pretty new at Javascript (and web design). I'm trying to design an interactive webgame for purely educational purposes (I'm a professional educator. Most of my programming experience in creating self-contained Java apps).
In my HTML document, I have some internal script that creates a boolean array called hypotheses. I also have an external JS script called game.js that produces some visual output based on its own array, also called hypotheses, which I call using . I would like to update the external array from the internal one, but nothing I try works. The internal script is called from a form.
<script>
var testedhypotheses = [];
var hypotheses = hypArray(); //load up a boolean array of hypotheses.
function testHypothesis(theform, numTest){
//update numbers
theform.newhyp.value = theform.newhyp.value - numTest;
//move hypotheses from one list to the other
for(var i; i < numTest; i++){
testedHypotheses.push(hypotheses.pop());
}
//pass the array of hypotheses to the external function.
updateHyp(testedHypotheses);
</script>
The function definitely works, and items are being moved from one array to another. However, the function updateHyp() is not being called. I've tried it a bunch of ways, but the most recent was to include this in the HTML file:
<script type="text/javascript" src="game.js">
var updateHyp = function (hypArray) {
updateHypotheses(hypArray);
};
</script>
Inside game.js, I have the following code:
var updateHypotheses = function(hypArray){
var end = hypotheses.length;
for(var i = end; i < hypArray.length; i++){
var ind = hypotheses.length;
var tf = hypArray[i];
var rando = Math.random();
var res rando < 0.5 ? 1 : 0;
hypotheses.push(new Hypothesis(i, tf, res));
}
}
};
It seems that this code is never getting called. Any help would be much appreciated!!!

Javascript ignoring all files as opposed to one

I'm trying to get my javascript to ignore one file type extension that's held in a folder with a bunch of photoshop images. For all of the other file types in the folder I have it so that these file types populate a window and the user can import into their work space.
I have modified my script to ignore the file extension I want ignored, however it no longer populates the window with all of the other file types containted in the folder. But when I take out the file I want ignore from the folder, the window gets populated as it should.
This is what I have at the moment that checks my folder for the file types:
//Prompt for folder location
var Path = Folder.selectDialog("Select Folder Location for Renders")
// Use the path to the application and append the samples folder
var samplesFolder = Folder(Path)
//Get the files
var fileList = samplesFolder.getFiles()
//Creat Array to hold names
var renderTypes = new Array();
//Parse Initial name to get similar render elements
var beautyRender = fileList[0].name
beautyRender = beautyRender.substr(0, beautyRender.length-4)
//Get the render elements with a similar name
for (var i = 0; i < fileList.length; i++)
{
var filename = fileList[i].name;
if (filename.match(/\.(stitchinfo)$/i) == null)
{
if(fileList[i].name.substring(0,beautyRender.length) === beautyRender)
{
renderTypes.push(fileList[i].name);
}
}
}
Can anyone see what I've done wrong and need to modify?
Update
I'm still trying to get this to work and following the help from one of the posters below I have modified my code to the following:
for (var i = 0; i < fileList.length; i++)
{
var filename = fileList[i].name;
if (filename.match(/\.(stitchinfo)$/i) == null)
{
renderTypes.push(fileList[i].name);
}
}
However, with this new code comes a new problem in that it returns every file contained in the folders and displays it.
I'm still stumped as to how I can get this to work as I would like. Please can anyone help me?
You're creating a sparse array, because you skip elements in renderTypes when you ignore a filename in fileList. That may be confusing your rendering code. Change to:
renderTypes.push(fileList[i].name);
What if :
for (var i = 0; i < fileList.length; i++)
{
var filename = fileList[i].name;
if (filename.match(/\.(stitchinfo)$/i) == null)
{
if(fileList[i].name.substring(0,beautyRender.length) === beautyRender)
{
renderTypes.push(fileList[i].name);
}
}
}
Wrong usage of the array
Missing ";"
Unnecessary use of "continue".
Managed to get a fix for this.
What I've ended up doing is creating a new function and passing that into my call for checking the folder locations.
function ignoreMe(f)
{
return f.name.match(/\.(stitchinfo)$/i) == null;
}
And the folder check:
var fileList = samplesFolder.getFiles(ignoreMe);

Categories