Language Reference¶
ADia
is an indent based language such as Python
and uses indentation
to specify the parent/children
relationship between entities. Leading
whitespaces at the beginning of a line is used to compute the indentation
level of the line, which in turn is used to determine the grouping of
statements.
Every statement of the ADia
language is consist of one operation
and
an optional text
as follow:
operation[: text]
Example:
adia.print('''
diagram: foo
sequence:
foo -> bar
''')
DIAGRAM: foo
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
| |
|~~~~~~>|
| |
|<------|
| |
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
Diagram Header¶
Every ADia
document should starts with the diagram: [TITLE]
attribute.
There is also two optional attributes: version
and author
.
Example:
adia.print('''
diagram: Foo
version: 1.0
author: Alice
sequence: Foo & Bar
foo -> bar
''')
DIAGRAM: Foo
author: Alice
version: 1.0
SEQUENCE: Foo & Bar
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
| |
|~~~~~~>|
| |
|<------|
| |
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
Diagram Section¶
Every ADia
document may consists of zero or more sections which could be
one of sequence
, class
and fork
.
adia.print('''
diagram: Foo
sequence: Foo & Bar
foo -> bar
sequence: Bar & Baz
bar -> baz
''')
DIAGRAM: Foo
SEQUENCE: Foo & Bar
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
| |
|~~~~~~>|
| |
|<------|
| |
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
SEQUENCE: Bar & Baz
+-----+ +-----+
| bar | | baz |
+-----+ +-----+
| |
|~~~~~~>|
| |
|<------|
| |
+-----+ +-----+
| bar | | baz |
+-----+ +-----+
Note
Currently, only the sequence
diagram is implemented. It means every
ADia
document may consists of zero or more sequence diagrams.
Sequence Diagram¶
A sequence diagram always starts with the sequence: [TITLE]
keyword and
basically it is a collection of modules
and items
which described
below.
Module¶
You may use shorter name for modules for simplicity and define comprehensive
title with MODULE.title: TITLE
statement.
adia.print('''
diagram: foo
sequence:
foo.title: Mr Foo
foo -> bar: hello!
''')
DIAGRAM: foo
+---------+ +-----+
| Mr Foo | | bar |
+---------+ +-----+
| |
|~~~hello!~~~>|
| |
|<------------|
| |
+---------+ +-----+
| Mr Foo | | bar |
+---------+ +-----+
Note¶
You can put note anywhere and at every indentation level. see below to learn
about the Single-Module
and Multi-Module
notes.
Single-Module Note¶
adia.print('''
diagram: foo
sequence:
@foo: Over the foo->bar
foo -> bar
bar -> baz
@baz: Inside the bar->baz
@bar: Under the bar->baz
''')
DIAGRAM: foo
+-----+ +-----+ +-----+
| foo | | bar | | baz |
+-----+ +-----+ +-----+
| | |
--------------------- | |
| Over the foo->bar | | |
--------------------- | |
| | |
|~~~~~~~~~~~~~~~~~~~>| |
| |~~~~~~~~~~~~~~~~~~~~>|
| | |
| | -----------------------
| | | Inside the bar->baz |
| | -----------------------
| | |
| |<--------------------|
| | |
| ---------------------- |
| | Under the bar->baz | |
| ---------------------- |
| | |
|<-------------------| |
| | |
+-----+ +-----+ +-----+
| foo | | bar | | baz |
+-----+ +-----+ +-----+
Multi-Module Note¶
A Multi-Module Note
may cover two or more modules.
adia.print('''
diagram: foo
sequence:
@foo ~ bar: Lorem Ipsum
foo -> bar
bar -> baz
@foo ~ baz: Lorem Ipsum
''')
DIAGRAM: foo
+-----+ +-----+ +-----+
| foo | | bar | | baz |
+-----+ +-----+ +-----+
| | |
--------------- |
| Lorem Ipsum | |
--------------- |
| | |
|~~~~~~>| |
| |~~~~~~>|
| | |
-----------------------
| Lorem Ipsum |
-----------------------
| | |
| |<------|
|<------| |
| | |
+-----+ +-----+ +-----+
| foo | | bar | | baz |
+-----+ +-----+ +-----+
Call¶
A call is consists of CALLER -> CALLEE[: [FUNCTION] [=> RETURN]]
.
CALLER
and CALLEE
are modules which described above.
FUNCTION
and RETURN
can be any ASCII
character.
Changed in version 1.0: -> RETURN
is replaced by => RETURN
.
adia.print('''
diagram: foo
sequence:
@foo ~ bar: Without function name
foo -> bar
@foo ~ bar: With function name
foo -> bar: init(options)
@foo ~ bar: With function name & return value
foo -> bar: init(options) => err
@foo ~ bar: Only return value
foo -> bar: => err
''')
DIAGRAM: foo
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
| |
-------------------------------------
| Without function name |
-------------------------------------
| |
|~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
| |
|<----------------------------|
| |
-------------------------------------
| With function name |
-------------------------------------
| |
|~~~init(options)~~~~~~~~~~~~>|
| |
|<----------------------------|
| |
-------------------------------------
| With function name & return value |
-------------------------------------
| |
|~~~init(options)~~~~~~~~~~~~>|
| |
|<--err-----------------------|
| |
-------------------------------------
| Only return value |
-------------------------------------
| |
|~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
| |
|<--err-----------------------|
| |
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
Self Call¶
adia.print('''
diagram: foo
sequence:
foo -> foo
foo -> foo: self_test() => Result
''')
DIAGRAM: foo
+-----+
| foo |
+-----+
|
|~~~~~~+
| |
|<-----+
|
|~~~self_test()~~~+
| |
|<--Result--------+
|
+-----+
| foo |
+-----+
Callstack¶
Use one indentation level to put one or more item inside another.
Consider these Python
modules: foo.py
and bar.py
.
foo.py
import bar
bat.init()
bar.py
import baz
import qux
def prepare():
...
def init():
prepare()
baz.init()
qux.init()
ADia
representation of the codes above would be something like this:
adia.print('''
diagram: foo
sequence:
foo -> bar: init()
bar -> bar: prepare()
bar -> baz: init()
bar -> qux: init()
''')
DIAGRAM: foo
+-----+ +-----+ +-----+ +-----+
| foo | | bar | | baz | | qux |
+-----+ +-----+ +-----+ +-----+
| | | |
|~~~init()~~~>| | |
| |~~~prepare()~~~+ | |
| | | | |
| |<--------------+ | |
| | | |
| |~~~init()~~~~~~~~>| |
| | | |
| |<-----------------| |
| | | |
| |~~~init()~~~~~~~~~~~~~~~~>|
| | | |
| |<-------------------------|
|<------------| | |
| | | |
+-----+ +-----+ +-----+ +-----+
| foo | | bar | | baz | | qux |
+-----+ +-----+ +-----+ +-----+
Condition¶
adia.print('''
diagram: foo
sequence:
foo -> bar: init(force, full)
if: force
bar -> baz: force_init()
elif: full
bar -> baz: full_init()
else:
bar -> baz: init()
''')
DIAGRAM: foo
+-----+ +-----+ +-----+
| foo | | bar | | baz |
+-----+ +-----+ +-----+
| | |
|~~~init(force, full)~~~>| |
| | |
| ***************************
| * if force *
| ***************************
| | |
| |~~~force_init()~~~>|
| | |
| |<------------------|
| | |
| ***************************
| * elif full *
| ***************************
| | |
| |~~~full_init()~~~~>|
| | |
| |<------------------|
| | |
| ***************************
| * else *
| ***************************
| | |
| |~~~init()~~~~~~~~~>|
| | |
| |<------------------|
| | |
| ***************************
| * end if *
| ***************************
| | |
|<-----------------------| |
| | |
+-----+ +-----+ +-----+
| foo | | bar | | baz |
+-----+ +-----+ +-----+
Loop¶
For Loop¶
adia.print('''
diagram: foo
sequence:
foo -> bar: init(forks)
for: i in range(forks)
bar -> baz: fork(i)
''')
DIAGRAM: foo
+-----+ +-----+ +-----+
| foo | | bar | | baz |
+-----+ +-----+ +-----+
| | |
|~~~init(forks)~~~>| |
| | |
| *************************
| * for i in range(forks) *
| *************************
| | |
| |~~~fork(i)~~~~~~>|
| | |
| |<----------------|
| | |
| *************************
| * end for *
| *************************
| | |
|<-----------------| |
| | |
+-----+ +-----+ +-----+
| foo | | bar | | baz |
+-----+ +-----+ +-----+
While Loop¶
adia.print('''
diagram: foo
sequence:
while: True
foo -> bar: accept() => socket
''')
DIAGRAM: foo
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
| |
***********************
* while True *
***********************
| |
|~~~accept()~~~>|
| |
|<--socket------|
| |
***********************
* end while *
***********************
| |
+-----+ +-----+
| foo | | bar |
+-----+ +-----+
Comments¶
Every line started with # is comment and will be ignored by the lexer.