ea 0.6.108 → 0.6.109
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/lib/ea/diagram/display_config.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/enum_literals.rb +8 -37
- data/lib/ea/svg/ea_emitter/compartment/operations.rb +2 -1
- data/lib/ea/svg/ea_emitter/element/compartment_geometry.rb +2 -3
- data/lib/ea/svg/ea_emitter/element/header_line_provider/name.rb +9 -14
- data/lib/ea/svg/ea_emitter/element/operation_renderer.rb +18 -8
- data/lib/ea/svg/ea_emitter/elements.rb +6 -5
- data/lib/ea/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: db09c594a106072a0600df4d18a9db32ac9823fe348d903440639946d4bbbc25
|
|
4
|
+
data.tar.gz: e39606ab7c251e044d5f1918e624a088d4c812503a5899d5c2ce1bd2bf04b6f6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8631b532ab58510c40589b8918fab7c03ec36f9c838a8497e985f38588b039c8ee1b77fba537506285d1b3771af156f44a7daf2824a335a4ae6514be6793b156
|
|
7
|
+
data.tar.gz: 7f5e2eea1b46aa5ac9dc60e0d9a74e693bc7e47d965a46948c2621fcc9c4a9775732ffb2aab5c1b3c6a0a59806aab713eb64ae1cacd08d8e063bfe7f19b4ef2f
|
|
@@ -101,6 +101,11 @@ module Ea
|
|
|
101
101
|
style_flags["OpParams"] != "0"
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
+
# Type-only parameter detail is stored as OpParams=1.
|
|
105
|
+
def operation_parameter_detail
|
|
106
|
+
:type_only if style_flags["OpParams"] == "1"
|
|
107
|
+
end
|
|
108
|
+
|
|
104
109
|
# Element Alias instead of Name in the header. Defaults to false
|
|
105
110
|
# — most diagrams show the Name.
|
|
106
111
|
def use_alias?
|
|
@@ -6,13 +6,11 @@ module Ea
|
|
|
6
6
|
module Compartment
|
|
7
7
|
# Enumeration literal compartment: divider line + "literals"
|
|
8
8
|
# italic header + each literal name. Skipped when the
|
|
9
|
-
# classifier has no literals or
|
|
9
|
+
# classifier has no literals or no content geometry.
|
|
10
10
|
module EnumLiterals
|
|
11
11
|
module_function
|
|
12
12
|
|
|
13
|
-
#
|
|
14
|
-
# 13px apart at 7pt (attr rows use 14), first row at
|
|
15
|
-
# divider + 14. No compartment divider, no header label.
|
|
13
|
+
# Caption and literal rows share the same baseline spacing.
|
|
16
14
|
LITERAL_LINE_OFFSET = 6
|
|
17
15
|
|
|
18
16
|
def render(context)
|
|
@@ -29,16 +27,8 @@ module Ea
|
|
|
29
27
|
)
|
|
30
28
|
text_blocks = []
|
|
31
29
|
row_y = context.geometry.enum_literal_first_y
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# (t_attribute.Default); bare literal lists render the
|
|
35
|
-
# rows directly. Corpus-verified (PT_TypeOfSA:
|
|
36
|
-
# "literals" caption + "ServingParcel = SP" rows;
|
|
37
|
-
# CV_SequenceType: bare rows, no caption).
|
|
38
|
-
if caption?(context)
|
|
39
|
-
text_blocks << caption_text(context, row_y)
|
|
40
|
-
row_y += line_h
|
|
41
|
-
end
|
|
30
|
+
text_blocks << caption_text(context, row_y)
|
|
31
|
+
row_y += line_h
|
|
42
32
|
context.enum_literals.each_with_index do |literal, idx|
|
|
43
33
|
y = row_y + (idx * line_h)
|
|
44
34
|
text_blocks << visibility_placeholder(context, y)
|
|
@@ -47,28 +37,6 @@ module Ea
|
|
|
47
37
|
wrap_group(text_blocks, context.theme.text_color)
|
|
48
38
|
end
|
|
49
39
|
|
|
50
|
-
def caption?(context)
|
|
51
|
-
values_caption?(context) || grown?(context)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# EA draws the 'literals' caption on every enum box it
|
|
55
|
-
# re-lays (grown height) - corpus 8/8 grown=caption. Boxes
|
|
56
|
-
# keeping stored size keep their stored caption state,
|
|
57
|
-
# captured by the stored literal values.
|
|
58
|
-
def grown?(context)
|
|
59
|
-
stored = context.element&.bounds
|
|
60
|
-
return false unless stored
|
|
61
|
-
|
|
62
|
-
context.bounds.height > stored.height + 4
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def values_caption?(context)
|
|
66
|
-
context.enum_literals.any? do |l|
|
|
67
|
-
value = l.value.to_s
|
|
68
|
-
!value.empty? && value != l.name.to_s
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
40
|
def caption_text(context, y)
|
|
73
41
|
content = "literals"
|
|
74
42
|
len = TextRenderer.estimate_width(content, context.size, nil,
|
|
@@ -101,9 +69,12 @@ module Ea
|
|
|
101
69
|
|
|
102
70
|
def literal_name_text(context, literal, y)
|
|
103
71
|
content = literal_display(literal)
|
|
72
|
+
# EA uses the attribute row point-size increment for literal names.
|
|
73
|
+
offset = context.theme.attribute_spec.content_x_offset || 26
|
|
74
|
+
offset += 2 * (context.size - 7) if context.size_unit == "pt"
|
|
104
75
|
TextRenderer.new(
|
|
105
76
|
content: content,
|
|
106
|
-
x: context.bounds.x +
|
|
77
|
+
x: context.bounds.x + offset,
|
|
107
78
|
y: y,
|
|
108
79
|
family: context.family, size: context.size,
|
|
109
80
|
size_unit: context.size_unit, logical_height: context.logical_height,
|
|
@@ -28,7 +28,8 @@ module Ea
|
|
|
28
28
|
bounds: context.bounds,
|
|
29
29
|
first_y: context.geometry.op_first_y,
|
|
30
30
|
family: context.family, size: context.size,
|
|
31
|
-
size_unit: context.size_unit, logical_height: context.logical_height
|
|
31
|
+
size_unit: context.size_unit, logical_height: context.logical_height,
|
|
32
|
+
parameter_detail: context.diagram&.display_config&.operation_parameter_detail
|
|
32
33
|
)
|
|
33
34
|
parts.join("\n")
|
|
34
35
|
end
|
|
@@ -152,9 +152,8 @@ module Ea
|
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
# EA draws a single divider under the header and seats
|
|
155
|
-
# enumeration
|
|
156
|
-
#
|
|
157
|
-
# "literals" header. Verified against EA-published SVGs.
|
|
155
|
+
# the enumeration caption directly after it (+14 at 7pt),
|
|
156
|
+
# followed by the literal rows without a second divider.
|
|
158
157
|
def enum_literal_first_y
|
|
159
158
|
return nil unless divider_y
|
|
160
159
|
|
|
@@ -11,12 +11,9 @@ module Ea
|
|
|
11
11
|
# - Foreign elements (owning package ≠ the diagram's package,
|
|
12
12
|
# gated on t_diagram.ShowForeign) render the qualified
|
|
13
13
|
# name "OwningPackage::Name".
|
|
14
|
-
# - Qualified
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# each centered independently. Corpus-verified: every
|
|
18
|
-
# wrapped header overflows its box and every single-line
|
|
19
|
-
# header fits (tightest observed slack 6px).
|
|
14
|
+
# - Qualified names wrap after their colon separator when
|
|
15
|
+
# the measured name reaches the box width minus 6px.
|
|
16
|
+
# Each resulting line retains its separator and is centered.
|
|
20
17
|
#
|
|
21
18
|
# InstanceSpecification returns [] (InstanceSpec provider
|
|
22
19
|
# already emitted the full label).
|
|
@@ -42,9 +39,8 @@ module Ea
|
|
|
42
39
|
return [[name, weight]]
|
|
43
40
|
end
|
|
44
41
|
|
|
45
|
-
if name.
|
|
46
|
-
|
|
47
|
-
[["#{qualifier}::", weight], [base, weight]]
|
|
42
|
+
if (qualified = name.match(/\A(.+?:{1,2})([^:\s].*)\z/))
|
|
43
|
+
[[qualified[1], weight], [qualified[2], weight]]
|
|
48
44
|
else
|
|
49
45
|
HeaderLinePipeline.wrap_words(name, context, weight).map do |line|
|
|
50
46
|
[line, weight]
|
|
@@ -59,11 +55,10 @@ module Ea
|
|
|
59
55
|
family: context.family, weight: "700", style: font_style,
|
|
60
56
|
logical_height: context.logical_height
|
|
61
57
|
).round
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
len > context.bounds_width.to_i - 6
|
|
58
|
+
# Qualified classifier names also wrap at the exact boundary;
|
|
59
|
+
# ordinary word wrapping keeps the shared pipeline threshold.
|
|
60
|
+
usable = context.bounds_width.to_i - 6
|
|
61
|
+
name.match?(/:{1,2}[^:\s]/) ? len >= usable : len > usable
|
|
67
62
|
end
|
|
68
63
|
|
|
69
64
|
# EA renders the plain classifier name in element headers;
|
|
@@ -16,7 +16,8 @@ module Ea
|
|
|
16
16
|
VISIBILITY_X_OFFSET = 5
|
|
17
17
|
CONTENT_X_OFFSET = 22
|
|
18
18
|
|
|
19
|
-
def self.render(operations, bounds:, first_y:, family:, size:, size_unit: "px",
|
|
19
|
+
def self.render(operations, bounds:, first_y:, family:, size:, size_unit: "px",
|
|
20
|
+
logical_height: nil, parameter_detail: nil)
|
|
20
21
|
# EA's op rows pitch 13 (size + 6), same as attribute
|
|
21
22
|
# rows (6D4C665D: ops 541..658 step 13).
|
|
22
23
|
line_h = Ea::Fonts::Metrics.compartment_line_height(
|
|
@@ -39,14 +40,15 @@ module Ea
|
|
|
39
40
|
y = first_y + ((idx + offset) * line_h)
|
|
40
41
|
text_blocks << build_text(bounds.x + VISIBILITY_X_OFFSET, y,
|
|
41
42
|
visibility_prefix(op), family, size, size_unit, logical_height: logical_height)
|
|
43
|
+
text = operation_text(op, parameter_detail: parameter_detail)
|
|
42
44
|
text_blocks << build_text(bounds.x + AttributeRenderer.content_x_offset(size), y,
|
|
43
|
-
|
|
45
|
+
text, family, size, size_unit, logical_height: logical_height)
|
|
44
46
|
end
|
|
45
47
|
%(<g style="#{Style::TEXT_GROUP}">\n#{text_blocks.join("\n")}\n</g>)
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
# Builds display lines for a classifier's operations.
|
|
49
|
-
def self.lines_for(classifier)
|
|
51
|
+
def self.lines_for(classifier, parameter_detail: nil)
|
|
50
52
|
ops = classifier.operations
|
|
51
53
|
return [] unless ops&.any?
|
|
52
54
|
|
|
@@ -54,7 +56,7 @@ module Ea
|
|
|
54
56
|
visibility = visibility_prefix(op).strip
|
|
55
57
|
params = (op.parameters || []).map do |p|
|
|
56
58
|
type = namespace_double_colon(p.type_name)
|
|
57
|
-
p
|
|
59
|
+
parameter_text(p, type, parameter_detail)
|
|
58
60
|
end.join(", ")
|
|
59
61
|
return_type = namespace_double_colon(op.return_type_name)
|
|
60
62
|
"#{visibility} #{op.name}(#{params}): #{return_type}".strip
|
|
@@ -66,9 +68,9 @@ module Ea
|
|
|
66
68
|
end
|
|
67
69
|
private_class_method :visibility_prefix
|
|
68
70
|
|
|
69
|
-
def self.operation_text(operation)
|
|
71
|
+
def self.operation_text(operation, parameter_detail: nil)
|
|
70
72
|
prefix = operation.is_reception ? "«signal» " : ""
|
|
71
|
-
text = "#{prefix}#{operation.name}(#{reception_params(operation)})"
|
|
73
|
+
text = "#{prefix}#{operation.name}(#{reception_params(operation, parameter_detail)})"
|
|
72
74
|
return text unless operation.return_type_name && !operation.is_reception
|
|
73
75
|
|
|
74
76
|
"#{text}: #{operation.return_type_name}"
|
|
@@ -82,11 +84,19 @@ module Ea
|
|
|
82
84
|
end
|
|
83
85
|
private_class_method :namespace_double_colon
|
|
84
86
|
|
|
85
|
-
def self.
|
|
87
|
+
def self.parameter_text(param, type, parameter_detail)
|
|
88
|
+
return "#{type}*" if param.direction == "inout"
|
|
89
|
+
return type if parameter_detail == :type_only
|
|
90
|
+
|
|
91
|
+
"#{param.name}: #{type}"
|
|
92
|
+
end
|
|
93
|
+
private_class_method :parameter_text
|
|
94
|
+
|
|
95
|
+
def self.reception_params(operation, parameter_detail)
|
|
86
96
|
params = (operation.parameters || []).filter_map { |p|
|
|
87
97
|
next nil if p.type_name.to_s.empty?
|
|
88
98
|
|
|
89
|
-
p
|
|
99
|
+
parameter_text(p, p.type_name, parameter_detail)
|
|
90
100
|
}.join(", ")
|
|
91
101
|
params
|
|
92
102
|
end
|
|
@@ -144,7 +144,10 @@ module Ea
|
|
|
144
144
|
end
|
|
145
145
|
op_lines = if is_classifier && show_operations? &&
|
|
146
146
|
(operations_visible?(element) || regenerated_context?)
|
|
147
|
-
Element::OperationRenderer.lines_for(
|
|
147
|
+
Element::OperationRenderer.lines_for(
|
|
148
|
+
classifier,
|
|
149
|
+
parameter_detail: display_config.operation_parameter_detail
|
|
150
|
+
)
|
|
148
151
|
else
|
|
149
152
|
[]
|
|
150
153
|
end
|
|
@@ -440,12 +443,10 @@ module Ea
|
|
|
440
443
|
classifier.literals || []
|
|
441
444
|
end
|
|
442
445
|
|
|
443
|
-
#
|
|
444
|
-
# literal carries a stored code value.
|
|
446
|
+
# A populated literal compartment includes its caption row.
|
|
445
447
|
def enum_row_count_for(classifier)
|
|
446
448
|
literals = enum_literals_for(classifier)
|
|
447
|
-
|
|
448
|
-
literals.size + (caption ? 1 : 0)
|
|
449
|
+
literals.empty? ? 0 : literals.size + 1
|
|
449
450
|
end
|
|
450
451
|
|
|
451
452
|
def tagged_values_for(classifier)
|
data/lib/ea/version.rb
CHANGED