Add line numbering to a .docx with ActiveXObject('Word.Application') - javascript

Hi i want to add line numbering to the opened .docx file before converting it to .pdf and i really didn't find how to do that on code, it is converting my .docx file to pdf but i wanna add line numbering too, am using ActiveXObject with javascript to do that on server
var obj = new ActiveXObject("Scripting.FileSystemObject");
var docPath = WScript.Arguments(0);
docPath = obj.GetAbsolutePathName(docPath);
var pdfPath = docPath.replace(/\.doc[^.]*$/, ".pdf");
var objWord = null;
try
{
objWord = new ActiveXObject("Word.Application");
objWord.Visible = false;
var objDoc = objWord.Documents.Open(docPath);
var format = 17;
objDoc.SaveAs(pdfPath, format);
objDoc.Close();
WScript.Echo("Saving '" + docPath + "' as '" + pdfPath + "'...");
}
catch(e){
WScript.Echo(e);
}
finally
{
if (objWord != null)
{
objWord.Quit();
}
}

If you want to automate Word but you don't know how to do it in code, start recording a macro, do what you want, then stop recording and review the code. You should be able to figure out what you need from the generated code.
Here's an example of a recorded macro:
Sub Macro1
With Selection.PageSetup
With .LineNumbering
.Active = True
.StartingNumber = 1
.CountBy = 1
.RestartMode = wdRestartContinuous
.DistanceFromText = wdAutoPosition
End With
.Orientation = wdOrientPortrait
.TopMargin = InchesToPoints(1)
.BottomMargin = InchesToPoints(1)
.LeftMargin = InchesToPoints(1)
.RightMargin = InchesToPoints(1)
.Gutter = InchesToPoints(0)
.HeaderDistance = InchesToPoints(0.5)
.FooterDistance = InchesToPoints(0.5)
.PageWidth = InchesToPoints(8.5)
.PageHeight = InchesToPoints(11)
.FirstPageTray = wdPrinterDefaultBin
.OtherPagesTray = wdPrinterDefaultBin
.SectionStart = wdSectionNewPage
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.VerticalAlignment = wdAlignVerticalTop
.SuppressEndnotes = False
.MirrorMargins = False
.TwoPagesOnOne = False
.BookFoldPrinting = False
.BookFoldRevPrinting = False
.BookFoldPrintingSheets = 1
.GutterPos = wdGutterPosLeft
End With
End Sub
Based on that example, I would assume your code would need to include this for line numbers:
objDoc.PageSetup.LineNumbering.Active = true;

Related

How to pass a JavaScript variable to XML?

