mikitex70 / plantuml-markdown

PlantUML plugin for Python-Markdown
BSD 2-Clause "Simplified" License
192 stars 55 forks source link

Build Status

PlantUML Extension for Python-Markdown

Introduction

This plugin implements a block extension that can be used to specify a PlantUML diagram that will be converted into an image and inserted into the document.

Syntax:

::uml:: [format="png|svg|txt"] [classes="class1 class2 ..."] [alt="text for alt"] [title="Text for title"] [width="300px"] [height="300px"]
  PlantUML script diagram
::end-uml::

Example:

::uml:: format="png" classes="uml myDiagram" alt="My super diagram placeholder" title="My super diagram" width="300px" height="300px"
  Goofy ->  MickeyMouse: calls
  Goofy <-- MickeyMouse: responds
::end-uml::

The GitLab/GitHub block syntax is also recognized. Example:

```plantuml id="myDiag" format="png" classes="uml myDiagram" alt="My super diagram placeholder" title="My super diagram" width="300px" height="300px"
  Goofy ->  MickeyMouse: calls
  Goofy <-- MickeyMouse: responds
```

Options are optional (otherwise the wouldn't be options), but if present must be specified in the order id, format, classes, alt, title, width, height, and source. The option value may be enclosed in single or double quotes.

Supported values for format parameter are:

The width and height options must include a CSS unit.

source parameter is used for inclusion of an external source diagram instead on an inline code. Here's an example in GitLab/GitHub block syntax.

basic.puml

@startuml
title Authentication Sequence
    Alice->Bob: Authentication Request
    note right of Bob: Bob thinks about it
    Bob->Alice: Authentication Response
@enduml

index.md

```plantuml source="basic.puml"
'' This code is appended to the contents of basic.puml
Goofy ->  MickeyMouse: calls
Goofy <-- MickeyMouse: responds
```

Installation

To use the plugin with Python-Markdown you have the following options. Please note that before using the package, you will need to configure which PlantUML binary to use: a local binary, or a remote server (see below for further details).

  1. [Linux] Use Python's pip package manager and run the following command. After running, the package should be ready to use.
    $ pip install plantuml-markdown
  2. [Windows] You can use Chocolatey, a package manager for Windows. From an elevated terminal, run the following command:
    >>> choco install plantuml

    (Note: This command will install all dependencies, Java and Graphviz included, see https://chocolatey.org/packages/plantuml for details.)

After the package is installed, you can use this plugin by activating it in the markdown_py command. For example:

  $ markdown_py -x plantuml_markdown mydoc.md > out.html

Using a local PlantUML binary

You need to install PlantUML (see the site for details) and Graphviz 2.26.3 or later. The plugin expects a program plantuml in the classpath. If not installed by your package manager, you can create a shell script and place it somewhere in the classpath. For example, save the following into /usr/local/bin/plantuml (supposing PlantUML installed into /opt/plantuml):

#!/bin/bash
java $PLANTUML_JAVAOPTS -jar /opt/plantuml/plantuml.jar ${@}

The PLANTUML_JAVAOPTS variable can be used to set specific Java options, such as memory tuning options, or to set system variable used by PlantUML, such as then include search path. This would avoid modifications of the plantuml script. For example, with a diagram like:

```plantuml
!include myDefs.puml

A --> B

you can do:

export PLANTUML_JAVAOPTS="-Dplantuml.include.path=$HOME/plantuml_defs" markdown_py -x plantuml_markdown mydoc.md > out.html


The same thing can be done using the environment variable `_JAVA_OPTIONS`, which is read by default by the `java`
executable.

On Windows can be used the following `plantuml.bat` (many thanks to [henn1001](https://github.com/henn1001)):

@echo off set mypath=%~dp0

setlocal set GRAPHVIZ_DOT=%mypath%\Graphviz\bin\dot.exe

java %PLANTUML_JAVAOPTS% -jar %mypath%\plantuml.jar %*


Make sure the `plantuml.bat` is on the path.

For [Gentoo Linux][Gentoo] there is an ebuild at http://gpo.zugaina.org/dev-util/plantuml/RDep: you can download
the ebuild and the `files` subfolder or you can add the `zugaina` repository with [layman][]
(recommended).

### Using a remote server

#### Using a PlantUML server

From version `2.0` a [PlantUML server] can be used for rendering diagrams. This speedups a
lot the diagrams rendering but needs to send the diagram source to a server.

You can download the [war](http://sourceforge.net/projects/plantuml/files/plantuml.war/download) and deploy in a servlet
container, or you can run it as a [docker container](https://hub.docker.com/r/plantuml/plantuml-server/).

In either cases you need to specify the URL of the server in a configuration file like:

```yaml
plantuml_markdown:
  server: http://www.plantuml.com/plantuml  # PlantUML server, for remote rendering
  # other global options
  insecure: False                           # set to True if the server uses self-signed certificates
  cachedir: /tmp                            # set a non-empty value to enable caching
  base_dir: .                               # where to search for diagrams to include
  config:                                   # PlantUML config file, relative to base_dir (a PlantUML file included in every diagram)
  format: png                               # default diagram image format
  classes: class1,class2                    # default diagram classes
  encoding: utf-8                           # character encoding for external files (default utf-8)
  title: UML diagram                        # default title (tooltip) for diagram images
  alt: UML diagram image                    # default `alt` attribute for diagram images
  image_maps: True                          # generate image maps when the format is png and there are hyperlinks
  priority: 30                              # plugin priority; the higher, the sooner will be applied (default 30)
  http_method: GET                          # GET or POST  - note that plantuml.com only supports GET (default GET)       
  fallback_to_get: True                     # When using POST, should GET be used as fallback (POST will fail if @startuml/@enduml tags not used) (default True)
  theme: bluegray                           # theme to be set, can be overridden inside puml files, (default none)
  puml_notheme_cmdlist: [                             
                          'version', 
                          'listfonts', 
                          'stdlib', 
                          'license'
                        ]                   # theme will not be set if listed commands present (default as listed)

Then you need to specify the configuration file on the command line:

markdown_py -x plantuml_markdown -c myconfig.yml mydoc.md > out.html

Using a Kroki server

Starting from version 3.7.0 a Kroki server can be used as an alternative of PlantUML server. The configuration is similar, only use the kroki_server configuration property instead of the server property.

File inclusion management

Usually, remote servers, for security reasons, do not allow arbitrary '!include' instructions to be executed.

To try to bypass this limitation, the plugin behaves as follows:

If using a local PlantUML installation includes works out of the box only if includes are in the current directory. If they are in other directories there are two possibilities:

Plugin options

The plugin has several configuration option:

For passing options to the plantuml_plugin see the documentation of the tool you are using.

For markdown_py, simply write a YAML file with the configurations and use the -c option on the command line. See the Using a PlantUML server section for an example.

A note on the priority configuration

With markdownm_py plugin extensions can conflict if they manipulate the same block of text. Examples are the Fenced Code Blocks or Snippets extensions.

Every plugin has a priority configured, most wants to be run as te first or the last plugin in the chain. The plantuml_markdown plugin fits in the middle, trying to work as best without conflicting with other plugins.

If you are getting strange behaviours in conjunction with other plugins, you can use the priority configuration to try to avoid the conflict, letting the plugin run before (higher value) or after other plugins (lower value).

As an example of possible conflicts see issue #38.

Running tests

plantuml-markdown is tested with Python >= 3.6 and Markdown >= 3.0.1. Older versions of Python or Markdown may work, but if it doesn't I can't guarantee a fix as they are end-of-life versions.

The test execution requires a specific version of PlantUML (the image generated can be different with different PlantUML versions).

Before to run tests, install the required dependencies:

pip install -r test-requirements.txt

To run the tests, execute the following command:

nose2 --verbose -F

This command uses a custom version of the plantuml command which will download the expected version of PlantUML for tests execution without clobbering the system.

Running tests using Docker

This requires docker and docker-compose to be installed

First setup a small python alpine image with all the dependencies pre-installed.

docker-compose build

then run the container to automatically trigger tests and print the output mapping the contents of your workspace

docker-compose up

To set specific version of Markdown or Python:

PTYHON_VER=3.9 MARKDOWN_VER=3.3.7 docker-compose build && docker-compose up