drawio_dsl 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.builders/generators/10-layout.rb +15 -2
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +10 -0
- data/lib/drawio_dsl/configuration.rb +12 -12
- data/lib/drawio_dsl/dom_builder.rb +41 -23
- data/lib/drawio_dsl/drawio.rb +21 -41
- data/lib/drawio_dsl/layout_engine.rb +38 -26
- data/lib/drawio_dsl/schema.rb +306 -48
- data/lib/drawio_dsl/version.rb +1 -1
- data/lib/drawio_dsl/xml_builder.rb +7 -7
- data/lib/drawio_dsl.rb +0 -1
- data/package-lock.json +2 -2
- data/package.json +1 -1
- metadata +2 -3
- data/lib/drawio_dsl/layout_container.rb +0 -54
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 96f9176e2e3f9b37f0a02f462d075835aae641a43d14dc45c747a1434fcb17df
         | 
| 4 | 
            +
              data.tar.gz: 07ef19170c1721bb9ebe7a58d9cc6d20ca000d620b555941c2e396d83a8b27e0
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: ccb338c21e1a14d55e0fb7965c05c014714e37081a1b2f365ea01168017d15327043255a23346dde6c7674419c5458ea9516411240108e5e5c4cb688b9210a9f
         | 
| 7 | 
            +
              data.tar.gz: ab033223b347fa65e1e6e2ddb91d93085276052dd21685d5bd76db0c9cc0f92c1c0a2e5cade339f4e1f7a67569ee42153249d61ec6f15bdb8401e7b52d25d57b
         | 
| @@ -5,9 +5,22 @@ KManager.action :bootstrap do | |
| 5 5 | 
             
                    on_exist:                   :skip,                      # %i[skip write compare]
         | 
| 6 6 | 
             
                    on_action:                  :queue                      # %i[queue execute]
         | 
| 7 7 | 
             
                  )
         | 
| 8 | 
            +
                  .diagram(theme: :style_01)
         | 
| 9 | 
            +
                  .page('Grid-Right', page_shadow: 1) do
         | 
| 10 | 
            +
                    grid_layout(wrap_at: 3)
         | 
| 11 | 
            +
                    square(title: 'Square')
         | 
| 12 | 
            +
                    rectangle(title: 'Rectangle')
         | 
| 13 | 
            +
                    rectangle(title: 'Rectangle (Rounded)', rounded: 1)
         | 
| 14 | 
            +
                    circle(title: 'Circle')
         | 
| 15 | 
            +
                    process(title: 'Process')
         | 
| 16 | 
            +
                    ellipse(title: 'Ellipse')
         | 
| 17 | 
            +
                  end
         | 
| 8 18 |  | 
| 9 | 
            -
                 | 
| 10 | 
            -
             | 
| 19 | 
            +
                diagram = DrawioDsl::XmlBuilder.new(director.builder.diagram)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
             | 
| 22 | 
            +
                File.write('../spec/.samples/drawio/10-layout.xml', diagram.build)
         | 
| 23 | 
            +
                File.write('../spec/.samples/drawio/10-layout.drawio', diagram.build)
         | 
| 11 24 | 
             
              end
         | 
| 12 25 | 
             
            end
         | 
| 13 26 |  | 
    
        data/.rubocop.yml
    CHANGED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,13 @@ | |
| 1 | 
            +
            # [0.1.0](https://github.com/klueless-io/drawio_dsl/compare/v0.0.1...v0.1.0) (2022-03-02)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
             | 
