plantuml icon indicating copy to clipboard operation
plantuml copied to clipboard

New command-line interface

Open arnaudroques opened this issue 1 month ago β€’ 13 comments

We are currently redesigning the PlantUML command-line options to better align with the GNU command-line standards.

This means:

  • The new options follow consistent naming and structure.
  • The legacy options will still be supported for a transition period, but they will no longer be documented.

πŸ‘‰ Your feedback is very valuable at this stage! We invite you to test to let us know what feels clear (or confusing).

Below is the full list of options that will be available in the future beta release:

plantuml - generate diagrams from plain text

Usage:
  java -jar plantuml.jar [options] [file|dir]...
  java -jar plantuml.jar [options] --gui

Description:
  Process PlantUML sources from files, directories (optionally recursive), or stdin (-pipe).

Wildcards (for files/dirs):
  *   any characters except '/' and '\'
  ?   exactly one character except '/' and '\'
  **  any characters across directories (recursive)
  Tip: quote patterns to avoid shell expansion (e.g., "**/*.puml").

General:
 -h, --help ....................... Show help and usage information
     --help-more .................. Show extended help (advanced options)
     --version .................... Show PlantUML and Java version
     --author ..................... Show information about PlantUML authors
     --gui ........................ Launch the graphical user interface
     --dark-mode .................. Render diagrams in dark mode
 -v, --verbose .................... Enable verbose logging
     --duration ................... Print total processing time
     --progress-bar ............... Show a textual progress bar
     --splash-screen .............. Show splash screen with progress bar
     --check-graphviz ............. Check Graphviz installation
     --http-server[:<port>] ....... Start internal HTTP server for rendering (default port : 4242)

Input & preprocessing:
 -p, --pipe ....................... Read source from stdin, write result to stdout
 -D<var>=<value>,
     --define <VAR>=<value> ....... Define a preprocessing variable (equivalent to '!define <var> <value>')
 -I<file>,
     --include <file> ............. Include external file (as with '!include <file>')
 -P<key>=<value>,
     --pragma <key>=<value> ....... Set pragma (equivalent to '!pragma <key> <value>')
 -S<key>=<value>,
     --skinparam <key>=<value> .... Set skin parameter (equivalent to 'skinparam <key> <value>')
     --theme <name> ............... Apply a theme
     --config <file> .............. Specify configuration file
     --charset <name> ............. Use a specific input charset
     --exclude <pattern> .......... Exclude input files matching the given pattern

Execution control:
     --check-syntax ............... Check diagram syntax without generating images
     --stop-on-error .............. Stop at the first syntax error
     --check-before-run ........... Pre-check syntax of all inputs and stop faster on error
     --no-error-image ............. Do not generate error images for diagrams with syntax errors
     --graphviz-timeout <seconds>   Set Graphviz processing timeout (in seconds)
     --threads <n|auto> ........... Use <n> threads for processing  (auto = available processors)

Metadata & assets:
     --extract-source ............. Extract embedded PlantUML source from PNG or SVG metadata
     --disable-metadata ........... Do not include metadata in generated files
     --skip-fresh ................. Skip PNG/SVG files that are already up-to-date (using metadata)
     --sprite <4|8|16[z]> <file> .. Encode a sprite definition from an image file
     --encode-url ................. Generate an encoded PlantUML URL from a source file
     --decode-url <string> ........ Decode a PlantUML encoded URL back to its source
     --list-keywords .............. Print the list of PlantUML language keywords
     --dot-path <path-to-dot-exe>   Specify the path to the Graphviz 'dot' executable
     --ftp-server ................. Start a local FTP server for diagram rendering (rarely used)

Output control:
     --output-dir <dir> ........... Generate output files in the specified directory
     --overwrite .................. Allow overwriting of read-only output files

Output format (choose one):
 -f <name>, --format <name> ....... Set the output format for generated diagrams
                                    (e.g. png, svg, pdf, eps, latex, txt, utxt, obfuscate, preproc...)

Available formats:
     --eps ........................ Generate images in EPS format
     --html ....................... Generate HTML files for class diagrams
     --latex ...................... Generate LaTeX/TikZ output
     --latex-nopreamble ........... Generate LaTeX/TikZ output without preamble
     --obfuscate .................. Replace text in diagrams with obfuscated strings to share diagrams safely
     --pdf ........................ Generate PDF images
     --png ........................ Generate PNG images (default)
     --preproc .................... Generate the preprocessed source after applying !include, !define... (no rendering)
     --scxml ...................... Generate SCXML files for state diagrams
     --svg ........................ Generate SVG images
     --txt ........................ Generate ASCII art diagrams
     --utxt ....................... Generate ASCII art diagrams using Unicode characters
     --vdx ........................ Generate VDX files
     --xmi ........................ Generate XMI files for class diagrams

