Text before and after functions is discarded by the v2 preprocessor

0 votes
asked Jun 18, 2019 in Bug by ahktenzero (120 points)

I have some defines I use for building database diagrams with PlantUML which I am trying to convert to use the new preprocessor, but the new function definitions behave differently to the old defines and this is causing problems. With defines, when they were referenced in the rest of the file the define was expanded and the rest of the line left as it was, with functions it appears to replace the entire line discarding any text before or after the function.

I have made a minimal example to demonstrate the problem. Below is a version with the old preprocessor which works:

@startuml
!define test(name) class name << (A, #FF00DD >>

test(test) {
    id: int4
    do_something(): void
}

@enduml

This expands to

@startuml

class test << (A, #FF00DD >> {
    id: int4
    do_something(): void
}

@enduml

Converted to the new preprocessor:

@startuml
!function test($name)
class $name << (A, #FF00DD >>
!endfunction

test("test") {
    id: int4
    do_something(): void
}

@enduml

expands to

@startuml

class test << (A, #FF00DD >>
    id: int4
    do_something(): void
}

@enduml

The bracket on the line after test("test") has been discarded, which causes a syntax error.

The problem also appears if the function is called in the middle or at the end of the line, with all the text except for the function output being discarded.

1 Answer

0 votes
answered Jun 18, 2019 by plantuml (295,000 points)

In your case, you may use "return function" instead of "void function".
Generally speaking, !define should be changed in "return function" and !definelong in "void function".

So you can use:

@startuml
!function test($name)
!return "class "+$name+" << (A, #FF00DD >>"
!endfunction

test("test") {
    id: int4
    do_something(): void
}
@enduml

Note that you can use the "unquoted" keyword to avoid quotes when calling your function:

@startuml
!unquoted function test($name)
!return "class "+$name+" << (A, #FF00DD >>"
!endfunction

test(test) {
    id: int4
    do_something(): void
}
@enduml

Finally, since your method is very short, you can have:

@startuml
!unquoted function test($name) return "class "+$name+" << (A, #FF00DD >>"

test(test) {
    id: int4
    do_something(): void
}
@enduml

Now, I understand that your example is just a minimum example.
So tell us if it does apply to your real usage !

commented Jun 18, 2019 by ahktenzero (120 points)
Thanks for the explanation. Using return functions has solved the problem and I have successfully converted my diagram to use the new preprocessor.

I think it would be helpful to add the suggestion to use return functions in place of most defines to the migration notes.
commented Jun 18, 2019 by plantuml (295,000 points)

You're right, we've just updated the migration notes.

http://plantuml.com/preprocessing

Thanks!

...