Giter Site home page Giter Site logo

enteee / plantuml-parser Goto Github PK

View Code? Open in Web Editor NEW
133.0 6.0 32.0 1.81 MB

Parse PlantUML with JavaScript or TypeScript

Home Page: https://duckpond.ch/category/plantuml-parser

License: Apache License 2.0

JavaScript 26.53% Nix 0.91% TypeScript 37.37% PEG.js 35.19%
parser plantuml javascript typescript typescript-library javascript-library plantuml-parser

plantuml-parser's Introduction

plantuml-parser npm version Build Status Coverage Status Twitter URL

Parse PlantUML with JavaScript or TypeScript

The aim of this project is to provide a feature-complete, well tested and maintainable Parsing Expression Grammar (PEG) for the PlantUML syntax. The parser is designed to be used as JavaScript library or from the Command Line.

Important: The parser is not yet feature-complete. But we focus on writing a robust implementation which can parse parts of diagrams without knowing the full syntax. This means that the parser probably still parses just about enough to get you started. If not, please contribute ❤️.

Installation

$ npm install --save plantuml-parser

Examples / Fixtures

PlantUML is not a formally defined language - something we would like to change. This means we have to build this parser by reverse engineering from examples. For this reason we keep a large set of PlantUML diagrams (in.plantuml) and the corresponding formatted output (parse[File]-out.<formatter>) in test/fixtures/. We even have diagrams which exposed bugs in the parser or diagrams which contain known broken PlantUML syntax. Please help us expand that collection by contributing your own diagrams. Every diagram counts 🚀.

Usage

const { parse, parseFile, formatters } = require('plantuml-parser');

// Example PlantUML
const data = `
@startuml
  class A
  class B
  A --|> B
@enduml
`;

// parse PlantUML
const result = parse(data);

// Format and print parse result
console.log(
  formatters.default(result)
);
Output

[
  {
    "elements": [
      {
        "name": "A",
        "title": "A",
        "isAbstract": false,
        "members": [],
        "extends_": [],
        "implements_": [],
        "generics": [],
        "stereotypes": []
      },
      {
        "name": "B",
        "title": "B",
        "isAbstract": false,
        "members": [],
        "extends_": [],
        "implements_": [],
        "generics": [],
        "stereotypes": []
      },
      {
        "left": "A",
        "right": "B",
        "leftType": "Unknown",
        "rightType": "Unknown",
        "leftArrowHead": "",
        "rightArrowHead": "|>",
        "leftArrowBody": "-",
        "rightArrowBody": "-",
        "leftCardinality": "",
        "rightCardinality": "",
        "label": "",
        "hidden": false
      }
    ]
  }
]

parse(data, options)

Parse PlantUML in data. Returns the parse result.

  • data: data to parse
  • options: supports all PEG.js parser options. Enable tracing with options.verbose = true. If tracing is enabled, options is also forwarded to the tracer object. See pegjs-backtrace options for a full list of supported tracer options.

parseFile(pattern, options, cb)

