expressir 2.1.30 → 2.1.31

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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +98 -0
  3. data/.github/workflows/links.yml +100 -0
  4. data/.github/workflows/rake.yml +4 -0
  5. data/.github/workflows/release.yml +5 -0
  6. data/.github/workflows/validate_schemas.yml +1 -1
  7. data/.gitignore +3 -0
  8. data/.rubocop.yml +1 -1
  9. data/.rubocop_todo.yml +244 -39
  10. data/Gemfile +2 -1
  11. data/README.adoc +621 -54
  12. data/docs/Gemfile +12 -0
  13. data/docs/_config.yml +141 -0
  14. data/docs/_guides/changes/changes-format.adoc +778 -0
  15. data/docs/_guides/changes/importing-eengine.adoc +898 -0
  16. data/docs/_guides/changes/index.adoc +396 -0
  17. data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
  18. data/docs/_guides/changes/validating-changes.adoc +681 -0
  19. data/docs/_guides/cli/benchmark-performance.adoc +834 -0
  20. data/docs/_guides/cli/coverage-analysis.adoc +921 -0
  21. data/docs/_guides/cli/format-schemas.adoc +547 -0
  22. data/docs/_guides/cli/index.adoc +8 -0
  23. data/docs/_guides/cli/managing-changes.adoc +927 -0
  24. data/docs/_guides/cli/validate-ascii.adoc +645 -0
  25. data/docs/_guides/cli/validate-schemas.adoc +534 -0
  26. data/docs/_guides/index.adoc +165 -0
  27. data/docs/_guides/ler/creating-packages.adoc +664 -0
  28. data/docs/_guides/ler/index.adoc +305 -0
  29. data/docs/_guides/ler/loading-packages.adoc +707 -0
  30. data/docs/_guides/ler/package-formats.adoc +748 -0
  31. data/docs/_guides/ler/querying-packages.adoc +826 -0
  32. data/docs/_guides/ler/validating-packages.adoc +750 -0
  33. data/docs/_guides/liquid/basic-templates.adoc +813 -0
  34. data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
  35. data/docs/_guides/liquid/drops-reference.adoc +829 -0
  36. data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
  37. data/docs/_guides/liquid/index.adoc +468 -0
  38. data/docs/_guides/manifests/creating-manifests.adoc +483 -0
  39. data/docs/_guides/manifests/index.adoc +307 -0
  40. data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
  41. data/docs/_guides/manifests/validating-manifests.adoc +713 -0
  42. data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
  43. data/docs/_guides/ruby-api/index.adoc +257 -0
  44. data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
  45. data/docs/_guides/ruby-api/search-engine.adoc +609 -0
  46. data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
  47. data/docs/_pages/data-model.adoc +665 -0
  48. data/docs/_pages/express-language.adoc +506 -0
  49. data/docs/_pages/getting-started.adoc +414 -0
  50. data/docs/_pages/index.adoc +116 -0
  51. data/docs/_pages/introduction.adoc +256 -0
  52. data/docs/_pages/ler-packages.adoc +837 -0
  53. data/docs/_pages/parsers.adoc +683 -0
  54. data/docs/_pages/schema-manifests.adoc +431 -0
  55. data/docs/_references/index.adoc +228 -0
  56. data/docs/_tutorials/creating-ler-package.adoc +735 -0
  57. data/docs/_tutorials/documentation-coverage.adoc +795 -0
  58. data/docs/_tutorials/index.adoc +221 -0
  59. data/docs/_tutorials/liquid-templates.adoc +806 -0
  60. data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
  61. data/docs/_tutorials/querying-schemas.adoc +751 -0
  62. data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
  63. data/docs/index.adoc +242 -0
  64. data/docs/lychee.toml +84 -0
  65. data/examples/demo_ler_usage.sh +86 -0
  66. data/examples/ler/README.md +111 -0
  67. data/examples/ler/simple_example.ler +0 -0
  68. data/examples/ler/simple_schema.exp +33 -0
  69. data/examples/ler_build.rb +75 -0
  70. data/examples/ler_cli.rb +79 -0
  71. data/examples/ler_demo_complete.rb +276 -0
  72. data/examples/ler_query.rb +91 -0
  73. data/examples/ler_query_examples.rb +305 -0
  74. data/examples/ler_stats.rb +81 -0
  75. data/examples/phase3_demo.rb +159 -0
  76. data/examples/query_demo_simple.rb +131 -0
  77. data/expressir.gemspec +2 -0
  78. data/lib/expressir/cli.rb +12 -4
  79. data/lib/expressir/commands/manifest.rb +427 -0
  80. data/lib/expressir/commands/package.rb +1274 -0
  81. data/lib/expressir/commands/validate.rb +70 -37
  82. data/lib/expressir/commands/validate_ascii.rb +607 -0
  83. data/lib/expressir/commands/validate_load.rb +88 -0
  84. data/lib/expressir/express/formatter.rb +5 -1
  85. data/lib/expressir/express/formatters/remark_item_formatter.rb +25 -0
  86. data/lib/expressir/express/parser.rb +33 -0
  87. data/lib/expressir/manifest/resolver.rb +213 -0
  88. data/lib/expressir/manifest/validator.rb +195 -0
  89. data/lib/expressir/model/declarations/entity.rb +6 -0
  90. data/lib/expressir/model/dependency_resolver.rb +270 -0
  91. data/lib/expressir/model/indexes/entity_index.rb +103 -0
  92. data/lib/expressir/model/indexes/reference_index.rb +148 -0
  93. data/lib/expressir/model/indexes/type_index.rb +149 -0
  94. data/lib/expressir/model/interface_validator.rb +384 -0
  95. data/lib/expressir/model/repository.rb +400 -5
  96. data/lib/expressir/model/repository_validator.rb +295 -0
  97. data/lib/expressir/model/search_engine.rb +525 -0
  98. data/lib/expressir/model.rb +4 -94
  99. data/lib/expressir/package/builder.rb +200 -0
  100. data/lib/expressir/package/metadata.rb +81 -0
  101. data/lib/expressir/package/reader.rb +165 -0
  102. data/lib/expressir/schema_manifest.rb +11 -1
  103. data/lib/expressir/version.rb +1 -1
  104. data/lib/expressir.rb +15 -2
  105. metadata +114 -4
  106. data/docs/benchmarking.adoc +0 -107
  107. data/docs/liquid_drops.adoc +0 -1547