Statistics:
     --disable-stats .............. Disable statistics collection (default behavior)
     --enable-stats ............... Enable statistics collection
     --export-stats-html .......... Export collected statistics to an HTML report and exit
     --export-stats ............... Export collected statistics to a text report and exit
     --html-stats ................. Output general statistics in HTML format
     --xml-stats .................. Output general statistics in XML format
     --realtime-stats ............. Generate statistics in real time during processing
     --loop-stats ................. Continuously print usage statistics during execution


Examples:
  # Process all .puml recursively
  java -jar plantuml.jar "**/*.puml"

  # Check syntax only (CI)
  java -jar plantuml.jar --check-syntax src/diagrams

  # Read from stdin and write to stdout (SVG)
  cat diagram.puml | java -jar plantuml.jar --svg -pipe > out.svg

  # Encode a sprite from an image
  java -jar plantuml.jar --sprite 16z myicon.png

  # Use a define
  java -jar plantuml.jar -DAUTHOR=John diagram.puml

  # Change output directory
  java -jar plantuml.jar --format svg --output-dir out diagrams/

Exit codes:
  0   Success
  >0  Error (syntax error or processing failure)

See also:
  java -jar plantuml.jar --help-more
  Documentation: https://plantuml.com

Thanks for your help and feedback!

arnaudroques avatar Oct 11 '25 09:10 arnaudroques

     -preproc ..................... Output preprocessor text of diagrams

Is this intentionally a single hyphen?

jeanmarc avatar Oct 15 '25 05:10 jeanmarc

Hi @jeanmarc

     -preproc ..................... Output preprocessor text of diagrams

Is this intentionally a single hyphen?

Yes, that is just for backward compatibility.

But according to:

  • https://github.com/plantuml/plantuml/commit/c719239231f14fc503f55a2c253627421d93584f

The help had be corrected by @arnaudroques

Regard, Th.

The-Lum avatar Oct 15 '25 06:10 The-Lum

This is controlling input, isn't it? --exclude <pattern> .......... Exclude input files matching the given pattern

SieDa avatar Oct 18 '25 07:10 SieDa

Hi @jeanmarc

     -preproc ..................... Output preprocessor text of diagrams

Is this intentionally a single hyphen?

Yes, that is just for backward compatibility.

But according to:

