Giter Site home page Giter Site logo

yuzutech / kroki Goto Github PK

View Code? Open in Web Editor NEW
2.7K 24.0 204.0 57.95 MB

Creates diagrams from textual descriptions!

Home Page: https://kroki.io

License: MIT License

Dockerfile 0.06% Java 2.14% JavaScript 97.46% HTML 0.02% Makefile 0.01% CSS 0.17% Shell 0.03% PureBasic 0.02% HyPhy 0.01% HCL 0.01% Mermaid 0.01% Go 0.01% TeX 0.06% D2 0.01% SystemVerilog 0.01%
diagrams text images api erd c4 plantuml uml ditaa blockdiag

kroki's Introduction

Kroki

GitHub Actions build status Zulip chat

Kroki provides a unified API with support for BlockDiag (BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, RackDiag), BPMN, Bytefield, C4 (with PlantUML), D2, DBML, Diagrams.net (experimental), Ditaa, Erd, Excalidraw, GraphViz, Mermaid, Nomnoml, Pikchr, PlantUML, SvgBob, Symbolator, UMLet, Vega, Vega-Lite, WaveDrom and WireViz…​ and more to come!

Quickstart

This section offers a basic tutorial for evaluating Kroki. More comprehensive installation instructions are in the Kroki documentation.

Usage

Kroki uses a simple algorithm (deflate + base64) to encode your diagram in the URL:

GET /plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000

You can also call Kroki with POST:

POST /
{
  "diagram_source": "Bob -> Alice : hello",
  "diagram_type": "plantuml",
  "output_format": "svg"
}

In this case, you don’t need to encode your diagram.

It’s also possible to send your diagram as plain text using the Content-Type header. The output format will be specified using the Accept header and the diagram source will be sent as the request body:

POST /plantuml
Accept: image/svg+xml
Content-Type: text/plain

Bob -> Alice : hello

You can also define the output format in the URL if you don’t want to add an Accept header:

POST /plantuml/svg
Content-Type: text/plain

Bob -> Alice : hello

The same concept applies when sending the diagram as JSON:

POST /plantuml/svg
{
  "diagram_source": "Bob -> Alice : hello"
}

Project layout

Kroki has a modular architecture:

server

A Java web server (powered by Vert.x) that acts as a gateway. Kroki server is built using Maven.

umlet

A tiny Java API on top of UMlet (mini) to generate diagrams.

nomnoml

A Node.js CLI on top of the Nomnoml diagram library.

vega

A Node.js CLI on top of the vega diagram library. Also supports Vega-Lite concise grammar.

mermaid

A companion web server written in JavaScript (powered by micro) that provides Mermaid diagram library.

bpmn

A companion web server written in JavaScript (powered by micro) that provides bpmn-js diagram library.

bytefield

A Node.js CLI on top of the bytefield-svg diagram library.

wavedrom

A Node.js CLI on top of the wavedrom diagram library.

excalidraw

A companion web server written in JavaScript (powered by micro) that provides Excalidraw.

diagrams.net

A companion web server written in JavaScript (powered by micro) that provides diagrams.net.

Build

Gateway Server

The first step is to build the project using Maven:

$ make buildServer

Docker Images

To build all the Docker images, use the following command:

$ sudo make buildDockerImages
Note
sudo might not be needed depending on your distribution and docker configuration.

Run

Once the Docker images are built, you can run Kroki using docker:

$ docker run -d -p 8000:8000 yuzutech/kroki

Companion Containers

If you want to use one of the following diagram libraries then you will also need to start the corresponding companion container:

yuzutech/kroki-mermaid

Mermaid

yuzutech/kroki-bpmn

BPMN

yuzutech/kroki-excalidraw

Excalidraw

yuzutech/kroki-diagramsnet (experimental)

diagrams.net

You can use docker-compose to run multiple containers:

docker-compose.yml
version: "3"
services:
  core:
    image: yuzutech/kroki
    environment:
      - KROKI_MERMAID_HOST=mermaid
      - KROKI_BPMN_HOST=bpmn
      - KROKI_EXCALIDRAW_HOST=excalidraw
    ports:
      - "8000:8000"
  mermaid:
    image: yuzutech/kroki-mermaid
    expose:
      - "8002"
  bpmn:
    image: yuzutech/kroki-bpmn
    expose:
      - "8003"
  excalidraw:
    image: yuzutech/kroki-excalidraw
    expose:
      - "8004"
  # experimental!
  diagramsnet:
    image: yuzutech/kroki-diagramsnet
    expose:
      - "8005"
$ docker-compose up -d

kroki's People

Contributors

0xflotus avatar anb0s avatar arukiidou avatar bauglir avatar bobzomer avatar cmorty avatar copyrights avatar deining avatar dependabot-preview[bot] avatar dependabot[bot] avatar derlin avatar felixvanoost avatar gerlingsm avatar ggrossetie avatar gjacquenot avatar groovytron avatar heiss avatar jerojasro avatar lind avatar marcelwaldvogel avatar mattvaughan avatar mikaello avatar nejch avatar nekator avatar rfdonnelly avatar rlespinasse avatar sayakmukhopadhyay avatar ssaraswati avatar stephenc avatar sturtison avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kroki's Issues

Use relative path for root page

