kramdown-plantuml 1.1.13 → 1.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 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