startsub / includesub example in documentation behaves differently than current stable release

0 votes
asked Feb 20, 2020 in Bug by Tarik Idris

I was trying to include a simplified view of a complex component in a higher-level component diagram. To achieve this, I attempted to use startsub / includesub as described in the documentation (https://plantuml.com/en/preprocessing):

You can also use !startsub NAME and !endsub to indicate sections of text to include from other files using !includesub. For example:

file1.puml:

@startuml

A -> A : stuff1
!startsub BASIC
B -> B : stuff2
!endsub
C -> C : stuff3
!startsub BASIC
D -> D : stuff4
!endsub
@enduml

file1.puml would be rendered exactly as if it were:

@startuml

A -> A : stuff1
B -> B : stuff2
C -> C : stuff3
D -> D : stuff4
@enduml

However, this would also allow you to have another file2.puml like this:

file2.puml

@startuml

title this contains only B and D
!includesub file1.puml!BASIC
@enduml

This file would be rendered exactly as if:

@startuml

title this contains only B and D
B -> B : stuff2
D -> D : stuff4
@enduml

 Now my main problem is that I don't see D->D: stuff4. The resulting diagram only contains the first part "B->B: stuff2". I have updated to the most recent version (plantuml.1.2020.1.jar) but have not seen a change.

Since my diagram has multiple interfaces in multiple components that I want to include in some views but not others, the documented behavior would be ideal for me. Using multiple different subs (BASIC, BASIC2, ...) would be to cumbersome. The only real workaround I have found is to define a variabel and then use if statements to switch the unwanted interfaces off. But this doesn't work very well, since the diagram does not render unless you define the variable.

2 Answers

0 votes
answered Feb 20, 2020 by plantuml (257,860 points)

Ok, I confirm that the "D" part is not present and that this is a bug.

Actually, this "subs" feature is an old one, that we support only for backward compatibiliy. We're going to fix it anyway.

If you think about a new and better syntax to achieve your goal, please give us some idea !

But this doesn't work very well, since the diagram does not render unless you define the variable.

Not sure to understand this one. Could you give a short example that show the issue ? (So that we could also fix it).

0 votes
answered Feb 21, 2020 by plantuml (257,860 points)

Ok, so this should be fixed in last beta http://beta.plantuml.net/plantuml.jar

Tell us if it's not working for you!

But this doesn't work very well, since the diagram does not render unless you define the variable.

We are still interested by a short example here : I think there is something wrong that we should fix... Thanks!

commented Feb 21, 2020 by Tarik Idris

Hi, thanks for the quick response! This works as expected now.

Let me elaborate on my variable issue.
I rewrote the example using my variable approach:

test.iuml:
@startuml
A -> A : stuff1
!if ($with_details=="true")
B -> B : stuff2
!endif
C -> C : stuff3
!if ($with_details=="true")
D -> D : stuff4
!endif
@enduml

test_main.iuml:
@startuml
!$with_details="false"
!include test.iuml
@enduml

This works, i.e. it shows stuff2 and stuff4. It would be a decent workaround, if I could render test.iuml while working on it. But when my IDE tries to render test.iuml, it throws an error because $with_details is not defined ("Unknown variable $with_details"). So to see my updates rendered, I have to switch to test_main.uml.
I tried defining $with_details in test.iuml already, but it overrides anything I do in the "including" file test_main.iuml. So if test.iuml includes the instruction !$with_details="true", I can render the detailled file test.iuml while working on it, but test_main.iuml will always render the whole thing (stuff1, stuff2, stuff3 and stuff4).

You also asked for an alternative syntax to achieve my goal. I am trying to create an arc42-based architecture documentation and want to use PlantUML component diagrams for the building blocks. This is a hierarchy and I want to hide the details on the higher levels.
Ideally, I would like to "collapse" a package with multiple sub-components into a component. Similarly, I would also like to be able to include all components from a file without their interfaces. A syntax that could possibly tackle both issues at once, would be to add a list of "type conversions" to an include preprocessing instruction, e.g.
!includeTransformed test.iuml(Package->Component, Interfaces->Comment)
I have no idea how feasible this is though, so feel free to ignore me. Also, the fixed includesub will already adress most of my problem. 

Thanks again for the great support!
 

commented Feb 21, 2020 by plantuml (257,860 points)

Ok, thanks for the explanation.

So we've build yet another beta :-)

http://beta.plantuml.net/plantuml.jar

In tests, if some variable does not exist, its value is set to "undefined".

So you can safely have now :

@startuml
A -> A : stuff1
!log foo $with_details
!if ($with_details=="true")
B -> B : stuff2
!endif
C -> C : stuff3
!if ($with_details=="true")
D -> D : stuff4
!endif
!if ($with_details=="undefined")
D -> D : with_details is undefined
!endif
@enduml

Is this what you were expecting ?

About type conversion, we *could* extend !include syntax to allow :

!include test.iuml[Package=>Component][Interfaces=>Comment]

When "test.iuml" will be included, we will replace strings. Note that this would be a raw replacement (like a global "search and replace"). What do you think about it ?

commented Feb 21, 2020 by Tarik Idris

Works great. So I have 2 options to create alternative versions of a diagram now.
Thanks again, you guys are awesome!

About type conversion, we *could* extend !include syntax to allow :

!include test.iuml[Package=>Component][Interfaces=>Comment]

When "test.iuml" will be included, we will replace strings. Note that this would be a raw replacement (like a global "search and replace"). What do you think about it ?

It wouldn't really help with my use case. The syntax for packages and components is to different. But don't worry, that use case isn't particularly important and there are enough ways to do this with little redundancy. I get the feeling that my suggested syntax would require plantUML to be something it is not (i.e. less about fluidly expressing diagrams using text and more about understanding classes, components and structures like more heavy weight UML software does).

...