Instructions
Please follow these instructions as close as you can, but remember: "A Foolish Consistency is the Hobgoblin of Little Minds"[2][3]. In other words, if any of these rules cause your code to be less readable/maintainable you should not follow the rule in that particular circumstance. The goal is always readability and maintainability. At the very least, please pick a style and stick to it.
White space
Probably the most important factor for readable code is the right amount of spacing in the right places. In OpenSCAD, as in many other programming languages, white space (empty lines, spaces, and tabs) is ignored, which gives us the freedom to arrange the code in a readable, maintainable fashion.
Indentation
In virtually all languages the suggestion (if not the rule, as in Python) is that whenever you begin some kind of code block (conditional, loop, module) your code should indent (with tabs or spaces) one level beyond the current indentation level. Ex:
for(z = [-5, 5]) { // place the opening curly brace on the same line
translate([0, 0, z]) {
if(z < 0) {
cube(size = 0.5, center = false);
}
else if(z > 0) {
cube(size=0.25, center = false);
}
else {
cube(size=0.35, center = false);
}
} // lines up with the block opener
} // For long code blocks use a reminder comment here (e.g. // for(z))
The placement of curly braces should following Compact Control Readability Style[4]. This makes the code fairly compact while making it easy to scan the left edge of the code for lined up control statements like if/else. Blocks should use open/close curly braces in all cases (even single-line blocks) to prevent mistakes.
In OpenSCAD the indentation should always be done with tabs, not spaces, since the OpenSCAD editor indent shortcut uses tabs. It is, however appropriate (and encouraged) to use spaces to align constants and operators as in these examples:
vector_of_vectors = [[0, 0, 0],
[1, 0, 1],
[0, 1, 0]];
polygon(
points = [[0, 0],
[1, 0], // One tab, followed by spaces for alignment
[1, 1], // Ditto
[0, 1]],
paths = [[0, 1, 2, 3]] // Align the = operator
);
Something to note here is that spacing for alignment will only work with a mono font, therefore it is recommended to choose a mono font in OpenSCAD's preferences.
One unique rule should be made for OpenSCAD regarding indenting code blocks. Since transformations and assignments often come in groups (e.g. assign(...) scale(...) rotate(...) translate(...) {...}), one need not add indentation for each member of the group. It is much cleaner/readable in this case to think of the entire group as the block opener and line them up at the same indentation level. Ex.:
assign(x = 5)
scale([1, 1, 0.5])
rotate([180, 0, 0])
translate([5, 5, 0])
if(y == 0) {
cube([1, 2, 3]);
}
This should be done with assign, scale, rotate, translate, difference, union, and color but other block statements should only be used if they are the last item in the group. The first items in the group should always be "assign" statements if they exist.
Spaces
Spaces are nice to provide some separation between elements in code, but it is important not to go overboard. Spaces after commas (,) makes it easy to read through list items, spaces around colons (:) makes it easier to read ranges, and spaces around operators (=, +, -, *, /, %, , =, ==, !=, !, &&, ||) makes it easier to read statements in general. A solitary "!" should always have a space on both sides to make sure it is clearly visible. A "-" should always be surrounded by spaces except when it is acting as a unary operator (negating an expression). There is no need for spaces before or after parentheses (()) or brackets ([]), but a space before an opening curly brace ({) is helpful.
Comments
All files should begin with a comment block (/*...*/) describing the thing, followed by a Thingdoc[5] block that provides a more formal definition of the thing. A /*...*/ comment block before each module describing the input parameters is also useful. An example:
/**
* Draws an awesome object!
*
* @param int width The width of the awesome object, defaults to 5
*/
module awesome_object(width = 5) {
.
.
.
}
If you are tempted to comment out code, first see if you can accomplish what you are attempting using conditional statements or modules and leaving all code uncommented. For example, this:
// Uncomment the following line for an example usage!
//my_awesome_thing(10, 5);
could be changed to this:
module my_awesome_thing_demo(param1, param2) {
my_awesome_thing(param1, param2);
}
For complex blocks of code, it can be helpful to include comments to describe the purpose of a particular line. If these comments are short they can be placed at the end of the line, following a // comment opener, otherwise they should be placed on one or more new lines above the referenced code (making sure to indent/align to the level of the referenced code before starting the comment).
Line Length
It's hard to provide a solid rule for line length since (as of this writing) OpenSCAD does not display line/column information. General guidelines can still be established, however. One should always try to avoid wrapped lines, because they make code much less readable. Of course, the width of the editor is different for everyone so just set your editor width to a reasonable size of the OpenSCAD window (around 50%) and see what wraps. You can fix these lines in the following ways:
1. Modularize code. If it makes sense in your situation, you can move code from the offending line into a module or function to shorten the line.
2. Split the line. Split the line into as many lines as needed where they will all fit on one line. Split after commas and operators and use a combination of tabs and spaces to line up with the previous line.
Naming Convention
Variable naming in OpenSCAD should follow the underscore_naming convention to match the naming scheme used for OpenSCAD's built-in modules. In other words, variables should be all lower-case with underscores to separate words. Try and keep variable names short, unique, and meaningful.
General Guidelines
Modularization
Generally speaking, a module should not be over one page long. If you have a module this long, see if you can break out some of the code into separate modules to reduce the length of the module. You may be surprised to find that some of this code is reusable. Even if the code is used only once, taking this action can still improve readability.
[1] openscad.org/
[2] python.org/dev/peps/pep-0008/
[3] bartleby.com/100/420.47.html
[4] en.wikipedia.org/wiki/Indent_style#Compact_Control_Readability_style
[5] github.com/prusajr/ThingDoc/wiki/Syntax




