Introducción a Asciidoc y Asciidoctor (5): diagramas
Jorge
Posted on February 24, 2020
| | Este post es la continuación a intro-asciidoctor-4.html |
| | Yo utilizo sistemas Linux por lo que los comando que indico para instalar software estan orientados a este.Si tienes interés en saber cómo hacerlo en Windows, escribeme y lo investigaré |
Objetivo
En este post veremos cómo crear diferentes tipos de diagramas usando sólo un editor de texto.
Los tipos de diagramas son variados y de diferentes ámbitos como:
Diagramas de clases, relaciones, actividades, etc tipicos de UML
Diagramas de arquitectura software
Diagramas Gant para organización de proyectos, tareas, equipos, etc
Representación de componentes UI (textbox, listbox, buttons, checks, etc)
Gramatica, para representar partes de una sintaxis por ejemplo
Otros
Requisitos
El primer requisito que necesitamos es tener instalado asciidoctor, tal como se ha explicadoen los post anteriores de esta serie.
| | Para este post vamos a usar asciidoctorj |
$sdk man install asciidoctorj
La instalacion de asciidoctorj incluye por defecto el segundo requisito que necesitaremos para dotar a nuestros documentosde diagramas, asciidoctor-diagram
En caso de que estés usando la versión ruby deberás instalar la gema correspondiente:
$ gem install asciidoctor-diagram
En realidad asciidoctor_diagram por si mismo NO genera ningun diagrama, sino que podriamos decir que es el "pegamento"entre asciidoctor y los diferentes generadores de diagramas. En la página oficial podemos ver los tipos soportados:
The extensions supports the AsciiToSVG, BlockDiag (BlockDiag, SeqDiag, ActDiag, NwDiag),Ditaa, Erd, GraphViz, Mermaid, Msc, PlantUML, Shaape, SvgBob, Syntrax, UMLet, Vega,Vega-Lite and WaveDrom syntax.
| | Esta lista no es exclusiva, pudiendo incorporar nuevos interpretes gracias al modelo de extensionesde Asciidoctor. Yo mismo he hecho alguna extension en Java y es realmente fácil |
Si utilizamos el método indicado anteriormente para la instalación de Asciidoctor (AsciidoctorJ) tendremos incluidospor defecto los diagramas Ditaa y PlantUML (tal vez algun otro) asi que si vamos a usar algun otro tipo tendremos quetener instalado el ejecutable correspondiente.
De forma generica, y como consejo, yo siempre instalo Graphviz puesto que muchos de estos generadores lo usan
$sudo apt-get install graphviz
Mermaid
Si por ejemplo queremos generar diagramas usando Mermaid tendremos que ejecutar:
$ npm install -g mermaid.cli
o si usamos yarn
$ yarn global add mermaid.cli
Syntrax
Por su parte, syntrax esta desarrollado en python por lo que tendremos que tener instalado este software y ejecutar
$pip install --upgrade syntrax
| | Efectivamente, como has podido adivinar te toca conocer la sintaxis de cada generador que quieras utilizar.Asciidoctor-diagram solo sirve como puente entre tu documento y el generador |
Sintaxis
La potencia de poder adjuntar a nuestra documentacion diagramas definidos en formato texto es inmensa, pudiendo aprovechartodas las caracteristicas propias de la filosofía "doc-as-code", es decir, crear y manejar nuestra documentación igualque lo hacemos con el código: editores de texto, versionable, mergear ramas, aprovaciones, despliegues continuos, etc
Include implícito
Asi pues la sintaxis para definir un diagrama a lo largo de nuestra documentación consiste simplemente en crear unbloque donde se especifique el tipo de diagrama que vamos a usar e incluir el cuerpo del diagrama dentro del mismo:
Por ejemplo:
Este parrafo es parte de nuestra documentacion, donde queremos poner a continuacion un diagrama de clases
plantuml::fichero_mi_diagrama.txt[]
donde fichero_mi_diagrama.txt puede ser un fichero de texto como el siguiente:
class Car
Driver - Car : drives >
Car *- Wheel : have 4 >
Car -- Person : < owns
De tal forma que nuestro documento se vería como:
Este parrafo es parte de nuestra documentación, donde queremos poner a continuación un diagrama de clases
Bloques
Si no quieres crear más ficheros también puedes usar bloques para incluir tus diagramas junto con la documentacion:
Este parrafo es parte de nuestra documentación, donde queremos poner a continuación un diagrama de clases
[plantuml]
++++
class Car
Driver - Car : drives >
Car *- Wheel : have 4 >
Car -- Person : < owns
++++
Y el resultado sería el mismo.
Ejemplos
A continuacion algunos diagramas de ejemplos generados con Ditaa, PlantUML, Mermaid y Syntrax
Diseño Software
Procesos
[ditaa]
....
+-------------+
| Asciidoctor |-------+
| diagram | |
+-------------+ | PNG out
^ |
| ditaa in |
| v
+--------+ +--------+----+ /---------------\
| | --+ Asciidoctor +--> | |
| Text | +-------------+ | Beautiful |
|Document| | !magic! | | Output |
| {d}| | | | |
+---+----+ +-------------+ \---------------/
: ^
| Lots of work |
+-----------------------------------+
....
UML
[plantuml]
++++
title Relationships - Class Diagram
class Dwelling {
+Int Windows
+void LockTheDoor()
}
class Apartment
class House
class Commune
class Window
class Door
Dwelling <|-down- Apartment: Inheritance
Dwelling <|-down- Commune: Inheritance
Dwelling <|-down- House: Inheritance
Dwelling "1" *-up- "many" Window: Composition
Dwelling "1" *-up- "many" Door: Composition
skinparam componentStyle uml2
class Car {
.. Field Examples ..
- Name: Type { arg1, arg2, argn }
+Name: Type { arg1, arg2, argn }
#Name: Type { arg1, arg2, argn }
~Name: Type { arg1, arg2, argn }
.. Method Examples ..
-Name(): Type { arg1, arg2, argn }
+Name(): Type { arg1, arg2, argn }
#Name(): Type { arg1, arg2, argn }
~Name(): Type { arg1, arg2, argn }
.. Static Example ..
+{static} Name(): Type { arg1, arg2, argn }
.. Abstract Example ..
+{abstract} Name(): Type { arg1, arg2, argn }
}
class Car
ICar ()- Car
ICar2 ()-- Car
Car -() ICar3
+++
[plantuml]
++++
title Parallel - Activity Diagram
start
:Eat Hot Wings;
:Drink Homebrew;
if (Turn On The Game?) then (yes)
fork
:__Having Fun__!!!;
fork again
:Scream At TV!!;
end fork
else (no)
:Not Having Fun;
:Eat Poptart;
endif
:Go To Bed;
stop
+++
[plantuml]
++++
title Conditional - Activity Diagram
start
:Eat Hot Wings;
note right: This is a note to the right
:Drink Homebrew;
note left: This is a note to the left
if (Turn On The Game?) then (yes)
:__Having Fun__!!!;
else (no)
:Not Having Fun;
endif
:Go To Bed;
stop
+++
[mermaid]
++++
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
++++
Arquitectura
[plantuml]
++++
!define SPRITESURL https://raw.githubusercontent.com/rabelenda/cicon-plantuml-sprites/v1.0/sprites
!includeurl SPRITESURL/tomcat.puml
!includeurl SPRITESURL/kafka.puml
!includeurl SPRITESURL/java.puml
!includeurl SPRITESURL/cassandra.puml
!includeurl SPRITESURL/python.puml
!includeurl SPRITESURL/redis.puml
title Cloudinsight sprites example
skinparam monochrome true
rectangle "<$tomcat>\nwebapp" as webapp
queue "<$kafka>" as kafka
rectangle "<$java>\ndaemon" as daemon
rectangle "<$python>\ndaemon2" as daemon2
database "<$cassandra>" as cassandra
database "<$redis>" as redis
webapp -> kafka
kafka -> daemon
kafka -> daemon2
daemon --> cassandra
daemon2 --> redis
++++
Gestion proyectos
[mermaid]
++++
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d
++++
UI/UX
[plantuml]
++++
@startsalt
{
Just plain text
[This is my button]
() Unchecked radio
(X) Checked radio
[] Unchecked box
[X] Checked box
"This is a textbox "
^This is a droplist^
==
User Name:| "Justin "
Password: | "**** "
[Ok ] | [ Close ]
==
Name | " "
Direction: | { (X) Left | () Right | () Up | () Down }
Attending?: | { [] Yes | [] No
[] Maybe }
[Browse...] }
}
@endsalt
+++
[plantuml]
++++
@startsalt
{+
{/ <b>General | Fullscreen | Behavior | Saving }
{
{ Open image in: | ^Smart Mode^ }
[X] Smooth images when zoomed
[X] Confirm image deletion
[ ] Show hidden images
}
[Close]
}
@ensalt
++++
[plantuml]
++++
(*) --> "
{{
salt
{+
<b>an example
choose one option
()one
()two
[ok]
}
}}
" as choose
choose -right-> "
{{
salt
{+
<b>please wait
operation in progress
<&clock>
[cancel]
}
}}
" as wait
wait -right-> "
{{
salt
{+
<b>success
congratulations!
[ok]
}
}}
" as success
wait -down-> "
{{
salt
{+
<b>error
failed, sorry
[ok]
}
}}
"
++++
Sintaxis
[syntrax]
++++
stack(
line('attribute', '/(attribute) identifier', 'of'),
line(choice(toploop('/entity_designator', ','), 'others', 'all'), ':'),
opt('bypass'),
line(optx('A', 'B', 'C')),
line('/entity_class', 'is', '/expression', ';')
)
++++
Otros
Posted on February 24, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.