expressir 2.3.6 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +1 -1
- data/.gitignore +2 -0
- data/.rubocop_todo.yml +17 -12
- data/CHANGELOG.md +159 -0
- data/docs/_guides/ler/step-packages.adoc +385 -0
- data/lib/expressir/coverage.rb +4 -4
- data/lib/expressir/express/builder_registry.rb +3 -1
- data/lib/expressir/express/builders/expression_builder.rb +2 -2
- data/lib/expressir/express/builders/helpers.rb +2 -8
- data/lib/expressir/express/builders/qualifier_builder.rb +2 -1
- data/lib/expressir/express/formatter.rb +32 -164
- data/lib/expressir/express/formatters/data_types_formatter.rb +39 -6
- data/lib/expressir/express/formatters/declarations_formatter.rb +47 -8
- data/lib/expressir/express/formatters/expressions_formatter.rb +20 -5
- data/lib/expressir/express/formatters/literals_formatter.rb +11 -1
- data/lib/expressir/express/formatters/references_formatter.rb +10 -1
- data/lib/expressir/express/formatters/remark_formatter.rb +1 -89
- data/lib/expressir/express/formatters/remark_item_formatter.rb +5 -4
- data/lib/expressir/express/formatters/statements_formatter.rb +32 -9
- data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +7 -3
- data/lib/expressir/express/hyperlink_formatter.rb +1 -3
- data/lib/expressir/express/model_visitor.rb +1 -1
- data/lib/expressir/express/pretty_formatter.rb +31 -108
- data/lib/expressir/express/remark_attacher.rb +118 -88
- data/lib/expressir/express/schema_head_formatter.rb +1 -3
- data/lib/expressir/model/concerns.rb +6 -0
- data/lib/expressir/model/declarations/interface_item.rb +2 -0
- data/lib/expressir/model/declarations/interfaced_item.rb +3 -0
- data/lib/expressir/model/declarations/remark_item.rb +3 -0
- data/lib/expressir/model/declarations/schema.rb +7 -5
- data/lib/expressir/model/exp_file.rb +1 -0
- data/lib/expressir/model/identifier.rb +3 -1
- data/lib/expressir/model/model_element.rb +3 -3
- data/lib/expressir/model/repository.rb +8 -0
- data/lib/expressir/model/search_engine.rb +1 -1
- data/lib/expressir/package/reader.rb +9 -24
- data/lib/expressir/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ecbd13317e56cc0139eb317331134c80ba9f5ae95eaf221f2f5e2046ebe95387
|
|
4
|
+
data.tar.gz: 86dbdfe6818f5c751d11c6fc4cd81e53a60b38145d3f7d80f5bd1b5ff6869815
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b3b26b8456c55b2a5b342d508a2af8f1e3c46ed23f78b96b5900a036292533c33b68f140248f6c8b552f5ed571adc245fe71acf1159b21feca3aa6c0b7bb354f
|
|
7
|
+
data.tar.gz: 3d33e2d5c850898a8b451a91cd76a9a85736b7e4c6d846c29e1652dc5e8fbb080bec35b2c55a908c7da68bdb32c5b7940162ea88cd811a519643a5f97db65fcf
|
data/.github/workflows/rake.yml
CHANGED
data/.gitignore
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-05
|
|
3
|
+
# on 2026-06-05 10:03:10 UTC using RuboCop version 1.86.0.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
9
|
+
# Offense count: 1072
|
|
10
10
|
# This cop supports safe autocorrection (--autocorrect).
|
|
11
11
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
12
12
|
# URISchemes: http, https
|
|
@@ -24,11 +24,10 @@ Lint/DuplicateBranch:
|
|
|
24
24
|
- 'lib/expressir/express/remark_attacher.rb'
|
|
25
25
|
- 'lib/expressir/model/search_engine.rb'
|
|
26
26
|
|
|
27
|
-
# Offense count:
|
|
27
|
+
# Offense count: 1
|
|
28
28
|
Lint/DuplicateCaseCondition:
|
|
29
29
|
Exclude:
|
|
30
30
|
- 'lib/expressir/commands/package.rb'
|
|
31
|
-
- 'lib/expressir/express/formatter.rb'
|
|
32
31
|
|
|
33
32
|
# Offense count: 1
|
|
34
33
|
Lint/DuplicateMethods:
|
|
@@ -51,7 +50,12 @@ Lint/UnusedMethodArgument:
|
|
|
51
50
|
- 'lib/expressir/express/cache.rb'
|
|
52
51
|
- 'lib/expressir/express/parser.rb'
|
|
53
52
|
|
|
54
|
-
# Offense count:
|
|
53
|
+
# Offense count: 2
|
|
54
|
+
Lint/UselessConstantScoping:
|
|
55
|
+
Exclude:
|
|
56
|
+
- 'lib/expressir/express/remark_attacher.rb'
|
|
57
|
+
|
|
58
|
+
# Offense count: 240
|
|
55
59
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
56
60
|
Metrics/AbcSize:
|
|
57
61
|
Enabled: false
|
|
@@ -67,12 +71,12 @@ Metrics/BlockLength:
|
|
|
67
71
|
Metrics/BlockNesting:
|
|
68
72
|
Max: 6
|
|
69
73
|
|
|
70
|
-
# Offense count:
|
|
74
|
+
# Offense count: 190
|
|
71
75
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
72
76
|
Metrics/CyclomaticComplexity:
|
|
73
77
|
Enabled: false
|
|
74
78
|
|
|
75
|
-
# Offense count:
|
|
79
|
+
# Offense count: 290
|
|
76
80
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
77
81
|
Metrics/MethodLength:
|
|
78
82
|
Max: 167
|
|
@@ -82,7 +86,7 @@ Metrics/MethodLength:
|
|
|
82
86
|
Metrics/ParameterLists:
|
|
83
87
|
Max: 8
|
|
84
88
|
|
|
85
|
-
# Offense count:
|
|
89
|
+
# Offense count: 162
|
|
86
90
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
87
91
|
Metrics/PerceivedComplexity:
|
|
88
92
|
Enabled: false
|
|
@@ -151,7 +155,7 @@ RSpec/ContextWording:
|
|
|
151
155
|
- 'spec/expressir/commands/validate_ascii_spec.rb'
|
|
152
156
|
- 'spec/expressir/model/repository_spec.rb'
|
|
153
157
|
|
|
154
|
-
# Offense count:
|
|
158
|
+
# Offense count: 2
|
|
155
159
|
# Configuration parameters: IgnoredMetadata.
|
|
156
160
|
RSpec/DescribeClass:
|
|
157
161
|
Exclude:
|
|
@@ -160,6 +164,7 @@ RSpec/DescribeClass:
|
|
|
160
164
|
- '**/spec/routing/**/*'
|
|
161
165
|
- '**/spec/system/**/*'
|
|
162
166
|
- '**/spec/views/**/*'
|
|
167
|
+
- 'spec/expressir/express/formatter_architecture_spec.rb'
|
|
163
168
|
- 'spec/expressir/integration/package_roundtrip_spec.rb'
|
|
164
169
|
|
|
165
170
|
# Offense count: 6
|
|
@@ -172,7 +177,7 @@ RSpec/DescribeMethod:
|
|
|
172
177
|
- 'spec/expressir/model/repository_statistics_spec.rb'
|
|
173
178
|
- 'spec/expressir/model/search_engine_advanced_spec.rb'
|
|
174
179
|
|
|
175
|
-
# Offense count:
|
|
180
|
+
# Offense count: 480
|
|
176
181
|
# Configuration parameters: CountAsOne.
|
|
177
182
|
RSpec/ExampleLength:
|
|
178
183
|
Max: 122
|
|
@@ -213,7 +218,7 @@ RSpec/IteratedExpectation:
|
|
|
213
218
|
RSpec/MessageSpies:
|
|
214
219
|
EnforcedStyle: receive
|
|
215
220
|
|
|
216
|
-
# Offense count:
|
|
221
|
+
# Offense count: 596
|
|
217
222
|
RSpec/MultipleExpectations:
|
|
218
223
|
Max: 114
|
|
219
224
|
|
|
@@ -253,7 +258,7 @@ RSpec/SpecFilePathFormat:
|
|
|
253
258
|
- 'spec/expressir/model/repository_statistics_spec.rb'
|
|
254
259
|
- 'spec/expressir/model/search_engine_advanced_spec.rb'
|
|
255
260
|
|
|
256
|
-
# Offense count:
|
|
261
|
+
# Offense count: 2
|
|
257
262
|
Security/MarshalLoad:
|
|
258
263
|
Exclude:
|
|
259
264
|
- 'lib/expressir/package/reader.rb'
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Breaking Changes
|
|
11
|
+
|
|
12
|
+
#### Repository Structure Change
|
|
13
|
+
|
|
14
|
+
The `Repository` class now uses a `files` attribute containing `ExpFile` objects instead of a direct `schemas` attribute.
|
|
15
|
+
|
|
16
|
+
**Old structure:**
|
|
17
|
+
```ruby
|
|
18
|
+
repository = Expressir::Model::Repository.new
|
|
19
|
+
repository.schemas << schema1
|
|
20
|
+
repository.schemas << schema2
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**New structure:**
|
|
24
|
+
```ruby
|
|
25
|
+
repository = Expressir::Model::Repository.new
|
|
26
|
+
repository.add_schema(schema1)
|
|
27
|
+
repository.add_schema(schema2)
|
|
28
|
+
|
|
29
|
+
# Or with files:
|
|
30
|
+
exp_file = Expressir::Express::Parser.from_file("schema.exp")
|
|
31
|
+
repository.files << exp_file
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
#### ExpFile Model Introduced
|
|
35
|
+
|
|
36
|
+
A new `ExpFile` class represents a single EXPRESS file with its own preamble remarks and schemas:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
# ExpFile has:
|
|
40
|
+
# - path: the file path
|
|
41
|
+
# - schemas: array of schemas in the file
|
|
42
|
+
# - untagged_remarks: file-level preamble remarks
|
|
43
|
+
|
|
44
|
+
exp_file = Expressir::Model::ExpFile.new(path: "my_schema.exp")
|
|
45
|
+
exp_file.schemas = [schema]
|
|
46
|
+
exp_file.untagged_remarks = [remark_info]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
#### Parser Return Type Changed
|
|
50
|
+
|
|
51
|
+
`Expressir::Express::Parser.from_file` now returns an `ExpFile` instead of a `Repository`:
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
# Old: returned Repository
|
|
55
|
+
# New: returns ExpFile
|
|
56
|
+
exp_file = Expressir::Express::Parser.from_file("schema.exp")
|
|
57
|
+
exp_file.path # => "schema.exp"
|
|
58
|
+
exp_file.schemas # => [#<Expressir::Model::Declarations::Schema...>]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### Error Class Changes
|
|
62
|
+
|
|
63
|
+
- `InvalidSchemaManifestError` → Use `ManifestValidationError` instead
|
|
64
|
+
- `Expressir::Express::CacheVersionMismatchError` → Use `Expressir::Express::Error::CacheVersionMismatchError`
|
|
65
|
+
|
|
66
|
+
#### RemarkInfo Required
|
|
67
|
+
|
|
68
|
+
Remark formatters now require `RemarkInfo` objects instead of strings:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
# Old:
|
|
72
|
+
formatter.format_preamble_remark("This is a remark")
|
|
73
|
+
|
|
74
|
+
# New:
|
|
75
|
+
remark = Expressir::Model::RemarkInfo.new(text: "This is a remark")
|
|
76
|
+
formatter.format_preamble_remark(remark)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- `Expressir::Model::ExpFile` class for representing EXPRESS files
|
|
82
|
+
- `Expressir::Model::Concerns` module with marker modules for O(1) type checking:
|
|
83
|
+
- `HasRemarkItems` - types that can have remark_items children
|
|
84
|
+
- `ScopeContainer` - types that can contain declarations
|
|
85
|
+
- `HasInformalPropositions` - types supporting informal propositions
|
|
86
|
+
- `HasWhereRules` - types supporting where rules
|
|
87
|
+
- `Repository#add_schema(schema)` method for adding schemas
|
|
88
|
+
- `Repository#files` attribute for storing ExpFile objects
|
|
89
|
+
- `Package::Builder#normalize_repository` ensures proper serialization format
|
|
90
|
+
|
|
91
|
+
### Changed
|
|
92
|
+
|
|
93
|
+
- `Repository#schemas` now returns schemas from both `files` and internal storage
|
|
94
|
+
- `Parser.from_file` returns `ExpFile` instead of `Repository`
|
|
95
|
+
- `Parser.from_files` creates `Repository` with `ExpFile` objects
|
|
96
|
+
- `Parser.from_exp` returns `ExpFile` instead of `Repository`
|
|
97
|
+
- `format_repository` in formatters handles both file-based and direct schemas
|
|
98
|
+
- Preamble remarks now attach to `ExpFile` instead of first `Schema`
|
|
99
|
+
|
|
100
|
+
### Removed
|
|
101
|
+
|
|
102
|
+
- All backward compatibility code for legacy serialized data
|
|
103
|
+
- `Repository#schemas=` writer (use `add_schema` instead)
|
|
104
|
+
- Legacy string handling in remark formatters
|
|
105
|
+
- `InvalidSchemaManifestError` alias (use `ManifestValidationError`)
|
|
106
|
+
- Legacy `@schemas` attribute migration in Repository
|
|
107
|
+
- Array-based type checking in `remark_attacher.rb` (replaced with module markers)
|
|
108
|
+
|
|
109
|
+
### Migration Guide
|
|
110
|
+
|
|
111
|
+
#### Updating Code That Uses Repository
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
# Before:
|
|
115
|
+
repo = Expressir::Model::Repository.new
|
|
116
|
+
repo.schemas << schema
|
|
117
|
+
|
|
118
|
+
# After:
|
|
119
|
+
repo = Expressir::Model::Repository.new
|
|
120
|
+
repo.add_schema(schema)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Updating Code That Parses Files
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
# Before:
|
|
127
|
+
repo = Expressir::Express::Parser.from_file("schema.exp")
|
|
128
|
+
schema = repo.schemas.first
|
|
129
|
+
|
|
130
|
+
# After:
|
|
131
|
+
exp_file = Expressir::Express::Parser.from_file("schema.exp")
|
|
132
|
+
schema = exp_file.schemas.first
|
|
133
|
+
|
|
134
|
+
# Or wrap in repository:
|
|
135
|
+
repo = Expressir::Model::Repository.new
|
|
136
|
+
repo.files << Expressir::Express::Parser.from_file("schema.exp")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### Updating Serialized Packages
|
|
140
|
+
|
|
141
|
+
Old `.ler` packages need to be regenerated with the new format:
|
|
142
|
+
|
|
143
|
+
```ruby
|
|
144
|
+
# Load old package (will fail with new code)
|
|
145
|
+
# repo = Expressir::Model::Repository.from_package("old.ler")
|
|
146
|
+
|
|
147
|
+
# Regenerate by parsing original EXPRESS files
|
|
148
|
+
exp_file = Expressir::Express::Parser.from_file("schema.exp")
|
|
149
|
+
repo = Expressir::Model::Repository.new
|
|
150
|
+
repo.files << exp_file
|
|
151
|
+
repo.export_to_package("new.ler", name: "My Package", version: "1.0.0")
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## [2.2.1] - 2024-03-14
|
|
155
|
+
|
|
156
|
+
### Changed
|
|
157
|
+
|
|
158
|
+
- Refactored `require` to `autoload` pattern for better load performance
|
|
159
|
+
- Updated error handling to use error classes instead of `abort`
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: STEP Standard Packages
|
|
3
|
+
parent: LER Packages
|
|
4
|
+
grand_parent: Guides
|
|
5
|
+
nav_order: 7
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= STEP Standard Packages (SRL, SML, SMRL)
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
This guide explains how to create and use LER packages from STEP standard
|
|
13
|
+
schema collections: the STEPmod Resource Library (SRL), STEPmod Module Library
|
|
14
|
+
(SML), and the combined STEP Resource and Module Library (SMRL).
|
|
15
|
+
|
|
16
|
+
== References
|
|
17
|
+
|
|
18
|
+
* link:creating-packages.html[Creating Packages]
|
|
19
|
+
* link:loading-packages.html[Loading Packages]
|
|
20
|
+
* link:querying-packages.html[Querying Packages]
|
|
21
|
+
|
|
22
|
+
== Concepts
|
|
23
|
+
|
|
24
|
+
SRL (STEPmod Resource Library):: The collection of 133 resource schemas that
|
|
25
|
+
define core EXPRESS types, entities, and functions used across STEP application
|
|
26
|
+
protocols. Located in `schemas/resources/` of the STEPmod distribution.
|
|
27
|
+
|
|
28
|
+
SML (STEP Module Library):: The collection of application modules (643 modules,
|
|
29
|
+
1205 ARM and MIM schemas) that define modular data models. Located in
|
|
30
|
+
`schemas/modules/` of the STEPmod distribution.
|
|
31
|
+
|
|
32
|
+
SMRL (STEP Resource and Module Library):: The combined set of all SRL resource
|
|
33
|
+
schemas and SML module schemas (1341 total).
|
|
34
|
+
|
|
35
|
+
STEPmod:: The ISO 10303 standards maintenance and development toolkit that
|
|
36
|
+
contains the source EXPRESS schemas for STEP.
|
|
37
|
+
|
|
38
|
+
== Prerequisites
|
|
39
|
+
|
|
40
|
+
You need a local copy of the STEPmod distribution (ISO 10303 repository). The
|
|
41
|
+
schema directory structure looks like:
|
|
42
|
+
|
|
43
|
+
[source]
|
|
44
|
+
----
|
|
45
|
+
iso-10303/
|
|
46
|
+
├── schemas/
|
|
47
|
+
│ ├── resources/ # SRL: 133 resource schemas
|
|
48
|
+
│ │ ├── action_schema/
|
|
49
|
+
│ │ │ └── action_schema.exp
|
|
50
|
+
│ │ ├── geometry_schema/
|
|
51
|
+
│ │ │ └── geometry_schema.exp
|
|
52
|
+
│ │ └── ...
|
|
53
|
+
│ └── modules/ # SML: 643 modules, 1205 schemas
|
|
54
|
+
│ ├── colour/
|
|
55
|
+
│ │ ├── arm.exp
|
|
56
|
+
│ │ └── mim.exp
|
|
57
|
+
│ ├── geometry/
|
|
58
|
+
│ │ ├── arm.exp
|
|
59
|
+
│ │ └── mim.exp
|
|
60
|
+
│ └── ...
|
|
61
|
+
└── ...
|
|
62
|
+
----
|
|
63
|
+
|
|
64
|
+
== Creating an SRL package
|
|
65
|
+
|
|
66
|
+
The SRL contains resource schemas that provide common definitions reused across
|
|
67
|
+
STEP application protocols.
|
|
68
|
+
|
|
69
|
+
=== Using the Ruby API
|
|
70
|
+
|
|
71
|
+
[source,ruby]
|
|
72
|
+
----
|
|
73
|
+
require "expressir"
|
|
74
|
+
|
|
75
|
+
base_dir = "/path/to/iso-10303"
|
|
76
|
+
resource_files = Dir.glob("#{base_dir}/schemas/resources/**/*.exp").sort
|
|
77
|
+
|
|
78
|
+
puts "Building SRL from #{resource_files.length} resource schemas..."
|
|
79
|
+
|
|
80
|
+
# Parse all resource schemas
|
|
81
|
+
repo = Expressir::Express::Parser.from_files(resource_files)
|
|
82
|
+
|
|
83
|
+
puts "Parsed #{repo.schemas.length} schemas"
|
|
84
|
+
|
|
85
|
+
# Export as LER package
|
|
86
|
+
repo.export_to_package(
|
|
87
|
+
"srl.ler",
|
|
88
|
+
name: "SRL",
|
|
89
|
+
description: "STEPmod Resource Library - ISO 10303 resource schemas",
|
|
90
|
+
serialization_format: "marshal"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
puts "Created srl.ler"
|
|
94
|
+
----
|
|
95
|
+
|
|
96
|
+
=== Performance characteristics
|
|
97
|
+
|
|
98
|
+
[example]
|
|
99
|
+
====
|
|
100
|
+
* 133 resource schemas
|
|
101
|
+
* Parse time: ~10 seconds
|
|
102
|
+
* Package size: ~5 MB
|
|
103
|
+
====
|
|
104
|
+
|
|
105
|
+
== Creating an SML package
|
|
106
|
+
|
|
107
|
+
The SML contains application modules, each with ARM (Application Reference
|
|
108
|
+
Model) and MIM (Mapped Information Model) schemas.
|
|
109
|
+
|
|
110
|
+
=== Using the Ruby API
|
|
111
|
+
|
|
112
|
+
[source,ruby]
|
|
113
|
+
----
|
|
114
|
+
require "expressir"
|
|
115
|
+
|
|
116
|
+
base_dir = "/path/to/iso-10303"
|
|
117
|
+
module_files = Dir.glob("#{base_dir}/schemas/modules/**/{arm,mim}.exp").sort
|
|
118
|
+
|
|
119
|
+
puts "Building SML from #{module_files.length} module schemas..."
|
|
120
|
+
|
|
121
|
+
# Parse all module schemas
|
|
122
|
+
repo = Expressir::Express::Parser.from_files(module_files)
|
|
123
|
+
|
|
124
|
+
puts "Parsed #{repo.schemas.length} schemas"
|
|
125
|
+
|
|
126
|
+
# Export as LER package
|
|
127
|
+
repo.export_to_package(
|
|
128
|
+
"sml.ler",
|
|
129
|
+
name: "SML",
|
|
130
|
+
description: "STEP Module Library - ISO 10303 application modules",
|
|
131
|
+
serialization_format: "marshal"
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
puts "Created sml.ler"
|
|
135
|
+
----
|
|
136
|
+
|
|
137
|
+
=== Performance characteristics
|
|
138
|
+
|
|
139
|
+
[example]
|
|
140
|
+
====
|
|
141
|
+
* 1205 module schemas (643 modules)
|
|
142
|
+
* Parse time: ~3 minutes
|
|
143
|
+
* Package size: ~14 MB
|
|
144
|
+
====
|
|
145
|
+
|
|
146
|
+
== Creating an SMRL package
|
|
147
|
+
|
|
148
|
+
The SMRL combines all resource and module schemas into a single package.
|
|
149
|
+
|
|
150
|
+
=== Using the Ruby API
|
|
151
|
+
|
|
152
|
+
[source,ruby]
|
|
153
|
+
----
|
|
154
|
+
require "expressir"
|
|
155
|
+
|
|
156
|
+
base_dir = "/path/to/iso-10303"
|
|
157
|
+
resource_files = Dir.glob("#{base_dir}/schemas/resources/**/*.exp").sort
|
|
158
|
+
module_files = Dir.glob("#{base_dir}/schemas/modules/**/{arm,mim}.exp").sort
|
|
159
|
+
all_files = resource_files + module_files
|
|
160
|
+
|
|
161
|
+
puts "Building SMRL from #{all_files.length} schemas..."
|
|
162
|
+
|
|
163
|
+
# Parse all schemas
|
|
164
|
+
repo = Expressir::Express::Parser.from_files(all_files)
|
|
165
|
+
|
|
166
|
+
puts "Parsed #{repo.schemas.length} schemas"
|
|
167
|
+
|
|
168
|
+
# Export as LER package
|
|
169
|
+
repo.export_to_package(
|
|
170
|
+
"smrl.ler",
|
|
171
|
+
name: "SMRL",
|
|
172
|
+
description: "STEP Resource and Module Library - Complete ISO 10303 schemas",
|
|
173
|
+
serialization_format: "marshal"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
puts "Created smrl.ler"
|
|
177
|
+
----
|
|
178
|
+
|
|
179
|
+
=== Performance characteristics
|
|
180
|
+
|
|
181
|
+
[example]
|
|
182
|
+
====
|
|
183
|
+
* 1341 schemas (133 resources + 1205 modules)
|
|
184
|
+
* Parse time: ~8 minutes
|
|
185
|
+
* Package size: ~24 MB
|
|
186
|
+
====
|
|
187
|
+
|
|
188
|
+
== Loading and searching packages
|
|
189
|
+
|
|
190
|
+
All three package types use the same loading and querying API.
|
|
191
|
+
|
|
192
|
+
=== Loading a package
|
|
193
|
+
|
|
194
|
+
[source,ruby]
|
|
195
|
+
----
|
|
196
|
+
require "expressir"
|
|
197
|
+
|
|
198
|
+
# Load any .ler package
|
|
199
|
+
repo = Expressir::Model::Repository.from_package("smrl.ler")
|
|
200
|
+
puts "Loaded #{repo.schemas.length} schemas"
|
|
201
|
+
----
|
|
202
|
+
|
|
203
|
+
Load times are fast regardless of package size:
|
|
204
|
+
|
|
205
|
+
[example]
|
|
206
|
+
====
|
|
207
|
+
* SRL (133 schemas): ~1 second
|
|
208
|
+
* SML (1205 schemas): ~3 seconds
|
|
209
|
+
* SMRL (1340 schemas): ~5 seconds
|
|
210
|
+
====
|
|
211
|
+
|
|
212
|
+
=== Finding entities by qualified name
|
|
213
|
+
|
|
214
|
+
Use `find_entity` for instant lookups when you know the schema and entity name:
|
|
215
|
+
|
|
216
|
+
[source,ruby]
|
|
217
|
+
----
|
|
218
|
+
entity = repo.find_entity(qualified_name: "geometry_schema.axis2_placement_3d")
|
|
219
|
+
if entity
|
|
220
|
+
puts "Found: #{entity.id}"
|
|
221
|
+
puts "Schema: #{entity.parent.id}"
|
|
222
|
+
end
|
|
223
|
+
----
|
|
224
|
+
|
|
225
|
+
=== Listing all entities
|
|
226
|
+
|
|
227
|
+
[source,ruby]
|
|
228
|
+
----
|
|
229
|
+
entities = repo.list_entities
|
|
230
|
+
puts "Total: #{entities.length} entities"
|
|
231
|
+
|
|
232
|
+
entities.first(5).each do |e|
|
|
233
|
+
puts " #{e.parent.id}.#{e.id}"
|
|
234
|
+
end
|
|
235
|
+
----
|
|
236
|
+
|
|
237
|
+
=== Listing entities from a specific schema
|
|
238
|
+
|
|
239
|
+
[source,ruby]
|
|
240
|
+
----
|
|
241
|
+
entities = repo.list_entities(schema: "mathematical_functions_schema")
|
|
242
|
+
puts "Entities in mathematical_functions_schema: #{entities.length}"
|
|
243
|
+
----
|
|
244
|
+
|
|
245
|
+
=== Listing all types
|
|
246
|
+
|
|
247
|
+
[source,ruby]
|
|
248
|
+
----
|
|
249
|
+
types = repo.list_types
|
|
250
|
+
puts "Total: #{types.length} types"
|
|
251
|
+
----
|
|
252
|
+
|
|
253
|
+
=== Finding a specific schema
|
|
254
|
+
|
|
255
|
+
[source,ruby]
|
|
256
|
+
----
|
|
257
|
+
schema = repo.schemas.find { |s| s.id == "mathematical_functions_schema" }
|
|
258
|
+
if schema
|
|
259
|
+
puts "Entities: #{schema.entities&.length || 0}"
|
|
260
|
+
puts "Types: #{schema.types&.length || 0}"
|
|
261
|
+
puts "Functions: #{schema.functions&.length || 0}"
|
|
262
|
+
end
|
|
263
|
+
----
|
|
264
|
+
|
|
265
|
+
=== Using SearchEngine for pattern matching
|
|
266
|
+
|
|
267
|
+
[source,ruby]
|
|
268
|
+
----
|
|
269
|
+
require "expressir"
|
|
270
|
+
|
|
271
|
+
repo = Expressir::Model::Repository.from_package("smrl.ler")
|
|
272
|
+
engine = Expressir::Model::SearchEngine.new(repo)
|
|
273
|
+
|
|
274
|
+
# Find all entities containing "product"
|
|
275
|
+
results = engine.search(pattern: "product", type: "entity")
|
|
276
|
+
results.each do |r|
|
|
277
|
+
puts "#{r[:schema]}.#{r[:id]}"
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Find all SELECT types
|
|
281
|
+
select_types = engine.list(type: "type", category: "select")
|
|
282
|
+
puts "SELECT types: #{select_types.length}"
|
|
283
|
+
|
|
284
|
+
# Wildcard search for geometry-related entities
|
|
285
|
+
results = engine.search(pattern: "geometry*")
|
|
286
|
+
----
|
|
287
|
+
|
|
288
|
+
== Complete build script
|
|
289
|
+
|
|
290
|
+
Here is a complete script for building all three STEP packages:
|
|
291
|
+
|
|
292
|
+
[source,ruby]
|
|
293
|
+
----
|
|
294
|
+
#!/usr/bin/env ruby
|
|
295
|
+
# build_step_packages.rb
|
|
296
|
+
|
|
297
|
+
require "expressir"
|
|
298
|
+
require "optparse"
|
|
299
|
+
|
|
300
|
+
options = {
|
|
301
|
+
stepmod_dir: nil,
|
|
302
|
+
output_dir: ".",
|
|
303
|
+
packages: ["srl", "sml", "smrl"]
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
OptionParser.new do |opts|
|
|
307
|
+
opts.banner = "Usage: build_step_packages.rb [options]"
|
|
308
|
+
|
|
309
|
+
opts.on("--stepmod DIR", "Path to iso-10303 directory") do |v|
|
|
310
|
+
options[:stepmod_dir] = v
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
opts.on("--output DIR", "Output directory (default: .)") do |v|
|
|
314
|
+
options[:output_dir] = v
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
opts.on("--packages LIST", "Comma-separated list: srl,sml,smrl") do |v|
|
|
318
|
+
options[:packages] = v.split(",")
|
|
319
|
+
end
|
|
320
|
+
end.parse!
|
|
321
|
+
|
|
322
|
+
abort("--stepmod is required") unless options[:stepmod_dir]
|
|
323
|
+
|
|
324
|
+
base_dir = options[:stepmod_dir]
|
|
325
|
+
|
|
326
|
+
if options[:packages].include?("srl")
|
|
327
|
+
puts "=== Building SRL ==="
|
|
328
|
+
files = Dir.glob("#{base_dir}/schemas/resources/**/*.exp").sort
|
|
329
|
+
repo = Expressir::Express::Parser.from_files(files)
|
|
330
|
+
output = File.join(options[:output_dir], "srl.ler")
|
|
331
|
+
repo.export_to_package(output,
|
|
332
|
+
name: "SRL",
|
|
333
|
+
description: "STEPmod Resource Library",
|
|
334
|
+
serialization_format: "marshal")
|
|
335
|
+
puts "Created #{output} (#{repo.schemas.length} schemas)"
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
if options[:packages].include?("sml")
|
|
339
|
+
puts "\n=== Building SML ==="
|
|
340
|
+
files = Dir.glob("#{base_dir}/schemas/modules/**/{arm,mim}.exp").sort
|
|
341
|
+
repo = Expressir::Express::Parser.from_files(files)
|
|
342
|
+
output = File.join(options[:output_dir], "sml.ler")
|
|
343
|
+
repo.export_to_package(output,
|
|
344
|
+
name: "SML",
|
|
345
|
+
description: "STEP Module Library",
|
|
346
|
+
serialization_format: "marshal")
|
|
347
|
+
puts "Created #{output} (#{repo.schemas.length} schemas)"
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
if options[:packages].include?("smrl")
|
|
351
|
+
puts "\n=== Building SMRL ==="
|
|
352
|
+
resource_files = Dir.glob("#{base_dir}/schemas/resources/**/*.exp").sort
|
|
353
|
+
module_files = Dir.glob("#{base_dir}/schemas/modules/**/{arm,mim}.exp").sort
|
|
354
|
+
repo = Expressir::Express::Parser.from_files(resource_files + module_files)
|
|
355
|
+
output = File.join(options[:output_dir], "smrl.ler")
|
|
356
|
+
repo.export_to_package(output,
|
|
357
|
+
name: "SMRL",
|
|
358
|
+
description: "STEP Resource and Module Library",
|
|
359
|
+
serialization_format: "marshal")
|
|
360
|
+
puts "Created #{output} (#{repo.schemas.length} schemas)"
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
puts "\nDone!"
|
|
364
|
+
----
|
|
365
|
+
|
|
366
|
+
Usage:
|
|
367
|
+
|
|
368
|
+
[source,bash]
|
|
369
|
+
----
|
|
370
|
+
ruby build_step_packages.rb \
|
|
371
|
+
--stepmod /path/to/iso-10303 \
|
|
372
|
+
--output ./packages \
|
|
373
|
+
--packages srl,sml,smrl
|
|
374
|
+
----
|
|
375
|
+
|
|
376
|
+
== Summary
|
|
377
|
+
|
|
378
|
+
* Use `Dir.glob` to collect all EXPRESS files for SRL, SML, or SMRL
|
|
379
|
+
* `Expressir::Express::Parser.from_files` parses all files into a single
|
|
380
|
+
repository
|
|
381
|
+
* `repo.export_to_package` creates a `.ler` package with pre-built indexes
|
|
382
|
+
* `Repository.from_package` loads packages in seconds
|
|
383
|
+
* `find_entity(qualified_name:)` provides instant lookups
|
|
384
|
+
* `list_entities` and `list_types` enumerate all items
|
|
385
|
+
* `SearchEngine` supports pattern matching and filtering
|