Regular Expressions in addon Script

This forum is for 'Work-in-Progress' QCAD user developed script Add Ons and Plug-ins.

Please use this forum to request/submit your script Add-Ons & Plug-in idea's.

Moderators: andrew, Husky, J-J

Post Reply
mshamrock53
Registered Member
Posts: 2
Joined: Mon Oct 23, 2023 2:16 am

Regular Expressions in addon Script

Post by mshamrock53 » Sun Apr 14, 2024 7:15 pm

All - I have become quite interested in writing small addon scripts to QCAD. Huge thanks to the moderators and regular contributors on here helping us new guys out. Hoping someone can help me figure out why the following script fails on this line:

const trimmedValues = values.map(value => value.trim().replace(/^"|"$/g, ''));

The debugger warning is "Uncaught exception at C:/Program Files/QCAD/scripts/Misc/drawTable\readTextFile.js:40: SyntaxError: Parse error" I have bascially individually tested all parts and they seem to run ok. Full disclosure that I am an engineer pretending to be a coder!

Code: Select all

include("scripts/EAction.js");
include("scripts/library.js");

var appWin = EAction.getMainWindow(); 

// A full path and complete filename with suffix. 
// IMPORTANT: script engine processes backslash "\" as an escape character so each  "\" must be doubled as shown below
// var fileName = "C:\\Users\\Michael\\Documents\\QCAD_Working\\drawTable.txt";     

function readTextFile(fileName) {
	
	var fi = new QFileInfo(fileName); 

	// When the file doesn't exist then issue a warning and return 'undefined':
	
	if (!fi.exists()) {                                          
    appWin.handleUserWarning("File does not exist");
    return undefined;
	}   

   var file = new QFile(fileName);
   var flags = makeQIODeviceOpenMode(QIODevice.ReadOnly, QIODevice.Text);
    if (file.open(flags)) {
        var textStream = new QTextStream(file);
        setUtf8Codec(textStream);
        
		var inputArray = []
		while (!textStream.atEnd())
		{
			var line = textStream.readLine();			
			qDebug(line)			
			function parseLine(colString) {
				// Split the string by "|"
				const values = colString.split('|');

				// Trim whitespace from each value and remove surrounding quotes if present
				const trimmedValues = values.map(value => value.trim().replace(/^"|"$/g, ''));
				return trimmedValues;
			}
			
			var lineArray = parseLine(line)			
			inputArray.push(lineArray)
        }
		file.close();
        return inputArray;
    }
    return undefined;
}

CVH
Premier Member
Posts: 3485
Joined: Wed Sep 27, 2017 4:17 pm

Re: Regular Expressions in addon Script

Post by CVH » Mon Apr 15, 2024 6:43 am

Hi, and welcome to the QCAD forum.

You didn't provide an example of the input so a few things are left for guessing. :wink:

As far I can check it, Array.map(...) is nowhere used and probably not supported by the ECMAScript implementation under QCAD.
Consider the ECMAScript engine as an early adoption without all the fancy enhancements that exist today. :wink:
Array.map(...) is an ECMAScript5 (ES5) feature.
You have to iterate through each array item from the splitted textline.
OR
Use Array.forEach(...) but even that hardly occurs in common QCAD scripts.