* [c719239](https://github.com/plantuml/plantuml/commit/c719239231f14fc503f55a2c253627421d93584f)

The help had be corrected by @arnaudroques

Regard, Th.

For me -preproc is an exception in the list and not self-explaining like the others. All other formats generate an output file.ext where ext ist the fmt which is input on --format fmt or it is specified by --fmt. If format preproc is not such an option, then it should be added to output-format:

     --format <fmt>, -f <fmt> ..... Set the output format for generated diagrams and output into files with extension '.fmt'
                                    (see 'Available formats:' for 'fmt', e.g. png, svg, pdf, eps, latex, txt, utxt),
     --preproc, -preproc ........... Output preprocessor text of diagrams into file with extentions '.preproc'. 

By that you can keep backword compatibility adressed and the exception properly explained and at sometime eliminated. You should adress if multiple <fmt> can be choosen for output in one step, like --format png svg and how that works with --preproc.

Or : Set the output format for one generated diagram.

Thanks a lot for this overall approach.

SieDa avatar Oct 18 '25 08:10 SieDa

This is controlling input, isn't it? --exclude <pattern> .......... Exclude input files matching the given pattern

Yes, you’re right, thanks for pointing that out!

For clarity, we've also updated the original post with the latest version of the help text.

Thanks again!

arnaudroques avatar Oct 18 '25 09:10 arnaudroques

You should adress if multiple <fmt> can be choosen for output in one step, like --format png svg

This is not possible yet, but in the future we are considering support for --format png --format svg or --png --svg.

arnaudroques avatar Oct 18 '25 10:10 arnaudroques

It would be very very very appreciated to have a parameter to set the path to a skin file. I have PlantUml files in many different directories where I want to be able to use the same skin file for all of them. In Linux I solve this by using symbolic links in the directories to the same skin file. Unfortunately I have no solution for this if I am on Windows (e.g. developing in VS Code). Then it would have been great if you could specify the path to your skin file to the PlantUml extension in VS Code .

pederalm avatar Oct 23 '25 07:10 pederalm

Path to a skin file is a first step. Imagine you provide a directory with general templates for header, foooter and logo and reference from header.puml by !include ./logo/mylogo.svg to include the logo relative to the location of the header template, that does not work. It will look from the directory of where you work and include the header template into your diagram. Providing the templates into your project by git submodule, to easily manage them to stay actual and use that in allyour projects is the next level of complexity, you can't easily express inside the logo embedding. You need a ./resolution relative to the path of the file, that is using it and you need a special .p./ resolution to the directory where your main PlantUML diagram file is located and a .git./ resolution to the base of the git repo that you are working with and from there you can define where you embed your template submodule. Globally you can decide to have it in ~/plantuml/templates, but then the version is distracted from the central git repo, but also `~/' is not yet supported to relate to your personal directory.

Today you have to decide to manage all diagramms on the same directory level inside your repo, then you can handle that with '../and./` somehow - and that is not nice to go with but it works savely ;-)

SieDa avatar Oct 23 '25 10:10 SieDa

It would be very very very appreciated to have a parameter to set the path to a skin file. I have PlantUml files in many different directories where I want to be able to use the same skin file for all of them. In Linux I solve this by using symbolic links in the directories to the same skin file. Unfortunately I have no solution for this if I am on Windows (e.g. developing in VS Code). Then it would have been great if you could specify the path to your skin file to the PlantUml extension in VS Code .

Just to be sure, are you refering to the !include directive or to the skin directive?

arnaudroques avatar Oct 23 '25 12:10 arnaudroques

Imagine you provide a directory with general templates for header, foooter and logo and reference from header.puml by !include ./logo/mylogo.svg to include the logo relative to the location of the header template, that does not work. It will look from the directory of where you work and include the header template into your diagram. Providing the templates into your project by git submodule, to easily manage them to stay actual and use that in allyour projects is the next level of complexity, you can't easily express inside the logo embedding. You need a ./resolution relative to the path of the file, that is using it and you need a special .p./ resolution to the directory where your main PlantUML diagram file is located and a .git./ resolution to the base of the git repo that you are working with and from there you can define where you embed your template submodule. Globally you can decide to have it in ~/plantuml/templates, but then the version is distracted from the central git repo, but also `~/' is not yet supported to relate to your personal directory.

This discussion gave me a lot of ideas. Indeed, ./ represents the directory that contains the initial file, even when this ./ is used inside files included by that first file β€” even if those included files are located in other directories. (Well, at least I think so… I’m not entirely sure anymore β€” can someone confirm? πŸ™‚)

But we could imagine introducing other syntaxes. For instance, :/ could represent the directory of the current file (the included file that is currently being processed).

And for those writing scripts, we could add:

  • #/ β€” the directory containing the plantuml.jar file
  • $/ β€” the current working directory when the script was launched

Example setup

You have the following files:

/home/Joe/current/example.puml
/home/Joe/current/lib/style.puml
/home/Joe/software/install/plantuml.jar

And you run:

cd /home/Joe
java -jar /home/Joe/software/install/plantuml.jar current/example.puml

Inside example.puml, you include:

!include /home/Joe/current/lib/style.puml

Meaning of the proposed path prefixes

Context Symbol Meaning Concrete value in this example
From example.puml ./ Directory of the initial file /home/Joe/current
:/ Directory of the current file being processed /home/Joe/current
#/ Directory containing plantuml.jar /home/Joe/software/install
$/ Current working directory when PlantUML was run /home/Joe
From style.puml (included by example.puml) ./ Directory of the initial file (still example.puml) /home/Joe/current
:/ Directory of the currently included file /home/Joe/current/lib
#/ Directory containing plantuml.jar /home/Joe/software/install
$/ Current working directory when PlantUML was run /home/Joe

Summary

  • ./ β†’ always refers to the directory of the first loaded file (the entry point).
  • :/ β†’ refers to the directory of the file currently being processed, and therefore changes with each !include.
  • #/ β†’ constant throughout execution; points to the directory containing the PlantUML JAR.
  • $/ β†’ the working directory from which the Java process was launched.

This is only a proposal... any thoughts?

arnaudroques avatar Oct 23 '25 12:10 arnaudroques

I Like the proposal. See it from another more global view.

  • ./, ../ and / stay unchanged to what we have now
  • :/ the current file, which influences the used !include :/logo/logo.svg beeing in a subdir of the current file (header.puml),

But

  • #/ might be resolved by a new builtin function like %path/. That name will fit to the known behaviour of %version

As you start coding scripts (.sh as in bash or other shells), how to bring both worlds together?

  • ~/ might be a good standard to support anyway. /home can be accessed by %getenv($HOME), if working in the same way, it might be easy to implement and it might leed to more simple coding.

I would therefor make a major shift - but saving the comunity's work might lead to the other way round:

  • ./ be the working directory, where you e.g. run ./script.sh or call java.

  • #/ therefore would take the todays first loaded file (entry point for the diagramm, actually replace ./).

  • $ starts a Variable, % starts a built in function - that might mess up parsing the code.

Does this match into this ticket or should that be discussed separately ?

SieDa avatar Oct 23 '25 14:10 SieDa

Does this match into this ticket or should that be discussed separately ?

Sure, please go to https://github.com/plantuml/plantuml/issues/2400 for this future feature :-) Thanks for your help!

arnaudroques avatar Oct 23 '25 17:10 arnaudroques

  • -pipe is spelled with a single dash twice in the help text. According to the new design, it should be spelled wiht two dashes (one dash is accepted for backward compatibility, but the new way is two dashes)
  • Compared to https://github.com/plantuml/plantuml/issues/1753, two output formats seem to be missing
    • -teps:text Generate images using EPS format, preserving text as text (as opposed to -teps Generate images using EPS format, rendering text as outlines)
    • -tbraille Generate Braille image [Ref. QA-4752]

VladimirAlexiev avatar Nov 11 '25 14:11 VladimirAlexiev