Hi again,
I had look at the source code and made some progress. I found out that - contrary to !include - !includesub is processed after !define are applied. Exactly what I need! That led to the following simple solution:
Rendered file:
@startuml
!define INCLUDE(FILE, ID) !includesub FILE!ID
INCLUDE(CMyClass.iuml, FuncB)
@enduml
Included file:
@startuml
!startsub FuncB
note over CMyClass: Hello from FuncB!
!endsub
@enduml
However, when trying to apply this to my actual problem, plantuml crashes (version 1.2018.08 and the beta from beta.plantuml.net uploaded 2018-07-25 15:07).
I'm trying to use the preprocessor to generate a file similar to this (image):
@startuml
SomeClass -> CMyClass: FuncA()
activate CMyClass
note over CMyClass: Hello from FuncA!
CMyClass -> CMyClass: FuncB()
activate CMyClass
note over CMyClass: Hello from FuncB!
CMyClass <-- CMyClass
deactivate CMyClass
SomeClass <-- CMyClass
deactivate CMyClass
@enduml
This is the rendered file, that I'm using:
@startuml
!definelong CALL_METHOD(_fromClass, _toClass, _func, _args = "", _return = "")
_fromClass -> _toClass: _func()
activate _toClass
!includesub _toClass.iuml!_func
_fromClass <-- _toClass: _return
deactivate _toClass
!enddefinelong
' crashes, works when CALL_METHOD in FuncA is removed
CALL_METHOD(SomeClass, CMyClass, FuncB)
' crashes
'CALL_METHOD(SomeClass, CMyClass, FuncA)
@enduml
And this is the included file CMyClass.iuml:
@startuml
!startsub FuncA
note over CMyClass: Hello from FuncA!
CALL_METHOD(CMyClass, CMyClass, FuncB)
!endsub
!startsub FuncB
note over CMyClass: Hello from FuncB!
!endsub
@enduml
This is the error message I get:
$> java -classpath .\target\classes\ net.sourceforge.plantuml.Run -tpng .\test_include.puml
Exception in thread "main" java.lang.IllegalStateException
at net.sourceforge.plantuml.preproc.Defines.saveState(Defines.java:181)
at net.sourceforge.plantuml.preproc.Preprocessor.<init>(Preprocessor.java:79)
at net.sourceforge.plantuml.preproc.SubPreprocessor.manageIncludeSub(SubPreprocessor.java:131)
at net.sourceforge.plantuml.preproc.SubPreprocessor.readLine(SubPreprocessor.java:99)
at net.sourceforge.plantuml.preproc.Preprocessor.readLine(Preprocessor.java:95)
at net.sourceforge.plantuml.preproc.SubPreprocessor.manageIncludeSub(SubPreprocessor.java:133)
at net.sourceforge.plantuml.preproc.SubPreprocessor.readLine(SubPreprocessor.java:99)
at net.sourceforge.plantuml.preproc.Preprocessor.readLine(Preprocessor.java:95)
at net.sourceforge.plantuml.BlockUmlBuilder.init(BlockUmlBuilder.java:86)
at net.sourceforge.plantuml.BlockUmlBuilder.<init>(BlockUmlBuilder.java:68)
at net.sourceforge.plantuml.SourceFileReader.<init>(SourceFileReader.java:86)
at net.sourceforge.plantuml.Run.manageFileInternal(Run.java:432)
at net.sourceforge.plantuml.Run.processArgs(Run.java:361)
at net.sourceforge.plantuml.Run.manageAllFiles(Run.java:331)
at net.sourceforge.plantuml.Run.main(Run.java:179)
Is there a way to fix this? Or even better, evaluate for !include after !define have been applied? Because this is the only reason I had to resort to !includesub instead of !include_many.
Any help is highly appreciated as I'm trying to apply plantuml to a large codebase and only this kind of preprocessor trickery would keep it managable.
BTW, plantuml is already really awesome. It's been extremely helpful to map existing architectures (I use class and sequence diagrams). Thanks a lot!