When you first see PlantUML for simple diagrams, it looks like just a simple data format. It is not. As you go from diagram type to diagram type, you see lots of alternate syntaxes. For example, any JSON object is a valid PlantUML program. It generates a visualization of the JSON.
More than that, there are mini-languages embedded in some formats. Creole, a simple formatting language, can be used to provide the content for a box in your diagram.
PlantUML also offers a powerful preprocessor with variables, functions, and procedures, loops, conditionals, etc and some diagram types (e.g. C4) are built just with these abstractions.
It seems that whenever the maintainers want to add new features, they seem to lean on more syntax and embedded parsers. The result is both that the onramp can be very gentle to non-programmers because it can look very natural. Here’s a simple sequence diagram:
@startuml
actor User
User -> A: DoWork
A -> A: Internal call
A -> B: << createRequest >>
A <-- B: RequestCreated
User <-- A: Done
@enduml
That’s great! If that’s all you want from your sequence diagrams, PlantUML syntax is very nice. I don’t even think I need to explain that syntax. But, as soon as you want more control or extra elements, it gets complicated quickly.
My sequence diagrams all use lifetime bars and show creation and deletion. There is a short-hand for all of that, and here’s an example from the reference guide.
@startuml
alice -> bob ++ : hello
bob -> bob ++ : self call
bob -> bib ++ #005500 : hello
bob -> george ** : create
return done
return rc
bob -> george !! : delete
return success
@enduml
It’s still manageable. But, it goes deeper and deeper. It’s hard for me to imagine that there’s a sequence diagram I’d want, but couldn’t get. But, there’s a lot of random, seemingly unrelated stuff I’d need to learn to get it.
I’m ok with that, because I want diagrams-as-code more than I want simple code. And I know that most of the time, the code isn’t that bad.