Metanorma PlantUML plugin (metanorma-plugin-plantuml)
Purpose
This Metanorma plugin enables the usage of PlantUML diagrams in Metanorma documents.
It provides a Ruby API that wraps a bundled PlantUML JAR file.
PlantUML
PlantUML is a popular tool that allows users to create rich diagrams from plain text descriptions, including:
-
UML diagrams
-
Sequence diagram
-
Usecase diagram
-
Class diagram
-
Object diagram
-
Activity diagram
-
Component diagram
-
Deployment diagram
-
State diagram
-
Timing diagram
-
It also supports the following non-UML diagrams:
-
JSON Data
-
YAML Data
-
Network diagram (nwdiag)
-
Wireframe graphical interface
-
Archimate diagram
-
Specification and Description Language (SDL)
-
Ditaa diagram
-
Gantt diagram
-
MindMap diagram
-
Work Breakdown Structure diagram
-
Mathematic with AsciiMath or JLaTeXMath notation
-
Entity Relationship diagram
For more details, please refer to the official PlantUML website.
The official PlantUML Language Reference Guide is available at:
Installation
$ gem install metanorma-plugin-plantuml
Usage
General
This plugin enables PlantUML diagram generation in Metanorma documents through multiple methods, including:
-
Block syntax using
[plantuml]
blocks -
Command syntax using
plantuml_image::{path}[{options}]
Both syntaxes support various diagram types, output formats, and image
attributes, as well as PlantUML’s include!
and includesub!
directives for
modular diagrams.
The effect of both syntaxes is the same: they generate and embed PlantUML diagrams as images in the output document.
However, there are important differences in using them with external files, as it is described in the various options.
The difference lies in how the PlantUML source is provided:
-
In the block syntax, the PlantUML source is defined directly within the document, and hence generated by PlantUML without a specific file context.
-
In the command syntax, the PlantUML source is read from an external file, which provides a file context for the PlantUML source.
Generally, the command syntax is more suitable for referencing external PlantUML files.
Command syntax for external diagrams
PlantUML diagrams can be directly referenced from external files using the
plantuml_image::{path}[{options}]
command.
Syntax:
plantuml_image::{plantuml-source.puml}[{options}]
Where,
{plantuml-source.puml}
-
Path to the PlantUML source file, relative to the path of the document root file.
{options}
-
(Optional) Comma-separated list of options to customize diagram generation.
plantuml_image
command without optionsplantuml_image::foo/bar.puml[]
The file foo/bar.puml
looks like:
@startuml
Alice -> Bob: Hello
Bob -> Alice: Hi there
@enduml
plantuml_image
command with optionsplantuml_image::foo/bar.puml[format=svg]
The file foo/bar.puml
is the same as above.
The format=svg
option specifies the output format as SVG.
The path to the PlantUML source file is relative to the document root file, which is illustrated in the following example.
Given the following directory structure:
dir/
dir/sources/document.adoc
dir/sources/sections/section_1.adoc
dir/sources/plantuml/my_diagram.puml
Where:
-
document.adoc
includessections/section_1.adoc
-
section_1.adoc
contains theplantuml_image
command.
The path to the PlantUML source file in section_1.adoc
is specified relative
to document.adoc
, the document root, which is plantuml/my_diagram.puml
:
plantuml_image::plantuml/my_diagram.puml[]
Block syntax for inline diagrams
PlantUML diagrams can be defined directly within your Metanorma document using
[plantuml]
blocks.
Syntax:
[plantuml]
....
{PlantUML diagram source here}
....
Where,
[plantuml]
-
Specifies that the block contains PlantUML source code.
….
-
Delimiters that indicate the start and end of the PlantUML source code.
{PlantUML diagram source here}
-
The actual PlantUML diagram definition using PlantUML syntax.
The block can be used with or without options.
Syntax with options:
[plantuml,{options}]
....
{PlantUML diagram source here}
....
Where,
{options}
-
Comma-separated list of options to customize diagram generation.
[plantuml]
block[plantuml]
....
@startuml
Alice -> Bob: Hello
Bob -> Alice: Hi there
@enduml
....
Supported diagram types
PlantUML, and therefore this plugin, supports various diagram types, each with
its own @start
and @end
directives:
-
@startuml
/@enduml
-
UML diagrams (sequence, class, activity, etc.)
-
@startmindmap
/@endmindmap
-
Mind map diagrams
-
@startgantt
/@endgantt
-
Gantt charts
-
@startsalt
/@endsalt
-
Wireframe diagrams
-
@startdot
/@enddot
-
Graphviz DOT diagrams
-
@startditaa
/@endditaa
-
ASCII art diagrams
-
@startjson
/@endjson
-
JSON data visualization
-
@startyaml
/@endyaml
-
YAML data visualization
[plantuml]
....
@startuml sequence-example
participant Alice
participant Bob
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response
@enduml
....
[plantuml]
....
@startmindmap
* Metanorma
** Standards
*** ISO
*** IEC
*** ITU
** Formats
*** PDF
*** HTML
*** Word
@endmindmap
....
Format options
Single format specification
The output format is specified using the format
option, which can be applied
in both block and command syntaxes.
Block syntax:
[plantuml,format={format}]
Command syntax:
plantuml_image::{path}[format={format}]
Where {format}
can be one of the following:
png
-
(default) Portable Network Graphics
svg
-
Scalable Vector Graphics
pdf
-
Portable Document Format
txt
-
ASCII art text output
eps
-
Encapsulated PostScript
[plantuml,format=svg]
....
@startuml
Alice -> Bob: Hello
@enduml
....
plantuml_image::path/to/my-plantuml.puml[format=svg]
Multiple format generation
It is possible to generate multiple output formats simultaneously by specifying
the formats
option, which accepts a comma-separated list of formats.
While Metanorma does not currently support embedding multiple images for a single diagram, generating multiple formats can be useful for documentation or other purposes.
Block syntax:
[plantuml,formats="{format1},{format2},..."]
Command syntax:
plantuml_image::{path}[formats="{format1},{format2},..."]
Where {format1}
, {format2}
, etc. can be any of the supported formats listed
above.
[plantuml,formats="png,svg,pdf"]
....
@startuml
Alice -> Bob: Hello
@enduml
....
Document-level format configuration
The default format for all PlantUML diagrams in a document can be set using the
plantuml-image-format
document attribute.
Syntax:
:plantuml-image-format: {format}
Where {format}
can be any of the supported formats listed above.
:plantuml-image-format: svg
[plantuml]
....
@startuml
Alice -> Bob: Hello
@enduml
....
Using !include
and !includesub
General
PlantUML supports modular diagram definitions using the !include
and
!includesub
directives to include external PlantUML files or specific parts of
them.
PlantUML is able to resolve relative paths in these directives based on the context of the PlantUML source.
This is where the behavior differs between the block syntax and the command syntax:
-
In the block syntax, as the PlantUML source is defined inline within the document, there is no associated file path for the PlantUML source. The consequence is that PlantUML cannot resolve relative paths in
!include
or!includesub
directives, as there is no associated file path. In order to resolve includes, you must specify theincludedirs
option to provide directories to search for included files. -
In the command syntax, the PlantUML source is read from an external file. This means that relative paths in
!include
or!includesub
directives are resolved relative to the location of the PlantUML source file. Theincludedirs
option is not needed for resolving includes, but can still be used to add additional directories to search.
Setting includedirs
PlantUML allows you to specify include directories using the includedirs
option. This option can be set at both the document level and the block level,
through the option of the same name.
There are two ways to set includedirs
:
-
Document-level configuration using the
plantuml-includedirs
document attribute -
The
includedirs
option in the[plantuml]
block orplantuml_image
command
Note that when using the plantuml_image
command, the directory that contains
the specified PlantUML file will be automatically added as one of the
includedirs
directories. This means that any relative includes in the PlantUML
file will be resolved relative to the file’s location, even if includedirs
is
not explicitly set.
Document-level plantuml-includedirs
attribute
It is possible to set default include directories (separated by semicolons) for
all PlantUML diagrams in a document using the plantuml-includedirs
document
attribute.
This is useful when a document contains multiple PlantUML diagrams that share common include files stored in specific directories, e.g. style definitions.
The directories specified in this attribute will be used as the default include
paths for all PlantUML diagrams in the document, including for both [plantuml]
blocks and plantuml_image
commands.
Note
|
When using the plantuml_image command, the directory that contains the
specified PlantUML file will always be automatically added as one of the
includedirs directories.
|
Syntax:
:plantuml-includedirs: {path1};{path2};...
Where,
-
{path1}
,{path2}
, etc. -
paths to directories (relative to document root) containing PlantUML files to be included, delimited by semicolons.
NoteAll paths passed to includedirs
must be relative to the document root file, see Command syntax for external diagrams on how to determine the document root.
includedirs
attribute:plantuml-includedirs: path/to/plantuml/include-1;path/to/plantuml/include-2
[plantuml]
....
@startuml
!include sequences.puml!1
@enduml
....
[plantuml]
....
@startuml
!include components.puml!FRONTEND
!include components.puml!BACKEND
WebApp --> APIGateway
MobileApp --> APIGateway
APIGateway --> DB
@enduml
....
[plantuml]
....
@startuml
title this contains only B and D
!includesub subpart.puml!BASIC
@enduml
....
These [plantuml]
blocks use !include
and !includesub
directives to include
external PlantUML files. PlantUML will search the include directories specified
by includedirs
options to find sequences.puml
, components.puml
and
subpart.puml
, at:
-
path/to/plantuml/include-1
-
path/to/plantuml/include-2
plantuml_image
command with document-level includedirs
attribute:plantuml-includedirs: path/to/plantuml/include-1;path/to/plantuml/include-2
plantuml_image::path/to/my-plantuml-1.puml[]
plantuml_image::path/to/my-plantuml-2.puml[]
With path/to/my-plantuml-1.puml
as:
@startuml
!include sequences.puml!1
@enduml
With path/to/my-plantuml-2.puml
as:
@startuml
!include components.puml!FRONTEND
!include components.puml!BACKEND
WebApp --> APIGateway
MobileApp --> APIGateway
APIGateway --> DB
@enduml
In using the plantuml_image
command, the directory containing each PlantUML file
(path/to
in this case) is automatically added to the includedirs
.
Thus in rendering path/to/my-plantuml-1.puml
, PlantUML will search for
sequences.puml
in both path/to
and the directories specified by the
plantuml-includedirs
attribute.
Similarly, in rendering path/to/my-plantuml-2.puml
, PlantUML will search for
components.puml
in both path/to
and the directories specified by the
plantuml-includedirs
attribute.
Diagram-level includedirs
option
The includedirs
option can be used to specify include directories (separated
by semicolons) for both [plantuml]
blocks and the plantuml_image
command.
This option applies only to a single diagram in the document without affecting others.
The diagram-level includedirs
configuration can be used together with the
document-level configuration to provide more granular control over include
paths, where it is considered to have higher precedence than the document-level
configuration.
Syntax:
[plantuml,includedirs="{path1};{path2};..."]
Where,
-
{path1}
,{path2}
, etc. -
paths to directories containing PlantUML files to be included, delimited by semicolons.
includedirs
in [plantuml]
blocks[plantuml,includedirs="path/to/plantuml/include-1"]
....
@startuml
!include sequences.puml!1
@enduml
....
[plantuml,includedirs="path/to/plantuml/include-2"]
....
@startuml
!include components.puml!FRONTEND
!include components.puml!BACKEND
WebApp --> APIGateway
MobileApp --> APIGateway
APIGateway --> DB
@enduml
....
This plugin will search sequences.puml
in path/to/plantuml/include-1
and
components.puml
in path/to/plantuml/include-2
.
includedirs
with plantuml_image
commandplantuml_image::path/to/my-plantuml-1.puml[includedirs=path/to/plantuml/include-1]
plantuml_image::path/to/my-plantuml-2.puml[includedirs=path/to/plantuml/include-2]
Image attributes
The block and command syntaxes both support standard AsciiDoc image attributes to customize the appearance and behavior of the generated PlantUML diagrams.
Supported attributes are as follows:
id
-
Element identifier
title
-
Image title/caption
alt
-
Alternative text
width
-
Image width
height
-
Image height
align
-
Alignment (left, center, right)
float
-
Float positioning
role
-
CSS class/role
Block syntax:
[plantuml,{image-attributes}]
....
{PlantUML diagram source here}
....
Command syntax:
plantuml_image::{path}[{image-attributes}]
Where,
{image-attributes}
-
Comma-separated list of AsciiDoc image attributes in
key=value
format.
[plantuml]
block[plantuml,id=my-diagram,title="My Sequence Diagram",width=600,height=400]
....
@startuml
Alice -> Bob: Hello
@enduml
....
Filename specification
PlantUML supports specifying custom filenames for generated diagrams using the
@start{type} [filename]
directive, where {type}
is the diagram type (e.g.,
uml
, mindmap
, etc.) and filename
is the desired name for the output
file.
This feature is not well documented in official PlantUML documentation, but is described at:
-
PlantUML Language Reference Guide, 4.7, where
@startuml PERT
is used -
PlantUML Forum: Please specify filename @startuml extension automatically
When a custom filename is specified, PlantUML generates the output file using the specified filename and the appropriate file extension based on the diagram type.
This custom filename feature is supported in both block and command syntaxes.
Syntax:
[plantuml]
....
@startuml {custom-filename}
{PlantUML diagram source here}
@enduml
....
Where,
{custom-filename}
-
Desired name for the generated diagram file, without file extension.
[plantuml]
block[plantuml]
....
@startuml AliceToBob
Alice -> Bob: Hello
@enduml
....
This generates AliceToBob.png
(which is the default format since none was
specified) instead of an auto-generated filename. This file is then embedded in
the output document using the specified filename.
Disable PlantUML processing
It is possible to disable PlantUML processing either document-wide or via an environment variable.
When disabled, PlantUML blocks are rendered as code listings instead of diagrams.
The :plantuml-disabled:
document attribute can be used to disable PlantUML
processing for a specific document.
Syntax:
:plantuml-disabled:
[plantuml]
....
@startuml
Alice -> Bob: Hello
@enduml
....
This renders the PlantUML block as a code listing instead of a diagram.
The same effect can be achieved using by setting the PLANTUML_DISABLED
environment variable to true
.
Syntax:
$ PLANTUML_DISABLED=true metanorma ...
$ PLANTUML_DISABLED=true metanorma document.adoc
File organization
Generated PlantUML images are stored in a _plantuml_images/
directory
relative to the document location (the document root, if it is made of multiple
files).
This directory is automatically created if it doesn’t exist.
Development
Architecture
This plugin follows a layered architecture that separates concerns between Metanorma integration and PlantUML execution:
Metanorma Document
↓
BlockProcessor ← (processes `[plantuml]` blocks)
and ImageBlockMacroProcessor ← (processes `plantuml_image::` commands)
↓
Backend ← (Metanorma integration, paths, validation)
↓
Wrapper ← (Java/JAR execution, file I/O)
↓
PlantUML JAR ← (diagram generation)
BlockProcessor
-
Processes
[plantuml]
blocks in Metanorma documents and integrates with the Metanorma rendering pipeline. ImageBlockMacroProcessor
-
Processes
plantuml_image::{path}[{options}]
commands in Metanorma documents and integrates with the Metanorma rendering pipeline. Backend
-
Handles Metanorma-specific logic including document paths, PlantUML source validation, filename extraction, and attribute mapping.
Wrapper
-
Provides low-level PlantUML JAR execution with cross-platform Java handling, file I/O operations, and format conversion.
Version mapping
This gem uses semantic versioning independent of the PlantUML JAR version.
The following table shows the relationship between gem versions and bundled PlantUML versions:
Gem version | PlantUML version | Notes |
---|---|---|
1.0.0 |
1.2025.4 |
Latest release with updated architecture |
1.0.5 |
1.2025.7 |
Latest release |
This approach allows the gem to follow standard semantic versioning practices while clearly documenting which PlantUML version is bundled with each release.
Updating PlantUML version
General
This gem bundles a specific version of PlantUML JAR file.
There are two ways to update to a newer version.
Automatic update (recommended)
The simplest way to update PlantUML is to use the automated update task:
$ bundle exec rake update_plantuml
This task will:
-
Search GitHub for the latest valid PlantUML release (excluding pre-releases and native builds)
-
Compare with the current version and skip if already up to date
-
Update version files automatically (both PlantUML and gem versions)
-
Download and verify the new JAR file
-
Test the JAR functionality to ensure it works correctly
The task uses exit codes to indicate the result:
-
Exit code 0: No update needed (already up to date)
-
Exit code 1: Update completed successfully
-
Exit code 2: Update failed due to an error
Manual update
For manual updates or to specify a particular version:
-
Check the latest PlantUML release at https://github.com/plantuml/plantuml/releases
-
Use the manual version update task:
$ bundle exec rake update_plantuml_version[1.2025.7]
-
Download the new JAR file:
$ bundle exec rake clean_jar download_jar
-
Test the functionality:
$ bundle exec rake test_plantuml
Version checking
You can check the current PlantUML and gem versions:
$ bundle exec rake check_plantuml_version
You can find the latest available PlantUML version:
$ bundle exec rake find_latest_plantuml
Available rake tasks
PlantUML management tasks
$ bundle exec rake update_plantuml # Update PlantUML to latest version (automatic)
$ bundle exec rake update_plantuml_version[VERSION] # Update PlantUML to specific version (manual)
$ bundle exec rake check_plantuml_version # Check current PlantUML and gem versions
$ bundle exec rake find_latest_plantuml # Find latest valid PlantUML release
$ bundle exec rake test_plantuml # Test PlantUML JAR functionality
JAR file management tasks
$ bundle exec rake download_jar # Download PlantUML JAR file
$ bundle exec rake clean_jar # Remove downloaded JAR file
Development tasks
$ bundle exec rake spec # Run tests
$ bundle exec rake # Default task: download JAR + run tests
Task descriptions
update_plantuml
-
Automatically finds the latest valid PlantUML release, updates version files, downloads the new JAR, and tests functionality. This is the recommended way to update PlantUML.
update_plantuml_version[VERSION]
-
Manually updates the PlantUML version in
version.rb
to the specified version and increments the gem version. Use this when you need to specify a particular PlantUML version. check_plantuml_version
-
Displays the current PlantUML JAR version and gem version from
version.rb
. find_latest_plantuml
-
Searches GitHub for the latest valid PlantUML release, filtering out pre-releases, native builds, and invalid versions. Shows the version and release information.
test_plantuml
-
Tests the downloaded PlantUML JAR by running version checks and generating a test diagram to ensure functionality.
download_jar
-
Downloads the PlantUML JAR file based on the version specified in
version.rb
. Creates thedata/
directory if it doesn’t exist. clean_jar
-
Removes the downloaded PlantUML JAR file from
data/plantuml.jar
.
Documentation
Please refer to https://www.metanorma.org.
Copyright and license
Copyright Ribose.
PlantUML is open-sourced under multiple licenses. For more details, please refer to the PlantUML repository at https://github.com/plantuml/plantuml.
For the purposes of this plugin, it is distributed under the MIT license.
Licensed under the 2-Clause BSD License.