Why is my file_text_read_string not working in GML? - gml

I have the below GML code where I am attempting to read strings from "mygame.txt". When I run the code, the array is just filled with "". I found the buffer section of code and I can see that the var s actually contains the contents of my game. Any idea why the array, arr[] does not properly read the string?
lines= 0
var file = file_text_open_read("mygame.txt"); // need to store in "data files" folder
if (file!= -1){
while (!file_text_eof(file)) {
file_text_readln(file);
lines++;
}
var file_buffer = buffer_load("mygame.txt");
var s = buffer_read(file_buffer, buffer_string);
buffer_delete(file_buffer);
for (var i = 0; i < lines; ++i;){
arr[i] = file_text_read_string(file);
file_text_readln(file);
}
file_text_close(file);
for (var i = 0; i < 1; ++i;){
}}

You are:
Reading the file line by line without saving the strings anywhere
Reading the entirety of a file to a string that you never use
Doing an actual loop to read lines of text from a file, except lines is still 0 so it executes 0 times
(and also you've already read that file until end-of-file so this isn't going to work anyway)
Rest assured, that doesn't work - you have all the parts to do so but they are mashed up with non-functioning code. Could have been
lines = 0;
var file = file_text_open_read("mygame.txt");
if (file != -1) {
while (!file_text_eof(file)) {
arr[lines] = file_text_read_string(file);
file_text_readln(file);
lines++;
}
file_text_close(file);
// arr is now populated with lines from the file
}

The array arr[] is displaying blanks because in
while (!file_text_eof(file)) {
file_text_readln(file);
lines++;
}
I was reading the file through to the end of the file in order to mistakenly get the # of lines in the file for the for loop.
for (var i = 0; i < lines; ++i;){
arr[i] = file_text_read_string(file);
file_text_readln(file);
}
At this point, I am already at the end of the file and therefore no more lines exist. The above for loop processed regardless because the it doesn't care that I was already at the end of file. So all of the indexes in arr[] are blank because it's trying to read lines that don't exist.
To resolve, after the while loop I closed and reopened the file before the for loop.
lines= 0
var file = file_text_open_read("mygame.txt"); // need to store in "data files" folder
if (file!= -1){
while (!file_text_eof(file)) {
file_text_readln(file);
lines++;
}
file_text_close(file);
file_text_open_read(file);
for (var i = 0; i < lines; ++i;){
arr[i] = file_text_read_string(file);
file_text_readln(file);
}
file_text_close(file);
for (var i = 0; i < 1; ++i;){
}}
Another code example by YellowAfterlife is the proper coding
lines = 0;
var file = file_text_open_read("mygame.txt");
if (file != -1) {
while (!file_text_eof(file)) {
arr[lines] = file_text_read_string(file);
file_text_readln(file);
lines++;
}
file_text_close(file);
// arr is now populated with lines from the file
}

Related

Update PDF using pdfBox