We are using Kroki behind a ReverseProxy and in an (virtual) subfolder. Everything is working fine, but the root page is not displayed properly because all resources are absolute paths.

Building the containers locally throws an error

The current behaviour

When we try to build the project's container, I get the following error cabal: Failed to build graphviz-2999.6.0.0. See the build log above for details..

Ouput of sudo make buildDockerImages:

cd nomnoml && make package
make[1]: Entering directory '/whatever/kroki/nomnoml'
docker build -f ops/docker/alpine/Dockerfile -t kroki-builder-nomnoml:alpine -t kroki-builder-nomnoml:latest -t kroki-builder-nomnoml:0.6.1-alpine .
Sending build context to Docker daemon  71.68kB

Step 1/9 : FROM node:10.15.0-alpine
 ---> 288d2f688643
Step 2/9 : RUN npm install -g pkg pkg-fetch
 ---> Using cache
 ---> 3c4c75c98283
Step 3/9 : ENV NODE node10
 ---> Using cache
 ---> 6a370b45d3ed
Step 4/9 : ENV PLATFORM alpine
 ---> Using cache
 ---> a4ee05cfb54a
Step 5/9 : ENV ARCH x64
 ---> Using cache
 ---> 7aa49102dfea
Step 6/9 : RUN /usr/local/bin/pkg-fetch ${NODE} ${PLATFORM} ${ARCH}
 ---> Using cache
 ---> 16a057199af7
Step 7/9 : COPY . /app
 ---> Using cache
 ---> 512be82b555b
Step 8/9 : WORKDIR /app
 ---> Using cache
 ---> 657c348dcaa2
Step 9/9 : RUN /usr/local/bin/pkg --targets ${NODE}-${PLATFORM}-${ARCH} . -o app.bin
 ---> Using cache
 ---> 40357553b986
Successfully built 40357553b986
Successfully tagged kroki-builder-nomnoml:alpine
Successfully tagged kroki-builder-nomnoml:latest
Successfully tagged kroki-builder-nomnoml:0.6.1-alpine
make[1]: Leaving directory '/whatever/kroki/nomnoml'
docker build -f server/ops/docker/build-static-erd -t kroki-builder-static-erd .
Sending build context to Docker daemon  36.72MB

Step 1/7 : FROM haskell:8
 ---> d0f33c86f706
Step 2/7 : RUN git clone https://github.com/BurntSushi/erd.git
 ---> Using cache
 ---> 23a26bf93de2
Step 3/7 : WORKDIR erd
 ---> Using cache
 ---> 6d47027f8d8f
Step 4/7 : RUN git checkout c443372d431a5020afa91989829352a2aa6b07cb
 ---> Using cache
 ---> d4e74e4d6bc3
Step 5/7 : RUN cabal update
 ---> Using cache
 ---> ef540b91b020
Step 6/7 : RUN cabal install --only-dependencies --force-reinstalls
 ---> Running in 93852ef0394e
Wrote tarball sdist to /erd/dist-newstyle/sdist/erd-0.1.3.0.tar.gz
Resolving dependencies...
Build profile: -w ghc-8.8.1 -O1
In order, the following will be built (use -v for more details):
 - containers-0.5.11.0 (lib) (requires download & build)
 - extensible-exceptions-0.1.1.4 (lib:extensible-exceptions) (requires download & build)
 - parallel-1.1.0.1 (lib:parallel) (requires download & build)
 - fgl-5.7.0.1 (lib) (requires download & build)
 - binary-0.8.7.0 (lib) (requires download & build)
 - text-1.2.4.0 (lib) (requires download & build)
 - polyparse-1.13 (lib) (requires download & build)
 - parsec-3.1.14.0 (lib) (requires download & build)
 - graphviz-2999.6.0.0 (lib:graphviz) (requires download & build)
Downloading  extensible-exceptions-0.1.1.4
Downloaded   extensible-exceptions-0.1.1.4
Downloading  containers-0.5.11.0
Starting     extensible-exceptions-0.1.1.4 (all, legacy fallback)
Downloaded   containers-0.5.11.0
Downloading  binary-0.8.7.0
Starting     containers-0.5.11.0 (lib)
Building     extensible-exceptions-0.1.1.4 (all, legacy fallback)
Downloaded   binary-0.8.7.0
Downloading  fgl-5.7.0.1
Installing   extensible-exceptions-0.1.1.4 (all, legacy fallback)
Building     containers-0.5.11.0 (lib)
Completed    extensible-exceptions-0.1.1.4 (all, legacy fallback)
Downloaded   fgl-5.7.0.1
Downloading  parallel-1.1.0.1
Downloaded   parallel-1.1.0.1
Downloading  text-1.2.4.0
Downloaded   text-1.2.4.0
Downloading  parsec-3.1.14.0
Downloaded   parsec-3.1.14.0
Downloading  polyparse-1.13
Downloaded   polyparse-1.13
Downloading  graphviz-2999.6.0.0
Downloaded   graphviz-2999.6.0.0
Installing   containers-0.5.11.0 (lib)
Completed    containers-0.5.11.0 (lib)
Starting     parallel-1.1.0.1 (all, legacy fallback)
Starting     fgl-5.7.0.1 (lib)
Starting     binary-0.8.7.0 (lib)
Building     parallel-1.1.0.1 (all, legacy fallback)
Building     fgl-5.7.0.1 (lib)
Building     binary-0.8.7.0 (lib)
Installing   parallel-1.1.0.1 (all, legacy fallback)
Completed    parallel-1.1.0.1 (all, legacy fallback)
Installing   fgl-5.7.0.1 (lib)
Completed    fgl-5.7.0.1 (lib)
Installing   binary-0.8.7.0 (lib)
Completed    binary-0.8.7.0 (lib)
Starting     text-1.2.4.0 (lib)
Building     text-1.2.4.0 (lib)
Installing   text-1.2.4.0 (lib)
Completed    text-1.2.4.0 (lib)
Starting     polyparse-1.13 (lib)
Starting     parsec-3.1.14.0 (lib)
Building     polyparse-1.13 (lib)
Building     parsec-3.1.14.0 (lib)
Installing   parsec-3.1.14.0 (lib)
Completed    parsec-3.1.14.0 (lib)
Installing   polyparse-1.13 (lib)
Completed    polyparse-1.13 (lib)
Starting     graphviz-2999.6.0.0 (all, legacy fallback)
Building     graphviz-2999.6.0.0 (all, legacy fallback)

