txt: ## dist_zef-antononcube-UML-Translators.md
  # Raku UML::Translators
  
  ## In brief
  
  This repository is for a Raku package for the translations of code into
  [Unified Modeling Language (UML)](https://en.wikipedia.org/wiki/Unified_Modeling_Language)
  specifications and vice versa.
  
  Currently, the package only translates Object-Oriented Programming (OOP) Raku code into:
  
  * The Domain Specific Language (DSL) of [Mermaid-JS](https://mermaid-js.github.io/mermaid/)
  * The DSL of [PlantUML](https://plantuml.com)
  * Argument specification of the UML class diagram function [`UMLClassGraph`](https://github.com/antononcube/MathematicaForPrediction/blob/master/Misc/UMLDiagramGeneration.m)
    of the Mathematica / Wolfram Language (WL) package [AAp1]
  
  See [AA2] for usage examples of both PlantUML and `UMLClassGraph` in Mathematica.
  
  **Remark:** The package provides Command Line Interface (CLI) script.
  
  **Remark:** (Currently) the development of PlantUML is more robust and complete than that of Mermaid-JS.
  Hence, workflow-wise, using this package to generate PlantUML specs would produce (on average) best results.
  
  ### Future plans
  
  A fully fledged version of this package would translate:
  
  * C++, Java, Kotlin, or Raku code into UML specs
  * UML specs into C++, Java, Kotlin, or Raku code
  
  Currently, only UML specs are generated to PlantUML's DSL and a much poorer WL DSL.
  Ideally, subsequent versions of this package would be able to use UML specifications
  encoded in XML and JSON.
  
  ---
  
  ## Installation
  
  ### From zef's ecosystem
  
  ```
  zef install UML::Translators
  
  ```
  
  ### From GitHub
  
  ```
  zef install https://github.com/antononcube/Raku-UML-Translators.git 
  
  ```
  
  ---
  
  ## Command Line Interface
  
  The package provides the CLI script `to-uml-spec`. Here is its usage message:
  
  ```
  to-uml-spec --help
  
  ```
  
  ```
  # Usage:
  #   to-uml-spec <packageName> [--type=<Str>] [-I=<Str>] [--attributes] [--methods] [--concise-grammar-classes] [--format=<Str>] [--plot] [--jar=<Str>] [--viewer=<Str>] -- Make a UML diagram for a specified package.
  #   
  #     <packageName>                Package name.
  #     --type=<Str>                 Type of the UML diagram. [default: 'class']
  #     -I=<Str>                     Using include path to find libraries. [default: '']
  #     --attributes                 Should the class attributes be included in the UML diagrams or not? [default: True]
  #     --methods                    Should the class methods be included in the UML diagrams or not? [default: True]
  #     --concise-grammar-classes    Should grammar classes be shortened or not? [default: True]
  #     --format=<Str>               Format of the output, one of 'Mermaid', 'MermaidJS', 'Plant', 'PlantUML', 'WL', 'WLUML', or 'Whatever'. [default: 'PlantUML']
  #     --plot                       Should the result be plotted or not? [default: False]
  #     --jar=<Str>                  JAR file to use if --plot. If --jar is an empty string then PLANTUMLJAR and PLANTUML_JAR are attempted. [default: '']
  #     --viewer=<Str>               Image viewer program to use if --plot. If --viewer is an empty string then open is used on macOS and xdg-open on Linux. [default: '']
  
  ```
  
  ### Usage examples
  
  Generate PlantUML spec for the Raku package
  ["ML::Clustering"](https://raku.land/zef:antononcube/ML::Clustering):
  
  ```
  to-uml-spec --/methods --/attributes "ML::Clustering"
  
  ```
  
  ```
  # @startuml
  # class "find-clusters" <<routine>> {
  # }
  # "find-clusters" --|> Routine
  # "find-clusters" --|> Block
  # "find-clusters" --|> Code
  # "find-clusters" --|> Callable
  # 
  # 
  # class "k-means" <<routine>> {
  # }
  # "k-means" --|> Routine
  # "k-means" --|> Block
  # "k-means" --|> Code
  # "k-means" --|> Callable
  # 
  # 
  # class ML::Clustering::KMeans  {
  # }
  # ML::Clustering::KMeans --|> ML::Clustering::DistanceFunctions
  # 
  # 
  # class ML::Clustering::DistanceFunctions <<role>> {
  # }
  # 
  # 
  # @enduml
  
  ```
  
  With this shell command we generate a Plant UML spec for the package
  ["Chemistry::Stoichiometry"](https://raku.land/cpan:ANTONOV/Chemistry::Stoichiometry)
  and create the UML diagram image with a local PlantUML JAR file (downloaded from [PUML1]):
  
  ```
  to-uml-spec --/methods --/attributes 'Chemistry::Stoichiometry' | java -jar ~/Downloads/plantuml-1.2022.5.jar -pipe -tjpg > /tmp/myuml.jpg
  
  ```
  
  ---
  
  ## Raku session
  
  ### UML for ad hoc classes
  
  Here we generate a PlantUML spec:
  
  ```
  use UML::Translators;
  module MyPackageClass {
    role A { method a1 {} }
    role B { method b1 {} }
    class C does A { has $!c-var; method c1 {} }
    class D does B is C { has $!d-var; method d1 {} }
  }
  to-uml-spec('MyPackageClass')
  
  ```
  
  ```
  # @startuml
  # class MyPackageClass::C  {
  #   {field} $!c-var
  #   {method} BUILDALL
  #   {method} a1
  #   {method} c1
  # }
  # MyPackageClass::C --|> MyPackageClass::A
  # 
  # 
  # class MyPackageClass::D  {
  #   {field} $!c-var
  #   {field} $!d-var
  #   {method} BUILDALL
  #   {method} b1
  #   {method} d1
  # }
  # MyPackageClass::D --|> MyPackageClass::C
  # MyPackageClass::D --|> MyPackageClass::A
  # MyPackageClass::D --|> MyPackageClass::B
  # 
  # 
  # class MyPackageClass::B <<role>> {
  #   {method} b1
  # }
  # 
  # 
  # class MyPackageClass::A <<role>> {
  #   {method} a1
  # }
  # 
  # 
  # @enduml
  
  ```
  
  Here we generate a MermaidJS spec:
  
  ```
  to-uml-spec('MyPackageClass', format => 'mermaid')
  
  ```
  
  ```
  classDiagram
  class MyPackageClass_C {
    +$!c-var
    +BUILDALL()
    +a1()
    +c1()
  }
  MyPackageClass_C --|> MyPackageClass_A
  
  
  class MyPackageClass_D {
    +$!c-var
    +$!d-var
    +BUILDALL()
    +b1()
    +d1()
  }
  MyPackageClass_D --|> MyPackageClass_C
  MyPackageClass_D --|> MyPackageClass_A
  MyPackageClass_D --|> MyPackageClass_B
  
  
  class MyPackageClass_B {
    <<role>>
    +b1()
  }
  
  
  class MyPackageClass_A {
    <<role>>
    +a1()
  }
  
  ```
  
  ### UML for packages
  
  Get PlantUML code for the package
  ['Chemistry::Stoichiometry'](https://raku.land/cpan:ANTONOV/Chemistry::Stoichiometry):
  
  ```
  say to-uml-spec('Chemistry::Stoichiometry'):!methods:!attributes
  
  ```
  
  ```
  # @startuml
  # class Chemistry::Stoichiometry::ResourceAccess  {
  # }
  # 
  # 
  # class Chemistry::Stoichiometry::Grammar <<grammar>> {
  # }
  # Chemistry::Stoichiometry::Grammar --|> Grammar
  # Chemistry::Stoichiometry::Grammar --|> Match
  # Chemistry::Stoichiometry::Grammar --|> Capture
  # Chemistry::Stoichiometry::Grammar --|> Chemistry::Stoichiometry::Grammar::ChemicalElement
  # Chemistry::Stoichiometry::Grammar --|> Chemistry::Stoichiometry::Grammar::ChemicalEquation
  # Chemistry::Stoichiometry::Grammar --|> NQPMatchRole
  # 
  # 
  # class Chemistry::Stoichiometry::Grammar::ChemicalEquation <<role>> {
  # }
  # 
  # 
  # class Chemistry::Stoichiometry::Grammar::ChemicalElement <<role>> {
  # }
  # 
  # 
  # class Chemistry::Stoichiometry::Actions::EquationBalance  {
  # }
  # Chemistry::Stoichiometry::Actions::EquationBalance --|> Chemistry::Stoichiometry::Actions::EquationMatrix
  # 
  # 
  # class Chemistry::Stoichiometry::Actions::MolecularMass  {
  # }
  # 
  # 
  # class Chemistry::Stoichiometry::Actions::EquationMatrix  {
  # }
  # 
  # 
  # class Chemistry::Stoichiometry::Actions::WL::System  {
  # }
  # 
  # 
  # @enduml
  
  ```
  
  Get WL UML graph spec for the package [AAp1]:
  
  ```
  say to-uml-spec('Chemistry::Stoichiometry', format => 'wluml'):!methods:!attributes
  
  ```
  
  ```
  # UMLClassGraph[
  # "Parents" -> Flatten[{"Chemistry::Stoichiometry::Grammar" \[DirectedEdge] "Grammar", "Chemistry::Stoichiometry::Grammar" \[DirectedEdge] "Match", "Chemistry::Stoichiometry::Grammar" \[DirectedEdge] "Capture", "Chemistry::Stoichiometry::Grammar" \[DirectedEdge] "Chemistry::Stoichiometry::Grammar::ChemicalElement", "Chemistry::Stoichiometry::Grammar" \[DirectedEdge] "Chemistry::Stoichiometry::Grammar::ChemicalEquation", "Chemistry::Stoichiometry::Grammar" \[DirectedEdge] "NQPMatchRole", "Chemistry::Stoichiometry::Actions::EquationBalance" \[DirectedEdge] "Chemistry::Stoichiometry::Actions::EquationMatrix"}],
  # "RegularMethods" -> Flatten[{}],
  # "Abstract" -> Flatten[{"Chemistry::Stoichiometry::Grammar::ChemicalElement", "Chemistry::Stoichiometry::Grammar::ChemicalEquation", "NQPMatchRole"}],
  # "EntityColumn" -> False, VertexLabelStyle -> "Text", ImageSize -> Large, GraphLayout -> Automatic]
  
  ```
  
  ### Classes in a name space
  
  Get the classes, roles, subs, and constants of a namespace:
  
  ```
  .say for namespace-types('ML::TriesWithFrequencies', :how-pairs).sort(*.key)
  
  ```
  
  ```
  # ML::TriesWithFrequencies::LeafProbabilitiesGatherer => Perl6::Metamodel::ClassHOW
  # ML::TriesWithFrequencies::ParetoBasedRemover => Perl6::Metamodel::ClassHOW
  # ML::TriesWithFrequencies::PathsGatherer => Perl6::Metamodel::ClassHOW
  # ML::TriesWithFrequencies::RegexBasedRemover => Perl6::Metamodel::ClassHOW
  # ML::TriesWithFrequencies::ThresholdBasedRemover => Perl6::Metamodel::ClassHOW
  # ML::TriesWithFrequencies::Trie => Perl6::Metamodel::ClassHOW
  # ML::TriesWithFrequencies::TrieTraverse => Perl6::Metamodel::ParametricRoleGroupHOW
  # ML::TriesWithFrequencies::Trieish => Perl6::Metamodel::ParametricRoleGroupHOW
  # TRIEROOT => Str
  # TRIEVALUE => Str
  
  ```
  
  ---
  
  ## Potential problems
  
  ### Mermaid JS
  
  The package can export class diagrams in the
  [Mermaid-JS format](https://mermaid-js.github.io/mermaid/#/classDiagram).
  Unfortunately, currently (November 2022) Mermaid-JS does not support colon characters in class names.
  Hence, colons are replaced with underscores.
  
  Also, currently (November 2022) class specs in Mermaid-JS cannot be empty. I.e. the Mermaid JS code
  generated here ***will not*** produce a diagram:
  
  ```
  to-uml-spec --/methods --/attributes "ML::Clustering" --format=mermaid  
  
  ```
  
  ```
  # classDiagram
  # class ML_Clustering_KMeans {
  # }
  # ML_Clustering_KMeans --|> ML_Clustering_DistanceFunctions
  # 
  # 
  # class k_means {
  #   <<routine>>
  # }
  # k_means --|> Routine
  # k_means --|> Block
  # k_means --|> Code
  # k_means --|> Callable
  # 
  # 
  # class ML_Clustering_DistanceFunctions {
  #   <<role>>
  # }
  # 
  # 
  # class find_clusters {
  #   <<routine>>
  # }
  # find_clusters --|> Routine
  # find_clusters --|> Block
  # find_clusters --|> Code
  # find_clusters --|> Callable
  
  ```
  
  (Because of the empty definition `ML_Clustering_KMeans { }`.)
  
  This command should produce Mermaid JS code that will produce diagram:
  
  ```
  to-uml-spec --/methods --/attributes "ML::Clustering" --format=mermaid  
  
  ```
  
  ---
  
  ## References
  
  [AA1] Anton Antonov, et al.,
  ["Find programmatically all classes, grammars, and roles in a Raku package"](https://stackoverflow.com/q/68622047/14163984),
  (2021),
  [StackOverflow](https://stackoverflow.com).
  
  [AA2] Anton Antonov,
  ["Generating UML diagrams for Raku namespaces"](https://community.wolfram.com/groups/-/m/t/2549055),
  (2022),
  [community.wolfram.com](https://community.wolfram.com).
  
  [AAp1] Anton Antonov,
  ["UML Diagram Generation Mathematica package"](https://github.com/antononcube/MathematicaForPrediction/blob/master/Misc/UMLDiagramGeneration.m),
  (2016),
  [MathematicaForPrediction at GitHub/antononcube](https://github.com/antononcube).
  
  [ES1] Eugene Steinberg and Vojtech Krasa,
  [PlantUML integration IntelliJ IDEA plugin](https://plugins.jetbrains.com/plugin/7017-plantuml-integration),
  [JetBrains Plugins Marketplace](https://plugins.jetbrains.com).
  
  [GV1] [graphviz.org](https://graphviz.org).
  
  [PUML1] [plantuml.com](https://plantuml.com).
  
  [PUML2] [PlantUML online demo server](http://www.plantuml.com/plantuml).
  
  [UMLD1] [uml-diagrams.org](https://www.uml-diagrams.org).
  
  [WK1] Wikipedia entry, ["Graphviz"](https://en.wikipedia.org/wiki/Graphviz).
  
  [WK2] Wikipedia entry, ["PlantUML"](https://en.wikipedia.org/wiki/PlantUML).
  
  [WK3] Wikipedia entry, ["Unified Modeling Language"](https://en.wikipedia.org/wiki/Unified_Modeling_Language).
  