I want to pass JavaScript variable's value to an XML file. I have already seen this question and answer here but since my XML file is not that small but rather big, I would like to know how to do this without writing whole xml if possible.
I have this JavaScript code
render_receipt: function () {
// this._super();
var self = this;
if (self.pos.config.disable_fiscalization == false) {
var data = self.get_receipt_render_env();
self.$('.pos-receipt-container').html("")
var total_amount = data['receipt']['total_with_tax'];
var vat = self.pos['company']['vat'];
var header_time = data['order']['formatted_validation_date'];
var order_name = data['order']['name'];
var soft_code = self.pos['company']['software_code'];
var business_unit_code = self.pos['config']['business_unit_code'];
var business_unit_address = self.pos.business_unit_address
var tcr_code = self.pos['config']['tcr_code'];
var operator_code = self.pos.get_cashier().operator_code
// create message
message = vat + '|' + header_time + '|' + order_name + '|' + business_unit_code + '|' + tcr_code + '|' + soft_code + '|' + total_amount
var order = self.pos.get_order();
if (!this.pos.config.iface_print_via_proxy) {
var invoiced = new $.Deferred();
// if (self.pos.config.disable_fiscalization == false) {
// console.log("hasEnoughSpeed", hasEnoughSpeed, isAlive)
if (isAlive && hasEnoughSpeed) {
rpc.query({
model: 'pos.order',
method: 'search_read',
domain: [['pos_reference', '=', order['name']]],
fields: ['iic_code', 'header_send_datetime', 'amount_total', 'fic', 'business_unit_code', 'operator_code', 'fiscalization_url', 'partner_id']
})
.then(function (orders) {
var partner = null;
if (orders.length && orders[0]['partner_id'] == false) {
var data = self.get_receipt_render_env();
data['partner_name'] = orders[0]['partner_id'][1];
data['street'] = false;
data['country'] = false;
data['city'] = false;
data['zip'] = false;
data['vat'] = false;
data['nslf'] = orders[0]['iic_code'];
// alert(data['nslf'])
data['nivf'] = orders[0]['fic'];
data['business_unit_code'] = business_unit_code;
data['operator_code'] = operator_code;
data['business_unit_address'] = business_unit_address
self.$('.pos-receipt-container').html(qweb.render('PosTicket', data));
var qr = new QRious({
element: document.getElementById('qr-code'),
size: 200,
});
I'd like to pass data['nsfl'] to this XML div tag. I have already tried as you see and it is failing, I get why it is failing and from the other side I don't know how to make work either. Thanks in advance guys!!!
<div>
<div style="font-weight:bold;font-size:12px;">NSLF: <t t-esc="data['nslf']"/></div>
</div>

How to set a time-driven (clock) trigger for a function that needs parameters sent to it?

I'm trying to have a function run with a time-driven (clock) trigger. My issue is, the function needs variables sent to it as parameters. Normally if I'm not using a trigger I'll just send it directly like this.
<script>
function runFunction(){
google.script.run.myFunction(x,y,z);
}
</script>
And on the server side, I'll call them easily.
function myFunction(x,y,z){
var a = x;
var b = y;
var c = z;
Logger.log(a+b+c);
}
But when I'm using a time-driven (clock) trigger to run the function how can I get x,y,z into the function.
I searched around and saw one method of creating scriptProperties out of the parameters in the trigger function like this.
EDITED This is the actual code.
Client side.
<script>
function sendCall() {
var testNumber = document.getElementById('numberCall').value;
var testGroup = document.getElementById('groupsCall').value;
var testtime = document.getElementById('scheduleCall').value;
var now = document.getElementsByName('sendTimeCall')[0].checked;
var number;
if(testNumber == ''){
number = null;
}else{
number = testNumber;
}
var group;
if(testGroup == ""){
group = null;
}else{
group = testGroup;
}
var time;
if(testtime == ''){
time = null;
}else{
time = testtime;
}
var file = document.getElementsByName('audio')[0].files[0];
var name = file.name;
var reader = new FileReader();
reader.onload = function (e) {
var content = reader.result;
google.script.run.withSuccessHandler(success2).triggerCall(group, number, content, time, now, name);
return false;
}
reader.readAsDataURL(file);
}
</script>
Server side - Trigger Function.
function triggerCall(group, number, content, time, now, name){
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
'GROUP_CALL': group,
'AUDIO': content,
'NUMBER_CALL': number,
'FILE_NAME': name
});
var status;
if(now){
status = 'Call Sent';
}else{
status = 'Call Scheduled';
}
if(now){
return makeCall(status);
}else{
// Set here the date you want to schedule the one-time trigger
var rawdate = time;
var today_D = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));
var scheduled_D = new Date(rawdate);
var time_af = Math.abs(scheduled_D - today_D) / 36e5;
ScriptApp.newTrigger("makeCall")
.timeBased()
.after(time_af * 60 *60 * 1000)
.create();
}
return status;
}
Server side - Here is The function that actually does the work.
function makeCall(status) {
var scriptProperties = PropertiesService.getScriptProperties();
var blob = scriptProperties.getProperty('AUDIO');
var number = scriptProperties.getProperty('NUMBER_CALL');
var group = scriptProperties.getProperty('GROUP_CALL');
var name = scriptProperties.getProperty('FILE_NAME');
var fullNumber;
if(group){
var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxx');
var sheet = ss.getSheetByName(group)
var length = sheet.getLastRow();
var values = sheet.getRange(1, 1, length).getValues();
fullNumber = values.flat();
}else{
var num = number;
var prefix = '+1';
var removeDashes = num.replace(/-/g,"");
var format = prefix + removeDashes;
var comma = format.replace(/ /g, ' +1');
fullNumber = comma.split(' ')
}
//upload file to drive
var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxx');
var blob = blob.split(",");
var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'audio/mpeg', name);
var file = folder.createFile(blob);
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
var id = file.getId();
for (var i = 0; i < fullNumber.length; i++){
//the url with HTTP request to create a call and parameters
var callsUrl = "https://api.twilio.com/2010-04-01/Accounts/ACxxxxxxxxxxxxxxxx/Calls.json";
var payload = {
"To": fullNumber[i],
"From" : "+177777777",
"Twiml" : "<Response><Play>https://docs.google.com/uc?export=play&id=" + id + "</Play></Response>",
};
var options = {
"method" : "post",
"payload" : payload
};
options.headers = {
"Authorization" : "Basic " + Utilities.base64Encode("xxxxxxxxxxx:xxxxxxxx")
};
UrlFetchApp.fetch(callsUrl, options);
}
scriptProperties.deleteProperty('AUDIO');
scriptProperties.deleteProperty('NUMBER_CALL');
scriptProperties.deleteProperty('GROUP_CALL');
scriptProperties.deleteProperty('FILE_NAME');
return status;
}
The problem is when I run the above code without the file input it works, But when I run it as above the function doesn't work. I did some trouble shooting and I think it has to do with transferring the file as a Data URL via the properties method. Is there a limit to how long of a string the VALUE can be?
in a nut shell these are the 2 points of my question.
Any other ideas how to send parameters to a triggered function
How I could do it using PropertiesService.
I would like to propose the following modification.
Modification points:
I think that the reason of your issue might be due to the maximum data size for PropertiesService. In the current stage, it seems that "Properties total storage" is "500kB / property store". I thought that in this case, when you upload a file, the file size might be over than it.
In order to remove your issue, how about creating content as a temporal file and put the file ID to the PropertiesService?
When above points are reflected to your script, it becomes as follows.
Pattern 1:
In this pattern, content is saved as a temporal file and that is used in the function of makeCall().
triggerCall()
function triggerCall(group, number, content, time, now, name){
var scriptProperties = PropertiesService.getScriptProperties();
var tempFile = DriveApp.createFile("tempFile.txt", content, MimeType.PLAIN_TEXT); // Added
scriptProperties.setProperties({'GROUP_CALL': group,'AUDIO': tempFile.getId(),'NUMBER_CALL': number,'FILE_NAME': name}); // Modified
var status;
if(now){
status = 'Call Sent';
}else{
status = 'Call Scheduled';
}
if(now){
return makeCall(status);
}else{
var rawdate = time;
var today_D = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));
var scheduled_D = new Date(rawdate);
var time_af = Math.abs(scheduled_D - today_D) / 36e5;
ScriptApp.newTrigger("makeCall").timeBased().after(time_af * 60 *60 * 1000).create();
}
return status;
}
makeCall()
function makeCall(status) {
var scriptProperties = PropertiesService.getScriptProperties();
var tempfileId = scriptProperties.getProperty('AUDIO'); // Modified
var number = scriptProperties.getProperty('NUMBER_CALL');
var group = scriptProperties.getProperty('GROUP_CALL');
var name = scriptProperties.getProperty('FILE_NAME');
var fullNumber;
if(group){
var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxx');
var sheet = ss.getSheetByName(group)
var length = sheet.getLastRow();
var values = sheet.getRange(1, 1, length).getValues();
fullNumber = values.flat();
}else{
var num = number;
var prefix = '+1';
var removeDashes = num.replace(/-/g,"");
var format = prefix + removeDashes;
var comma = format.replace(/ /g, ' +1');
fullNumber = comma.split(' ')
}
var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxx');
var tempFile = DriveApp.getFileById(tempfileId); // Added
var text = tempFile.getBlob().getDataAsString(); // Added
tempFile.setTrashed(true); // Added
var blob = text.split(","); // Modified
var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'audio/mpeg', name);
var file = folder.createFile(blob);
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
var id = file.getId();
for (var i = 0; i < fullNumber.length; i++){
var callsUrl = "https://api.twilio.com/2010-04-01/Accounts/ACxxxxxxxxxxxxxxxx/Calls.json";
var payload = {"To": fullNumber[i],"From" : "+177777777","Twiml" : "<Response><Play>https://docs.google.com/uc?export=play&id=" + id + "</Play></Response>"};
var options = {"method" : "post","payload" : payload};
options.headers = {"Authorization" : "Basic " + Utilities.base64Encode("xxxxxxxxxxx:xxxxxxxx")};
UrlFetchApp.fetch(callsUrl, options);
}
scriptProperties.deleteProperty('AUDIO');
scriptProperties.deleteProperty('NUMBER_CALL');
scriptProperties.deleteProperty('GROUP_CALL');
scriptProperties.deleteProperty('FILE_NAME');
return status;
}
Pattern 2:
In this pattern, content is saved to a file as the decoded data and that is used in the function of makeCall().
triggerCall()
function triggerCall(group, number, content, time, now, name){
var scriptProperties = PropertiesService.getScriptProperties();
var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxx'); // Added
var blob = content.split(","); // Added
var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'audio/mpeg', name); // Added
var file = folder.createFile(blob); // Added
scriptProperties.setProperties({'GROUP_CALL': group,'AUDIO': file.getId(),'NUMBER_CALL': number,'FILE_NAME': name}); // Modified
var status;
if(now){
status = 'Call Sent';
}else{
status = 'Call Scheduled';
}
if(now){
return makeCall(status);
}else{
var rawdate = time;
var today_D = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));
var scheduled_D = new Date(rawdate);
var time_af = Math.abs(scheduled_D - today_D) / 36e5;
ScriptApp.newTrigger("makeCall").timeBased().after(time_af * 60 *60 * 1000).create();
}
return status;
}
makeCall()
function makeCall(status) {
var scriptProperties = PropertiesService.getScriptProperties();
var fileId = scriptProperties.getProperty('AUDIO'); // Modified
var number = scriptProperties.getProperty('NUMBER_CALL');
var group = scriptProperties.getProperty('GROUP_CALL');
var name = scriptProperties.getProperty('FILE_NAME');
var fullNumber;
if(group){
var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxx');
var sheet = ss.getSheetByName(group)
var length = sheet.getLastRow();
var values = sheet.getRange(1, 1, length).getValues();
fullNumber = values.flat();
}else{
var num = number;
var prefix = '+1';
var removeDashes = num.replace(/-/g,"");
var format = prefix + removeDashes;
var comma = format.replace(/ /g, ' +1');
fullNumber = comma.split(' ')
}
var file = DriveApp.getFileById(fileId); // Modified
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
var id = file.getId();
for (var i = 0; i < fullNumber.length; i++){
var callsUrl = "https://api.twilio.com/2010-04-01/Accounts/ACxxxxxxxxxxxxxxxx/Calls.json";
var payload = {"To": fullNumber[i],"From" : "+177777777","Twiml" : "<Response><Play>https://docs.google.com/uc?export=play&id=" + id + "</Play></Response>"};
var options = {"method" : "post","payload" : payload};
options.headers = {"Authorization" : "Basic " + Utilities.base64Encode("xxxxxxxxxxx:xxxxxxxx")};
UrlFetchApp.fetch(callsUrl, options);
}
scriptProperties.deleteProperty('AUDIO');
scriptProperties.deleteProperty('NUMBER_CALL');
scriptProperties.deleteProperty('GROUP_CALL');
scriptProperties.deleteProperty('FILE_NAME');
return status;
}
Note:
In this modified script, when a file is uploaded, content is saved as a temporal file and the file ID is put to the PropertiesService. When makeCall is run, content is retrieved by the file ID and convert to the blob and saved it as a file. And the temporal file is removed. By this, the limitation of PropertiesService can be cleared.
But, in the current stage, the maximum blob size of Google Apps Script is 50 MB (52,428,800 bytes). So when the uploaded file size is over 50 MB, an error occurs. In this case, the file is converted to the base64 data. So, the maximum size is the size of base64 data. Please be careful this.
Reference:
Current limitations

