hsbExport | hsbcad Model Data Formatting
This feature allows the properties of Entities, Projects and Groups to be formatted inside a string.
The feature was primarily developed to allow user defined names to be specified that included dynamic content from model data.
e.g. when defining folder names for CNC output the number or name of the project could be included. C:\MyCNCData\@(ProjectNumber)
How the format string is defined
The format string is made up of constant text and variables. The variables take the form:
@(<VariableName>)
The variable names directly relate to the property names of the classes so any string, number, enumeration or boolean property can be specified. If the variable name cannot be found it will not be resolved and will stay inside the format string unchanged.
e.g. for a Beam using a format string of "@(Length) x @(Width) x @(Height)" would use the Length, Width and Height properties of the beam.
There are also a set of variable names that provide special functionality.
Parent variable names
The following variables represent data for parent objects that can be accessed from their children.
e.g. including the element number a beam belongs to.
string beamDescription = beam.Format("@(Length) x @(Width) x @(Height) from @(ElementNumber)");
Multiwall Variable Name
A special variable name exists to list the single walls of a multiwall.
@(SingleWalls) or just @(SW) will list the names of the single walls.
@(ReverseSingleWalls) or just @(RSW) will list the names of the single walls in reverse order. This can be necessary where the orientation of the multiwall has changed.
An optional paramter can also be used to specify the delimiter.
@(SingleWalls:<delimiter>) where the can be one or more characters.
e.g. For a multiwall containing the walls FF1, FF2, FF3 and FF4 the following formats could be used:
@(SW) = FF1-FF2-FF3-FF4
@(SW:_) = FF1_FF2_FF3_FF4
@(SW:, ) = FF1, FF2, FF3, FF4
Formatting Functions
There are a number of functions that can be used to format string values.
E.g. To take the last two characters from the element number: @(ElementNumber:R2)
Possible functions are:
For example:
Given a group name of "House\Floor\Walls"
@(GroupName:L5) = "House"
@(GroupName:R5) = "Walls"
@(GroupName:S7) = "Floor\Walls"
@(GroupName:S7;5) = "Floor"
It is also possible to chain them together.
@(GroupName:S7:R5:U) = "WALLS"
@(GroupLevel3:PL7) = " Walls"
@(GroupLevel3:PR7;x) = "Wallsxxx"
@(GroupName:T1;\) = "Floor"
Or given a beam with a solid width of 29.499765 mm
@(SolidWidth:0) = “29”
@(SolidWidth:1) = “29.5”
@(SolidWidth:2) = “29.5”
Same could be done for a beam using: @(Solidheight) or @(SolidWidth)
D: default value if variable does not get resolved
If Information property is set to: Lion,Tiger,Frog
@(nokey) => @(nokey) // no default specified
@(nokey:D) => // empty default returns blank
@(nokey:D"bb") => bb // default value must be enclosed in double brackets
@(nokey:D;"cc") => cc // default value can also be second argument
@(nokey:D:PR4;A) => AAAA // After default substitution other commands can be applied
@(nokey:D"BB":PR4;A) => BBAA // After default substitution other commands can be applied
@(nokey:PR7;a:D:PR4;b) => bbbb // Commands before default are ignored in case of default
@(Information:T1;,:PL6;a:D:PR7;b) => aTigerb // Default is ignored if variable is resolved
As you know, @(nokey:D) => // empty default returns blank
@(key1:D)@(key2:D) would always take key1 and key2, but this ends up as an 'or' if only one is present.
T: Tokeniser
The T function has since V23.8.9 an additional option 3rd argument, which expresses the default in case the index is out of range.
T Tokenise to get the nth (n is 0 based index) part out of a separated list.
The first argument is the index. The second is an optional separator, which defaults to ;. The third optional argument, which default to an empty string, is the string which is returned in case the index is out of range.
If Information property is set to: Lion,Tiger, Elephant,Frog
@(Information:T0;,) => Lion // the first value with index 0
@(Information:T1;,) => Tiger // the second value with index 1
@(Information:T2;,) => Elephant // values are automatically trimmed
@(Information:T4;,) => // empty string, because index 4 (fifth value) is out of range
@(Information:T4;,;pink elephant) => pink elephant // index out of range will use the default
If the separator is ; you can omit it in the expression, so if Information is set to Lion;Tiger; Elephant;Frog
@(Information:T0) => Lion // the first value with index 0
@(Information:T1) => Tiger // the second value with index 1
@(Information:T2) => Elephant // values are automatically trimmed
@(Information:T4) => // empty string, because index 4 (fifth value) is out of range
@(Information:T4;;pink elephant) => pink elephant // index out of range will use the default
Separators for the tokenizer can be specified enclosed or not enclosed with double quotes.
Since the colon is already used in chaining the different commands, it always has to be enclosed in double quotes.
So if you want to use colon : as a separator you have to enclose it in double quotes as in the following example:
Given
label = "elephant:lion"
@(label:T1;":")
becomes "lion"
CU: Unit Conversion and Formatting
@(SolidLength:CU;mm) - change the value from drawing units to mm
@(SolidLength:CU;m) - change to m
@(SolidLength:CU;cm)
@(SolidLength:CU;in)
@(SolidLength:CU;ft)
@(Volume:CU;m) => change value to cubic meters
@(Len:DN3) => force decimal notation, rounding to 3
@(Len:AN3) => force architectural notation, rounding to 1/8
@(Len:CU;mm:DN3) => convert to mm, decimal notation
@(SolidLength:AN3) - formatted to 1/8 inch
@(SolidLength:AN4) - formatted to 1/16 inch
@(SolidLength:AN5) - formatted to 1/32 inch
Aliases
Aliases allow values to be replaced with another value, an alias.
The aliases are stored in files inside the company folder.
e.g. TestAliases.dat.
An alias is made up of:
- Expression – what is being mapped to. This can contain the wild card character '*' to represent zero or more characters.
- Text – the value being returned if the expression is matched.
e.g.
Expression = "*ground*"
Text = "GF"
This would match the following "House\Ground Floor\Walls" and "GF" would be the result.
The is implemented inside the formatting as an Alias string function.
e.g. Assuming the global aliases are being used:
@(GroupName:A) would look for an alias of the group name.
To use a custom alias file a parameter is specified.
e.g. using the custom "Test" alias (file name is TestAliases.dat)
@(GroupName:A;Test)
For more information see our article about Aliases. Alias Manager
MapX and PropertySets
Propertysets are groups of Properties that are added to objects.
MapX is a map (like a set of properties) that is available in the exporter.
MapX and PropretySet data can be accessed by simply specifying the path to data in the underlying map starting with the MapX key or PropertySet name.
The MapX data will take precendence over the PropertySet data.
e.g. An entitty has MapX data with a key of "Hsb_ElementInfo" which contains a value "Weight".
This could be accessed using the format:
@(Hsb_ElementInfo.Weight)
The path for MapX data can go as deep as necessary.
e.g. @(Key.SubMap1.SubMap2.SubMap3.ValueKey).
Drawing Properties
The Drawing Properties are specified as:
@(DrawingProperties.Title)
@(DrawingProperties.Author)
@(DrawingProperties.Subject)
@(DrawingProperties.KeyWords)
@(DrawingProperties.Comments)
@(DrawingProperties.LastSavedBy)
@(DrawingProperties.RevisionNumber)
@(DrawingProperties.HyperLink)
Custom properties are access the same way:
@(DrawingProperties.<CustomPropertyName>)
e.g. @(DrawingProperties.HOI)
Standard names will always take precedence over customer ones, and the names are not case sensitive.
RX: Regex RX;”expression” or RXn;”expression” or RXn;”expression”;”result”
Learning regex you could use: https://qntm.org/files/re/re.html.
As a regex reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference
Some of us use a tool called expresso when validating regex expressions: http://www.ultrapico.com/Expresso.htm.
Find a match using a regex expression. By default the matching expression is returned. Since in an input string multiple matches might be found, the n-th match can be returned by specifying a first argument. By default the first match is returned. When the result string is added as third argument, the match is used to build the result string. In this case regex indexed groups and named groups can be used.
The regex expression as well as the result are encapsulated in double quotes “. The consequence of that is when you want to use double quotes inside them, you have to escape it. The escape character is back slash \. So besides the other special regex characters that need escaping, the double quote needs it too.
If Information property is set to: Lion,Tiger,Frog
The following regex will return the following result:
@(Information:RX;"[^,]+") => Lion
@(Information:RX0;"[^,]+") => Lion
@(Information:RX1;"\\w+") => Tiger
@(Information:RX2;"\\w+") => Frog
@(Information:RX3;"\\w+") =>
For an Information property: Lion,Tiger():"Elephant";Frog
The following regex will return the following result:
@(Information:RX;"[^,]+") => Lion
@(Information:RX;"\\w+") => Lion
@(Information:RX0;"\\w+") => Lion
@(Information:RX1;"\\w+") => Tiger
@(Information:RX;"[^,]*") => Lion // @(Animals:RX"[^,]*")
@(Information:RX;"[^)]*") => Lion,Tiger( // ) chars inside regex string are allowed
@(Information:RX;"[^:]*") => Lion,Tiger() // : chars inside regex string are allowed
@(Information:RX;"[^\\]*"") => Lion
RR: Regex Replace RR;”expression”;”substitute” or RRn;”expression”;” substitute”
For regex see: https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference or https://qntm.org/files/re/re.html.
Find and replace all regex matches. The string with the substituted matches is returned. Since in an input string multiple matches might be found, the first n-th matches will be substituted by specifying a first argument. By default all matches are replaced. The substitute string can contain regex indexed groups and named groups.
The regex expression as well as the substitute are encapsulated in double quotes “. The consequence of that is when you want to use double quotes inside them, you have to escape it. The escape character is back slash \. So besides the other special regex characters that need escaping, the double quote needs it too.
With the Information property set to: Lion,Tiger,Frog
the following regex replace will return the following result:
@(Information:RR;”[^,]+”;”pussy”) => pussy,pussy,pussy
@(Information:RR0;”[^,]+”;”pussy”) => Lion,Tiger,Frog
@(Information:RR1;”\\w+“;”pussy”) => pussy,Tiger,Frog
@(Information:RR2;”\\w+“;”pussy”) => pussy,pussy,Frog
@(Information:RR3;”\\w+“;”pussy”) => pussy,pussy,pussy
@(Information:RR4;”\\w+“;”pussy”) => pussy,pussy,pussy
@(Information:RR4;”\\w+“;””) => ,, // replace with nothing
With the Information property set to: a lion, a tiger, a frog
the following regex replace will return the following result:
@(Information:RR;”\\s*\\w+\\s*([^,]+)“;”$1”) => lion,tiger,frog // can use group by one based index
@(Information:RR;”\\s*\\w+\\s*(?<key>[^,]+)“;”${key}”) => lion,tiger,frog // can use named group
@(Information:RR1;”\\s*\\w+\\s*[^,]+“;”\\””) => \\”, a tiger, a frog // can substitute into”