I would like to ask if having a PDF it is possible, using pdfbox libraries, to update it at a specific point.
I am trying to use a solution already online but seems the gettoken() method does not enter code heresection the words properly to allow me to find the part I would like to modify.
This is the code(Groovy):
for( int i = 0; i < dataContext.getDataCount(); i++ ) {
InputStream is = dataContext.getStream(i);
Properties props = dataContext.getProperties(i);
String searchString= "Hours worked";
String replacement = "Hours worked: 2";
File file = new File("\\\\****\\UKDC\\GFS\\PRE\\PREPROD\\Alchemer\\Template\\***.pdf");
PDDocument doc = PDDocument.load(file);
for ( PDPage page : doc.getPages() )
{
PDFStreamParser parser = new PDFStreamParser(page);
parser.parse();
List tokens = parser.getTokens();
logger.info("in Page");
for (int j = 0; j < tokens.size(); j++)
{
logger.info("tokens:"+tokens[j]);
Object next = tokens.get(j);
//logger.info("in Object");
if (next instanceof Operator)
{
Operator op = (Operator) next;
String pstring = "";
int prej = 0;
//Tj and TJ are the two operators that display strings in a PDF
if (op.getName().equals("Tj"))
{
logger.info("in Tj");
// Tj takes one operator and that is the string to display so lets update that operator
COSString previous = (COSString) tokens.get(j - 1);
String string = previous.getString();
logger.info("previousString:"+string);
string = string.replaceFirst(searchString, replacement);
previous.setValue(string.getBytes());
} else
if (op.getName().equals("TJ"))
{
logger.info("in TJ:"+ op.getName());
COSArray previous = (COSArray) tokens.get(j - 1);
logger.info("previous:"+previous);
for (int k = 0; k < previous.size(); k++)
{
Object arrElement = previous.getObject(k);
if (arrElement instanceof COSString)
{
COSString cosString = (COSString) arrElement;
String string = cosString.getString();
logger.info("string:"+string);
if (j == prej || string.equals(" ") || string.equals(":") || string.equals("-")) {
pstring += string;
} else {
prej = j;
pstring = string;
}
}
}
logger.info("pstring:"+pstring);
if (searchString.equals(pstring.trim()))
{
logger.info("in searchString");
COSString cosString2 = (COSString) previous.getObject(0);
cosString2.setValue(replacement.getBytes());
int total = previous.size()-1;
for (int k = total; k > 0; k--) {
previous.remove(k);
}
}
}
}
}
logger.info("in updatedStream");
// now that the tokens are updated we will replace the page content stream.
PDStream updatedStream = new PDStream(doc);
OutputStream out = updatedStream.createOutputStream(COSName.FLATE_DECODE);
ContentStreamWriter tokenWriter = new ContentStreamWriter(out);
tokenWriter.writeTokens(tokens);
logger.info("in tokenWriter");
out.close();
page.setContents(updatedStream);
doc.save("\\\\***\\UKDC\\GFS\\PRE\\PREPROD\\Alchemer\\***1.pdf");
}
Executing the code I am trying to search "Hours worked" String and update with
"Hours worked: 2"
There are 2 questions:
1.When I execute and check the logs can see the Tokens are not created properly:
enter image description here
enter image description here
So are created two different COSArrays meantime I have all in one Line:
enter image description here
and this can be a problem if I have to search a specific word.
When it find the word it seems it is working but it apply a strange char:
enter image description here
So Here 2 questions:
How to manage to specify the token behaviour (or maybe for the parser) to get an entire phrase in the same token until a special char happen?
Hot to format the new char in the new PDF?
Hope you can help me, thanks for your support.

How to parse subfolders for find specific files?

I Would like to create a script for photoshop who allow me to search some files with a specific name (for example : 300x250_F1.jpg, 300x250_F2.jpg, 300x600_F1.jpg, etc... ) in differents subfolders (all in the same parent folder) and after load them in my active document. The problem is names of subfolders will be everytime differents.
I definitely need some help :)
i found a code which almost do what i want (thank you).
I'm almost good but i have a problem: if the variable "mask" have only one value, it works. But with few values, it doesn't work anymore.
I think it's because i made an array with the mask variable and i have to update the script...
var topFolder = Folder.selectDialog("");
//var topFolder = new Folder('~/Desktop/PS_TEST');
var fileandfolderAr = scanSubFolders(topFolder, /\.(jpg)$/i);
//var fileandfolderAr = scanSubFolders(topFolder, /\.(jpg|tif|psd|bmp|gif|png|)$/i);
var fileList = fileandfolderAr[0];
var nom = decodeURI(fileList);
//all file paths found and amount of files found
//alert("fileList: " + nom + "\n\nFile Amount: " + fileList.length);
//alert(allFiles);
for (var a = 0; a < fileList.length; a++) {
var docRef = open(fileList[a]);
//do things here
}
function scanSubFolders(tFolder, mask) { // folder object, RegExp or string
var sFolders = [];
var allFiles = [];
var mask = ["300x250_F1", "300x250_F2"];
sFolders[0] = tFolder;
for (var j = 0; j < sFolders.length; j++) { // loop through folders
var procFiles = sFolders[j].getFiles();
for (var i = 0; i < procFiles.length; i++) { // loop through this folder contents
if (procFiles[i] instanceof File) {
if (mask == undefined) {
allFiles.push(procFiles); // if no search mask collect all files
}
if (procFiles[i].fullName.search(mask) != -1) {
allFiles.push(procFiles[i]); // otherwise only those that match mask
}
}
else if (procFiles[i] instanceof Folder) {
sFolders.push(procFiles[i]); // store the subfolder
scanSubFolders(procFiles[i], mask); // search the subfolder
}
}
}
return [allFiles, sFolders];
}
There are several ways you can accomplish this without reassigning mask within the scanSubFolders function.
Solution 1: use a regex
The function is already set up to accept a regex or string as a mask. You just need to use one that would match the pattern of the files you're targeting.
var fileandfolderAr = scanSubFolders(topFolder, /300x250_F(1|2)/gi);
Solution 2: call the function within a loop
If regex isn't your thing, you could still utilize an array of strings, but do it outside the function. Loop the array of masks and call the function with each one, then execute your primary logic on the results of each call.
var topFolder = Folder.selectDialog("");
var myMasks = ["300x250_F1", "300x250_F2"];
for (var index in myMasks) {
var mask = myMasks[index]
var fileandfolderAr = scanSubFolders(topFolder, mask);
var fileList = fileandfolderAr[0];
for (var a = 0; a < fileList.length; a++) {
var docRef = open(fileList[a]);
//do things here
}
}
Don't forget to remove var mask = ["300x250_F1", "300x250_F2"]; from within the scanSubFolders function or else these won't work.