export separate art boards as PNG illustrator script

I've created to a simple illustrator script to loop through the artboards and export each as a PNG back into the folder that the original illustrator file is in. At least I thought I had. I don't need to do anything complicated with layers or different formats this is just a speed up production sort of a thing. I'm a bit rusty on .jsx and appreciate there are similar solutions out there, but I can't get this to run. It seems to fail on the doc.ExportFile line but I really can't see what I'm doing wrong. I'd appreciate anyone taking a look:
var doc = activeDocument;;//Gets the active document
var numArtboards = doc.artboards.length;//returns the number of artboards in the document
var basePath = new File($.fileName).parent.fsName;
$.writeln(doc)
var options;
options = new ExportOptionsPNG24();
options.artBoardClipping = true;
options.matte = false;
options.horizontalScale = 100;
options.verticalScale = 100;
options.transparency = true;
for (var i = 0; i < numArtboards; i++ ) {
doc.artboards.setActiveArtboardIndex( i );
var artboardName = doc.artboards[i].name;
var destFile = new File('/' + artboardName + ".png");
doc.exportFile(destFile, ExportFormat.PNG24 , options);
}
The main problem seemed to be that you hve to have a destination path with the file name. This now seems to work: (You may need to altter the fileNamr generation as code just gets the first nune letters of a filename)
var doc = app.activeDocument;;//Gets the active document
var fleName = doc.name.slice(0, 9)//Get the file code number not the full name;
var numArtboards = doc.artboards.length;//returns the number of artboards in the document
var filePath = (app.activeDocument.fullName.parent.fsName).toString().replace(/\\/g, '/');
$.writeln("fleName= ",fleName)
$.writeln("numArtboards= ",numArtboards)
$.writeln("filePath= ",filePath);
var options = new ExportOptionsPNG24();
for (var i = 0; i < numArtboards; i++ ) {
doc.artboards.setActiveArtboardIndex( i );
options.artBoardClipping = true;
options.matte = false;
options.horizontalScale = 100;
options.verticalScale = 100;
options.transparency = true;
var artboardName = doc.artboards[i].name;
$.writeln("artboardName= ", artboardName);
var destFile = new File(filePath + "/" + fleName + " " + artboardName + ".png");
$.writeln("destFile= ",destFile);
doc.exportFile(destFile,ExportType.PNG24,options);
}

