skanaar / nomnoml

The sassy UML diagram renderer
https://www.nomnoml.com
MIT License
2.66k stars 208 forks source link

Feature request: Allow for classes in frames to reference one another. #158

Closed SuperSonicHub1 closed 2 years ago

SuperSonicHub1 commented 2 years ago

I'll be referring to this example throughout this issue.

[<frame> Trash Taste; a weekly anime and lifestyle podcast|
    [CDawgVA]
    [Gigguk]
    [The Anime Man]
]

[<frame> VShojo; a VTuber company|
    [Ironmouse] -> collaborator [CDawgVA]
]

Currently in nomnoml, classes within frames cannot have associations with other frames. The Ironmouse class in the VShojo frame has no idea that the CDawgVA class in the Trash Taste frame exists, and so a CDawgVA class is created in the VShojo frame. This makes it hard to symbolize, say, connections between people in different organizations. I think there are two possible solutions to this problem.

Singletons

Inspired by the singleton pattern in object-oriented programming, you could add a singleton directive to the nomnoml syntax, which would make all further references to an object with the same type and name point to that object.

// Create a singleton...

[<frame> Trash Taste|
    [<singleton> CDawgVA]
]

// and now all objects with the same name will reference it.
[Ironmouse] -> collaborator [CDawgVA] // Equivalent to the same CDawgVA above.

// This works with other types as well.

[<frame> Example Frame|
    [<singleton:actor> John Doe]
]

[<actor> Jane Doe] -> married to [<actor> John Doe]

Indexing

Inspired by dictionaries, nomnoml could introduce a special root type and an indexing syntax, so that any object in a diagram can be referenced from anywhere. Obviously, we don't want to deal with recursion, so a root class wouldn't be able to refer to itself nor not be indexed.

[<frame> Trash Taste|
    [<singleton> CDawgVA]
]

[Ironmouse] -> collaborator [<root>][<frame> Trash Taste][CDawgVA] // Equivalent to the same CDawgVA above.

// This *could* be valid, as both the frame and Ironmouse are on the same depth but would likely be confusing very quickly.
[Ironmouse] -> collaborator [<frame> Trash Taste][CDawgVA] 

// This is invalid.
[John] -> [<root>]

// This is also invalid.
[<root>] -> [<root>]

I want this feature as I'm using nomnoml to document the relationships between people in organizations, which is a bit outside of this program's wheelhouse but could definitely see it being useful for writing pseudocode with the diagrams, such as calling a method of a class inside a package or module. If you'd want me to help you with adding such a feature, I'd be glad to.

skanaar commented 2 years ago

This is a common request and there is a discussion here #6. I really appreciate the detailed proposed solutions that you have provided.