Adobe InDesign script to affect only selected Table/Text Frame

I am new to scripting and copied this one below and it works great but not all tables are the same in the document and I just want to affect the selected tables/text frames.
Is there an easy way to make this code work the way I am looking to do.
var myDoc = app.activeDocument;
var myWidths = [.5,.35,.44,.44];
for(var T=0; T < myDoc.textFrames.length; T++){
for(var i=0; i < myDoc.textFrames[T].tables.length; i++){
for(var j=0; j < myWidths.length; j++){
myDoc.textFrames[T].tables[i].columns[j].width = myWidths[j];
}
}
}
Thanks for any help, just starting to dive into InDesign Scripting and understand it.
Yes, it can be done quite easy:
var myWidths = [.5,.35,.44,.44];
var sel = app.selection;
if (sel.length != 1) exit();
var frame = sel[0];
if (frame.constructor.name != 'TextFrame') exit();
for (var i = 0; i < frame.tables.length; i++) {
for (var j = 0; j < myWidths.length; j++) {
frame.tables[i].columns[j].width = myWidths[j];
}
}
It will work for one selected text frame.
If you need to process several selected frames here is another variant of the code:
var myWidths = [.5,.35,.44,.44];
var frames = app.selection
var f = frames.length
while(f--) {
if (frames[f].constructor.name != 'TextFrame') continue;
var tables = frames[f].tables;
var t = tables.length;
while(t--) {
var table = tables[t];
var c = table.columns.length;
while(c--) {
table.columns[c].width = myWidths[c];
}
}
}

realm react-native: how to query correctly an array of strings

can someone show me how to query an array of strings with realm in react-native?
assume i have an array like the following:
const preferences = ["automatic","suv","blue",eco]
What I want is to get realm results where ALL strings in the attribute "specifications" of Cars is in "preferences".
E.g.: If an instance of Cars.specifications contains ["automatic","suv"]
a result should be returned.
But if an instance of Cars.specifications contained ["automatic,"suv","green"] this instance shouldn't be returned.
The length of preferences can vary.
Thank you very much.
Update:
What i tried is the following:
const query = realm.objects("Cars").filtered('specifications = preferences[0] OR specifications = preferences[1]')
As you see it is an OR operator which is surely wrong and it is hardcoded. Looping with realm really confuses me.
This code will work!
const collection = realm.objects('Cars');
const preferences = ["automatic","suv","blue","eco"];
let queryString = 'ANY ';
for (let i = 0; i < preferences.length; i++) {
if (i === 0) {
queryString += `specifications CONTAINS '${preferences[i]}'`;
}
if (i !== 0 && i + 1 <= preferences.length) {
queryString += ` OR specifications CONTAINS '${preferences[i]}'`;
}
}
const matchedResult = collection.filtered(queryString);
example of function to test if a word is inside an array of word
function inArray(word, array) {
var lgth = array.length;
word = word.toLowerCase();
for (var i = 0; i < lgth; i++) {
array[i] = (array[i]).toLowerCase();
if (array[i] == word) return true;
}
return false;
}
const preferences = ["automatic","suv","blue","eco"];
const specifications = ["automatic","suv"] ;
const specifications2 = ["automatic","suv", "boat"] ;
function test(spec,pref){
for (var i in spec){
if(!inArray(spec[i],pref)){
return false ;
}
}
return true;
}
console.log(test(specifications,preferences));
console.log(test(specifications2,preferences));
https://jsfiddle.net/y1dz2gvu/

Make compound path in Adobe Illustrator by script

There are some compoundPathItems in myfile.ai
How can i run "Object > Compound Path > Make" or send "ctrl+8" from jsx? At line with comment ERROR HERE i get error message "A new object cannot be created at the specified location".
#target illustrator
if (app.documents.length > 0) {
var idoc = app.activeDocument;
var cp = idoc.compoundPathItems.add();
var allPaths = activeDocument.pathItems;
//Select objects
for(var i = 0;i < allPaths.length;i++){
allPaths[i].selected = true;
}
var selection = app.activeDocument.selection;
for (var i=0; i<selection.length; i++) {
selection[i].move (cp, ElementPlacement.PLACEATEND); // move selected path inside the compound path ERROR HERE
selection[i].evenodd = true; // necessary to determine "insideness" or to make holes.
}
alert(selection);
app.executeMenuCommand("compoundPath");