Parse all PlantUML diagrams in the files matching pattern. If given, the callback function cb will make this function behave asynchronous.

  • pattern: files to parse, supports globbing, e.g.: **/*.plantuml.
  • options: supports all PEG.js parser options. Enable tracing with options.verbose = true. If tracing is enabled, options is also forwarded to the tracer object. See pegjs-backtrace options for a full list of supported tracer options.
  • cb: (optional) asynchronous callback. Called with: cb(err, result)

formatters: A collection of built-in parse result formatters.

For a detailed description of all the formatters see src/formatters.

Command Line Interface

Installation

# npm install --global plantuml-parser

Usage

Options:
  --version        Show version number                                 [boolean]
  --formatter, -f  formatter to use
                              [choices: "default", "graph"] [default: "default"]
  --input, -i      input file(s) to read, supports globbing
                                                       [string] [default: stdin]
  --output, -o     output file to write               [string] [default: stdout]
  --color, -c      colorful output                    [boolean] [default: false]
  --verbose, -v    1x print verbose output, 2x print parser tracing
                                                            [count] [default: 0]
  --help           Show help                                           [boolean]

Features

  • Diagram Types:
    • Class
    • Component
    • Use Case
    • Sequence
    • Activity
    • State
    • Object
    • Deployment
    • Timing
  • Support for StdLibs:
    • C4 (v2.4.0)
  • Formatters:
    • JSON
    • Graph
  • Testing, CI/CD:
    • Fixtures for all formatters
    • Code coverage
    • Code formatting
    • Code linting
    • Error case testing
    • Dependency audit
  • Misc

Test

$ npm test

This will run:

  • unit tests
  • code coverage
  • eslint

Contribute ❤️

Every contribution counts. Please,

When contributing code, always also update the fixtures and run tests.

$ npm run fixtures
$ npm test
$ git commit

For more information see our contribution guidelines.

Related

  • PEG.js: Parser Generator for JavaScript
  • ts-pegjs: Plugin for pegjs to generate TypeScript parsers
  • PlantUML code generator: Provides a command line utility to generate code in various languages given a PlantUML class diagram.

License

plantuml-parser's People

Contributors

blurname avatar chris927 avatar dependabot[bot] avatar dgassma avatar enteee avatar id101010 avatar paduc 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

plantuml-parser's Issues

diagram ids

Is your feature request related to a problem? Please describe.
Plantuml allows to assign an ID to a diagram for the purpose of reuse.

@startuml(id=MY_OWN_ID)
@enduml

See: http://plantuml.com/de/preprocessing

Describe the solution you'd like
Either the ID is parsed or everything after @startuml is ignored.

Support `@startuml name`

VS Code shows a hint, when the name is not set. It looks like that this @startuml name Syntax is officially supported but not documented. Example and more informations can be found in the following issue of vscode repository.

@startuml System Context of Project Collector System
!include https://raw.githubusercontent.com/adrianvlupu/C4-PlantUML/latest/C4_Context.puml

grafik

yarn run v1.22.19
$ node src/plantuml-helper.js
/Users/tobiashochgurtel/work-dev/project-collector/plantuml-c4-analytic/node_modules/plantuml-parser/dist/plantuml.js:11669
        throw peg$buildStructuredError(peg$maxFailExpected, peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, peg$maxFailPos < input.length
        ^

Error [SyntaxError]: Expected "(", "\n", "\r\n", or [ ,\t] but "S" found.
    at peg$buildStructuredError (/Users/tobiashochgurtel/work-dev/project-collector/plantuml-c4-analytic/node_modules/plantuml-parser/dist/plantuml.js:704:16)
    at peg$parse (/Users/tobiashochgurtel/work-dev/project-collector/plantuml-c4-analytic/node_modules/plantuml-parser/dist/plantuml.js:11669:15)
    at parseSync (/Users/tobiashochgurtel/work-dev/project-collector/plantuml-c4-analytic/node_modules/plantuml-parser/dist/index.js:64:12)
    at file:///Users/tobiashochgurtel/work-dev/project-collector/plantuml-c4-analytic/src/plantuml-helper.js:18:18
    at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3) {
  expected: [
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: '(', ignoreCase: false },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: '\n', ignoreCase: false },
    { type: 'literal', text: '\r\n', ignoreCase: false }
  ],
  found: 'S',
  location: {
    start: { offset: 10, line: 1, column: 11 },
    end: { offset: 11, line: 1, column: 12 }
  }
}

Node.js v19.7.0
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Can't parse named diagrams

Describe the bug
PUML diagrams can have names which comes right after the start directive.

Currently the tool breaks when passing such diagrams.

To Reproduce

  1. try to parse or parseFile a named diagram
  2. See error:
return new peg$SyntaxError(
           ^
SyntaxError: Expected "(", "\n", "\r\n", or [ \t] but "n" found.

PlantUML

@startuml name
  class A
  class B
  A --|> B
@enduml

Expected behavior
Tool should parse normally.

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Mac OS Mojave
  • node
  • v12

Smartphone (please complete the following information):
N/A

Additional context
N/A

TypeScript Formatter

Is your feature request related to a problem? Please describe.
I am against auto-generating source code. But from feedback that I have received lots of people see value in this. And probably there is. For example, If you want to live a documentation first scheme. Or (the cooler use-case) if you want to write test code for your documentation...

Describe the solution you'd like
Therefore a formatter which return valid TypeScript classes and interfaces from PlantUML would be interesting.

Describe alternatives you've considered
Not doing it.

Additional context
Again I am not a huge fan of generating code from documentation automatically. Once generated code evolves normally much quicker than documentation. Maybe a collaboration with a code to PlatUML tool would be beneficial in order to provide a full blown "doc->code->doc" solution.

Angle brackets in generics and stereotypes not properly parsed

Describe the bug
To some degree, angle brackets are allowed in generics and stereotypes. For example, the following diagram:

' Angle brackets in generics
class TestGenericsWithAngleBrackets < <G1> >
class TestGenericsWithDoubleAngleBrackets < <<G1>> >

' Angle brackets in stereotypes
class TestStereotypeWithAngleBrackets << <S1> >>
class TestStereotypeWithDoubleAngleBrackets << <<S1>> >>

produces the following diagram:
angle-brackets

Currently we do not support this in the parser. Therefore the parsed result is:

[
  {
    "name": "anglebrackets",
    "diagrams": [
      {
        "elements": [
          {
            "comment": "Angle brackets in generics"
          },
          {
            "name": "TestGenericsWithAngleBrackets",
            "title": "TestGenericsWithAngleBrackets",
            "isAbstract": false,
            "members": [],
            "extends_": [],
            "implements_": [],
            "generics": "<G1",
            "stereotype": ""
          },
          {
            "name": "TestGenericsWithDoubleAngleBrackets",
            "title": "TestGenericsWithDoubleAngleBrackets",
            "isAbstract": false,
            "members": [],
            "extends_": [],
            "implements_": [],
            "generics": "<<G1",
            "stereotype": ""
          },
          {
            "comment": "Angle brackets in stereotypes"
          },
          {
            "name": "TestStereotypeWithAngleBrackets",
            "title": "TestStereotypeWithAngleBrackets",
            "isAbstract": false,
            "members": [],
            "extends_": [],
            "implements_": [],
            "generics": "",
            "stereotype": "<S1>"
          },
          {
            "name": "TestStereotypeWithDoubleAngleBrackets",
            "title": "TestStereotypeWithDoubleAngleBrackets",
            "isAbstract": false,
            "members": [],
            "extends_": [],
            "implements_": [],
            "generics": "",
            "stereotype": "<<S1"
          }
        ]
      }
    ]
  }
]

To Reproduce
Steps to reproduce the behavior:

  1. Write diagram to file anglebrackets
  2. node dist/bin/cli.js -i anglebrackets

Expected behavior
Angle brackets should be parsed properly and added to the generics and/or stereotype property.

Additional context

Double angle brackets:

class TestStereotypeWithDoubleAngleBrackets << <<S1>> >>

Is not properly handled by the original plantuml implementation.

DOT notation formatter

Is your feature request related to a problem? Please describe.
Formatting parsed plantuml diagrams as DOT.

Example (from wikipedia):

graph graphname {
     // This attribute applies to the graph itself
     size="1,1";
     // The label attribute can be used to change the label of a node
     a [label="Foo"];
     // Here, the node shape is changed.
     b [shape=box];
     // These edges both have different line properties
     a -- b -- c [color=blue];
     b -- d [style=dotted];
     // [style=invis] hides a node.
   }

Possible implementation

Maybe by using dagre's graphlibDot.write. Or an other alternative...

Parser does not read the types of class attributes

I am using this tool to parse class diagrams. The tool doesn't parse the types of attributes.

NodeJS script:

import { parse, parseFile, formatters } from 'plantuml-parser';

// Example PlantUML
const data = `
@startuml
!theme plain
class Publication {
  title : String
}
@enduml
`;

// parse PlantUML
const result = parse(data);

// Format and print parse result
console.log(
  formatters.default(result)
);

Output:

[
  {
    "elements": [
      {
        "name": "Publication",
        "title": "Publication",
        "isAbstract": false,
        "members": [
          {
            "name": "title",
            "isStatic": false,
            "accessor": "+",
            "type": ""
          }
        ],
        "extends_": [],
        "implements_": [],
        "generics": [],
        "stereotypes": []
      }
    ]
  }
]

The String type of the title attribute is not present in the output.

diagram includes are not supported

Describe the bug

In plantUML you can use !include and !includeurl for importing dependencies for a diagram (extensions, icons etc.) http://plantuml.com/preprocessing.

But if such imports are used the parser breaks.

return new peg$SyntaxError(
           ^
source-map-support.js:445
SyntaxError: Expected "'", "(", "/'", "@enduml", "[", "abstract ", "class ", "cloud", "component ", "database", "digraph", "enum ", "folder", "frame", "interface ", "namespace", "node", "note ", "package", "rectangle", "skinparam ", "state", "together ", "usecase ", [ \t], or [A-Za-z0-9._] but "}" found.

To Reproduce
Steps to reproduce the behavior:

  1. Use parse with content or use parseFile with given uml
  2. See error stack

PlantUML

@startuml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/release/1-0/C4.puml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/release/1-0/C4_Container.puml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/release/1-0/C4_Context.puml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/release/1-0/C4_Component.puml

System_Boundary(MetricsExecution, "Metrics Execution") {
    Component(apiRouter, "Express Routeer", "Api router")

    System_Ext(puppeteer, "puppeteer", "Headless Chrome Provider")

    Rel(apiRouter, PageRenderService, "url: string")
    Rel(PageRenderService, apiRouter, "IMetric<T>[]")
}
@enduml

Expected behavior
It should parse normally

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Mac OS Mojave
  • Browser Node
  • Version 12

Additional context
N/A

Make the parser internally typed

  • Implement return type checking in ts-pegjs: metadevpro/ts-pegjs#46
  • add type declarations for all symbols to conf.js: build.returnTypes

This will make the parser internally typed and will guarantee type correctness of parses return value.

Implement Error case testing

Is your feature request related to a problem? Please describe.
I would also like to be able to test for bad syntax.

Describe the solution you'd like
The fixtures directory should support error files which do contain information about expected parsing exceptions. Those negative tests are successful if the parsing raises that exact exception.

Additional context
This might enable me to bump code coverage above 70% or so.

Is there any type guards?

Is your feature request related to a problem? Please describe.
I imported plantuml-parser in my Next.js app, and I need some of type guards.
Now I just written a piece of type guards(only for what I need), and they are in my app project.

eg. When I render UML in browser,

  • classify between interface and class to show some icon
  • classify between methods and member variable to separate div tag

Describe the solution you'd like

  1. As far as I have been able to find in the repository, it does not appear that type guards are provided.
    If I am mistaken and type guards already exists in the project, please let me know.

  2. May I create a pull request to add the type guard I coded?
    It might help other users. (although it may not be necessary)
    Currently I have only created type guards for a few classes I need, but
    I consider that I can create type guards for all types defined in types.d.ts.

Here is an example of what I have created;

const isMethod = (maybeMethod: Object): maybeMethod is Method => {
  return (
    hasPrimitive(maybeMethod, 'name', 'string') &&
    hasPrimitive(maybeMethod, 'isStatic', 'boolean') &&
    hasStringLiteral(maybeMethod, 'accessor', isAccessor) &&
    hasPrimitive(maybeMethod, 'returnType', 'string') &&
    hasPrimitive(maybeMethod, '_arguments', 'string')
  );
};

const isMemberVariable = (maybeMemberVariable: Object): maybeMemberVariable is MemberVariable => {
  return (
    hasPrimitive(maybeMemberVariable, 'name', 'string') &&
    hasPrimitive(maybeMemberVariable, 'isStatic', 'boolean') &&
    hasStringLiteral(maybeMemberVariable, 'accessor', isAccessor) &&
    hasPrimitive(maybeMemberVariable, 'type', 'string')
  );
};

const isMember = (maybeMember: Object): maybeMember is Member => {
  return isMethod(maybeMember) || isMemberVariable(maybeMember);
};

// how to use
const renderClass = (c: Class) => {
  const variables = c.members.filter(member => isMemberVariable(member));
  const methods = c.members.filter(member => isMethod(member));

  return <div className="container">
    <h1>{c.title}</h1>
    {variables.length > 0 &&<div className="properties">
      <h2>properties</h2>
      <ul>{variables.map(v => <li>{v.name}</li>)}</ul>
    </div>}
    {methods.length > 0 &&<div className="methods">
      <h2>methods</h2>
      <ul>{methods.map(m => <li>{m.name}</li>)}</ul>
    </div>}
  </div>
}

Add a formatter for a proper OO model

I'm using PlantUML and this great parser to describe my Typescript classes.

Could we imagine an output being a ts/js object that contains the relationships between the class objects ?

Instead of a list of nodes and edges I would like to have an object I can traverse and only contains OOP concepts (not display concepts like visibility or links).

I'm thinking of something a bit like this:

const model = {
  nodes: [{
    name: "MyClass",
    type: "class",
    members: [
      {
        name: "create",
        type: "method",
        isStatic: true,
        isAbstract: false,
        visibility: "public",
        arguments: [{
          type: "Int", // could also be a reference to a class/interface node
          name: "age"
        }],
        returnType: {
          name: "MyClass",
          // ... reference to the MyClass node
        }
      }
    ],
    extends: [ 
      // direct reference to another class node
    ],
    implements: [
      // direct reference to an interface node
    ]
  }]
}

(The direct references would cause circularity which would prevent serialisation but that is not the point)

Would this type of formatter find a place in plantuml-parser ?

Preprocessor

Is your feature request related to a problem? Please describe.
PlantUML comes with a built-in preprocessor official documentation. In order support parsing of all different PlantUML diagrams, this parser should also implement preprocessor instruction parsing and a JavaScript implemented preprocessor (preprocess()).

Describe the solution you'd like

  • Add test fixtures for all examples in the official documentation
  • Create a new parser for preprocessor instructions
  • Add those preprocessor instruction set to the plantuml parser -> make the normal parser skip over preprocessor instructions.
  • Write preprocess(diagram: string): string which runs all preprocessor instructions on a raw diagram

Describe alternatives you've considered

Syntax error when reading empty spaced-out brackets

The parser cannot read the plantuml file if it contains brackets separated on different lines and if there is nothing inside the brackets.

@startuml
!theme plain
    class AbstractNode 
    {
    }
@enduml

Error message from NodeJS.

$ node extraction/plantuml-test.js 
C:\Users\songy\node_modules\plantuml-parser\dist\plantuml.js:704
        return new SyntaxError(SyntaxError.buildMessage(expected1, found), expected1, found, location1);
               ^

Error [SyntaxError]: Expected "'", "(", "/'", "BiRel", "BiRel_D", "BiRel_Down", "BiRel_L", "BiRel_Left", "BiRel_Neighbor", "Bi
Rel_R", "BiRel_Right", "BiRel_U", "BiRel_Up", "Boundary", "Component", "ComponentDb", "ComponentDb_Ext", "ComponentQueue", "Co
mponentQueue_Ext", "Component_Ext", "Container", "ContainerDb", "ContainerDb_Ext", "ContainerQueue", "ContainerQueue_Ext", "Co
ntainer_Boundary", "Container_Ext", "Deployment_Node", "Deployment_Node_L", "Deployment_Node_R", "Enterprise_Boundary", "Node"
, "Node_L", "Node_R", "Person", "Person_Ext", "Rel", "Rel_", "Rel_Back", "Rel_Back_Neighbor", "Rel_D", "Rel_Down", "Rel_L", "R
el_Left", "Rel_Neighbor", "Rel_R", "Rel_Right", "Rel_U", "Rel_Up", "System", "SystemDb", "SystemDb_Ext", "SystemQueue", "Syste
mQueue_Ext", "System_Boundary", "System_Ext", "[", "abstract ", "class ", "cloud", "component ", "database", "digraph", "enum 
", "folder", "frame", "interface ", "namespace", "node", "note ", "package", "rectangle", "skinparam ", "state", "together ", 
"usecase ", [ ,\t], or [A-Z,a-z,0-9,.,_] but "}" found.
    at peg$buildStructuredError (C:\Users\songy\node_modules\plantuml-parser\dist\plantuml.js:704:16)
    at peg$parse (C:\Users\songy\node_modules\plantuml-parser\dist\plantuml.js:11598:15)
    at parseSync (C:\Users\songy\node_modules\plantuml-parser\dist\index.js:64:12)
    at file:///C:/Users/songy/Documents/My%20Documents/UDEM/master%20thesis/uml%20data/database/cleaning/three-step/extraction
/plantuml-test.js:14:16
    at ModuleJob.run (node:internal/modules/esm/module_job:197:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:61:12) {
  expected: [
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: "'", ignoreCase: false },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: "/'", ignoreCase: false },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: '[', ignoreCase: false },
    { type: 'literal', text: '[', ignoreCase: false },
    { type: 'literal', text: '(', ignoreCase: false },
    { type: 'literal', text: '(', ignoreCase: false },
    {
      type: 'class',
      parts: [ [ 'A', 'Z' ], [ 'a', 'z' ], [ '0', '9' ], '.', '_' ],
      inverted: false,
      ignoreCase: false
    },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: '[', ignoreCase: false },
    { type: 'literal', text: '[', ignoreCase: false },
    { type: 'literal', text: '(', ignoreCase: false },
    { type: 'literal', text: '(', ignoreCase: false },
    {
      type: 'class',
      parts: [ [ 'A', 'Z' ], [ 'a', 'z' ], [ '0', '9' ], '.', '_' ],
      inverted: false,
      ignoreCase: false
    },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'skinparam ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'skinparam ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'together ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'package', ignoreCase: true },
    { type: 'literal', text: 'namespace', ignoreCase: true },
    { type: 'literal', text: 'node', ignoreCase: true },
    { type: 'literal', text: 'folder', ignoreCase: true },
    { type: 'literal', text: 'frame', ignoreCase: true },
    { type: 'literal', text: 'cloud', ignoreCase: true },
    { type: 'literal', text: 'database', ignoreCase: true },
    { type: 'literal', text: 'rectangle', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'note ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'note ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'note ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'note ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'abstract ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'class ', ignoreCase: false },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'abstract ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'class ', ignoreCase: false },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'interface ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'interface ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'enum ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'enum ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'component ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: '[', ignoreCase: false },
    { type: 'literal', text: '[', ignoreCase: false },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'usecase ', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: '(', ignoreCase: false },
    { type: 'literal', text: '(', ignoreCase: false },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'Person_Ext', ignoreCase: true },
    { type: 'literal', text: 'SystemDb_Ext', ignoreCase: true },
    { type: 'literal', text: 'SystemQueue_Ext', ignoreCase: true },
    { type: 'literal', text: 'Person', ignoreCase: true },
    { type: 'literal', text: 'System_Ext', ignoreCase: true },
    { type: 'literal', text: 'SystemDb', ignoreCase: true },
    { type: 'literal', text: 'SystemQueue', ignoreCase: true },
    { type: 'literal', text: 'System', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: 'ContainerQueue_Ext', ignoreCase: true },
    { type: 'literal', text: 'ContainerQueue', ignoreCase: true },
    { type: 'literal', text: 'ContainerDb_Ext', ignoreCase: true },
    { type: 'literal', text: 'ContainerDb', ignoreCase: true },
    { type: 'literal', text: 'Container_Ext', ignoreCase: true },
    { type: 'literal', text: 'Container', ignoreCase: true },
    { type: 'literal', text: 'ComponentQueue_Ext', ignoreCase: true },
    { type: 'literal', text: 'ComponentQueue', ignoreCase: true },
    { type: 'literal', text: 'ComponentDb_Ext', ignoreCase: true },
    { type: 'literal', text: 'ComponentDb', ignoreCase: true },
    { type: 'literal', text: 'Component_Ext', ignoreCase: true },
    { type: 'literal', text: 'Component', ignoreCase: true },
    {
      type: 'class',
      parts: [ ' ', '\t' ],
    { type: 'literal', text: 'Rel_Up', ignoreCase: true },
    ... 30 more items
  ],
  found: '}',
  location: {
    start: { offset: 58, line: 6, column: 5 },
    end: { offset: 59, line: 6, column: 6 }
  }
}

C4 PlantUML elements with parameters passed with $ are not recognized

Describe the bug

When I add elements and pass the arguments like it's shown on the C4 PlantUML page with a $-character ($descr="description") these elements are not recognized.

In general nearly all examples on the C4 PlantUML page can't be displayed because of that issue.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

PlantUML

@startuml
Person(person_descr, "person", $descr="description")
Person(person_descr, "person", $descr="") ' an empty parameter also doesn't work
Person(person_tags_one, "person", $tags="one+two")
@enduml

Here more and it shows that it's a valid syntax

Expected behavior
The elements should be returned.

Comments not properly parsed

Describe the bug
One line comments are not properly parsed.

PlantUML

@startuml
' this is a comment
@enduml

yields:

[
  {
    "name": "comment.diag",
    "diagrams": [
      {
        "elements": [
          [
            [],
            "'",
            [
              [
                [
                  null,
                  " "
                ],
                [
                  null,
                  "t"
                ],
                [
                  null,
                  "h"
                ],
                [
                  null,
                  "i"
                ],
                [
                  null,
                  "s"
                ],
                [
                  null,
                  " "
                ],
                [
                  null,
                  "i"
                ],
                [
                  null,
                  "s"
                ],
                [
                  null,
                  " "
                ],
                [
                  null,
                  "a"
                ],
                [
                  null,
                  " "
                ],
                [
                  null,
                  "c"
                ],
                [
                  null,
                  "o"
                ],
                [
                  null,
                  "m"
                ],
                [
                  null,
                  "m"
                ],
                [
                  null,
                  "e"
                ],
                [
                  null,
                  "n"
                ],
                [
                  null,
                  "t"
                ]
              ],
              "\n"
            ]
          ]
        ]
      }
    ]
  }
]

Expected behavior

Should be something like:

[
  {
    "name": "comment.diag",
    "diagrams": [
      {
        "elements": [
          {
             "comment": "this is a comment"
          }
        ]
      }
    ]
  }
]
A clear and concise description of what you expected to happen.

Add support for sequence diagrams

Is your feature request related to a problem? Please describe.
No

Describe the solution you'd like
The README says that sequence diagrams are not yet supported. Please prioritize formatting of sequence diagrams!

Describe alternatives you've considered

  • The deprecated formatting in the VSCode extension makes things worse.
  • There's a list here: plantuml/plantuml#714 (comment) -- alas this is the only Github project with a decent amount of stars. The rest of the links listed have only a handful of stars...so a bit uncertain about ising them.

Additional context
Nada

Thank you in advance for your help!

TS definitions support?

Is your feature request related to a problem? Please describe.
It's almost a universal expectation for modules to have types so they can be used in a TS application.

Describe the solution you'd like
If you are coding in TS, ship with declaration: true but you can also add it separately to https://github.com/DefinitelyTyped.

Describe alternatives you've considered
I will have a go at creating something and will let you know when I have something.

Additional context
No.

Create a class entry for implicitly defined UML classes

Some plantuml code only has statements between UML classes like this

LiteralExp <|-- TemplateExp

The left-right members of the association are not explicitly stated as classes using the class keyword. It would be nice if the parsed json result from this tool treats this as an implicitly defined class. The json should have a class entry like this, in addition to the left-right entry.

"elements": [
        {
          "name": "LiteralExp",
          "title": "LiteralExp",
          "isAbstract": false,
          "members": [],
          "extends_": [],
          "implements_": [],
          "generics": [],
          "stereotypes": []
        },
]

Do you have a plan to make this libary work inside a browser ?

Is your feature request related to a problem? Please describe.

No.

Describe the solution you'd like

I want to use this library in my React app, but an error cased by fast-glob says glob path is valid only in NodeJS.
I would be happy if I can have api for browser.

Describe alternatives you've considered

I can't come up with other idea.

Supporting entity and struct

@startuml db
title Database 

entity QuestionType {
}
@enduml

or


@startuml db
title Database 

struct QuestionType {
}
@enduml

So this variation of class diagram throws an error. I am wondering is it possible to support them?

Properly fill the title of a component

the diagram:

@startuml
interface _COMP_EXT1_IF1 as SwfComponentBase
component _COMP8 as RoadBoundaryFusion
@enduml

results in the formatted graph:

{
  "nodes": [
    {
      "name": "_COMP_EXT1_IF1",
      "members": [],
      "id": "_COMP_EXT1_IF1",
      "type": "Interface",
      "hidden": true
    },
    {
      "name": "_COMP8",
      "id": "_COMP8",
      "type": "Component",
      "title": "_COMP8",
      "hidden": true
    }
  ],
  "edges": [
    {
      "from": "_COMP8",
      "to": "",
      "name": "contains",
      "hidden": true
    }
  ]
}

ID, title and name of a component are identical but. But the title should be the string after as.

For example:
component _COMP8 as RoadBoundaryFusion
should result in

    {
      "name": "_COMP8",
      "id": "_COMP8",
      "type": "Component",
      "title": "RoadBoundaryFusion",
      "hidden": true
    }

package not properly parsed

The following diagram:

@startuml

interface _COMP_EXT1_IF1

package p1 as rmf{
  component _COMP8 
}

@enduml

results in

SyntaxError: Expected "'", "(", "/'", "@enduml", "[", "\"", "abstract ", "class ", "cloud", "component ", "database", "digraph  ", "enum ", "folder", "frame", "interface ", "namespace", "node", "note ", "package", "rectangle", "skinparam ", "state", "tog  ether ", "usecase ", [ \t], or [A-Za-z0-9._] but "}" found.

I had a quick look to the grammar but did not find the root cause. I guess it should work however.

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.