kramdown-plantuml 1.1.13 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af8b7df3676e0e2a57ebe8e4fc96f0e51388036d7910c9547bbd73f75b9ebde0
4
- data.tar.gz: 1dc627d6d92fd81bd88a2ad7b9bc31f11a319117e734bff80d3e49651be07979
3
+ metadata.gz: 22eb0afc1243816120df8e8acfcf9344e652f376b5b3b06a30bf9ad5968977d5
4
+ data.tar.gz: ba1ddb45bb16802cd21b4e138a2914b56c7d8405edbaec0c17dbdef0da2a9843
5
5
  SHA512:
6
- metadata.gz: 6e7fd6b35fe88507e326370e901b1cc02b7801e1b1a82d2510fa4f3cb41528a43e4465d4c44336ce05ae292a3bc4d1f11b3a382bc779e648c73aab70a33384ea
7
- data.tar.gz: 919450a3b77827d699c2c071c161d7bb29cc7400e6bb108cc6f745e7e8980137174767e208d3cfae2c72ba9701fcc346415d2ee348817f79f4391e3d0ae39162
6
+ metadata.gz: 715ab104a048c524ef11da13d607e8701f90b6125bbcf251688204ad8011c46f673a94e188c23b5635a01c0af7f057e7d077e62df4d405d9353ac9df5a403ffc
7
+ data.tar.gz: cc532b7f4548e2a457971e4267113976d5422ce9772fae2ba71f7480a81e1d80dc1f752bcd2a979387e18024cb9a89b2bab55b043e539f31b15d9e7834083dfc
@@ -15,13 +15,13 @@ jobs:
15
15
  fetch-depth: 0
16
16
 
17
17
  - name: Setup GitVersion
18
- uses: gittools/actions/gitversion/setup@v0.9.10
18
+ uses: gittools/actions/gitversion/setup@v0.9.11
19
19
  with:
20
20
  versionSpec: '5.x.x'
21
21
 
22
22
  - name: Execute GitVersion
23
23
  id: gitversion
24
- uses: gittools/actions/gitversion/execute@v0.9.10
24
+ uses: gittools/actions/gitversion/execute@v0.9.11
25
25
 
26
26
  - name: Create variables
27
27
  id: variables
data/README.md CHANGED
@@ -130,6 +130,31 @@ kramdown:
130
130
  directory: path/to/themes