Failed to build graphviz-2999.6.0.0.
Build log (
/root/.cabal/logs/ghc-8.8.1/graphviz-2999.6.0.0-c6eb5d98d43404431a1e831a5e372cc6643f0e2ed6c9f0444064337d13a6e254.log
):
Configuring graphviz-2999.6.0.0...
Warning: 'ghc-prof-options: -prof' is not necessary and will lead to problems
when used on a library. Use the configure flag --enable-library-profiling
and/or --enable-profiling.
Preprocessing library for graphviz-2999.6.0.0..
Building library for graphviz-2999.6.0.0..
[1 of 8] Compiling Data.GraphViz.Types.Internal ( Data/GraphViz/Types/Internal.hs, dist/build/Data/GraphViz/Types/Internal.o )
[2 of 8] Compiling Data.GraphViz.Types.Parsing ( Data/GraphViz/Types/Parsing.hs, dist/build/Data/GraphViz/Types/Parsing.o )

Data/GraphViz/Types/Parsing.hs:178:28: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘Char’
    Suppress this warning by saying ‘_ <- character '.'’
    |
178 |                 frac <- do character '.'
    |                            ^^^^^^^^^^^^^

Data/GraphViz/Types/Parsing.hs:188:25: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘Char’
    Suppress this warning by saying ‘_ <- character 'e'’
    |
188 |     where parseExp = do character 'e'
    |                         ^^^^^^^^^^^^^

Data/GraphViz/Types/Parsing.hs:268:21: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘String’
    Suppress this warning by saying ‘_ <- string fld’
    |
268 | parseField fld = do string fld
    |                     ^^^^^^^^^^

Data/GraphViz/Types/Parsing.hs:269:21: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘String’
    Suppress this warning by saying ‘_ <- whitespace'’
    |
269 |                     whitespace'
    |                     ^^^^^^^^^^^

Data/GraphViz/Types/Parsing.hs:270:21: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘Char’
    Suppress this warning by saying ‘_ <- character '='’
    |
270 |                     character '='
    |                     ^^^^^^^^^^^^^

Data/GraphViz/Types/Parsing.hs:271:21: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘String’
    Suppress this warning by saying ‘_ <- whitespace'’
    |
271 |                     whitespace'
    |                     ^^^^^^^^^^^

Data/GraphViz/Types/Parsing.hs:301:22: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘String’
    Suppress this warning by saying ‘_ <- whitespace'’
    |
301 |                      whitespace'
    |                      ^^^^^^^^^^^

Data/GraphViz/Types/Parsing.hs:302:22: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘Char’
    Suppress this warning by saying ‘_ <- parseComma’
    |
302 |                      parseComma
    |                      ^^^^^^^^^^

Data/GraphViz/Types/Parsing.hs:303:22: warning: [-Wunused-do-bind]
    A do-notation statement discarded a result of type ‘String’
    Suppress this warning by saying ‘_ <- whitespace'’
    |
303 |                      whitespace'
    |                      ^^^^^^^^^^^
[3 of 8] Compiling Data.GraphViz.Types.Printing ( Data/GraphViz/Types/Printing.hs, dist/build/Data/GraphViz/Types/Printing.o )

Data/GraphViz/Types/Printing.hs:152:16: error:
    Ambiguous occurrence ‘<>’
    It could refer to
       either ‘Prelude.<>’,
              imported from ‘Prelude’ at Data/GraphViz/Types/Printing.hs:38:8-35
              (and originally defined in ‘GHC.Base’)
           or ‘Text.PrettyPrint.<>’,
              imported from ‘Text.PrettyPrint’ at Data/GraphViz/Types/Printing.hs:(51,1)-(58,32)
              (and originally defined in ‘Text.PrettyPrint.HughesPJ’)
    |
152 | wrap b a d = b <> d <> a
    |                ^^

Data/GraphViz/Types/Printing.hs:152:21: error:
    Ambiguous occurrence ‘<>’
    It could refer to
       either ‘Prelude.<>’,
              imported from ‘Prelude’ at Data/GraphViz/Types/Printing.hs:38:8-35
              (and originally defined in ‘GHC.Base’)
           or ‘Text.PrettyPrint.<>’,
              imported from ‘Text.PrettyPrint’ at Data/GraphViz/Types/Printing.hs:(51,1)-(58,32)
              (and originally defined in ‘Text.PrettyPrint.HughesPJ’)
    |
