ea 0.4.0 → 0.5.0
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/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/STATUS.md +109 -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 +80 -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 +82 -0
- data/lib/ea/diff/html_reporter.rb +91 -0
- data/lib/ea/diff.rb +15 -0
- data/lib/ea/export/json/generator.rb +42 -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 +73 -0
- data/lib/ea/export/plantuml.rb +12 -0
- data/lib/ea/export/xmi/generator.rb +77 -0
- data/lib/ea/export/xmi.rb +11 -0
- data/lib/ea/export/xsd/class_mapping.rb +65 -0
- data/lib/ea/export/xsd/generator.rb +142 -0
- data/lib/ea/export/xsd/namespace_registry.rb +82 -0
- data/lib/ea/export/xsd.rb +19 -0
- data/lib/ea/export.rb +14 -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 +35 -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/query/builder.rb +108 -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/tagged_values.rb +30 -0
- data/lib/ea/svg/ea_emitter/compartment.rb +58 -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 +15 -24
- 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 +82 -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/version.rb +4 -1
- data/lib/ea.rb +14 -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 +449 -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,24 @@
|
|
|
1
|
+
# 43 - Unify Color Computation (ColorResolver)
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Outcome
|
|
6
|
+
|
|
7
|
+
New `Ea::Svg::EaEmitter::ColorResolver` is single source of truth
|
|
8
|
+
for fill + stroke color decisions. Precedence chain:
|
|
9
|
+
1. element BCol (when present and not sentinel)
|
|
10
|
+
2. theme per-type pastel (when theme is themed)
|
|
11
|
+
3. stereotype color (via stereotype_resolver)
|
|
12
|
+
4. default fill
|
|
13
|
+
|
|
14
|
+
Same chain for stroke (LCol → theme.border → default).
|
|
15
|
+
|
|
16
|
+
Replaces 4 inline methods in Elements (resolve_fill, theme_fill_for,
|
|
17
|
+
fill_for_classifier, primary_stereotype).
|
|
18
|
+
|
|
19
|
+
## Files changed
|
|
20
|
+
|
|
21
|
+
- lib/ea/svg/ea_emitter/color_resolver.rb — NEW
|
|
22
|
+
- lib/ea/svg/ea_emitter.rb — autoload
|
|
23
|
+
- lib/ea/svg/ea_emitter/elements.rb — delegate to ColorResolver
|
|
24
|
+
- spec/ea/svg/ea_emitter/color_resolver_spec.rb — 10 specs
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# 44 - Theme-Aware TextRenderer
|
|
2
|
+
|
|
3
|
+
## Status: ANALYZED (2026-07-26, closed)
|
|
4
|
+
|
|
5
|
+
## Decision
|
|
6
|
+
|
|
7
|
+
TextRenderer already accepts per-call fill/weight/size_unit
|
|
8
|
+
overrides. Callers (HeaderRenderer, AttributeRenderer, etc.)
|
|
9
|
+
can pass theme-derived values explicitly. Adding theme
|
|
10
|
+
awareness inside TextRenderer would duplicate the FontResolver
|
|
11
|
+
logic — better to keep TextRenderer stateless.
|
|
12
|
+
|
|
13
|
+
Theme values flow through FontResolver which is now theme-aware
|
|
14
|
+
(fixup 45). HeaderRenderer etc. can consult FontResolver for
|
|
15
|
+
weight/size_unit/fill and pass to TextRenderer.
|
|
16
|
+
|
|
17
|
+
Closing — current design is correct MECE separation.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# 45 - Theme-Aware FontResolver
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Outcome
|
|
6
|
+
|
|
7
|
+
FontResolver constructor accepts optional `theme:` param.
|
|
8
|
+
Precedence chain:
|
|
9
|
+
1. element.font_family (per-element override)
|
|
10
|
+
2. theme.font_family (when theme is themed)
|
|
11
|
+
3. diagram-default (most common element font)
|
|
12
|
+
4. locale fallback (Calibri 10)
|
|
13
|
+
|
|
14
|
+
Same for size. Added `size_unit_for` and theme-aware weight_for.
|
|
15
|
+
|
|
16
|
+
Elements passes theme via `FontResolver.new(diagram, theme: theme)`.
|
|
17
|
+
|
|
18
|
+
## Files changed
|
|
19
|
+
|
|
20
|
+
- lib/ea/svg/ea_emitter/font_resolver.rb — theme param + size_unit
|
|
21
|
+
- lib/ea/svg/ea_emitter/elements.rb — pass theme to FontResolver
|
|
22
|
+
- spec/ea/svg/ea_emitter/font_resolver_spec.rb — theme :119 specs
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# 46 - Style Constants Parameterized by Theme
|
|
2
|
+
|
|
3
|
+
## Status: ANALYZED (2026-07-26, deferred)
|
|
4
|
+
|
|
5
|
+
## Decision
|
|
6
|
+
|
|
7
|
+
Current Style constants (CONNECTOR_LINE, DIAMOND_FILLED, etc.)
|
|
8
|
+
bake in stroke-width=2. Making them theme-parameterized would
|
|
9
|
+
require threading Theme through Connectors/Markers — significant
|
|
10
|
+
plumbing for marginal benefit since:
|
|
11
|
+
- Plateau (default theme) is the primary use case and uses sw=2
|
|
12
|
+
- Theme :119 diagrams use the same constants but render via
|
|
13
|
+
Elements (which already uses theme.stroke_width)
|
|
14
|
+
|
|
15
|
+
The Connectors/Markers layer doesn't yet need theme support
|
|
16
|
+
since plateau parity is the primary target. Deferred until
|
|
17
|
+
theme-aware connector rendering is required.
|
|
18
|
+
|
|
19
|
+
## Files changed
|
|
20
|
+
|
|
21
|
+
None.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# 47 - Canvas Frame Inset
|
|
2
|
+
|
|
3
|
+
## Status: ANALYZED (2026-07-26, deferred)
|
|
4
|
+
|
|
5
|
+
## Decision
|
|
6
|
+
|
|
7
|
+
When frame is enabled, elements can overlap the frame border
|
|
8
|
+
(6px inset). This is a real issue but only affects the simple/
|
|
9
|
+
basic test diagrams (where frame is opt-in via frame: true).
|
|
10
|
+
|
|
11
|
+
Plateau (frame disabled) is unaffected.
|
|
12
|
+
|
|
13
|
+
The fix would require BoundsCalculator to add 6px to all
|
|
14
|
+
elements when frame is enabled — non-trivial plumbing. Deferred
|
|
15
|
+
until frame auto-detection is implemented.
|
|
16
|
+
|
|
17
|
+
## Files changed
|
|
18
|
+
|
|
19
|
+
None.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 48 - Background Rect Format Match
|
|
2
|
+
|
|
3
|
+
## Status: ANALYZED (2026-07-26, verified correct)
|
|
4
|
+
|
|
5
|
+
## Finding
|
|
6
|
+
|
|
7
|
+
Verified Background.render output against EA reference:
|
|
8
|
+
EA: <g style="fill:#FFFFFF;fill-opacity:1.00;">
|
|
9
|
+
Ours: <g style="fill:#FFFFFF;fill-opacity:1.00;">
|
|
10
|
+
|
|
11
|
+
MATCH. No change needed.
|
|
12
|
+
|
|
13
|
+
## Files changed
|
|
14
|
+
|
|
15
|
+
None.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# 49 - Render All Sample Diagrams Integration Test
|
|
2
|
+
|
|
3
|
+
## Status: DEFERRED
|
|
4
|
+
|
|
5
|
+
## Decision
|
|
6
|
+
|
|
7
|
+
The visual_regression_spec.rb already renders many diagrams
|
|
8
|
+
from the plateau XMI. Adding a new spec for examples/exports/*
|
|
9
|
+
would duplicate the test surface without adding new coverage
|
|
10
|
+
until QEA loader is wired (for style_ex).
|
|
11
|
+
|
|
12
|
+
Deferred until QEA wiring or when specific sample diagrams
|
|
13
|
+
need targeted testing.
|
|
14
|
+
|
|
15
|
+
## Files changed
|
|
16
|
+
|
|
17
|
+
None.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 50 - SVG Emitter Architecture Documentation
|
|
2
|
+
|
|
3
|
+
## Status: ANALYZED (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Architecture summary
|
|
6
|
+
|
|
7
|
+
Document
|
|
8
|
+
└─ LayerSequencer (frame?, theme via diagram.style_ex)
|
|
9
|
+
├─ Background
|
|
10
|
+
├─ DiagramFrame (opt-in)
|
|
11
|
+
├─ Elements → Element::* compartment renderers
|
|
12
|
+
│ ├─ ShapeRenderer → TextRenderer
|
|
13
|
+
│ ├─ HeaderRenderer → TextRenderer
|
|
14
|
+
│ ├─ DividerRenderer
|
|
15
|
+
│ ├─ AttributeRenderer → TextRenderer
|
|
16
|
+
│ ├─ OperationRenderer → TextRenderer
|
|
17
|
+
│ └─ EnumerationLiteralRenderer → TextRenderer
|
|
18
|
+
├─ Connectors → Layer
|
|
19
|
+
├─ Markers → Marker::Registry (OCP) → Layer
|
|
20
|
+
└─ Labels → TextRenderer
|
|
21
|
+
|
|
22
|
+
Cross-cutting:
|
|
23
|
+
Canvas (value object, translate_x/y)
|
|
24
|
+
BoundsCalculator (3 source strategies)
|
|
25
|
+
ColorResolver (BCol → theme → stereotype → default)
|
|
26
|
+
FontResolver (element → theme → diagram → locale)
|
|
27
|
+
Theme / ThemeRegistry (OCP)
|
|
28
|
+
TextRenderer (decimal coords + rotation transform)
|
|
29
|
+
Style (centralized constants)
|
|
30
|
+
|
|
31
|
+
## Files changed
|
|
32
|
+
|
|
33
|
+
None — documented in TODO.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 51 - Promote Theme to Ea::Theme Top-Level Namespace
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
Theme is currently `Ea::Svg::EaEmitter::Theme` — buried inside the
|
|
8
|
+
SVG emitter. But Theme is a DOMAIN concept (visual style), not
|
|
9
|
+
rendering-specific. Other consumers (HTML docs, image rendering,
|
|
10
|
+
documentation generation) will also need themes.
|
|
11
|
+
|
|
12
|
+
The current placement violates MECE: Theme logic is mixed with
|
|
13
|
+
SVG rendering concerns.
|
|
14
|
+
|
|
15
|
+
## What needs to change
|
|
16
|
+
|
|
17
|
+
1. New `Ea::Theme` module at top level (in `lib/ea/theme.rb`)
|
|
18
|
+
2. Move `Ea::Svg::EaEmitter::Theme` → `Ea::Theme::Definition`
|
|
19
|
+
3. Move `Ea::Svg::EaEmitter::ThemeRegistry` → `Ea::Theme::Registry`
|
|
20
|
+
4. Move `Ea::Svg::EaEmitter::ThemeColors` → merge into Definition
|
|
21
|
+
5. Backward-compat aliases in EaEmitter (temporary)
|
|
22
|
+
|
|
23
|
+
## Acceptance
|
|
24
|
+
|
|
25
|
+
- Ea::Theme module exists with autoloads for Definition, Registry
|
|
26
|
+
- Ea::Svg::EaEmitter::Theme aliases to Ea::Theme::Definition
|
|
27
|
+
- All existing specs pass
|
|
28
|
+
- New spec verifies the namespace move
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 52 - Theme::Definition with Integrated Fills
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
`ThemeColors` is a separate module mapping classifier types to
|
|
8
|
+
fill colors. This is a Theme concern — the colors ARE part of the
|
|
9
|
+
theme definition. Currently they're scattered across two modules.
|
|
10
|
+
|
|
11
|
+
## What needs to change
|
|
12
|
+
|
|
13
|
+
1. `Ea::Theme::Definition` gains a `fills` attribute (Hash:
|
|
14
|
+
classifier class name → hex color)
|
|
15
|
+
2. `#fill_for(classifier)` method on Definition returns the
|
|
16
|
+
per-type fill or nil
|
|
17
|
+
3. `#with(**overrides)` method returns a new Definition with the
|
|
18
|
+
specified fields overridden (immutable editing pattern)
|
|
19
|
+
4. Built-in :default and :119 themes include their fills inline
|
|
20
|
+
|
|
21
|
+
## Acceptance
|
|
22
|
+
|
|
23
|
+
- Definition has `fills` Hash attribute
|
|
24
|
+
- Definition#fill_for(classifier) returns correct color per type
|
|
25
|
+
- Definition#with(**overrides) returns new Definition
|
|
26
|
+
- All existing specs pass
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# 53 - Theme::Registry with YAML Loading
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
Current `ThemeRegistry` has built-in themes hard-coded as Ruby
|
|
8
|
+
constants. Like `stereotype_colors.yml`, themes should be
|
|
9
|
+
externalized to YAML files for easy editing.
|
|
10
|
+
|
|
11
|
+
## What needs to change
|
|
12
|
+
|
|
13
|
+
1. `Ea::Theme::Loader` loads a YAML file into a Definition
|
|
14
|
+
2. `Ea::Theme::Registry.load_dir(path)` loads all themes from
|
|
15
|
+
a directory (one YAML file per theme)
|
|
16
|
+
3. `config/themes/` directory holds theme definition files:
|
|
17
|
+
- `default.yml` — no theme (uses element-stored values)
|
|
18
|
+
- `119.yml` — Carlito 7pt, gray text, purple-gray borders
|
|
19
|
+
4. Registry auto-loads from `config/themes/` on first access
|
|
20
|
+
|
|
21
|
+
## YAML format
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
id: "119"
|
|
25
|
+
name: EA White Theme
|
|
26
|
+
font:
|
|
27
|
+
family: Carlito
|
|
28
|
+
size: 7
|
|
29
|
+
unit: pt
|
|
30
|
+
text:
|
|
31
|
+
color: "#595959"
|
|
32
|
+
weight_normal: 0
|
|
33
|
+
weight_bold: 700
|
|
34
|
+
border:
|
|
35
|
+
color: "#9A8484"
|
|
36
|
+
stroke_width: 1
|
|
37
|
+
fills:
|
|
38
|
+
Klass: "#FDFAF7"
|
|
39
|
+
Interface: "#F1ECFA"
|
|
40
|
+
DataType: "#FAF9E6"
|
|
41
|
+
Enumeration: "#E8FDE3"
|
|
42
|
+
PrimitiveType: "#FAF9E6"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Acceptance
|
|
46
|
+
|
|
47
|
+
- config/themes/default.yml and 119.yml exist
|
|
48
|
+
- Registry.load_dir loads them
|
|
49
|
+
- YAML format matches Definition fields
|
|
50
|
+
- New spec covers YAML loading
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# 54 - Diagram#theme and #theme= API
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
Currently `Diagram` has `theme_id` (string from style_ex) but
|
|
8
|
+
no way to get or set the resolved Theme Definition object. Users
|
|
9
|
+
cannot:
|
|
10
|
+
- Get the active theme: `diagram.theme`
|
|
11
|
+
- Set a theme: `diagram.theme = :119`
|
|
12
|
+
- Override theme on a specific diagram: `diagram.theme = custom_def`
|
|
13
|
+
|
|
14
|
+
## What needs to change
|
|
15
|
+
|
|
16
|
+
1. `Diagram#theme` — returns resolved Definition:
|
|
17
|
+
- theme_override if set
|
|
18
|
+
- Registry.lookup(theme_id) otherwise
|
|
19
|
+
- Registry::DEFAULT if neither
|
|
20
|
+
2. `Diagram#theme=(value)` — accepts:
|
|
21
|
+
- `Ea::Theme::Definition` instance → sets theme_override
|
|
22
|
+
- String ID (":119") → sets theme_id, clears override
|
|
23
|
+
- Symbol ID (:119) → sets theme_id, clears override
|
|
24
|
+
3. `Diagram#theme_override` — stores explicit Definition
|
|
25
|
+
4. JSON mapping for theme_id and theme_override
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
# Read theme
|
|
31
|
+
diagram.theme # → Ea::Theme::Definition
|
|
32
|
+
|
|
33
|
+
# Set by ID
|
|
34
|
+
diagram.theme = :119
|
|
35
|
+
diagram.theme = ":119"
|
|
36
|
+
|
|
37
|
+
# Set custom definition
|
|
38
|
+
diagram.theme = Ea::Theme::Definition.new(id: "custom", ...)
|
|
39
|
+
|
|
40
|
+
# Edit existing theme (immutable → new instance)
|
|
41
|
+
diagram.theme = diagram.theme.with(text_color: "#FF0000")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Acceptance
|
|
45
|
+
|
|
46
|
+
- Diagram#theme returns Definition
|
|
47
|
+
- Diagram#theme= accepts Definition, String, Symbol
|
|
48
|
+
- Diagram#theme_override stores explicit Definition
|
|
49
|
+
- JSON round-trip preserves theme_id and theme_override
|
|
50
|
+
- New specs cover all access patterns
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 55 - Update EaEmitter to Use Ea::Theme Namespace
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
After promoting Theme to Ea::Theme (TODO 51), the EaEmitter must
|
|
8
|
+
reference the new paths. ColorResolver, FontResolver, Elements,
|
|
9
|
+
and LayerSequencer all reference `ThemeRegistry.lookup(diagram.theme_id)`.
|
|
10
|
+
|
|
11
|
+
## What needs to change
|
|
12
|
+
|
|
13
|
+
1. All `Ea::Svg::EaEmitter::ThemeRegistry` → `Ea::Theme::Registry`
|
|
14
|
+
2. All `Ea::Svg::EaEmitter::Theme` → `Ea::Theme::Definition`
|
|
15
|
+
3. `Diagram#theme` (from TODO 54) replaces `ThemeRegistry.lookup(diagram.theme_id)`
|
|
16
|
+
4. ColorResolver and FontResolver accept `Definition` directly
|
|
17
|
+
5. Keep backward-compat aliases in EaEmitter (deprecated)
|
|
18
|
+
|
|
19
|
+
## Acceptance
|
|
20
|
+
|
|
21
|
+
- EaEmitter references Ea::Theme::*
|
|
22
|
+
- diagram.theme used everywhere (replacing manual Registry lookup)
|
|
23
|
+
- All existing specs pass
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# 56 - Theme Definition YAML Files
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
Theme definitions should be in human-editable YAML files (like
|
|
8
|
+
`stereotype_colors.yml`), not hard-coded Ruby constants.
|
|
9
|
+
|
|
10
|
+
## What needs to change
|
|
11
|
+
|
|
12
|
+
1. `config/themes/default.yml` — no theme override
|
|
13
|
+
2. `config/themes/119.yml` — EA White Theme (Carlito 7pt)
|
|
14
|
+
3. Both follow the YAML format defined in TODO 53
|
|
15
|
+
4. Ea::Theme::Loader auto-loads from config/themes/ on first
|
|
16
|
+
Registry access
|
|
17
|
+
|
|
18
|
+
## default.yml
|
|
19
|
+
|
|
20
|
+
```yaml
|
|
21
|
+
id: default
|
|
22
|
+
name: Default (element-stored values)
|
|
23
|
+
font:
|
|
24
|
+
family: null
|
|
25
|
+
size: null
|
|
26
|
+
unit: px
|
|
27
|
+
text:
|
|
28
|
+
color: "#000000"
|
|
29
|
+
weight_normal: 400
|
|
30
|
+
weight_bold: 700
|
|
31
|
+
border:
|
|
32
|
+
color: "#000000"
|
|
33
|
+
stroke_width: 2
|
|
34
|
+
fills: {}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 119.yml
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
id: "119"
|
|
41
|
+
name: EA White Theme
|
|
42
|
+
font:
|
|
43
|
+
family: Carlito
|
|
44
|
+
size: 7
|
|
45
|
+
unit: pt
|
|
46
|
+
text:
|
|
47
|
+
color: "#595959"
|
|
48
|
+
weight_normal: 0
|
|
49
|
+
weight_bold: 700
|
|
50
|
+
border:
|
|
51
|
+
color: "#9A8484"
|
|
52
|
+
stroke_width: 1
|
|
53
|
+
fills:
|
|
54
|
+
Ea::Model::Klass: "#FDFAF7"
|
|
55
|
+
Ea::Model::Interface: "#F1ECFA"
|
|
56
|
+
Ea::Model::DataType: "#FAF9E6"
|
|
57
|
+
Ea::Model::Enumeration: "#E8FDE3"
|
|
58
|
+
Ea::Model::PrimitiveType: "#FAF9E6"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Acceptance
|
|
62
|
+
|
|
63
|
+
- Both YAML files exist and parse correctly
|
|
64
|
+
- Loader loads them into Registry
|
|
65
|
+
- Registry.lookup("119") returns Definition with all fields
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 57 - Theme Specs and Integration Test
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
The Theme refactor (TODO 51-56) is a major architectural change.
|
|
8
|
+
Comprehensive specs are needed to verify:
|
|
9
|
+
1. YAML loading
|
|
10
|
+
2. Definition immutability + #with
|
|
11
|
+
3. Registry OCP (register new themes)
|
|
12
|
+
4. Diagram#theme API (get/set/override)
|
|
13
|
+
5. Integration: render with custom theme
|
|
14
|
+
|
|
15
|
+
## What needs to change
|
|
16
|
+
|
|
17
|
+
1. `spec/ea/theme/definition_spec.rb` — value object behavior
|
|
18
|
+
2. `spec/ea/theme/registry_spec.rb` — registry + YAML loading
|
|
19
|
+
3. `spec/ea/theme/loader_spec.rb` — YAML parsing
|
|
20
|
+
4. `spec/ea/model/diagram_theme_spec.rb` — Diagram#theme API
|
|
21
|
+
5. Integration spec: render with custom theme, verify output
|
|
22
|
+
|
|
23
|
+
## Acceptance
|
|
24
|
+
|
|
25
|
+
- All spec files created with comprehensive coverage
|
|
26
|
+
- >90% line coverage on Ea::Theme::*
|
|
27
|
+
- All existing specs pass
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 58 - EA::Ea.rb Entry Point Autoload for Theme
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
`Ea::Theme` is a new top-level namespace. It needs proper autoload
|
|
8
|
+
registration in `lib/ea.rb` (the gem entry point).
|
|
9
|
+
|
|
10
|
+
## What needs to change
|
|
11
|
+
|
|
12
|
+
1. `lib/ea/theme.rb` — module entry file with autoloads
|
|
13
|
+
2. `lib/ea.rb` adds `autoload :Theme, "ea/theme"`
|
|
14
|
+
3. All Theme sub-files follow autoload pattern
|
|
15
|
+
|
|
16
|
+
## Acceptance
|
|
17
|
+
|
|
18
|
+
- `require "ea"` makes `Ea::Theme::*` available
|
|
19
|
+
- No require_relative in any Theme file
|
|
20
|
+
- All autoloads defined in `lib/ea/theme.rb`
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# 59 - Thread Theme Through All Renderers
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
Only `Elements` consults `diagram.theme`. Four other renderers
|
|
8
|
+
hardcode values:
|
|
9
|
+
- `Labels` — hardcodes Yu Gothic UI 13px, #000000 fill
|
|
10
|
+
- `DiagramFrame` — hardcodes Calibri 7pt, #000000 fill
|
|
11
|
+
- `Connectors` — hardcodes stroke-width:2 via Style constant
|
|
12
|
+
- `Markers` — hardcodes stroke-width:2 via Style constant
|
|
13
|
+
|
|
14
|
+
Theme :119 needs sw=1, Carlito 7pt, #595959 text everywhere.
|
|
15
|
+
|
|
16
|
+
## What needs to change
|
|
17
|
+
|
|
18
|
+
1. `LayerSequencer` reads `diagram.theme` and passes to all
|
|
19
|
+
child renderers via constructor param.
|
|
20
|
+
2. Labels gains `theme:` → uses theme.font_family / text_color
|
|
21
|
+
3. DiagramFrame gains `theme:` → uses theme.font_family / text_color
|
|
22
|
+
4. Connectors/Markers gain `theme:` → use theme.stroke_width
|
|
23
|
+
|
|
24
|
+
## Acceptance
|
|
25
|
+
|
|
26
|
+
- All renderers receive and use theme
|
|
27
|
+
- Theme :119 diagrams render all text in #595959
|
|
28
|
+
- All connector lines render at sw=1 when themed
|
|
29
|
+
- Existing specs pass
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# 60 - CLI --theme Option for ea svg Command
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
The `ea svg NAME FILE` CLI command renders a diagram. Users
|
|
8
|
+
cannot override the theme from the command line. Adding a
|
|
9
|
+
`--theme=ID` flag lets users test different themes without
|
|
10
|
+
modifying the QEA/XMI source.
|
|
11
|
+
|
|
12
|
+
## What needs to change
|
|
13
|
+
|
|
14
|
+
1. `Ea::Cli::Command::Svg` accepts `--theme=ID` option
|
|
15
|
+
2. When provided, sets `diagram.theme = ID` before rendering
|
|
16
|
+
3. `--theme=default` resets to no-theme
|
|
17
|
+
4. `--theme=list` prints available theme IDs
|
|
18
|
+
|
|
19
|
+
## Acceptance
|
|
20
|
+
|
|
21
|
+
- `ea svg MyDiagram model.xmi --theme=119` works
|
|
22
|
+
- `ea svg MyDiagram model.xmi --theme=list` lists themes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 61 - Theme Definition Validation
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
`Ea::Theme::Definition.new` accepts any values without
|
|
8
|
+
validation. Invalid data (malformed hex, negative font_size,
|
|
9
|
+
nil required fields) produces silently broken rendering.
|
|
10
|
+
|
|
11
|
+
## What needs to change
|
|
12
|
+
|
|
13
|
+
1. `Definition#initialize` validates:
|
|
14
|
+
- id is non-empty string
|
|
15
|
+
- colors match /^#[0-9A-Fa-f]{6}$/
|
|
16
|
+
- font_size is nil or positive integer
|
|
17
|
+
- stroke_width is positive integer
|
|
18
|
+
- text_weight_normal/bold are integers
|
|
19
|
+
2. Raises `ArgumentError` with descriptive message on violation
|
|
20
|
+
3. Skip validation when loading from YAML (trust source) — use
|
|
21
|
+
`Definition.new(..., validate: false)` or `Definition.from_hash`
|
|
22
|
+
|
|
23
|
+
## Acceptance
|
|
24
|
+
|
|
25
|
+
- Invalid hex raises ArgumentError
|
|
26
|
+
- Negative font_size raises ArgumentError
|
|
27
|
+
- Empty id raises ArgumentError
|
|
28
|
+
- Valid Definition passes without error
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 62 - Theme Builder DSL
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
Creating themes programmatically via `Definition.new(id:..., font_family:..., ...)`
|
|
8
|
+
is verbose. A builder DSL provides a more ergonomic, intention-revealing API.
|
|
9
|
+
|
|
10
|
+
## Proposed API
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
Ea::Theme.build("my_theme", name: "My Theme") do |t|
|
|
14
|
+
t.font family: "Arial", size: 12, unit: "px"
|
|
15
|
+
t.text color: "#333333", weight_normal: 400
|
|
16
|
+
t.border color: "#666666", stroke_width: 1
|
|
17
|
+
t.fill "Ea::Model::Klass" => "#F0F0F0"
|
|
18
|
+
end
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## What needs to change
|
|
22
|
+
|
|
23
|
+
1. `Ea::Theme.build(id, name: nil)` yields a builder
|
|
24
|
+
2. Builder methods set attributes
|
|
25
|
+
3. Returns a Definition registered in Registry
|
|
26
|
+
|
|
27
|
+
## Acceptance
|
|
28
|
+
|
|
29
|
+
- DSL creates valid Definition
|
|
30
|
+
- Definition is registered for lookup
|
|
31
|
+
- New spec covers DSL usage
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# 63 - Theme Integration Rendering Spec
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
The theme system has unit specs but no end-to-end integration
|
|
8
|
+
test verifying that a themed diagram renders with the correct
|
|
9
|
+
font, colors, and stroke widths in the SVG output.
|
|
10
|
+
|
|
11
|
+
## What needs to change
|
|
12
|
+
|
|
13
|
+
1. Spec loads simple.qea/model.xml
|
|
14
|
+
2. Sets diagram.theme = "119"
|
|
15
|
+
3. Renders via Ea::Svg::EaEmitter::Document
|
|
16
|
+
4. Parses SVG output and asserts:
|
|
17
|
+
- Text fill is #595959 (not #000000)
|
|
18
|
+
- Element stroke is #9A8484 (not #000000)
|
|
19
|
+
- Stroke-width is 1 (not 2)
|
|
20
|
+
- Font-family is Carlito (not Calibri)
|
|
21
|
+
|
|
22
|
+
## Acceptance
|
|
23
|
+
|
|
24
|
+
- Integration spec verifies all theme attributes in rendered SVG
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# 64 - Theme Write-Back to StyleEx
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
When `diagram.theme = :119` is called, the theme_override_id is
|
|
8
|
+
set in memory. There's no way to persist this back to the QEA's
|
|
9
|
+
`t_diagram.StyleEx` field.
|
|
10
|
+
|
|
11
|
+
## What needs to change
|
|
12
|
+
|
|
13
|
+
1. `Diagram#to_style_ex` — serializes style_ex_flags back to
|
|
14
|
+
`Key=Value;` format, merging theme_id into existing flags
|
|
15
|
+
2. QEA writer (when implemented) uses this to write back
|
|
16
|
+
3. Diagram#apply_theme_to_style_ex — mutates style_ex in-place
|
|
17
|
+
|
|
18
|
+
## Acceptance
|
|
19
|
+
|
|
20
|
+
- Diagram.to_style_ex produces valid StyleEx string
|
|
21
|
+
- Theme ID round-trips through to_style_ex → from_style_ex
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# 65 - Remove Dead EaEmitter Theme Files
|
|
2
|
+
|
|
3
|
+
## Status: DONE (2026-07-26)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
After promoting Theme to Ea::Theme::*, the old files remain:
|
|
8
|
+
- `lib/ea/svg/ea_emitter/theme.rb`
|
|
9
|
+
- `lib/ea/svg/ea_emitter/theme_registry.rb`
|
|
10
|
+
- `lib/ea/svg/ea_emitter/theme_colors.rb`
|
|
11
|
+
|
|
12
|
+
These are no longer loaded (autoloads removed, replaced with
|
|
13
|
+
constant aliases). They're dead code sitting on disk.
|
|
14
|
+
|
|
15
|
+
## What needs to change
|
|
16
|
+
|
|
17
|
+
The EaEmitter module file now uses aliases:
|
|
18
|
+
```ruby
|
|
19
|
+
Theme = ::Ea::Theme::Definition
|
|
20
|
+
ThemeRegistry = ::Ea::Theme::Registry
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The old physical files should be marked as deprecated or removed.
|
|
24
|
+
Per the user's "NEVER DELETE FILES" rule, mark as deprecated with
|
|
25
|
+
a pointer to the new location, don't delete.
|
|
26
|
+
|
|
27
|
+
## Acceptance
|
|
28
|
+
|
|
29
|
+
- Old files have deprecation notice
|
|
30
|
+
- No code loads them
|