预处理

一些预处理功能包含在PlantUML中, ,并可用于所有的图。

这些功能与C语言的预处理器非常相似,只是特殊字符# 改为感叹号!

定义变量

虽然这不是必须的, 我们强烈建议变量名以 $开头。

变量有三种数据类型:

  • 整 型 (int)
  • 字符串 (str) - 必须被单引号或双引号包围;
  • JSON (JSON) - 必须被大括号包围。

(JSON 变量的定义与使用, 详见 Preprocessing-JSON 页面)

在函数外创建的变量作用域是global, 你可以在任何地方访问他们 (包括函数).当定义变量的时候你可以使用 global强调这一点。

🎉 Copied!

@startuml
!$a  = 42
!$ab = "foo1"
!$cd = "foo2"
!$ef = $ab + $cd
!$foo = { "name": "John", "age" : 30 }

Alice -> Bob : $a
Alice -> Bob : $ab
Alice -> Bob : $cd
Alice -> Bob : $ef
Alice -> Bob : Do you know **$foo.name** ?
@enduml

你还可以使用以下语法,仅在变量没有被定义时才对变量进行赋值: !$a ?= "foo"

🎉 Copied!

@startuml
Alice -> Bob : 1. **$name** should be empty

!$name ?= "Charlie"
Alice -> Bob : 2. **$name** should be Charlie

!$name = "David"
Alice -> Bob : 3. **$name** should be David

!$name ?= "Ethan"
Alice -> Bob : 4. **$name** should be David
@enduml

布尔表达式

布尔表示法 [0是假的]