152 | wrap b a d = b <> d <> a
    |                     ^^

Data/GraphViz/Types/Printing.hs:155:26: error:
    Ambiguous occurrence ‘<>’
    It could refer to
       either ‘Prelude.<>’,
              imported from ‘Prelude’ at Data/GraphViz/Types/Printing.hs:38:8-35
              (and originally defined in ‘GHC.Base’)
           or ‘Text.PrettyPrint.<>’,
              imported from ‘Text.PrettyPrint’ at Data/GraphViz/Types/Printing.hs:(51,1)-(58,32)
              (and originally defined in ‘Text.PrettyPrint.HughesPJ’)
    |
155 | commaDel a b = unqtDot a <> comma <> unqtDot b
    |                          ^^

Data/GraphViz/Types/Printing.hs:155:35: error:
    Ambiguous occurrence ‘<>’
    It could refer to
       either ‘Prelude.<>’,
              imported from ‘Prelude’ at Data/GraphViz/Types/Printing.hs:38:8-35
              (and originally defined in ‘GHC.Base’)
           or ‘Text.PrettyPrint.<>’,
              imported from ‘Text.PrettyPrint’ at Data/GraphViz/Types/Printing.hs:(51,1)-(58,32)
              (and originally defined in ‘Text.PrettyPrint.HughesPJ’)
    |
155 | commaDel a b = unqtDot a <> comma <> unqtDot b
    |                                   ^^

Data/GraphViz/Types/Printing.hs:158:25: error:
    Ambiguous occurrence ‘<>’
    It could refer to
       either ‘Prelude.<>’,
              imported from ‘Prelude’ at Data/GraphViz/Types/Printing.hs:38:8-35
              (and originally defined in ‘GHC.Base’)
           or ‘Text.PrettyPrint.<>’,
              imported from ‘Text.PrettyPrint’ at Data/GraphViz/Types/Printing.hs:(51,1)-(58,32)
              (and originally defined in ‘Text.PrettyPrint.HughesPJ’)
    |
158 | printField f v = text f <> equals <> toDot v
    |                         ^^

Data/GraphViz/Types/Printing.hs:158:35: error:
    Ambiguous occurrence ‘<>’
    It could refer to
       either ‘Prelude.<>’,
              imported from ‘Prelude’ at Data/GraphViz/Types/Printing.hs:38:8-35
              (and originally defined in ‘GHC.Base’)
           or ‘Text.PrettyPrint.<>’,
              imported from ‘Text.PrettyPrint’ at Data/GraphViz/Types/Printing.hs:(51,1)-(58,32)
              (and originally defined in ‘Text.PrettyPrint.HughesPJ’)
    |
158 | printField f v = text f <> equals <> toDot v
    |                                   ^^
cabal: Failed to build graphviz-2999.6.0.0. See the build log above for
details.

Expected behaviour

The containers images should be built without any issue

Way to reproduce the error

  1. git clone the repository
  2. Run sudo make buildDockerImages

Thanks in advance for your help.

Support for plantuml include directive on self hosted servers

About

plantuml's include directive is a powerful feature, as illustrated e.g. with C4 but also in corporate scenarios, allowing to switch diagrams into a common CI, with a single line.

As discussed here, I think it would be safe to enable (restricted) support for !include in self hosted scenarios.

Security

include_url

According to here !include is also covering the features of !include_url meanwhile. We discuss remote and local includes below:

include

In order to safeguard uneducated operators of a self hosted kroki server from unauthorized file reads and cross site attacks !include should

  • only act on a single preconfigured directory (e.g. $PLANTHOME), if set - and
  • accept as parameter only plain filenames, without paths.

With those restrictions, I suggest to allow even the configuration of remote base urls as $PLANTHOME (use case example: Fileservers, with a set of themes).

When there is no such base directory configured, kroki should keep ignoring !include lines in diagram bodies (behaviour like now).

includesub

This is an include variant with the syntax: !includesub file1.puml!BASIC where "BASIC" would be only a part of an external definition file.
I suggest to support it, with the same restrictions as for !include.

Configuration

We are in container age, so I suggest to support as one and only way to configure the presence and location of such a base directory an exported environment variable.

Running kroki on 32bit system

Hello Mr. @Mogztter I wanted to run kroki on my 32bit ubuntu server to get my hands on the docker but I get the error in the screenshot when I try to build docker images. Is it not possible to do it on a 32bit system or am I missing something here? Sorry for posting here I am not able to use mailing services atm.
Screenshot (2)

Automate the release process

The current process is roughly:

  • mvn versions:set -DnewVersion={{version}}
  • mvn clean package
  • Update version in the Makefile
  • Build, tag and publish Docker images
  • git tag v{{version}}
  • git commit -m "Release version {{version}}"
  • git push origin master --tags

Create a new release page on GitHub: https://github.com/yuzutech/kroki/releases

(Unified) Text output format and PlantUML

Hello Guillaume,

First, as it is my first report, I would like to thank you for this best unified API solution. It's very plaisant to play with it.

Second, as i work now on plantuml class diagram, i've found that there are multiple output formats, but i don't see any references in the documentation. Did i missed something (a specific page) ?

