Please provide a way to include blocks of code from a file into itself

+1 vote
asked Mar 23, 2017 in Closed feature request by Chris38 (220 points)

I'd like to include blocks of code from a file into itself, without having to specify the actual file name.

I want to keep a single file with several diagrams, all using a few common macros.  What I have so far is something like this in my diagrams.txt file:

@startuml(id=MACROS)
/'my macros'/
@enduml

@startuml
!include diagrams.txt!MACROS
/' my diagram'/
@enduml

/'a bunch more diagrams, similar to above block'/

This works great, however, the !include relies on knowing the file name...is there a way to specify "current file"? If not, would you consider adding such a feature?

The file name is usually known, but when I embed the file in a word document and double click on it, word generates a temporary file. I don't want to have to change the name in my include directives to match the temporary file name.

Also as a hack, I have to add a title to the empty diagram (the one containing only macros) to avoid an error.

commented Jun 6, 2019 by anonymous
It does not seem to work with the preprocessor v2, correct?
commented Jun 6, 2019 by plantuml (295,000 points)
Correct. It seems that this feature has been forgotten...

We are going to re-implement it with preprocessor V2.

We'll post a message here when this will be ready.

Thanks for the feedback!
commented Jun 7, 2019 by plantuml (295,000 points)

After some more tests, it looks like

file diag1.txt:

@startuml(id=MACROS)
title MACROS
!define FOO1 bar1
!FOO2="bar2"
@enduml

@startuml
!include diag1.txt!MACROS
Alice -> Bob : FOO1
Alice -> Bob : FOO2
@enduml

is working

@startuml
title
Read from file %filename()
Path is %dirpath()
len %strlen("foo")
end title
alice->bob:hello
!include %dirpath()/foo1.txt
!include %dirpath()/%filename().include
@enduml

is also working.

Could you provide a short snippet that shows the issue ?

Thanks

commented Jun 7, 2019 by anonymous

My bad, it works once I make all the needed changes. I add to add the path and file name to the include (it was not necessary before, using startdef and includedef). But I was missing parenthesis for the dirpath() and filename() calls.

Below is how I have it working now. I have this sort of things embedded in a word document that we use as a template, and want it be self contained (opening the embedded object then pulls everything together-macros and diagram- in a temp file that changes name. 

Great job, and thank you so much for the quick answer.

@startuml(id=MACROS)
' Macros definitions
' Generic, consistent way to set up all diagrams

!function TITLE_ALL(s)
  title s
  footer Generated %date()
  skinparam shadowing false
  skinparam handwritten false
!endfunction

' Specific settings for sequence diagrams
!function TITLE_SEQUENCE(s)
  TITLE_ALL(s)
  hide footbox
!endfunction

@enduml

'------------------------------------------------------------
'end of macros, start of diagrams
'------------------------------------------------------------

@startuml(id=diagram_id)
!include %dirpath()/%filename()!MACROS
  TITLE_ALL("Your diagram here")
@enduml

@startuml(id=test_repeat_loop)
!include %dirpath()/%filename()!MACROS
  TITLE_SEQUENCE("Your diagram here")
  a->b
  b->a
@enduml 

1 Answer

+1 vote
answered Mar 26, 2017 by plantuml (295,000 points)
selected Mar 23, 2018 by Anthony-Gaudino
 
Best answer

In last beta https://www.dropbox.com/s/koo42q3d9gxw288/plantuml.jar?dl=0
We have added %filename% and %dirpath% variables.

So assuming the file "test1.txt" contains the following:

@startuml
title
Read from file %filename%
Path is %dirpath%
end title
alice->bob:hello
!include %dirpath%/foo1.txt
!include %dirpath%/%filename%.include
@enduml

and that you have in the same directory two files "foo1.txt" and "test1.txt.include"


To turn around your title trick, we added @startdef/@enddef blocks that would allow to define your macros in last beta https://www.dropbox.com/s/koo42q3d9gxw288/plantuml.jar?dl=0:

@startdef(id=macro)
Alice -> Bob : hello1
@enddef

@startuml
!includedef macro
Alice -> Bob : hello2
@enduml

OR

@startdef(id=mymacro)
!definelong ...
!definelong ...
!definelong ...
@enddef

@startuml
!includedef mymacro
Alice -> Bob : hello2
@enduml

Then you will be able to include those blocks using some new !includedef XXX directive

I think this would allow you to do something somehow cleaner.
Any thought about this ?

commented Mar 27, 2017 by Chris38 (220 points)
I like the beta, thank you. It even works with file names that have spaces :)