| 4 | 
            +
            ### Features
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            * initial draw-io dsl ([ac197c8](https://github.com/klueless-io/drawio_dsl/commit/ac197c88b66b883b5fcce93090c285bc9ccdb7a3))
         | 
| 7 | 
            +
            * initial draw-io dsl ([12c8b98](https://github.com/klueless-io/drawio_dsl/commit/12c8b98392e5f7da598cf2f9c375f1ca7041533b))
         | 
| 8 | 
            +
            * initial draw-io dsl ([6ef32ad](https://github.com/klueless-io/drawio_dsl/commit/6ef32adcb1287d9993ebe30c437326716357a08e))
         | 
| 9 | 
            +
            * initial draw-io dsl ([16827b5](https://github.com/klueless-io/drawio_dsl/commit/16827b57767d12c387167b86f17b33115d1d0378))
         | 
| 10 | 
            +
             | 
| 1 11 | 
             
            ## [Unreleased]
         | 
| 2 12 |  | 
| 3 13 | 
             
            ## [0.1.0] - 2022-02-25
         | 
| @@ -17,16 +17,16 @@ module DrawioDsl | |
| 17 17 |  | 
| 18 18 | 
             
                BaseStyle = Struct.new(:white_space, :html, :rounded, :shadow, :sketch, :glass, keyword_init: true)
         | 
| 19 19 |  | 
| 20 | 
            -
                 | 
| 21 | 
            -
                 | 
| 20 | 
            +
                ShapeDefaults   = Struct.new(:type, :x, :y, :w, :h, :style_modifiers)
         | 
| 21 | 
            +
                ShapeThemeStyle = Struct.new(:fill_color, :stroke_color, :font_color, :gradient, keyword_init: true)
         | 
| 22 22 |  | 
| 23 23 | 
             
                attr_accessor :base_style
         | 
| 24 24 |  | 
| 25 25 | 
             
                # Theme colors
         | 
| 26 26 | 
             
                attr_accessor :themes
         | 
| 27 27 |  | 
| 28 | 
            -
                #  | 
| 29 | 
            -
                attr_accessor : | 
| 28 | 
            +
                # Shape shapes
         | 
| 29 | 
            +
                attr_accessor :shape
         | 
| 30 30 | 
             
                attr_accessor :square
         | 
| 31 31 | 
             
                attr_accessor :rectangle
         | 
| 32 32 | 
             
                attr_accessor :circle
         | 
| @@ -39,13 +39,13 @@ module DrawioDsl | |
| 39 39 | 
             
                def initialize
         | 
| 40 40 | 
             
                  @base_style = BaseStyle.new(white_space: :wrap, html: 1, rounded: nil, shadow: nil, sketch: nil, glass: nil)
         | 
| 41 41 |  | 
| 42 | 
            -
                  @ | 
| 43 | 
            -
                  @square     =  | 
| 44 | 
            -
                  @rectangle  =  | 
| 45 | 
            -
                  @circle     =  | 
| 46 | 
            -
                  @process    =  | 
| 47 | 
            -
                  @ellipse    =  | 
| 48 | 
            -
                  @triangle   =  | 
| 42 | 
            +
                  @shape      = ShapeDefaults.new(:shape   , 0, 0, 20, 20, '')
         | 
| 43 | 
            +
                  @square     = ShapeDefaults.new(:square    , 0, 0, 160, 160, '')
         | 
| 44 | 
            +
                  @rectangle  = ShapeDefaults.new(:rectangle , 0, 0, 200, 120, '')
         | 
| 45 | 
            +
                  @circle     = ShapeDefaults.new(:circle    , 0, 0, 160, 160, 'ellipse')
         | 
| 46 | 
            +
                  @process    = ShapeDefaults.new(:process   , 0, 0, 200, 120, 'shape=process')
         | 
| 47 | 
            +
                  @ellipse    = ShapeDefaults.new(:ellipse   , 0, 0, 200, 120, 'ellipse')
         | 
| 48 | 
            +
                  @triangle   = ShapeDefaults.new(:triangle  , 0, 0, 160, 160, 'rhombus')
         | 
| 49 49 |  | 
| 50 50 | 
             
                  @themes     = {}
         | 
| 51 51 | 
             
                  add_themes
         | 
| @@ -62,7 +62,7 @@ module DrawioDsl | |
| 62 62 | 
             
                private
         | 
| 63 63 |  | 
| 64 64 | 
             
                def add_theme(name, **opts)
         | 
| 65 | 
            -
                  @themes[name] =  | 
| 65 | 
            +
                  @themes[name] = ShapeThemeStyle.new(**opts)
         | 
| 66 66 | 
             
                end
         | 
| 67 67 |  | 
| 68 68 | 
             
                # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
         | 
| @@ -7,7 +7,8 @@ module DrawioDsl | |
| 7 7 | 
             
                attr_reader :last_action
         | 
| 8 8 |  | 
| 9 9 | 
             
                attr_reader :current_page
         | 
| 10 | 
            -
                attr_reader : | 
| 10 | 
            +
                attr_reader :current_layout_rule
         | 
| 11 | 
            +
                attr_reader :current_shape
         | 
| 11 12 |  | 
| 12 13 | 
             
                def initialize
         | 
| 13 14 | 
             
                  @actions = []
         | 
| @@ -18,7 +19,7 @@ module DrawioDsl | |
| 18 19 | 
             
                  @actions = []
         | 
| 19 20 | 
             
                  @last_action = {}
         | 
| 20 21 | 
             
                  set_diagram
         | 
| 21 | 
            -
                  set_layout_engine
         | 
| 22 | 
            +
                  # set_layout_engine
         | 
| 22 23 | 
             
                end
         | 
| 23 24 |  | 
| 24 25 | 
             
                def queue_action(action)
         | 
| @@ -26,16 +27,6 @@ module DrawioDsl | |
| 26 27 | 
             
                  @last_action = action
         | 
| 27 28 | 
             
                end
         | 
| 28 29 |  | 
| 29 | 
            -
                def set_layout_engine(**opts)
         | 
| 30 | 
            -
                  @layout_engine = DrawioDsl::LayoutEngine.new(**opts)
         | 
| 31 | 
            -
                end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                def layout_engine
         | 
| 34 | 
            -
                  return @layout_engine if defined? @layout_engine
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                  set_layout_engine
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
             | 
| 39 30 | 
             
                def set_diagram(**opts)
         | 
| 40 31 | 
             
                  @diagram = DrawioDsl::Schema::Diagram.new(**opts)
         | 
| 41 32 | 
             
                end
         | 
| @@ -55,40 +46,67 @@ module DrawioDsl | |
| 55 46 | 
             
                  @current_page
         | 
| 56 47 | 
             
                end
         | 
| 57 48 |  | 
| 58 | 
            -
                 | 
| 59 | 
            -
             | 
| 49 | 
            +
                # ----------------------------------------------------------------------
         | 
| 50 | 
            +
                # Layout provides rules for positioning components
         | 
| 51 | 
            +
                # ----------------------------------------------------------------------
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def add_grid_layout(**opts)
         | 
| 54 | 
            +
                  rule = DrawioDsl::Schema::GridLayout.new(current_page, **opts)
         | 
| 55 | 
            +
                  add_layout_rule(rule)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                def add_flex_layout(**opts)
         | 
| 59 | 
            +
                  rule = DrawioDsl::Schema::FlexLayout.new(current_page, **opts)
         | 
| 60 | 
            +
                  add_layout_rule(rule)
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                def add_layout_rule(rule)
         | 
| 64 | 
            +
                  @current_layout_rule = rule
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  rule.id = "rule-#{current_page.nodes.length + 1}" unless rule.id
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  current_page.nodes << rule
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  rule
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                # ----------------------------------------------------------------------
         | 
| 74 | 
            +
                # Shapes represent visual components
         | 
| 75 | 
            +
                # ----------------------------------------------------------------------
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                def add_shape(shape)
         | 
| 78 | 
            +
                  @current_shape = shape
         | 
| 60 79 |  | 
| 61 | 
            -
                   | 
| 80 | 
            +
                  shape.id = "#{current_page.id}-#{current_page.nodes.length + 1}" unless shape.id
         | 
| 62 81 |  | 
| 63 | 
            -
                   | 
| 82 | 
            +
                  current_page.nodes << shape
         | 
| 64 83 |  | 
| 65 | 
            -
                   | 
| 66 | 
            -
                  @current_element
         | 
| 84 | 
            +
                  shape
         | 
| 67 85 | 
             
                end
         | 
| 68 86 |  | 
| 69 87 | 
             
                def add_square(**opts)
         | 
| 70 88 | 
             
                  square = DrawioDsl::Schema::Square.new(current_page, **opts)
         | 
| 71 | 
            -
                   | 
| 89 | 
            +
                  add_shape(square)
         | 
| 72 90 | 
             
                end
         | 
| 73 91 |  | 
| 74 92 | 
             
                def add_rectangle(**opts)
         | 
| 75 93 | 
             
                  rectangle = DrawioDsl::Schema::Rectangle.new(current_page, **opts)
         | 
| 76 | 
            -
                   | 
| 94 | 
            +
                  add_shape(rectangle)
         | 
| 77 95 | 
             
                end
         | 
| 78 96 |  | 
| 79 97 | 
             
                def add_circle(**opts)
         | 
| 80 98 | 
             
                  circle = DrawioDsl::Schema::Circle.new(current_page, **opts)
         | 
| 81 | 
            -
                   | 
| 99 | 
            +
                  add_shape(circle)
         | 
| 82 100 | 
             
                end
         | 
| 83 101 |  | 
| 84 102 | 
             
                def add_process(**opts)
         | 
| 85 103 | 
             
                  process = DrawioDsl::Schema::Process.new(current_page, **opts)
         | 
| 86 | 
            -
                   | 
| 104 | 
            +
                  add_shape(process)
         | 
| 87 105 | 
             
                end
         | 
| 88 106 |  | 
| 89 107 | 
             
                def add_ellipse(**opts)
         | 
| 90 108 | 
             
                  ellipse = DrawioDsl::Schema::Ellipse.new(current_page, **opts)
         | 
| 91 | 
            -
                   | 
| 109 | 
            +
                  add_shape(ellipse)
         | 
| 92 110 | 
             
                end
         | 
| 93 111 |  | 
| 94 112 | 
             
                def debug
         | 
    
        data/lib/drawio_dsl/drawio.rb
    CHANGED
    
    | @@ -5,12 +5,6 @@ module DrawioDsl | |
| 5 5 | 
             
              class Drawio < KDirector::Directors::BaseDirector
         | 
| 6 6 | 
             
                default_builder_type(DrawioDsl::DomBuilder)
         | 
| 7 7 |  | 
| 8 | 
            -
                def layout(**opts)
         | 
| 9 | 
            -
                  builder.set_layout_engine(**opts)
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  self
         | 
| 12 | 
            -
                end
         | 
| 13 | 
            -
             | 
| 14 8 | 
             
                def diagram(**opts)
         | 
| 15 9 | 
             
                  builder.set_diagram(**opts)
         | 
| 16 10 |  | 
| @@ -23,6 +17,13 @@ module DrawioDsl | |
| 23 17 |  | 
| 24 18 | 
             
                  self
         | 
| 25 19 | 
             
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def apply_layout
         | 
| 22 | 
            +
                  engine = DrawioDsl::LayoutEngine.new(builder.diagram)
         | 
| 23 | 
            +
                  engine.call
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  self
         | 
| 26 | 
            +
                end
         | 
| 26 27 | 
             
              end
         | 
| 27 28 |  | 
| 28 29 | 
             
              # DrawioDsl::DrawioPage is created when you call .page on the draw-io DSL.
         | 
| @@ -41,63 +42,42 @@ module DrawioDsl | |
| 41 42 | 
             
                  builder.add_page(**opts)
         | 
| 42 43 | 
             
                end
         | 
| 43 44 |  | 
| 45 | 
            +
                def layout_rule(**opts)
         | 
| 46 | 
            +
                  builder.add_layout_rule(**opts)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def grid_layout(**opts)
         | 
| 50 | 
            +
                  builder.add_grid_layout(**opts)
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def flex_layout(**opts)
         | 
| 54 | 
            +
                  builder.add_flex_layout(**opts)
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 44 57 | 
             
                def square(**opts)
         | 
| 45 | 
            -
                  opts = attach_xy(**opts)
         | 
| 46 58 | 
             
                  builder.add_square(**opts)
         | 
| 47 | 
            -
                  update_layout
         | 
| 48 59 | 
             
                end
         | 
| 49 60 |  | 
| 50 61 | 
             
                def rectangle(**opts)
         | 
| 51 | 
            -
                  opts = attach_xy(**opts)
         | 
| 52 62 | 
             
                  builder.add_rectangle(**opts)
         | 
| 53 | 
            -
                  update_layout
         | 
| 54 63 | 
             
                end
         | 
| 55 64 |  | 
| 56 65 | 
             
                def circle(**opts)
         | 
| 57 | 
            -
                  opts = attach_xy(**opts)
         | 
| 58 66 | 
             
                  builder.add_circle(**opts)
         | 
| 59 | 
            -
                  update_layout
         | 
| 60 67 | 
             
                end
         | 
| 61 68 |  | 
| 62 69 | 
             
                def process(**opts)
         | 
| 63 | 
            -
                  opts = attach_xy(**opts)
         | 
| 64 70 | 
             
                  builder.add_process(**opts)
         | 
| 65 | 
            -
                  update_layout
         | 
| 66 71 | 
             
                end
         | 
| 67 72 |  | 
| 68 73 | 
             
                def ellipse(**opts)
         | 
| 69 | 
            -
                  opts = attach_xy(**opts)
         | 
| 70 74 | 
             
                  builder.add_ellipse(**opts)
         | 
| 71 | 
            -
                  update_layout
         | 
| 72 75 | 
             
                end
         | 
| 73 76 |  | 
| 74 77 | 
             
                private
         | 
| 75 78 |  | 
| 76 | 
            -
                def  | 
| 77 | 
            -
                  builder. | 
| 78 | 
            -
                end
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                # attr_reader :layout_engine
         | 
| 81 | 
            -
                # set_layout
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                # layout.container.place_element(element)
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                def update_layout
         | 
| 86 | 
            -
                  return unless auto_layout
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                  # puts current_element.page.x
         | 
| 89 | 
            -
                  # puts current_element.page.y
         | 
| 90 | 
            -
                  # puts current_element.page.w
         | 
| 91 | 
            -
                  # puts current_element.page.h
         | 
| 92 | 
            -
             | 
| 93 | 
            -
                  @current_x += current_element.w + 20
         | 
| 94 | 
            -
                  @current_y += current_element.h + 20
         | 
| 95 | 
            -
                end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                def attach_xy(**opts)
         | 
| 98 | 
            -
                  opts[:x] ||= current_x
         | 
| 99 | 
            -
                  opts[:y] ||= current_y
         | 
| 100 | 
            -
                  opts
         | 
| 79 | 
            +
                def current_shape
         | 
| 80 | 
            +
                  builder.current_shape
         | 
| 101 81 | 
             
                end
         | 
| 102 82 | 
             
              end
         | 
| 103 83 | 
             
            end
         | 
| @@ -9,39 +9,51 @@ module DrawioDsl | |
| 9 9 | 
             
              # Elements will be placed on the page in the order they are added.
         | 
| 10 10 | 
             
              # Row/column flow objects will hold information about horizontal and vertical element padding
         | 
| 11 11 | 
             
              class LayoutEngine
         | 
| 12 | 
            -
                 | 
| 13 | 
            -
             | 
| 14 | 
            -
                 | 
| 15 | 
            -
                 | 
| 16 | 
            -
             | 
| 17 | 
            -
                 | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 12 | 
            +
                attr_reader :diagram
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                attr_reader :current_page
         | 
| 15 | 
            +
                attr_reader :current_layout
         | 
| 16 | 
            +
                attr_reader :page_margin_top
         | 
| 17 | 
            +
                attr_reader :page_margin_left
         | 
| 18 | 
            +
                attr_reader :x
         | 
| 19 | 
            +
                attr_reader :y
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def initialize(diagram)
         | 
| 22 | 
            +
                  @diagram = diagram
         | 
| 23 | 
            +
                  @x = 0
         | 
| 24 | 
            +
                  @y = 0
         | 
| 22 25 | 
             
                end
         | 
| 23 26 |  | 
| 24 | 
            -
                def  | 
| 25 | 
            -
                   | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
                def go_vertical(**opts)
         | 
| 29 | 
            -
                  @container = LayoutContainer.new(self, direction: :vertical, **opts)
         | 
| 30 | 
            -
                end
         | 
| 27 | 
            +
                def call
         | 
| 28 | 
            +
                  diagram.pages.each do |page|
         | 
| 29 | 
            +
                    focus_on_page(page)
         | 
| 31 30 |  | 
| 32 | 
            -
             | 
| 33 | 
            -
                   | 
| 31 | 
            +
                    apply_layout_to_page(page)
         | 
| 32 | 
            +
                  end
         | 
| 34 33 | 
             
                end
         | 
| 35 34 |  | 
| 36 | 
            -
                 | 
| 37 | 
            -
                # def position_element(element)
         | 
| 38 | 
            -
                #   container.horizontal?
         | 
| 39 | 
            -
                # end
         | 
| 35 | 
            +
                private
         | 
| 40 36 |  | 
| 41 | 
            -
                 | 
| 37 | 
            +
                def focus_on_page(page)
         | 
| 38 | 
            +
                  @current_page   = page
         | 
| 39 | 
            +
                  page.position_x = page.margin_left
         | 
| 40 | 
            +
                  page.position_y = page.margin_top
         | 
| 41 | 
            +
                end
         | 
| 42 42 |  | 
| 43 | 
            -
                 | 
| 43 | 
            +
                def apply_layout_to_page(page)
         | 
| 44 | 
            +
                  page.nodes.each do |node|
         | 
| 45 | 
            +
                    case node.classification
         | 
| 46 | 
            +
                    when :layout_rule
         | 
| 47 | 
            +
                      @current_layout = node
         | 
| 48 | 
            +
                    when :shape
         | 
| 49 | 
            +
                      current_layout.position_shape(node)
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                    node.debug(format: :row)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 44 54 |  | 
| 45 | 
            -
                 | 
| 55 | 
            +
                def define_layout_rule(layout_rule)
         | 
| 56 | 
            +
                  layout_rule.debug
         | 
| 57 | 
            +
                end
         | 
| 46 58 | 
             
              end
         | 
| 47 59 | 
             
            end
         | 
    
        data/lib/drawio_dsl/schema.rb
    CHANGED
    
    | @@ -2,12 +2,12 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module DrawioDsl
         | 
| 4 4 | 
             
              module Schema
         | 
| 5 | 
            -
                # Common Style is the reused on Diagram, Page and  | 
| 5 | 
            +
                # Common Style is the reused on Diagram, Page and Shape
         | 
| 6 6 | 
             
                #
         | 
| 7 7 | 
             
                # When styles are not provided at each level, then they will inherit from
         | 
| 8 8 | 
             
                # the parent common style.
         | 
| 9 9 | 
             
                #
         | 
| 10 | 
            -
                #  | 
| 10 | 
            +
                # Shapes will use the common style of their page
         | 
| 11 11 | 
             
                class CommonStyle
         | 
| 12 12 | 
             
                  attr_accessor :theme
         | 
| 13 13 | 
             
                  attr_accessor :white_space
         | 
| @@ -76,7 +76,7 @@ module DrawioDsl | |
| 76 76 |  | 
| 77 77 | 
             
                  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
         | 
| 78 78 | 
             
                  def initialize(**args)
         | 
| 79 | 
            -
                    @host = args[:host] | 
| 79 | 
            +
                    @host = args[:host]   || SecureRandom.alphanumeric(3)
         | 
| 80 80 |  | 
| 81 81 | 
             
                    # Apply a random theme to the diagram if none is specified.
         | 
| 82 82 | 
             
                    @theme = args[:theme] || KConfig.configuration.drawio.random_theme
         | 
| @@ -85,22 +85,22 @@ module DrawioDsl | |
| 85 85 | 
             
                      default_style = KConfig.configuration.drawio.base_style
         | 
| 86 86 |  | 
| 87 87 | 
             
                      # Inherit from configured style when specific style not specified.
         | 
| 88 | 
            -
                      @white_space | 
| 89 | 
            -
                      @html | 
| 90 | 
            -
                      @rounded | 
| 91 | 
            -
                      @shadow | 
| 92 | 
            -
                      @sketch | 
| 93 | 
            -
                      @glass | 
| 88 | 
            +
                      @white_space  ||= default_style.white_space
         | 
| 89 | 
            +
                      @html         ||= default_style.html
         | 
| 90 | 
            +
                      @rounded      ||= default_style.rounded
         | 
| 91 | 
            +
                      @shadow       ||= default_style.shadow
         | 
| 92 | 
            +
                      @sketch       ||= default_style.sketch
         | 
| 93 | 
            +
                      @glass        ||= default_style.glass
         | 
| 94 94 | 
             
                    end
         | 
| 95 95 |  | 
| 96 96 | 
             
                    @palette = DrawioDsl::Schema::DefaultPalette.new(self, **args) do |diagram|
         | 
| 97 97 | 
             
                      theme_palette = KConfig.configuration.drawio.palette(diagram.theme)
         | 
| 98 98 |  | 
| 99 99 | 
             
                      # Inherit from theme when specific palette options are not specified.
         | 
| 100 | 
            -
                      @fill_color | 
| 100 | 
            +
                      @fill_color   ||= theme_palette.fill_color
         | 
| 101 101 | 
             
                      @stroke_color ||= theme_palette.stroke_color
         | 
| 102 | 
            -
                      @font_color | 
| 103 | 
            -
                      @gradient | 
| 102 | 
            +
                      @font_color   ||= theme_palette.font_color
         | 
| 103 | 
            +
                      @gradient     ||= theme_palette.gradient
         | 
| 104 104 | 
             
                    end
         | 
| 105 105 |  | 
| 106 106 | 
             
                    @pages = args[:pages] || []
         | 
| @@ -118,16 +118,22 @@ module DrawioDsl | |
| 118 118 | 
             
                  end
         | 
| 119 119 | 
             
                end
         | 
| 120 120 |  | 
| 121 | 
            -
                # Page is a container for  | 
| 121 | 
            +
                # Page is a container for nodes
         | 
| 122 122 | 
             
                class Page
         | 
| 123 123 | 
             
                  attr_accessor :diagram
         | 
| 124 124 |  | 
| 125 | 
            +
                  # These transient attributes hold the current x, y location for the last element added to the page
         | 
| 126 | 
            +
                  attr_accessor :position_x
         | 
| 127 | 
            +
                  attr_accessor :position_y
         | 
| 128 | 
            +
             | 
| 125 129 | 
             
                  attr_accessor :id
         | 
| 126 130 | 
             
                  attr_accessor :name
         | 
| 127 131 | 
             
                  attr_accessor :theme
         | 
| 128 132 | 
             
                  attr_accessor :style
         | 
| 129 133 | 
             
                  attr_accessor :palette
         | 
| 130 | 
            -
                  attr_accessor : | 
| 134 | 
            +
                  attr_accessor :margin_left
         | 
| 135 | 
            +
                  attr_accessor :margin_top
         | 
| 136 | 
            +
                  attr_accessor :nodes
         | 
| 131 137 |  | 
| 132 138 | 
             
                  # attr_accessor :dx              # dx         = "2636"
         | 
| 133 139 | 
             
                  # attr_accessor :dy              # dy         = "2332"
         | 
| @@ -150,9 +156,14 @@ module DrawioDsl | |
| 150 156 | 
             
                  def initialize(diagram, **args)
         | 
| 151 157 | 
             
                    @diagram = diagram
         | 
| 152 158 |  | 
| 159 | 
            +
                    @position_x   = 0
         | 
| 160 | 
            +
                    @position_y   = 0
         | 
| 161 | 
            +
             | 
| 153 162 | 
             
                    @id           = args[:id]
         | 
| 154 163 | 
             
                    @name         = args[:name]
         | 
| 155 164 | 
             
                    @theme        = args[:theme]        || diagram.theme
         | 
| 165 | 
            +
                    @margin_left  = args[:margin_left]  || 50
         | 
| 166 | 
            +
                    @margin_top   = args[:margin_top]   || 50
         | 
| 156 167 |  | 
| 157 168 | 
             
                    @grid         = args[:grid]         || 0
         | 
| 158 169 | 
             
                    @grid_size    = args[:grid_size]    || 10
         | 
| @@ -171,25 +182,25 @@ module DrawioDsl | |
| 171 182 |  | 
| 172 183 | 
             
                    @style = DrawioDsl::Schema::CommonStyle.new(**args) do
         | 
| 173 184 | 
             
                      # Inherit from the diagram style when specific style not specified.
         | 
| 174 | 
            -
                      @white_space | 
| 175 | 
            -
                      @html | 
| 176 | 
            -
                      @rounded | 
| 177 | 
            -
                      @shadow | 
| 178 | 
            -
                      @sketch | 
| 179 | 
            -
                      @glass | 
| 185 | 
            +
                      @white_space  ||= diagram.style.white_space
         | 
| 186 | 
            +
                      @html         ||= diagram.style.html
         | 
| 187 | 
            +
                      @rounded      ||= diagram.style.rounded
         | 
| 188 | 
            +
                      @shadow       ||= diagram.style.shadow
         | 
| 189 | 
            +
                      @sketch       ||= diagram.style.sketch
         | 
| 190 | 
            +
                      @glass        ||= diagram.style.glass
         | 
| 180 191 | 
             
                    end
         | 
| 181 192 |  | 
| 182 193 | 
             
                    @palette = DrawioDsl::Schema::DefaultPalette.new(self, **args) do |page|
         | 
| 183 194 | 
             
                      theme_palette = KConfig.configuration.drawio.palette(page.theme)
         | 
| 184 195 |  | 
| 185 196 | 
             
                      # Inherit from theme when specific palette options are not specified.
         | 
| 186 | 
            -
                      @fill_color | 
| 197 | 
            +
                      @fill_color   ||= theme_palette.fill_color
         | 
| 187 198 | 
             
                      @stroke_color ||= theme_palette.stroke_color
         | 
| 188 | 
            -
                      @font_color | 
| 189 | 
            -
                      @gradient | 
| 199 | 
            +
                      @font_color   ||= theme_palette.font_color
         | 
| 200 | 
            +
                      @gradient     ||= theme_palette.gradient
         | 
| 190 201 | 
             
                    end
         | 
| 191 202 |  | 
| 192 | 
            -
                    @ | 
| 203 | 
            +
                    @nodes = args[:nodes] || []
         | 
| 193 204 | 
             
                  end
         | 
| 194 205 | 
             
                  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
         | 
| 195 206 |  | 
| @@ -200,15 +211,254 @@ module DrawioDsl | |
| 200 211 | 
             
                      theme: theme,
         | 
| 201 212 | 
             
                      palette: palette.to_h,
         | 
| 202 213 | 
             
                      style: style.to_h,
         | 
| 203 | 
            -
                       | 
| 214 | 
            +
                      margin_left: margin_left,
         | 
| 215 | 
            +
                      margin_top: margin_top,
         | 
| 216 | 
            +
                      position_x: position_x,
         | 
| 217 | 
            +
                      position_y: position_y,
         | 
| 218 | 
            +
                      nodes: nodes.map(&:to_h)
         | 
| 204 219 | 
             
                    }
         | 
| 205 220 | 
             
                  end
         | 
| 206 221 | 
             
                end
         | 
| 207 222 |  | 
| 208 | 
            -
                #  | 
| 209 | 
            -
                class  | 
| 223 | 
            +
                # Node is a base for shapes, connections, positioners and layout rules
         | 
| 224 | 
            +
                class Node
         | 
| 225 | 
            +
                  attr_accessor :id
         | 
| 210 226 | 
             
                  attr_accessor :page
         | 
| 227 | 
            +
                  attr_accessor :classification
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                  def initialize(page, **args)
         | 
| 230 | 
            +
                    @page = page
         | 
| 231 | 
            +
                    @id = args[:id]
         | 
| 232 | 
            +
                    @classification = args[:classification] || :unknown
         | 
| 233 | 
            +
                  end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                  def to_h
         | 
| 236 | 
            +
                    {
         | 
| 237 | 
            +
                      id: id,
         | 
| 238 | 
            +
                      classification: classification
         | 
| 239 | 
            +
                    }
         | 
| 240 | 
            +
                  end
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                  def debug(format: :detail)
         | 
| 243 | 
            +
                    if format == :detail
         | 
| 244 | 
            +
                      debug_detail(to_h)
         | 
| 245 | 
            +
                    else
         | 
| 246 | 
            +
                      debug_row(classification, id)
         | 
| 247 | 
            +
                    end
         | 
| 248 | 
            +
                  end
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                  def debug_detail(**key_values)
         | 
| 251 | 
            +
                    key_values.each do |key, value|
         | 
| 252 | 
            +
                      puts "#{key.to_s.ljust(15)}: #{value}"
         | 
| 253 | 
            +
                    end
         | 
| 254 | 
            +
                  end
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                  # rubocop:disable Metrics/AbcSize, Metrics/ParameterLists
         | 
| 257 | 
            +
                  def debug_row(classification, id, type = nil, x = nil, y = nil, width = nil, height = nil)
         | 
| 258 | 
            +
                    row = []
         | 
| 259 | 
            +
                    row << classification.to_s.ljust(11)
         | 
| 260 | 
            +
                    row << id.to_s.ljust(6)
         | 
| 261 | 
            +
                    row << (type.nil? ? '' : type).to_s.ljust(15)
         | 
| 262 | 
            +
                    row << (x.nil? ? '' : x).to_s.rjust(5)
         | 
| 263 | 
            +
                    row << (y.nil? ? '' : y).to_s.rjust(5)
         | 
| 264 | 
            +
                    row << (width.nil? ? '' : width).to_s.rjust(5)
         | 
| 265 | 
            +
                    row << (height.nil? ? '' : height).to_s.rjust(5)
         | 
| 266 | 
            +
                    puts row.join(' | ')
         | 
| 267 | 
            +
                  end
         | 
| 268 | 
            +
                  # rubocop:enable Metrics/AbcSize, Metrics/ParameterLists
         | 
| 269 | 
            +
                end
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                # Provides base configuration for automatic layouts
         | 
| 272 | 
            +
                class LayoutRule < Node
         | 
| 273 | 
            +
                  attr_accessor :type
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                  # represents the x coordinate of the top left corner layout area
         | 
| 276 | 
            +
                  # this coordinate is based on the current location of the page
         | 
| 277 | 
            +
                  attr_accessor :anchor_x
         | 
| 278 | 
            +
                  attr_accessor :anchor_y
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                  def initialize(page, **args)
         | 
| 281 | 
            +
                    @after_init_fired = false
         | 
| 282 | 
            +
             | 
| 283 | 
            +
                    super(page, **args.merge(classification: :layout_rule))
         | 
| 284 | 
            +
                  end
         | 
| 285 | 
            +
             | 
| 286 | 
            +
                  def fire_after_init
         | 
| 287 | 
            +
                    return if @after_init_fired
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                    @after_init_fired = true
         | 
| 290 | 
            +
                    after_init
         | 
| 291 | 
            +
                  end
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                  def after_init
         | 
| 294 | 
            +
                    @anchor_x ||= page.position_x
         | 
| 295 | 
            +
                    @anchor_y ||= page.position_y
         | 
| 296 | 
            +
                  end
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                  def to_h
         | 
| 299 | 
            +
                    super.merge(
         | 
| 300 | 
            +
                      type: type,
         | 
| 301 | 
            +
                      anchor_x: anchor_x,
         | 
| 302 | 
            +
                      anchor_y: anchor_y
         | 
| 303 | 
            +
                    )
         | 
| 304 | 
            +
                  end
         | 
| 305 | 
            +
                end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                # Provides grid style layouts
         | 
| 308 | 
            +
                class GridLayout < LayoutRule
         | 
| 309 | 
            +
                  attr_accessor :direction
         | 
| 310 | 
            +
                  attr_accessor :wrap_at
         | 
| 311 | 
            +
                  attr_accessor :grid_size
         | 
| 312 | 
            +
                  attr_accessor :cell_no
         | 
| 313 | 
            +
                  attr_accessor :h_align
         | 
| 314 | 
            +
                  attr_accessor :v_align
         | 
| 315 | 
            +
             | 
| 316 | 
            +
                  def initialize(page, **args)
         | 
| 317 | 
            +
                    @type       = :grid_layout
         | 
| 318 | 
            +
                    @direction  = args[:direction]  || :horizontal
         | 
| 319 | 
            +
                    @wrap_at    = args[:wrap_at]    || 5
         | 
| 320 | 
            +
                    @grid_size  = args[:grid_size]  || 220
         | 
| 321 | 
            +
                    @h_align    = args[:h_align]    || :center
         | 
| 322 | 
            +
                    @v_align    = args[:v_align]    || :center
         | 
| 323 | 
            +
                    @cell_no    = 1
         | 
| 324 | 
            +
             | 
| 325 | 
            +
                    super(page, **args)
         | 
| 326 | 
            +
                  end
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                  def position_shape(shape)
         | 
| 329 | 
            +
                    fire_after_init
         | 
| 211 330 |  | 
| 331 | 
            +
                    shape.x = horizontal_shape_alignment(shape)
         | 
| 332 | 
            +
                    shape.y = vertical_shape_alignment(shape)
         | 
| 333 | 
            +
             | 
| 334 | 
            +
                    # puts '------------------'
         | 
| 335 | 
            +
                    # puts "cell: #{cell_no}"
         | 
| 336 | 
            +
                    # puts "wrap_at: #{wrap_at}"
         | 
| 337 | 
            +
                    # puts "shape-x: #{shape.x}"
         | 
| 338 | 
            +
                    # puts "shape-y: #{shape.y}"
         | 
| 339 | 
            +
                    # puts "page-x: #{page.position_x}"
         | 
| 340 | 
            +
                    # puts "page-y: #{page.position_y}"
         | 
| 341 | 
            +
                    # puts "anchor-x: #{anchor_x}"
         | 
| 342 | 
            +
                    # puts "anchor-y: #{anchor_y}"
         | 
| 343 | 
            +
             | 
| 344 | 
            +
                    move_cell_horizontally if direction == :horizontal
         | 
| 345 | 
            +
                    move_cell_vertically if direction == :vertical
         | 
| 346 | 
            +
                  end
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                  def to_h
         | 
| 349 | 
            +
                    super.merge(
         | 
| 350 | 
            +
                      direction: direction,
         | 
| 351 | 
            +
                      wrap_at: wrap_at,
         | 
| 352 | 
            +
                      grid_size: grid_size,
         | 
| 353 | 
            +
                      cell_no: cell_no
         | 
| 354 | 
            +
                    )
         | 
| 355 | 
            +
                  end
         | 
| 356 | 
            +
             | 
| 357 | 
            +
                  private
         | 
| 358 | 
            +
             | 
| 359 | 
            +
                  # rubocop:disable Metrics/AbcSize
         | 
| 360 | 
            +
                  def horizontal_shape_alignment(shape)
         | 
| 361 | 
            +
                    return page.position_x + ((grid_size - shape.w) / 2)    if h_align == :left
         | 
| 362 | 
            +
                    return page.position_x + (grid_size - shape.x)          if v_align == :right
         | 
| 363 | 
            +
             | 
| 364 | 
            +
                    page.position_x
         | 
| 365 | 
            +
                  end
         | 
| 366 | 
            +
                  # rubocop:enable Metrics/AbcSize
         | 
| 367 | 
            +
             | 
| 368 | 
            +
                  # rubocop:disable Metrics/AbcSize
         | 
| 369 | 
            +
                  def vertical_shape_alignment(shape)
         | 
| 370 | 
            +
                    return page.position_y + ((grid_size - shape.h) / 2)    if v_align == :middle
         | 
| 371 | 
            +
                    return page.position_y + (grid_size - shape.h)          if v_align == :bottom
         | 
| 372 | 
            +
             | 
| 373 | 
            +
                    page.position_y
         | 
| 374 | 
            +
                  end
         | 
| 375 | 
            +
                  # rubocop:enable Metrics/AbcSize
         | 
| 376 | 
            +
             | 
| 377 | 
            +
                  def move_cell_horizontally
         | 
| 378 | 
            +
                    if cell_no >= wrap_at
         | 
| 379 | 
            +
                      # Flow down to the next row
         | 
| 380 | 
            +
                      page.position_x = anchor_x
         | 
| 381 | 
            +
                      page.position_y += grid_size
         | 
| 382 | 
            +
                      @cell_no = 1
         | 
| 383 | 
            +
                    else
         | 
| 384 | 
            +
                      page.position_x += grid_size
         | 
| 385 | 
            +
                      @cell_no += 1
         | 
| 386 | 
            +
                    end
         | 
| 387 | 
            +
                  end
         | 
| 388 | 
            +
             | 
| 389 | 
            +
                  def move_cell_vertically
         | 
| 390 | 
            +
                    if cell_no >= wrap_at
         | 
| 391 | 
            +
                      # Flow right to the next column
         | 
| 392 | 
            +
                      page.position_y = anchor_y
         | 
| 393 | 
            +
                      page.position_x += grid_size
         | 
| 394 | 
            +
                      @cell_no = 0
         | 
| 395 | 
            +
                    else
         | 
| 396 | 
            +
                      page.position_y += grid_size
         | 
| 397 | 
            +
                      @cell_no += 1
         | 
| 398 | 
            +
                    end
         | 
| 399 | 
            +
                  end
         | 
| 400 | 
            +
                end
         | 
| 401 | 
            +
             | 
| 402 | 
            +
                # Provides flex style layouts
         | 
| 403 | 
            +
                class FlexLayout < LayoutRule
         | 
| 404 | 
            +
                  attr_accessor :direction
         | 
| 405 | 
            +
                  attr_accessor :wrap_at
         | 
| 406 | 
            +
             | 
| 407 | 
            +
                  def initialize(page, **args)
         | 
| 408 | 
            +
                    @type = :flex_layout
         | 
| 409 | 
            +
                    @direction = args[:direction] || :horizontal
         | 
| 410 | 
            +
                    @wrap_at = args[:wrap_at] || (direction == :horizontal ? 1000 : 800)
         | 
| 411 | 
            +
             | 
| 412 | 
            +
                    super(page, **args)
         | 
| 413 | 
            +
                  end
         | 
| 414 | 
            +
             | 
| 415 | 
            +
                  # rubocop:disable Metrics/AbcSize, Style/GuardClause
         | 
| 416 | 
            +
                  def position_shape(shape)
         | 
| 417 | 
            +
                    fire_after_init
         | 
| 418 | 
            +
             | 
| 419 | 
            +
                    shape.x = page.position_x
         | 
| 420 | 
            +
                    shape.y = page.position_y
         | 
| 421 | 
            +
             | 
| 422 | 
            +
                    # Flow down to the next row
         | 
| 423 | 
            +
                    if direction == :horizontal
         | 
| 424 | 
            +
                      if page.position_x + shape.w > boundary
         | 
| 425 | 
            +
                        page.position_x = anchor_x
         | 
| 426 | 
            +
                        page.position_y += grid_size
         | 
| 427 | 
            +
                        @cell_no = 0
         | 
| 428 | 
            +
                      else
         | 
| 429 | 
            +
                        page.position_x += grid_size
         | 
| 430 | 
            +
                      end
         | 
| 431 | 
            +
                    end
         | 
| 432 | 
            +
             | 
| 433 | 
            +
                    # Flow right to the next column
         | 
| 434 | 
            +
                    if direction == :vertical
         | 
| 435 | 
            +
                      if page.position_y + shape.h > boundary
         | 
| 436 | 
            +
                        page.position_y = anchor_y
         | 
| 437 | 
            +
                        page.position_x += grid_size
         | 
| 438 | 
            +
                        @cell_no = 0
         | 
| 439 | 
            +
                      else
         | 
| 440 | 
            +
                        page.position_y += grid_size
         | 
| 441 | 
            +
                      end
         | 
| 442 | 
            +
                    end
         | 
| 443 | 
            +
                  end
         | 
| 444 | 
            +
                  # rubocop:enable Metrics/AbcSize, Style/GuardClause
         | 
| 445 | 
            +
             | 
| 446 | 
            +
                  private
         | 
| 447 | 
            +
             | 
| 448 | 
            +
                  def boundary
         | 
| 449 | 
            +
                    return @boundary if defined? @boundary
         | 
| 450 | 
            +
             | 
| 451 | 
            +
                    bounds = grid_size * wrap_at
         | 
| 452 | 
            +
                    @boundary = bounds + (direction == :horizontal ? anchor_x : anchor_y)
         | 
| 453 | 
            +
                  end
         | 
| 454 | 
            +
             | 
| 455 | 
            +
                  def to_h
         | 
| 456 | 
            +
                    super.merge(direction: direction, wrap_at: wrap_at)
         | 
| 457 | 
            +
                  end
         | 
| 458 | 
            +
                end
         | 
| 459 | 
            +
             | 
| 460 | 
            +
                # Shape is a graphical element, it can be a shape, a text, or a group (todo)
         | 
| 461 | 
            +
                class Shape < Node
         | 
| 212 462 | 
             
                  attr_accessor :theme
         | 
| 213 463 | 
             
                  attr_accessor :title
         | 
| 214 464 |  | 
| @@ -225,7 +475,6 @@ module DrawioDsl | |
| 225 475 | 
             
                  attr_accessor :font_color
         | 
| 226 476 | 
             
                  attr_accessor :gradient
         | 
| 227 477 |  | 
| 228 | 
            -
                  attr_accessor :id
         | 
| 229 478 | 
             
                  attr_accessor :type
         | 
| 230 479 | 
             
                  attr_accessor :x
         | 
| 231 480 | 
             
                  attr_accessor :y
         | 
| @@ -234,14 +483,14 @@ module DrawioDsl | |
| 234 483 | 
             
                  attr_accessor :style_modifiers
         | 
| 235 484 |  | 
| 236 485 | 
             
                  def initialize(page, **args)
         | 
| 237 | 
            -
                     | 
| 238 | 
            -
                     | 
| 486 | 
            +
                    args[:classification] = :shape
         | 
| 487 | 
            +
                    super(page, **args)
         | 
| 239 488 |  | 
| 240 | 
            -
                    apply_defaults(args, KConfig.configuration.drawio. | 
| 489 | 
            +
                    apply_defaults(args, KConfig.configuration.drawio.shape)
         | 
| 241 490 | 
             
                  end
         | 
| 242 491 |  | 
| 243 492 | 
             
                  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
         | 
| 244 | 
            -
                  def apply_defaults(args,  | 
| 493 | 
            +
                  def apply_defaults(args, shape_defaults)
         | 
| 245 494 | 
             
                    @theme            = args[:theme] || page.theme # KConfig.configuration.drawio.themes.sample
         | 
| 246 495 | 
             
                    theme_palette     = KConfig.configuration.drawio.palette(page.theme)
         | 
| 247 496 | 
             
                    @title            = args[:title]            || ''
         | 
| @@ -253,12 +502,12 @@ module DrawioDsl | |
| 253 502 | 
             
                    @sketch           = args[:sketch]           || page.style.sketch
         | 
| 254 503 | 
             
                    @glass            = args[:glass]            || page.style.glass
         | 
| 255 504 |  | 
| 256 | 
            -
                    @type             = args[:type]             ||  | 
| 257 | 
            -
                    @x                = args[:x]                ||  | 
| 258 | 
            -
                    @y                = args[:y]                ||  | 
| 259 | 
            -
                    @w                = args[:w]                ||  | 
| 260 | 
            -
                    @h                = args[:h]                ||  | 
| 261 | 
            -
                    @style_modifiers  = args[:style_modifiers]  ||  | 
| 505 | 
            +
                    @type             = args[:type]             || shape_defaults.type
         | 
| 506 | 
            +
                    @x                = args[:x]                || shape_defaults.x
         | 
| 507 | 
            +
                    @y                = args[:y]                || shape_defaults.y
         | 
| 508 | 
            +
                    @w                = args[:w]                || shape_defaults.w
         | 
| 509 | 
            +
                    @h                = args[:h]                || shape_defaults.h
         | 
| 510 | 
            +
                    @style_modifiers  = args[:style_modifiers]  || shape_defaults.style_modifiers
         | 
| 262 511 |  | 
| 263 512 | 
             
                    @fill_color       = args[:fill_color]       || theme_palette.fill_color
         | 
| 264 513 | 
             
                    @stroke_color     = args[:stroke_color]     || theme_palette.stroke_color
         | 
| @@ -287,6 +536,7 @@ module DrawioDsl | |
| 287 536 | 
             
                  def to_h
         | 
| 288 537 | 
             
                    {
         | 
| 289 538 | 
             
                      id: id,
         | 
| 539 | 
            +
                      classification: classification,
         | 
| 290 540 | 
             
                      type: type,
         | 
| 291 541 | 
             
                      x: x,
         | 
| 292 542 | 
             
                      y: y,
         | 
| @@ -295,10 +545,18 @@ module DrawioDsl | |
| 295 545 | 
             
                      style: style
         | 
| 296 546 | 
             
                    }
         | 
| 297 547 | 
             
                  end
         | 
| 548 | 
            +
             | 
| 549 | 
            +
                  def debug(format: :detail)
         | 
| 550 | 
            +
                    if format == :detail
         | 
| 551 | 
            +
                      debug_detail({ id: id, classification: classification, type: type })
         | 
| 552 | 
            +
                    else
         | 
| 553 | 
            +
                      debug_row(classification, id, type, x, y, w, h)
         | 
| 554 | 
            +
                    end
         | 
| 555 | 
            +
                  end
         | 
| 298 556 | 
             
                end
         | 
| 299 557 |  | 
| 300 | 
            -
                # Graphical  | 
| 301 | 
            -
                class Square <  | 
| 558 | 
            +
                # Graphical shape in the form of a square
         | 
| 559 | 
            +
                class Square < Shape
         | 
| 302 560 | 
             
                  def initialize(page, **args)
         | 
| 303 561 | 
             
                    super(page, **args)
         | 
| 304 562 |  | 
| @@ -306,8 +564,8 @@ module DrawioDsl | |
| 306 564 | 
             
                  end
         | 
| 307 565 | 
             
                end
         | 
| 308 566 |  | 
| 309 | 
            -
                # Graphical  | 
| 310 | 
            -
                class Rectangle <  | 
| 567 | 
            +
                # Graphical shape in the form of a rectangle
         | 
| 568 | 
            +
                class Rectangle < Shape
         | 
| 311 569 | 
             
                  def initialize(page, **args)
         | 
| 312 570 | 
             
                    super(page, **args)
         | 
| 313 571 |  | 
| @@ -315,8 +573,8 @@ module DrawioDsl | |
| 315 573 | 
             
                  end
         | 
| 316 574 | 
             
                end
         | 
| 317 575 |  | 
| 318 | 
            -
                # Graphical  | 
| 319 | 
            -
                class Circle <  | 
| 576 | 
            +
                # Graphical shape in the form of a circle
         | 
| 577 | 
            +
                class Circle < Shape
         | 
| 320 578 | 
             
                  def initialize(page, **args)
         | 
| 321 579 | 
             
                    super(page, **args)
         | 
| 322 580 |  | 
| @@ -324,8 +582,8 @@ module DrawioDsl | |
| 324 582 | 
             
                  end
         | 
| 325 583 | 
             
                end
         | 
| 326 584 |  | 
| 327 | 
            -
                # Graphical  | 
| 328 | 
            -
                class Process <  | 
| 585 | 
            +
                # Graphical shape in the form of an rectangle with to vertical lines
         | 
| 586 | 
            +
                class Process < Shape
         | 
| 329 587 | 
             
                  def initialize(page, **args)
         | 
| 330 588 | 
             
                    super(page, **args)
         | 
| 331 589 |  | 
| @@ -333,8 +591,8 @@ module DrawioDsl | |
| 333 591 | 
             
                  end
         | 
| 334 592 | 
             
                end
         | 
| 335 593 |  | 
| 336 | 
            -
                # Graphical  | 
| 337 | 
            -
                class Ellipse <  | 
| 594 | 
            +
                # Graphical shape in the form of an ellipse
         | 
| 595 | 
            +
                class Ellipse < Shape
         | 
| 338 596 | 
             
                  def initialize(page, **args)
         | 
| 339 597 | 
             
                    super(page, **args)
         | 
| 340 598 |  | 
    
        data/lib/drawio_dsl/version.rb
    CHANGED
    
    
| @@ -52,8 +52,8 @@ module DrawioDsl | |
| 52 52 | 
             
                      xml.root do
         | 
| 53 53 | 
             
                        xml.mxCell(id: "#{page.id}-A")
         | 
| 54 54 | 
             
                        xml.mxCell(id: "#{page.id}-B", parent: "#{page.id}-A")
         | 
| 55 | 
            -
                        page. | 
| 56 | 
            -
                           | 
| 55 | 
            +
                        page.nodes.each do |node|
         | 
| 56 | 
            +
                          build_shape(xml, node) if node.classification == :shape
         | 
| 57 57 | 
             
                        end
         | 
| 58 58 | 
             
                      end
         | 
| 59 59 | 
             
                    end
         | 
| @@ -61,13 +61,13 @@ module DrawioDsl | |
| 61 61 | 
             
                end
         | 
| 62 62 | 
             
                # rubocop:enable  Metrics/MethodLength, Metrics/AbcSize, Metrics/BlockLength
         | 
| 63 63 |  | 
| 64 | 
            -
                def  | 
| 64 | 
            +
                def build_shape(xml, shape)
         | 
| 65 65 | 
             
                  # puts "opts: #{opts}"
         | 
| 66 | 
            -
                  puts  | 
| 67 | 
            -
                  puts  | 
| 66 | 
            +
                  # puts shape.x
         | 
| 67 | 
            +
                  # puts shape.y
         | 
| 68 68 |  | 
| 69 | 
            -
                  xml.mxCell(id:  | 
| 70 | 
            -
                    xml.mxGeometry(x:  | 
| 69 | 
            +
                  xml.mxCell(id: shape.id, value: shape.title, style: shape.style, vertex: 1, parent: "#{shape.page.id}-B") do
         | 
| 70 | 
            +
                    xml.mxGeometry(x: shape.x, y: shape.y, width: shape.w, height: shape.h, as: 'geometry')
         | 
| 71 71 | 
             
                  end
         | 
| 72 72 | 
             
                end
         | 
| 73 73 | 
             
              end
         | 
    
        data/lib/drawio_dsl.rb
    CHANGED
    
    | @@ -12,7 +12,6 @@ require_relative 'drawio_dsl/version' | |
| 12 12 | 
             
            require_relative 'drawio_dsl/schema'
         | 
| 13 13 | 
             
            require_relative 'drawio_dsl/dom_builder'
         | 
| 14 14 | 
             
            require_relative 'drawio_dsl/xml_builder'
         | 
| 15 | 
            -
            require_relative 'drawio_dsl/layout_container'
         | 
| 16 15 | 
             
            require_relative 'drawio_dsl/layout_engine'
         | 
| 17 16 | 
             
            require_relative 'drawio_dsl/drawio'
         | 
| 18 17 |  | 
    
        data/package-lock.json
    CHANGED
    
    | @@ -1,12 +1,12 @@ | |
| 1 1 | 
             
            {
         | 
| 2 2 | 
             
              "name": "drawio_dsl",
         | 
| 3 | 
            -
              "version": "0. | 
| 3 | 
            +
              "version": "0.2.0",
         | 
| 4 4 | 
             
              "lockfileVersion": 2,
         | 
| 5 5 | 
             
              "requires": true,
         | 
| 6 6 | 
             
              "packages": {
         | 
| 7 7 | 
             
                "": {
         | 
| 8 8 | 
             
                  "name": "drawio_dsl",
         | 
| 9 | 
            -
                  "version": "0. | 
| 9 | 
            +
                  "version": "0.2.0",
         | 
| 10 10 | 
             
                  "devDependencies": {
         | 
| 11 11 | 
             
                    "@klueless-js/semantic-release-rubygem": "github:klueless-js/semantic-release-rubygem",
         | 
| 12 12 | 
             
                    "@semantic-release/changelog": "^6.0.1",
         | 
    
        data/package.json
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: drawio_dsl
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - David Cruwys
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2022-03- | 
| 11 | 
            +
            date: 2022-03-04 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: k_config
         | 
| @@ -95,7 +95,6 @@ files: | |
| 95 95 | 
             
            - lib/drawio_dsl/dom_builder.rb
         | 
| 96 96 | 
             
            - lib/drawio_dsl/drawio.rb
         | 
| 97 97 | 
             
            - lib/drawio_dsl/drawio_dsl-OLD.x
         | 
| 98 | 
            -
            - lib/drawio_dsl/layout_container.rb
         | 
| 99 98 | 
             
            - lib/drawio_dsl/layout_engine.rb
         | 
| 100 99 | 
             
            - lib/drawio_dsl/schema.rb
         | 
| 101 100 | 
             
            - lib/drawio_dsl/version.rb
         | 
| @@ -1,54 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module DrawioDsl
         | 
| 4 | 
            -
              # The layout engine is responsible for laying out the elements on the page.
         | 
| 5 | 
            -
              #
         | 
| 6 | 
            -
              # The layout engine can automatically place elements on the page.
         | 
| 7 | 
            -
              #
         | 
| 8 | 
            -
              # It will keep track of layout boundaries, current position and flow direction.
         | 
| 9 | 
            -
              # Elements are positioned on the page in the order they are added.
         | 
| 10 | 
            -
              # Row/column flow objects will hold information about horizontal and vertical element padding
         | 
| 11 | 
            -
              class LayoutContainer
         | 
| 12 | 
            -
                DEFAULT_DIRECTION       = :vertical
         | 
| 13 | 
            -
                DEFAULT_PADDING         = 20
         | 
| 14 | 
            -
                DEFAULT_BOUNDARY_HEIGHT = 800
         | 
| 15 | 
            -
                DEFAULT_BOUNDARY_WIDTH  = 1000
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                attr_reader :engine
         | 
| 18 | 
            -
                attr_accessor :direction
         | 
| 19 | 
            -
                attr_accessor :padding
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                def initialize(engine, **opts)
         | 
| 22 | 
            -
                  @engine     = engine
         | 
| 23 | 
            -
                  @direction  = opts[:direction] || DEFAULT_DIRECTION
         | 
| 24 | 
            -
                  @padding    = opts[:padding]   || DEFAULT_PADDING
         | 
| 25 | 
            -
                  @boundary   = opts[:boundary]
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                def vertical?
         | 
| 29 | 
            -
                  @direction == :vertical
         | 
| 30 | 
            -
                end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                def horizontal?
         | 
| 33 | 
            -
                  @direction == :horizontal
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                attr_writer :boundary
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                def boundary
         | 
| 39 | 
            -
                  @boundary ||= (vertical? ? DEFAULT_BOUNDARY_HEIGHT : DEFAULT_BOUNDARY_WIDTH)
         | 
| 40 | 
            -
                end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                # Place the incoming element by altering it's x, y coordinates based on the rules engine
         | 
| 43 | 
            -
                def place_element(element)
         | 
| 44 | 
            -
                  place_vertical(element) if vertical?
         | 
| 45 | 
            -
                end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                def place_vertical(element)
         | 
| 48 | 
            -
                  element.x = engine.x
         | 
| 49 | 
            -
                  element.y = engine.y
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  engine.y += (element.h + padding)
         | 
| 52 | 
            -
                end
         | 
| 53 | 
            -
              end
         | 
| 54 | 
            -
            end
         |