BTW, great 400 page on online demo server :

kroki_io_400

When I see this, I've tried the txt format that we should avoid with UTF-8 char, and used instead utxt

Example with my statements

@startuml
namespace Bartlett.GraphUml {
  class ClassDiagramBuilder << class >> {
    +{static} OPTIONS_DEFAULTS : array = […] {readOnly}

    –graph : Graph
    –options : array
    –formatterFactory : FormatterFactory
    --
    +__construct(graph : Graphp.Graph.Graph, options : array = )
    +createVertexClass(class : mixed) : Graphp.Graph.Vertex
    +createVertexExtension(extension : mixed) : Graphp.Graph.Vertex
    –getInterfaces(reflection : ReflectionClass) : array

  }
  interface ClassDiagramBuilderInterface << interface >> {
    +{static} OPTIONS_DEFAULTS : array = […] {readOnly}

    --
    +{abstract}createVertexClass(class) : Graphp.Graph.Vertex
    +{abstract}createVertexExtension(extension) : Graphp.Graph.Vertex

  }
}
Bartlett.GraphUml.ClassDiagramBuilder ..|> Bartlett.GraphUml.ClassDiagramBuilderInterface
@enduml

That give with txt format such result

,---------------------------------------------------------------.
|ClassDiagramBuilder                                            |
|---------------------------------------------------------------|
|+OPTIONS_DEFAULTS : array = […] {readOnly}                     |
|                                                               |
|-graph : Graph                                                 |
|-options : array                                               |
|-formatterFactory : FormatterFactory                           |
|--                                                             |
|---------------------------------------------------------------|
|+__construct(graph : Graphp.Graph.Graph, options : array = )   |
|+createVertexClass(class : mixed) : Graphp.Graph.Vertex        |
|+createVertexExtension(extension : mixed) : Graphp.Graph.Vertex|
|-getInterfaces(reflection : ReflectionClass) : array           |
`---------------------------------------------------------------'
                                |                                
                                |                                
    ,-------------------------------------------------------.    
    |ClassDiagramBuilderInterface                           |    
    |-------------------------------------------------------|    
    |+OPTIONS_DEFAULTS : array = […] {readOnly}             |    
    |                                                       |    
    |--                                                     |    
    |-------------------------------------------------------|    
    |+createVertexClass(class) : Graphp.Graph.Vertex        |    
    |+createVertexExtension(extension) : Graphp.Graph.Vertex|    
    `-------------------------------------------------------'    

And then with utxt format

,---------------------------------------------------------------.
|ClassDiagramBuilder                                            |
|---------------------------------------------------------------|
|+OPTIONS_DEFAULTS : array = […] {readOnly}                     |
|                                                               |
|-graph : Graph                                                 |
|-options : array                                               |
|-formatterFactory : FormatterFactory                           |
|--                                                             |
|---------------------------------------------------------------|
|+__construct(graph : Graphp.Graph.Graph, options : array = )   |
|+createVertexClass(class : mixed) : Graphp.Graph.Vertex        |
|+createVertexExtension(extension : mixed) : Graphp.Graph.Vertex|
|-getInterfaces(reflection : ReflectionClass) : array           |
`---------------------------------------------------------------'
                                |                                
                                |                                
    ,-------------------------------------------------------.    
    |ClassDiagramBuilderInterface                           |    
    |-------------------------------------------------------|    
    |+OPTIONS_DEFAULTS : array = […] {readOnly}             |    
    |                                                       |    
    |--                                                     |    
    |-------------------------------------------------------|    
    |+createVertexClass(class) : Graphp.Graph.Vertex        |    
    |+createVertexExtension(extension) : Graphp.Graph.Vertex|    
    `-------------------------------------------------------'    

It's almost good for me, except that the namespace (package) is missing (see png format below), and the arrow of implemention edge is missing too

kroki_io_plantuml

Thanks again
Laurent

Set up automatic updates

It would be great if kroki stayed up to date with the latest versions of various libraries. I'd suggest setting up https://app.dependabot.com/ to get notified about updates. Note that it will only update the package.json and package.lock files, though.

Migrate the CI and release to GitHub Actions?

This is a proposal to migrate the CI and the (future) release job to GitHub Actions.
A few benefits:

  • Better integration
  • Faster startup/build time (I've seen build time improvement on multiple projects)
  • macOS, Windows and Linux support on the same platform
  • ... ?

A few drawbacks:

  • Platform/vendor "lock-in" (ie. put all your eggs in the same basket)
  • ... ?

Also Travis builds status don't show up on pull requests anymore for the past few days!

@groovytron Do you have an opinion on it?

Add a page with all the types of diagrams supported

  • Block diagram
  • Sequence diagram
  • Sequence diagram
  • Activity diagram
  • Network diagram
  • Entity Relationship Diagram
  • UML diagram
  • Use case diagram
  • State machine
  • Object Oriented Graph
  • C4 Context diagram
  • C4 Container diagram
  • C4 Component diagram
  • Work Breakdown Structure (PlantUML beta)
  • Mindmap diagram (PlantUML beta)

Nomnoml service seems broken

Current behaviour

When I curl the nomnoml engine I get this error:

$ curl -X POST -H 'Content-type: text/plain' -H 'Accept: svg+xml' --data-binary @tests/smoke/diagrams/pirate.nomnoml http://localhost:80
00/nomnoml/svg
Error 500: pkg/prelude/bootstrap.js:1185
      throw error;
      ^

Error: Cannot find module 'nomnoml'
1) If you want to compile the package/file into executable, please pay attention to compilation warnings and specify a literal in 'require' call. 2) If you don't want to compile the package/f
ile into executable and want to 'require' it from filesystem (likely plugin), specify an absolute path in 'require' call using process.cwd() or process.execPath.
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:580:15)
    at Function.Module._resolveFilename (pkg/prelude/bootstrap.js:1287:46)
    at Function.Module._load (internal/modules/cjs/loader.js:506:25)
    at Module.require (internal/modules/cjs/loader.js:635:17)
    at Module.require (pkg/prelude/bootstrap.js:1166:31)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.<anonymous> (/snapshot/app/index.js:0:0)
    at Module._compile (pkg/prelude/bootstrap.js:1261:22)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:710:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
 (exit code 1)%