I like the startdef/enddef too. If I understand correctly, that would allow a block with no diagram, or if some diagrams are defined in the block, they would only be generated at the point the block is included, correct?

And by the way, one big reason for that feature is that I am creating word documents in which I put the .png generated by plantUML. To keep the source file available, so I can later change the diagrams, I also "drag and drop" the .txt with the diagram definition into word. Now I can simply double click on the .txt file to open it in my editor (word create a temp file, and that is when I really need those improvements to the include functionality). From my text editor, I mapped a key to launch the plantuml viewer from the current folder. This makes it very easy for me to update the diagrams and copy/paste the new/updated png into the document.

I might have a couple  unrelated requests/issues that I will post separately.

Thanks again, great job, very useful program.
commented Mar 28, 2017 by plantuml (295,000 points)
Unfortunately, the @startdef has to create an image (otherwise, the Word Addin would be lost).
Right now, the image contains only the text "@startdef(id=macro)"
It could be possible to generate a single pixel image, but I'm not sure that is is a good idea.

PS:
The drag&drop of the .txt in the word document is a good idea: maybe the Word Addin could work that way too ?
commented Mar 28, 2017 by Chris38 (220 points)
Now I am a bit confused :)

I am not sure what startdef/endef brings, maybe I am misunderstanding. Is that a combination of startuml and definelong? Can you still pass parameters?

In my example, I put all my macros in one block, using several definelong, and all of my diagrams include all my macros (initially, all the macros were in single, separate file, which gave me headaches for use in Word).

Christophe
commented Mar 28, 2017 by plantuml (295,000 points)
Sorry, I'm not very clear.
Actually, @startdef/@enddef does not bring very much.
My idea is to declare in the @startdef/@enddef all your macros.
So I'd better give you as example:

@startdef(id=mymacro)
!definelong ...
!definelong ...
!definelong ...
@enddef

@startuml
!includedef mymacro
Alice -> Bob : hello2
@enduml

It just save you from using your "title" workaround in the fist block.
Does it make more sense ?
commented Mar 28, 2017 by Chris38 (220 points)
I see, thanks. I like it.
 And this works only if the macros are in the same file, correct ?(removing the need for the new variables you provided, in that particular case).
The latest beta gives me error though...The first error is "empty description" (for the startdef block). If I add a "title" line in the block, then that error clears. But then I cannot call my macros. This is an example, simplified to a single macro, maybe I just have a typo...
@startdef(id=MACROS)
!definelong TITLE_ALL(s)
  title s
  footer Generated %date%
  skinparam shadowing false
  skinparam handwritten false
!enddefinelong
title this seems to be needed still
@enddef
 
@startuml
!includedef MACROS
TITLE_ALL("test")
Alice -> Bob : hello2
@enduml  

Also, I guess I will have to update my vim plugin so that it detects the plantuml file type when the first block is startdef.

Thanks,
Christophe
commented Mar 29, 2017 by plantuml (295,000 points)
edited Mar 29, 2017 by plantuml
> And this works only if the macros are in the same file, correct ?
> (removing the need for the new variables you provided, in that particular case).
Yes, correct.
We will keep the new variables anyway, as it may be still useful for some needs.

About macros, there was an issue in previous beta, we've fixed it in last beta (beta 11), so your example should work now.
(Thanks for your tests by the way!)
https://www.dropbox.com/s/koo42q3d9gxw288/plantuml.jar?dl=0

About vim plugin, no sure if it need some update, as long as it detects @start/@end instead of @startuml/@enduml
commented Mar 29, 2017 by Chris38 (220 points)
The last beta works beautifully for me, thank you!
Christophe
...