没有真正的布尔类型,但是PlantUML使用这个整数约定:

  • 整数0 表示false
  • 任何非空数字(如1 或任何字符串(如"1" 甚至"0")* 表示true

[Ref.QA-9702]

布尔运算和运算符 [&&, ||, ()]

你可以使用布尔表达式,在测试中,使用:
  • 小括号 ();
  • 和运算符 &&;
  • 或运算符 ||

(见下一个例子,在if 测试中。)

布尔内置函数 [%false(), %true(), %not(<exp>)=== ]

为了方便,你可以使用这些布尔内置函数:

  • %false()
  • %true()
  • %not(<exp>)

[参见preprocessing#0umqmmdy1n9yk362kjka[内置函数]]

条件

  • 可以在条件里使用表达式.
  • 支持else语法

🎉 Copied!

@startuml
!$a = 10
!$ijk = "foo"
Alice -> Bob : A
!if ($ijk == "foo") && ($a+10>=4)
Alice -> Bob : yes
!else
Alice -> Bob : This should not appear
!endif
Alice -> Bob : B
@enduml

While 循环 [!while, !endwhile]

你可以使用!while!endwhile 关键字来实现重复循环。

While 循环(在活动图上)。

🎉 Copied!

@startuml
!procedure $foo($arg)
  :procedure start;
  !while $arg!=0
    !$i=3
    #palegreen:arg=$arg;
    !while $i!=0
      :arg=$arg and i=$i;
      !$i = $i - 1
    !endwhile
    !$arg = $arg - 1
  !endwhile
  :procedure end;
!endprocedure

start
$foo(2)
end
@enduml

[改编自QA-10838]

While循环(在Mindmap图上)。

🎉 Copied!

@startmindmap
!procedure $foo($arg)
  !while $arg!=0
    !$i=3
    **[#palegreen] arg = $arg
    !while $i!=0
      *** i = $i
      !$i = $i - 1
    !endwhile
    !$arg = $arg - 1
  !endwhile
!endprocedure

*:While
Loop;
$foo(2)
@endmindmap

While 循环(在组件/部署图上)

🎉 Copied!

@startuml
!procedure $foo($arg)
  !while $arg!=0
    [Component $arg] as $arg
    !$arg = $arg - 1
  !endwhile
!endprocedure

$foo(4)

1->2
3-->4
@enduml

[参考QA-14088]

空函数

  • 函数名 必须$开头
  • 参数名 必须$开头
  • 空函数可以调用其他空函数

例:

🎉 Copied!

@startuml
!procedure msg($source, $destination)
$source --> $destination
!endprocedure

!procedure init_class($name)
class $name {
$addCommonMethod()
}
!endprocedure


!procedure $addCommonMethod()
  toString()
  hashCode()
!endprocedure


init_class("foo1")
init_class("foo2")
msg("foo1", "foo2")
@enduml

函数里定义的变量作用域为local. 意味着随函数一同销毁.

返回函数

返回函数不输出任何东西. 它只是定义了一个你可以调用的函数:
  • 直接在变量和图中文本中使用
  • 被其他返回函数调用
  • 被其他空函数调用

  • 函数名 应该 以一个$开头
  • 参数名 应该 以一个 $开关

🎉 Copied!

@startuml
!function $double($a)
!return $a + $a
!endfunction

Alice -> Bob : The double of 3 is $double(3)
@enduml

可以简化函数定义为一行:

🎉 Copied!

@startuml
!function $double($a) return $a + $a

Alice -> Bob : The double of 3 is $double(3)
Alice -> Bob : $double("This work also for strings.")
@enduml

像空函数一样, 变量默认为'local'本地变量 (随函数退出销毁). 并且, 你可以在函数中访问'global'全局变量. 并且, 如何一个全局变量已存在,你仍可以使用 local 关键字创建一个同名的本地变量.

🎉 Copied!

@startuml
!procedure $dummy()
!local $ijk = "local"
Alice -> Bob : $ijk
!endprocedure

!global $ijk = "foo"

Alice -> Bob : $ijk
$dummy()
Alice -> Bob : $ijk
@enduml

参数默认值

在返回和空函数中, 你可以定义参数默认值.

🎉 Copied!

@startuml
!function $inc($value, $step=1)
!return $value + $step
!endfunction

Alice -> Bob : Just one more $inc(3)
Alice -> Bob : Add two to three : $inc(3, 2)
@enduml

只有在尾端的参数列表才可以定义默认值.

🎉 Copied!

@startuml
!procedure defaulttest($x, $y="DefaultY", $z="DefaultZ")
note over Alice
  x = $x
  y = $y
  z = $z
end note
!endprocedure

defaulttest(1, 2, 3)
defaulttest(1, 2)
defaulttest(1)
@enduml

非引号函数

默认情况下, 调用一个函数需要引号. 可以使用 unquoted 关键字指明一个函数的参数不需要使用引号.

🎉 Copied!

@startuml
!unquoted function id($text1, $text2="FOO") return $text1 + $text2

alice -> bob : id(aa)
alice -> bob : id(ab,cd)
@enduml

关键字参数

和Python一样,你可以使用关键字参数:

🎉 Copied!

@startuml

!unquoted procedure $element($alias, $description="", $label="", $technology="", $size=12, $colour="green")
rectangle $alias as "
<color:$colour><<$alias>></color>
==$label==
//<size:$size>[$technology]</size>//

  $description"
!endprocedure

$element(myalias, "This description is %newline()on several lines", $size=10, $technology="Java")
@enduml

Including files or URL [!include, !include_many, !include_once]

Use the !include directive to include file in your diagram. Using URL, you can also include file from Internet/Intranet. Protected Internet resources can also be accessed, this is described in URL authentication.

Imagine you have the very same class that appears in many diagrams. Instead of duplicating the description of this class, you can define a file that contains the description.

🎉 Copied!

@startuml

interface List
List : int size()
List : void clear()
List <|.. ArrayList
@enduml

File List.iuml

interface List
List : int size()
List : void clear()

The file List.iuml can be included in many diagrams, and any modification in this file will change all diagrams that include it.

You can also put several @startuml/@enduml text block in an included file and then specify which block you want to include adding !0 where 0 is the block number. The !0 notation denotes the first diagram.

For example, if you use !include foo.txt!1, the second @startuml/@enduml block within foo.txt will be included.

You can also put an id to some @startuml/@enduml text block in an included file using @startuml(id=MY_OWN_ID) syntax and then include the block adding !MY_OWN_ID when including the file, so using something like !include foo.txt!MY_OWN_ID.

By default, a file can only be included once. You can use !include_many instead of !include if you want to include some file several times. Note that there is also a !include_once directive that raises an error if a file is included several times.

Including Subpart [!startsub, !endsub, !includesub]

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

Builtin functions [%]

Some functions are defined by default. Their name starts by %

Name Description Example Return
%chr Return a character from a give Unicode value %chr(65) A
%darken Return a darken color of a given color with some ratio %darken("red", 20) #CC0000
%date Retrieve current date. You can provide an optional format for the date %date("yyyy.MM.dd' at 'HH:mm") current date
You can provide another optional time (on epoch format) %date("YYYY-MM-dd", %now() + 1*24*3600) tomorrow date
%dec2hex Return the hexadecimal string (String) of a decimal value (Int) %dec2hex(12) c
%dirpath Retrieve current dirpath %dirpath() current path
%feature Check if some feature is available in the current PlantUML running version %feature("theme") true
%false Return always false %false() false
%file_exists Check if a file exists on the local filesystem %file_exists("c:/foo/dummy.txt") true if the file exists
%filename Retrieve current filename %filename() current filename
%function_exists Check if a function exists %function_exists("$some_function") true if the function has been defined
%get_variable_value Retrieve some variable value %get_variable_value("$my_variable") the value of the variable
%getenv Retrieve environment variable value %getenv("OS") the value of OS variable
%hex2dec Return the decimal value (Int) of a hexadecimal string (String) %hex2dec("d") or %hex2dec(d) 13
%hsl_color Return the RGBa color from a HSL color %hsl_color(h, s, l) or %hsl_color(h, s, l, a) %hsl_color(120, 100, 50) #00FF00
%intval Convert a String to Int %intval("42") 42
%is_dark Check if a color is a dark one %is_dark("#000000") true
%is_light Check if a color is a light one %is_light("#000000") false
%lighten Return a lighten color of a given color with some ratio %lighten("red", 20) #CC3333
%load_json Load JSON data from local file or external URL %load_json("http://localhost:7778/management/health") JSON data
%lower Return a lowercase string %lower("Hello") hello in that example
%newline Return a newline %newline() a newline
%not Return the logical negation of an expression %not(2+2==4) false in that example
%now Return the current epoch time %now() 1685547132 in that example (when updating the doc.)
%ord Return a Unicode value from a given character %ord("A") 65
%lighten Return a lighten color of a given color with some ratio %lighten("red", 20) #CC3333
%reverse_color Reverse a color using RGB %reverse_color("#FF7700") #0088FF
%reverse_hsluv_color Reverse a color using HSLuv %reverse_hsluv_color("#FF7700") #602800
%set_variable_value Set a global variable %set_variable_value("$my_variable", "some_value") an empty string
%size Return the size of any string or JSON structure %size("foo") 3 in the example
%string Convert an expression to String %string(1 + 2) 3 in the example
%strlen Calculate the length of a String %strlen("foo") 3 in the example
%strpos Search a substring in a string %strpos("abcdef", "ef") 4 (position of ef)
%substr Extract a substring. Takes 2 or 3 arguments %substr("abcdef", 3, 2) "de" in the example
%true Return always true %true() true
%upper Return an uppercase string %upper("Hello") HELLO in that example
%variable_exists Check if a variable exists %variable_exists("$my_variable") true if the variable has been defined exists
%version Return PlantUML current version %version() 1.2020.8 for example
%invoke_procedure() Dynamically invoke a procedure by its name, passing optional arguments to the called procedure. %invoke_procedure("$go", "hello from Bob...") Depends on the invoked procedure
%call_user_func() Invoke a return function by its name with given arguments. %call_user_func("bold", "Hello") Depends on the called function
%splitstr Split a string into an array based on a specified delimiter. %splitstr("abc~def~ghi", "~") ["abc", "def", "ghi"]

Logging [!log]

You can use !log to add some log output when generating the diagram. This has no impact at all on the diagram itself. However, those logs are printed in the command line's output stream. This could be useful for debug purpose.

🎉 Copied!

@startuml
!function bold($text)
!$result = "<b>"+ $text +"</b>"
!log Calling bold function with $text. The result is $result
!return $result
!endfunction

Alice -> Bob : This is bold("bold")
Alice -> Bob : This is bold("a second call")
@enduml

Memory dump [!dump_memory]

You can use !dump_memory to dump the full content of the memory when generating the diagram. An optional string can be put after !dump_memory. This has no impact at all on the diagram itself. This could be useful for debug purpose.

🎉 Copied!

@startuml
!function $inc($string)
!$val = %intval($string)
!log value is $val
!dump_memory
!return $val+1
!endfunction

Alice -> Bob : 4 $inc("3")
!unused = "foo"
!dump_memory EOF
@enduml

Assertion [!assert]

You can put assertions in your diagram.

🎉 Copied!

@startuml
Alice -> Bob : Hello
!assert %strpos("abcdef", "cd")==3 : "This always fails"
@enduml

Building custom library [!import, !include]

It's possible to package a set of included files into a single .zip or .jar archive. This single zip/jar can then be imported into your diagram using !import directive.

Once the library has been imported, you can !include file from this single zip/jar.

Example:

@startuml

!import /path/to/customLibrary.zip
' This just adds "customLibrary.zip" in the search path

!include myFolder/myFile.iuml
' Assuming that myFolder/myFile.iuml is located somewhere
' either inside "customLibrary.zip" or on the local filesystem

...

Search path

You can specify the java property plantuml.include.path in the command line.

For example:

java -Dplantuml.include.path="c:/mydir" -jar plantuml.jar atest1.txt

Note the this -D option has to put before the -jar option. -D options after the -jar option will be used to define constants within plantuml preprocessor.

Argument concatenation [##]

It is possible to append text to a macro argument using the ## syntax.

🎉 Copied!

@startuml
!unquoted procedure COMP_TEXTGENCOMP(name)
[name] << Comp >>
interface Ifc << IfcType >> AS name##Ifc
name##Ifc - [name]
!endprocedure
COMP_TEXTGENCOMP(dummy)
@enduml

Dynamic invocation [%invoke_procedure(), %call_user_func()]

You can dynamically invoke a procedure using the special %invoke_procedure() procedure. This procedure takes as first argument the name of the actual procedure to be called. The optional following arguments are copied to the called procedure.

For example, you can have:

🎉 Copied!

@startuml
!procedure $go()
  Bob -> Alice : hello
!endprocedure

!$wrapper = "$go"

%invoke_procedure($wrapper)
@enduml

🎉 Copied!

@startuml
!procedure $go($txt)
  Bob -> Alice : $txt
!endprocedure

%invoke_procedure("$go", "hello from Bob...")
@enduml

For return functions, you can use the corresponding special function %call_user_func() :

🎉 Copied!

@startuml
!function bold($text)
!return "<b>"+ $text +"</b>"
!endfunction

Alice -> Bob : %call_user_func("bold", "Hello") there
@enduml

Evaluation of addition depending of data types [+]

Evaluation of $a + $b depending of type of $a or $b

🎉 Copied!

@startuml
title
<#LightBlue>|= |=  $a |=  $b |=  <U+0025>string($a + $b)|
<#LightGray>| type | str | str | str (concatenation) |
| example |= "a" |= "b" |= %string("a" + "b") |
<#LightGray>| type | str | int | str (concatenation) |
| ex.|= "a" |=  2  |= %string("a" + 2)   |
<#LightGray>| type | str | int | str (concatenation) |
| ex.|=  1  |= "b" |= %string(1 + "b")   |
<#LightGray>| type | bool | str | str (concatenation) |
| ex.|= <U+0025>true() |= "b" |= %string(%true() + "b") |
<#LightGray>| type | str | bool | str (concatenation) |
| ex.|= "a" |= <U+0025>false() |= %string("a" + %false()) |
<#LightGray>| type |  int  |  int | int (addition of int) |
| ex.|=  1  |=  2  |= %string(1 + 2)     |
<#LightGray>| type |  bool  |  int | int (addition) |
| ex.|= <U+0025>true() |= 2 |= %string(%true() + 2) |
<#LightGray>| type |  int  |  bool | int (addition) |
| ex.|=  1  |= <U+0025>false() |= %string(1 + %false()) |
<#LightGray>| type |  int  |  int | int (addition) |
| ex.|=  1  |=  <U+0025>intval("2")  |= %string(1 + %intval("2")) |
end title
@enduml

Preprocessing JSON

You can extend the functionality of the current Preprocessing with JSON Preprocessing features:

  • JSON Variable definition
  • Access to JSON data
  • Loop over JSON array

(See more details on Preprocessing-JSON page)

Including theme [!theme]

Use the !theme directive to change the default theme of your diagram.

🎉 Copied!

@startuml
!theme spacelab
class Example {
  Theme spacelab
}
@enduml

You will find more information on the dedicated page.

迁移说明

目前的预处理是由legacy preprocessor.升级而来.

虽然一些历史遗留功能仍被目前的预处理支持, 但是你不应该继续使用 (他们不久将会被移除).

  • You should not use !define and !definelong anymore. Use !function, !procedure or variable definition instead. !define should be replaced by return !function and !definelong should be replaced by !procedure.
  • 你不应该再使用 !define!definelong. 使用 !function 和定义变量替换他们. !define替换为 返回函数 而 !definelong 应该替换为 void function.
  • !include 现在允许多包含 : 不应该再使用 !include_many
  • !include 现在可以授受URL, 所以不再需要 !includeurl
  • 一些特性 (比如 %date%) 替换为内建函数 (例如 %date())
  • 当不带参数调用历史遗留!definelong 宏的时候, 你必须使用括号. 必须使用 my_own_definelong() 因为 my_own_definelong不带括号的形式不被新的预处理语法解析.

如果你有什么疑问请联系我们.

%splitstr builtin function

🎉 Copied!

@startmindmap
!$list = %splitstr("abc~def~ghi", "~")

* root
!foreach $item in $list
  ** $item
!endfor
@endmindmap

Similar to:

🎉 Copied!

@startmindmap
* root
!foreach $item in ["abc", "def", "ghi"]
  ** $item
!endfor
@endmindmap

[Ref. QA-15374]

%get_all_theme() builtin function

You can use the %get_all_theme() builtin function to retreive a JSON array of all PlantUML theme.

🎉 Copied!

@startjson
%get_all_theme()
@endjson

[from version 1.2024.4]

%get_all_stdlib builtin function

Compact version (only standard library name)

You can use the %get_all_stdlib() builtin function to retreive a JSON array of all PlantUML stdlib names.

🎉 Copied!

@startjson
%get_all_stdlib()
@endjson

Detailed version (with version and source)

With whatever parameter, you can use %get_all_stdlib(detailed) to retreive a JSON object of all PlantUML stdlib.

🎉 Copied!

@startjson
%get_all_stdlib(detailed)
@endjson

[from version 1.2024.4]

%random builtin function

You can use the %random builtin function to retreive a random integer.

Nb param. Input Output
0 %random() returns 0 or 1
1 %random(n) returns an interger between 0 and n - 1
2 %random(min, max) returns an interger between min and max - 1

🎉 Copied!

@startcreole
| Nb param. | Input | Output |
| 0 | <U+0025>random()      | %random()     |
| 1 | <U+0025>random(5)     | %random(5)    |
| 2 | <U+0025>random(7, 15) | %random(7, 15) |
@endcreole

[from version 1.2024.2]


Privacy Policy      Advertise