diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 609e6d883..34cb7567f 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -750,27 +750,31 @@ func (c *compiler) validateNear(g *d2graph.Graph) { continue } - var edgeConnectToOutsideOfNear *d2graph.Edge - for _, edge := range g.Edges { - srcNearContainer := edge.Src.OuterNearContainer() - dstNearContainer := edge.Dst.OuterNearContainer() - - if srcNearContainer != dstNearContainer { - edgeConnectToOutsideOfNear = edge - break - } - } - - if edgeConnectToOutsideOfNear != nil { - c.errorf(edgeConnectToOutsideOfNear.References[0].Edge, "cannot connect objects from within a container, that has near constant set, to objects outside that container") - continue - } } else { c.errorf(obj.Attributes.NearKey, "near key %#v must be the absolute path to a shape or one of the following constants: %s", d2format.Format(obj.Attributes.NearKey), strings.Join(d2graph.NearConstantsArray, ", ")) continue } } } + + for _, edge := range g.Edges { + srcNearContainer := edge.Src.OuterNearContainer() + dstNearContainer := edge.Dst.OuterNearContainer() + + var isSrcNearConst, isDstNearConst bool + + if srcNearContainer != nil { + _, isSrcNearConst = d2graph.NearConstants[d2graph.Key(srcNearContainer.Attributes.NearKey)[0]] + } + if dstNearContainer != nil { + _, isDstNearConst = d2graph.NearConstants[d2graph.Key(dstNearContainer.Attributes.NearKey)[0]] + } + + if (isSrcNearConst || isDstNearConst) && srcNearContainer != dstNearContainer { + c.errorf(edge.References[0].Edge, "cannot connect objects from within a container, that has near constant set, to objects outside that container") + } + } + } func (c *compiler) validateBoardLinks(g *d2graph.Graph) { diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 6814f2f5b..76d241451 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -970,7 +970,8 @@ func (obj *Object) GetDefaultSize(mtexts []*d2target.MText, ruler *textmeasure.R func (obj *Object) OuterNearContainer() *Object { temp := obj - for temp != nil { + // find outer near container that isn't itself + for temp != nil && temp != obj { if temp.Attributes.NearKey != nil { return temp }