using getElementById to get input from a multiline text file into id

I'm a novice at javascript and I'm trying to collect and display information from a text file for manipulation. It is for a caption that needs to be displayed when the program starts up.
So far, I can get the function to work for one line, but when I tried using it for multiple lines, it only grabs the first line of text from the text file and displays it as many times I call it.
I know I need to maybe use an array, but that's a bit more advanced than where I'm currently at. Please let me know if using an array is the most efficient or only way to do this. The sample code is below, and I'm not married to my idea. I'm just trying to figure out the best way to make it work. My group has a template maker, but I can always change they way to do this if it is better.
function write_caption_view(){
var fsow;
fsow = new ActiveXObject("Scripting.FileSystemObject");
text_write = fsow.OpenTextFile(" ", 2, true, -2);
text_write.writeline(document.getElementById("cap").value);
text_write.Close();
stat_write = fsow.OpenTextFile(" ", 2, true, -2);
stat_write.writeline("CONFIGURED");
stat_write.close();
alert("Saved Caption");
}
function read_caption_view(){
var fsor;
fsor = new ActiveXObject("Scripting.FileSystemObject");
text_read = fsor.OpenTextFile(" ", 1, false, -2);
caption_notice = text_read.readline();
text_read.Close();
document.getElementById('cap').value = caption_notice;
}
function display_caption_view(){
document.getElementById('cap').innerHTML = caption_notice;
}
There is a nice example that shows how to split a multiline string into arrays
Basically, you have to split the string by newline
var lines = $('#input').val().split('\n');
or in your case
var lines = document.getElementById("cap1").value.split('\n');
Now in lines you have an array of strings. Those can be processed further with an iterator.
Please notice a simpler way to define a multiple line string in javascript is:
var multiStr = "This is the first line \
This is the second line \
This is more...";
Thanks for the assistance. I figured out a way to do so without an array, and while not as elegant, it works and provides a version that easy to update.
function write_caption_view(){
var fsow, fsor;
fsor = new ActiveXObject("Scripting.FileSystemObject");
fsow = new ActiveXObject("Scripting.FileSystemObject");
text_write = fsow.OpenTextFile("file location", 2, true, -2);
text_write.writeline(document.getElementById("capline1").value);
text_write.writeline(document.getElementById("capline2").value);
text_write.writeline(document.getElementById("capline3").value);
text_write.writeline(document.getElementById("capline4").value);
text_write.writeline(document.getElementById("capline5").value);
text_write.writeline(document.getElementById("capline6").value);
text_write.writeline(document.getElementById("capline7").value);
text_write.writeline(document.getElementById("capline8").value);
text_write.writeline(document.getElementById("capline9").value);
text_write.writeline(document.getElementById("capline10").value);
text_write.writeline(document.getElementById("capline11").value);
text_write.writeline(document.getElementById("capline12").value);
text_write.writeline(document.getElementById("capline13").value);
text_write.writeline(document.getElementById("capline14").value);
text_write.writeline(document.getElementById("capline15").value);
text_write.Close();
stat_write = fsow.OpenTextFile("file location", 2, true, -2);
stat_write.writeline("CONFIGURED");
stat_write.close();
alert("Saved Caption");
}
function read_caption_view(){
var fsor;
fsor = new ActiveXObject("Scripting.FileSystemObject");
fsor = new ActiveXObject("Scripting.FileSystemObject");
text_read = fsor.OpenTextFile("file location", 1, false, -2);
caption_notice_line1 = text_read.readline();
caption_notice_line2 = text_read.readline();
caption_notice_line3 = text_read.readline();
caption_notice_line4 = text_read.readline();
caption_notice_line5 = text_read.readline();
caption_notice_line6 = text_read.readline();
caption_notice_line7 = text_read.readline();
caption_notice_line8 = text_read.readline();
caption_notice_line9 = text_read.readline();
caption_notice_line10 = text_read.readline();
caption_notice_line11 = text_read.readline();
caption_notice_line12 = text_read.readline();
caption_notice_line13 = text_read.readline();
caption_notice_line14 = text_read.readline();
caption_notice_line15 = text_read.readline();
text_read.Close();
document.getElementById('capline1').innerHTML = caption_notice_line1;
document.getElementById('capline2').innerHTML = caption_notice_line2;
document.getElementById('capline3').innerHTML = caption_notice_line3;
document.getElementById('capline4').innerHTML = caption_notice_line4;
document.getElementById('capline5').innerHTML = caption_notice_line5;
document.getElementById('capline6').innerHTML = caption_notice_line6;
document.getElementById('capline7').innerHTML = caption_notice_line7;
document.getElementById('capline8').innerHTML = caption_notice_line8;
document.getElementById('capline9').innerHTML = caption_notice_line9;
document.getElementById('capline10').innerHTML = caption_notice_line10;
document.getElementById('capline11').innerHTML = caption_notice_line11;
document.getElementById('capline12').innerHTML = caption_notice_line12;
document.getElementById('capline13').innerHTML = caption_notice_line13;
document.getElementById('capline14').innerHTML = caption_notice_line14;
document.getElementById('capline15').innerHTML = caption_notice_line15;
}
function display_caption_view(){
document.getElementById('capline1').innerHTML = caption_notice_line1;
document.getElementById('capline2').innerHTML = caption_notice_line2;
document.getElementById('capline3').innerHTML = caption_notice_line3;
document.getElementById('capline4').innerHTML = caption_notice_line4;
document.getElementById('capline5').innerHTML = caption_notice_line5;
document.getElementById('capline6').innerHTML = caption_notice_line6;
document.getElementById('capline7').innerHTML = caption_notice_line7;
document.getElementById('capline8').innerHTML = caption_notice_line8;
document.getElementById('capline9').innerHTML = caption_notice_line9;
document.getElementById('capline10').innerHTML = caption_notice_line10;
document.getElementById('capline11').innerHTML = caption_notice_line11;
document.getElementById('capline12').innerHTML = caption_notice_line12;
document.getElementById('capline13').innerHTML = caption_notice_line13;
document.getElementById('capline14').innerHTML = caption_notice_line14;
document.getElementById('capline15').innerHTML = caption_notice_line15;
}