131
131
  ```
132
132
 
133
+ ### Dimensions and Styling
134
+
135
+ It's possible to customize the dimensions of the diagram by providing the
136
+ `width` and `height` configuration keys. It's also possible to add arbitrary
137
+ styling with the `style` key.
138
+
139
+ ```yaml
140
+ kramdown:
141
+ plantuml:
142
+ width: 200px
143
+ height: 100px
144
+ style: "border: 1px solid black"
145
+ ```
146
+
147
+ To remove the `width`, `height` and `style` attributes from the `<svg />`
148
+ element, set the key's value to `none`.
149
+
150
+ ```yaml
151
+ kramdown:
152
+ plantuml:
153
+ width: none
154
+ height: none
155
+ style: none
156
+ ```
157
+
133
158
  ### Errors
134
159
 
135
160
  By default, `kramdown-plantuml` will raise an error and crash if something goes
@@ -199,7 +224,7 @@ agreement][cla].
199
224
  [codacy]: https://www.codacy.com/gh/SwedbankPay/kramdown-plantuml/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=SwedbankPay/kramdown-plantuml&amp;utm_campaign=Badge_Grade
200
225
  [codecov-badge]: https://codecov.io/gh/SwedbankPay/kramdown-plantuml/branch/main/graph/badge.svg?token=U3QJLVG3HY
201
226
  [codecov]: https://codecov.io/gh/SwedbankPay/kramdown-plantuml/
202
- [diagram-svg]: ./spec/examples/diagram.svg
227
+ [diagram-svg]: ./spec/examples/network-diagram.svg
203
228
  [fenced]: https://www.markdownguide.org/extended-syntax/#syntax-highlighting
204
229
  [fork]: https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo
205
230
  [gem-badge]: https://badge.fury.io/rb/kramdown-plantuml.svg
@@ -42,6 +42,7 @@ Gem::Specification.new do |spec|
42
42
 
43
43
  spec.add_development_dependency 'rake', '~> 13.0'
44
44
  spec.add_development_dependency 'rspec', '~> 3.2'
45
+ spec.add_development_dependency 'rspec-html-matchers', '>= 0.9'
45
46
  spec.add_development_dependency 'rspec-its', '~> 1.3'
46
47
  spec.add_development_dependency 'rubocop', '~> 1.12'
47
48
  spec.add_development_dependency 'rubocop-rake', '~> 0.6'
@@ -26,7 +26,7 @@ module Kramdown
26
26
 
27
27
  def execute(diagram)
28
28
  raise ArgumentError, 'diagram cannot be nil' if diagram.nil?
29
- raise ArgumentError, "diagram must be a #{Diagram}" unless diagram.is_a?(Diagram)
29
+ raise ArgumentError, "diagram must be a #{PlantUmlDiagram}" unless diagram.is_a?(PlantUmlDiagram)
30
30
 
31
31
  cmd = "java -Djava.awt.headless=true -jar #{@plantuml_jar_file} -tsvg -failfast -pipe #{debug_args}"
32
32
 
@@ -91,8 +91,8 @@ module Kramdown
91
91
  def decode_and_convert(hash, options)
92
92
  encoded_plantuml = hash['plantuml']
93
93
  plantuml = HTMLEntities.new.decode encoded_plantuml
94
- diagram = ::Kramdown::PlantUml::Diagram.new(plantuml, options)
95
- diagram.convert_to_svg
94
+ diagram = ::Kramdown::PlantUml::PlantUmlDiagram.new(plantuml, options)
95
+ diagram.svg
96
96
  end
97
97
 
98
98
  def logger
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ruby's Object class.
4
+ class Object
5
+ # Performs a case insensitive, trimmed comparison of the Object and the
6
+ # String 'none' and Symbol :none. Returns true if the comparison is true,
7
+ # otherwise false.
8
+ #
9
+ # @return [Boolean] True if the Object is equal to 'none' or :none,
10
+ # otherwise false.
11
+ def none_s?
12
+ return false if nil?
13
+ return true if self == :none
14
+
15
+ to_s.strip.casecmp?('none')
16
+ end
17
+ end
@@ -1,18 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'none_s'
3
4
  require_relative 'log_wrapper'
4
5
 
5
6
  module Kramdown
6
7
  module PlantUml
7
8
  # Options for PlantUML processing
8
9
  class Options
9
- attr_reader :theme_name, :theme_directory
10
+ attr_reader :theme_name, :theme_directory, :width, :height, :style
10
11
 
11
12
  def initialize(options_hash = {})
12
13
  @logger = LogWrapper.init
13
14
  @options = massage(options_hash) || {}
14
15
  @raise_errors = extract_raise_errors(@options)
15
16
  extract_theme_options(@options)
17
+ extract_style_options(@options)
16
18
  end
17
19
 
18
20
  def raise_errors?
@@ -64,6 +66,23 @@ module Kramdown
64
66
  boolean(raise_errors, true)
65
67
  end
66
68
 
69
+ def extract_style_options(options)
70
+ return if options.nil? || options.empty?
71
+
72
+ set_instance_property(:width, options)
73
+ set_instance_property(:height, options)
74
+ set_instance_property(:style, options)
75
+ end
76
+
77
+ def set_instance_property(name, options)
78
+ return unless options.key? name
79
+
80
+ value = options[name]
81
+ value = :none if value.none_s?
82
+ prop_name = "@#{name}".to_sym
83
+ instance_variable_set(prop_name, value)
84
+ end
85
+
67
86
  def massage(options_hash)
68
87
  if options_hash.nil? || !options_hash.is_a?(Hash) || options_hash.empty?
69
88
  @logger.debug 'No options provided'
@@ -1,17 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'version'
4
- require_relative 'theme'
3
+ require_relative 'executor'
4
+ require_relative 'log_wrapper'
5
5
  require_relative 'options'
6
6
  require_relative 'plantuml_error'
7
- require_relative 'log_wrapper'
8
- require_relative 'executor'
7
+ require_relative 'svg_diagram'
8
+ require_relative 'theme'
9
+ require_relative 'version'
9
10
 
10
11
  module Kramdown
11
12
  module PlantUml
12
13
  # Represents a PlantUML diagram that can be converted to SVG.
13
- class Diagram
14
- attr_reader :theme, :plantuml, :result
14
+ class PlantUmlDiagram
15
+ attr_reader :theme, :plantuml, :result, :options
15
16
 
16
17
  def initialize(plantuml, options)
17
18
  raise ArgumentError, 'options cannot be nil' if options.nil?
@@ -25,15 +26,13 @@ module Kramdown
25
26
  @logger.warn 'PlantUML diagram is empty' if @plantuml.nil? || @plantuml.empty?
26
27
  end
27
28
 
28
- def convert_to_svg
29
- return @svg unless @svg.nil?
30
- return @plantuml if @plantuml.nil? || @plantuml.empty?
29
+ def svg
30
+ return @svg_diagram unless @svg_diagram.nil?
31
31
 
32
32
  @plantuml = @theme.apply(@plantuml)
33
33
  log(plantuml)
34
34
  @result = @executor.execute(self)
35
- @result.validate
36
- @svg = wrap(@result.without_xml_prologue)
35
+ @svg_diagram = SvgDiagram.new(@result)
37
36
  rescue StandardError => e
38
37
  raise e if @options.raise_errors?
39
38
 
@@ -42,16 +41,6 @@ module Kramdown
42
41
 
43
42
  private
44
43
 
45
- def wrap(svg)
46
- theme_class = @theme.name ? "theme-#{@theme.name}" : ''
47
- class_name = "plantuml #{theme_class}".strip
48
-
49
- wrapper_element_start = "<div class=\"#{class_name}\">"
50
- wrapper_element_end = '</div>'
51
-
52
- "#{wrapper_element_start}#{svg}#{wrapper_element_end}"
53
- end
54
-
55
44
  def log(plantuml)
56
45
  @logger.debug 'PlantUML converting diagram:'
57
46
  @logger.debug_multiline plantuml
@@ -31,11 +31,11 @@ module Kramdown
31
31
  end
32
32
 
33
33
  def header(result)
34
- if theme_not_found?(result) && !result.diagram.nil? && !result.diagram.theme.nil?
34
+ if theme_not_found?(result) && !result.plantuml_diagram.nil? && !result.plantuml_diagram.theme.nil?
35
35
  return <<~HEADER
36
36
  Conversion of the following PlantUML result failed because the
37
- theme '#{result.diagram.theme.name}' can't be found in the directory
38
- '#{result.diagram.theme.directory}':
37
+ theme '#{result.plantuml_diagram.theme.name}' can't be found in the directory
38
+ '#{result.plantuml_diagram.theme.directory}':
39
39
  HEADER
40
40
  end
41
41
 
@@ -50,9 +50,9 @@ module Kramdown
50
50
  end
51
51
 
52
52
  def plantuml(result)
53
- return nil if result.nil? || result.diagram.nil?
53
+ return nil if result.nil? || result.plantuml_diagram.nil?
54
54
 
55
- result.diagram.plantuml
55
+ result.plantuml_diagram.plantuml
56
56
  end
57
57
 
58
58
  def result(result)
@@ -2,46 +2,29 @@
2
2
 
3
3
  require_relative 'log_wrapper'
4
4
  require_relative 'plantuml_error'
5
- require_relative 'diagram'
5
+ require_relative 'svg_diagram'
6
6
 
7
7
  module Kramdown
8
8
  module PlantUml
9
9
  # Executes the PlantUML Java application.
10
10
  class PlantUmlResult
11
- attr_reader :diagram, :stdout, :stderr, :exitcode
11
+ attr_reader :plantuml_diagram, :stdout, :stderr, :exitcode
12
12
 
13
- def initialize(diagram, stdout, stderr, exitcode)
14
- raise ArgumentError, 'diagram cannot be nil' if diagram.nil?
15
- raise ArgumentError, "diagram must be a #{Diagram}" unless diagram.is_a?(Diagram)
13
+ def initialize(plantuml_diagram, stdout, stderr, exitcode)
14
+ raise ArgumentError, 'diagram cannot be nil' if plantuml_diagram.nil?
15
+ raise ArgumentError, "diagram must be a #{PlantUmlDiagram}" unless plantuml_diagram.is_a?(PlantUmlDiagram)
16
16
  raise ArgumentError, 'exitcode cannot be nil' if exitcode.nil?
17
17
  raise ArgumentError, "exitcode must be a #{Integer}" unless exitcode.is_a?(Integer)
18
18
 
19
- @diagram = diagram
19
+ @plantuml_diagram = plantuml_diagram
20
20
  @stdout = stdout
21
21
  @stderr = stderr
22
22
  @exitcode = exitcode
23
23
  @logger = LogWrapper.init
24
24
  end
25
25
 
26
- def without_xml_prologue
27
- return @stdout if @stdout.nil? || @stdout.empty?
28
-
29
- xml_prologue_start = '<?xml'
30
- xml_prologue_end = '?>'
31
-
32
- start_index = @stdout.index(xml_prologue_start)
33
-
34
- return @stdout if start_index.nil?
35
-
36
- end_index = @stdout.index(xml_prologue_end, xml_prologue_start.length)
37
-
38
- return @stdout if end_index.nil?
39
-
40
- end_index += xml_prologue_end.length
41
-
42
- @stdout.slice! start_index, end_index
43
-
44
- @stdout
26
+ def svg_diagram
27
+ @plantuml_diagram.svg
45
28
  end
46
29
 
47
30
  def valid?
@@ -53,7 +36,7 @@ module Kramdown
53
36
  @stderr.include?('CoreText note:')
54
37
  end
55
38
 
56
- def validate
39
+ def validate!
57
40
  raise PlantUmlError, self unless valid?
58
41
 
59
42
  return if @stderr.nil? || @stderr.empty?
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'none_s'
4
+
5
+ module Kramdown
6
+ module PlantUml
7
+ # Builds a CSS style string from a hash of style properties.
8
+ class StyleBuilder
9
+ def initialize
10
+ @hash = {}
11
+ end
12
+
13
+ def []=(key, value)
14
+ return if key.nil?
15
+
16
+ case key
17
+ when :width, :height
18
+ if none(value)
19
+ @hash.delete(key)
20
+ else
21
+ @hash[key] = value
22
+ end
23
+ else
24
+ self.style = value
25
+ end
26
+ end
27
+
28
+ def to_s
29
+ @hash.sort_by { |key, _| key }.map { |key, value| "#{key}:#{value}" }.join(';')
30
+ end
31
+
32
+ private
33
+
34
+ def none(value)
35
+ return true if value.nil?
36
+
37
+ value_s = value.to_s.strip
38
+
39
+ return true if value_s.empty? || value.none_s?
40
+
41
+ false
42
+ end
43
+
44
+ def style=(style)
45
+ return if style.nil? || style.strip.empty?
46
+
47
+ style.split(';').each do |pair|
48
+ key, value = pair.split(':')
49
+ key = key.strip.to_sym
50
+ value = value.strip
51
+ @hash[key] = value
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rexml/document'
4
+ require_relative 'none_s'
5
+ require_relative 'style_builder'
6
+ require_relative 'plantuml_diagram'
7
+
8
+ module Kramdown
9
+ module PlantUml
10
+ # A diagram in SVG format.
11
+ class SvgDiagram
12
+ def initialize(plantuml_result)
13
+ raise ArgumentError, 'plantuml_result cannot be nil' if plantuml_result.nil?
14
+ raise ArgumentError, "plantuml_result must be a #{PlantUmlResult}" unless plantuml_result.is_a?(PlantUmlResult)
15
+
16
+ plantuml_result.validate!
17
+ svg = plantuml_result.stdout
18
+ @doc = REXML::Document.new svg
19
+ @source = plantuml_result.plantuml_diagram
20
+ @style_builder = StyleBuilder.new
21
+ transfer_options(plantuml_result)
22
+ end
23
+
24
+ def to_s
25
+ return '' if @doc.root.nil?
26
+
27
+ wrapper_doc = REXML::Document.new
28
+ wrapper_doc.context[:attribute_quote] = :quote
29
+ wrapper_element = REXML::Element.new('div').tap do |div|
30
+ div.add_attribute 'class', wrapper_class_name
31
+ div.add_element @doc.root
32
+ end
33
+
34
+ wrapper_doc.add_element wrapper_element
35
+ wrapper_doc.to_s
36
+ end
37
+
38
+ def width
39
+ get_xml_attribute_value(:width)
40
+ end
41
+
42
+ def height
43
+ get_xml_attribute_value(:height)
44
+ end
45
+
46
+ def style
47
+ get_xml_attribute_value(:style)
48
+ end
49
+
50
+ private
51
+
52
+ def wrapper_class_name
53
+ theme_class = @source.theme.name ? "theme-#{@source.theme.name}" : ''
54
+ "plantuml #{theme_class}".strip
55
+ end
56
+
57
+ def get_xml_attribute_value(attribute_name)
58
+ return nil if @doc.root.nil?
59
+
60
+ name = attribute_name.to_s
61
+ value = @doc.root.attributes[name]
62
+ value.nil? || value.none_s? ? :none : value
63
+ end
64
+
65
+ def manipulate_xml_attribute(attribute_name, value)
66
+ if value.none_s?
67
+ remove_xml_attribute(attribute_name)
68
+ elsif !value.nil? && value.is_a?(String) && !value.strip.empty?
69
+ set_xml_attribute(attribute_name, value)
70
+ end
71
+
72
+ update_style unless attribute_name == :style || style == :none
73
+ end
74
+
75
+ def remove_xml_attribute(attribute_name)
76
+ @doc.root.attributes.get_attribute(attribute_name.to_s).remove
77
+ end
78
+
79
+ def set_xml_attribute(attribute_name, value)
80
+ name = attribute_name.to_s
81
+ @doc.root.attributes[name] = value
82
+ @style_builder[attribute_name] = value
83
+ end
84
+
85
+ def update_style
86
+ style = @style_builder.to_s
87
+ set_xml_attribute(:style, style)
88
+ end
89
+
90
+ def transfer_options(plantuml_result)
91
+ return if (options = options(plantuml_result)).nil?
92
+
93
+ %i[style width height].each do |attribute|
94
+ options.public_send(attribute).tap do |option_value|
95
+ next if option_value.nil?
96
+
97
+ option_value = option_value.to_s.strip
98
+
99
+ next if option_value.empty?
100
+
101
+ manipulate_xml_attribute(attribute, option_value)
102
+ end
103
+ end
104
+ end
105
+
106
+ def options(plantuml_result)
107
+ return nil if @doc.root.nil? \
108
+ || plantuml_result.nil? \
109
+ || plantuml_result.plantuml_diagram.nil?
110
+
111
+ plantuml_result.plantuml_diagram.options
112
+ end
113
+ end
114
+ end
115
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Kramdown
4
4
  module PlantUml
5
- VERSION = '1.1.13'
5
+ VERSION = '1.2.0'
6
6
  end
7
7
  end
data/lib/kramdown_html.rb CHANGED
@@ -5,7 +5,7 @@ require 'kramdown-parser-gfm'
5
5
  require_relative 'kramdown-plantuml/log_wrapper'
6
6
  require_relative 'kramdown-plantuml/plantuml_error'
7
7
  require_relative 'kramdown-plantuml/options'
8
- require_relative 'kramdown-plantuml/diagram'
8
+ require_relative 'kramdown-plantuml/plantuml_diagram'
9
9
  require_relative 'kramdown-plantuml/jekyll_provider'
10
10
 
11
11
  module Kramdown
@@ -38,8 +38,8 @@ module Kramdown
38
38
  end
39
39
 
40
40
  def convert_plantuml(plantuml, options)
41
- diagram = ::Kramdown::PlantUml::Diagram.new(plantuml, options)
42
- diagram.convert_to_svg
41
+ diagram = ::Kramdown::PlantUml::PlantUmlDiagram.new(plantuml, options)
42
+ diagram.svg.to_s
43
43
  rescue StandardError => e
44
44
  raise e if options.raise_errors?
45
45
 
data/pom.xml CHANGED
@@ -10,7 +10,7 @@
10
10
  <dependency>
11
11
  <groupId>net.sourceforge.plantuml</groupId>
12
12
  <artifactId>plantuml</artifactId>
13
- <version>1.2021.12</version>
13
+ <version>1.2021.14</version>
14
14
  </dependency>
15
15
  </dependencies>
16
16
  </project>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kramdown-plantuml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.13
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Swedbank Pay
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-05 00:00:00.000000000 Z
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlentities
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-html-matchers
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rspec-its
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -180,19 +194,22 @@ files:
180
194
  - LICENSE
181
195
  - README.md
182
196
  - Rakefile
183
- - bin/net/sourceforge/plantuml/plantuml/1.2021.12/plantuml-1.2021.12.jar
197
+ - bin/net/sourceforge/plantuml/plantuml/1.2021.14/plantuml-1.2021.14.jar
184
198
  - kramdown-plantuml.gemspec
185
199
  - lib/kramdown-plantuml.rb
186
200
  - lib/kramdown-plantuml/bool_env.rb
187
201
  - lib/kramdown-plantuml/console_logger.rb
188
- - lib/kramdown-plantuml/diagram.rb
189
202
  - lib/kramdown-plantuml/executor.rb
190
203
  - lib/kramdown-plantuml/jekyll_page_processor.rb
191
204
  - lib/kramdown-plantuml/jekyll_provider.rb
192
205
  - lib/kramdown-plantuml/log_wrapper.rb
206
+ - lib/kramdown-plantuml/none_s.rb
193
207
  - lib/kramdown-plantuml/options.rb
208
+ - lib/kramdown-plantuml/plantuml_diagram.rb
194
209
  - lib/kramdown-plantuml/plantuml_error.rb
195
210
  - lib/kramdown-plantuml/plantuml_result.rb
211
+ - lib/kramdown-plantuml/style_builder.rb
212
+ - lib/kramdown-plantuml/svg_diagram.rb
196
213
  - lib/kramdown-plantuml/theme.rb
197
214
  - lib/kramdown-plantuml/version.rb
198
215
  - lib/kramdown-plantuml/which.rb