And I just noticed these warnings when I run make package for the nomnoml builder container:

$ make package
docker build -f ops/docker/alpine/Dockerfile -t kroki-builder-nomnoml:alpine -t kroki-builder-nomnoml:latest -t kroki-builder-nomnoml:0.6.1-alpine .
Sending build context to Docker daemon  71.68kB
Step 1/9 : FROM node:10.15.0-alpine
 ---> 288d2f688643
Step 2/9 : RUN npm install -g pkg pkg-fetch
 ---> Using cache
 ---> 90cdd61e6d5a
Step 3/9 : ENV NODE node10
 ---> Using cache
 ---> a624dbdc66ca
Step 4/9 : ENV PLATFORM alpine
 ---> Using cache
 ---> 7c1905875633
Step 5/9 : ENV ARCH x64
 ---> Using cache
 ---> e9a231d32196
Step 6/9 : RUN /usr/local/bin/pkg-fetch ${NODE} ${PLATFORM} ${ARCH}
 ---> Using cache
 ---> 791929534cc9
Step 7/9 : COPY . /app
 ---> c011cda81bf6
Step 8/9 : WORKDIR /app
 ---> Running in 0b9d775c3015
Removing intermediate container 0b9d775c3015
 ---> fb232be716f8
Step 9/9 : RUN /usr/local/bin/pkg --targets ${NODE}-${PLATFORM}-${ARCH} . -o app.bin
 ---> Running in 7b1757ee33e6
> [email protected]
> Warning Cannot find module 'nomnoml' from '/app'
  /app/index.js
> Warning Cannot find module 'nomnoml' from '/app'
  /app/index.js
Removing intermediate container 7b1757ee33e6
 ---> 383287f6031f
Successfully built 383287f6031f
Successfully tagged kroki-builder-nomnoml:alpine
Successfully tagged kroki-builder-nomnoml:latest
Successfully tagged kroki-builder-nomnoml:0.6.1-alpine

The pkg error comes from the fact that I didn't run npm install in the nomnoml directory because then theres is no node_modules with nomnoml if I don't do that and it will never be in th container as it's copied into the container.
But if I run npm install before running make package in the nomnoml directory, the warning disappears but I still get the curl error I told about in the beginning. So it looks like there is a problem with nomnoml packaging.

Desired behaviour

  • nomnoml should be included in the container
  • The nomnoml service should answer a 200 HTTP code with a response body containing the SVG.

Host system information

