ea 0.4.0 → 0.5.1
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/CHANGELOG.md +128 -1
- data/Rakefile +3 -0
- data/TODO.complete/01-t-xref-parsing.md +91 -0
- data/TODO.complete/02-per-label-geometry.md +50 -0
- data/TODO.complete/03-object-properties-constraints.md +57 -0
- data/TODO.complete/04-operation-params.md +37 -0
- data/TODO.complete/05-pdata-flag-matrix.md +52 -0
- data/TODO.complete/06-emf-image-rendering.md +34 -0
- data/TODO.complete/07-auxiliary-tables.md +47 -0
- data/TODO.complete/10-mdg-stereotype-registry.md +40 -0
- data/TODO.complete/11-gml-xsd-generation.md +42 -0
- data/TODO.complete/13-shapescript-interpreter.md +28 -0
- data/TODO.complete/20-cli-diff.md +46 -0
- data/TODO.complete/21-cli-render.md +26 -0
- data/TODO.complete/22-cli-export.md +29 -0
- data/TODO.complete/23-cli-mdg.md +23 -0
- data/TODO.complete/30-headerlines-ocp-refactor.md +72 -0
- data/TODO.complete/31-public-send-cleanup.md +61 -0
- data/TODO.complete/32-spec-coverage.md +33 -0
- data/TODO.complete/33-blocked-parity-gaps.md +41 -0
- data/TODO.complete/36-stereotype-icon-wiring.md +32 -0
- data/TODO.complete/37-cli-lint.md +32 -0
- data/TODO.complete/38-cli-query.md +26 -0
- data/TODO.complete/39-cli-info.md +23 -0
- data/TODO.complete/40-ocl-evaluator.md +31 -0
- data/TODO.complete/41-round-trip-spec.md +18 -0
- data/TODO.complete/42-html-diff-report.md +18 -0
- data/TODO.complete/43-json-schema-export.md +20 -0
- data/TODO.complete/44-remaining-qea-tables.md +40 -0
- data/TODO.complete/45-shapescript-extensions.md +25 -0
- data/TODO.complete/46-xsd-consolidation.md +20 -0
- data/TODO.complete/47-headerlines-legacy-removal.md +20 -0
- data/TODO.complete/51-remove-respond-to.md +25 -0
- data/TODO.complete/52-xsd-decouple-fixtures.md +23 -0
- data/TODO.complete/53-xmi-public-send-cleanup.md +26 -0
- data/TODO.complete/54-wire-stereotype-icon-renderer.md +20 -0
- data/TODO.complete/55-wire-shapescript.md +20 -0
- data/TODO.complete/56-wire-emf-renderer.md +27 -0
- data/TODO.complete/57-wire-ocl-evaluator.md +23 -0
- data/TODO.complete/58-diff-modifications.md +21 -0
- data/TODO.complete/59-delete-toy-xmi-export.md +30 -0
- data/TODO.complete/60-curate-json-export.md +20 -0
- data/TODO.complete/61-plantuml-relationships.md +22 -0
- data/TODO.complete/62-changelog.md +17 -0
- data/TODO.complete/63-dependabot-fix.md +18 -0
- data/TODO.complete/STATUS.md +85 -0
- data/TODO.diagrams/01-svg-measurement-harness.md +31 -0
- data/TODO.diagrams/02-polygon-over-rendering.md +29 -0
- data/TODO.diagrams/03-text-over-rendering.md +30 -0
- data/TODO.diagrams/04-rect-under-rendering.md +33 -0
- data/TODO.diagrams/05-canvas-dimension-parity.md +51 -0
- data/TODO.diagrams/06-group-layering-parity.md +39 -0
- data/TODO.diagrams/07-text-content-fidelity.md +65 -0
- data/TODO.diagrams/08-qea-direct-pipeline.md +46 -0
- data/TODO.diagrams/12-connector-labels.md +40 -0
- data/TODO.diagrams/12-per-entity-svg-layer-ordering.md +24 -0
- data/TODO.diagrams/13-marker-polygon-vs-path-dispatch.md +20 -0
- data/TODO.diagrams/13-per-text-type-font-sizes.md +33 -0
- data/TODO.diagrams/14-center-header-text.md +33 -0
- data/TODO.diagrams/14-filter-diagram-frame-elements.md +18 -0
- data/TODO.diagrams/15-deep-dead-code-audit.md +47 -0
- data/TODO.diagrams/15-per-element-font-from-style.md +24 -0
- data/TODO.diagrams/16-canvas-marker-extent.md +30 -0
- data/TODO.diagrams/16-document-remaining-parity-gaps.md +91 -0
- data/TODO.diagrams/17-italic-abstract-classes.md +28 -0
- data/TODO.diagrams/17-remaining-parity-gaps.md +90 -0
- data/TODO.diagrams/18-canvas-from-image-bounds.md +20 -0
- data/TODO.diagrams/18-property-lookup-index.md +42 -0
- data/TODO.diagrams/19-connector-sx-sy-routing.md +27 -0
- data/TODO.diagrams/19-replace-respond-to-with-is-a.md +31 -0
- data/TODO.diagrams/20-split-labels-emitter.md +56 -0
- data/TODO.diagrams/20-visibility-glyph-font-encoding.md +27 -0
- data/TODO.diagrams/21-aggregation-navigability-arrow.md +21 -0
- data/TODO.diagrams/21-auto-generated-legend-block.md +65 -0
- data/TODO.diagrams/22-ghost-element-discriminator.md +57 -0
- data/TODO.diagrams/22-style-based-path-grouping.md +28 -0
- data/TODO.diagrams/23-marker-polygon-deduplication.md +47 -0
- data/TODO.diagrams/23-multiplicity-label-positioning.md +29 -0
- data/TODO.diagrams/24-marker-anchor-structural.md +35 -0
- data/TODO.diagrams/24-track-marker-anchors-structurally.md +66 -0
- data/TODO.diagrams/24-truncate-properties-to-fit-box.md +24 -0
- data/TODO.diagrams/26-phantom-general-parent-rendering.md +59 -0
- data/TODO.diagrams/27-path-grouping-mode-detection.md +43 -0
- data/TODO.diagrams/28-architecture-cleanup-batch.md +47 -0
- data/TODO.diagrams/30-decompose-elements-groups-for.md +52 -0
- data/TODO.diagrams/32-examples-coverage-batch.md +78 -0
- data/TODO.diagrams/36-instance-specification-model.md +42 -0
- data/TODO.diagrams/37-element-icon-decorations.md +41 -0
- data/TODO.diagrams/38-html-note-and-receptions.md +32 -0
- data/TODO.diagrams/39-property-stereotype-discriminator.md +40 -0
- data/TODO.diagrams/40-standalone-1-discriminator.md +38 -0
- data/TODO.diagrams/41-xmi-to-svg-pipeline.md +113 -0
- data/TODO.diagrams/42-close-all-parity-deltas.md +69 -0
- data/TODO.diagrams/43-marker-deduplication-strategy.md +54 -0
- data/TODO.diagrams/44-element-icon-decorations.md +34 -0
- data/TODO.diagrams/45-phantom-parent-class-boxes.md +40 -0
- data/TODO.diagrams/46-user-drawn-legend-swatches.md +44 -0
- data/TODO.diagrams/47-attribute-line-fidelity.md +72 -0
- data/TODO.diagrams/48-spec-coverage-critical-emitter-components.md +45 -0
- data/TODO.diagrams/49-spec-coverage-orchestrators.md +25 -0
- data/TODO.diagrams/50-examples-parity.md +85 -0
- data/TODO.diagrams/51-property-oy-gap-and-remaining-gaps.md +48 -0
- data/TODO.diagrams/52-marker-registration-architecture.md +89 -0
- data/TODO.diagrams/53-remaining-example-gaps.md +86 -0
- data/TODO.diagrams/54-display-name-nested-classes.md +40 -0
- data/TODO.diagrams/55-visibility-icon-discriminator.md +58 -0
- data/TODO.diagrams/56-package-contents-rendering.md +148 -0
- data/TODO.diagrams/57-instance-specification-model.md +100 -0
- data/TODO.diagrams/58-domain-model-note-text.md +67 -0
- data/TODO.diagrams/59-classes-arrow-discriminator.md +57 -0
- data/TODO.diagrams/60-testschema-association-marker.md +40 -0
- data/TODO.diagrams/61-legend-block-rendering.md +55 -0
- data/TODO.diagrams/61-plateau-parity-gaps.md +59 -0
- data/TODO.diagrams/62-ghost-element-rendering.md +56 -0
- data/TODO.diagrams/63-qualified-name-wrap.md +36 -0
- data/TODO.diagrams/64-property-stereotype-labels.md +22 -0
- data/TODO.diagrams/65-path-coordinate-frame.md +62 -0
- data/TODO.diagrams/67-path-coordinate-frame.md +62 -0
- data/TODO.diagrams/68-inherited-attributes.md +65 -0
- data/TODO.diagrams/69-package-anchor-conditional.md +29 -0
- data/TODO.diagrams/70-mdg-technology-support.md +68 -0
- data/TODO.diagrams/71-off-canvas-parent-ghost.md +45 -0
- data/TODO.diagrams/72-basic-attr-divider-paths.md +39 -0
- data/TODO.diagrams/73-plateau-polygon-gap.md +69 -0
- data/TODO.diagrams/74-plateau-rect-gap.md +22 -0
- data/TODO.diagrams/75-plateau-text-gap.md +39 -0
- data/TODO.diagrams/76-basic-poly-path-gaps.md +41 -0
- data/TODO.diagrams/77-basic-text-overrender.md +40 -0
- data/TODO.diagrams/78-headerlines-ocp-refactor.md +65 -0
- data/TODO.diagrams/79-architecture-backlog.md +65 -0
- data/TODO.diagrams/80-basic-triangle-polygons.md +51 -0
- data/TODO.diagrams/81-plateau-path-overrender.md +53 -0
- data/TODO.diagrams/82-appearance-canvas-offset.md +54 -0
- data/TODO.diagrams/83-3d-diagram-subtitle.md +58 -0
- data/TODO.diagrams/84-canvas-offset-mismatches.md +61 -0
- data/TODO.diagrams/85-phantom-property-overrender.md +95 -0
- data/TODO.diagrams/86-foreign-package-rule.md +62 -0
- data/TODO.diagrams/87-internal-tech-encryption.md +80 -0
- data/TODO.diagrams/EXAMPLES_STATUS.md +88 -0
- data/TODO.diagrams/README.md +69 -0
- data/TODO.diagrams/STATUS.md +73 -0
- data/TODO.fixup/01-default-grouped-paths.md +34 -0
- data/TODO.fixup/02-marker-consolidation-per-connector.md +20 -0
- data/TODO.fixup/03-diagram-font-inference.md +28 -0
- data/TODO.fixup/04-extract-bounds-calculator.md +25 -0
- data/TODO.fixup/05-marker-registry-ocp.md +32 -0
- data/TODO.fixup/06-connector-path-bend-routing.md +28 -0
- data/TODO.fixup/07-edge-attachment-formula.md +22 -0
- data/TODO.fixup/08-visual-diff-harness.md +28 -0
- data/TODO.fixup/09-extract-element-compartments.md +34 -0
- data/TODO.fixup/10-canvas-width-overshoot-fix.md +20 -0
- data/TODO.fixup/11-layer-sequencer-extraction.md +18 -0
- data/TODO.fixup/12-path-style-harmony.md +23 -0
- data/TODO.fixup/13-datatype-stereotype-fallback.md +28 -0
- data/TODO.fixup/14-ea-exe-reverse-engineering-notes.md +56 -0
- data/TODO.fixup/15-enumeration-literal-rendering.md +30 -0
- data/TODO.fixup/16-operation-compartment-rendering.md +42 -0
- data/TODO.fixup/17-path-count-calibration.md +27 -0
- data/TODO.fixup/18-polygon-count-calibration.md +32 -0
- data/TODO.fixup/19-rect-count-undershoot-investigation.md +40 -0
- data/TODO.fixup/20-stereotype-color-from-classifier.md +18 -0
- data/TODO.fixup/21-visibility-filter-for-properties.md +24 -0
- data/TODO.fixup/22-multiplicity-display-rule-calibration.md +25 -0
- data/TODO.fixup/23-diagram-frame-title-element.md +31 -0
- data/TODO.fixup/24-note-element-rendering.md +23 -0
- data/TODO.fixup/25-ea-exe-disassembly-findings.md +177 -0
- data/TODO.fixup/26-svg-renderer-architecture.md +78 -0
- data/TODO.fixup/27-svg-element-emitters-disassembly.md +135 -0
- data/TODO.fixup/28-geometry-parser-identification.md +57 -0
- data/TODO.fixup/29-qea-svg-xmi-triple-comparison.md +185 -0
- data/TODO.fixup/30-theme-system-stub.md +46 -0
- data/TODO.fixup/31-theme-value-object-registry.md +17 -0
- data/TODO.fixup/32-styleex-on-diagram-model.md +22 -0
- data/TODO.fixup/33-text-encoding-decimals-rotation.md +29 -0
- data/TODO.fixup/34-per-type-fill-via-theme.md +18 -0
- data/TODO.fixup/35-stroke-width-per-theme.md +7 -0
- data/TODO.fixup/36-qea-rect-coord-normalization.md +24 -0
- data/TODO.fixup/37-package-shape-rendering.md +22 -0
- data/TODO.fixup/38-note-element-rendering.md +15 -0
- data/TODO.fixup/39-styleex-flag-honoring.md +25 -0
- data/TODO.fixup/40-connector-dashed-lines.md +15 -0
- data/TODO.fixup/41-diagram-frame-showborder-detection.md +23 -0
- data/TODO.fixup/42-textrenderer-centralization.md +10 -0
- data/TODO.fixup/43-colorresolver-unification.md +24 -0
- data/TODO.fixup/44-theme-aware-textrenderer.md +17 -0
- data/TODO.fixup/45-theme-aware-fontresolver.md +22 -0
- data/TODO.fixup/46-style-parameterized-by-theme.md +21 -0
- data/TODO.fixup/47-canvas-frame-inset.md +19 -0
- data/TODO.fixup/48-background-rect-format.md +15 -0
- data/TODO.fixup/49-all-samples-integration-test.md +17 -0
- data/TODO.fixup/50-svg-emitter-architecture-docs.md +33 -0
- data/TODO.fixup/51-promote-theme-to-ea-namespace.md +28 -0
- data/TODO.fixup/52-theme-definition-integrated-fills.md +26 -0
- data/TODO.fixup/53-theme-registry-yaml-loading.md +50 -0
- data/TODO.fixup/54-diagram-theme-api.md +50 -0
- data/TODO.fixup/55-update-eaemitter-to-ea-theme.md +23 -0
- data/TODO.fixup/56-theme-yaml-files.md +65 -0
- data/TODO.fixup/57-theme-specs-and-integration.md +27 -0
- data/TODO.fixup/58-ea-entry-point-theme-autoload.md +20 -0
- data/TODO.fixup/59-thread-theme-through-all-renderers.md +29 -0
- data/TODO.fixup/60-cli-theme-option.md +22 -0
- data/TODO.fixup/61-theme-validation.md +28 -0
- data/TODO.fixup/62-theme-builder-dsl.md +31 -0
- data/TODO.fixup/63-theme-integration-rendering-spec.md +24 -0
- data/TODO.fixup/64-theme-writeback-styleex.md +21 -0
- data/TODO.fixup/65-remove-dead-eaemitter-theme-files.md +30 -0
- data/TODO.fixup/66-styleex-writeback.md +22 -0
- data/TODO.fixup/67-delete-dead-code.md +28 -0
- data/TODO.fixup/68-figure-parity-status.md +82 -0
- data/TODO.fixup/69-package-polygon-rendering.md +54 -0
- data/TODO.fixup/70-tagged-values-compartment.md +39 -0
- data/TODO.fixup/71-auto-detect-theme-from-xmi.md +37 -0
- data/TODO.fixup/72-sample-exports-as-regression-specs.md +37 -0
- data/TODO.fixup/73-delete-dead-transformations.md +14 -0
- data/TODO.fixup/74-delete-dead-diagram-renderers.md +18 -0
- data/TODO.fixup/75-visibility-legend-icons.md +23 -0
- data/TODO.fixup/76-plateau-text-undershoot.md +27 -0
- data/TODO.fixup/77-canvas-frame-margins.md +28 -0
- data/TODO.fixup/78-note-element-rendering.md +30 -0
- data/TODO.fixup/79-operation-compartment-rendering.md +27 -0
- data/TODO.fixup/80-tagged-value-stereotype-visibility.md +37 -0
- data/TODO.fixup/81-figure-parity-current-state.md +63 -0
- data/config/qea_schema.yml +356 -0
- data/config/themes/119.yml +98 -0
- data/config/themes/default.yml +14 -0
- data/examples/exports/20251010_current_plateau_v5/UML_EA.DTD +6856 -0
- data/examples/exports/20251010_current_plateau_v5/model.xml +96709 -0
- data/examples/exports/ArcGISWorkspace_template/UML_EA.DTD +6856 -0
- data/examples/exports/ArcGISWorkspace_template/model.xml +1427 -0
- data/examples/exports/UmlModel_template/UML_EA.DTD +6856 -0
- data/examples/exports/UmlModel_template/model.xml +23 -0
- data/examples/exports/basic/UML_EA.DTD +6856 -0
- data/examples/exports/basic/model.xml +8039 -0
- data/examples/exports/simple/UML_EA.DTD +6856 -0
- data/examples/exports/simple/model.xml +585 -0
- data/examples/exports/simple_example/UML_EA.DTD +6856 -0
- data/examples/exports/simple_example/model.xml +23 -0
- data/examples/exports/test/UML_EA.DTD +6856 -0
- data/examples/exports/test/model.xml +1638 -0
- data/examples/qea/basic.qea +0 -0
- data/frontend/README.md +51 -0
- data/frontend/dist/app.iife.js +24 -0
- data/frontend/dist/style.css +1 -0
- data/frontend/index.html +26 -0
- data/frontend/package-lock.json +2359 -0
- data/frontend/package.json +26 -0
- data/frontend/src/App.vue +59 -0
- data/frontend/src/app.ts +8 -0
- data/frontend/src/components/AppHeader.vue +127 -0
- data/frontend/src/components/AppSidebar.vue +119 -0
- data/frontend/src/components/ClassDetails.vue +247 -0
- data/frontend/src/components/DiagramView.vue +79 -0
- data/frontend/src/components/PackageDetails.vue +92 -0
- data/frontend/src/components/PackageTreeNode.vue +64 -0
- data/frontend/src/components/SearchResults.vue +48 -0
- data/frontend/src/components/WelcomeView.vue +87 -0
- data/frontend/src/shims-vue.d.ts +5 -0
- data/frontend/src/stores/dataStore.ts +79 -0
- data/frontend/src/stores/uiStore.ts +167 -0
- data/frontend/src/styles/main.css +1566 -0
- data/frontend/src/types.ts +221 -0
- data/frontend/tests/e2e/__screenshots__/new-dark-mode.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-package-details.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-search-modal.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-sidebar-collapsed.png +0 -0
- data/frontend/tests/e2e/__screenshots__/new-welcome.png +0 -0
- data/frontend/tests/e2e/render.spec.ts +188 -0
- data/frontend/tsconfig.json +20 -0
- data/frontend/vite.config.ts +26 -0
- data/frontend/vitest.config.ts +8 -0
- data/lib/ea/cli/app.rb +57 -2
- data/lib/ea/cli/command/diagrams.rb +37 -28
- data/lib/ea/cli/command/diff.rb +46 -0
- data/lib/ea/cli/command/export.rb +101 -0
- data/lib/ea/cli/command/info.rb +75 -0
- data/lib/ea/cli/command/lint.rb +48 -0
- data/lib/ea/cli/command/mdg.rb +98 -0
- data/lib/ea/cli/command/query.rb +34 -0
- data/lib/ea/cli/command/render.rb +135 -0
- data/lib/ea/cli/command/svg.rb +8 -15
- data/lib/ea/cli/command.rb +7 -0
- data/lib/ea/diagram/display_config.rb +184 -0
- data/lib/ea/diagram.rb +4 -41
- data/lib/ea/diff/change.rb +30 -0
- data/lib/ea/diff/comparator.rb +109 -0
- data/lib/ea/diff/html_reporter.rb +91 -0
- data/lib/ea/diff.rb +15 -0
- data/lib/ea/export/json/generator.rb +118 -0
- data/lib/ea/export/json.rb +12 -0
- data/lib/ea/export/json_schema/generator.rb +77 -0
- data/lib/ea/export/json_schema.rb +12 -0
- data/lib/ea/export/plantuml/generator.rb +140 -0
- data/lib/ea/export/plantuml.rb +12 -0
- data/lib/ea/export/xsd/class_mapping.rb +65 -0
- data/lib/ea/export/xsd/generator.rb +137 -0
- data/lib/ea/export/xsd/namespace_registry.rb +82 -0
- data/lib/ea/export/xsd.rb +19 -0
- data/lib/ea/export.rb +13 -0
- data/lib/ea/image/emf_renderer.rb +42 -0
- data/lib/ea/image.rb +12 -0
- data/lib/ea/lint/engine.rb +30 -0
- data/lib/ea/lint/lint_rule.rb +38 -0
- data/lib/ea/lint/offense.rb +18 -0
- data/lib/ea/lint/rules/cyclic_generalization.rb +62 -0
- data/lib/ea/lint/rules/duplicate_name.rb +28 -0
- data/lib/ea/lint/rules/missing_stereotype.rb +40 -0
- data/lib/ea/lint/rules/naming_convention.rb +44 -0
- data/lib/ea/lint/rules/orphan_element.rb +28 -0
- data/lib/ea/lint/rules.rb +14 -0
- data/lib/ea/lint.rb +13 -0
- data/lib/ea/mdg/document.rb +120 -0
- data/lib/ea/mdg/loader.rb +118 -0
- data/lib/ea/mdg/registry.rb +98 -0
- data/lib/ea/mdg/stereotype_alias_registry.rb +77 -0
- data/lib/ea/mdg/xml/applies_to.rb +18 -0
- data/lib/ea/mdg/xml/apply.rb +18 -0
- data/lib/ea/mdg/xml/content.rb +18 -0
- data/lib/ea/mdg/xml/documentation.rb +24 -0
- data/lib/ea/mdg/xml/stereotype.rb +28 -0
- data/lib/ea/mdg/xml/stereotypes.rb +18 -0
- data/lib/ea/mdg/xml/tag.rb +28 -0
- data/lib/ea/mdg/xml/tagged_values.rb +18 -0
- data/lib/ea/mdg/xml/technology.rb +28 -0
- data/lib/ea/mdg/xml/uml_profile.rb +22 -0
- data/lib/ea/mdg/xml/uml_profiles.rb +18 -0
- data/lib/ea/mdg/xml.rb +24 -0
- data/lib/ea/mdg.rb +25 -0
- data/lib/ea/model/classifier.rb +4 -0
- data/lib/ea/model/constraint.rb +24 -0
- data/lib/ea/model/diagram.rb +85 -0
- data/lib/ea/model/diagram_connector.rb +34 -0
- data/lib/ea/model/diagram_element.rb +16 -0
- data/lib/ea/model/document.rb +47 -2
- data/lib/ea/model/ghost_label.rb +32 -0
- data/lib/ea/model/instance_specification.rb +34 -0
- data/lib/ea/model/legend.rb +43 -0
- data/lib/ea/model/legend_item.rb +26 -0
- data/lib/ea/model/note.rb +28 -0
- data/lib/ea/model/operation.rb +2 -0
- data/lib/ea/model/property.rb +2 -0
- data/lib/ea/model/relationship.rb +2 -0
- data/lib/ea/model/signal.rb +14 -0
- data/lib/ea/model/slot.rb +19 -0
- data/lib/ea/model.rb +8 -0
- data/lib/ea/ocl/evaluator.rb +94 -0
- data/lib/ea/ocl/nodes.rb +30 -0
- data/lib/ea/ocl/parser.rb +133 -0
- data/lib/ea/ocl/unsupported_error.rb +7 -0
- data/lib/ea/ocl.rb +13 -0
- data/lib/ea/qea/factory/document_builder.rb +24 -10
- data/lib/ea/qea/factory/generalization_builder.rb +9 -11
- data/lib/ea/qea/infrastructure/table_reader.rb +9 -0
- data/lib/ea/qea/models/ea_author.rb +35 -0
- data/lib/ea/qea/models/ea_glossary.rb +34 -0
- data/lib/ea/qea/models/ea_image.rb +53 -0
- data/lib/ea/qea/models/ea_implement.rb +32 -0
- data/lib/ea/qea/models/ea_list.rb +42 -0
- data/lib/ea/qea/models/ea_object_effort.rb +34 -0
- data/lib/ea/qea/models/ea_object_problem.rb +37 -0
- data/lib/ea/qea/models/ea_object_require.rb +34 -0
- data/lib/ea/qea/models/ea_object_resource.rb +34 -0
- data/lib/ea/qea/models/ea_object_risk.rb +34 -0
- data/lib/ea/qea/models/ea_object_scenario.rb +34 -0
- data/lib/ea/qea/models/ea_object_test.rb +35 -0
- data/lib/ea/qea/models/ea_object_trx.rb +34 -0
- data/lib/ea/qea/models/ea_operation.rb +7 -0
- data/lib/ea/qea/models/ea_palette.rb +30 -0
- data/lib/ea/qea/models/ea_palette_item.rb +36 -0
- data/lib/ea/qea/models/ea_phase.rb +40 -0
- data/lib/ea/qea/models/ea_role_constraint.rb +32 -0
- data/lib/ea/qea/models/ea_secrypt.rb +34 -0
- data/lib/ea/qea/models/ea_version.rb +39 -0
- data/lib/ea/qea/models/ea_xref.rb +11 -1
- data/lib/ea/qea/models.rb +19 -0
- data/lib/ea/qea/services/database_loader.rb +22 -1
- data/lib/ea/qea/validation/database/ocl_constraint_validator.rb +65 -0
- data/lib/ea/qea/validation/database.rb +2 -0
- data/lib/ea/qea/validation/validation_engine.rb +2 -0
- data/lib/ea/qea/validation.rb +2 -0
- data/lib/ea/query/builder.rb +127 -0
- data/lib/ea/query.rb +9 -0
- data/lib/ea/render/image_converter.rb +101 -0
- data/lib/ea/render.rb +10 -0
- data/lib/ea/shapescript/parser.rb +208 -0
- data/lib/ea/shapescript/renderer.rb +74 -0
- data/lib/ea/shapescript/shape.rb +34 -0
- data/lib/ea/shapescript.rb +24 -0
- data/lib/ea/sources/qea/adapter.rb +22 -5
- data/lib/ea/sources/qea/classifier_builder.rb +184 -7
- data/lib/ea/sources/qea/diagram_builder.rb +352 -24
- data/lib/ea/sources/qea/id_normalizer.rb +16 -1
- data/lib/ea/sources/qea/instance_builder.rb +113 -0
- data/lib/ea/sources/qea/legend_builder.rb +137 -0
- data/lib/ea/sources/qea/note_builder.rb +58 -0
- data/lib/ea/sources/qea/object_classifier_map.rb +6 -1
- data/lib/ea/sources/qea/operation_builder.rb +1 -0
- data/lib/ea/sources/qea/package_builder.rb +16 -0
- data/lib/ea/sources/qea/relationship_builder.rb +21 -5
- data/lib/ea/sources/qea/tagged_value_builder.rb +28 -9
- data/lib/ea/sources/qea/xref/legend_definition.rb +35 -0
- data/lib/ea/sources/qea/xref/parser.rb +150 -0
- data/lib/ea/sources/qea/xref/property_definition.rb +29 -0
- data/lib/ea/sources/qea/xref/record.rb +41 -0
- data/lib/ea/sources/qea/xref/stereotype_application.rb +37 -0
- data/lib/ea/sources/qea/xref.rb +27 -0
- data/lib/ea/sources/qea.rb +4 -0
- data/lib/ea/sources/xmi/adapter.rb +80 -2
- data/lib/ea/sources/xmi/classifier_builder.rb +10 -1
- data/lib/ea/sources/xmi/diagram_builder.rb +95 -18
- data/lib/ea/sources/xmi/extension_geometry_parser.rb +19 -2
- data/lib/ea/sources/xmi/extension_style_parser.rb +15 -2
- data/lib/ea/sources/xmi/note_builder.rb +46 -0
- data/lib/ea/sources/xmi/property_builder.rb +9 -0
- data/lib/ea/sources/xmi/stereotype_builder.rb +54 -0
- data/lib/ea/sources/xmi/tag_builder.rb +45 -0
- data/lib/ea/sources/xmi/umldi_keyword_extractor.rb +87 -0
- data/lib/ea/sources/xmi.rb +4 -0
- data/lib/ea/spa/output/sharded_multi_file_strategy.rb +18 -3
- data/lib/ea/spa/output/single_file_strategy.rb +8 -2
- data/lib/ea/spa/output/strategy.rb +34 -0
- data/lib/ea/svg/connector_router.rb +134 -0
- data/lib/ea/svg/ea_emitter/background.rb +2 -3
- data/lib/ea/svg/ea_emitter/bounds_calculator.rb +142 -0
- data/lib/ea/svg/ea_emitter/canvas.rb +56 -33
- data/lib/ea/svg/ea_emitter/color_resolver.rb +56 -0
- data/lib/ea/svg/ea_emitter/compartment/attributes.rb +28 -0
- data/lib/ea/svg/ea_emitter/compartment/constraints.rb +30 -0
- data/lib/ea/svg/ea_emitter/compartment/enum_literals.rb +86 -0
- data/lib/ea/svg/ea_emitter/compartment/header.rb +32 -0
- data/lib/ea/svg/ea_emitter/compartment/header_divider.rb +57 -0
- data/lib/ea/svg/ea_emitter/compartment/instance_slots.rb +96 -0
- data/lib/ea/svg/ea_emitter/compartment/instance_underline.rb +67 -0
- data/lib/ea/svg/ea_emitter/compartment/note_body.rb +52 -0
- data/lib/ea/svg/ea_emitter/compartment/note_text.rb +102 -0
- data/lib/ea/svg/ea_emitter/compartment/operations.rb +38 -0
- data/lib/ea/svg/ea_emitter/compartment/package_contents.rb +72 -0
- data/lib/ea/svg/ea_emitter/compartment/package_from_parent.rb +136 -0
- data/lib/ea/svg/ea_emitter/compartment/shape.rb +82 -0
- data/lib/ea/svg/ea_emitter/compartment/stereotype_icon.rb +32 -0
- data/lib/ea/svg/ea_emitter/compartment/tagged_values.rb +30 -0
- data/lib/ea/svg/ea_emitter/compartment.rb +60 -0
- data/lib/ea/svg/ea_emitter/connectors.rb +46 -12
- data/lib/ea/svg/ea_emitter/diagram_frame.rb +143 -0
- data/lib/ea/svg/ea_emitter/document.rb +49 -25
- data/lib/ea/svg/ea_emitter/element/attribute_line_builder.rb +117 -0
- data/lib/ea/svg/ea_emitter/element/attribute_renderer.rb +119 -0
- data/lib/ea/svg/ea_emitter/element/bcol_decoder.rb +29 -0
- data/lib/ea/svg/ea_emitter/element/compartment_geometry.rb +113 -0
- data/lib/ea/svg/ea_emitter/element/constraint_renderer.rb +53 -0
- data/lib/ea/svg/ea_emitter/element/divider_renderer.rb +17 -0
- data/lib/ea/svg/ea_emitter/element/enumeration_literal_renderer.rb +34 -0
- data/lib/ea/svg/ea_emitter/element/filter.rb +44 -0
- data/lib/ea/svg/ea_emitter/element/hand_draw_shape_renderer.rb +77 -0
- data/lib/ea/svg/ea_emitter/element/header_line_pipeline.rb +43 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/instance_spec.rb +27 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/name.rb +76 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/parent_ghost.rb +25 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider/stereotype_label.rb +68 -0
- data/lib/ea/svg/ea_emitter/element/header_line_provider.rb +19 -0
- data/lib/ea/svg/ea_emitter/element/header_lines.rb +27 -0
- data/lib/ea/svg/ea_emitter/element/header_renderer.rb +48 -0
- data/lib/ea/svg/ea_emitter/element/icon_renderer.rb +109 -0
- data/lib/ea/svg/ea_emitter/element/legend_renderer.rb +177 -0
- data/lib/ea/svg/ea_emitter/element/note_shape_renderer.rb +112 -0
- data/lib/ea/svg/ea_emitter/element/operation_renderer.rb +100 -0
- data/lib/ea/svg/ea_emitter/element/package_shape_renderer.rb +181 -0
- data/lib/ea/svg/ea_emitter/element/row_icon_renderer.rb +156 -0
- data/lib/ea/svg/ea_emitter/element/shape_renderer.rb +17 -0
- data/lib/ea/svg/ea_emitter/element/stereotype_icon_renderer.rb +119 -0
- data/lib/ea/svg/ea_emitter/element/tagged_value_renderer.rb +50 -0
- data/lib/ea/svg/ea_emitter/element/text_escape.rb +20 -0
- data/lib/ea/svg/ea_emitter/element.rb +37 -0
- data/lib/ea/svg/ea_emitter/elements.rb +283 -95
- data/lib/ea/svg/ea_emitter/font_resolver.rb +111 -0
- data/lib/ea/svg/ea_emitter/ghost_labels.rb +66 -0
- data/lib/ea/svg/ea_emitter/label/end_label.rb +266 -0
- data/lib/ea/svg/ea_emitter/label/midpoint_label.rb +101 -0
- data/lib/ea/svg/ea_emitter/label/registry.rb +50 -0
- data/lib/ea/svg/ea_emitter/label.rb +23 -0
- data/lib/ea/svg/ea_emitter/labels.rb +93 -27
- data/lib/ea/svg/ea_emitter/layer.rb +20 -0
- data/lib/ea/svg/ea_emitter/layer_sequencer.rb +93 -0
- data/lib/ea/svg/ea_emitter/marker/arrow_path.rb +52 -0
- data/lib/ea/svg/ea_emitter/marker/diamond.rb +57 -0
- data/lib/ea/svg/ea_emitter/marker/kind.rb +35 -0
- data/lib/ea/svg/ea_emitter/marker/open_triangle.rb +27 -0
- data/lib/ea/svg/ea_emitter/marker/package_import.rb +39 -0
- data/lib/ea/svg/ea_emitter/marker/plus.rb +40 -0
- data/lib/ea/svg/ea_emitter/marker/registry.rb +42 -0
- data/lib/ea/svg/ea_emitter/marker.rb +37 -0
- data/lib/ea/svg/ea_emitter/markers.rb +351 -64
- data/lib/ea/svg/ea_emitter/render_context.rb +52 -0
- data/lib/ea/svg/ea_emitter/style.rb +15 -0
- data/lib/ea/svg/ea_emitter/text_renderer.rb +92 -0
- data/lib/ea/svg/ea_emitter.rb +33 -11
- data/lib/ea/svg/parity/checker.rb +105 -0
- data/lib/ea/svg/parity/source.rb +59 -0
- data/lib/ea/svg/parity/suite.rb +113 -0
- data/lib/ea/svg/parity.rb +14 -0
- data/lib/ea/svg.rb +2 -15
- data/lib/ea/theme/definition.rb +176 -0
- data/lib/ea/theme/loader.rb +125 -0
- data/lib/ea/theme/registry.rb +96 -0
- data/lib/ea/theme.rb +37 -0
- data/lib/ea/transformations.rb +5 -88
- data/lib/ea/validation/xmi_parity.rb +80 -0
- data/lib/ea/validation.rb +12 -0
- data/lib/ea/version.rb +4 -1
- data/lib/ea.rb +15 -4
- data/lib/tasks/svg_bench.rake +87 -0
- data/lutaml-uml-0.5.1.gem +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes-list.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-2-gradients.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-3-colors.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance-fonts.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-5-behavior.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-6-sequence.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-2-objects.png +0 -0
- data/reference-docs/enterprise-architect-appearance-dialogs/appearance-3-links.png +0 -0
- metadata +464 -26
- data/lib/ea/diagram/configuration.rb +0 -379
- data/lib/ea/diagram/element_renderers/base_renderer.rb +0 -77
- data/lib/ea/diagram/element_renderers/class_renderer.rb +0 -323
- data/lib/ea/diagram/element_renderers/connector_renderer.rb +0 -41
- data/lib/ea/diagram/element_renderers/package_renderer.rb +0 -61
- data/lib/ea/diagram/element_renderers.rb +0 -43
- data/lib/ea/diagram/extractor.rb +0 -566
- data/lib/ea/diagram/layout_engine.rb +0 -170
- data/lib/ea/diagram/path_builder.rb +0 -202
- data/lib/ea/diagram/style_parser.rb +0 -42
- data/lib/ea/diagram/style_resolver.rb +0 -291
- data/lib/ea/diagram/svg_renderer.rb +0 -274
- data/lib/ea/diagram/util.rb +0 -73
- data/lib/ea/svg/bounds_calculator.rb +0 -74
- data/lib/ea/svg/connector_path.rb +0 -138
- data/lib/ea/svg/element_box.rb +0 -256
- data/lib/ea/svg/renderer.rb +0 -77
- data/lib/ea/svg/style_resolver.rb +0 -72
- data/lib/ea/transformations/configuration.rb +0 -333
- data/lib/ea/transformations/format_registry.rb +0 -366
- data/lib/ea/transformations/parsers/base_parser.rb +0 -482
- data/lib/ea/transformations/parsers/qea_parser.rb +0 -401
- data/lib/ea/transformations/parsers/xmi_parser.rb +0 -243
- data/lib/ea/transformations/transformation_engine.rb +0 -390
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# TODO-D 65: Path coordinate frame mismatch (y-axis sign)
|
|
2
|
+
|
|
3
|
+
## Status: open
|
|
4
|
+
|
|
5
|
+
Elements render at the wrong vertical position because
|
|
6
|
+
`bounds_from_rect` interprets `RectTop` as the math-convention
|
|
7
|
+
y (negative, larger=lower) when EA actually stores it as the
|
|
8
|
+
negation of the screen-space y (negative, larger=higher).
|
|
9
|
+
|
|
10
|
+
The bench's shape_delta_total doesn't catch this because counts
|
|
11
|
+
match — but per-path coordinate comparison shows every ref path
|
|
12
|
+
is "missing" from our output (coordinate values differ).
|
|
13
|
+
|
|
14
|
+
## Evidence (plateau QEA, "Bridge" diagram)
|
|
15
|
+
|
|
16
|
+
Raw EA rect for `_CityObject`:
|
|
17
|
+
- RectLeft=611, RectTop=-64, RectRight=941, RectBottom=-186
|
|
18
|
+
|
|
19
|
+
Reference SVG renders `_CityObject` text at `y=73`.
|
|
20
|
+
|
|
21
|
+
Our model produces `bounds.y = -186` (taking `min(RectTop, RectBottom)`).
|
|
22
|
+
After canvas translation we render at `y > 1000` (bottom of canvas).
|
|
23
|
+
|
|
24
|
+
The correct interpretation is:
|
|
25
|
+
- screen-y of element's top edge = `-RectTop = 64`
|
|
26
|
+
- height = `RectTop - RectBottom = -64 - (-186) = 122`
|
|
27
|
+
|
|
28
|
+
With a small offset (33 in basic.qea, 9 in plateau Bridge) we'd
|
|
29
|
+
match the reference's text baseline.
|
|
30
|
+
|
|
31
|
+
## Approach
|
|
32
|
+
|
|
33
|
+
Update `DiagramBuilder#bounds_from_rect`:
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
def bounds_from_rect(obj_row)
|
|
37
|
+
left = obj_row.rectleft || 0
|
|
38
|
+
right = obj_row.rectright || 0
|
|
39
|
+
top = obj_row.recttop || 0
|
|
40
|
+
bottom = obj_row.rectbottom || 0
|
|
41
|
+
Ea::Model::Bounds.new(
|
|
42
|
+
x: [left, right].min,
|
|
43
|
+
y: -[top, bottom].max, # flip y-axis
|
|
44
|
+
width: (right - left).abs,
|
|
45
|
+
height: (bottom - top).abs
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then rework `Canvas#translate_y` and `BoundsCalculator` to use
|
|
51
|
+
positive y values consistently. The current min_y computation
|
|
52
|
+
also needs to flip.
|
|
53
|
+
|
|
54
|
+
This is a large change — needs careful re-verification against
|
|
55
|
+
basic.qea and test.qea to avoid regressing the 24/24 currently
|
|
56
|
+
matched.
|
|
57
|
+
|
|
58
|
+
## Impact
|
|
59
|
+
|
|
60
|
+
Doesn't change counts (and so won't move the bench needle), but
|
|
61
|
+
makes the visual output match EA positionally. Required before
|
|
62
|
+
we can claim "100% identical to QEA->SVG" in any visual sense.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# TODO-D 67: Path coordinate frame (y-axis sign)
|
|
2
|
+
|
|
3
|
+
## Status: open
|
|
4
|
+
|
|
5
|
+
Elements render at the wrong vertical position because
|
|
6
|
+
`bounds_from_rect` interprets `RectTop` as the math-convention
|
|
7
|
+
y (negative, larger=lower on screen) when EA actually stores
|
|
8
|
+
it as the negation of the screen-space y.
|
|
9
|
+
|
|
10
|
+
The bench's shape_delta_total doesn't catch this because counts
|
|
11
|
+
match — but per-path coordinate comparison shows every ref path
|
|
12
|
+
is "missing" from our output (coordinate values differ).
|
|
13
|
+
|
|
14
|
+
## Evidence (plateau QEA, "Bridge" diagram)
|
|
15
|
+
|
|
16
|
+
Raw EA rect for `_CityObject`:
|
|
17
|
+
- RectLeft=611, RectTop=-64, RectRight=941, RectBottom=-186
|
|
18
|
+
|
|
19
|
+
Reference SVG renders `_CityObject` text at `y=73`.
|
|
20
|
+
|
|
21
|
+
Our model produces `bounds.y = -186` (taking `min(RectTop, RectBottom)`).
|
|
22
|
+
After canvas translation we render at `y > 1000` (bottom of canvas).
|
|
23
|
+
|
|
24
|
+
The correct interpretation is:
|
|
25
|
+
- screen-y of element's top edge = `-RectTop = 64`
|
|
26
|
+
- height = `RectTop - RectBottom = -64 - (-186) = 122`
|
|
27
|
+
|
|
28
|
+
With the canvas's positive offset (40 frame inset + diagram-specific),
|
|
29
|
+
we match the reference's text baseline.
|
|
30
|
+
|
|
31
|
+
## Approach
|
|
32
|
+
|
|
33
|
+
Update `DiagramBuilder#bounds_from_rect`:
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
def bounds_from_rect(obj_row)
|
|
37
|
+
left = obj_row.rectleft || 0
|
|
38
|
+
right = obj_row.rectright || 0
|
|
39
|
+
top = obj_row.recttop || 0
|
|
40
|
+
bottom = obj_row.rectbottom || 0
|
|
41
|
+
Ea::Model::Bounds.new(
|
|
42
|
+
x: [left, right].min,
|
|
43
|
+
y: -[top, bottom].max, # flip y-axis
|
|
44
|
+
width: (right - left).abs,
|
|
45
|
+
height: (bottom - top).abs
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then rework `Canvas#translate_y` and `BoundsCalculator` to use
|
|
51
|
+
positive y values consistently. The current min_y computation
|
|
52
|
+
also needs to flip.
|
|
53
|
+
|
|
54
|
+
This is a large change — needs careful re-verification against
|
|
55
|
+
basic.qea and test.qea to avoid regressing the 184/188 currently
|
|
56
|
+
matched.
|
|
57
|
+
|
|
58
|
+
## Impact
|
|
59
|
+
|
|
60
|
+
Doesn't change counts (and so won't move the bench needle), but
|
|
61
|
+
makes the visual output match EA positionally. Required before
|
|
62
|
+
we can claim "100% identical to QEA->SVG" in any visual sense.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# TODO-D 68: Association-derived virtual properties (phantom attributes)
|
|
2
|
+
|
|
3
|
+
## Status: open (discriminator unresolved)
|
|
4
|
+
|
|
5
|
+
EA renders some association SourceRole values as virtual
|
|
6
|
+
"property" attributes inside the source classifier's attribute
|
|
7
|
+
compartment. For example, ImplicitGeometry has 4 associations to
|
|
8
|
+
CityFurniture with SourceRoles lod1..4ImplicitRepresentation.
|
|
9
|
+
EA renders "+lod1ImplicitRepresentation" inside ImplicitGeometry's
|
|
10
|
+
attribute compartment on every diagram where ImplicitGeometry is
|
|
11
|
+
placed with an expanded attribute compartment.
|
|
12
|
+
|
|
13
|
+
## Investigation findings
|
|
14
|
+
|
|
15
|
+
The phantom attributes come from t_connector.SourceRole on
|
|
16
|
+
Association and Aggregation connectors. In the plateau QEA:
|
|
17
|
+
- 206 Aggregations have SourceRoles
|
|
18
|
+
- 172 Associations have SourceRoles
|
|
19
|
+
|
|
20
|
+
Not all SourceRoles render as virtual attributes. The discriminator
|
|
21
|
+
that gates rendering has NOT been identified. Adding all 378
|
|
22
|
+
SourceRoles as properties causes massive over-rendering (text
|
|
23
|
+
delta: +20,000). The correct subset is much smaller.
|
|
24
|
+
|
|
25
|
+
### What was tried
|
|
26
|
+
|
|
27
|
+
1. **All SourceRoles as properties**: text +20k — far too many.
|
|
28
|
+
The vast majority of SourceRoles do NOT render in EA output.
|
|
29
|
+
|
|
30
|
+
2. **Only when connector NOT on current diagram**: incorrect —
|
|
31
|
+
on the ImplicitGeometry diagram, the lod* connectors ARE on
|
|
32
|
+
the diagram AND the phantom attrs still show.
|
|
33
|
+
|
|
34
|
+
3. **Only for GML stereotypes (Type/FeatureType)**: promising
|
|
35
|
+
but not all "Type" stereotyped classifiers show SourceRole
|
|
36
|
+
attrs on every diagram. CityGMLCore shows ImplicitGeometry
|
|
37
|
+
WITHOUT the lod texts (element is in collapsed mode).
|
|
38
|
+
|
|
39
|
+
### What's known
|
|
40
|
+
|
|
41
|
+
- SourceRoles render ONLY when the element's attribute compartment
|
|
42
|
+
is visible AND expanded (has NSL/font settings in ObjectStyle).
|
|
43
|
+
- The position of phantom attr texts in the ref SVG is OUTSIDE
|
|
44
|
+
any element rect (floating) on some diagrams, suggesting EA
|
|
45
|
+
places them at connector-label positions rather than inside
|
|
46
|
+
the attribute compartment.
|
|
47
|
+
- Multiple phantom attrs at the same position suggests overlap
|
|
48
|
+
rendering (all at same x,y) which is characteristic of connector
|
|
49
|
+
end-labels, not attribute-compartment lines.
|
|
50
|
+
|
|
51
|
+
### Next steps
|
|
52
|
+
|
|
53
|
+
1. Investigate whether the phantom attrs are actually connector
|
|
54
|
+
LABELS (from $LLB/$LLT geometry) rather than attribute
|
|
55
|
+
compartment lines. The position (412, 473) doesn't match any
|
|
56
|
+
element's attribute compartment area.
|
|
57
|
+
|
|
58
|
+
2. Check if the phantom attrs come from a per-diagram setting
|
|
59
|
+
like "Show inherited/association attributes" flag in the
|
|
60
|
+
t_diagram StyleEx or PDATA.
|
|
61
|
+
|
|
62
|
+
3. If they ARE attribute-compartment lines (not labels),
|
|
63
|
+
identify the precise subset of SourceRoles that EA renders
|
|
64
|
+
(maybe only when the connector's DestRole is empty AND the
|
|
65
|
+
SourceRole matches a naming convention).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# TODO-D 69: Package anchor marker conditional rendering
|
|
2
|
+
|
|
3
|
+
## Status: completed
|
|
4
|
+
|
|
5
|
+
The «import» connector's package_anchor marker (4-point closed
|
|
6
|
+
trapezoid at the source end) was rendered unconditionally,
|
|
7
|
+
causing 9 phantom paths on the plateau "Urban Planning ADE2"
|
|
8
|
+
diagram.
|
|
9
|
+
|
|
10
|
+
## Root cause
|
|
11
|
+
|
|
12
|
+
EA's t_diagramlinks.Geometry string carries explicit SX/SY/EX/EY
|
|
13
|
+
offset fields when the connector has been explicitly configured
|
|
14
|
+
with edge-attachment offsets. When SX/SY are absent, the
|
|
15
|
+
connector is auto-routed and EA suppresses the package_anchor
|
|
16
|
+
marker.
|
|
17
|
+
|
|
18
|
+
## Fix
|
|
19
|
+
|
|
20
|
+
Added `has_geometry_offsets` boolean to DiagramConnector model.
|
|
21
|
+
DiagramBuilder sets it by checking whether the raw Geometry
|
|
22
|
+
string contains "SX=". PackageImport marker returns [] when
|
|
23
|
+
false.
|
|
24
|
+
|
|
25
|
+
## Verification
|
|
26
|
+
|
|
27
|
+
- basic.qea Package Imports: SX=0;SY=0 present -> marker renders
|
|
28
|
+
- plateau Urban Planning ADE2: SX/SY absent -> no marker
|
|
29
|
+
- Urban Planning ADE2 delta dropped from 9 to 0 → matched
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# TODO-D 70: MDG Technology Support
|
|
2
|
+
|
|
3
|
+
## Status: Phases 1 & 2 complete; Phase 3 deferred
|
|
4
|
+
|
|
5
|
+
EA's MDG (Model Driven Generation) technologies bundle UML
|
|
6
|
+
profiles, reference models, and toolbox definitions in a single
|
|
7
|
+
XMI file. When EA loads an MDG, the MDG's classes/attributes/
|
|
8
|
+
stereotypes become available to all models — including inherited
|
|
9
|
+
attribute rendering when a classifier's stereotype maps to an
|
|
10
|
+
MDG-defined metaclass.
|
|
11
|
+
|
|
12
|
+
## Architecture (shipped)
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Ea::Mdg # standalone namespace
|
|
16
|
+
├─ Document # one MDG file's parsed model
|
|
17
|
+
│ ├─ ClassifierEntry (id, name, package_name, properties)
|
|
18
|
+
│ ├─ PropertyEntry (name, type_name, visibility, mult)
|
|
19
|
+
│ └─ GeneralizationEntry (specific_id, general_id)
|
|
20
|
+
├─ Loader # XMI parser → Document
|
|
21
|
+
└─ Registry # multi-MDG lookup, ancestor walking
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Integration:
|
|
25
|
+
|
|
26
|
+
- `Ea::Sources::Qea::Adapter.from_path(path, mdg_registry: nil)`
|
|
27
|
+
- When `mdg_registry:` is wired, `ClassifierBuilder#properties_for`
|
|
28
|
+
merges MDG-inherited attributes into the classifier's property
|
|
29
|
+
list.
|
|
30
|
+
- Backward-compatible: omitting `mdg_registry:` preserves prior
|
|
31
|
+
behavior exactly.
|
|
32
|
+
|
|
33
|
+
## Verified against reference MDG files
|
|
34
|
+
|
|
35
|
+
- `MDG ISO19103.xml` (12 classifiers, 5 packages)
|
|
36
|
+
- `ISO 19103 Edition 1 XML.xml` (62 classifiers, 68 generalizations,
|
|
37
|
+
properties under UML:Classifier.feature)
|
|
38
|
+
- Ancestor walk yields correct inherited properties
|
|
39
|
+
(e.g. UnitsList → StandardUnits → 11 properties)
|
|
40
|
+
|
|
41
|
+
## What's still needed for plateau parity
|
|
42
|
+
|
|
43
|
+
The plateau phantom attributes (`+lod1ImplicitRepresentation`
|
|
44
|
+
on `ImplicitGeometry`, `+boundedBy` on `_CityObject`, etc.) come
|
|
45
|
+
from a **CityGML/GML MDG** that is not in the user's
|
|
46
|
+
`~/src/lutaml/xmi/references/ImplementationModels/` directory.
|
|
47
|
+
|
|
48
|
+
To close those specific gaps:
|
|
49
|
+
1. Obtain the CityGML/GML MDG technology XML file.
|
|
50
|
+
2. Pass it via `mdg_registry:` when loading the plateau QEA.
|
|
51
|
+
3. The classifier's `Type` stereotype will resolve to the MDG's
|
|
52
|
+
`Type` class, and its ancestor properties will merge in.
|
|
53
|
+
|
|
54
|
+
This is data-availability, not architecture. The plumbing works.
|
|
55
|
+
|
|
56
|
+
## Phase 3 (deferred)
|
|
57
|
+
|
|
58
|
+
- Stereotype definition extraction (UML:Profile/Stereotype) for
|
|
59
|
+
applying tagged values from MDG stereotype definitions.
|
|
60
|
+
- CLI subcommand: `ea mdg list` / `ea mdg show <name>`.
|
|
61
|
+
- Toolbox definition parsing (for future toolbox rendering).
|
|
62
|
+
|
|
63
|
+
## Test coverage
|
|
64
|
+
|
|
65
|
+
- `spec/ea/mdg/loader_spec.rb` (6 specs)
|
|
66
|
+
- `spec/ea/mdg/registry_spec.rb` (8 specs)
|
|
67
|
+
- `spec/ea/sources/qea/mdg_integration_spec.rb` (3 specs)
|
|
68
|
+
- Total: 17 new specs; full suite 1839 examples, 0 failures.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# TODO-D 71: Off-canvas parent class ghost line in element header
|
|
2
|
+
|
|
3
|
+
## Status: completed (2026-08-01)
|
|
4
|
+
|
|
5
|
+
EA prepends the off-canvas parent classifier's name as an italic
|
|
6
|
+
line at the top of a placed element's header when ALL of:
|
|
7
|
+
|
|
8
|
+
1. The diagram's HideParents PDATA flag is 0 (default).
|
|
9
|
+
2. The placed element has a Generalization to a parent NOT placed
|
|
10
|
+
on the current diagram.
|
|
11
|
+
3. No other element from the parent's package is placed on the
|
|
12
|
+
diagram (EA treats the parent's package as "represented").
|
|
13
|
+
|
|
14
|
+
e.g. on the indoor diagram (HideParents=0), Room's parent
|
|
15
|
+
_CityObject (in the "core" package, off-canvas, no other core
|
|
16
|
+
elements placed) renders as an italic "_CityObject" line above
|
|
17
|
+
Room's own header. On Building (HideParents=1), no parent ghosts
|
|
18
|
+
render at all.
|
|
19
|
+
|
|
20
|
+
## Implementation
|
|
21
|
+
|
|
22
|
+
- RelationshipBuilder populates Generalization.specific_id and
|
|
23
|
+
.general_id (child + parent GUIDs).
|
|
24
|
+
- Diagram model gains show_parents attribute; DiagramBuilder
|
|
25
|
+
parses HideParents= from t_diagram.PDATA.
|
|
26
|
+
- RenderContext carries off_canvas_parent_name; Elements resolves
|
|
27
|
+
it via document.relationships + model_index + diagram.elements.
|
|
28
|
+
- HeaderLines prepends [name, :italic] when the value is non-nil.
|
|
29
|
+
- LayerSequencer threads `document:` to Elements.
|
|
30
|
+
|
|
31
|
+
## Plateau QEA impact
|
|
32
|
+
|
|
33
|
+
- Before: text delta -98 (98 texts missing vs ref)
|
|
34
|
+
- After: text delta -36 (62 texts closed)
|
|
35
|
+
- 188/188 diagrams matched.
|
|
36
|
+
|
|
37
|
+
## Remaining gap (-36)
|
|
38
|
+
|
|
39
|
+
The foreign-package rule is slightly too aggressive — some diagrams
|
|
40
|
+
(tran_2, urf_urbanFunction) render parent ghosts for parents in
|
|
41
|
+
"represented" packages. Removing the foreign-package check
|
|
42
|
+
over-corrects to +60 (over-render). The true discriminator is
|
|
43
|
+
narrower than "package represented" but broader than just
|
|
44
|
+
HideParents. Defer to a future investigation if a clearer signal
|
|
45
|
+
(e.g., a t_object flag, MDG stereotype pattern) is identified.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# TODO-D 72: Spurious per-attribute divider paths on basic.qea outlier
|
|
2
|
+
|
|
3
|
+
## Status: open
|
|
4
|
+
|
|
5
|
+
basic.qea diagram "Two Level Class Composition Hierarchy with
|
|
6
|
+
Attributes" (4FC1D352-...) over-renders 16 short horizontal <path>
|
|
7
|
+
elements that the EA reference does not emit.
|
|
8
|
+
|
|
9
|
+
## Symptom
|
|
10
|
+
|
|
11
|
+
- rect: ours=18 ref=18 (matches)
|
|
12
|
+
- path: ours=50 ref=34 (+16 overshoot)
|
|
13
|
+
- polygon: ours=17 ref=17 (matches)
|
|
14
|
+
- text: ours=102 ref=102 (matches)
|
|
15
|
+
|
|
16
|
+
## Pattern of the extra paths
|
|
17
|
+
|
|
18
|
+
All 16 extras are short 110px-wide horizontal lines at evenly
|
|
19
|
+
spaced y coordinates that line up with attribute rows:
|
|
20
|
+
|
|
21
|
+
- M 661 66 L 771 66
|
|
22
|
+
- M 661 152 L 771 152
|
|
23
|
+
- M 661 238 L 771 238
|
|
24
|
+
- M 487 66 L 597 66
|
|
25
|
+
- M 487 152 L 597 152
|
|
26
|
+
- ... (12 more at the same y values across 4 element columns)
|
|
27
|
+
|
|
28
|
+
## Hypothesis
|
|
29
|
+
|
|
30
|
+
We render per-attribute separator lines between each attribute row.
|
|
31
|
+
EA only emits a single header→content divider plus the element rect
|
|
32
|
+
outline; attribute rows are NOT visually separated by horizontal
|
|
33
|
+
lines in EA's encoding.
|
|
34
|
+
|
|
35
|
+
## Next step
|
|
36
|
+
|
|
37
|
+
Audit Compartment::Attributes and DividerRenderer for any per-row
|
|
38
|
+
line emission. The fix is to suppress row separators and keep only
|
|
39
|
+
the header divider.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# TODO-D 73: Plateau polygon under-render (-4)
|
|
2
|
+
|
|
3
|
+
## Status: partially investigated (2026-08-02)
|
|
4
|
+
|
|
5
|
+
Across 188 plateau diagrams, we render 4 fewer `<polygon>` elements
|
|
6
|
+
than EA's reference SVG. Per-diagram deltas:
|
|
7
|
+
|
|
8
|
+
- Appearance (BC1F7E00, C31C1314): -2 each
|
|
9
|
+
- CityGMLCore (88D0CB44): -1
|
|
10
|
+
- 都市計画決定情報の概要 (8FD488EF): -1
|
|
11
|
+
- 立体的な範囲、区域界、品質属性 (1321F39B): -1
|
|
12
|
+
- 都市施設 (C96CBC24): -1
|
|
13
|
+
- 3D都市モデル応用スキーマと他のスキーマとの関係 (DFBB1072): +3
|
|
14
|
+
- udx (6481E2CC): +1
|
|
15
|
+
|
|
16
|
+
## Investigation update (2026-08-02)
|
|
17
|
+
|
|
18
|
+
For 都市施設 / 都市計画決定情報 / 立体的な範囲: each missing
|
|
19
|
+
polygon is a small 4-point DIAMOND inside an element body.
|
|
20
|
+
|
|
21
|
+
Example (都市施設):
|
|
22
|
+
`<polygon points="323 401 328 411 333 401 328 391" ...>`
|
|
23
|
+
Inside a `<g>` with fill="#FAF1EC" stroke="#69738C"
|
|
24
|
+
|
|
25
|
+
These colors (#FAF1EC, #69738C) are NOT standard aggregation
|
|
26
|
+
diamond colors (#FFFFFF fill, #000000 stroke). They appear to be
|
|
27
|
+
**stereotype decorator icons** — small symbolic icons EA renders
|
|
28
|
+
inside element bodies when a stereotype provides a custom icon.
|
|
29
|
+
|
|
30
|
+
## Follow-up investigation (2026-08-02)
|
|
31
|
+
|
|
32
|
+
Found EA installation at:
|
|
33
|
+
~/Library/Application Support/CrossOver/Bottles/
|
|
34
|
+
Enterprise Architect 16.x/drive_c/Program Files/Sparx Systems/EA/
|
|
35
|
+
|
|
36
|
+
Located stereotype-related files:
|
|
37
|
+
- Config/GML/GMLStereotypes.xml — only stereotype ALIASES, no icons
|
|
38
|
+
- MDGTechnologies/*.xml — many MDG files, none reference icons
|
|
39
|
+
- TemplateResources161.dll — likely contains compiled icon resources
|
|
40
|
+
- t_stereotypes table — empty Metafile BLOBs for FeatureType
|
|
41
|
+
|
|
42
|
+
Found element-style flag `HideIcon=0` on FeatureType elements on
|
|
43
|
+
都市施設 — confirmed EA DOES intend to show an icon.
|
|
44
|
+
|
|
45
|
+
## Discriminator puzzle
|
|
46
|
+
|
|
47
|
+
On 都市施設, ALL 21 placed FeatureType elements have HideIcon=0.
|
|
48
|
+
But ref renders the diamond icon for only 1 of them
|
|
49
|
+
(CollectiveFacilitiesForReconstruction — the largest element).
|
|
50
|
+
|
|
51
|
+
The discriminator is NOT:
|
|
52
|
+
- HideIcon flag (all elements have it = 0)
|
|
53
|
+
- Stereotype (all are FeatureType)
|
|
54
|
+
- Element size (icon position is element-relative)
|
|
55
|
+
|
|
56
|
+
Hypotheses for the actual discriminator:
|
|
57
|
+
1. The element is "selected" or "active" in the source QEA
|
|
58
|
+
2. The element is the diagram's "subject" (a per-diagram flag)
|
|
59
|
+
3. The icon is part of a legend/key, not per-element
|
|
60
|
+
|
|
61
|
+
## Implementation needed
|
|
62
|
+
|
|
63
|
+
To close this gap requires either:
|
|
64
|
+
1. Reverse-engineering EA's stereotype decorator icon logic
|
|
65
|
+
2. Parsing the EMF BLOB from t_image (1 image, 69KB)
|
|
66
|
+
3. Extracting icon resources from EA.exe / TemplateResources161.dll
|
|
67
|
+
|
|
68
|
+
Even then, the discriminator for WHICH elements get icons is
|
|
69
|
+
unclear from available data.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# TODO-D 74: Plateau rect over-render (+4)
|
|
2
|
+
|
|
3
|
+
## Status: open
|
|
4
|
+
|
|
5
|
+
Across 188 plateau diagrams, we render 4 more `<rect>` elements
|
|
6
|
+
than EA's reference SVG. Per-diagram deltas are spread thin.
|
|
7
|
+
|
|
8
|
+
## Likely causes
|
|
9
|
+
|
|
10
|
+
1. **Phantom connector label boxes**: my phantom connector code
|
|
11
|
+
synthesizes label boxes (LLB/LLT) that may render extra rects.
|
|
12
|
+
2. **Element rect for hidden elements**: elements that should be
|
|
13
|
+
filtered (e.g., via element_filter) but still render their
|
|
14
|
+
bounding rects.
|
|
15
|
+
3. **Compartment background rects**: extra rects for compartments
|
|
16
|
+
that EA suppresses in certain modes.
|
|
17
|
+
|
|
18
|
+
## Next step
|
|
19
|
+
|
|
20
|
+
Identify the 4 specific diagrams with rect_delta > 0 and inspect
|
|
21
|
+
the actual `<rect>` content vs ref. Likely a per-diagram PDATA
|
|
22
|
+
flag mismatch.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# TODO-D 75: Plateau text under-render (-36)
|
|
2
|
+
|
|
3
|
+
## Status: open (partial — closed 62 of original -98 in TODO-D 71)
|
|
4
|
+
|
|
5
|
+
Across 188 plateau diagrams, we render 36 fewer `<text>` elements
|
|
6
|
+
than EA's reference SVG. Top undershoot diagrams:
|
|
7
|
+
|
|
8
|
+
- tran_2 (-4): missing 2× RoadAttribute, 1× TransportationComplex,
|
|
9
|
+
1× _TransportationObject, 1× TrafficAreaAttribute
|
|
10
|
+
- urf_urbanFunction (-4): similar pattern
|
|
11
|
+
- 12 diagrams at -3 each
|
|
12
|
+
- many at -2
|
|
13
|
+
|
|
14
|
+
## Root cause
|
|
15
|
+
|
|
16
|
+
The foreign-package rule in `off_canvas_parent_name_for` is too
|
|
17
|
+
aggressive. It suppresses parent ghosts when ANY placed element
|
|
18
|
+
shares the parent's package, but EA actually renders ghosts in
|
|
19
|
+
this case for diagrams like tran_2 and urf_urbanFunction.
|
|
20
|
+
|
|
21
|
+
The discriminator is narrower than "package represented" — possibly
|
|
22
|
+
related to whether the parent is in a base library (gml) vs a user
|
|
23
|
+
package (uro, tran), or some other property of the parent class.
|
|
24
|
+
|
|
25
|
+
## What was tried
|
|
26
|
+
|
|
27
|
+
1. **Just HideParents flag**: closed -98 to +60 (over-rendered 60).
|
|
28
|
+
2. **HideParents + foreign-package check**: closed +60 to -36
|
|
29
|
+
(under-rendered 36).
|
|
30
|
+
|
|
31
|
+
The truth is between these. Narrower discriminator needed.
|
|
32
|
+
|
|
33
|
+
## Deferred
|
|
34
|
+
|
|
35
|
+
Requires identifying the precise EA rule. Could be:
|
|
36
|
+
- A t_object flag on the parent (e.g., is it generic/template)
|
|
37
|
+
- The parent's package being a "base library" (gml vs user model)
|
|
38
|
+
- A specific stereotype pattern (e.g., base GML stereotypes)
|
|
39
|
+
- Connector-level metadata we're not yet reading
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# TODO-D 76: basic.qea polygon under-render (-6) and path over-render (+6)
|
|
2
|
+
|
|
3
|
+
## Status: open
|
|
4
|
+
|
|
5
|
+
After the aggregation arrow fix (TODO-D 73), basic.qea reached
|
|
6
|
+
22/22 diagrams matched within tolerance, but two aggregate deltas
|
|
7
|
+
remain:
|
|
8
|
+
|
|
9
|
+
- polygon: ours=95, ref=101 (-6)
|
|
10
|
+
- path: ours=208, ref=202 (+6)
|
|
11
|
+
|
|
12
|
+
## Per-diagram pattern
|
|
13
|
+
|
|
14
|
+
- Package Dependencies (0EDEA6EF): polygon +3
|
|
15
|
+
- Basic Class Diagram with Attributes (4F421236): polygon -2
|
|
16
|
+
- Basic Class Diagram with Operations (2AAB709F): polygon -2
|
|
17
|
+
- Basic Class Diagram with Receptions (4DBDAB9E): polygon -2
|
|
18
|
+
- Basic Class Diagram with Attributes and Operations (D2FA55D3): polygon -2
|
|
19
|
+
- Basic Class Diagram with Multiplicities (78030266): polygon -1
|
|
20
|
+
- Basic Class Diaram with Roles (6E95B74E): polygon -1
|
|
21
|
+
- Domain Model (E325B9D8): polygon +1
|
|
22
|
+
|
|
23
|
+
## Likely cause (Basic Class Diagram family)
|
|
24
|
+
|
|
25
|
+
For the 4 diagrams with polygon=-2, we're missing 2 small triangle
|
|
26
|
+
polygon markers per diagram. These are likely Generalization arrow
|
|
27
|
+
triangles that we suppress somewhere.
|
|
28
|
+
|
|
29
|
+
The +3 polygon overshoot on "Package Dependencies" is likely a
|
|
30
|
+
package-import marker (anchor shape) that EA omits.
|
|
31
|
+
|
|
32
|
+
## Path over-render (+6)
|
|
33
|
+
|
|
34
|
+
After the aggregation arrow fix, the +16 path over-render on the
|
|
35
|
+
outlier closed (to 0). The remaining +6 paths are likely from
|
|
36
|
+
similar marker issues on the diagrams above.
|
|
37
|
+
|
|
38
|
+
## Next step
|
|
39
|
+
|
|
40
|
+
For each affected diagram, compare our markers vs ref's markers.
|
|
41
|
+
Identify which marker emission is incorrect.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# TODO-D 77: basic.qea text over-render (+2)
|
|
2
|
+
|
|
3
|
+
## Status: open
|
|
4
|
+
|
|
5
|
+
basic.qea's two diagrams overshoot text by 1 each:
|
|
6
|
+
|
|
7
|
+
- Classes: +1
|
|
8
|
+
- Composition with Substitution: +1
|
|
9
|
+
|
|
10
|
+
## Composition with Substitution diff
|
|
11
|
+
|
|
12
|
+
Ours has:
|
|
13
|
+
+1 "Class B.3" (split qualified name part)
|
|
14
|
+
+1 "Class B.2"
|
|
15
|
+
+1 "Class B.1"
|
|
16
|
+
+1 "«property»" (spurious property stereotype)
|
|
17
|
+
|
|
18
|
+
Ref has:
|
|
19
|
+
+1 "Class B::Class B.1" (single qualified name line)
|
|
20
|
+
+1 "Class B::Class B.2"
|
|
21
|
+
+1 "Class B::Class B.3"
|
|
22
|
+
|
|
23
|
+
So our qualified-name wrap is incorrectly splitting "Class B::X"
|
|
24
|
+
into two lines for these nested classes. The qualified name should
|
|
25
|
+
render as ONE line per element, not as "Class B::" + "X".
|
|
26
|
+
|
|
27
|
+
The spurious "«property»" text appears to come from a connector
|
|
28
|
+
SourceRole label that we render but ref doesn't on this diagram.
|
|
29
|
+
|
|
30
|
+
## Classes diff
|
|
31
|
+
|
|
32
|
+
Need to identify what specific text differs on the Classes diagram.
|
|
33
|
+
|
|
34
|
+
## Next step
|
|
35
|
+
|
|
36
|
+
1. Inspect why qualified-name wrap triggers for "Class B::Class B.X"
|
|
37
|
+
(likely a width estimation mismatch).
|
|
38
|
+
2. Identify the connector whose SourceRole produces "«property»"
|
|
39
|
+
and apply the right suppression (similar to aggregation arrow
|
|
40
|
+
fix — only render on specific directions).
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# TODO-D 78: Refactor HeaderLines into provider chain (OCP)
|
|
2
|
+
|
|
3
|
+
## Status: open (architecture improvement)
|
|
4
|
+
|
|
5
|
+
The current `HeaderLines.for` accepts a growing list of kwargs:
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
def for(classifier,
|
|
9
|
+
diagram_package_id: nil,
|
|
10
|
+
visually_nested: false,
|
|
11
|
+
umldi_keyword: nil,
|
|
12
|
+
bounds_width: nil,
|
|
13
|
+
font_size: 9,
|
|
14
|
+
off_canvas_parent_name: nil) # added in TODO-D 71
|
|
15
|
+
...
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Adding the off-canvas parent line required:
|
|
20
|
+
1. A new kwarg on `for`
|
|
21
|
+
2. New logic inside `for` to prepend the line
|
|
22
|
+
3. Threading the value from `Elements#build_context` through `RenderContext`
|
|
23
|
+
|
|
24
|
+
This is OCP-violating: each new header line variant (e.g., "realized
|
|
25
|
+
interfaces", "template parameters", "constraint summary") would
|
|
26
|
+
require modifying `HeaderLines.for` again.
|
|
27
|
+
|
|
28
|
+
## Proposed refactor
|
|
29
|
+
|
|
30
|
+
Convert `HeaderLines` into a chain of line providers, each
|
|
31
|
+
contributing 0+ lines to the header. New line types = new provider
|
|
32
|
+
class, registered into the chain (no modification of existing
|
|
33
|
+
code).
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
module Element
|
|
37
|
+
module HeaderLineProvider
|
|
38
|
+
ALL = [
|
|
39
|
+
StereotypeLine, # «FeatureType» line (when present)
|
|
40
|
+
ParentClassLine, # italic off-canvas parent (TODO-D 71)
|
|
41
|
+
QualifiedNameLine, # the bold class name (with optional wrap)
|
|
42
|
+
].freeze
|
|
43
|
+
|
|
44
|
+
def self.lines_for(classifier, context:)
|
|
45
|
+
ALL.flat_map { |provider| provider.lines_for(classifier, context) }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Where `context` is a small Struct carrying the inputs each provider
|
|
52
|
+
may need (diagram_package_id, visually_nested, off_canvas_parent_name,
|
|
53
|
+
bounds_width, font_size, etc.).
|
|
54
|
+
|
|
55
|
+
## Benefit
|
|
56
|
+
|
|
57
|
+
Adding a new line type (e.g., "interface signatures" on Interface
|
|
58
|
+
classifiers) becomes a single new provider class — `HeaderLines.for`
|
|
59
|
+
never changes.
|
|
60
|
+
|
|
61
|
+
## Migration
|
|
62
|
+
|
|
63
|
+
Incremental: extract one provider at a time, starting with the
|
|
64
|
+
off-canvas parent line (the most recent addition). Each extraction
|
|
65
|
+
is independently shippable.
|