JavaScript + InDesign: Find a word in a .indd document and write a .txt file with page number locations

I'm running into a problem while trying to execute a script to find a specific word — in this case the name of a project within a book — and write the page numbers of all its occurrences in my InDesign document to a .txt file.
Problem: For whatever reason, the returned "parentPage.name" values are listed out of order (i.e.: its occurrence on p. 184 appears in the list before p. 11, for example, etc.)
I'm not sure if it's related to this code (below) or elsewhere:
pg_nr = found_txt.parentTextFrames[0].parentPage.name;
If anyone has any ideas for how to resolve this, that'd be great. Thank you!
A full version of my code is below:
main ();
function main() {
var file_name = new Date() + "-Title-Project_Name-Page_Location";
var filepath = "~/Desktop/" + file_name + ".txt";
var write_file = File(filepath);
write_file = new File(filepath);
var write_text;
write_text = write_file.open('w', undefined, undefined);
write_file.encoding = "UTF-8";
write_file.lineFeed = "Macintosh";
#target indesign;
var doc = app.activeDocument;
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
app.findChangeTextOptions.includeLockedLayersForFind = true;
app.findChangeTextOptions.includeLockedStoriesForFind = true;
app.findChangeTextOptions.includeHiddenLayers = false;
app.findChangeTextOptions.includeMasterPages = false;
app.findChangeTextOptions.includeFootnotes = true;
app.findChangeTextOptions.caseSensitive = false;
app.findChangeTextOptions.wholeWord = false;
project_name = "Project Name";
app.findTextPreferences.findWhat = project_name;
find_txt = doc.findText();
for (var i = 0; i < find_txt.length; i++) {
if (find_txt[i].contents == project_name) {
found_txt = find_txt[i];
pg_nr = found_txt.parentTextFrames[0].parentPage.name;
write_file.writeln(project_name + " : p. " + pg_nr + "\r\r");
}
}
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
write_file.close();
return;
}
Here's the script modified to push results to an array, and then sort them by the order of appearance in the document.
Clearly the answer is way late... But hopefully it's of use in the future.
main ();
function main() {
var arrResults = [];
#target indesign;
var doc = app.activeDocument;
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
app.findChangeTextOptions.includeLockedLayersForFind = true;
app.findChangeTextOptions.includeLockedStoriesForFind = true;
app.findChangeTextOptions.includeHiddenLayers = false;
app.findChangeTextOptions.includeMasterPages = false;
app.findChangeTextOptions.includeFootnotes = true;
app.findChangeTextOptions.caseSensitive = false;
app.findChangeTextOptions.wholeWord = false;
project_name = "Project Name";
app.findTextPreferences.findWhat = project_name;
find_txt = doc.findText();
for (var i = 0; i < find_txt.length; i++) {
if (find_txt[i].contents == project_name) {
found_txt = find_txt[i];
pg_nr = found_txt.parentTextFrames[0].parentPage.name;
pg_index = found_txt.parentTextFrames[0].parentPage.documentOffset;
// pushes results into an array of objects
arrResults[arrResults.length] = {"project_name":project_name,"page_number":pg_nr,"page_index":pg_index};
}
}
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
// sorts array by the document offset (order of appearance in document)
arrResults = arrResults.sort(function(a,b){return a.page_index>b.page_index});
// convert object to string
for(var i = 0; i<arrResults.length; i++){
arrResults[i] = "project:"+arrResults[i].project_name+", pg:"+arrResults[i].page_number;
}
var file_name = new Date() + "-Title-Project_Name-Page_Location";
var filepath = "~/Desktop/" + file_name + ".txt";
var write_file = new File(filepath);
var write_text;
write_text = write_file.open('w');
write_file.encoding = "UTF-8";
write_file.lineFeed = "Macintosh";
write_file.write(arrResults.join("\n"));
return;
}

Categories