$ cat /etc/*release
NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
BUILD_ID=rolling
ANSI_COLOR="0;36"
HOME_URL="https://www.archlinux.org/"
DOCUMENTATION_URL="https://wiki.archlinux.org/"
SUPPORT_URL="https://bbs.archlinux.org/"
BUG_REPORT_URL="https://bugs.archlinux.org/"
LOGO=archlinux
$ node --version
v12.13.0
$ npm --version
6.12.0

Thanks in advance for your help.

The mermaid companion container errors on startup

The current behaviour

The mermaid companion seems to be broken and shows this error:

Unable to start the service Error: Failed to launch chrome

Output of docker-compose up:

blockdiag_1  | [2019-04-24 06:09:02 +0000] [1] [INFO] Starting gunicorn 19.9.0
blockdiag_1  | [2019-04-24 06:09:02 +0000] [1] [INFO] Listening at: http://0.0.0.0:8001 (1)
blockdiag_1  | [2019-04-24 06:09:02 +0000] [1] [INFO] Using worker: sync
blockdiag_1  | [2019-04-24 06:09:02 +0000] [7] [INFO] Booting worker with pid: 7
mermaid_1    | Unable to start the service Error: Failed to launch chrome!
mermaid_1    | 
mermaid_1    | 
mermaid_1    | TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
mermaid_1    | 
mermaid_1    |     at onClose (/snapshot/app/node_modules/puppeteer/lib/Launcher.js:342:14)
mermaid_1    |     at Interface.helper.addEventListener (/snapshot/app/node_modules/puppeteer/lib/Launcher.js:331:50)
mermaid_1    |     at Interface.emit (events.js:187:15)
mermaid_1    |     at Interface.close (readline.js:379:8)
mermaid_1    |     at Socket.onend (readline.js:157:10)
mermaid_1    |     at Socket.emit (events.js:187:15)
mermaid_1    |     at endReadableNT (_stream_readable.js:1081:12)
mermaid_1    |     at process._tickCallback (internal/process/next_tick.js:63:19)
kroki-stack_mermaid_1 exited with code 1
kroki_1      | Apr 24, 2019 6:09:03 AM io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer
kroki_1      | INFO: Succeeded in deploying verticle

docker-compose.yaml:

version: "3"
services:
  kroki:
    image: yuzutech/kroki:0.0.4
    environment:
      - KROKI_BLOCKDIAG_HOST=blockdiag
      - KROKI_MERMAID_HOST=mermaid
    ports:
      - "8000:8000"
  blockdiag:
    image: yuzutech/kroki-blockdiag:0.0.4
    ports:
      - "8001:8001"
  mermaid:
    image: yuzutech/kroki-mermaid:0.0.4
    ports:
      - "8002:8002"

Expected behaviour

The container should start and wait for HTTP requests.

Way to reproduce the error

  1. Put the docker-compose.yml in a directory
  2. Run docker-compose up in this directory

Thanks in advance for your help.

Add smoke tests on Travis

Now that the containers are built on Travis (thanks to @groovytron) I think we should add smoke tests that:

  • Run the docker image yuzutech/kroki (or all images using docker-compose)
  • Check that the server is running on port X
  • Send a few requests and check the result to make sure the server is working as expected

Kroki does not render included PlantUML sprites

Given following image is given to Kroki

@startuml
!pragma revision 1

'!define AzurePuml https://raw.githubusercontent.com/RicardoNiepel/Azure-PlantUML/master/dist
'!includeurl AzurePuml/AzureRaw.puml
'!includeurl AzurePuml/Databases/AzureCosmosDb.puml
'!includeurl AzurePuml/Compute/AzureFunction.puml

!include <azure/AzureRaw>
!include <azure/Databases/AzureCosmosDb>
!include <azure/Compute/AzureFunction>

component "<color:red><$AzureFunction></color>" as myFunction
database "<color:#0072C6><$AzureCosmosDb></color>" as myCosmosDb
rectangle "<color:AZURE_SYMBOL_COLOR><$AzureCosmosDb></color>" as mySecondCosmosDb
AzureFunction(mySecondFunction, "Stream Processing", "Consumption")

myFunction --> myCosmosDb
mySecondFunction --> mySecondCosmosDb
@enduml

Then rendering ends with following error message Error 400: Syntax Error? (line: 12)

Image will be rendered when AzureFunction line removed but even then all sprites are missing.

Selection_031

Below is a link how the image should look in Kroki

http://www.plantuml.com/plantuml/uml/XL5FRzem5B_xKvXiqZPf4BR39g4eWeNr10K5SMWloDYlmL9iH_Ppg_RJrv0QIbhQet__hJTso2nwLPDUOrcb6BLmBvqqcluYv5jFm9tKG2TFti8ooEWEiN6ZDBNiOL19tFcjTs2vqGWQ1zoej9ISMM6k9JHGfmTdVrapZUlvB5NC8TXKI8SXNMfUUm7UrgU6rb66-2QyBecc3DcMEN2jl31E6JVTVkWfZ6eyGkkuyffZ-6Rh8D51CxPdZoFoBdEf-Otm_RgS41vmeq4ZJJ9kQcD75aIUVJtNPUc1onFA75MF4IVYfVve_Z8S_lrT_8a1SKyt8EB40aUcg_gKCBbTb_ytgvlvlyLiKoncY_Api1M4Wul8ahFbtoCTWPyqMQ45fkZI6WxEILqb0IoCTburUqdoWv3J7sc_dxzU70CxV6V46BG8ftm6

SVG content is duplicated in SeqDiagram

I tried to get an SVG version of a sample seqdiag diagram via Kroki CLI and found out that
the SVG code is doubled — repeated two times instead of one.

seqdiag {
  start [label = "Contract"]
  start [label = "End"]
  start  -> stage1 [label = "1st"];
  stage1  -> stage2 [label = "2st"];
}

I've attached an SVG. As you can see, all the code from

<rect fill="rgb(0,0,0)" height="111" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="127" y="141" />

to

<text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="341.5" y="198">2st</text>

is repeated twice.

For comparison, here's the SVGproduced by http://blockdiag.com/en/seqdiag/demo.html

<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkspace="http://www.inkscape.org/namespaces/inkscape" xmlns:xlink="http://www.w3.org/1999/xlink" style="width: 640px; height: 274px;">
  <defs id="defs_block">
    <filter height="1.504" id="filter_blur" inkspace:collect="always" width="1.1575" x="-0.07875" y="-0.252">
      <feGaussianBlur id="feGaussianBlur3780" inkspace:collect="always" stdDeviation="4.2"></feGaussianBlur>
    </filter>
  </defs>
  <title>blockdiag</title>
  <desc></desc>
  <rect fill="rgb(0,0,0)" height="111" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="127" y="141"></rect>
  <rect fill="rgb(0,0,0)" height="111" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="319" y="141"></rect>
  <rect fill="rgb(0,0,0)" height="46" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="511" y="206"></rect>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="46"></rect>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="46"></rect>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="451" y="46"></rect>
  <path d="M 128 80 L 128 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"></path>
  <rect fill="moccasin" height="111" stroke="rgb(0,0,0)" width="8" x="124" y="135"></rect>
  <path d="M 320 80 L 320 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"></path>
  <rect fill="moccasin" height="111" stroke="rgb(0,0,0)" width="8" x="316" y="135"></rect>
  <path d="M 512 80 L 512 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"></path>
  <rect fill="moccasin" height="46" stroke="rgb(0,0,0)" width="8" x="508" y="200"></rect>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="40"></rect>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="128" y="66">End</text>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="256" y="40"></rect>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="37" x="320" y="66">stage1</text>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="448" y="40"></rect>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="37" x="512" y="66">stage2</text>
  <path d="M 136 135 L 312 135" fill="none" stroke="rgb(0,0,0)"></path>
  <polygon fill="rgb(0,0,0)" points="304,131 312,135 304,139" stroke="rgb(0,0,0)"></polygon>
  <path d="M 328 200 L 504 200" fill="none" stroke="rgb(0,0,0)"></path>
  <polygon fill="rgb(0,0,0)" points="496,196 504,200 496,204" stroke="rgb(0,0,0)"></polygon>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="149" y="133">1st</text>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="341" y="198">2st</text>
</svg>

And the SVG produced by Kroki:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkspace="http://www.inkscape.org/namespaces/inkscape" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 640 274" width="640px" height="274px">
  <defs id="defs_block">
    <filter height="1.504" id="filter_blur" inkspace:collect="always" width="1.1575" x="-0.07875" y="-0.252">
      <feGaussianBlur id="feGaussianBlur3780" inkspace:collect="always" stdDeviation="4.2"/>
    </filter>
  </defs>
  <title>blockdiag</title>
  <desc>seqdiag {
  start [label = "Contract"]
  start [label = "End"]
  start  -&gt; stage1 [label = "1st"];
  stage1  -&gt; stage2 [label = "2st"];
}</desc>
  <rect fill="rgb(0,0,0)" height="111" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="127" y="141"/>
  <rect fill="rgb(0,0,0)" height="111" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="319" y="141"/>
  <rect fill="rgb(0,0,0)" height="46" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="511" y="206"/>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="46"/>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="46"/>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="451" y="46"/>
  <path d="M 128 80 L 128 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"/>
  <rect fill="moccasin" height="111" stroke="rgb(0,0,0)" width="8" x="124" y="135"/>
  <path d="M 320 80 L 320 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"/>
  <rect fill="moccasin" height="111" stroke="rgb(0,0,0)" width="8" x="316" y="135"/>
  <path d="M 512 80 L 512 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"/>
  <rect fill="moccasin" height="46" stroke="rgb(0,0,0)" width="8" x="508" y="200"/>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="40"/>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="128.5" y="66">End</text>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="256" y="40"/>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="37" x="320.5" y="66">stage1</text>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="448" y="40"/>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="37" x="512.5" y="66">stage2</text>
  <path d="M 136 135 L 312 135" fill="none" stroke="rgb(0,0,0)"/>
  <polygon fill="rgb(0,0,0)" points="304,131 312,135 304,139" stroke="rgb(0,0,0)"/>
  <path d="M 328 200 L 504 200" fill="none" stroke="rgb(0,0,0)"/>
  <polygon fill="rgb(0,0,0)" points="496,196 504,200 496,204" stroke="rgb(0,0,0)"/>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="149.5" y="133">1st</text>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="341.5" y="198">2st</text>
  <rect fill="rgb(0,0,0)" height="111" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="127" y="141"/>
  <rect fill="rgb(0,0,0)" height="111" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="319" y="141"/>
  <rect fill="rgb(0,0,0)" height="46" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="511" y="206"/>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="46"/>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="46"/>
  <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="451" y="46"/>
  <path d="M 128 80 L 128 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"/>
  <rect fill="moccasin" height="111" stroke="rgb(0,0,0)" width="8" x="124" y="135"/>
  <path d="M 320 80 L 320 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"/>
  <rect fill="moccasin" height="111" stroke="rgb(0,0,0)" width="8" x="316" y="135"/>
  <path d="M 512 80 L 512 262" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4"/>
  <rect fill="moccasin" height="46" stroke="rgb(0,0,0)" width="8" x="508" y="200"/>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="40"/>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="128.5" y="66">End</text>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="256" y="40"/>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="37" x="320.5" y="66">stage1</text>
  <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="448" y="40"/>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="37" x="512.5" y="66">stage2</text>
  <path d="M 136 135 L 312 135" fill="none" stroke="rgb(0,0,0)"/>
  <polygon fill="rgb(0,0,0)" points="304,131 312,135 304,139" stroke="rgb(0,0,0)"/>
  <path d="M 328 200 L 504 200" fill="none" stroke="rgb(0,0,0)"/>
  <polygon fill="rgb(0,0,0)" points="496,196 504,200 496,204" stroke="rgb(0,0,0)"/>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="149.5" y="133">1st</text>
  <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="19" x="341.5" y="198">2st</text>
</svg>

Feature request: support ditaa command-line arguments

This project is very helpful, but I'm in trouble with drawing result of ditaa.
I've found that running ditaa with --no-separation argument solves my problem.
So I want the feature running ditaa with command-line arguments such as -E,--no-separation or -S,--no-shadows.

How to use in docker

Great project.
But I am new to docker.
After launch "docker run yuzutech/kroki", how to use it to produce images?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.