It is probable better (or required) to escape the quotation marks: xxx.replace(/^\"|\"$/g, "");

I would not define a local function for that, simply handle the split up syntax in direct.
Declaring constants with const is hardly used.

Some other remarks:
- When QCAD is running it is usually not required to include EAction or the library but it won't hurt.
- Don't mix single and double quotation marks.
As per each set it is not an error but in the long run you might mix up things and that will be an error.
I tend to use single quotation marks exclusively in textual remarks and double quotation marks in code like the majority in QCAD scripts.

- Simply use EAction.handleUserWarning("...") instead of appWin.handleUserWarning("...") (similar for ..UserMessage & ..UserInfo)
- End a line of instructions with a semicolon.
- Use proper code indentation, it is common in QCAD to used 4 spaces instead of a TAB.
For Windows I can recommend Notepad++ with its native JavaScript language renderer.
It has easy command buttons to replace TABs or for remove trailing spaces for example. I also use the EOL conversion.

- Your remark on paths in Windows style won't be an issue when the filename is sourced from a fileDialog.

Code: Select all

include("scripts/EAction.js");
include("scripts/library.js");

var appWin = EAction.getMainWindow();

// A full path and complete filename with suffix.
// IMPORTANT: script engine processes backslash "\" as an escape character so each  "\" must be doubled as shown below
// var fileName = "C:\\Users\\Michael\\Documents\\QCAD_Working\\drawTable.txt";

function readTextFile(fileName) {
    var file = new QFile(fileName);
    var flags = makeQIODeviceOpenMode(QIODevice.ReadOnly, QIODevice.Text);

    // When the file doesn't exist then issue a warning and return 'undefined':
    if (!file.open(flags)) {
        EAction.handleUserWarning("File does not exist");
        return undefined;
    }

    // Process an open file as stream:
    else {
        var textStream = new QTextStream(file);
        setUtf8Codec(textStream);

        var inputArray = [];
        while (!textStream.atEnd()) {
            var line = textStream.readLine();
            qDebug(line);

            // Skip empty lines:
            if (line.isEmpty()) {
                continue;
            }

            // Split the string up at "|":
            var lineArray = line.split("|");

            // Trim whitespace from each value and remove surrounding quotes if present:
            for (var i=0; i<lineArray.length; i++) {
                var value = lineArray[i].trim().replace(/^\"|\"$/g, "");
                lineArray[i] = value.trim();
            }

            // Collect textual line as an array:
            inputArray.push(lineArray);
        }
        file.close();
        return inputArray;
    }
};

If the intention is to draw a table with text and values then that can be done with DrawFromCSV.
See: Misc .. Import/Export .. Draw from CSV and the related files under that script folder:
https://github.com/qcad/qcad/blob/maste ... rawFromCSV
https://github.com/qcad/qcad/blob/maste ... SV_doc.pdf
Consider it as a macro parser that supports most common drawing objects and much more.
What can be achieved with that is only limited to your spreadsheet skills.
Drawing a table (furniture) is also possible. :wink:

Regards,
CVH

mshamrock53
Registered Member
Posts: 2
Joined: Mon Oct 23, 2023 2:16 am

Re: Regular Expressions in addon Script

Post by mshamrock53 » Sat Apr 20, 2024 8:12 pm

Many thanks CVH! The JS best practices are appreciated.

I did quite a bit of digging and couldn't find any sort of table generator so decided to make my own (a separate script I did not post to keep things simple). if only I had found your incredible csv addon and documentation first! That documentation should be an appendix to the user manual IMO.

Just for anyone reading this... the Array.map() does seem to be supported in QCAD scripts... but obviously I recommend following CVH's advice and not trying to get fancy.

My one question is why would I want to to escape the quotes?
It is probable better (or required) to escape the quotation marks: xxx.replace(/^\"|\"$/g, "");

CVH
Premier Member
Posts: 3485
Joined: Wed Sep 27, 2017 4:17 pm

Re: Regular Expressions in addon Script

Post by CVH » Sun Apr 21, 2024 6:51 am

mshamrock53 wrote:
Sat Apr 20, 2024 8:12 pm
Just for anyone reading this... the Array.map() does seem to be supported in QCAD scripts
Dug deeper and found one standard open source script that uses it: SvgImporter.js
(We can not actually search in PRO resources ...)
https://github.com/qcad/qcad/blob/maste ... er.js#L553
https://github.com/qcad/qcad/blob/maste ... er.js#L936

.map(...) is also a function of the QTransform Class.

I now think that it is the 'Arrow function' method that throws an error.
mshamrock53 wrote:
Sat Apr 20, 2024 8:12 pm
My one question is why would I want to to escape the quotes?
For no good reason except readability probably. :wink:
Not an expert in this matter.

I think it is required in new RegExp(...)
This pops up very often: new RegExp("[^<>/\\\\\":;\?\*|,=`]{1,255}")
Explained as not in the list of : <>/\":;?* and 1 to 255 characters long for Layer names, Block names, ...
https://help.autodesk.com/view/ACD/2015 ... 4E0E7DEA8E
The backslash and the double quotes seems to be escaped twice.
Digging further I stumbled on a few rare occurrences where the double quotes were escaped.
That is the sole reason for the careful notice "probable better" .. "or required"

Regards,
CVH

Post Reply

Return to “QCAD 'Script Add-On & Plug-in challenge' - Work in Progress”