@@ -0,0 +1,468 @@
1
+ ---
2
+ title: Liquid
3
+ has_children: true
4
+ nav_order: 6
5
+ ---
6
+
7
+ = Liquid integration with Expressir
8
+
9
+ == Purpose
10
+
11
+ This guide explains how Expressir integrates with the Liquid template
12
+ language to enable flexible, automated documentation generation from
13
+ EXPRESS schemas. Liquid templates provide a powerful way to transform
14
+ EXPRESS data models into human-readable documentation in any format.
15
+
16
+ == References
17
+
18
+ * link:../../tutorials/liquid-templates.html[Liquid Templates Tutorial]
19
+ - Step-by-step introduction
20
+ * link:../ruby-api/[Ruby API Guides] - Programming interface
21
+ * https://shopify.github.io/liquid/[Liquid Documentation] - Official
22
+ Liquid language reference
23
+
24
+ == Concepts
25
+
26
+ Liquid:: A safe, customer-facing template language created by Shopify
27
+ for generating dynamic content from data.
28
+
29
+ Drop:: A Ruby object wrapper that makes Expressir model data accessible
30
+ in Liquid templates with a simplified, template-friendly interface.
31
+
32
+ Template:: A text file containing Liquid markup that defines how to
33
+ transform data into output.
34
+
35
+ Filter:: A Liquid function that transforms values (e.g., `upcase`,
36
+ `join`, `map`).
37
+
38
+ Tag:: A Liquid control structure for logic and flow control (e.g.,
39
+ `if`, `for`, `assign`).
40
+
41
+ == What is Liquid?
42
+
43
+ Liquid is a template language that allows you to generate dynamic
44
+ content from structured data. Originally created by Shopify, it provides:
45
+
46
+ * **Safe execution**: Templates cannot execute arbitrary code
47
+ * **Simple syntax**: Easy to learn and read
48
+ * **Flexible output**: Generate HTML, Markdown, plain text, or any
49
+ format
50
+ * **Powerful features**: Loops, conditionals, filters, and more
51
+ * **Data binding**: Access object attributes naturally
52
+
53
+ .Simple Liquid example
54
+ [example]
55
+ ====
56
+ [source,liquid]
57
+ ----
58
+ Hello {{ user.name }}!
59
+
60
+ {% if user.premium %}
61
+ Thank you for your premium membership.
62
+ {% endif %}
63
+
64
+ Your items:
65
+ {% for item in user.items %}
66
+ - {{ item.name }}: ${{ item.price }}
67
+ {% endfor %}
68
+ ----
69
+ ====
70
+
71
+ == Why use Liquid with Expressir?
72
+
73
+ Expressir + Liquid enables powerful documentation workflows:
74
+
75
+ **Automated documentation**::
76
+ Generate complete schema documentation automatically from EXPRESS
77
+ source files without manual maintenance.
78
+
79
+ **Consistent formatting**::
80
+ Apply uniform styling and structure across all schema documentation.
81
+
82
+ **Multiple output formats**::
83
+ Create HTML, Markdown, LaTeX, or custom formats from the same source
84
+ data.
85
+
86
+ **Customizable templates**::
87
+ Adapt documentation style to your organization's standards and
88
+ requirements.
89
+
90
+ **Maintainable**::
91
+ Update templates independently of schema changes; regenerate
92
+ documentation when schemas evolve.
93
+
94
+ **Version control friendly**::
95
+ Store templates in version control; track documentation changes
96
+ alongside code.
97
+
98
+ == How Expressir integrates with Liquid
99
+
100
+ Expressir provides seamless Liquid integration through the "drops"
101
+ pattern:
102
+
103
+ [source]
104
+ ----
105
+ EXPRESS Schema → Expressir Parser → Ruby Data Model →
106
+ Liquid Drop → Template → Documentation Output
107
+ ----
108
+
109
+ === The drops pattern
110
+
111
+ Expressir models implement a `to_liquid` method that converts them to
112
+ "drop" objects specifically designed for template use:
113
+
114
+ [source,ruby]
115
+ ----
116
+ # Parse EXPRESS schema
117
+ repository = Expressir::Express::Parser.from_file("schema.exp")
118
+
119
+ # Convert to Liquid drop
120
+ repo_drop = repository.to_liquid
121
+
122
+ # Use in template
123
+ template = Liquid::Template.parse("{{ repository.schemas.size }} schemas")
124
+ output = template.render("repository" => repo_drop)
125
+ ----
126
+
127
+ Every Expressir model class has a corresponding drop:
128
+
129
+ * `Repository` → `RepositoryDrop`
130
+ * `Schema` → `SchemaDrop`
131
+ * `Entity` → `EntityDrop`
132
+ * `Type` → `TypeDrop`
133
+ * `Attribute` → `AttributeDrop`
134
+ * And more...
135
+
136
+ Drops provide:
137
+
138
+ * Simplified attribute access for templates
139
+ * Consistent interface across all model types
140
+ * Safe data exposure (no internal implementation details)
141
+ * Natural navigation through model relationships
142
+
143
+ == Quick start
144
+
145
+ This example demonstrates the basic workflow from EXPRESS to
146
+ documentation:
147
+
148
+ .Create sample schema (example.exp)
149
+ [source,express]
150
+ ----
151
+ SCHEMA example_schema;
152
+
153
+ ENTITY person;
154
+ name : STRING;
155
+ age : INTEGER;
156
+ END_ENTITY;
157
+
158
+ ENTITY company;
159
+ company_name : STRING;
160
+ employees : SET [0:?] OF person;
161
+ END_ENTITY;
162
+
163
+ END_SCHEMA;
164
+ ----
165
+
166
+ .Create template (template.liquid)
167
+ [source,liquid]
168
+ ----
169
+ # {{ schema.id }}
170
+
171
+ ## Entities
172
+
173
+ {% for entity in schema.entities %}
174
+ ### {{ entity.id }}
175
+
176
+ Attributes:
177
+ {% for attr in entity.attributes %}
178
+ - **{{ attr.id }}**: {{ attr.type }}
179
+ {% endfor %}
180
+ {% endfor %}
181
+ ----
182
+
183
+ .Generate documentation (generate.rb)
184
+ [source,ruby]
185
+ ----
186
+ require "expressir"
187
+ require "liquid"
188
+
189
+ # Parse schema
190
+ repo = Expressir::Express::Parser.from_file("example.exp")
191
+ schema_drop = repo.schemas.first.to_liquid
192
+
193
+ # Load and render template
194
+ template = Liquid::Template.parse(File.read("template.liquid"))
195
+ output = template.render("schema" => schema_drop)
196
+
197
+ # Output result
198
+ puts output
199
+ ----
200
+
201
+ .Run the generator
202
+ [source,bash]
203
+ ----
204
+ ruby generate.rb
205
+ ----
206
+
207
+ .Output (example_schema.md)
208
+ [source,markdown]
209
+ ----
210
+ # example_schema
211
+
212
+ ## Entities
213
+
214
+ ### person
215
+
216
+ Attributes:
217
+ - **name**: STRING
218
+ - **age**: INTEGER
219
+
220
+ ### company
221
+
222
+ Attributes:
223
+ - **company_name**: STRING
224
+ - **employees**: SET [0:?] OF person
225
+ ----
226
+
227
+ == Key features
228
+
229
+ === Template-friendly data access
230
+
231
+ Access model attributes naturally in templates:
232
+
233
+ [source,liquid]
234
+ ----
235
+ {{ repository.schemas.size }}
236
+ {{ schema.id }}
237
+ {{ entity.attributes.first.id }}
238
+ {{ entity.attributes | map: "id" | join: ", " }}
239
+ ----
240
+
241
+ === Nested navigation
242
+
243
+ Navigate relationships easily:
244
+
245
+ [source,liquid]
246
+ ----
247
+ {% for schema in repository.schemas %}
248
+ {% for entity in schema.entities %}
249
+ {% for attr in entity.attributes %}
250
+ {{ schema.id }}.{{ entity.id }}.{{ attr.id }}
251
+ {% endfor %}
252
+ {% endfor %}
253
+ {% endfor %}
254
+ ----
255
+
256
+ === Built-in filters
257
+
258
+ Use Liquid's powerful filters:
259
+
260
+ [source,liquid]
261
+ ----
262
+ {{ entity.id | upcase }}
263
+ {{ schema.entities | size }}
264
+ {{ entity.attributes | map: "id" | join: ", " }}
265
+ {{ description | truncate: 100 }}
266
+ ----
267
+
268
+ === Control flow
269
+
270
+ Apply logic in templates:
271
+
272
+ [source,liquid]
273
+ ----
274
+ {% if entity.abstract %}
275
+ Abstract entity
276
+ {% endif %}
277
+
278
+ {% for attr in entity.attributes %}
279
+ {% if attr.optional %}
280
+ Optional: {{ attr.id }}
281
+ {% endif %}
282
+ {% endfor %}
283
+ ----
284
+
285
+ == When to use Liquid templates
286
+
287
+ Liquid templates are ideal for:
288
+
289
+ **Documentation generation**::
290
+ * Schema overviews
291
+ * Entity reference pages
292
+ * Type catalogs
293
+ * Function documentation
294
+
295
+ **Report creation**::
296
+ * Coverage reports
297
+ * Change summaries
298
+ * Dependency analysis
299
+ * Statistics dashboards
300
+
301
+ **Code generation**::
302
+ * Stub implementations
303
+ * Test fixtures
304
+ * Configuration files
305
+ * API wrappers
306
+
307
+ **Data transformation**::
308
+ * Format conversion
309
+ * Structure flattening
310
+ * Cross-references
311
+ * Index generation
312
+
313
+ == When NOT to use Liquid templates
314
+
315
+ Consider alternatives when:
316
+
317
+ **Complex business logic**::
318
+ If you need complex calculations, validations, or algorithms, use Ruby
319
+ directly instead of cramming logic into templates.
320
+
321
+ **Performance critical**::
322
+ For processing thousands of schemas or generating large outputs,
323
+ consider direct Ruby code or compiled templates.
324
+
325
+ **Interactive applications**::
326
+ Liquid is for batch generation. For interactive tools, use Rails views
327
+ or other web frameworks.
328
+
329
+ **Simple formatting**::
330
+ For basic pretty-printing, use
331
+ link:../ruby-api/formatting-schemas.html[Expressir's built-in
332
+ formatter].
333
+
334
+ == Architecture
335
+
336
+ The Expressir Liquid integration consists of several layers:
337
+
338
+ [source]
339
+ ----
340
+ ┌─────────────────────────────────────────────────────────────┐
341
+ │ Template Layer │
342
+ │ (Liquid templates, filters, tags, includes) │
343
+ └─────────────────────┬───────────────────────────────────────┘
344
+
345
+
346
+ ┌─────────────────────────────────────────────────────────────┐
347
+ │ Drop Layer │
348
+ │ (RepositoryDrop, SchemaDrop, EntityDrop, etc.) │
349
+ └─────────────────────┬───────────────────────────────────────┘
350
+
351
+
352
+ ┌─────────────────────────────────────────────────────────────┐
353
+ │ Model Layer │
354
+ │ (Repository, Schema, Entity, Type, Attribute, etc.) │
355
+ └─────────────────────┬───────────────────────────────────────┘
356
+
357
+
358
+ ┌─────────────────────────────────────────────────────────────┐
359
+ │ Parser Layer │
360
+ │ (EXPRESS Parser, Cache, References) │
361
+ └─────────────────────────────────────────────────────────────┘
362
+ ----
363
+
364
+ Each layer has a specific responsibility:
365
+
366
+ **Template Layer**::
367
+ User-facing templates that define output structure and format.
368
+
369
+ **Drop Layer**::
370
+ Adapters that expose model data to templates safely and conveniently.
371
+
372
+ **Model Layer**::
373
+ Rich Ruby objects representing EXPRESS constructs with full
374
+ capabilities.
375
+
376
+ **Parser Layer**::
377
+ Converts EXPRESS text files into model objects.
378
+
379
+ == Common patterns
380
+
381
+ === Single file documentation
382
+
383
+ Generate one document per schema:
384
+
385
+ [source,ruby]
386
+ ----
387
+ schemas.each do |schema|
388
+ drop = schema.to_liquid
389
+ output = template.render("schema" => drop)
390
+ File.write("#{schema.id}.md", output)
391
+ end
392
+ ----
393
+
394
+ === Multi-file documentation
395
+
396
+ Generate multiple files from one schema:
397
+
398
+ [source,ruby]
399
+ ----
400
+ schema.entities.each do |entity|
401
+ drop = entity.to_liquid
402
+ output = template.render("entity" => drop)
403
+ File.write("entities/#{entity.id}.md", output)
404
+ end
405
+ ----
406
+
407
+ === Index generation
408
+
409
+ Create navigation and table of contents:
410
+
411
+ [source,liquid]
412
+ ----
413
+ # Schema Index
414
+
415
+ {% for schema in repository.schemas %}
416
+ - [{{ schema.id }}]({{ schema.id }}.md)
417
+ ({{ schema.entities.size }} entities)
418
+ {% endfor %}
419
+ ----
420
+
421
+ === Conditional rendering
422
+
423
+ Show different content based on data:
424
+
425
+ [source,liquid]
426
+ ----
427
+ {% if entity.abstract %}
428
+ **Abstract Entity** - Cannot be instantiated
429
+ {% endif %}
430
+
431
+ {% if entity.attributes.size > 0 %}
432
+ ## Attributes
433
+ ...
434
+ {% else %}
435
+ No attributes defined.
436
+ {% endif %}
437
+ ----
438
+
439
+ == Next steps
440
+
441
+ Continue learning about Liquid integration:
442
+
443
+ * link:basic-templates.html[Basic Templates] - Template syntax and
444
+ structure
445
+ * link:drops-reference.html[Drops Reference] - Complete drop API
446
+ * link:filters-and-tags.html[Filters and Tags] - Available operations
447
+ * link:documentation-generation.html[Documentation Generation] -
448
+ Complete workflows
449
+
450
+ **Practice examples**:
451
+
452
+ * link:../../tutorials/liquid-templates.html[Liquid Templates
453
+ Tutorial] - Hands-on exercises
454
+ * Browse example templates in the Expressir repository
455
+
456
+ == Summary
457
+
458
+ Liquid integration with Expressir provides:
459
+
460
+ * ✅ Safe, flexible template language for documentation generation
461
+ * ✅ Natural data access through drop objects
462
+ * ✅ Support for any output format (HTML, Markdown, etc.)
463
+ * ✅ Powerful built-in filters and control structures
464
+ * ✅ Maintainable, version-controlled template system
465
+ * ✅ Separation of content (data) from presentation (templates)
466
+
467
+ Liquid templates transform EXPRESS schemas into professional
468
+ documentation automatically, consistently, and maintainably.